code_generator.js 35 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211
  1. // iVProg - www.usp.br/line/ivprog
  2. // LInE - Free Education, Private Data
  3. // eslint-disable @typescript-eslint/no-use-before-define
  4. // globals $
  5. import { Types } from "./types";
  6. import * as Models from "./ivprog_elements";
  7. import { LocalizedStrings } from "./../services/localizedStringsService";
  8. import * as Utils from "./utils";
  9. // Code to main function
  10. export function generate () {
  11. $(".ivprog_visual_panel").find(".error_icon").remove();
  12. let code = LocalizedStrings.getUI("program") + " { ";
  13. code += globalsCode();
  14. code += "\n";
  15. let has_error = false;
  16. for (let i = 0; i < window.program_obj.functions.length; i++) {
  17. const n_code = functionsCode(window.program_obj.functions[i]);
  18. if (n_code == null) {
  19. has_error = true;
  20. }
  21. code += n_code;
  22. code += "\n";
  23. }
  24. code += "\n}";
  25. if (has_error) {
  26. return null;
  27. } else {
  28. return code;
  29. }
  30. }
  31. function functionsCode (function_obj) {
  32. let ret = "\n " + LocalizedStrings.getUI("function") + " "; // not \t - using fixed space to indentation
  33. const has_error = false;
  34. switch (function_obj.return_type) {
  35. case Types.INTEGER:
  36. ret += LocalizedStrings.getUI("type_integer");
  37. break;
  38. case Types.REAL:
  39. ret += LocalizedStrings.getUI("type_real");
  40. break;
  41. case Types.TEXT:
  42. ret += LocalizedStrings.getUI("type_text");
  43. break;
  44. case Types.BOOLEAN:
  45. ret += LocalizedStrings.getUI("type_boolean");
  46. break;
  47. case Types.CHAR:
  48. ret += LocalizedStrings.getUI("type_char");
  49. break;
  50. case Types.VOID:
  51. ret += LocalizedStrings.getUI("type_void");
  52. break;
  53. }
  54. ret += " ";
  55. if (function_obj.return_dimensions == 1) {
  56. ret += "[] ";
  57. } else if (function_obj.return_dimensions == 2) {
  58. ret += "[][] ";
  59. }
  60. if (function_obj.is_main) {
  61. ret += LocalizedStrings.getUI("start");
  62. } else {
  63. ret += function_obj.name;
  64. }
  65. ret += " ("; // open parameter to function
  66. for (let j = 0; j < function_obj.parameters_list.length; j++) {
  67. ret += parametersCode(function_obj.parameters_list[j]);
  68. if (j + 1 < function_obj.parameters_list.length) {
  69. ret += ", ";
  70. }
  71. }
  72. ret += ") {"; // close parameters to function
  73. for (let j = 0; j < function_obj.variables_list.length; j++) {
  74. ret += variablesCode(function_obj.variables_list[j]);
  75. }
  76. for (let j = 0; j < function_obj.commands.length; j++) {
  77. //D try {
  78. ret += commandsCode(function_obj.commands[j]);
  79. /* //D } catch (err) {
  80. has_error = true; console.error(err.message); var todos = $('body').find('.command_container');
  81. for (var i = 0; i < todos.length; i++) { if ($(todos[i]).data('command') == function_obj.commands[j]) {
  82. $( todos[i] ).prepend(' <i class="ui icon red exclamation triangle error_icon"></i> '); break;
  83. } } }*/
  84. }
  85. ret += "\n }"; // close function - "\n\t" using fixed space to indentation
  86. if (has_error) {
  87. return null;
  88. } else {
  89. return ret;
  90. }
  91. }
  92. function commandsCode (command_obj, indentation = 2) {
  93. switch (command_obj.type) {
  94. case Models.COMMAND_TYPES.break:
  95. return breaksCode(command_obj, indentation);
  96. case Models.COMMAND_TYPES.comment:
  97. return commentsCode(command_obj, indentation);
  98. case Models.COMMAND_TYPES.reader:
  99. return readersCode(command_obj, indentation);
  100. case Models.COMMAND_TYPES.writer:
  101. return writersCode(command_obj, indentation);
  102. case Models.COMMAND_TYPES.functioncall:
  103. return functioncallsCode(command_obj, indentation);
  104. case Models.COMMAND_TYPES.attribution:
  105. return attributionsCode(command_obj, indentation);
  106. case Models.COMMAND_TYPES.whiletrue:
  107. return whiletruesCode(command_obj, indentation);
  108. case Models.COMMAND_TYPES.dowhiletrue:
  109. return doWhilesCode(command_obj, indentation);
  110. case Models.COMMAND_TYPES.iftrue:
  111. return iftruesCode(command_obj, indentation);
  112. case Models.COMMAND_TYPES.repeatNtimes:
  113. return repeatNtimesCode(command_obj, indentation);
  114. case Models.COMMAND_TYPES.switch:
  115. return switchsCode(command_obj, indentation);
  116. case Models.COMMAND_TYPES.return:
  117. return returnsCode(command_obj, indentation);
  118. }
  119. }
  120. function returnsCode (command_obj, indentation) {
  121. let ret = "\n";
  122. for (let i = 0; i < indentation; i++) {
  123. ret += " "; // "\t" - using fixed space to indentation
  124. }
  125. ret += LocalizedStrings.getUI("text_return");
  126. if (command_obj.variable_value_menu) {
  127. try {
  128. ret += " " + elementExpressionCode(command_obj.variable_value_menu);
  129. //ret += ' ' + variableValueMenuCode(command_obj.variable_value_menu, true);
  130. } catch (err) {
  131. //Empty block
  132. }
  133. }
  134. return ret;
  135. }
  136. function breaksCode (_command_obj, indentation) {
  137. let ret = "\n";
  138. for (let i = 0; i < indentation; i++) {
  139. ret += " "; // "\t" - using fixed space to indentation
  140. }
  141. ret += LocalizedStrings.getUI("text_break");
  142. return ret;
  143. }
  144. // Write Switch code
  145. function switchsCode (command_obj, indentation) {
  146. let ret = "\n";
  147. for (let i = 0; i < indentation; i++) {
  148. ret += " "; // "\t" - using fixed space to indentation
  149. }
  150. ret += LocalizedStrings.getUI("text_code_switch") + "(";
  151. ret += variableValueMenuCode(command_obj.variable);
  152. ret += ") { ";
  153. if (command_obj.cases) {
  154. for (let i = 0; i < command_obj.cases.length; i++) {
  155. ret += switchcasesCode(command_obj.cases[i], indentation + 1);
  156. }
  157. }
  158. ret += "\n";
  159. for (let i = 0; i < indentation; i++) {
  160. ret += " "; // "\t" - using fixed space to indentation
  161. }
  162. ret += "} ";
  163. return ret;
  164. }
  165. function switchcasesCode (switchcase, indentation) {
  166. let ret = "\n";
  167. for (let i = 0; i < indentation; i++) {
  168. ret += " "; // "\t" - using fixed space to indentation
  169. }
  170. ret += LocalizedStrings.getUI("text_code_case") + " ";
  171. ret += variableValueMenuCode(switchcase.variable_value_menu);
  172. ret += " :";
  173. if (switchcase.commands_block) {
  174. for (let i = 0; i < switchcase.commands_block.length; i++) {
  175. ret += commandsCode(switchcase.commands_block[i], indentation + 1);
  176. }
  177. }
  178. return ret;
  179. }
  180. export function repeatNtimesHeader (command_obj) {
  181. let ret = "";
  182. if (command_obj.var_attribution) {
  183. ret += '<span class="repeatN_text_par_1">';
  184. ret += variableValueMenuCode(command_obj.var_attribution);
  185. ret += '</span>';
  186. //leo ret += ` ${LocalizedStrings.getUI("text_code_for_from")} `;
  187. ret += ' ' + LocalizedStrings.getUI("text_code_for_from") + ' ';
  188. ret += '<span class="repeatN_text_par_2">';
  189. ret += variableValueMenuCode(command_obj.expression1);
  190. ret += '</span>';
  191. }
  192. //D var ret1 = LocalizedStrings.getUI("text_code_for_from") + ' ';
  193. //D var ret2 = ` ${LocalizedStrings.getUI("text_code_for_from")} `;
  194. //D console.log("********** code_generator.js: repeatNtimesHeader(.): 1 ret=" + ret1 + "\n" + ret2 + "\n"); //leo remover xxxxxxxxxxx
  195. if (command_obj.expression2) {
  196. //leo ret += ` ${LocalizedStrings.getUI("text_code_for_to")} `;
  197. ret += ' ' + LocalizedStrings.getUI("text_code_for_to") + ' ';
  198. ret += '<span class="repeatN_text_par_3">';
  199. ret += variableValueMenuCode(command_obj.expression2);
  200. ret += '</span>';
  201. }
  202. if (command_obj.expression3) {
  203. //leo ret += ` ${LocalizedStrings.getUI("text_code_for_pass")} `;
  204. ret += ' ' + LocalizedStrings.getUI("text_code_for_pass") + ' ';
  205. ret += '<span class="repeatN_text_par_4">';
  206. switch (command_obj.expression3.itens[1]) {
  207. case Models.ARITHMETIC_TYPES.plus:
  208. ret += " +";
  209. break;
  210. case Models.ARITHMETIC_TYPES.minus:
  211. ret += " -";
  212. break;
  213. }
  214. ret += variableValueMenuCode(command_obj.expression3.itens[2]);
  215. ret += '</span>';
  216. }
  217. return ret;
  218. }
  219. function repeatNtimesCode (command_obj, indentation) {
  220. let ret = "\n";
  221. for (let i = 0; i < indentation; i++) {
  222. ret += " "; // "\t" - using fixed space to indentation
  223. }
  224. ret += LocalizedStrings.getUI("text_for") + " ";
  225. if (command_obj.var_attribution) {
  226. ret += variableValueMenuCode(command_obj.var_attribution);
  227. ret += ` ${LocalizedStrings.getUI("text_code_for_from")} `;
  228. ret += variableValueMenuCode(command_obj.expression1);
  229. }
  230. if (command_obj.expression2) {
  231. ret += ` ${LocalizedStrings.getUI("text_code_for_to")} `;
  232. ret += variableValueMenuCode(command_obj.expression2);
  233. }
  234. if (command_obj.expression3) {
  235. ret += ` ${LocalizedStrings.getUI("text_code_for_pass")} `;
  236. switch (command_obj.expression3.itens[1]) {
  237. case Models.ARITHMETIC_TYPES.plus:
  238. ret += " +";
  239. break;
  240. case Models.ARITHMETIC_TYPES.minus:
  241. ret += " -";
  242. break;
  243. }
  244. ret += variableValueMenuCode(command_obj.expression3.itens[2]);
  245. }
  246. ret += " { ";
  247. if (command_obj.commands_block) {
  248. for (let i = 0; i < command_obj.commands_block.length; i++) {
  249. ret += commandsCode(command_obj.commands_block[i], indentation + 1);
  250. }
  251. }
  252. ret += "\n";
  253. for (let i = 0; i < indentation; i++) {
  254. ret += " "; // "\t" - using fixed space to indentation
  255. }
  256. ret += "}";
  257. return ret;
  258. }
  259. // Write IfElse code
  260. function iftruesCode (command_obj, indentation) {
  261. let ret = "\n";
  262. for (let i = 0; i < indentation; i++) {
  263. ret += " "; // "\t" - using fixed space to indentation
  264. }
  265. ret += LocalizedStrings.getUI("text_if");
  266. if (!command_obj.expression) {
  267. Utils.renderErrorMessage(command_obj.expression.dom_object, LocalizedStrings.getUI("inform_valid_expression"));
  268. } else {
  269. ret += "(";
  270. ret += elementExpressionCode(command_obj.expression);
  271. ret += ")";
  272. }
  273. /*switch (command_obj.expression.expression.type) {
  274. case Models.EXPRESSION_TYPES.exp_logic: ret += logicExpressionCode(command_obj.expression.expression); break;
  275. case Models.EXPRESSION_TYPES.exp_arithmetic: ret += arithmeticExpressionCode(command_obj.expression.expression); break;
  276. }*/
  277. ret += " { ";
  278. if (command_obj.commands_block) {
  279. for (let i = 0; i < command_obj.commands_block.length; i++) {
  280. ret += commandsCode(command_obj.commands_block[i], indentation + 1);
  281. }
  282. }
  283. ret += "\n";
  284. for (let i = 0; i < indentation; i++) {
  285. ret += " "; // "\t" - using fixed space to indentation
  286. }
  287. ret += "} " + LocalizedStrings.getUI("text_else") + " {";
  288. if (command_obj.commands_else) {
  289. for (let i = 0; i < command_obj.commands_else.length; i++) {
  290. ret += commandsCode(command_obj.commands_else[i], indentation + 1);
  291. }
  292. }
  293. ret += "\n";
  294. for (let i = 0; i < indentation; i++) {
  295. ret += " "; // "\t" - using fixed space to indentation
  296. }
  297. ret += "}";
  298. return ret;
  299. } // function iftruesCode(command_obj, indentation)
  300. function doWhilesCode (command_obj, indentation) {
  301. let ret = "\n";
  302. for (let i = 0; i < indentation; i++) {
  303. ret += " "; // "\t" - using fixed space to indentation
  304. }
  305. ret += LocalizedStrings.getUI("text_code_do") + " { ";
  306. if (command_obj.commands_block) {
  307. for (let i = 0; i < command_obj.commands_block.length; i++) {
  308. ret += commandsCode(command_obj.commands_block[i], indentation + 1);
  309. }
  310. }
  311. ret += "\n";
  312. for (let i = 0; i < indentation; i++) {
  313. ret += " "; // "\t" - using fixed space to indentation
  314. }
  315. ret += "} " + LocalizedStrings.getUI("text_code_do_until");
  316. if (!command_obj.expression) {
  317. Utils.renderErrorMessage(command_obj.expression.dom_object, LocalizedStrings.getUI("inform_valid_expression"));
  318. }
  319. /*switch (command_obj.expression.expression.type) {
  320. case Models.EXPRESSION_TYPES.exp_logic: ret += logicExpressionCode(command_obj.expression.expression); break;
  321. case Models.EXPRESSION_TYPES.exp_arithmetic: ret += arithmeticExpressionCode(command_obj.expression.expression); break;
  322. }*/
  323. if (command_obj.expression) {
  324. ret += "(";
  325. ret += elementExpressionCode(command_obj.expression);
  326. ret += ")";
  327. }
  328. return ret;
  329. } // function doWhilesCode(command_obj, indentation)
  330. function whiletruesCode (command_obj, indentation) {
  331. let ret = "\n";
  332. for (let i = 0; i < indentation; i++) {
  333. ret += " "; // "\t" - using fixed space to indentation
  334. }
  335. ret += LocalizedStrings.getUI("text_code_while");
  336. if (!command_obj.expression) {
  337. Utils.renderErrorMessage(command_obj.expression.dom_object, LocalizedStrings.getUI("inform_valid_expression"));
  338. }
  339. /*switch (command_obj.expression.expression.type) {
  340. case Models.EXPRESSION_TYPES.exp_logic: ret += logicExpressionCode(command_obj.expression.expression); break;
  341. case Models.EXPRESSION_TYPES.exp_arithmetic: ret += arithmeticExpressionCode(command_obj.expression.expression); break;
  342. }*/
  343. if (command_obj.expression) {
  344. ret += "(";
  345. ret += elementExpressionCode(command_obj.expression);
  346. ret += ")";
  347. }
  348. ret += " { ";
  349. if (command_obj.commands_block) {
  350. for (let i = 0; i < command_obj.commands_block.length; i++) {
  351. ret += commandsCode(command_obj.commands_block[i], indentation + 1);
  352. }
  353. }
  354. ret += "\n";
  355. for (let i = 0; i < indentation; i++) {
  356. ret += " "; // "\t" - using fixed space to indentation
  357. }
  358. ret += "}";
  359. return ret;
  360. } // function whiletruesCode(command_obj, indentation)
  361. function logicExpressionCode (expression) {
  362. let ret = "(";
  363. if (expression.first_operand.type == Models.EXPRESSION_TYPES.exp_logic) {
  364. ret += logicExpressionCode(expression.first_operand);
  365. } else if (
  366. expression.first_operand.type == Models.EXPRESSION_TYPES.exp_arithmetic
  367. ) {
  368. ret += arithmeticExpressionCode(expression.first_operand);
  369. } else {
  370. ret += variableValueMenuCode(expression.first_operand);
  371. }
  372. if (expression.operator) {
  373. switch (expression.operator) {
  374. case Models.LOGIC_COMPARISON.equals_to:
  375. ret += " == ";
  376. break;
  377. case Models.LOGIC_COMPARISON.not_equals_to:
  378. ret += " != ";
  379. break;
  380. case Models.LOGIC_COMPARISON.and:
  381. ret += " && ";
  382. break;
  383. case Models.LOGIC_COMPARISON.or:
  384. ret += " || ";
  385. break;
  386. }
  387. if (expression.second_operand.type == Models.EXPRESSION_TYPES.exp_logic) {
  388. ret += logicExpressionCode(expression.second_operand);
  389. } else if (
  390. expression.second_operand.type == Models.EXPRESSION_TYPES.exp_arithmetic
  391. ) {
  392. ret += arithmeticExpressionCode(expression.second_operand);
  393. } else {
  394. ret += variableValueMenuCode(expression.second_operand);
  395. }
  396. }
  397. ret += ")";
  398. return ret;
  399. } // function logicExpressionCode(expression)
  400. function arithmeticExpressionCode (expression) {
  401. let ret = "(";
  402. if (expression.first_operand.type == Models.EXPRESSION_TYPES.exp_logic) {
  403. ret += logicExpressionCode(expression.first_operand);
  404. } else if (
  405. expression.first_operand.type == Models.EXPRESSION_TYPES.exp_arithmetic
  406. ) {
  407. ret += arithmeticExpressionCode(expression.first_operand);
  408. } else {
  409. ret += variableValueMenuCode(expression.first_operand);
  410. }
  411. switch (expression.operator) {
  412. case Models.ARITHMETIC_COMPARISON.greater_than:
  413. ret += " > ";
  414. break;
  415. case Models.ARITHMETIC_COMPARISON.less_than:
  416. ret += " < ";
  417. break;
  418. case Models.ARITHMETIC_COMPARISON.equals_to:
  419. ret += " == ";
  420. break;
  421. case Models.ARITHMETIC_COMPARISON.not_equals_to:
  422. ret += " != ";
  423. break;
  424. case Models.ARITHMETIC_COMPARISON.greater_than_or_equals_to:
  425. ret += " >= ";
  426. break;
  427. case Models.ARITHMETIC_COMPARISON.less_than_or_equals_to:
  428. ret += " <= ";
  429. break;
  430. }
  431. if (expression.second_operand.type == Models.EXPRESSION_TYPES.exp_logic) {
  432. ret += logicExpressionCode(expression.second_operand);
  433. } else if (
  434. expression.second_operand.type == Models.EXPRESSION_TYPES.exp_arithmetic
  435. ) {
  436. ret += arithmeticExpressionCode(expression.second_operand);
  437. } else {
  438. ret += variableValueMenuCode(expression.second_operand);
  439. }
  440. ret += ")";
  441. return ret;
  442. } // function arithmeticExpressionCode(expression)
  443. function attributionsCode (command_obj, indentation) {
  444. let ret = "\n";
  445. for (let i = 0; i < indentation; i++) {
  446. ret += " "; // "\t" - using fixed space to indentation
  447. }
  448. ret += variableValueMenuCode(command_obj.variable) + " <- ";
  449. /*for (var i = 0; i < command_obj.expression.length; i++) { ret += elementExpressionCode(command_obj.expression[i]); }*/
  450. ret += elementExpressionCode(command_obj.expression);
  451. return ret;
  452. }
  453. export function elementExpressionCode (expression_obj) {
  454. let ret = "";
  455. for (let i = 0; i < expression_obj.length; i++) {
  456. if (expression_obj[i].type) {
  457. ret += variableValueMenuCode(expression_obj[i]);
  458. } else if (expression_obj[i].type_op) {
  459. switch (expression_obj[i].item) {
  460. case Models.ARITHMETIC_TYPES.plus:
  461. ret += " + ";
  462. break;
  463. case Models.ARITHMETIC_TYPES.minus:
  464. ret += " - ";
  465. break;
  466. case Models.ARITHMETIC_TYPES.multiplication:
  467. ret += " * ";
  468. break;
  469. case Models.ARITHMETIC_TYPES.division:
  470. ret += " / ";
  471. break;
  472. case Models.ARITHMETIC_TYPES.module:
  473. ret += " % ";
  474. break;
  475. case Models.LOGIC_COMPARISON.equals_to:
  476. ret += " == ";
  477. break;
  478. case Models.LOGIC_COMPARISON.not_equals_to:
  479. ret += " != ";
  480. break;
  481. case Models.LOGIC_COMPARISON.and:
  482. ret += " " + LocalizedStrings.getUI("logic_operator_and") + " ";
  483. break;
  484. case Models.LOGIC_COMPARISON.or:
  485. ret += " " + LocalizedStrings.getUI("logic_operator_or") + " ";
  486. break;
  487. case Models.LOGIC_COMPARISON.not:
  488. ret += " " + LocalizedStrings.getUI("logic_operator_not") + " ";
  489. break;
  490. case Models.ARITHMETIC_COMPARISON.greater_than:
  491. ret += " > ";
  492. break;
  493. case Models.ARITHMETIC_COMPARISON.less_than:
  494. ret += " < ";
  495. break;
  496. case Models.ARITHMETIC_COMPARISON.greater_than_or_equals_to:
  497. ret += " >= ";
  498. break;
  499. case Models.ARITHMETIC_COMPARISON.less_than_or_equals_to:
  500. ret += " <= ";
  501. break;
  502. case Models.EXPRESSION_TYPES.write_sep:
  503. ret += ', " ", ';
  504. break;
  505. }
  506. } else {
  507. ret += " " + expression_obj[i] + " ";
  508. }
  509. }
  510. return ret;
  511. } // export function elementExpressionCode(expression_obj)
  512. function functioncallsCode (command_obj, indentation) {
  513. let ret = "\n";
  514. for (let i = 0; i < indentation; i++) {
  515. ret += " "; // "\t" - using fixed space to indentation
  516. }
  517. ret += variableValueMenuCode(command_obj.function_called);
  518. return ret;
  519. }
  520. // Presents "write(.)" command in iVProg graphical interface
  521. function readersCode (command_obj, indentation) {
  522. let ret = "\n";
  523. for (let i = 0; i < indentation; i++) {
  524. ret += " "; // "\t" - using fixed space to indentation
  525. }
  526. ret += LocalizedStrings.getUI("text_command_read") + "("; // open
  527. ret += variableValueMenuCode(command_obj.variable_value_menu);
  528. ret += ")"; // close
  529. return ret;
  530. }
  531. export function variableValueMenuCode (variable_obj, is_return = false) {
  532. let ret = "";
  533. try {
  534. if (variable_obj.function_called) {
  535. if (variable_obj.function_called.name) {
  536. ret += variable_obj.function_called.name + "("; // open
  537. } else {
  538. ret += LocalizedStrings.translateInternalFunction(variable_obj.function_called.identifier, variable_obj.function_called.category) + "(";
  539. }
  540. if (variable_obj.parameters_list) {
  541. for (let i = 0; i < variable_obj.parameters_list.length; i++) {
  542. ret += variableValueMenuCode(variable_obj.parameters_list[i]);
  543. if (i + 1 < variable_obj.parameters_list.length) {
  544. ret += ", ";
  545. }
  546. }
  547. }
  548. ret += ")"; // close
  549. //D console.log("********** code_generator.js: variableValueMenuCode(.): ret=" + ret); //leo remover xxxxxxxxxxx
  550. } else if (variable_obj.content.type) {
  551. ret += variable_obj.content.name;
  552. if (
  553. variable_obj.content.dimensions == 1 &&
  554. variable_obj.dimensions != 1
  555. ) {
  556. ret += "[" + variableValueMenuCode(variable_obj.column) + "]"; // array
  557. }
  558. if (variable_obj.content.dimensions == 2 && variable_obj.dimensions != 2 && variable_obj.reference_dimensions == 1) {
  559. ret += "[" + variableValueMenuCode(variable_obj.row) + "]"; // array
  560. } else if (variable_obj.content.dimensions == 2 && variable_obj.dimensions != 2) {
  561. ret += "[" + variableValueMenuCode(variable_obj.row) + "]"; // array
  562. ret += "[" + variableValueMenuCode(variable_obj.column) + "]"; // array
  563. }
  564. } else {
  565. const content = String(variable_obj.content);
  566. if (isNaN(content)) {
  567. // console.debug("Content length: ", content.length);
  568. // console.debug("Char code at 0", content.charCodeAt(0));
  569. const isBackslash = content.charCodeAt(0) === 92;
  570. if (content.length === 1 || (content.length === 2 && isBackslash)) {
  571. ret += `'${content}'`;
  572. } else {
  573. ret += '"' + variable_obj.content + '"';
  574. }
  575. } else if (content.length == 0) {
  576. ret += '""';
  577. } else if (content.trim().length == 0) {
  578. ret += '"' + content + '"';
  579. } else {
  580. ret += variable_obj.content;
  581. }
  582. }
  583. } catch (err) {
  584. if (!is_return) {
  585. Utils.renderErrorMessage(variable_obj.dom_object, LocalizedStrings.getUI("inform_valid_content"));
  586. throw err;
  587. }
  588. }
  589. return ret;
  590. } // export function variableValueMenuCode(variable_obj, is_return = false)
  591. // Write to file command "write(.)"
  592. function writersCode (command_obj, indentation) {
  593. let ret = "\n";
  594. for (let i = 0; i < indentation; i++) {
  595. ret += " "; // "\t" - using fixed space to indentation
  596. }
  597. ret += LocalizedStrings.getUI("text_command_write") + "(";
  598. /*for (var i = 0; i < command_obj.content.length; i++) {
  599. ret += variableValueMenuCode(command_obj.content[i]);
  600. if ((i + 1) < command_obj.content.length) { ret += ' + ';}
  601. }*/
  602. ret += elementExpressionCode(command_obj.content);
  603. if (command_obj.newline) {
  604. ret += ', "\\n"';
  605. }
  606. ret += ") ";
  607. return ret;
  608. }
  609. function commentsCode (command_obj, indentation) {
  610. let ret = "\n";
  611. for (let i = 0; i < indentation; i++) {
  612. ret += " "; // "\t" - using fixed space to indentation
  613. }
  614. ret += "// ";
  615. ret += command_obj.comment_text.content;
  616. return ret;
  617. }
  618. function parametersCode (parameter_obj) {
  619. let ret = "";
  620. switch (parameter_obj.type) {
  621. case Types.INTEGER:
  622. ret += " " + LocalizedStrings.getUI("type_integer") + " ";
  623. break;
  624. case Types.REAL:
  625. ret += " " + LocalizedStrings.getUI("type_real") + " ";
  626. break;
  627. case Types.TEXT:
  628. ret += " " + LocalizedStrings.getUI("type_text") + " ";
  629. break;
  630. case Types.BOOLEAN:
  631. ret += " " + LocalizedStrings.getUI("type_boolean") + " ";
  632. break;
  633. case Types.CHAR:
  634. ret += " " + LocalizedStrings.getUI("type_char") + " ";
  635. break;
  636. }
  637. if (parameter_obj.reference)
  638. ret += "&";
  639. ret += parameter_obj.name + "";
  640. if (parameter_obj.dimensions == 1) {
  641. ret += " []";
  642. } else if (parameter_obj.dimensions == 2) {
  643. ret += " [][]";
  644. }
  645. return ret;
  646. }
  647. // Write variable declaration code
  648. function variablesCode (variable_obj) {
  649. let ret = "";
  650. const temp = variable_obj;
  651. ret += "\n "; // "\n\t\n" - using fixed space to indentation (adjust to the function indentation)
  652. if (temp.is_constant) {
  653. ret += "const ";
  654. }
  655. switch (temp.type) {
  656. case Types.INTEGER:
  657. ret += LocalizedStrings.getUI("type_integer") + " ";
  658. break;
  659. case Types.REAL:
  660. ret += LocalizedStrings.getUI("type_real") + " ";
  661. break;
  662. case Types.TEXT:
  663. ret += LocalizedStrings.getUI("type_text") + " ";
  664. break;
  665. case Types.BOOLEAN:
  666. ret += LocalizedStrings.getUI("type_boolean") + " ";
  667. break;
  668. case Types.CHAR:
  669. ret += LocalizedStrings.getUI("type_char") + " ";
  670. break;
  671. }
  672. ret += temp.name + " ";
  673. //D console.log("********** code_generator.js: variablesCode(.): ret=|" + ret + "|"); //leo remover xxxxxxxxxxx
  674. if (temp.dimensions == 1) {
  675. ret += "[" + temp.columns + "] ";
  676. switch (temp.type) {
  677. case Types.INTEGER:
  678. ret += "<- {";
  679. for (let j = 0; j < temp.value.length; j++) {
  680. ret += temp.value[j];
  681. if (j + 1 < temp.value.length) {
  682. ret += ", ";
  683. }
  684. }
  685. ret += "}";
  686. break;
  687. case Types.REAL:
  688. ret += "<- {";
  689. for (let j = 0; j < temp.value.length; j++) {
  690. ret += parseFloat(temp.value[j]).toFixed(2);
  691. if (j + 1 < temp.value.length) {
  692. ret += ", ";
  693. }
  694. }
  695. ret += "}";
  696. break;
  697. case Types.TEXT:
  698. ret += "<- {";
  699. for (let j = 0; j < temp.value.length; j++) {
  700. ret += '"' + temp.value[j] + '"';
  701. if (j + 1 < temp.value.length) {
  702. ret += ", ";
  703. }
  704. }
  705. ret += "}";
  706. break;
  707. case Types.BOOLEAN:
  708. ret += "<- {";
  709. for (let j = 0; j < temp.value.length; j++) {
  710. if (temp.value[j]) {
  711. ret += LocalizedStrings.getUI("logic_value_true");
  712. } else {
  713. ret += LocalizedStrings.getUI("logic_value_false");
  714. }
  715. if (j + 1 < temp.value.length) {
  716. ret += ", ";
  717. }
  718. }
  719. ret += "}";
  720. break;
  721. case Types.CHAR:
  722. ret += "<- {";
  723. for (let j = 0; j < temp.value.length; j++) {
  724. ret += "'" + temp.value[j] + "'";
  725. if (j + 1 < temp.value.length) {
  726. ret += ", ";
  727. }
  728. }
  729. ret += "}";
  730. break;
  731. }
  732. } else if (temp.dimensions == 2) {
  733. ret += "[" + temp.rows + "][" + temp.columns + "] ";
  734. switch (temp.type) {
  735. case Types.INTEGER:
  736. ret += "<- {";
  737. for (let j = 0; j < temp.rows; j++) {
  738. ret += "{";
  739. for (let k = 0; k < temp.columns; k++) {
  740. ret += temp.value[j][k];
  741. if (k + 1 < temp.columns) {
  742. ret += ", ";
  743. }
  744. }
  745. ret += "}";
  746. if (j + 1 < temp.rows) {
  747. ret += ", ";
  748. }
  749. }
  750. ret += "}";
  751. break;
  752. case Types.REAL:
  753. ret += "<- {";
  754. for (let j = 0; j < temp.rows; j++) {
  755. ret += "{";
  756. for (let k = 0; k < temp.columns; k++) {
  757. ret += parseFloat(temp.value[j][k]).toFixed(2);
  758. if (k + 1 < temp.columns) {
  759. ret += ", ";
  760. }
  761. }
  762. ret += "}";
  763. if (j + 1 < temp.rows) {
  764. ret += ", ";
  765. }
  766. }
  767. ret += "}";
  768. break;
  769. case Types.TEXT:
  770. ret += "<- {";
  771. for (let j = 0; j < temp.rows; j++) {
  772. ret += "{";
  773. for (let k = 0; k < temp.columns; k++) {
  774. ret += '"' + temp.value[j][k] + '"';
  775. if (k + 1 < temp.columns) {
  776. ret += ", ";
  777. }
  778. }
  779. ret += "}";
  780. if (j + 1 < temp.rows) {
  781. ret += ", ";
  782. }
  783. }
  784. ret += "}";
  785. break;
  786. case Types.BOOLEAN:
  787. ret += "<- {";
  788. for (let j = 0; j < temp.rows; j++) {
  789. ret += "{";
  790. for (let k = 0; k < temp.columns; k++) {
  791. if (temp.value[j][k]) {
  792. ret += LocalizedStrings.getUI("logic_value_true");
  793. } else {
  794. ret += LocalizedStrings.getUI("logic_value_false");
  795. }
  796. if (k + 1 < temp.columns) {
  797. ret += ", ";
  798. }
  799. }
  800. ret += "}";
  801. if (j + 1 < temp.rows) {
  802. ret += ", ";
  803. }
  804. }
  805. ret += "}";
  806. break;
  807. case Types.CHAR:
  808. ret += "<- {";
  809. for (let j = 0; j < temp.rows; j++) {
  810. ret += "{";
  811. for (let k = 0; k < temp.columns; k++) {
  812. ret += "'" + temp.value[j][k] + "'";
  813. if (k + 1 < temp.columns) {
  814. ret += ", ";
  815. }
  816. }
  817. ret += "}";
  818. if (j + 1 < temp.rows) {
  819. ret += ", ";
  820. }
  821. }
  822. ret += "}";
  823. break;
  824. }
  825. } else {
  826. switch (temp.type) {
  827. case Types.INTEGER:
  828. ret += "<- " + temp.value;
  829. break;
  830. case Types.REAL:
  831. ret += "<- " + parseFloat(temp.value).toFixed(2);
  832. break;
  833. case Types.TEXT:
  834. ret += '<- "' + temp.value + '"';
  835. break;
  836. case Types.BOOLEAN:
  837. ret += "<- ";
  838. if (temp.value) {
  839. ret += LocalizedStrings.getUI("logic_value_true");
  840. } else {
  841. ret += LocalizedStrings.getUI("logic_value_false");
  842. }
  843. break;
  844. case Types.CHAR:
  845. ret += "<- '" + temp.value + "'";
  846. break;
  847. }
  848. }
  849. return ret;
  850. } // function variablesCode(variable_obj)
  851. function globalsCode () {
  852. let ret = "";
  853. if (window.program_obj.globals) {
  854. for (let i = 0; i < window.program_obj.globals.length; i++) {
  855. const temp = window.program_obj.globals[i];
  856. ret += " "; // "\t" - using fixed space to indentation
  857. if (temp.is_constant) {
  858. ret += "const "; //TODO Internacionalizar - insert it in ./ivprog/i18n/ui.csv
  859. }
  860. switch (temp.type) {
  861. case Types.INTEGER:
  862. ret += LocalizedStrings.getUI("type_integer");
  863. break;
  864. case Types.REAL:
  865. ret += LocalizedStrings.getUI("type_real");
  866. break;
  867. case Types.TEXT:
  868. ret += LocalizedStrings.getUI("type_text");
  869. break;
  870. case Types.BOOLEAN:
  871. ret += LocalizedStrings.getUI("type_boolean");
  872. break;
  873. case Types.CHAR:
  874. ret += LocalizedStrings.getUI("type_char");
  875. break;
  876. }
  877. ret += " " + temp.name + " ";
  878. if (temp.dimensions == 1) {
  879. ret += "[" + temp.columns + "] ";
  880. switch (temp.type) {
  881. case Types.INTEGER:
  882. ret += "<- {";
  883. for (let j = 0; j < temp.value.length; j++) {
  884. ret += temp.value[j];
  885. if (j + 1 < temp.value.length) {
  886. ret += ", ";
  887. }
  888. }
  889. ret += "}";
  890. break;
  891. case Types.REAL:
  892. ret += "<- {";
  893. for (let j = 0; j < temp.value.length; j++) {
  894. ret += parseFloat(temp.value[j]).toFixed(2);
  895. if (j + 1 < temp.value.length) {
  896. ret += ", ";
  897. }
  898. }
  899. ret += "}";
  900. break;
  901. case Types.TEXT:
  902. ret += "<- {";
  903. for (let j = 0; j < temp.value.length; j++) {
  904. ret += '"' + temp.value[j] + '"';
  905. if (j + 1 < temp.value.length) {
  906. ret += ", ";
  907. }
  908. }
  909. ret += "}";
  910. break;
  911. case Types.BOOLEAN:
  912. ret += "<- {";
  913. for (let j = 0; j < temp.value.length; j++) {
  914. if (temp.value[j]) {
  915. ret += LocalizedStrings.getUI("logic_value_true");
  916. } else {
  917. ret += LocalizedStrings.getUI("logic_value_false");
  918. }
  919. if (j + 1 < temp.value.length) {
  920. ret += ", ";
  921. }
  922. }
  923. ret += "}";
  924. break;
  925. case Types.CHAR:
  926. ret += "<- {";
  927. for (let j = 0; j < temp.value.length; j++) {
  928. ret += "'" + temp.value[j] + "'";
  929. if (j + 1 < temp.value.length) {
  930. ret += ", ";
  931. }
  932. }
  933. ret += "}";
  934. break;
  935. }
  936. } else if (temp.dimensions == 2) {
  937. ret += "[" + temp.rows + "][" + temp.columns + "] ";
  938. switch (temp.type) {
  939. case Types.INTEGER:
  940. ret += "<- {";
  941. for (let j = 0; j < temp.rows; j++) {
  942. ret += "{";
  943. for (let k = 0; k < temp.columns; k++) {
  944. ret += temp.value[j][k];
  945. if (k + 1 < temp.columns) {
  946. ret += ", ";
  947. }
  948. }
  949. ret += "}";
  950. if (j + 1 < temp.rows) {
  951. ret += ", ";
  952. }
  953. }
  954. ret += "}";
  955. break;
  956. case Types.REAL:
  957. ret += "<- {";
  958. for (let j = 0; j < temp.rows; j++) {
  959. ret += "{";
  960. for (let k = 0; k < temp.columns; k++) {
  961. ret += parseFloat(temp.value[j][k]).toFixed(2);
  962. if (k + 1 < temp.columns) {
  963. ret += ", ";
  964. }
  965. }
  966. ret += "}";
  967. if (j + 1 < temp.rows) {
  968. ret += ", ";
  969. }
  970. }
  971. ret += "}";
  972. break;
  973. case Types.TEXT:
  974. ret += "<- {";
  975. for (let j = 0; j < temp.rows; j++) {
  976. ret += "{";
  977. for (let k = 0; k < temp.columns; k++) {
  978. ret += '"' + temp.value[j][k] + '"';
  979. if (k + 1 < temp.columns) {
  980. ret += ", ";
  981. }
  982. }
  983. ret += "}";
  984. if (j + 1 < temp.rows) {
  985. ret += ", ";
  986. }
  987. }
  988. ret += "}";
  989. break;
  990. case Types.BOOLEAN:
  991. ret += "<- {";
  992. for (let j = 0; j < temp.rows; j++) {
  993. ret += "{";
  994. for (let k = 0; k < temp.columns; k++) {
  995. if (temp.value[j][k]) {
  996. ret += LocalizedStrings.getUI("logic_value_true");
  997. } else {
  998. ret += LocalizedStrings.getUI("logic_value_false");
  999. }
  1000. if (k + 1 < temp.columns) {
  1001. ret += ", ";
  1002. }
  1003. }
  1004. ret += "}";
  1005. if (j + 1 < temp.rows) {
  1006. ret += ", ";
  1007. }
  1008. }
  1009. ret += "}";
  1010. break;
  1011. case Types.CHAR:
  1012. ret += "<- {";
  1013. for (let j = 0; j < temp.rows; j++) {
  1014. ret += "{";
  1015. for (let k = 0; k < temp.columns; k++) {
  1016. ret += "'" + temp.value[j][k] + "'";
  1017. if (k + 1 < temp.columns) {
  1018. ret += ", ";
  1019. }
  1020. }
  1021. ret += "}";
  1022. if (j + 1 < temp.rows) {
  1023. ret += ", ";
  1024. }
  1025. }
  1026. ret += "}";
  1027. break;
  1028. }
  1029. } else {
  1030. switch (temp.type) {
  1031. case Types.INTEGER:
  1032. ret += "<- " + temp.value;
  1033. break;
  1034. case Types.REAL:
  1035. ret += "<- " + parseFloat(temp.value).toFixed(2);
  1036. break;
  1037. case Types.TEXT:
  1038. ret += '<- "' + temp.value + '"';
  1039. break;
  1040. case Types.BOOLEAN:
  1041. ret += "<- ";
  1042. if (temp.value) {
  1043. ret += LocalizedStrings.getUI("logic_value_true");
  1044. } else {
  1045. ret += LocalizedStrings.getUI("logic_value_false");
  1046. }
  1047. break;
  1048. case Types.CHAR:
  1049. ret += "<- '" + temp.value + "'";
  1050. break;
  1051. }
  1052. }
  1053. }
  1054. }
  1055. return ret;
  1056. } // function globalsCode()