// iVProg - www.usp.br/line/ivprog // LInE - Free Education, Private Data import { Types } from "../types"; import * as Models from "../ivprog_elements"; import { LocalizedStrings } from "../../services/localizedStringsService"; import * as VariableValueMenuManagement from "./variable_value_menu"; import { registerUserEvent, ActionTypes } from "../../services/userLog"; import WatchJS from "melanke-watchjs"; import * as Utils from '../utils'; window.timer = false; // @calledby ./ivprog/js/util/codeParser.js: function parseWriter(command, function_obj) export function renderExpression (command, function_obj, div_to_render, expression_array) { console.log("./ivprog/js/visualUI/commands/generic_expression.js: renderExpression(.): expression_array=" + JSON.stringify(expression_array)); //leo if (!expression_array || !expression_array[0] || expression_array[0]===undefined) { console.log(" *** ERROR! expression_array or expression_array[0] empty"); return; //leo } //D command=" + JSON.stringify(command) + "\nexpression_array=" + JSON.stringify(expression_array) + "\n"); //leo //D function_obj=||" + JSON.stringify(function_obj) + "||\n div_to_render.empty(); WatchJS.unwatch(command, "expression"); WatchJS.watch(command, "expression", function () { if (window.timer) return; const m = div_to_render.find(".single_element_expression").not(".mouse_distance").not(".add_parentheses"); let s = ""; m.each(function (e) { if ($(this).hasClass("parentheses_in_expression")) { s += $(this).text() + " "; } else { s += $(this).find(".text").text(); s += $(this).find(".var_name").text(); s += $(this).find(".parameters_function_called").text(); s += $(this).find(".value_rendered").text(); s += " "; } }); if (s) { window.timer = true; } else { return; } registerUserEvent(function_obj.name, ActionTypes.CHANGE_COMMAND_EXP, command.type, "/", s); setTimeout(function () { window.timer = false; }, 200); }, 20, true ); if (command.type === Models.COMMAND_TYPES.attribution) { WatchJS.unwatch(command.variable); WatchJS.watch( command.variable, function () { renderExpression(command, function_obj, div_to_render, expression_array); }, 0 ); if (command.variable.content) { const types_included = []; if (command.variable.content.type == Types.INTEGER || command.variable.content.type == Types.REAL) { types_included.push(Models.EXPRESSION_TYPES.exp_arithmetic); } else if (command.variable.content.type == Types.BOOLEAN) { types_included.push(Models.EXPRESSION_TYPES.exp_conditional); types_included.push(Models.EXPRESSION_TYPES.exp_logic); types_included.push(Models.EXPRESSION_TYPES.exp_arithmetic); } else if (command.variable.content.type == Types.TEXT) { types_included.push(Models.EXPRESSION_TYPES.exp_conditional); types_included.push(Models.EXPRESSION_TYPES.exp_logic); types_included.push(Models.EXPRESSION_TYPES.exp_arithmetic); } else { console.log("./ivprog/js/visualUI/commands/generic_expression.js: renderExpression(.): NOT RECOGNIZED! SEE command.variable.content.type=" + command.variable.content.type); } //D console.log("generic_expression.js: renderExpression(.): command.variable.content: command=" + JSON.stringify(command)); //leo renderElements(command, function_obj, div_to_render, expression_array, types_included); } else { div_to_render.text(LocalizedStrings.getUI("var_menu_select_var").toLowerCase()); } } else { const types_included = []; types_included.push(Models.EXPRESSION_TYPES.exp_conditional); types_included.push(Models.EXPRESSION_TYPES.exp_logic); if (command.type === Models.COMMAND_TYPES.writer) types_included.push(Models.EXPRESSION_TYPES.write_sep); types_included.push(Models.EXPRESSION_TYPES.exp_arithmetic); //D console.log("generic_expression.js: renderExpression(.): else de Models.COMMAND_TYPES.attribution: command.type=" + command.type); //leo //D console.log("generic_expression.js: renderExpression(.): else de Models.COMMAND_TYPES.attribution: expression_array=" + JSON.stringify(expression_array)); //leo renderElements(command, function_obj, div_to_render, expression_array, types_included); } div_to_render.children(".mouse_distance").addClass("mouse_distance_hidden"); div_to_render.children(".higher_element").on("mousemove", function (evt) { if (!window.open_or_close) { $(this).css("position", "relative", "!important"); $(this).children(".mouse_distance").css("opacity", "1"); } }); div_to_render.children(".higher_element").on("mouseout", function (evt) { if (!window.open_or_close) { $(this).css("position", "absolute", "!important"); $(this).children(".mouse_distance").css("opacity", "0"); } }); const lixeira = $('
'); div_to_render.find(".single_element_expression").on("mousedown", function (evt) { window.posX = evt.clientX; window.posY = evt.clientY; }); Sortable.create(div_to_render[0], { animation: 100, ghostClass: "ghost", group: { name: "shared", put: false, // Do not allow items to be put into this list }, draggable: ".single_element_expression", sort: false, filter: ".not_allowed", onStart: function () { $("body").append(lixeira); lixeira.css("display", "block"); lixeira.css("top", window.posY + 70, "!important"); lixeira.css("left", window.posX - 20, "!important"); }, onMove: function () { lixeira.addClass("color_test"); }, onEnd: function () { lixeira.remove(); div_to_render.find(".ghost").removeClass("ghost"); }, }); new Sortable(lixeira[0], { group: "shared", animation: 150, onAdd: function (evt) { lixeira.css("display", "none"); lixeira.find(".single_element_expression").remove(); lixeira.css("background-color", ""); lixeira.remove(); removeElement(evt, expression_array); renderExpression(command, function_obj, div_to_render, expression_array); }, }); } // export function renderExpression(command, function_obj, div_to_render, expression_array) function removeElement (event, expression_array) { const indice = $(event.item).data("index"); const first = expression_array[0]; if (expression_array[indice].type) { // if is alone in expression: if (expression_array.length == 1) { //function_obj.commands.splice(function_obj.commands.indexOf(command), 1); expression_array.splice(0, 1); } else if (expression_array.length > 1) { if (indice > 0 && expression_array[indice - 1].type_op) { if (indice < expression_array.length && expression_array[indice - 2] == "(" && expression_array[indice + 1].type_op) { // ")" Jed expression_array.splice(indice + 1, 1); } expression_array.splice(indice, 1); expression_array.splice(indice - 1, 1); if (indice - 2 < expression_array.length && expression_array[indice - 2] == "(" && expression_array[indice - 1] == ")") { expression_array.splice(indice - 1, 1); expression_array.splice(indice - 2, 1); if (indice - 3 >= 0 && indice - 3 < expression_array.length && expression_array[indice - 3].type_op) { expression_array.splice(indice - 3, 1); } } } else if (indice < expression_array.length - 1 && expression_array[indice + 1].type_op) { expression_array.splice(indice + 1, 1); expression_array.splice(indice, 1); } else if (indice < expression_array.length - 1 && indice > 0 && expression_array[indice - 1] == "(" && expression_array[indice + 1] == ")") { if (indice > 1 && expression_array[indice - 2].type_op) { expression_array.splice(indice + 1, 1); expression_array.splice(indice, 1); expression_array.splice(indice - 1, 1); expression_array.splice(indice - 2, 1); } else if (indice < expression_array.length - 2 && expression_array[indice + 2].type_op) { expression_array.splice(indice + 1, 1); expression_array.splice(indice, 1); expression_array.splice(indice - 1, 1); } else { expression_array.splice(indice + 1, 1); expression_array.splice(indice, 1); expression_array.splice(indice - 1, 1); } } } } else if (expression_array[indice].type_op) { // iVProg doesn't support operator remove } else { // else if (expression_array[indice].type_op) let opening = -1; let closing = -1; if (expression_array[indice] == "(") { // ")" Jed opening = indice; for (var i = indice + 1; i < expression_array.length; i++) { if (expression_array[i] == ")") { // ")" Jed closing = i; break; } } } else { // if (expression_array[indice] == "(") // ")" Jed closing = indice; for (var i = indice - 1; i >= 0; i--) { if (expression_array[i] == "(") { // ")" to Jed opening = i; break; } } } if (expression_array[opening + 1].type_op) { expression_array.splice(closing, 1); expression_array.splice(opening + 1, 1); expression_array.splice(opening, 1); } else { expression_array.splice(closing, 1); expression_array.splice(opening, 1); } } // if expression is empty, add a new var value: if (expression_array.length == 0) { expression_array.push(new Models.VariableValueMenu(VariableValueMenuManagement.VAR_OR_VALUE_TYPES.all, null, null, null, true)); } if (first != expression_array[0] && expression_array[0].type_op) { expression_array.splice(0, 1); } } // function removeElement(event, expression_array) function renderElements (command, function_obj, div_to_render, expression_array, types_included) { //if (expression_array.length > 0) {if (!expression_array[0].type_op) {renderStartAddOperator(div_to_render, types_included, expression_array, command, function_obj, 0);}} let i = 0; //D console.log(" xxx 3 : expression_array.length=" + expression_array.length + " : " + JSON.stringify(expression_array)); for (i = 0; i < expression_array.length; i++) { if (expression_array[i].type == "var_value") { const div_temp = $('
'); if (i == 0) { if (expression_array.length > 0 && !expression_array[0].type_op) { //renderStartAddOperator(div_to_render, types_included, expression_array, command, function_obj, 0); } } VariableValueMenuManagement.renderMenu(command, expression_array[i], div_temp, function_obj); div_to_render.append(div_temp); } else if (expression_array[i] == "(" || expression_array[i] == ")") { if (expression_array[i] == ")") { renderFinalAddElements( div_to_render, types_included, expression_array, command, function_obj, i); renderParenthesis(div_to_render, expression_array[i], command, function_obj, i, expression_array); } else if (expression_array[i] == "(" && !expression_array[i + 1].type_op) { renderParenthesis(div_to_render, expression_array[i], command, function_obj, i, expression_array); renderStartAddOperator(div_to_render, types_included, expression_array, command, function_obj, i + 1); } else { renderParenthesis(div_to_render, expression_array[i], command, function_obj, i, expression_array); } } else { //leo if (i == 0) { } //leo else if (expression_array[i - 1] == "(") { } // ")" close to Jed editor renderOperatorMenu(command, function_obj, div_to_render, expression_array[i], types_included, i, expression_array); } } // for (i = 0; i < expression_array.length; i++) renderFinalAddElements(div_to_render, types_included, expression_array, command, function_obj, i, true); renderAddParenthesis(command, function_obj, div_to_render, expression_array, types_included); } // function renderElements(command, function_obj, div_to_render, expression_array, types_included) window.parentheses_activate = false; window.open_or_close = null; function renderAddParenthesis (command, function_obj, div_to_render, expression_array, types_included) { // Insert img of "(" ")" const addParentheses = $( '
' ); div_to_render.append(addParentheses); addParentheses.popup({ content: "Adicionar parênteses", delay: { show: 750, hide: 0, }, }); addParentheses.on("click", function (mouse_event) { // verificar se já está ativado if (window.parentheses_activate) { return; } div_to_render.find(".usepointer").off("click"); window.parentheses_activate = true; window.open_or_close = "open"; div_to_render.find(".dropdown").addClass("disabled"); div_to_render.find(".ghost_element").addClass("temp_class"); div_to_render.find(".ghost_element").removeClass("ghost_element"); const floatingObject = $('
(
'); floatingObject.draggable().appendTo("body"); floatingObject.css("position", "absolute"); mouse_event.type = "mousedown.draggable"; mouse_event.target = floatingObject[0]; floatingObject.css("left", mouse_event.pageX + 10); floatingObject.css("top", mouse_event.pageY + 10); floatingObject.trigger(mouse_event); div_to_render.on("mousemove", function (evt) { let actual_target = null; if ($(evt.target).hasClass("single_element_expression")) { actual_target = $(evt.target); } else { actual_target = $(evt.target).closest(".single_element_expression"); } if ( $(evt.target).hasClass("temp_class") || actual_target.length < 1 || actual_target.hasClass("add_parentheses") || actual_target.hasClass("rendered_parentheses") || $(evt.target).hasClass("expression_elements") ) { return; } renderGhostParentheses( actual_target, command, function_obj, div_to_render, expression_array ); }); div_to_render.on("mouseleave", function () { // window.open_parentheses.remove(); window.close_parentheses.remove(); }); let floating; $("body").on("mouseup", function (evt) { if (window.open_or_close == "open") { window.open_or_close = "close"; floatingObject.remove(); var comando_que_esta = $(evt.target).closest(".command_container"); var comando_certo = div_to_render.closest(".command_container"); if (!comando_que_esta.is(comando_certo)) { window.parentheses_activate = false; div_to_render.find(".temp_class").addClass("ghost_element"); div_to_render.find(".temp_class").removeClass("temp_class"); div_to_render.off("mousemove"); div_to_render.off("mouseleave"); $("body").off("mouseup"); window.open_parentheses.remove(); window.close_parentheses.remove(); window.inserir_open = -1; window.inserir_close = -1; window.open_or_close = null; renderExpression(command, function_obj, div_to_render, expression_array); return; } window.open_parentheses.addClass("parentheses_fixed"); floating = $('
)
'); floating.draggable().appendTo("body"); floating.css("position", "absolute"); floating.css("left", evt.pageX + 10); floating.css("top", evt.pageY + 10); $("body").on("mousemove", function (evts) { floating.css("left", evts.pageX + 10); floating.css("top", evts.pageY + 10); }); } else { floating.remove(); window.open_parentheses.removeClass("parentheses_fixed"); div_to_render.off("mousemove"); div_to_render.off("mouseleave"); $("body").off("mouseup"); setTimeout(function () { window.parentheses_activate = false; }, 50); var comando_que_esta = $(evt.target).closest(".command_container"); var comando_certo = div_to_render.closest(".command_container"); let is_correct = false; if (comando_que_esta.is(comando_certo)) { is_correct = true; } if (is_correct) { expression_array.splice(window.inserir_open, 0, "("); expression_array.splice(window.inserir_close, 0, ")"); } window.inserir_open = -1; window.inserir_close = -1; window.open_or_close = null; renderExpression(command, function_obj, div_to_render, expression_array); } }); }); } window.open_parentheses = $('
(
'); window.close_parentheses = $('
)
'); window.inserir_open = -1; window.inserir_close = -1; function renderGhostParentheses (actual_target, command, function_obj, div_to_render, expression_array) { // window.open_parentheses.remove(); window.close_parentheses.remove(); const index_in_array = actual_target.data("index"); if ( expression_array[index_in_array] == "(" || expression_array[index_in_array] == ")" ) { return; } if (window.open_or_close == "close") { if (index_in_array < window.inserir_open) { return; } } // Tratando a situacao quando e' na primeira posicao: if (index_in_array == 0) { if (expression_array[index_in_array].type == "var_value") { if (window.open_or_close == "open") { window.open_parentheses.insertBefore(actual_target); window.inserir_open = index_in_array; } //if (expression_array.length == 1) { if (window.open_or_close == "close") { window.close_parentheses.insertAfter(actual_target); window.inserir_close = index_in_array + 2; } //} else { var count_opened = 0; var count_closed = 0; for (var i = 0; i < expression_array.length; i++) { if (expression_array[i] == "(") { count_opened++; } if (expression_array[i] == ")") { count_closed++; } if (count_opened != count_closed) { } else { if (count_opened > 0) { if (window.open_or_close == "close") { window.close_parentheses.insertAfter( div_to_render.find( '.single_element_expression[data-index="' + i + '"]' ) ); window.inserir_close = i + 2; } break; } else { if (expression_array[i].type == "var_value") { if (window.open_or_close == "close") { window.close_parentheses.insertAfter( div_to_render.find( '.single_element_expression[data-index="' + i + '"]' ) ); window.inserir_close = i + 2; } break; } } } } //} } else if (expression_array[index_in_array].type_op) { if (window.open_or_close == "open") { window.open_parentheses.insertBefore(actual_target); window.inserir_open = index_in_array; } var count_opened = 0; var count_closed = 0; for (var i = 1; i < expression_array.length; i++) { // $('.slide-link[data-slide="0"]') if (expression_array[i] == "(") { count_opened++; } if (expression_array[i] == ")") { count_closed++; } if (count_opened != count_closed) { } else { if (count_opened > 0) { if (expression_array[i].type == "var_value") { window.close_parentheses.insertAfter( div_to_render.find( '.single_element_expression[data-index="' + i + '"]' ) ); window.inserir_close = i + 2; } break; } else { if (expression_array[i].type == "var_value") { if (expression_array[i].type == "var_value") { window.close_parentheses.insertAfter( div_to_render.find( '.single_element_expression[data-index="' + i + '"]' ) ); window.inserir_close = i + 2; } break; } } } } } return; } // Tratando quando não é no índice 0: if (expression_array[index_in_array].type == "var_value") { if (window.open_or_close == "open") { window.open_parentheses.insertBefore(actual_target); window.inserir_open = index_in_array; } if (window.open_or_close == "close") { window.close_parentheses.insertAfter(actual_target); window.inserir_close = index_in_array + 2; } return; } if (expression_array[index_in_array].type_op) { // buscar para a esquerda primeiro: if (expression_array[index_in_array - 1] == "(") { if (window.open_or_close == "open") { window.open_parentheses.insertBefore(actual_target); window.inserir_open = index_in_array; } } else if (expression_array[index_in_array - 1] == ")") { // buscar a abertura var count_opened = 0; var count_closed = 0; for (var j = index_in_array - 1; j >= 0; j--) { if (expression_array[j] == "(") { // "}){" Jed count_opened++; } if (expression_array[j] == ")") { count_closed++; } if (count_opened != count_closed) { } else { if (count_closed > 0) { if (window.open_or_close == "open") { window.open_parentheses.insertBefore( div_to_render.find( '.single_element_expression[data-index="' + j + '"]' ) ); window.inserir_open = j; } break; } } } } else if (expression_array[index_in_array - 1].type == "var_value") { if (window.open_or_close == "open") { window.open_parentheses.insertBefore( div_to_render.find( '.single_element_expression[data-index="' + (index_in_array - 1) + '"]' ) ); window.inserir_open = index_in_array - 1; } } // buscar para a direita agora: if (expression_array[index_in_array + 1] == "(") { // "}){" Jed // buscar o fechamento: var count_opened = 0; var count_closed = 0; for (var j = index_in_array + 1; j < expression_array.length; j++) { if (expression_array[j] == "(") { // "}){" Jed count_opened++; } if (expression_array[j] == ")") { count_closed++; } if (count_opened != count_closed) { } else { if (count_opened > 0) { if (window.open_or_close == "close") { window.close_parentheses.insertAfter( div_to_render.find( '.single_element_expression[data-index="' + j + '"]' ) ); window.inserir_close = j + 2; } break; } } } } else if (expression_array[index_in_array + 1].type == "var_value") { if (window.open_or_close == "close") { window.close_parentheses.insertAfter(div_to_render.find('.single_element_expression[data-index="' + (index_in_array + 1) + '"]')); window.inserir_close = index_in_array + 3; } } } } function renderParenthesis (div_to_render, expression_content, command, function_obj, position, expression_array) { const ghost_parenthesis = $( '
' + expression_content + "
\n"); div_to_render.append(ghost_parenthesis); } function renderStartAddOperator (div_to_render, types_included, expression_array, command, function_obj, position) { let menu_final = '"; menu_final = $(menu_final); const div_temp = $( '
' ); div_temp.append(menu_final); const div_higher = $('
'); div_higher.append(div_temp); div_to_render.append(div_higher); menu_final.dropdown("set selected", Models.ARITHMETIC_TYPES.minus); div_temp.on("click", function () { if (!window.open_or_close) { const sera = position; if (types_included.indexOf(Models.EXPRESSION_TYPES.exp_arithmetic) >= 0) { expression_array.splice( sera, 0, new Models.ExpressionOperator( Models.EXPRESSION_TYPES.exp_arithmetic, Models.ARITHMETIC_TYPES.minus ) ); } else if ( types_included.indexOf(Models.EXPRESSION_TYPES.exp_logic) >= 0 ) { expression_array.splice( sera, 0, new Models.ExpressionOperator( Models.EXPRESSION_TYPES.exp_logic, Models.LOGIC_COMPARISON.equals_to ) ); } else if ( types_included.indexOf(Models.EXPRESSION_TYPES.exp_conditional) >= 0 ) { expression_array.splice( sera, 0, new Models.ExpressionOperator( Models.EXPRESSION_TYPES.exp_conditional, Models.ARITHMETIC_COMPARISON.greater_than ) ); } renderExpression(command, function_obj, div_to_render, expression_array); } }); } function renderFinalAddElements (div_to_render, types_included, expression_array, command, function_obj, position, is_last = false) { let menu_final = '"; menu_final = $(menu_final); const div_temp = $('
'); const div_higher = $('
'); const button = $(''); div_temp.append(button); if (!is_last) { div_higher.append(div_temp); div_to_render.append(div_higher); //div_temp.append(menu_final); div_temp.css("opacity", "0", "!important"); } else { div_temp.removeClass("mouse_distance"); div_temp.css("opacity", "1", "!important"); //div_temp.append(menu_final); div_to_render.append(div_temp); } menu_final.dropdown("set selected", Models.ARITHMETIC_TYPES.plus); div_temp.on("click", function () { const sera = position; if (expression_array[sera] == ")" && expression_array[sera - 1] == "(") { expression_array.splice( sera, 0, new Models.VariableValueMenu(VariableValueMenuManagement.VAR_OR_VALUE_TYPES.all, null, null, null, true) ); renderExpression(command, function_obj, div_to_render, expression_array); return; } if (types_included.indexOf(Models.EXPRESSION_TYPES.exp_arithmetic) >= 0) { expression_array.splice( sera, 0, new Models.ExpressionOperator( Models.EXPRESSION_TYPES.exp_arithmetic, Models.ARITHMETIC_TYPES.plus ) ); expression_array.splice( sera + 1, 0, new Models.VariableValueMenu( VariableValueMenuManagement.VAR_OR_VALUE_TYPES.all, null, null, null, true ) ); } else if (types_included.indexOf(Models.EXPRESSION_TYPES.exp_logic) >= 0) { expression_array.splice( sera, 0, new Models.ExpressionOperator( Models.EXPRESSION_TYPES.exp_logic, Models.LOGIC_COMPARISON.equals_to ) ); expression_array.splice( sera + 1, 0, new Models.VariableValueMenu( VariableValueMenuManagement.VAR_OR_VALUE_TYPES.all, null, null, null, true ) ); } else if ( types_included.indexOf(Models.EXPRESSION_TYPES.exp_conditional) >= 0 ) { expression_array.splice(sera, 0, new Models.ExpressionOperator(Models.EXPRESSION_TYPES.exp_conditional, Models.ARITHMETIC_COMPARISON.greater_than) ); expression_array.splice(sera + 1, 0, new Models.VariableValueMenu(VariableValueMenuManagement.VAR_OR_VALUE_TYPES.all, null, null, null, true) ); } renderExpression(command, function_obj, div_to_render, expression_array); }); } // Construct HTML menu item with: Space \n Arithmetics \n Logics \n Relational function renderOperatorMenu (command, function_obj, div_to_render, expression_element, types_included, position, expression_array) { let menu_final = '\n"; menu_final = $(menu_final); menu_final.find(".ivprog-write-sep").popup({ content: LocalizedStrings.getUI("write_seprator_menu_tooltip"), delay: { show: 500, hide: 0, }, }); const div_temp = $('
'); div_temp.append(menu_final); div_to_render.append(div_temp); menu_final.dropdown({ onChange: function (_value, _text, $selectedItem) { expression_element.item = $selectedItem.data("value"); expression_element.type_op = $selectedItem.data("type"); }, }); menu_final.dropdown("set selected", expression_element.item); } // function renderOperatorMenu(command, function_obj, div_to_render, expression_element, types_included, position, expression_array) function getArithmeticOperators () { let arithmetic_operators; arithmetic_operators = '
+
'; arithmetic_operators += '
-
'; arithmetic_operators += '
*
'; arithmetic_operators += '
/
'; arithmetic_operators += '
%
'; return arithmetic_operators; } function getLogicOperators () { let logic_operators; logic_operators = '
==
'; logic_operators += '
!=
'; logic_operators += '
' + LocalizedStrings.getUI("logic_operator_and") + "
\n"; logic_operators += '
' + LocalizedStrings.getUI("logic_operator_or") + "
\n"; logic_operators += '
' + LocalizedStrings.getUI("logic_operator_not") + "
\n"; return logic_operators; } function getRelationalOperators () { let relational_operators; relational_operators = '
>
'; relational_operators += '
<
'; relational_operators += '
==
'; relational_operators += '
!=
'; relational_operators += '
>=
'; relational_operators += '
<=
'; return relational_operators; } // function getRelationalOperators() function getSeparator () { //leo return '
${LocalizedStrings.getUI("write_seprator_menu_text")}
' + "\n"; return '
' + LocalizedStrings.getUI("write_seprator_menu_text") + '
' + "\n"; } // @calledby export function expressionParserCodeVisual(parsed, function_obj) function getVariable (function_obj, search) { //D console.log("./ivprog/js/visualUI/commands/generic_expression.js: getVariable(.): search=" + JSON.stringify(search)); //leo if (search == ")" || search == "(") { return search; } if (search.instance == "operator") { var obj; switch (search.value) { case '+': obj = new Models.ExpressionOperator(Models.EXPRESSION_TYPES.exp_arithmetic, Models.ARITHMETIC_TYPES.plus); break; case '-': obj = new Models.ExpressionOperator(Models.EXPRESSION_TYPES.exp_arithmetic, Models.ARITHMETIC_TYPES.minus); break; case '*': obj = new Models.ExpressionOperator(Models.EXPRESSION_TYPES.exp_arithmetic, Models.ARITHMETIC_TYPES.multiplication); break; case '/': obj = new Models.ExpressionOperator(Models.EXPRESSION_TYPES.exp_arithmetic, Models.ARITHMETIC_TYPES.division); break; case '%': obj = new Models.ExpressionOperator(Models.EXPRESSION_TYPES.exp_arithmetic, Models.ARITHMETIC_TYPES.module); break; case '>': obj = new Models.ExpressionOperator(Models.EXPRESSION_TYPES.exp_conditional, Models.ARITHMETIC_COMPARISON.greater_than); break; case '<': obj = new Models.ExpressionOperator(Models.EXPRESSION_TYPES.exp_conditional, Models.ARITHMETIC_COMPARISON.less_than); break; case '>=': obj = new Models.ExpressionOperator(Models.EXPRESSION_TYPES.exp_conditional, Models.ARITHMETIC_COMPARISON.greater_than_or_equals_to); break; case '<=': obj = new Models.ExpressionOperator(Models.EXPRESSION_TYPES.exp_conditional, Models.ARITHMETIC_COMPARISON.less_than_or_equals_to); break; case '==': obj = new Models.ExpressionOperator(Models.EXPRESSION_TYPES.exp_conditional, Models.ARITHMETIC_COMPARISON.equals_to); break; case '!=': obj = new Models.ExpressionOperator(Models.EXPRESSION_TYPES.exp_conditional, Models.ARITHMETIC_COMPARISON.not_equals_to); break; case 'and': obj = new Models.ExpressionOperator(Models.EXPRESSION_TYPES.exp_logic, Models.LOGIC_COMPARISON.and); break; case 'or': obj = new Models.ExpressionOperator(Models.EXPRESSION_TYPES.exp_logic, Models.LOGIC_COMPARISON.or); break; case 'not': obj = new Models.ExpressionOperator(Models.EXPRESSION_TYPES.exp_logic, Models.LOGIC_COMPARISON.not); break; } // switch (search.value) return obj; } // if (search.instance == "operator") if (search.instance == "expression" && search.type == "const") { if (search.value === true) { var obj = new Models.VariableValueMenu(VariableValueMenuManagement.VAR_OR_VALUE_TYPES.all, LocalizedStrings.getUI('logic_value_true'), null, null, true); return obj; } if (search.value === false) { var obj = new Models.VariableValueMenu(VariableValueMenuManagement.VAR_OR_VALUE_TYPES.all, LocalizedStrings.getUI('logic_value_false'), null, null, true); return obj; } //TODO If constant has value 0, then it is not updating element (let "Select") // ./ivprog/js/visualUI/ivprog_elements.js : export class VariableValueMenu // ./ivprog/js/visualUI/commands/variable_value_menu.js: function isVarInProgram (var_obj, function_obj) var obj = new Models.VariableValueMenu(VariableValueMenuManagement.VAR_OR_VALUE_TYPES.all, search.value, null, null, true); return obj; } var variavel = null; if (search.instance == "expression" && search.type == "var") { // 1. Procurar a variável na função: for (var j = 0; j < function_obj.variables_list.length; j++) { if (function_obj.variables_list[j].name == search.value) { variavel = function_obj.variables_list[j]; break; } } // 2. Procurar a variável nas gloais: if (!variavel) for (var j = 0; j < program_obj.globals.length; j++) { if (program_obj.globals[j].name == search.value) { variavel = program_obj.globals[j]; break; } } // 3. Procurar na lista de parâmetros: if (!variavel) for (var j = 0; j < function_obj.parameters_list.length; j++) { if (function_obj.parameters_list[j].name == search.value) { variavel = function_obj.parameters_list[j]; break; } } } if (search.instance == "expression" && search.type == "var" && !search.line) { var obj = new Models.VariableValueMenu(VariableValueMenuManagement.VAR_OR_VALUE_TYPES.all, variavel, null, null, true); return obj; } if (search.instance == "expression" && search.type == "var" && search.class == "vector") { var obj = new Models.VariableValueMenu(VariableValueMenuManagement.VAR_OR_VALUE_TYPES.all, variavel, null, getVariable(function_obj, search.line[0]), true); return obj; } if (search.instance == "expression" && search.type == "var" && search.class == "matrix") { var varL0 = getVariable(function_obj, search.line[0]); var varC0 = getVariable(function_obj, search.column[0]); var obj = new Models.VariableValueMenu(VariableValueMenuManagement.VAR_OR_VALUE_TYPES.all, variavel, varL0, varC0, true); return obj; } if (search.instance == "expression" && search.type == "function") { var obj = new Models.VariableValueMenu(VariableValueMenuManagement.VAR_OR_VALUE_TYPES.all, variavel, null, null, true); // Search fuction to reference - Procurar a funcao para referencia: for (var i = 0; i < program_obj.functions.length; i++) { if (program_obj.functions[i].name == search.value) { obj.function_called = program_obj.functions[i]; } } // Se ainda não foi encontrada, procurar na biblioteca do iVProg: if (!obj.function_called) { for (var i = 0; i < window.system_functions.length; i++) { if (search.value.split(".")[1] && search.value.split(".")[1] == window.system_functions[i].identifier) { obj.function_called = window.system_functions[i]; } else if (search.value == window.system_functions[i].identifier) { obj.function_called = window.system_functions[i]; } } } obj.parameters_list = []; for (var i = 0; i < search.params.length; i++) { obj.parameters_list.push(getVariable(function_obj,search.params[i][0])); } return obj; } } // function getVariable(function_obj, search) // @calledby codeParser.js: parseWriter(.) export function expressionParserToVisual (text, function_obj, input_field) { console.log("./ivprog/js/visualUI/commands/generic_expression.js: expressionParserToVisual(.)"); //leo if (text.trim().length == 0) { return [new Models.VariableValueMenu(VariableValueMenuManagement.VAR_OR_VALUE_TYPES.all, null, null, null, true)]; } var var_not_found = []; var fun_not_found = []; var parsed; try { parsed = ivprogCore.parseExpression(text); } catch (ex) { Utils.renderErrorMessage(input_field, LocalizedStrings.getUI('expression_invalid')); } if (!parsed) return null; var item_parsed; // to receive each parsed[i] and eventually remove '[' and ']' var sizeOfParsed = parsed.length; for (var i = 0; i < sizeOfParsed; i++) { var variavel = null; item_parsed = parsed[i]; //D console.log(" - " + i + " : type=" + item_parsed.type + " |" + parsed[i] + "| -> " + item_parsed + "|"); if (item_parsed.instance == "expression" && item_parsed.type == "var") { // 1. Procurar a variável na função: for (var j = 0; j < function_obj.variables_list.length; j++) { if (function_obj.variables_list[j].name == item_parsed.value) { variavel = function_obj.variables_list[j]; break; } } // 2. Procurar a variável nas globais: if (!variavel) for (var j = 0; j < program_obj.globals.length; j++) { if (program_obj.globals[j].name == item_parsed.value) { variavel = program_obj.globals[j]; break; } } // 3. Procurar a variável nos parâmetros: if (!variavel) for (var j = 0; j < function_obj.parameters_list.length; j++) { if (function_obj.parameters_list[j].name == item_parsed.value) { variavel = function_obj.parameters_list[j]; break; } } if (!variavel) var_not_found.push(item_parsed.value); } var funcao; if (item_parsed.instance == "expression" && item_parsed.type == "function") { // Procurar a funcao para referencia: for (var j = 0; j < program_obj.functions.length; j++) { if (program_obj.functions[j].name == item_parsed.value) { funcao = program_obj.functions[j]; } } // Se ainda nao encontrou, procurar na biblioteca do iVProg: if (!funcao) { for (var j = 0; j < window.system_functions.length; j++) { if (item_parsed.value.split(".")[1] && item_parsed.value.split(".")[1] == window.system_functions[j].identifier) { funcao = window.system_functions[j]; } else if (item_parsed.value == window.system_functions[j].identifier) { funcao = window.system_functions[j]; } } } if (!funcao) { fun_not_found.push(item_parsed.value); } } } // for (var i = 0; i < sizeOfParsed; i++) if (fun_not_found.length > 0) { let uniqueWords = [...new Set(fun_not_found)]; Utils.renderErrorMessage(input_field, LocalizedStrings.getUI('expression_undeclared_function') + " " + uniqueWords.join(", ")); return null; } if (var_not_found.length > 0) { let uniqueWords = [...new Set(var_not_found)]; Utils.renderErrorMessage(input_field, LocalizedStrings.getUI('expression_undelcared_variable') + " " + uniqueWords.join(", ")); return null; } var exp_obj = []; for (var i = 0; i < sizeOfParsed; i++) { item_parsed = parsed[i]; exp_obj.push(getVariable(function_obj, item_parsed)); } return exp_obj; } // export function expressionParserToVisual(text, function_obj, input_field) export function searchFunction (function_name) { for (var j = 0; j < program_obj.functions.length; j++) { if (program_obj.functions[j].name == function_name) { return program_obj.functions[j]; } } // Se ainda não encontrou, procurar na biblioteca do iVProg: for (var j = 0; j < window.system_functions.length; j++) { if (function_name.split(".")[1] && function_name.split(".")[1] == window.system_functions[j].identifier) { return window.system_functions[j]; } else if (function_name == window.system_functions[j].identifier) { return window.system_functions[j]; } } } // export function searchFunction(function_name) // Verify if it is list with "write_separator" inside "write(.)" // @calledby expressionParserCodeVisual((parsed, function_obj): item = checkIfWriteSeparator(function_obj, item_parsed2, sizeParsed); export function checkIfWriteSeparator (function_obj, item_parsed, sizeParsed) { // verify if it is list with "write_separator" inside "write(.) var item; var check_write_esp = 0, i; if (item_parsed.length==1) item_parsed = item_parsed[0]; // is array with object (get the object) if (item_parsed.type=="const" && item_parsed.class=="simple" && item_parsed.value==" ") { // avoid regular const with value 0 console.log(" [GE.cws] const, simple, branco! #parsed=" + sizeParsed + ", item_parsed.value.length=" + item_parsed.value.length + ", item_parsed.value='" + item_parsed.value + "'*******"); //leo if (sizeParsed>1 && item_parsed.value.length==1 && item_parsed.value.toUpperCase() == item_parsed.value.toLowerCase()) { // String // isNaN(item_parsed.value) if (item_parsed.value.charCodeAt(0)==32) // be sure it is space (not value 0) check_write_esp = 1; // ASCII 32 = ' ' } } if (check_write_esp == 1) { // is 'write_separator'? //TODO Implementar o construtor para espaco em branco - por enquanto troco o espaco pelo operador "+" //TODO Must be used: Models.EXPRESSION_TYPES.write_sep console.log(" [GE.cws] const, simple, branco! check_write_esp=" + check_write_esp + " : " + JSON.stringify(item_parsed) + "*******"); //leo item_parsed.type = Models.EXPRESSION_TYPES.exp_arithmetic; // "write_separator"; item_parsed.value = Models.ARITHMETIC_TYPES.plus; // "plus" item = new Models.ExpressionOperator(Models.EXPRESSION_TYPES.exp_arithmetic, Models.ARITHMETIC_TYPES.plus); // item = new Models.ExpressionOperator(Models.EXPRESSION_TYPES.exp_arithmetic, Models.ARITHMETIC_TYPES.write_sep); } else item = getVariable(function_obj, item_parsed); // if only 1 then the elements are inside it [[{...},{...}...]] return item; } // Process expression // @calledby ./ivprog/js/util/codeParser.js: parseWriter(.): send parameters of "write()" command export function expressionParserCodeVisual (parsed, function_obj) { if (!parsed) return null; var var_not_found = []; var fun_not_found = []; var vet_obj = []; //leo //D var str1 = ""; for (var ii=0; ii0) item_parsed = item_parsed[0]; // if vector get the first console.log(" [GE] " + i + " : type=" + (item_parsed[0] ? item_parsed[0].type : "<>") + " : parsed[" + i + "]=" + JSON.stringify(parsed[i])); var variavel = null; if (item_parsed.instance == "expression" && item_parsed.type == "var") { // 1. Search variable in function: for (var j = 0; j < function_obj.variables_list.length; j++) { if (function_obj.variables_list[j].name == item_parsed.value) { variavel = function_obj.variables_list[j]; break; } } // 2. Search variable in global variables: if (!variavel) for (var j = 0; j < program_obj.globals.length; j++) { if (program_obj.globals[j].name == item_parsed.value) { variavel = program_obj.globals[j]; break; } } // 3. Search variable in parameters: if (!variavel) for (var j = 0; j < function_obj.parameters_list.length; j++) { if (function_obj.parameters_list[j].name == item_parsed.value) { variavel = function_obj.parameters_list[j]; break; } } if (!variavel) var_not_found.push(item_parsed.value); } // if (item_parsed.instance == "expression" && item_parsed.type == "var") var funcao; if (item_parsed.instance == "expression" && item_parsed.type == "function") { // Search the function to reference = Procurar a funcao para referencia: for (var j = 0; j < program_obj.functions.length; j++) { if (program_obj.functions[j].name == item_parsed.value) { funcao = program_obj.functions[j]; } } // If not yet found, search in iVProg library = Se ainda nao encontrou, procurar na biblioteca do iVProg if (!funcao) { for (var j = 0; j < window.system_functions.length; j++) { if (item_parsed.value.split(".")[1] && item_parsed.value.split(".")[1] == window.system_functions[j].identifier) { funcao = window.system_functions[j]; } else if (item_parsed.value == window.system_functions[j].identifier) { funcao = window.system_functions[j]; } } } if (!funcao) { fun_not_found.push(item_parsed.value); } } } // for (var i = 0; i < parsed.length; i++) //ATTENTION: sensible cases ("write(a," ",b)"; "write(a+b)"; "repeat_for i from 0 to 10") var sizeParsed = parsed.length; if (sizeParsed==1) { // array with a single item //D console.log(" [GE] Final: entrou - sizeParsed=" + sizeParsed + ", parsed.length=" + parsed.length); //leo if (parsed[0].length>1) { // ignore constant (as 5 in "repeat_to i from 1 to 5" parsed = parsed[0]; // change to get elements of "parsed" as an array - allaw to work "i+1" (as "write(i+1)") sizeParsed = parsed.length; } } console.log(" [GE] Final: sizeParsed=" + sizeParsed + ", parsed.length=" + parsed.length + "\n [GE] parsed=" + JSON.stringify(parsed)); //leo var exp_obj = []; var item; for (var i=0; i < sizeParsed; i++) { // ./ivprog/js/util/codeParser.js : parseWriter(.): 'CodeParser.expressionParserCodeVisual(command.content, function_obj)' var item_parsed2 = parsed[i]; if (parsed.length === undefined) // in i=0, if "parsed" is not any more an array item_parsed2 = parsed; console.log(" [GE] i=" + i + ": #item_parsed2=" + item_parsed2.length + ", item_parsed2=" + JSON.stringify(item_parsed2)); //leo item = checkIfWriteSeparator(function_obj, item_parsed2, sizeParsed); // eventually change to work with "write(var1," ",var2)" //TODO Trick to identify: write(VAR," ",VAR) => parse = [VAR, " ", VAR] exp_obj.push(item); console.log(" [GE] Type " + (item_parsed2[0] ? item_parsed2[0].type : "<>") + "; Insert in 'exp_obj[" + i + "]=|" + JSON.stringify(item) + "|"); //leo } // for (var i = 0; i < sizeParsed; i++) return exp_obj; } // export function expressionParserCodeVisual(parsed, function_obj)