// 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)