title: 創(chuàng)建自定義塊 - 生成代碼
Create Custom BlocksGenerating Code
原文鏈接:https://developers.google.com/blockly/guides/create-custom-blocks/generating-code
大多數Blockly應用程序需要將塊轉換為代碼以供執(zhí)行。本頁介紹如何向自定義塊添加代碼生成器。
首先饿序,轉到generators /目錄并選擇與要生成的語言(JavaScript熬荆,Python共屈,PHP晒奕,Lua煮寡,Dart等)對應的子目錄妆毕。假設您的塊不適合現有類別,請創(chuàng)建一個新的JavaScript文件痹届。這個新的JavaScript文件需要包含在編輯器的HTML文件中的<script ...>標簽列表中呻待。
典型的塊的代碼生成器如下所示
Blockly.JavaScript['text_indexOf'] = function(block) {
// Search the text for a substring.
var operator = block.getFieldValue('END') == 'FIRST' ? 'indexOf' : 'lastIndexOf';
var subString = Blockly.JavaScript.valueToCode(block, 'FIND',
Blockly.JavaScript.ORDER_NONE) || '\'\'';
var text = Blockly.JavaScript.valueToCode(block, 'VALUE',
Blockly.JavaScript.ORDER_MEMBER) || '\'\'';
var code = text + '.' + operator + '(' + subString + ')';
return [code, Blockly.JavaScript.ORDER_MEMBER];
};
收集參數
任何塊的代碼生成器的第一個任務是收集所有的參數和字段數據。這個任務通常有幾個函數:
getFieldValue
block.getFieldValue('END')
此函數從指定名稱的字段返回值队腐。
- 在文本字段的情況下带污,此函數返回鍵入的文本。例如香到。 “Hello World”鱼冀。
- 在下拉列表的情況下,此函數返回與所選選項相關聯(lián)的與語言無關的文本悠就。英語塊可能有一個下拉菜單千绪,選擇了“first”,而德語中的下拉菜單將顯示“erste”梗脾。代碼生成器不必知道所有可能的人類語言荸型,因此getFieldValue函數將返回創(chuàng)建下拉列表時指定的語言中性文本(Blockly的核心塊通常使用大寫英語單詞,例如“FIRST”)炸茧。
- 在變量下拉的情況下瑞妇,此函數返回變量下拉的面向用戶的名稱稿静。請注意,此名稱不一定與生成的代碼中使用的變量名稱相同辕狰。例如改备,變量名“for”在Blockly中是合法的,但是在大多數語言中將與保留字沖突蔓倍,因此將被重命名為“for2”悬钳。同樣,阿拉伯語變量名“?????”在Blockly中是合法的偶翅,但在大多數語言中是非法的默勾,因此將被重命名為“_D9_85_D8_AA_D8_BA_D9_8A_D8_B1”。要獲取Blockly變量名稱為可用于生成代碼的變量名稱聚谁,請使用以下調用:
Blockly.JavaScript.variableDB_.getName(block.getFieldValue('VAR'), Blockly.Variables.NAME_TYPE);
請注意母剥,JavaScript應該更改為適當的語言(Python,PHP形导,Lua媳搪,Dart等),因為每種語言都有不同的保留字列表骤宣。
valueToCode
Blockly.JavaScript.valueToCode(block, 'FROM', Blockly.JavaScript.ORDER_ADDITION) || '0'
此函數查找連接到命名值輸入(“FROM”)的塊,生成該塊的代碼序愚,并將該代碼作為字符串返回憔披。如果輸入未連接,則此函數返回null爸吮,這就是為什么通常使用布爾值“或”和默認值跟隨函數的原因芬膝。因此,在上面的示例中形娇,如果沒有塊附加到名為“FROM”的輸入锰霜,則此輸入的默認代碼將為字符串'0'。
第三個參數指定嵌入所需的操作信息的順序桐早。每個語言生成器都有一個有序的優(yōu)先級列表癣缅。 valueToCode函數需要傳遞對應于將應用于返回的代碼的最大力的順序值。這允許valueToCode根據需要將代碼括在括號中哄酝。有關詳細信息友存,請參閱運營商優(yōu)先級頁面operator precedence。
請注意陶衅,JavaScript應該更改為適當的語言(Python屡立,PHP,Lua搀军,Dart等)膨俐。
statementToCode
Blockly.JavaScript.statementToCode(block, 'DO')
此函數查找連接到指定語句輸入的嵌套塊的堆棧勇皇,生成該堆棧的代碼,縮進代碼焚刺,并將代碼作為字符串返回敛摘。如果輸入未連接,則此函數返回一個空字符串檩坚。
請注意着撩,JavaScript應該更改為適當的語言(Python,PHP匾委,Lua拖叙,Dart等)。
組裝代碼
一旦收集了所有參數赂乐,就可以組合最終的代碼薯鳍。這對于大多數塊是直接的。這里是一個while循環(huán)的例子
var code = 'while (' + argument0 + ') {\n' + branch0 + '}\n';
語句塊(不返回值的那些塊)然后可以返回代碼挨措,而不用費心:
return code;
值塊(返回值的那些塊)有點復雜挖滤。這里是一個基本算術運算符(加號,減號等)的例子:
var code = argument0 + ' ' + operator + ' ' + argument1;
此示例說明了操作順序問題浅役≌端桑考慮形成表達式(2 *(3 + 4))的兩個連接的算術塊的情況。使用上述代碼剪切觉既,加法塊將返回字符串“3 + 4”惧盹,而乘法塊將使用其作為輸入以返回“2 * 3 + 4”。這個結果是不正確的瞪讼,因為執(zhí)行時3將更緊密地綁定到乘法钧椰。
為了解決這個問題,值塊必須返回一個包含兩個值的列表:代碼和適當的順序值:
return [code, Blockly.JavaScript.ORDER_ADDITION];
每個語言生成器都有一個有序的優(yōu)先級列表符欠。返回的順序值指定將代碼綁定在一起的最小強制嫡霞。有關詳細信息,請參閱運營商優(yōu)先級頁面operator precedence希柿。
如果生成的代碼要求子塊的代碼被包括兩次诊沪,則應該緩存參數cache the arguments以提高效率并防止副作用。