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;
const hide = function (vector) {
vector.visible = false;
remove_vector_arrow(vector);
return {description: `vector@${vector.id} is hidden`};
}
@ -30,21 +31,28 @@ const label = function (vector, text) {
}
const show = function (vector) {
vector.visible = true;
add_vector_arrow_to_svg(vector);
return {description: `vector@${vector.id} is visible`};
}
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) {
let value = visit(state[binding.name].lazy_expression);
let existing_value = bindings[binding.name].evaluated;
if (existing_value) {
if (existing_value.id) {
update_vector_arrow(existing_value.id, 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 () {
@ -109,7 +117,6 @@ const handle_enter = function () {
}
if (value.is_visual) {
if (value.is_vector) {
if (binding && bindings[binding].previous && bindings[binding].previous.is_visual) {
update_vector_arrow(bindings[binding].previous.id, value);
} else {
@ -119,6 +126,9 @@ const handle_enter = function () {
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();
@ -175,7 +185,7 @@ const visit = function (expr) {
case token_types.STAR:
return multiplication(visit(expr.left), visit(expr.right));
case token_types.SLASH:
return visit(expr.left) / visit(expr.right);
return division(visit(expr.left), visit(expr.right));
case token_types.DOT:
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)
@ -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);
}
if (right && right.is_vector && !left.is_vector) {
if (right.is_vector && !left.is_vector) {
return multiply(right, left);
}
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) {
if (left && left.is_vector && right && right.is_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.type = 'vector'; // for showing type to user
vector.is_new = true;
vector.visible = true;
vector.toString = function () {
return `vector@${this.id}{x0:${vector.x0},y0:${vector.y0} x:${vector.x},y:${vector.y}}`;
};

View file

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