fixed lazy eval, so that objects that disappear when a lazy expression is first nonsense, but then fixed, reappear again

This commit is contained in:
Sander Hautvast 2021-03-02 17:09:08 +01:00
parent 41c7551b4b
commit 655bfcc4a3
2 changed files with 59 additions and 23 deletions

View file

@ -19,6 +19,7 @@ let command_history_index = 0;
let index_sequence = 0; let index_sequence = 0;
const hide = function (vector) { const hide = function (vector) {
vector.visible = false;
remove_vector_arrow(vector); remove_vector_arrow(vector);
return {description: `vector@${vector.id} is hidden`}; return {description: `vector@${vector.id} is hidden`};
} }
@ -30,21 +31,28 @@ const label = function (vector, text) {
} }
const show = function (vector) { const show = function (vector) {
vector.visible = true;
add_vector_arrow_to_svg(vector); add_vector_arrow_to_svg(vector);
return {description: `vector@${vector.id} is visible`}; return {description: `vector@${vector.id} is visible`};
} }
export const update_lazy_objects = function () { export const update_lazy_objects = function () {
Object.values(bindings).forEach(binding => { let b = Object.values(bindings);
for (let i = 0; i < b.length; i++) {
let binding = b[i];
if (state[binding.name].lazy_expression) { if (state[binding.name].lazy_expression) {
let value = visit(state[binding.name].lazy_expression); let value = visit(state[binding.name].lazy_expression);
let existing_value = bindings[binding.name].evaluated; let existing_value = bindings[binding.name].evaluated;
if (existing_value) { if (existing_value.id) {
update_vector_arrow(existing_value.id, value); update_vector_arrow(existing_value.id, value);
bindings[binding.name].evaluated = value; bindings[binding.name].evaluated = value;
} else if (value.is_new && value.is_vector){
// hidden lazy object reappearing
value.label_text=binding.name;
add_vector_arrow_to_svg(value);
}
} }
} }
});
} }
export const adjust_input_element_height = function () { export const adjust_input_element_height = function () {
@ -109,7 +117,6 @@ const handle_enter = function () {
} }
if (value.is_visual) { if (value.is_visual) {
if (value.is_vector) {
if (binding && bindings[binding].previous && bindings[binding].previous.is_visual) { if (binding && bindings[binding].previous && bindings[binding].previous.is_visual) {
update_vector_arrow(bindings[binding].previous.id, value); update_vector_arrow(bindings[binding].previous.id, value);
} else { } else {
@ -119,6 +126,9 @@ const handle_enter = function () {
add_vector_arrow(value); add_vector_arrow(value);
} }
} }
} else {
if (binding && bindings[binding].previous && bindings[binding].previous.is_visual) {
label(bindings[binding].previous, '@' + bindings[binding].previous.id);
} }
} }
update_lazy_objects(); update_lazy_objects();
@ -175,7 +185,7 @@ const visit = function (expr) {
case token_types.STAR: case token_types.STAR:
return multiplication(visit(expr.left), visit(expr.right)); return multiplication(visit(expr.left), visit(expr.right));
case token_types.SLASH: case token_types.SLASH:
return visit(expr.left) / visit(expr.right); return division(visit(expr.left), visit(expr.right));
case token_types.DOT: case token_types.DOT:
return method_call(visit(expr.left), expr.right); // right is not evaluated. It's the method name return method_call(visit(expr.left), expr.right); // right is not evaluated. It's the method name
// could also be evaluated to itself, BUT it's of type call which would invoke a function (see below) // could also be evaluated to itself, BUT it's of type call which would invoke a function (see below)
@ -268,10 +278,10 @@ const functions = {
hide: (args) => { hide: (args) => {
return hide(args[0]); return hide(args[0]);
}, },
label: (args) =>{ label: (args) => {
return label(args[0], args[1]); return label(args[0], args[1]);
}, },
show: (args) =>{ show: (args) => {
return show(args[0]); return show(args[0]);
} }
} }
@ -296,15 +306,34 @@ const multiplication = function (left, right) {
}); });
}; };
if (left && left.is_vector && !right.is_vector) { if (left.is_vector && !right.is_vector) {
return multiply(left, right); return multiply(left, right);
} }
if (right && right.is_vector && !left.is_vector) { if (right.is_vector && !left.is_vector) {
return multiply(right, left); return multiply(right, left);
} }
return left * right; return left * right;
} }
const division = function (left, right) {
const divide = function (vector, scalar) {
return create_vector({
x0: vector.x0 / scalar,
y0: vector.y0 / scalar,
x: vector.x / scalar,
y: vector.y / scalar
});
};
if (left.is_vector && !right.is_vector) {
return divide(left, right);
}
if (!left.is_vector && !right.is_vector) {
return left / right;
}
throw {message: 'meaningless division'};
}
const addition = function (left, right) { const addition = function (left, right) {
if (left && left.is_vector && right && right.is_vector) { if (left && left.is_vector && right && right.is_vector) {
return create_vector({ return create_vector({
@ -335,6 +364,7 @@ export const create_vector = function (vector) { //rename to create_vector
vector.is_vector = true; // for comparison vector.is_vector = true; // for comparison
vector.type = 'vector'; // for showing type to user vector.type = 'vector'; // for showing type to user
vector.is_new = true; vector.is_new = true;
vector.visible = true;
vector.toString = function () { vector.toString = function () {
return `vector@${this.id}{x0:${vector.x0},y0:${vector.y0} x:${vector.x},y:${vector.y}}`; return `vector@${this.id}{x0:${vector.x0},y0:${vector.y0} x:${vector.x},y:${vector.y}}`;
}; };
@ -351,7 +381,7 @@ export const create_vector = function (vector) { //rename to create_vector
return vector; return vector;
} }
const resolve_arguments = function(argument_exprs) { const resolve_arguments = function (argument_exprs) {
let arguments_list = []; let arguments_list = [];
for (let i = 0; i < argument_exprs.length; i++) { for (let i = 0; i < argument_exprs.length; i++) {
arguments_list.push(visit(argument_exprs[i])); arguments_list.push(visit(argument_exprs[i]));

View file

@ -191,8 +191,10 @@ const draw_vectors = function () {
let vectors = Object.values(vectors_by_id); let vectors = Object.values(vectors_by_id);
for (let i = 0; i < vectors.length; i++) { for (let i = 0; i < vectors.length; i++) {
if (vectors[i].visible) {
add_vector_arrow_to_svg(vectors[i]); add_vector_arrow_to_svg(vectors[i]);
} }
}
svg.appendChild(vector_group); svg.appendChild(vector_group);
} }
@ -231,7 +233,11 @@ export const update_vector_arrow = function (existing_id, new_vector) {
arrow.setAttribute('d', d); arrow.setAttribute('d', d);
arrow.id = new_vector.id; arrow.id = new_vector.id;
update_label(existing_id, new_vector.id, calc_screen_x(new_vector.x) + 5, calc_screen_y(new_vector.y) + 5); update_label(existing_id, new_vector.id, calc_screen_x(new_vector.x) + 5, calc_screen_y(new_vector.y) + 5);
} else {
add_vector_arrow_to_svg(new_vector);
} }
delete vectors_by_id[existing_id];
vectors_by_id[new_vector.id] = new_vector;
} }
/** /**