Генерация кода

Генерация кода — это процесс преобразования блоков рабочей области в строку кода, которую можно выполнить.

Генерация кода чрезвычайно важна, поскольку именно она позволяет вашим блокам выполнять определенные действия, например вычислять арифметические выражения, перемещать персонажа по лабиринту или настраивать интернет-магазин!

Вы не можете «запускать» блоки напрямую. Вместо этого вы генерируете строки кода, а затем выполняете их.

Генераторы кода

Чтобы сгенерировать код, вам нужно выбрать, какой текстовый язык вы хотите сгенерировать.

Генератор кода — это класс, который обрабатывает правила генерации кода, специфичные для данного языка, но не специфичные для отдельного блока. Например, он обрабатывает такие вещи, как форматирование комментариев, отступы и цитирование строк.

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

const code = javascriptGenerator.workspaceToCode(myWorkspace);

Blockly предоставляет 5 встроенных генераторов кода:

  • JavaScript ES5
  • Питон 3
  • Луа 5.1
  • Дарт 2
  • PHP 7

Вы можете импортировать и использовать генераторы одним из следующих методов.

Модули

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);

Распаковать

Вы должны включить генератор после включения Blockly.

<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);

Локальные скрипты

Вы должны включить генератор после включения Blockly.

<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);

Если в этом списке нет языка, для которого вы хотите сгенерировать код, вы также можете создать собственный генератор кода .

Генераторы блочного кода

Вторая часть генерации кода определяет, какой код генерируют отдельные блоки. Это необходимо сделать для каждого блока, для каждого отдельного языка, который вы хотите сгенерировать.

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

Принцип работы генераторов кода различен для разных типов блоков:

Но все они требуют сбора значений из полей , сбора кода внутренних блоков , а затем объединения этих строк.

Поколение

Генерация может выполняться по запросу конечного пользователя (например, когда он нажимает кнопку) или непрерывно.

Непрерывные обновления позволяют отображать или запускать код всякий раз, когда пользователь вносит изменения. Генерация кода — это быстрая операция, поэтому это не оказывает большого влияния на производительность. Это делается с помощью прослушивателя событий .

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);

Преамбула или постскриптум

После того как вы сгенерировали код, вы можете включить (необязательно) преамбулу или код преамбулы в начало или конец сгенерированного кода.

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

Код преамбулы обычно используется для включения внешних определений в начале кода. Код Postscript обычно используется для вызова функций, запускающих поведение в конце кода.

Если сгенерированный код можно запустить «как есть», нет необходимости включать преамбулу или постскриптум.

Исполнение

После того, как вы сгенерировали код, вам нужно выяснить, как его выполнить. Решение о том, как его выполнить, очень зависит от приложения и выходит за рамки Blockly.

Для кода JavaScript команда Blockly рекомендует использовать JSInterpreter . Другие языки требуют других инструментов.