block--生成器(Generating Code)

Generating Code

大多數塊應用程序需要將塊轉換爲執行代碼。本頁介紹如何將代碼生成器添加到自定義塊。

首先,轉到generators/目錄並選擇與要生成的語言相對應的子目錄(JavaScript、Python、PHP、Lua、Dart等)。假設您的塊不適合現有的類別,則創建一個新的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];
};

Collecting the Arguments

任何塊的代碼生成器的第一個任務是收集所有參數和字段數據。此任務通常使用以下幾個功能:

getFieldValue

block.getFieldValue('END')

對於文本字段,此函數返回鍵入的文本。E、 g.“Hello World”。

在下拉列表的情況下,此函數返回與所選選項關聯的語言中性文本。一個英文塊可能有一個選擇了“first”的下拉列表,而在德語中,同一個下拉列表將顯示“erste”。代碼生成器不必知道所有可能的人類語言,因此getFieldValue函數將返回在創建下拉列表時指定的語言中性文本(Blockly的核心塊通常使用大寫的英語單詞,例如“FIRST”)。

對於變量下拉列表,此函數返回變量下拉列表的面向用戶的名稱。需要注意的是,該名稱不一定與生成代碼中使用的變量名稱相同。例如,變量名“For”在Blockly中是合法的,但在大多數語言中會與保留字衝突,因此會重命名爲“for2”。同樣地,阿拉伯語變量名“متغي”在塊中是合法的,但在大多數語言中是非法的,因此將被重命名爲“_D9_85_D8_AA_D8_BA_D9_8A_D8_B1”。要獲取生成代碼中可能使用的塊變量名,請使用以下調用:

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”)的塊,生成該塊的代碼,並將代碼作爲字符串返回。如果輸入未連接,則此函數返回空值,這就是爲什麼通常使用布爾值“或”和默認值跟隨函數的原因。因此,在上面的示例中,如果沒有塊附加到名爲“FROM”的輸入,則此輸入的默認代碼將是字符串“0”。

第三個參數指定嵌入所需的操作信息的順序。每個語言生成器都有一個有序的引用列表。ValueToCu碼函數需要傳遞與將應用於返回代碼的最大力相對應的順序值。這允許valueToCode在需要時將代碼括在圓括號中。有關詳細信息,請參閱“運算符優先級”頁。

注意,JavaScript應該更改爲適當的語言(Python、PHP、Lua、Dart等)。

statementToCode

Blockly.JavaScript.statementToCode(block, 'DO')

此函數用於查找連接到指定語句輸入的嵌套塊堆棧,生成該堆棧的代碼,縮進代碼,並將代碼作爲字符串返回。如果輸入未連接,此函數將返回空字符串。

注意,JavaScript應該更改爲適當的語言(Python、PHP、Lua、Dart等)。

Assembling the Code

收集完所有參數後,就可以彙編最後的代碼了。大多數街區都是直行的。下面是while循環的一個示例:

var code = 'while (' + argument0 + ') {\n' + branch0 + '}\n';

return code;

然後,語句塊(不返回值的語句塊)可以返回代碼而無需進一步ado:

值塊(那些返回值的塊)要複雜一些。下面是一個基本算術運算符(加號、減號等)的示例:

var code = argument0 + ' ' + operator + ' ' + argument1;

這個例子說明了一個操作順序問題。考慮兩個連接的算術塊形成表達式(2*(3+4))的情況。使用上面截取的代碼,加法塊將返回字符串“3+4”,而乘法塊將此作爲輸入返回“2*3+4”。這個結果是不正確的,因爲在執行時3將更緊密地綁定到乘法。

要解決此問題,值塊必須返回一個包含兩個值的列表:代碼和適當的順序值:

return [code, Blockly.JavaScript.ORDER_ADDITION];

每個語言生成器都有一個有序的引用列表。返回的order值指定將代碼綁定在一起的最小力。有關詳細信息,請參閱“運算符優先級”頁。

如果生成的代碼要求子塊的代碼包含兩次,則應緩存參數以提高效率並防止副作用。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章