/** * @license Licensed under the Apache License, Version 2.0 (the "License"): * http://www.apache.org/licenses/LICENSE-2.0 */ /** * @fileoverview Generating Arduino code for procedure (function) blocks. * * TODO: For now all variables will stay at "int". Once type is implemented * it needs to be captured on the functions with return. */ 'use strict'; goog.provide('Blockly.Python.procedures'); goog.require('Blockly.Python'); /** * Code generator to create a function with a return value (X). * Arduino code: void functionname { return X } * @param {!Blockly.Block} block Block to generate the code from. * @return {null} There is no code added to loop. */ Blockly.Python['procedures_defreturn'] = function(block) { var funcName = Blockly.Python.variableDB_.getName( block.getFieldValue('NAME'), Blockly.Procedures.NAME_TYPE); var branch = Blockly.Python.statementToCode(block, 'STACK'); // console.log("procedures.js-29; branch:\n"+ branch); if (Blockly.Python.STATEMENT_PREFIX) { branch = Blockly.Python.prefixLines( Blockly.Python.STATEMENT_PREFIX.replace(/%1/g, '\'' + block.id + '\''), Blockly.Python.INDENT) + branch; } if (Blockly.Python.INFINITE_LOOP_TRAP) { branch = Blockly.Python.INFINITE_LOOP_TRAP.replace(/%1/g, '\'' + block.id + '\'') + branch; } var returnValue = Blockly.Python.valueToCode(block, 'RETURN', Blockly.Python.ORDER_NONE) || ''; if (returnValue) { returnValue = ' return ' + returnValue + ';\n'; } // Get arguments with type var args = []; for (var x = 0; x < block.arguments_.length; x++) { args[x] = Blockly.Python.getArduinoType_(block.getArgType(block.arguments_[x])) + ' ' + Blockly.Python.variableDB_.getName(block.arguments_[x], Blockly.Variables.NAME_TYPE); } // Get return type var returnType = Blockly.Types.NULL; if (block.getReturnType) { returnType = block.getReturnType(); } returnType = Blockly.Python.getArduinoType_(returnType); // Construct code var code = returnType + ' ' + funcName + '(' + args.join(', ') + ') {\n' + branch + returnValue + '}'; code = Blockly.Python.scrub_(block, code); Blockly.Python.userFunctions_[funcName] = code; return null; }; /** * Code generator to create a function without a return value. * It uses the same code as with return value, as it will maintain the void * type. * Arduino code: void functionname { } */ Blockly.Python['procedures_defnoreturn'] = Blockly.Python['procedures_defreturn']; /** * Code generator to create a function call with a return value. * Arduino code: loop { functionname() } * @param {!Blockly.Block} block Block to generate the code from. * @return {array} Completed code with order of operation. */ Blockly.Python['procedures_callreturn'] = function(block) { var funcName = Blockly.Python.variableDB_.getName( block.getFieldValue('NAME'), Blockly.Procedures.NAME_TYPE); var args = []; for (var x = 0; x < block.arguments_.length; x++) { args[x] = Blockly.Python.valueToCode(block, 'ARG' + x, Blockly.Python.ORDER_NONE) || 'null'; } var code = funcName + '(' + args.join(', ') + ')'; return [code, Blockly.Python.ORDER_UNARY_POSTFIX]; }; /** * Code generator to create a function call without a return value. * Arduino code: loop { functionname() } * @param {!Blockly.Block} block Block to generate the code from. * @return {string} Completed code. */ Blockly.Python['procedures_callnoreturn'] = function(block) { var funcName = Blockly.Python.variableDB_.getName( block.getFieldValue('NAME'), Blockly.Procedures.NAME_TYPE); var args = []; for (var x = 0; x < block.arguments_.length; x++) { args[x] = Blockly.Python.valueToCode(block, 'ARG' + x, Blockly.Python.ORDER_NONE) || 'null'; } var code = funcName + '(' + args.join(', ') + ');\n'; return code; }; /** * Code generator to create a conditional (X) return value (Y) for a function. * Arduino code: if (X) { return Y; } * @param {!Blockly.Block} block Block to generate the code from. * @return {string} Completed code. */ Blockly.Python['procedures_ifreturn'] = function(block) { var condition = Blockly.Python.valueToCode(block, 'CONDITION', Blockly.Python.ORDER_NONE) || 'false'; var code = 'if (' + condition + ') {\n'; if (block.hasReturnValue_) { var value = Blockly.Python.valueToCode(block, 'VALUE', Blockly.Python.ORDER_NONE) || 'null'; code += ' return ' + value + ';\n'; } else { code += ' return;\n'; } code += '}\n'; return code; }; /** * Code generator to add code into the setup() and loop() functions. * Its use is not mandatory, but necessary to add manual code to setup(). * @param {!Blockly.Block} block Block to generate the code from. * @return {string} Completed code. */ Blockly.Python['arduino_functions'] = function(block) { // Edited version of Blockly.Generator.prototype.statementToCode function statementToCodeNoTab(block, name) { var targetBlock = block.getInputTargetBlock(name); var code = Blockly.Python.blockToCode(targetBlock); if (!goog.isString(code)) { throw 'Expecting code from statement block "' + targetBlock.type + '".'; } return code; } var setupBranch = Blockly.Python.statementToCode(block, 'SETUP_FUNC'); //var setupCode = Blockly.Python.scrub_(block, setupBranch); No comment block if (setupBranch) { Blockly.Python.addSetup('userSetupCode', setupBranch, true); } var loopBranch = statementToCodeNoTab(block, 'LOOP_FUNC'); //var loopcode = Blockly.Python.scrub_(block, loopBranch); No comment block return loopBranch; };