Generate code from blockly-json

Generate code from JSON File

Python Code Generation Process

One feature of Blockly is to export an existing program model as a JSON file. CEREBRA uses this JSON file as a source file for the python code generation. Fortunately, Blockly offers also a feature to generate python code from an exported program model. In the next section you find a code snipped which shows you how the python code generation works.

 

import Blockly, { Workspace } from 'blockly' import{pythonGenerator} from 'blockly/python'; export class PythonCodeGeneratorService{ public createPython(json:String) : String { var workspace: Workspace = new Blockly.Workspace() Blockly.serialization.workspaces.load(json, workspace) return pythonGenerator.workspaceToCode(workspace); } }

One important step is to create a headless workspace (Line: 6) before you load the given JSON File. After that you can use the given pythonGenerator from Blockly to generate your python code. In the attached file: workspace.json you find a full export for the given model in figure: Python Code Generation Process

 

One easy step to load a given workspace file is showed by the function: loadJsonFile.

import fs from 'fs' function loadJsonFile(): String { return JSON.parse(fs.readFileSync('your_path_here', 'utf-8')) }

 

Add custom code generator

 

Custom block with function and input

 

If you would like to add custom python code because you have added a new custom block with a new pib function then you have to follow these steps.

With Blockly you can easily inject new code generator functions for an existing code generator like python. You find some examples at the Bockly documentation but unfortunately most of them are outdated. At the moment CEREBRA is using Blockly version: 9.3.2 and some important imports has been changed. If you read some additional documentation please always check the imports.

Before you can generate new python code based on your custom block you have to register your block at Blockly. You find some helpful information in the section: Create custom blocks . After that you can inject your code generation in similar way. CEREBRA has an build-in Blockly application under the menu point “Program”. You can add your custom code in the file: program.component.ts. The following code snipped gives you an example of a code generator for the blocks in figure: Custom block with function and input and an export as JSON file.

Workspace JSON

{ "blocks": { "languageVersion": 0, "blocks": [ { "type": "my_custom_block_type", "id": "Igik0(s,HW+]5%wv/dv9", "x": 185, "y": 152, "inputs": { "TEXT": { "shadow": { "type": "text", "id": "`MAs;Bwg9IsT:H?T/6*?", "fields": { "TEXT": "abc" } }, "block": { "type": "my_custom_linked_block_type", "id": "2!*w=c#|9A9NAa5eEA9c", "fields": { "TEXT": "Hello I am Pib" } } } } } ] } }

Python Code Generator Extension

At first you have to import the pythonGenerator, to avoid some confusing import errors, please use the one from 'blockly/python.js'. After that you can add your new function to the pythonGeneratorby passing a new function. The key is the block’s type name ('my_custom_block_type') you have already used for the block definition one step before. For the given example the result is: print("Pib says: Hello I am Pib").

In the most common code generation scenarios the first task is to collect all the arguments and field data. There are several functions used for this task:

  • valueToCode

  • getFieldValue

  • statementToCode

valueToCode

This function finds the block connected to the named value input ('my_custom_linked_block_type'), generates the code for that block, and returns the code as a string. In the event that the input is not connected, this function returns null.

The third argument specifies order of operations information required for embedding. Each language generator has an ordered list of precedences. The valueToCode function needs to be passed the order value corresponding to the maximum force that will be applied to the returned code. This allows valueToCode to wrap the code in parentheses if required.

getFieldValue

This function returns the value from a field of the specified name ('my_custom_field'). E.g. the value of a text field.

statementToCode

This function finds the stack of nested blocks connected to the specified statement input, generates the code for that stack, indents the code, and returns the code as a string. In the event that the input is not connected, this function returns an empty string.

If would like learn more about the code generation then look at the Blockly doc: Code generation  |  Blockly  |  Google for Developers