// iVProg - www.usp.br/line/ivprog
// LInE - Free Education, Private Data
// eslint-disable @typescript-eslint/no-use-before-define
// globals $
import { Types } from "./types";
import * as Models from "./ivprog_elements";
import { LocalizedStrings } from "./../services/localizedStringsService";
import * as Utils from "./utils";
// Code to main function
export function generate () {
$(".ivprog_visual_panel").find(".error_icon").remove();
let code = LocalizedStrings.getUI("program") + " { ";
code += globalsCode();
code += "\n";
let has_error = false;
for (let i = 0; i < window.program_obj.functions.length; i++) {
const n_code = functionsCode(window.program_obj.functions[i]);
if (n_code == null) {
has_error = true;
}
code += n_code;
code += "\n";
}
code += "\n}";
if (has_error) {
return null;
} else {
return code;
}
}
function functionsCode (function_obj) {
let ret = "\n " + LocalizedStrings.getUI("function") + " "; // not \t - using fixed space to indentation
const has_error = false;
switch (function_obj.return_type) {
case Types.INTEGER:
ret += LocalizedStrings.getUI("type_integer");
break;
case Types.REAL:
ret += LocalizedStrings.getUI("type_real");
break;
case Types.TEXT:
ret += LocalizedStrings.getUI("type_text");
break;
case Types.BOOLEAN:
ret += LocalizedStrings.getUI("type_boolean");
break;
case Types.CHAR:
ret += LocalizedStrings.getUI("type_char");
break;
case Types.VOID:
ret += LocalizedStrings.getUI("type_void");
break;
}
ret += " ";
if (function_obj.return_dimensions == 1) {
ret += "[] ";
} else if (function_obj.return_dimensions == 2) {
ret += "[][] ";
}
if (function_obj.is_main) {
ret += LocalizedStrings.getUI("start");
} else {
ret += function_obj.name;
}
ret += " ("; // open parameter to function
for (let j = 0; j < function_obj.parameters_list.length; j++) {
ret += parametersCode(function_obj.parameters_list[j]);
if (j + 1 < function_obj.parameters_list.length) {
ret += ", ";
}
}
ret += ") {"; // close parameters to function
for (let j = 0; j < function_obj.variables_list.length; j++) {
ret += variablesCode(function_obj.variables_list[j]);
}
for (let j = 0; j < function_obj.commands.length; j++) {
//D try {
ret += commandsCode(function_obj.commands[j]);
/* //D } catch (err) {
has_error = true; console.error(err.message); var todos = $('body').find('.command_container');
for (var i = 0; i < todos.length; i++) { if ($(todos[i]).data('command') == function_obj.commands[j]) {
$( todos[i] ).prepend(' '); break;
} } }*/
}
ret += "\n }"; // close function - "\n\t" using fixed space to indentation
if (has_error) {
return null;
} else {
return ret;
}
}
function commandsCode (command_obj, indentation = 2) {
let code = "";
switch (command_obj.type) {
case Models.COMMAND_TYPES.break:
code = breaksCode(command_obj, indentation);
break;
case Models.COMMAND_TYPES.comment:
code = commentsCode(command_obj, indentation);
break;
case Models.COMMAND_TYPES.reader:
code = readersCode(command_obj, indentation);
break;
case Models.COMMAND_TYPES.writer:
code = writersCode(command_obj, indentation);
break;
case Models.COMMAND_TYPES.functioncall:
code = functioncallsCode(command_obj, indentation);
break;
case Models.COMMAND_TYPES.attribution:
code = attributionsCode(command_obj, indentation);
break;
case Models.COMMAND_TYPES.whiletrue:
code = whiletruesCode(command_obj, indentation);
break;
case Models.COMMAND_TYPES.dowhiletrue:
code = doWhilesCode(command_obj, indentation);
break;
case Models.COMMAND_TYPES.iftrue:
code = iftruesCode(command_obj, indentation);
break;
case Models.COMMAND_TYPES.repeatNtimes:
code = repeatNtimesCode(command_obj, indentation);
break;
case Models.COMMAND_TYPES.switch:
code = switchsCode(command_obj, indentation);
break;
case Models.COMMAND_TYPES.return:
code = returnsCode(command_obj, indentation);
break;
}
// IMPORTANT: do NOT add inline comment here!
// Each specific function (whiletruesCode, etc) does this
// To add here implies to DOUBLE the comment!
// Add comment if, and only if, is a simple command (without blocks)
const simpleCommands = [
Models.COMMAND_TYPES.break,
Models.COMMAND_TYPES.reader,
Models.COMMAND_TYPES.writer,
Models.COMMAND_TYPES.functioncall,
Models.COMMAND_TYPES.attribution,
Models.COMMAND_TYPES.return,
];
if (simpleCommands.includes(command_obj.type)) {
code = addInlineComment(code, command_obj);
}
return code;
} // function commandsCode(command_obj, indentation = 2)
function returnsCode (command_obj, indentation) {
let ret = "\n";
for (let i = 0; i < indentation; i++) {
ret += " "; // do not use "\t" - better using 2 fixed spaces as indentation
}
ret += LocalizedStrings.getUI("text_return");
if (command_obj.variable_value_menu) {
try {
ret += " " + elementExpressionCode(command_obj.variable_value_menu);
//ret += ' ' + variableValueMenuCode(command_obj.variable_value_menu, true);
} catch (err) {
//Empty block
}
}
return ret;
}
function breaksCode (_command_obj, indentation) {
let ret = "\n";
for (let i = 0; i < indentation; i++) {
ret += " "; // "\t" - using fixed space to indentation
}
ret += LocalizedStrings.getUI("text_break");
return ret;
}
// Write Switch code
function switchsCode (command_obj, indentation) {
let ret = "\n";
for (let i = 0; i < indentation; i++) {
ret += " "; // do not use "\t" - better using 2 fixed spaces as indentation
}
ret += LocalizedStrings.getUI("text_code_switch") + "(";
ret += variableValueMenuCode(command_obj.variable);
ret += ") { ";
if (command_obj.cases) {
for (let i = 0; i < command_obj.cases.length; i++) {
ret += switchcasesCode(command_obj.cases[i], indentation + 1);
}
}
ret += "\n";
for (let i = 0; i < indentation; i++) {
ret += " "; // do not use "\t" - better using 2 fixed spaces as indentation
}
ret += "} ";
return ret;
}
function switchcasesCode (switchcase, indentation) {
let ret = "\n";
for (let i = 0; i < indentation; i++) {
ret += " "; // do not use "\t" - better using 2 fixed spaces as indentation
}
ret += LocalizedStrings.getUI("text_code_case") + " ";
ret += variableValueMenuCode(switchcase.variable_value_menu);
ret += " :";
if (switchcase.commands_block) {
for (let i = 0; i < switchcase.commands_block.length; i++) {
ret += commandsCode(switchcase.commands_block[i], indentation + 1);
}
}
return ret;
}
export function repeatNtimesHeader (command_obj) {
let ret = "";
if (command_obj.var_attribution) {
ret += '';
ret += variableValueMenuCode(command_obj.var_attribution);
ret += '';
//leo ret += ` ${LocalizedStrings.getUI("text_code_for_from")} `;
ret += ' ' + LocalizedStrings.getUI("text_code_for_from") + ' ';
ret += '';
ret += variableValueMenuCode(command_obj.expression1);
ret += '';
}
//D var ret1 = LocalizedStrings.getUI("text_code_for_from") + ' ';
//D var ret2 = ` ${LocalizedStrings.getUI("text_code_for_from")} `;
//D console.log("********** code_generator.js: repeatNtimesHeader(.): 1 ret=" + ret1 + "\n" + ret2 + "\n"); //leo remover xxxxxxxxxxx
if (command_obj.expression2) {
//leo ret += ` ${LocalizedStrings.getUI("text_code_for_to")} `;
ret += ' ' + LocalizedStrings.getUI("text_code_for_to") + ' ';
ret += '';
ret += variableValueMenuCode(command_obj.expression2);
ret += '';
}
if (command_obj.expression3) {
//leo ret += ` ${LocalizedStrings.getUI("text_code_for_pass")} `;
ret += ' ' + LocalizedStrings.getUI("text_code_for_pass") + ' ';
ret += '';
switch (command_obj.expression3.itens[1]) {
case Models.ARITHMETIC_TYPES.plus:
ret += " +";
break;
case Models.ARITHMETIC_TYPES.minus:
ret += " -";
break;
}
ret += variableValueMenuCode(command_obj.expression3.itens[2]);
ret += '';
}
return ret;
}
function repeatNtimesCode (command_obj, indentation) {
let ret = "\n";
for (let i = 0; i < indentation; i++) {
ret += " "; // do not use "\t" - better using 2 fixed spaces as indentation
}
ret += LocalizedStrings.getUI("text_for") + " ";
if (command_obj.var_attribution) {
ret += variableValueMenuCode(command_obj.var_attribution);
ret += ` ${LocalizedStrings.getUI("text_code_for_from")} `;
ret += variableValueMenuCode(command_obj.expression1);
}
if (command_obj.expression2) {
ret += ` ${LocalizedStrings.getUI("text_code_for_to")} `;
ret += variableValueMenuCode(command_obj.expression2);
}
if (command_obj.expression3) {
ret += ` ${LocalizedStrings.getUI("text_code_for_pass")} `;
// To fix the bug UNDEFINED
// The problem is inside the struture of expression3
console.log("DEBUG expression3:", command_obj.expression3);
// Try to access in more than one form
let operator = null;
let operand = null;
// Verify if is ExpressionElement with items
if (command_obj.expression3.itens) {
operator = command_obj.expression3.itens[1];
operand = command_obj.expression3.itens[2];
}
// Verify if has direct structure (what is "direct structure"?)
else if (command_obj.expression3.operator) {
operator = command_obj.expression3.operator;
operand = command_obj.expression3.operand || command_obj.expression3.value;
}
// Try (directly) array
else if (Array.isArray(command_obj.expression3)) {
operator = command_obj.expression3[0];
operand = command_obj.expression3[1];
}
// Render operator (build operator to be HTML presented)
if (operator) {
switch (operator) {
case Models.ARITHMETIC_TYPES.plus:
ret += "+";
break;
case Models.ARITHMETIC_TYPES.minus:
ret += "-";
break;
default:
ret += "+"; // fallback
}
} else {
ret += "+"; // fallback
}
// Render operand (build operand to be HTML presented)
if (operand) {
ret += variableValueMenuCode(operand);
} else {
ret += "1"; // fallback
}
}
ret += " {";
// Add inline comment ONLY ONCE HERE
if (command_obj.inlineComment) {
ret += " // " + command_obj.inlineComment;
}
if (command_obj.commands_block) {
for (let i = 0; i < command_obj.commands_block.length; i++) {
ret += commandsCode(command_obj.commands_block[i], indentation + 1);
}
}
ret += "\n";
for (let i = 0; i < indentation; i++) {
ret += " "; // do not use "\t" - better using 2 fixed spaces as indentation
}
ret += "}";
// here, do not add "another" inline comment!
return ret;
} // function repeatNtimesCode(command_obj, indentation)
// Write IfElse code
// Whenever "click" to see "textual code"
function iftruesCode (command_obj, indentation) {
let ret = "\n";
//D console.log("code_generator.js!iftruesCode(.): "); //leo
for (let i = 0; i < indentation; i++) {
ret += " "; // do not use "\t" - better using 2 fixed spaces as indentation
}
ret += LocalizedStrings.getUI("text_if");
if (command_obj.expression) {
ret += "(";
ret += elementExpressionCode(command_obj.expression);
ret += ")";
} else {
//NOT necessary: Utils.renderErrorMessage(command_obj.expression.dom_object, LocalizedStrings.getUI("inform_valid_expression"));
}
ret += " {";
// Inline comment ONLY here
if (command_obj.inlineComment) {
ret += " // " + command_obj.inlineComment;
}
if (command_obj.commands_block) {
for (let i = 0; i < command_obj.commands_block.length; i++) {
ret += commandsCode(command_obj.commands_block[i], indentation + 1);
}
}
ret += "\n";
for (let i = 0; i < indentation; i++) {
ret += " "; // do not use "\t" - better using 2 fixed spaces as indentation
}
ret += "} " + LocalizedStrings.getUI("text_else") + " {";
if (command_obj.commands_else) {
for (let i = 0; i < command_obj.commands_else.length; i++) {
ret += commandsCode(command_obj.commands_else[i], indentation + 1);
}
}
ret += "\n";
for (let i = 0; i < indentation; i++) {
ret += " "; // do not use "\t" - better using 2 fixed spaces as indentation
}
ret += "}";
return ret;
} // function iftruesCode(command_obj, indentation)
function doWhilesCode (command_obj, indentation) {
let ret = "\n";
for (let i = 0; i < indentation; i++) {
ret += " "; // do not use "\t" - better using 2 fixed spaces as indentation
}
ret += LocalizedStrings.getUI("text_code_do") + " {";
if (command_obj.inlineComment) {
ret += " // " + command_obj.inlineComment;
}
if (command_obj.commands_block) {
for (let i = 0; i < command_obj.commands_block.length; i++) {
ret += commandsCode(command_obj.commands_block[i], indentation + 1);
}
}
ret += "\n";
for (let i = 0; i < indentation; i++) {
ret += " "; // do not use "\t" - better using 2 fixed spaces as indentation
}
ret += "} " + LocalizedStrings.getUI("text_code_do_until");
//x if (!command_obj.expression) { Utils.renderErrorMessage(command_obj.expression.dom_object, LocalizedStrings.getUI("inform_valid_expression")); }
if (command_obj.expression) {
ret += "(";
ret += elementExpressionCode(command_obj.expression);
ret += ")";
}
return ret;
} // function doWhilesCode(command_obj, indentation)
function whiletruesCode (command_obj, indentation) {
let ret = "\n";
for (let i = 0; i < indentation; i++) {
ret += " "; // do not use "\t" - better using 2 fixed spaces as indentation
}
ret += LocalizedStrings.getUI("text_code_while");
//x if (!command_obj.expression) Utils.renderErrorMessage(command_obj.expression.dom_object, LocalizedStrings.getUI("inform_valid_expression"));
if (command_obj.expression) {
ret += "(";
ret += elementExpressionCode(command_obj.expression);
ret += ")";
}
ret += " {";
if (command_obj.inlineComment) {
ret += " // " + command_obj.inlineComment;
}
if (command_obj.commands_block) {
for (let i = 0; i < command_obj.commands_block.length; i++) {
ret += commandsCode(command_obj.commands_block[i], indentation + 1);
}
}
ret += "\n";
for (let i = 0; i < indentation; i++) {
ret += " "; // do not use "\t" - better using 2 fixed spaces as indentation
}
ret += "}";
return ret;
} // function whiletruesCode(command_obj, indentation)
function logicExpressionCode (expression) {
let ret = "(";
if (expression.first_operand.type == Models.EXPRESSION_TYPES.exp_logic) {
ret += logicExpressionCode(expression.first_operand);
} else if (
expression.first_operand.type == Models.EXPRESSION_TYPES.exp_arithmetic
) {
ret += arithmeticExpressionCode(expression.first_operand);
} else {
ret += variableValueMenuCode(expression.first_operand);
}
if (expression.operator) {
switch (expression.operator) {
case Models.LOGIC_COMPARISON.equals_to:
ret += " == ";
break;
case Models.LOGIC_COMPARISON.not_equals_to:
ret += " != ";
break;
case Models.LOGIC_COMPARISON.and:
ret += " && ";
break;
case Models.LOGIC_COMPARISON.or:
ret += " || ";
break;
}
if (expression.second_operand.type == Models.EXPRESSION_TYPES.exp_logic) {
ret += logicExpressionCode(expression.second_operand);
} else if (
expression.second_operand.type == Models.EXPRESSION_TYPES.exp_arithmetic
) {
ret += arithmeticExpressionCode(expression.second_operand);
} else {
ret += variableValueMenuCode(expression.second_operand);
}
}
ret += ")";
return ret;
} // function logicExpressionCode(expression)
function arithmeticExpressionCode (expression) {
let ret = "(";
if (expression.first_operand.type == Models.EXPRESSION_TYPES.exp_logic) {
ret += logicExpressionCode(expression.first_operand);
} else if (
expression.first_operand.type == Models.EXPRESSION_TYPES.exp_arithmetic
) {
ret += arithmeticExpressionCode(expression.first_operand);
} else {
ret += variableValueMenuCode(expression.first_operand);
}
switch (expression.operator) {
case Models.ARITHMETIC_COMPARISON.greater_than:
ret += " > ";
break;
case Models.ARITHMETIC_COMPARISON.less_than:
ret += " < ";
break;
case Models.ARITHMETIC_COMPARISON.equals_to:
ret += " == ";
break;
case Models.ARITHMETIC_COMPARISON.not_equals_to:
ret += " != ";
break;
case Models.ARITHMETIC_COMPARISON.greater_than_or_equals_to:
ret += " >= ";
break;
case Models.ARITHMETIC_COMPARISON.less_than_or_equals_to:
ret += " <= ";
break;
}
if (expression.second_operand.type == Models.EXPRESSION_TYPES.exp_logic) {
ret += logicExpressionCode(expression.second_operand);
} else if (
expression.second_operand.type == Models.EXPRESSION_TYPES.exp_arithmetic
) {
ret += arithmeticExpressionCode(expression.second_operand);
} else {
ret += variableValueMenuCode(expression.second_operand);
}
ret += ")";
return ret;
} // function arithmeticExpressionCode(expression)
function attributionsCode (command_obj, indentation) {
let ret = "\n";
for (let i = 0; i < indentation; i++) {
ret += " "; // do not use "\t" - better using 2 fixed spaces as indentation
}
ret += variableValueMenuCode(command_obj.variable) + " <- ";
// for (var i = 0; i < command_obj.expression.length; i++) { ret += elementExpressionCode(command_obj.expression[i]); }
ret += elementExpressionCode(command_obj.expression);
return ret;
}
export function elementExpressionCode (expression_obj) {
let ret = "";
for (let i = 0; i < expression_obj.length; i++) {
if (expression_obj[i].type) {
ret += variableValueMenuCode(expression_obj[i]);
} else if (expression_obj[i].type_op) {
switch (expression_obj[i].item) {
case Models.ARITHMETIC_TYPES.plus:
ret += " + ";
break;
case Models.ARITHMETIC_TYPES.minus:
ret += " - ";
break;
case Models.ARITHMETIC_TYPES.multiplication:
ret += " * ";
break;
case Models.ARITHMETIC_TYPES.division:
ret += " / ";
break;
case Models.ARITHMETIC_TYPES.module:
ret += " % ";
break;
case Models.LOGIC_COMPARISON.equals_to:
ret += " == ";
break;
case Models.LOGIC_COMPARISON.not_equals_to:
ret += " != ";
break;
case Models.LOGIC_COMPARISON.and:
ret += " " + LocalizedStrings.getUI("logic_operator_and") + " ";
break;
case Models.LOGIC_COMPARISON.or:
ret += " " + LocalizedStrings.getUI("logic_operator_or") + " ";
break;
case Models.LOGIC_COMPARISON.not:
ret += " " + LocalizedStrings.getUI("logic_operator_not") + " ";
break;
case Models.ARITHMETIC_COMPARISON.greater_than:
ret += " > ";
break;
case Models.ARITHMETIC_COMPARISON.less_than:
ret += " < ";
break;
case Models.ARITHMETIC_COMPARISON.greater_than_or_equals_to:
ret += " >= ";
break;
case Models.ARITHMETIC_COMPARISON.less_than_or_equals_to:
ret += " <= ";
break;
case Models.EXPRESSION_TYPES.write_sep:
ret += ', " ", ';
break;
}
} else {
ret += " " + expression_obj[i] + " ";
}
}
return ret;
} // export function elementExpressionCode(expression_obj)
function functioncallsCode (command_obj, indentation) {
let ret = "\n";
for (let i = 0; i < indentation; i++) {
ret += " "; // do not use "\t" - better using 2 fixed spaces as indentation
}
ret += variableValueMenuCode(command_obj.function_called);
return ret;
}
// Presents "write(.)" command in iVProg graphical interface
function readersCode (command_obj, indentation) {
let ret = "\n";
for (let i = 0; i < indentation; i++) {
ret += " "; // do not use "\t" - better using 2 fixed spaces as indentation
}
ret += LocalizedStrings.getUI("text_command_read") + "("; // open
ret += variableValueMenuCode(command_obj.variable_value_menu);
ret += ")"; // close
return ret;
}
export function variableValueMenuCode (variable_obj, is_return = false) {
let ret = "";
try {
if (variable_obj.function_called) {
if (variable_obj.function_called.name) {
ret += variable_obj.function_called.name + "("; // open
} else {
ret += LocalizedStrings.translateInternalFunction(variable_obj.function_called.identifier, variable_obj.function_called.category) + "(";
}
if (variable_obj.parameters_list) {
for (let i = 0; i < variable_obj.parameters_list.length; i++) {
ret += variableValueMenuCode(variable_obj.parameters_list[i]);
if (i + 1 < variable_obj.parameters_list.length) {
ret += ", ";
}
}
}
ret += ")"; // close
//D console.log("********** code_generator.js: variableValueMenuCode(.): ret=" + ret); //leo remover xxxxxxxxxxx
} else if (variable_obj.content.type) {
ret += variable_obj.content.name;
if (variable_obj.content.dimensions == 1 && variable_obj.dimensions != 1) {
ret += "[" + variableValueMenuCode(variable_obj.column) + "]"; // array
}
if (variable_obj.content.dimensions == 2 && variable_obj.dimensions != 2 && variable_obj.reference_dimensions == 1) {
ret += "[" + variableValueMenuCode(variable_obj.row) + "]"; // array
} else if (variable_obj.content.dimensions == 2 && variable_obj.dimensions != 2) {
ret += "[" + variableValueMenuCode(variable_obj.row) + "]"; // array
ret += "[" + variableValueMenuCode(variable_obj.column) + "]"; // array
}
} else {
const content = String(variable_obj.content);
if (isNaN(content)) {
// console.debug("Content length: ", content.length);
// console.debug("Char code at 0", content.charCodeAt(0));
const isBackslash = content.charCodeAt(0) === 92;
if (content.length === 1 || (content.length === 2 && isBackslash)) {
ret += `'${content}'`;
} else {
ret += '"' + variable_obj.content + '"';
}
} else if (content.length == 0) {
ret += '""';
} else if (content.trim().length == 0) {
ret += '"' + content + '"';
} else {
ret += variable_obj.content;
}
}
} catch (err) {
var str = variable_obj==null || variable_obj==undefined ? "empty" : variable_obj.content; //D
console.log("js/visualUI/code_generator.js!variableValueMenuCode(.): Error, variable_obj.content=" + str); //D
if (!is_return) {
Utils.renderErrorMessage(variable_obj.dom_object, LocalizedStrings.getUI("inform_valid_content"));
throw err;
}
}
return ret;
} // export function variableValueMenuCode(variable_obj, is_return = false)
// Write to file command "write(.)"
function writersCode (command_obj, indentation) {
let ret = "\n";
for (let i = 0; i < indentation; i++) {
ret += " "; // do not use "\t" - better using 2 fixed spaces as indentation
}
ret += LocalizedStrings.getUI("text_command_write") + "(";
/*for (var i = 0; i < command_obj.content.length; i++) {
ret += variableValueMenuCode(command_obj.content[i]);
if ((i + 1) < command_obj.content.length) { ret += ' + ';}
}*/
ret += elementExpressionCode(command_obj.content);
if (command_obj.newline) {
ret += ', "\\n"';
}
ret += ") ";
return ret;
}
function commentsCode (command_obj, indentation) {
let ret = "\n";
for (let i = 0; i < indentation; i++) {
ret += " "; // do not use "\t" - better using 2 fixed spaces as indentation
}
ret += "// ";
//comment stars (Edilson)
let commentText = "";
if (command_obj.comment_text) {
if (typeof command_obj.comment_text === "object" && command_obj.comment_text.content) {
commentText = command_obj.comment_text.content;
} else if (typeof command_obj.comment_text === "string") {
commentText = command_obj.comment_text;
}
}
if (!commentText) {
commentText = command_obj.value || command_obj.comment || command_obj._text || "";
}
ret += commentText;
//comments ends (Edilson)
return ret;
}
function parametersCode (parameter_obj) {
let ret = "";
switch (parameter_obj.type) {
case Types.INTEGER:
ret += " " + LocalizedStrings.getUI("type_integer") + " ";
break;
case Types.REAL:
ret += " " + LocalizedStrings.getUI("type_real") + " ";
break;
case Types.TEXT:
ret += " " + LocalizedStrings.getUI("type_text") + " ";
break;
case Types.BOOLEAN:
ret += " " + LocalizedStrings.getUI("type_boolean") + " ";
break;
case Types.CHAR:
ret += " " + LocalizedStrings.getUI("type_char") + " ";
break;
}
if (parameter_obj.reference)
ret += "&";
ret += parameter_obj.name + "";
if (parameter_obj.dimensions == 1) {
ret += " []";
} else if (parameter_obj.dimensions == 2) {
ret += " [][]";
}
return ret;
}
// Write variable declaration code
function variablesCode (variable_obj) {
if (variable_obj.type === "comment" || variable_obj.constructor.name === "Comment") {
return commentsCode(variable_obj, 2);
}
let ret = "";
const temp = variable_obj;
ret += "\n "; // "\n\t\n" - using fixed space to indentation (adjust to the function indentation)
if (temp.is_constant) {
ret += "const ";
}
switch (temp.type) {
case Types.INTEGER:
ret += LocalizedStrings.getUI("type_integer") + " ";
break;
case Types.REAL:
ret += LocalizedStrings.getUI("type_real") + " ";
break;
case Types.TEXT:
ret += LocalizedStrings.getUI("type_text") + " ";
break;
case Types.BOOLEAN:
ret += LocalizedStrings.getUI("type_boolean") + " ";
break;
case Types.CHAR:
ret += LocalizedStrings.getUI("type_char") + " ";
break;
}
ret += temp.name + " ";
if (temp.dimensions == 1) {
ret += "[" + temp.columns + "] ";
switch (temp.type) {
case Types.INTEGER:
ret += "<- {";
for (let j = 0; j < temp.value.length; j++) {
ret += temp.value[j];
if (j + 1 < temp.value.length) {
ret += ", ";
}
}
ret += "}";
break;
case Types.REAL:
ret += "<- {";
for (let j = 0; j < temp.value.length; j++) {
ret += parseFloat(temp.value[j]).toFixed(2);
if (j + 1 < temp.value.length) {
ret += ", ";
}
}
ret += "}";
break;
case Types.TEXT:
ret += "<- {";
for (let j = 0; j < temp.value.length; j++) {
ret += '"' + temp.value[j] + '"';
if (j + 1 < temp.value.length) {
ret += ", ";
}
}
ret += "}";
break;
case Types.BOOLEAN:
ret += "<- {";
for (let j = 0; j < temp.value.length; j++) {
if (temp.value[j]) {
ret += LocalizedStrings.getUI("logic_value_true");
} else {
ret += LocalizedStrings.getUI("logic_value_false");
}
if (j + 1 < temp.value.length) {
ret += ", ";
}
}
ret += "}";
break;
case Types.CHAR:
ret += "<- {";
for (let j = 0; j < temp.value.length; j++) {
ret += "'" + temp.value[j] + "'";
if (j + 1 < temp.value.length) {
ret += ", ";
}
}
ret += "}";
break;
}
} else if (temp.dimensions == 2) {
ret += "[" + temp.rows + "][" + temp.columns + "] ";
switch (temp.type) {
case Types.INTEGER:
ret += "<- {";
for (let j = 0; j < temp.rows; j++) {
ret += "{";
for (let k = 0; k < temp.columns; k++) {
ret += temp.value[j][k];
if (k + 1 < temp.columns) {
ret += ", ";
}
}
ret += "}";
if (j + 1 < temp.rows) {
ret += ", ";
}
}
ret += "}";
break;
case Types.REAL:
ret += "<- {";
for (let j = 0; j < temp.rows; j++) {
ret += "{";
for (let k = 0; k < temp.columns; k++) {
ret += parseFloat(temp.value[j][k]).toFixed(2);
if (k + 1 < temp.columns) {
ret += ", ";
}
}
ret += "}";
if (j + 1 < temp.rows) {
ret += ", ";
}
}
ret += "}";
break;
case Types.TEXT:
ret += "<- {";
for (let j = 0; j < temp.rows; j++) {
ret += "{";
for (let k = 0; k < temp.columns; k++) {
ret += '"' + temp.value[j][k] + '"';
if (k + 1 < temp.columns) {
ret += ", ";
}
}
ret += "}";
if (j + 1 < temp.rows) {
ret += ", ";
}
}
ret += "}";
break;
case Types.BOOLEAN:
ret += "<- {";
for (let j = 0; j < temp.rows; j++) {
ret += "{";
for (let k = 0; k < temp.columns; k++) {
if (temp.value[j][k]) {
ret += LocalizedStrings.getUI("logic_value_true");
} else {
ret += LocalizedStrings.getUI("logic_value_false");
}
if (k + 1 < temp.columns) {
ret += ", ";
}
}
ret += "}";
if (j + 1 < temp.rows) {
ret += ", ";
}
}
ret += "}";
break;
case Types.CHAR:
ret += "<- {";
for (let j = 0; j < temp.rows; j++) {
ret += "{";
for (let k = 0; k < temp.columns; k++) {
ret += "'" + temp.value[j][k] + "'";
if (k + 1 < temp.columns) {
ret += ", ";
}
}
ret += "}";
if (j + 1 < temp.rows) {
ret += ", ";
}
}
ret += "}";
break;
}
} else {
switch (temp.type) {
case Types.INTEGER:
ret += "<- " + temp.value;
break;
case Types.REAL:
ret += "<- " + parseFloat(temp.value).toFixed(2);
break;
case Types.TEXT:
ret += '<- "' + temp.value + '"';
break;
case Types.BOOLEAN:
ret += "<- ";
if (temp.value) {
ret += LocalizedStrings.getUI("logic_value_true");
} else {
ret += LocalizedStrings.getUI("logic_value_false");
}
break;
case Types.CHAR:
ret += "<- '" + temp.value + "'";
break;
}
}
ret = addInlineComment(ret, temp); //comments (Edilson)
return ret;
} // function variablesCode(variable_obj)
function globalsCode () {
let ret = "";
if (window.program_obj.globals) {
for (let i = 0; i < window.program_obj.globals.length; i++) {
const temp = window.program_obj.globals[i];
ret += " "; // do not use "\t" - better using 2 fixed spaces as indentation
if (temp.is_constant) {
ret += "const "; //TODO Internacionalizar - insert it in ./ivprog/i18n/ui.csv
}
switch (temp.type) {
case Types.INTEGER:
ret += LocalizedStrings.getUI("type_integer");
break;
case Types.REAL:
ret += LocalizedStrings.getUI("type_real");
break;
case Types.TEXT:
ret += LocalizedStrings.getUI("type_text");
break;
case Types.BOOLEAN:
ret += LocalizedStrings.getUI("type_boolean");
break;
case Types.CHAR:
ret += LocalizedStrings.getUI("type_char");
break;
}
ret += " " + temp.name + " ";
if (temp.dimensions == 1) {
ret += "[" + temp.columns + "] ";
switch (temp.type) {
case Types.INTEGER:
ret += "<- {";
for (let j = 0; j < temp.value.length; j++) {
ret += temp.value[j];
if (j + 1 < temp.value.length) {
ret += ", ";
}
}
ret += "}";
break;
case Types.REAL:
ret += "<- {";
for (let j = 0; j < temp.value.length; j++) {
ret += parseFloat(temp.value[j]).toFixed(2);
if (j + 1 < temp.value.length) {
ret += ", ";
}
}
ret += "}";
break;
case Types.TEXT:
ret += "<- {";
for (let j = 0; j < temp.value.length; j++) {
ret += '"' + temp.value[j] + '"';
if (j + 1 < temp.value.length) {
ret += ", ";
}
}
ret += "}";
break;
case Types.BOOLEAN:
ret += "<- {";
for (let j = 0; j < temp.value.length; j++) {
if (temp.value[j]) {
ret += LocalizedStrings.getUI("logic_value_true");
} else {
ret += LocalizedStrings.getUI("logic_value_false");
}
if (j + 1 < temp.value.length) {
ret += ", ";
}
}
ret += "}";
break;
case Types.CHAR:
ret += "<- {";
for (let j = 0; j < temp.value.length; j++) {
ret += "'" + temp.value[j] + "'";
if (j + 1 < temp.value.length) {
ret += ", ";
}
}
ret += "}";
break;
}
} else if (temp.dimensions == 2) {
ret += "[" + temp.rows + "][" + temp.columns + "] ";
switch (temp.type) {
case Types.INTEGER:
ret += "<- {";
for (let j = 0; j < temp.rows; j++) {
ret += "{";
for (let k = 0; k < temp.columns; k++) {
ret += temp.value[j][k];
if (k + 1 < temp.columns) {
ret += ", ";
}
}
ret += "}";
if (j + 1 < temp.rows) {
ret += ", ";
}
}
ret += "}";
break;
case Types.REAL:
ret += "<- {";
for (let j = 0; j < temp.rows; j++) {
ret += "{";
for (let k = 0; k < temp.columns; k++) {
ret += parseFloat(temp.value[j][k]).toFixed(2);
if (k + 1 < temp.columns) {
ret += ", ";
}
}
ret += "}";
if (j + 1 < temp.rows) {
ret += ", ";
}
}
ret += "}";
break;
case Types.TEXT:
ret += "<- {";
for (let j = 0; j < temp.rows; j++) {
ret += "{";
for (let k = 0; k < temp.columns; k++) {
ret += '"' + temp.value[j][k] + '"';
if (k + 1 < temp.columns) {
ret += ", ";
}
}
ret += "}";
if (j + 1 < temp.rows) {
ret += ", ";
}
}
ret += "}";
break;
case Types.BOOLEAN:
ret += "<- {";
for (let j = 0; j < temp.rows; j++) {
ret += "{";
for (let k = 0; k < temp.columns; k++) {
if (temp.value[j][k]) {
ret += LocalizedStrings.getUI("logic_value_true");
} else {
ret += LocalizedStrings.getUI("logic_value_false");
}
if (k + 1 < temp.columns) {
ret += ", ";
}
}
ret += "}";
if (j + 1 < temp.rows) {
ret += ", ";
}
}
ret += "}";
break;
case Types.CHAR:
ret += "<- {";
for (let j = 0; j < temp.rows; j++) {
ret += "{";
for (let k = 0; k < temp.columns; k++) {
ret += "'" + temp.value[j][k] + "'";
if (k + 1 < temp.columns) {
ret += ", ";
}
}
ret += "}";
if (j + 1 < temp.rows) {
ret += ", ";
}
}
ret += "}";
break;
}
} else {
switch (temp.type) {
case Types.INTEGER:
ret += "<- " + temp.value;
break;
case Types.REAL:
ret += "<- " + parseFloat(temp.value).toFixed(2);
break;
case Types.TEXT:
ret += '<- "' + temp.value + '"';
break;
case Types.BOOLEAN:
ret += "<- ";
if (temp.value) {
ret += LocalizedStrings.getUI("logic_value_true");
} else {
ret += LocalizedStrings.getUI("logic_value_false");
}
break;
case Types.CHAR:
ret += "<- '" + temp.value + "'";
break;
}
}
}
}
return ret;
} // function globalsCode()
// Treat comments (Edilson)
function addInlineComment (code, command_obj) {
if (command_obj.inlineComment) {
return code.trimEnd() + " // " + command_obj.inlineComment;
}
return code;
}