Codegenerierung

Bei der Codegenerierung werden die Blöcke eines Arbeitsbereichs in einen Codestring umgewandelt, der ausgeführt werden kann.

Die Codegenerierung ist äußerst wichtig, da sie es Ihren Blöcken ermöglicht, Dinge tatsächlich zu tun, z. B. arithmetische Ausdrücke auszuwerten, ein Zeichen durch ein Labyrinth zu bewegen oder einen Onlineshop zu konfigurieren.

Sie können Blockierungen nicht direkt ausführen. Stattdessen generieren Sie Codestrings und führen diese dann aus.

Codegeneratoren

Um Code zu generieren, müssen Sie die textbasierte Sprache auswählen, die Sie generieren möchten.

Ein Codegenerator ist eine Klasse, die die Regeln zum Generieren von Code verarbeitet, der für eine bestimmte Sprache, aber nicht für einen einzelnen Block spezifisch ist. Sie verarbeitet beispielsweise Dinge wie das Formatieren von Kommentaren, das Einrücken von Anweisungen und das Zitieren von Strings.

// javascriptGenerator is a code generator that makes javascript strings.
import {javascriptGenerator} from 'blockly/javascript';

const code = javascriptGenerator.workspaceToCode(myWorkspace);

Blockly bietet fünf integrierte Codegeneratoren:

  • JavaScript ES5
  • Python 3
  • Lua 5.1
  • Dart 2
  • PHP 7

Du kannst die Generatoren mit einer der folgenden Methoden importieren und verwenden.

Module

import {javascriptGenerator} from 'blockly/javascript';
import {pythonGenerator} from 'blockly/python';
import {phpGenerator} from 'blockly/php';
import {luaGenerator} from 'blockly/lua';
import {dartGenerator} from 'blockly/dart';

const jsCode = javascriptGenerator.workspaceToCode(workspace);
const pythonCode = pythonGenerator.workspaceToCode(workspace);
const phpCode = phpGenerator.workspaceToCode(workspace);
const luaCode = luaGenerator.workspaceToCode(workspace);
const dartCode = dartGenerator.workspaceToCode(workspace);

Entpacken

Nach der Einbindung von Blockly musst du den Generator hinzufügen.

<script src="https://unpkg.com/blockly"></script>
<script src="https://unpkg.com/blockly/javascript_compressed"></script>
<script src="https://unpkg.com/blockly/python_compressed"></script>
<script src="https://unpkg.com/blockly/php_compressed"></script>
<script src="https://unpkg.com/blockly/lua_compressed"></script>
<script src="https://unpkg.com/blockly/dart_compressed"></script>
const jsCode = javascript.javascriptGenerator.workspaceToCode(workspace);
const pythonCode = python.pythonGenerator.workspaceToCode(workspace);
const phpCode = php.phpGenerator.workspaceToCode(workspace);
const luaCode = lua.luaGenerator.workspaceToCode(workspace);
const dartCode = dart.dartGenerator.workspaceToCode(workspace);

Lokale Skripts

Nach der Einbindung von Blockly musst du den Generator hinzufügen.

<script src="blockly_compressed.js"></script>
<script src="javascript_compressed.js"></script>
<script src="python_compressed.js"></script>
<script src="php_compressed.js"></script>
<script src="lua_compressed.js"></script>
<script src="dart_compressed.js"></script>
const jsCode = javascript.javascriptGenerator.workspaceToCode(workspace);
const pythonCode = python.pythonGenerator.workspaceToCode(workspace);
const phpCode = php.phpGenerator.workspaceToCode(workspace);
const luaCode = lua.luaGenerator.workspaceToCode(workspace);
const dartCode = dart.dartGenerator.workspaceToCode(workspace);

Wenn diese Liste nicht die Sprache enthält, für die Sie Code generieren möchten, können Sie auch einen benutzerdefinierten Codegenerator erstellen.

Blockcode-Generatoren

Der zweite Teil der Codegenerierung besteht darin, zu definieren, welchen Code die einzelnen Blöcke generieren. Dies muss für jeden Block und für jede einzelne Sprache, die Sie generieren möchten, erfolgen.

javascriptGenerator.forBlock['my_custom_block'] = function(block, generator) { /* ... */ }

Die Funktionsweise von Codegeneratoren ist je nach Blocktyp unterschiedlich:

Für sie alle müssen jedoch die Werte aus Feldern erfasst, der Code der inneren Blöcke erfasst und diese Strings dann verkettet werden.

Generierung

Die Generierung kann erfolgen, wenn der Endnutzer sie anfordert (z. B. durch Klicken auf eine Schaltfläche), oder aber fortlaufend.

Mit kontinuierlichen Updates können Sie den Code anzeigen oder ausführen, wenn der Nutzer eine Änderung vornimmt. Das Generieren von Code ist ein schneller Vorgang, die Leistung wird also kaum beeinträchtigt. Dazu wird ein Event-Listener verwendet.

const supportedEvents = new Set([
  Blockly.Events.BLOCK_CHANGE,
  Blockly.Events.BLOCK_CREATE,
  Blockly.Events.BLOCK_DELETE,
  Blockly.Events.BLOCK_MOVE,
]);

function updateCode(event) {
  if (workspace.isDragging()) return; // Don't update while changes are happening.
  if (!supportedEvents.has(event.type)) return;

  const code = javascriptGenerator.workspaceToCode(workspace);
  document.getElementById('textarea').value = code;
}

workspace.addChangeListener(updateCode);

Präambel- oder Postskript-Code

Nachdem Sie den Code generiert haben, können Sie (optionalen) Präambel- oder Präambelcode am Anfang oder Ende des generierten Codes einfügen.

let code = javascriptGenerator.workspaceToCode(workspace);
// Add a preamble and a postscript to the code.
code = `const def = 'some value';\n${code}\nkickOffSomeFunction();\n`;

Präambelcode wird normalerweise verwendet, um externe Definitionen an den Anfang des Codes einzufügen. Postscript-Code wird normalerweise verwendet, um Funktionen aufzurufen, um am Ende des Codes ein Verhalten einzuleiten.

Wenn Ihr generierter Code unverändert ausgeführt werden kann, ist es nicht erforderlich, eine Präambel oder ein Postscript einzufügen.

Umsetzung

Nachdem Sie den Code generiert haben, müssen Sie herausfinden, wie er ausgeführt werden soll. Die Entscheidung, wie sie ausgeführt wird, ist sehr anwendungsspezifisch und liegt außerhalb des Zuständigkeitsbereichs von Blockly.

Für JavaScript-Code empfiehlt das Blockly-Team die Verwendung von JSInterpreter. Für andere Sprachen sind andere Tools erforderlich.