代码生成器
Blockly的大多数应用程序都要求将用户的程序翻译成JavaScript,Python,PHP,Lua,Dart或其他语言。此操作由Blockly在客户端执行。这个过程就需要代码生成器。
生成代码
第一步是包含所用语言的生成器。Blockly包含以下5种生成器,分别对应不同的语言:
- javascript_compressed.js
- python_compressed.js
- php_compressed.js
- lua_compressed.js
- dart_compressed.js
当然,在引入某个生成器之前,你应该先引入blockly_compressed.js。例如,下面是包含的JavaScript生成器:
<script src="blockly_compressed.js"></script>
<script src="javascript_compressed.js"></script>
接下来,在应用程序中可以随时通过调用下来的函数将用户在工作区组合的块导出为代码:
var code = Blockly.JavaScript.workspaceToCode(workspace);
同理,如果你需要生成其它语言的代码,则把:
<script src="https://blockly-demo.appspot.com/static/javascript_compressed.js"></script>
中的JavaScript替换成Python,PHP,Lua,或Dart。
实时生成
生成代码是一个非常快速的操作,因此你可以时常调用此函数。一个常见的策略是通过向Blockly的更改事件添加监听器来实时生成和显示代码:
function myUpdateFunction(event) {
var code = Blockly.JavaScript.workspaceToCode(workspace);
console.info(code)
}
workspace.addChangeListener(myUpdateFunction);
在这里可以看到示例
查看event以获取更多信息。
给自定义块添加生成器函数
在上文中我们提到了如何去创建自定义工具,但我们同时还要指定这个块背后对应的代码。这样才能将该模块转换为代码。标准生成器通常采用以下格式:
Blockly.JavaScript['text_length'] = function(block) {
// String or array length.
var argument0 = Blockly.JavaScript.valueToCode(block, 'VALUE',
Blockly.JavaScript.ORDER_FUNCTION_CALL) || '\'\'';
return [argument0 + '.length', Blockly.JavaScript.ORDER_MEMBER];
};
生成器函数对块进行引用以进行处理。它将输入(上面的VALUE输入框)渲染为代码串,然后将这些代码串连接成更大的表达式。
请参阅使用自定义生成器 了解更多详细信
综合示例
下面的例子中,我们自定义了一个工具lenght_of,同时指定了它背后对应的代码。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Blockly Demo: Fixed Blockly</title>
<script src="../../blockly_compressed.js"></script>
<script src="../../blocks_compressed.js"></script>
<script src="../../msg/js/en.js"></script>
<script src="../../javascript_compressed.js"></script>
<style>
body {
background-color: #fff;
font-family: sans-serif;
}
h1 {
font-weight: normal;
font-size: 140%;
}
</style>
</head>
<body>
<div id="blocklyDiv" style="height: 580px; width: 600px;"></div>
<div>
<button id="gerateCode">生成代码</button>
<button id="runCode">执行代码</button>
</div>
<xml id="toolbox" style="display: none">
<block type="controls_if"></block>
<block type="logic_compare"></block>
<block type="controls_repeat_ext"></block>
<block type="math_number"></block>
<block type="math_arithmetic"></block>
<block type="text"></block>
<block type="text_print"></block>
<block type="string_length"></block>
</xml>
<script type="text/javascript">
var code = ""
document.getElementById("gerateCode").addEventListener("click",function(){
console.info(".....代码如下....")
code = Blockly.JavaScript.workspaceToCode(demoWorkspace);
console.info(code)
});
document.getElementById("runCode").addEventListener("click",function(){
console.info("执行代码如下....")
try{
eval(code)
}
catch(e){
console.info("执行代码错误",e)
}
});
</script>
<script type="text/javascript">
Blockly.Blocks['string_length'] = {
init: function() {
this.jsonInit({
"message0": 'length of %1',
"args0": [
{
"type": "input_value",
"name": "VALUE",
"check": "String"
}
],
"output": "Number",
"colour": 160,
"tooltip": "Returns number of letters in the provided text.",
"helpUrl": "http://www.w3schools.com/jsref/jsref_length_string.asp"
});
}
};
Blockly.JavaScript['string_length'] = function(block) {
// String or array length.
var argument0 = Blockly.JavaScript.valueToCode(block, 'VALUE',
Blockly.JavaScript.ORDER_FUNCTION_CALL) || '\'\'';
return [argument0 + '.length', Blockly.JavaScript.ORDER_MEMBER];
// return "'aaa'.length";
};
</script>
<script>
var demoWorkspace = Blockly.inject('blocklyDiv',
{
media: '../../media/',
toolbox: document.getElementById('toolbox')
});
</script>
</body>
</html>