コード生成

コード生成とは、ワークスペース上のブロックを実行可能な文字列に変換するプロセスです。

コードの生成は非常に重要です。なぜなら、コード生成によって、ブロックが実際にさまざまな処理(算術式の評価、迷路でのキャラクターの移動、オンライン ショップの設定など)を実行できるからです。

ブロックを直接「実行」することはできません。代わりに、コード文字列を生成して実行します。

コード生成ツール

コードを生成するには、生成するテキストベースの言語を選択する必要があります。

コード生成ツールは、特定の言語に固有であり、個々のブロックには固有ではないコードを生成するためのルールを処理するクラスです。たとえば、コメントの書式設定、ステートメントのインデント、文字列の引用などを処理します。

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

コードを生成する言語がこのリストに含まれていない場合は、カスタムコード生成ツールを作成することもできます。

ブロックコード ジェネレータ

コード生成の 2 つ目の部分は、個々のブロックが生成するコードを定義することです。これは、生成する個々の言語ごとに、ブロックごとに行う必要があります。

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 の範囲外です。

Blockly では JavaScript コードとして、JSInterpreter を使用することをおすすめします。他の言語では他のツールが必要。