procedures.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. /**
  2. * @license Licensed under the Apache License, Version 2.0 (the "License"):
  3. * http://www.apache.org/licenses/LICENSE-2.0
  4. */
  5. /**
  6. * @fileoverview Generating Arduino code for procedure (function) blocks.
  7. *
  8. * TODO: For now all variables will stay at "int". Once type is implemented
  9. * it needs to be captured on the functions with return.
  10. */
  11. 'use strict';
  12. goog.provide('Blockly.Python.procedures');
  13. goog.require('Blockly.Python');
  14. /**
  15. * Code generator to create a function with a return value (X).
  16. * Arduino code: void functionname { return X }
  17. * @param {!Blockly.Block} block Block to generate the code from.
  18. * @return {null} There is no code added to loop.
  19. */
  20. Blockly.Python['procedures_defreturn'] = function(block) {
  21. var funcName = Blockly.Python.variableDB_.getName(
  22. block.getFieldValue('NAME'), Blockly.Procedures.NAME_TYPE);
  23. var branch = Blockly.Python.statementToCode(block, 'STACK');
  24. // console.log("procedures.js-29; branch:\n"+ branch);
  25. if (Blockly.Python.STATEMENT_PREFIX) {
  26. branch = Blockly.Python.prefixLines(
  27. Blockly.Python.STATEMENT_PREFIX.replace(/%1/g,
  28. '\'' + block.id + '\''), Blockly.Python.INDENT) + branch;
  29. }
  30. if (Blockly.Python.INFINITE_LOOP_TRAP) {
  31. branch = Blockly.Python.INFINITE_LOOP_TRAP.replace(/%1/g,
  32. '\'' + block.id + '\'') + branch;
  33. }
  34. var returnValue = Blockly.Python.valueToCode(block, 'RETURN',
  35. Blockly.Python.ORDER_NONE) || '';
  36. if (returnValue) {
  37. returnValue = ' return ' + returnValue + ';\n';
  38. }
  39. // Get arguments with type
  40. var args = [];
  41. for (var x = 0; x < block.arguments_.length; x++) {
  42. args[x] =
  43. Blockly.Python.getArduinoType_(block.getArgType(block.arguments_[x])) +
  44. ' ' +
  45. Blockly.Python.variableDB_.getName(block.arguments_[x],
  46. Blockly.Variables.NAME_TYPE);
  47. }
  48. // Get return type
  49. var returnType = Blockly.Types.NULL;
  50. if (block.getReturnType) {
  51. returnType = block.getReturnType();
  52. }
  53. returnType = Blockly.Python.getArduinoType_(returnType);
  54. // Construct code
  55. var code = returnType + ' ' + funcName + '(' + args.join(', ') + ') {\n' +
  56. branch + returnValue + '}';
  57. code = Blockly.Python.scrub_(block, code);
  58. Blockly.Python.userFunctions_[funcName] = code;
  59. return null;
  60. };
  61. /**
  62. * Code generator to create a function without a return value.
  63. * It uses the same code as with return value, as it will maintain the void
  64. * type.
  65. * Arduino code: void functionname { }
  66. */
  67. Blockly.Python['procedures_defnoreturn'] =
  68. Blockly.Python['procedures_defreturn'];
  69. /**
  70. * Code generator to create a function call with a return value.
  71. * Arduino code: loop { functionname() }
  72. * @param {!Blockly.Block} block Block to generate the code from.
  73. * @return {array} Completed code with order of operation.
  74. */
  75. Blockly.Python['procedures_callreturn'] = function(block) {
  76. var funcName = Blockly.Python.variableDB_.getName(
  77. block.getFieldValue('NAME'), Blockly.Procedures.NAME_TYPE);
  78. var args = [];
  79. for (var x = 0; x < block.arguments_.length; x++) {
  80. args[x] = Blockly.Python.valueToCode(block, 'ARG' + x,
  81. Blockly.Python.ORDER_NONE) || 'null';
  82. }
  83. var code = funcName + '(' + args.join(', ') + ')';
  84. return [code, Blockly.Python.ORDER_UNARY_POSTFIX];
  85. };
  86. /**
  87. * Code generator to create a function call without a return value.
  88. * Arduino code: loop { functionname() }
  89. * @param {!Blockly.Block} block Block to generate the code from.
  90. * @return {string} Completed code.
  91. */
  92. Blockly.Python['procedures_callnoreturn'] = function(block) {
  93. var funcName = Blockly.Python.variableDB_.getName(
  94. block.getFieldValue('NAME'), Blockly.Procedures.NAME_TYPE);
  95. var args = [];
  96. for (var x = 0; x < block.arguments_.length; x++) {
  97. args[x] = Blockly.Python.valueToCode(block, 'ARG' + x,
  98. Blockly.Python.ORDER_NONE) || 'null';
  99. }
  100. var code = funcName + '(' + args.join(', ') + ');\n';
  101. return code;
  102. };
  103. /**
  104. * Code generator to create a conditional (X) return value (Y) for a function.
  105. * Arduino code: if (X) { return Y; }
  106. * @param {!Blockly.Block} block Block to generate the code from.
  107. * @return {string} Completed code.
  108. */
  109. Blockly.Python['procedures_ifreturn'] = function(block) {
  110. var condition = Blockly.Python.valueToCode(block, 'CONDITION',
  111. Blockly.Python.ORDER_NONE) || 'false';
  112. var code = 'if (' + condition + ') {\n';
  113. if (block.hasReturnValue_) {
  114. var value = Blockly.Python.valueToCode(block, 'VALUE',
  115. Blockly.Python.ORDER_NONE) || 'null';
  116. code += ' return ' + value + ';\n';
  117. } else {
  118. code += ' return;\n';
  119. }
  120. code += '}\n';
  121. return code;
  122. };
  123. /**
  124. * Code generator to add code into the setup() and loop() functions.
  125. * Its use is not mandatory, but necessary to add manual code to setup().
  126. * @param {!Blockly.Block} block Block to generate the code from.
  127. * @return {string} Completed code.
  128. */
  129. Blockly.Python['arduino_functions'] = function(block) {
  130. // Edited version of Blockly.Generator.prototype.statementToCode
  131. function statementToCodeNoTab(block, name) {
  132. var targetBlock = block.getInputTargetBlock(name);
  133. var code = Blockly.Python.blockToCode(targetBlock);
  134. if (!goog.isString(code)) {
  135. throw 'Expecting code from statement block "' + targetBlock.type + '".';
  136. }
  137. return code;
  138. }
  139. var setupBranch = Blockly.Python.statementToCode(block, 'SETUP_FUNC');
  140. //var setupCode = Blockly.Python.scrub_(block, setupBranch); No comment block
  141. if (setupBranch) {
  142. Blockly.Python.addSetup('userSetupCode', setupBranch, true);
  143. }
  144. var loopBranch = statementToCodeNoTab(block, 'LOOP_FUNC');
  145. //var loopcode = Blockly.Python.scrub_(block, loopBranch); No comment block
  146. return loopBranch;
  147. };