loops.js 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. /**
  2. * @license
  3. * Visual Blocks Language
  4. *
  5. * Copyright 2012 Google Inc.
  6. * https://blockly.googlecode.com/
  7. *
  8. * Licensed under the Apache License, Version 2.0 (the "License");
  9. * you may not use this file except in compliance with the License.
  10. * You may obtain a copy of the License at
  11. *
  12. * http://www.apache.org/licenses/LICENSE-2.0
  13. *
  14. * Unless required by applicable law or agreed to in writing, software
  15. * distributed under the License is distributed on an "AS IS" BASIS,
  16. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17. * See the License for the specific language governing permissions and
  18. * limitations under the License.
  19. */
  20. /**
  21. * @fileoverview Generating OpenSCAD for loop blocks.
  22. * @author fraser@google.com (Neil Fraser) modified by Jayod
  23. * unimplemented blocks copied from OpenJSCAD are commented out
  24. */
  25. 'use strict';
  26. goog.provide('Blockly.OpenSCAD.loops');
  27. goog.require('Blockly.OpenSCAD');
  28. /*
  29. Blockly.OpenSCAD['controls_repeat'] = function(block) {
  30. // Repeat n times (internal number).
  31. var repeats = Number(block.getFieldValue('TIMES'));
  32. var branch = Blockly.OpenSCAD.statementToCode(block, 'DO');
  33. if (Blockly.OpenSCAD.INFINITE_LOOP_TRAP) {
  34. branch = Blockly.OpenSCAD.INFINITE_LOOP_TRAP.replace(/%1/g,
  35. '\'' + block.id + '\'') + branch;
  36. }
  37. var loopVar = Blockly.OpenSCAD.variableDB_.getDistinctName(
  38. 'count', Blockly.Variables.NAME_TYPE);
  39. var code = 'for (var ' + loopVar + ' = 0; ' +
  40. loopVar + ' < ' + repeats + '; ' +
  41. loopVar + '++) {\n' +
  42. branch + '}\n';
  43. return code;
  44. };
  45. */
  46. Blockly.OpenSCAD['controls_repeat_ext'] = function(block) {
  47. // Repeat n times (external number).
  48. var repeats = Blockly.OpenSCAD.valueToCode(block, 'TIMES',
  49. Blockly.OpenSCAD.ORDER_ASSIGNMENT) || '0';
  50. var branch = Blockly.OpenSCAD.statementToCode(block, 'DO');
  51. if (Blockly.OpenSCAD.INFINITE_LOOP_TRAP) {
  52. branch = Blockly.OpenSCAD.INFINITE_LOOP_TRAP.replace(/%1/g,
  53. '\'' + block.id + '\'') + branch;
  54. }
  55. var code = '';
  56. var loopVar = Blockly.OpenSCAD.variableDB_.getDistinctName(
  57. 'count', Blockly.Variables.NAME_TYPE);
  58. var endVar = repeats - 1;
  59. if (!repeats.match(/^\w+$/) && !Blockly.isNumber(repeats)) {
  60. var endVar = Blockly.OpenSCAD.variableDB_.getDistinctName(
  61. 'repeat_end', Blockly.Variables.NAME_TYPE);
  62. code += 'var ' + endVar + ' = ' + repeats + ';\n';
  63. }
  64. // it was too hard to make union work correctly in the parser. Union after a loop to collect objects.
  65. code += 'union() { //end assign\n';
  66. code += 'for (' + loopVar + ' = [0 : ' + endVar + ']) ' + ' {\n' +
  67. branch + '}\n';
  68. code += '} //end assign\n';
  69. return code;
  70. };
  71. /*
  72. Blockly.OpenSCAD['controls_whileUntil'] = function(block) {
  73. // Do while/until loop.
  74. var until = block.getFieldValue('MODE') == 'UNTIL';
  75. var argument0 = Blockly.OpenSCAD.valueToCode(block, 'BOOL',
  76. until ? Blockly.OpenSCAD.ORDER_LOGICAL_NOT :
  77. Blockly.OpenSCAD.ORDER_NONE) || 'false';
  78. var branch = Blockly.OpenSCAD.statementToCode(block, 'DO');
  79. if (Blockly.OpenSCAD.INFINITE_LOOP_TRAP) {
  80. branch = Blockly.OpenSCAD.INFINITE_LOOP_TRAP.replace(/%1/g,
  81. '\'' + block.id + '\'') + branch;
  82. }
  83. if (until) {
  84. argument0 = '!' + argument0;
  85. }
  86. return 'while (' + argument0 + ') {\n' + branch + '}\n';
  87. };
  88. */
  89. Blockly.OpenSCAD['controls_for'] = function(block) {
  90. // For loop.
  91. var variable0 = Blockly.OpenSCAD.variableDB_.getName(
  92. block.getFieldValue('VAR'), Blockly.Variables.NAME_TYPE);
  93. var argument0 = Blockly.OpenSCAD.valueToCode(block, 'FROM',
  94. Blockly.OpenSCAD.ORDER_ASSIGNMENT);
  95. var argument1 = Blockly.OpenSCAD.valueToCode(block, 'TO',
  96. Blockly.OpenSCAD.ORDER_ASSIGNMENT);
  97. var increment = Blockly.OpenSCAD.valueToCode(block, 'BY',
  98. Blockly.OpenSCAD.ORDER_ASSIGNMENT);
  99. var branch = Blockly.OpenSCAD.statementToCode(block, 'DO');
  100. var hull = block.getFieldValue('HULL');
  101. var miss = 0;
  102. if (!argument0) {
  103. argument0 = '0';
  104. miss = 1;
  105. }
  106. if (!argument1) {
  107. argument1 = '0';
  108. miss = 1;
  109. }
  110. if (!increment) {
  111. increment = '1';
  112. miss = 1;
  113. }
  114. if (Blockly.OpenSCAD.INFINITE_LOOP_TRAP) {
  115. branch = Blockly.OpenSCAD.INFINITE_LOOP_TRAP.replace(/%1/g,
  116. '\'' + block.id + '\'') + branch;
  117. }
  118. // missing fields?
  119. if (miss)
  120. Blockscad.missingFields.push(block.id);
  121. var code = '';
  122. var varCode = Blockly.OpenSCAD.returnVarCode(block);
  123. var aC = varCode[0];
  124. var aP = varCode[1];
  125. if (hull == 'FALSE') {
  126. // Jennie - OpenSCAD is weird - increments can never be negative, even
  127. // when you are counting down in a loop. I'll absolute value the increment
  128. // given to make it make sense
  129. //increment = abs(increment);
  130. // it was too hard to make union work correctly in the parser. Union after a loop to collect objects.
  131. code += 'union() { //end assign\n';
  132. code += 'for (' + variable0 + ' = [' + argument0 + ' : ' +
  133. 'abs(' + increment + ') : ' + argument1 + ']';
  134. code += ') {\n' + aC + branch + '\n' + aP + '}\n';
  135. code += '} //end assign\n';
  136. }
  137. else {
  138. // in chainhull, I want to actually loop through to argument1 - (increment),
  139. // because chainhull involves doing a "step ahead" (hulling n with n+increment)
  140. var query = "([^a-z|A-Z])" + variable0 + "(?![a-z|A-Z])";
  141. var re = new RegExp(query, 'g');
  142. // console.log("reg exp = ", re);
  143. var new_string = "("+ variable0 + " + " + increment + ")";
  144. var branch_next = branch.replace(re, "$1" + new_string);
  145. code = "// chain hull\n";
  146. // Jennie - OpenSCAD is weird - increments can never be negative, even
  147. // when you are counting down in a loop. I'll absolute value the increment
  148. // given to make it make sense
  149. //increment = abs(increment);
  150. // it was too hard to make union work correctly in the parser. Union after a loop to collect objects.
  151. code += 'union() { //end assign\n';
  152. code += 'for (' + variable0 + ' = [' + argument0 + ' : ' +
  153. 'abs(' + increment + ') : ' + argument1 + " - " + increment + ']';
  154. code += ') {\n' + aC + ' hull() {\n' + branch + '\n' + branch_next +'\n } // end hull (in loop)' + '\n ' + aP + '} // end loop\n';
  155. code += '} //end assign\n';
  156. }
  157. return code;
  158. };
  159. Blockly.OpenSCAD['controls_for_chainhull'] = function(block) {
  160. // For loop.
  161. var variable0 = Blockly.OpenSCAD.variableDB_.getName(
  162. block.getFieldValue('VAR'), Blockly.Variables.NAME_TYPE);
  163. var argument0 = Blockly.OpenSCAD.valueToCode(block, 'FROM',
  164. Blockly.OpenSCAD.ORDER_ASSIGNMENT);
  165. var argument1 = Blockly.OpenSCAD.valueToCode(block, 'TO',
  166. Blockly.OpenSCAD.ORDER_ASSIGNMENT);
  167. var increment = Blockly.OpenSCAD.valueToCode(block, 'BY',
  168. Blockly.OpenSCAD.ORDER_ASSIGNMENT);
  169. var branch = Blockly.OpenSCAD.statementToCode(block, 'DO');
  170. var miss = 0;
  171. if (!argument0) {
  172. argument0 = '0';
  173. miss = 1;
  174. }
  175. if (!argument1) {
  176. argument1 = '0';
  177. miss = 1;
  178. }
  179. if (!increment) {
  180. increment = '1';
  181. miss = 1;
  182. }
  183. // in chainhull, I want to actually loop through to argument1 - (increment),
  184. // because chainhull involves doing a "step ahead" (hulling n with n+increment)
  185. var query = "([^a-z|A-Z])" + variable0 + "(?![a-z|A-Z])";
  186. var re = new RegExp(query, 'g');
  187. // console.log("reg exp = ", re);
  188. var new_string = "("+ variable0 + " + " + increment + ")";
  189. var branch_next = branch.replace(re, "$1" + new_string);
  190. //branch_next = branch_next.replace(re, new_string);
  191. // console.log("branch = ", branch);
  192. if (Blockly.OpenSCAD.INFINITE_LOOP_TRAP) {
  193. branch = Blockly.OpenSCAD.INFINITE_LOOP_TRAP.replace(/%1/g,
  194. '\'' + block.id + '\'') + branch;
  195. }
  196. // missing fields?
  197. if (miss)
  198. Blockscad.missingFields.push(block.id);
  199. var code;
  200. code = "// chain hull"
  201. // Jennie - OpenSCAD is weird - increments can never be negative, even
  202. // when you are counting down in a loop. I'll absolute value the increment
  203. // given to make it make sense
  204. //increment = abs(increment);
  205. code = 'for (' + variable0 + ' = [' + argument0 + ' : ' +
  206. 'abs(' + increment + ') : ' + argument1 + " - " + increment + ']';
  207. code += ') {\n' + ' hull() {\n' + branch + '\n' + branch_next + '\n }' + '\n}';
  208. return code;
  209. };
  210. /*
  211. Blockly.OpenSCAD['controls_forEach'] = function(block) {
  212. // For each loop.
  213. var variable0 = Blockly.OpenSCAD.variableDB_.getName(
  214. block.getFieldValue('VAR'), Blockly.Variables.NAME_TYPE);
  215. var argument0 = Blockly.OpenSCAD.valueToCode(block, 'LIST',
  216. Blockly.OpenSCAD.ORDER_ASSIGNMENT) || '[]';
  217. var branch = Blockly.OpenSCAD.statementToCode(block, 'DO');
  218. if (Blockly.OpenSCAD.INFINITE_LOOP_TRAP) {
  219. branch = Blockly.OpenSCAD.INFINITE_LOOP_TRAP.replace(/%1/g,
  220. '\'' + block.id + '\'') + branch;
  221. }
  222. var indexVar = Blockly.OpenSCAD.variableDB_.getDistinctName(
  223. variable0 + '_index', Blockly.Variables.NAME_TYPE);
  224. branch = ' ' + variable0 + ' = ' + argument0 + '[' + indexVar + '];\n' +
  225. branch;
  226. var code = 'for (var ' + indexVar + ' in ' + argument0 + ') {\n' +
  227. branch + '}\n';
  228. return code;
  229. };
  230. Blockly.OpenSCAD['controls_flow_statements'] = function(block) {
  231. // Flow statements: continue, break.
  232. switch (block.getFieldValue('FLOW')) {
  233. case 'BREAK':
  234. return 'break;\n';
  235. case 'CONTINUE':
  236. return 'continue;\n';
  237. }
  238. throw 'Unknown flow statement.';
  239. };
  240. */