so far unsuccesful attempt to introduce laziness. checking this in and then start refactoring some stuff that's in the way

This commit is contained in:
Sander Hautvast 2021-02-18 17:08:53 +01:00
parent a56cc0f46d
commit da5d9c7bdc
4 changed files with 6668 additions and 149 deletions

115
dist/bundle.js vendored

File diff suppressed because one or more lines are too long

6582
package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
import {scan, token_types} from './scanner';
import {parse} from './parser';
import {add_vector, remove_vector} from "./index";
import {add_vector, remove_vector, update_vector_arrow} from "./index";
/**
* handles user input from the console div
@ -12,6 +12,25 @@ command_input_element.value = '';
let command_history = [''];
let command_history_index = 0;
export const update_lazy_objects = function () {
let lazy_objects = Object.values(state).filter(e => Object.prototype.hasOwnProperty.apply(e, ['lazy_expression']));
for (let index = 0; index < lazy_objects.length; index++) {
let object = lazy_objects[index];
let value = visit_expression(object.lazy_expression);
let existing_value = state[object.binding];
if (existing_value) {
update_vector_arrow(existing_value.object.id, value.object);
}
state[object.binding].object = value.object;
let description = state[object.binding].description;
if (!description) {
description = state[object.binding];
}
return {description: object.binding + ':' + description};
}
}
export const adjust_input_element_height = function () {
let num_lines = command_input_element.value.split(/\n/).length;
command_input_element.setAttribute('style', 'height: ' + num_lines + 'em');
@ -70,10 +89,11 @@ command_input_element.onkeyup = function handle_key_input(event) {
}
};
let visit_expression = function (expr) {
export let visit_expression = function (expr) {
switch (expr.type) {
case 'declaration': {
let value = visit_expression(expr.initializer);
console.log(value);
let existing_value = state[expr.var_name.value];
if (existing_value) {
if (existing_value.type === 'vector') {
@ -127,19 +147,21 @@ let visit_expression = function (expr) {
case 'literal':
return expr.value;
case 'call':
return call(expr.name, expr.arguments);
case 'lazy':
console.log(expr.value);
return visit_expression(expr.value);
return function_call(expr.name, expr.arguments);
case 'lazy': {
let r = visit_expression(expr.value);
r.lazy_expression = expr.value;
return r;
}
}
}
const call = function (function_name, argument_exprs) {
const function_call = function (function_name, argument_exprs) {
let arguments_list = [];
for (let i = 0; i < argument_exprs.length; i++) {
arguments_list.push(visit_expression(argument_exprs[i]));
}
if (functions[function_name]) {
if (Object.prototype.hasOwnProperty.apply(functions, [function_name])) {
return functions[function_name](arguments_list);
} else {
let arg_list = '';
@ -162,7 +184,7 @@ const method_call = function (object_wrapper, method_or_property) {
return object_wrapper.object[method_or_property.name].apply(object_wrapper, method_or_property.arguments);
} else { // property
if (!Object.prototype.hasOwnProperty.call(object_wrapper.object, method_or_property.name)) {
if (!Object.prototype.hasOwnProperty.call(object_wrapper.object, [method_or_property.name])) {
throw {message: `property ${method_or_property.name} not found on ${object_wrapper.type}`};
}
return object_wrapper.object[method_or_property.name];
@ -176,7 +198,7 @@ const functions = {
help: () => help(),
vector: (args) => add_vector({x0: args[0], y0: args[1], x: args[2], y: args[3]}),
remove: (args) => {
if (Object.prototype.hasOwnProperty.call(args[0],'binding')){
if (Object.prototype.hasOwnProperty.call(args[0], ['binding'])) {
delete state[args[0].binding];
return remove_vector(args[0].object); // by binding value
} else {

View file

@ -1,8 +1,6 @@
import './console.js';
import './scanner.js';
import './parser.js';
export let add_vector, remove_vector;
import {update_lazy_objects} from "./console";
/**
* Main entry. draws the matrix
@ -25,7 +23,7 @@ const create = function (element_type) {
}
/**
* creates the d attribute string
* calculate the screen coordinates for grid values
* @param x0 start_x
* @param y0 start_y
* @param x1 end_x
@ -33,7 +31,19 @@ const create = function (element_type) {
* @returns {string} to put in an SVG path
*/
const calculate_d = function (x0, y0, x1, y1) {
return "M" + x0 + " " + y0 + " L" + x1 + " " + y1;
return create_d(origin_x + x0 * grid_size, origin_y - y0 * grid_size,
+origin_x + x1 * grid_size, origin_y - y1 * grid_size);
}
/**
* create a d attribute from screen coordinates
* @param s_x0
* @param s_y0
* @param s_x1
* @param s_y1
* @returns {string}
*/
const create_d = function (s_x0, s_y0, s_x1, s_y1) {
return "M" + s_x0 + " " + s_y0 + " L" + s_x1 + " " + s_y1;
}
/**
@ -47,7 +57,7 @@ const calculate_d = function (x0, y0, x1, y1) {
*/
const create_line = function (x0, y0, x1, y1, css_class) {
let path = create('path');
path.setAttribute('d', calculate_d(x0, y0, x1, y1));
path.setAttribute('d', create_d(x0, y0, x1, y1));
path.setAttribute('class', css_class);
return path;
}
@ -119,17 +129,23 @@ const remove_child = function (element, child_id) {
const redraw_grid = function () {
remove_child(svg, "grid");
svg.appendChild(create_grid('grid', 'bg-grid'));
remove_child(svg, 'axes');
svg.appendChild(create_axes());
}
export const update_vector_arrow = function (id, vector) {
let d = calculate_d(vector.x0, vector.y0, vector.x, vector.y);
document.getElementById(id).setAttribute('d', d);
}
/**
* Adds a vector to the set.
* @param vector
*/
add_vector = function (vector) {
export const add_vector = function (vector) {
vector.id = vectors.length;
vectors.push(vector);
redraw();
add_vector_to_group(vector);
vector.add = (other) => add_vector({
x0: vector.x0 + other.x0,
y0: vector.x0 + other.x0,
@ -152,7 +168,7 @@ add_vector = function (vector) {
}
remove_vector = function (vector_or_index) {
export const remove_vector = function (vector_or_index) {
let index;
if (vector_or_index.is_vector) {
for (let i = 0; i < vectors.length; i++) {
@ -170,7 +186,7 @@ remove_vector = function (vector_or_index) {
}
vectors.splice(index, 1);
redraw();
remove_child(document.getElementById('vectors'), index.toString());
return {description: `vector@${index} removed`};
}
@ -184,7 +200,7 @@ const move_vector = function (event) {
let current_y = event.clientY;
vectors[moving_vector.id].x = (current_x - origin_x) / grid_size;
vectors[moving_vector.id].y = (origin_y - current_y) / grid_size;
moving_vector.setAttribute('d', calculate_d(origin_x, origin_y, current_x, current_y));
moving_vector.setAttribute('d', create_d(origin_x, origin_y, current_x, current_y));
}
}
@ -197,22 +213,34 @@ const move_vector = function (event) {
* }
*/
const draw_vectors = function () {
const vector_group = create("g");
vector_group.id = 'vectors';
const vector_group = create_vector_group();
for (let i = 0; i < vectors.length; i++) {
let vector_arrow = arrow(vectors[i].id,
origin_x + vectors[i].x0 * grid_size,
origin_y - vectors[i].y0 * grid_size,
origin_x + vectors[i].x * grid_size,
origin_y - vectors[i].y * grid_size,
add_vector_to_group(vectors[i], vector_group);
}
svg.appendChild(vector_group);
}
const add_vector_to_group = function (vector, vector_group) {
if (!vector_group) {
vector_group = document.getElementById('vectors');
}
if (!vector_group) {
vector_group = create_vector_group();
}
let vector_arrow = arrow(vector.id, vector.x0, vector.y0, vector.x, vector.y,
'vector');
vector_arrow.onmousedown = function start_moving_vector(event) {
moving_vector = event.target;
};
vector_group.appendChild(vector_arrow);
}
const create_vector_group = function () {
const vector_group = create("g");
vector_group.id = 'vectors';
svg.appendChild(vector_group);
return vector_group;
}
/**
@ -233,6 +261,7 @@ const redraw = function () {
const create_axes = function () {
let axes_group = create('g');
axes_group.setAttribute('id', 'axes');
let x = create_line(0, origin_y, width, origin_y, 'axis');
x.id = 'x-axis';
axes_group.appendChild(x);
@ -272,9 +301,10 @@ function create_defs() {
const create_svg = function () {
let svg = create('svg');
svg.onmousemove = move_vector();
svg.onmousemove = move_vector;
svg.onmouseup = function stop_moving_vector() {
moving_vector = undefined;
update_lazy_objects();
};
let defs = create_defs();