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:
parent
a56cc0f46d
commit
da5d9c7bdc
4 changed files with 6668 additions and 149 deletions
115
dist/bundle.js
vendored
115
dist/bundle.js
vendored
File diff suppressed because one or more lines are too long
6582
package-lock.json
generated
Normal file
6582
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -1,6 +1,6 @@
|
||||||
import {scan, token_types} from './scanner';
|
import {scan, token_types} from './scanner';
|
||||||
import {parse} from './parser';
|
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
|
* handles user input from the console div
|
||||||
|
|
@ -12,6 +12,25 @@ command_input_element.value = '';
|
||||||
let command_history = [''];
|
let command_history = [''];
|
||||||
let command_history_index = 0;
|
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 () {
|
export const adjust_input_element_height = function () {
|
||||||
let num_lines = command_input_element.value.split(/\n/).length;
|
let num_lines = command_input_element.value.split(/\n/).length;
|
||||||
command_input_element.setAttribute('style', 'height: ' + num_lines + 'em');
|
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) {
|
switch (expr.type) {
|
||||||
case 'declaration': {
|
case 'declaration': {
|
||||||
let value = visit_expression(expr.initializer);
|
let value = visit_expression(expr.initializer);
|
||||||
|
console.log(value);
|
||||||
let existing_value = state[expr.var_name.value];
|
let existing_value = state[expr.var_name.value];
|
||||||
if (existing_value) {
|
if (existing_value) {
|
||||||
if (existing_value.type === 'vector') {
|
if (existing_value.type === 'vector') {
|
||||||
|
|
@ -127,19 +147,21 @@ let visit_expression = function (expr) {
|
||||||
case 'literal':
|
case 'literal':
|
||||||
return expr.value;
|
return expr.value;
|
||||||
case 'call':
|
case 'call':
|
||||||
return call(expr.name, expr.arguments);
|
return function_call(expr.name, expr.arguments);
|
||||||
case 'lazy':
|
case 'lazy': {
|
||||||
console.log(expr.value);
|
let r = visit_expression(expr.value);
|
||||||
return 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 = [];
|
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_expression(argument_exprs[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);
|
return functions[function_name](arguments_list);
|
||||||
} else {
|
} else {
|
||||||
let arg_list = '';
|
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);
|
return object_wrapper.object[method_or_property.name].apply(object_wrapper, method_or_property.arguments);
|
||||||
|
|
||||||
} else { // property
|
} 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}`};
|
throw {message: `property ${method_or_property.name} not found on ${object_wrapper.type}`};
|
||||||
}
|
}
|
||||||
return object_wrapper.object[method_or_property.name];
|
return object_wrapper.object[method_or_property.name];
|
||||||
|
|
@ -176,7 +198,7 @@ const functions = {
|
||||||
help: () => help(),
|
help: () => help(),
|
||||||
vector: (args) => add_vector({x0: args[0], y0: args[1], x: args[2], y: args[3]}),
|
vector: (args) => add_vector({x0: args[0], y0: args[1], x: args[2], y: args[3]}),
|
||||||
remove: (args) => {
|
remove: (args) => {
|
||||||
if (Object.prototype.hasOwnProperty.call(args[0],'binding')){
|
if (Object.prototype.hasOwnProperty.call(args[0], ['binding'])) {
|
||||||
delete state[args[0].binding];
|
delete state[args[0].binding];
|
||||||
return remove_vector(args[0].object); // by binding value
|
return remove_vector(args[0].object); // by binding value
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,6 @@
|
||||||
import './console.js';
|
|
||||||
import './scanner.js';
|
import './scanner.js';
|
||||||
import './parser.js';
|
import './parser.js';
|
||||||
|
import {update_lazy_objects} from "./console";
|
||||||
export let add_vector, remove_vector;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main entry. draws the matrix
|
* 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 x0 start_x
|
||||||
* @param y0 start_y
|
* @param y0 start_y
|
||||||
* @param x1 end_x
|
* @param x1 end_x
|
||||||
|
|
@ -33,7 +31,19 @@ const create = function (element_type) {
|
||||||
* @returns {string} to put in an SVG path
|
* @returns {string} to put in an SVG path
|
||||||
*/
|
*/
|
||||||
const calculate_d = function (x0, y0, x1, y1) {
|
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) {
|
const create_line = function (x0, y0, x1, y1, css_class) {
|
||||||
let path = create('path');
|
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);
|
path.setAttribute('class', css_class);
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
@ -119,17 +129,23 @@ const remove_child = function (element, child_id) {
|
||||||
const redraw_grid = function () {
|
const redraw_grid = function () {
|
||||||
remove_child(svg, "grid");
|
remove_child(svg, "grid");
|
||||||
svg.appendChild(create_grid('grid', 'bg-grid'));
|
svg.appendChild(create_grid('grid', 'bg-grid'));
|
||||||
|
remove_child(svg, 'axes');
|
||||||
svg.appendChild(create_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.
|
* Adds a vector to the set.
|
||||||
* @param vector
|
* @param vector
|
||||||
*/
|
*/
|
||||||
add_vector = function (vector) {
|
export const add_vector = function (vector) {
|
||||||
vector.id = vectors.length;
|
vector.id = vectors.length;
|
||||||
vectors.push(vector);
|
vectors.push(vector);
|
||||||
redraw();
|
add_vector_to_group(vector);
|
||||||
|
|
||||||
vector.add = (other) => add_vector({
|
vector.add = (other) => add_vector({
|
||||||
x0: vector.x0 + other.x0,
|
x0: vector.x0 + other.x0,
|
||||||
y0: 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;
|
let index;
|
||||||
if (vector_or_index.is_vector) {
|
if (vector_or_index.is_vector) {
|
||||||
for (let i = 0; i < vectors.length; i++) {
|
for (let i = 0; i < vectors.length; i++) {
|
||||||
|
|
@ -170,7 +186,7 @@ remove_vector = function (vector_or_index) {
|
||||||
}
|
}
|
||||||
|
|
||||||
vectors.splice(index, 1);
|
vectors.splice(index, 1);
|
||||||
redraw();
|
remove_child(document.getElementById('vectors'), index.toString());
|
||||||
return {description: `vector@${index} removed`};
|
return {description: `vector@${index} removed`};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -184,7 +200,7 @@ const move_vector = function (event) {
|
||||||
let current_y = event.clientY;
|
let current_y = event.clientY;
|
||||||
vectors[moving_vector.id].x = (current_x - origin_x) / grid_size;
|
vectors[moving_vector.id].x = (current_x - origin_x) / grid_size;
|
||||||
vectors[moving_vector.id].y = (origin_y - current_y) / 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,24 +213,36 @@ const move_vector = function (event) {
|
||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
const draw_vectors = function () {
|
const draw_vectors = function () {
|
||||||
const vector_group = create("g");
|
const vector_group = create_vector_group();
|
||||||
vector_group.id = 'vectors';
|
|
||||||
|
|
||||||
for (let i = 0; i < vectors.length; i++) {
|
for (let i = 0; i < vectors.length; i++) {
|
||||||
let vector_arrow = arrow(vectors[i].id,
|
add_vector_to_group(vectors[i], vector_group);
|
||||||
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,
|
|
||||||
'vector');
|
|
||||||
vector_arrow.onmousedown = function start_moving_vector(event) {
|
|
||||||
moving_vector = event.target;
|
|
||||||
};
|
|
||||||
vector_group.appendChild(vector_arrow);
|
|
||||||
}
|
}
|
||||||
svg.appendChild(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;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes all vectors in the svg and calls draw_vectors to draw updated versions.
|
* Removes all vectors in the svg and calls draw_vectors to draw updated versions.
|
||||||
*/
|
*/
|
||||||
|
|
@ -233,6 +261,7 @@ const redraw = function () {
|
||||||
|
|
||||||
const create_axes = function () {
|
const create_axes = function () {
|
||||||
let axes_group = create('g');
|
let axes_group = create('g');
|
||||||
|
axes_group.setAttribute('id', 'axes');
|
||||||
let x = create_line(0, origin_y, width, origin_y, 'axis');
|
let x = create_line(0, origin_y, width, origin_y, 'axis');
|
||||||
x.id = 'x-axis';
|
x.id = 'x-axis';
|
||||||
axes_group.appendChild(x);
|
axes_group.appendChild(x);
|
||||||
|
|
@ -272,9 +301,10 @@ function create_defs() {
|
||||||
const create_svg = function () {
|
const create_svg = function () {
|
||||||
let svg = create('svg');
|
let svg = create('svg');
|
||||||
|
|
||||||
svg.onmousemove = move_vector();
|
svg.onmousemove = move_vector;
|
||||||
svg.onmouseup = function stop_moving_vector() {
|
svg.onmouseup = function stop_moving_vector() {
|
||||||
moving_vector = undefined;
|
moving_vector = undefined;
|
||||||
|
update_lazy_objects();
|
||||||
};
|
};
|
||||||
|
|
||||||
let defs = create_defs();
|
let defs = create_defs();
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue