代码生成

代码生成是将工作区上的块转换为可执行的代码字符串的过程。

代码生成极为重要,因为借助代码生成功能,您的块能够实际执行一些操作,例如计算算术表达式、在迷宫中移动字符或配置网店!

您无法直接“运行”块。而是先生成代码字符串,然后执行这些字符串。

代码生成器

如需生成代码,您必须选择要生成的基于文本的语言。

代码生成器是一个类,负责处理关于生成代码的规则,这些规则特定于给定语言,但并不特定于某个块。例如,它可以处理注释格式、缩进语句和引用字符串等内容。

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

const code = javascriptGenerator.workspaceToCode(myWorkspace);

Blockly 提供 5 种内置代码生成器:

  • JavaScript ES5
  • Python 3
  • Lua 5.1
  • Dart 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 代码通常用于调用函数,以在代码末尾触发行为。

如果您生成的代码可按原样运行,则无需添加序言或 postscript。

执行

生成代码后,您需要确定如何执行代码。决定如何执行它的决定很大程度上取决于应用,不在 Blockly 的讨论范围之内。

对于 JavaScript 代码,Blockly 团队建议使用 JSInterpreter其他语言则需要使用其他工具。