diff --git a/src/instruction.js b/src/Instruction.js similarity index 53% rename from src/instruction.js rename to src/Instruction.js index c05deaf2..ccf2528e 100644 --- a/src/instruction.js +++ b/src/Instruction.js @@ -1,12 +1,22 @@ class Instruction { - constructor(scope, statement, before, run, graph, root, derivative) { + constructor( + scope, + statement, + before, + run, + graph, + after, + derivative = true, + priority = false + ) { this.scope = scope; this.statement = statement; this.before = before; this.run = run; this.graph = graph; - this.root = root; + this.after = after; this.derivative = derivative; + this.priority = priority; } } diff --git a/src/lang/$nuc/$ASSIGNMENT.js b/src/lang/$nuc/$ASSIGNMENT.js index 0034a549..ef60317a 100644 --- a/src/lang/$nuc/$ASSIGNMENT.js +++ b/src/lang/$nuc/$ASSIGNMENT.js @@ -6,7 +6,7 @@ const $INSTANCE = require("./$INSTANCE"); const Identifier = require("../ast/Identifier"); const graph = require("../../graph"); const CLASS = require("../../nuc/CLASS"); -const Instruction = require("../../instruction"); +const Instruction = require("../../Instruction"); function build(kind, left, right) { let statement = new $ASSIGNMENT(); @@ -91,15 +91,7 @@ class $ASSIGNMENT extends $ { } run(scope) { - return new Instruction( - scope, - this.$, - undefined, - true, - undefined, - undefined, - undefined - ); + return new Instruction(scope, this.$, null, true, null, null, null); } } diff --git a/src/lang/$nuc/$BLOCK.js b/src/lang/$nuc/$BLOCK.js index e5b7c012..c1d304cd 100644 --- a/src/lang/$nuc/$BLOCK.js +++ b/src/lang/$nuc/$BLOCK.js @@ -1,7 +1,7 @@ const BLOCK = require("../../nuc/BLOCK"); const BLOCK$CLASS = require("../../nuc/BLOCK$CLASS"); const $ = require("./$"); -const Instruction = require("../../instruction"); +const Instruction = require("../../Instruction"); const Scope = require("../../Scope"); const { v4: uuid } = require("uuid"); const _ = require("lodash"); @@ -77,8 +77,8 @@ class $BLOCK extends $ { statement.class = $class; statement.statements = this.stms; return [ - new Instruction(scope, statement, true, true, false), - new Instruction(scope, statement, false, false, true), + new Instruction(scope, statement, true, true, false, false), + new Instruction(scope, statement, false, false, true, true), ]; } else { let statement = new BLOCK(uuid()); @@ -86,8 +86,8 @@ class $BLOCK extends $ { statement.skip = this.skp; return [ - new Instruction(scope, statement, true, true, false), - new Instruction(scope, statement, false, false, true), + new Instruction(scope, statement, true, true, false, false), + new Instruction(scope, statement, false, false, true, true), ]; } } diff --git a/src/lang/$nuc/$FOR.js b/src/lang/$nuc/$FOR.js index e0138a94..50f3525c 100644 --- a/src/lang/$nuc/$FOR.js +++ b/src/lang/$nuc/$FOR.js @@ -1,6 +1,6 @@ const $ = require("./$"); const FOR = require("../../nuc/FOR"); -const Instruction = require("../../instruction"); +const Instruction = require("../../Instruction"); const Identifier = require("../ast/Identifier"); function build(variable, array, statements) { @@ -18,7 +18,7 @@ class $FOR extends $ { statement.array = new Identifier(this.arr); statement.statements = this.stms; - return new Instruction(scope, statement, false, true, false); + return new Instruction(scope, statement, false, true, false, false); } } diff --git a/src/lang/$nuc/$IF.js b/src/lang/$nuc/$IF.js index e30c279b..e086e67d 100644 --- a/src/lang/$nuc/$IF.js +++ b/src/lang/$nuc/$IF.js @@ -3,7 +3,7 @@ const graph = require("../../graph"); const IF = require("../../nuc/IF"); const CLASS = require("../../nuc/CLASS"); const IF$CLASS = require("../../nuc/IF$CLASS"); -const Instruction = require("../../instruction"); +const Instruction = require("../../Instruction"); const Expression = require("../../Expression"); const $EXPRESSION = require("./$EXPRESSION"); const Identifier = require("../ast/Identifier"); @@ -42,8 +42,8 @@ class $IF extends $ { } return [ - new Instruction(scope, statement, true, true, false, null, true), - new Instruction(scope, statement, false, false, true, null, true), + new Instruction(scope, statement, true, true, false, false), + new Instruction(scope, statement, false, false, true, true), ]; } } @@ -54,8 +54,8 @@ class $IF extends $ { statement.false = this.fls; return [ - new Instruction(scope, statement, true, true, false, null, true), - new Instruction(scope, statement, false, false, true, null, true), + new Instruction(scope, statement, true, true, false, false), + new Instruction(scope, statement, false, false, true, true), ]; } } diff --git a/src/lang/$nuc/$INSTANCE.js b/src/lang/$nuc/$INSTANCE.js index 405fa64f..0608ba29 100644 --- a/src/lang/$nuc/$INSTANCE.js +++ b/src/lang/$nuc/$INSTANCE.js @@ -4,7 +4,7 @@ const CLASS = require("../../nuc/CLASS"); const $LET = require("./$LET"); const Identifier = require("../ast/Identifier"); const random = require("../../lib/random"); -const Instruction = require("../../instruction"); +const Instruction = require("../../Instruction"); function build(cls, object, name, args = []) { let statement = new $INSTANCE(); @@ -58,8 +58,8 @@ class $INSTANCE extends $ { statement.name = name; statement.object = graph.retrieve(object); return [ - new Instruction(scope, statement, true, true, false, null, true), - new Instruction(scope, statement, false, false, true, null, true), + new Instruction(scope, statement, true, true, false, false), + new Instruction(scope, statement, false, false, true, true), ]; } else { const statement = new OBJECT(`${object}.${name}`); diff --git a/src/lang/$nuc/$PROPERTY.js b/src/lang/$nuc/$PROPERTY.js index 29223973..eaa99752 100644 --- a/src/lang/$nuc/$PROPERTY.js +++ b/src/lang/$nuc/$PROPERTY.js @@ -8,7 +8,7 @@ const Local = require("../../lib/local"); const FUNCTION = require("../../nuc/FUNCTION"); const Identifier = require("../ast/Identifier"); const $EXPRESSION = require("./$EXPRESSION"); -const Instruction = require("../../instruction"); +const Instruction = require("../../Instruction"); function build(object, name, value) { let statement = new $PROPERTY(); @@ -48,8 +48,8 @@ class $PROPERTY extends $ { statement.name = name; statement.value = this.val; return [ - new Instruction(scope, statement, true, true, false, null, true), - new Instruction(scope, statement, false, false, true, null, true), + new Instruction(scope, statement, true, true, false, false), + new Instruction(scope, statement, false, false, true, true), ]; } @@ -57,7 +57,7 @@ class $PROPERTY extends $ { statement.object = graph.retrieve(object); statement.name = name; statement.value = this.val; - return new Instruction(scope, statement, true, true, true); + return new Instruction(scope, statement, true, true, true, true); } } diff --git a/src/nuc/BLOCK$CLASS.js b/src/nuc/BLOCK$CLASS.js index 147bf831..87562481 100644 --- a/src/nuc/BLOCK$CLASS.js +++ b/src/nuc/BLOCK$CLASS.js @@ -1,6 +1,6 @@ const NODE = require("./NODE"); const BLOCK$INSTANCE = require("./BLOCK$INSTANCE"); -const Instruction = require("../instruction"); +const Instruction = require("../Instruction"); const { v4: uuid } = require("uuid"); const Scope = require("../Scope"); @@ -33,10 +33,10 @@ class BLOCK$CLASS extends NODE { instanceScope.$instance = this; statements.push( - new Instruction(instanceScope, statement, true, true, false) + new Instruction(instanceScope, statement, true, true, false, false) ); statements.push( - new Instruction(instanceScope, statement, false, false, true) + new Instruction(instanceScope, statement, false, false, true, true) ); } diff --git a/src/nuc/BLOCK.js b/src/nuc/BLOCK.js index ba296fdc..017f9d25 100644 --- a/src/nuc/BLOCK.js +++ b/src/nuc/BLOCK.js @@ -1,6 +1,6 @@ const NODE = require("./NODE"); const $ = require("../lang/$nuc/$"); -const Instruction = require("../instruction"); +const Instruction = require("../Instruction"); const Scope = require("../Scope"); class BLOCK extends NODE { @@ -14,7 +14,8 @@ class BLOCK extends NODE { newScope.block = this; return { next: this.statements.map( - (statement) => new Instruction(newScope, statement) + (statement) => + new Instruction(newScope, statement, null, null, null, null) ), }; } diff --git a/src/nuc/DELETE.js b/src/nuc/DELETE.js index d5514c0c..05afb696 100644 --- a/src/nuc/DELETE.js +++ b/src/nuc/DELETE.js @@ -1,6 +1,6 @@ const state = require("../state"); const graph = require("../graph"); -const Instruction = require("../instruction"); +const Instruction = require("../Instruction"); const Node = require("./NODE"); class DELETE { @@ -15,7 +15,9 @@ class DELETE { for (let node in graph.retrieve(key).next) { const statement = graph.retrieve(node); - list.push(new Instruction(scope.root, statement, false, true, false)); + list.push( + new Instruction(scope.root, statement, false, true, false, false) + ); } return { next: list, value: true }; diff --git a/src/nuc/FOR.js b/src/nuc/FOR.js index c911c10b..8d6a2330 100644 --- a/src/nuc/FOR.js +++ b/src/nuc/FOR.js @@ -1,5 +1,5 @@ const $BLOCK = require("../lang/$nuc/$BLOCK"); -const Instruction = require("../instruction"); +const Instruction = require("../Instruction"); const $LET = require("../lang/$nuc/$LET"); const state = require("../state"); const graph = require("../graph"); @@ -35,7 +35,7 @@ class FOR { this.index++; } - list.push(new Instruction(scope, this, false, true, false)); + list.push(new Instruction(scope, this, false, true, false, false)); return { next: list }; } } diff --git a/src/nuc/IF$CLASS.js b/src/nuc/IF$CLASS.js index 501b6775..a9589b58 100644 --- a/src/nuc/IF$CLASS.js +++ b/src/nuc/IF$CLASS.js @@ -4,7 +4,7 @@ const NODE = require("./NODE"); const _ = require("lodash"); const { v4: uuid } = require("uuid"); const Scope = require("../Scope"); -const Instruction = require("../instruction"); +const Instruction = require("../Instruction"); class IF$CLASS extends NODE { run(scope) { @@ -34,7 +34,7 @@ class IF$CLASS extends NODE { instanceScope.$instance = instance; statements.push( - new Instruction(instanceScope, statement, true, true, true, null, true) + new Instruction(instanceScope, statement, true, true, true, true) ); } diff --git a/src/nuc/IF.js b/src/nuc/IF.js index e8e40f43..4fafe662 100644 --- a/src/nuc/IF.js +++ b/src/nuc/IF.js @@ -1,5 +1,5 @@ const NODE = require("./NODE"); -const Instruction = require("../instruction"); +const Instruction = require("../Instruction"); const Scope = require("../Scope"); const state = require("../state"); const _ = require("lodash"); @@ -23,16 +23,16 @@ class IF extends NODE { const trueStatement = _.cloneDeep(this.true); return { next: [ - new Instruction(local, trueStatement, true, true, false), - new Instruction(local, trueStatement, false, false, true), + new Instruction(local, trueStatement, true, true, false, false), + new Instruction(local, trueStatement, false, false, true, true), ], }; } else if (this.false) { const falseStatement = _.cloneDeep(this.false); return { next: [ - new Instruction(local, falseStatement, true, true, false), - new Instruction(local, falseStatement, false, false, true), + new Instruction(local, falseStatement, true, true, false, false), + new Instruction(local, falseStatement, false, false, true, true), ], }; } diff --git a/src/nuc/OBJECT$CLASS.js b/src/nuc/OBJECT$CLASS.js index 9fa729a9..c57676dd 100644 --- a/src/nuc/OBJECT$CLASS.js +++ b/src/nuc/OBJECT$CLASS.js @@ -3,7 +3,7 @@ const Id = require("../lib/identifier"); const OBJECT$INSTANCE = require("./OBJECT$INSTANCE"); const graph = require("../graph"); const Scope = require("../Scope"); -const Instruction = require("../instruction"); +const Instruction = require("../Instruction"); class OBJECT$CLASS extends NODE { before() { @@ -32,7 +32,7 @@ class OBJECT$CLASS extends NODE { instanceScope.$instance = instance; statements.push( - new Instruction(instanceScope, statement, true, true, true, null, true) + new Instruction(instanceScope, statement, true, true, true, true) ); } diff --git a/src/nuc/OBJECT.js b/src/nuc/OBJECT.js index 63df195b..cc2b9c33 100644 --- a/src/nuc/OBJECT.js +++ b/src/nuc/OBJECT.js @@ -1,6 +1,6 @@ const state = require("../state"); const NODE = require("./NODE"); -const Instruction = require("../instruction"); +const Instruction = require("../Instruction"); const Scope = require("../Scope"); const Evaluation = require("../lang/Evaluation"); const Identifier = require("../lang/ast/Identifier"); @@ -69,8 +69,30 @@ class OBJECT extends NODE { const scope = new Scope(); scope.$instance = this; - list.push(new Instruction(scope, declaration, true, true, false, true)); - list.push(new Instruction(scope, declaration, false, false, true, true)); + list.push( + new Instruction( + scope, + declaration, + true, + true, + false, + false, + true, + true + ) + ); + list.push( + new Instruction( + scope, + declaration, + false, + false, + true, + true, + true, + true + ) + ); } const expression = new Instruction( @@ -78,6 +100,7 @@ class OBJECT extends NODE { $EXPRESSION(variable.node), true, true, + false, false ); expression.derivative = false; diff --git a/src/nuc/PROPERTY$CLASS.js b/src/nuc/PROPERTY$CLASS.js index f1611497..e25b3375 100644 --- a/src/nuc/PROPERTY$CLASS.js +++ b/src/nuc/PROPERTY$CLASS.js @@ -1,7 +1,7 @@ const NODE = require("./NODE"); const PROPERTY$INSTANCE = require("./PROPERTY$INSTANCE"); const _ = require("lodash"); -const Instruction = require("../instruction"); +const Instruction = require("../Instruction"); const Scope = require("../Scope"); class PROPERTY$CLASS extends NODE { @@ -27,7 +27,7 @@ class PROPERTY$CLASS extends NODE { instanceScope.$instance = instance; statements.push( - new Instruction(instanceScope, statement, true, true, true, null, true) + new Instruction(instanceScope, statement, true, true, true, true) ); } diff --git a/src/stack.js b/src/stack.js index a1fef380..23950193 100644 --- a/src/stack.js +++ b/src/stack.js @@ -1,8 +1,9 @@ const state = require("./state"); const graph = require("./graph"); +const NODE = require("./nuc/NODE"); const BLOCK = require("./nuc/BLOCK"); const IF = require("./nuc/IF"); -const Instruction = require("./instruction"); +const Instruction = require("./Instruction"); const Scope = require("./Scope"); const Node = require("./nuc/NODE"); const $ = require("./lang/$nuc/$"); @@ -15,7 +16,8 @@ function process(statements, prior, options = {}) { const { declarative } = options; let instructions = statements.map( - (statement) => new Instruction(root, statement, true, true, false) + (statement) => + new Instruction(root, statement, true, true, false, false, false) // TODO Confirm graph is false ); let result = { value: undefined, $nuc: [] }; @@ -82,8 +84,8 @@ function process(statements, prior, options = {}) { false, true, false, - null, - declarative + false, + instruction.derivative ); } }) @@ -103,7 +105,15 @@ function process(statements, prior, options = {}) { let next = statement.run(instruction.scope); next = Array.isArray(next) ? next : [next]; next.push( - new Instruction(instruction.scope, statement, false, false, true) + new Instruction( + instruction.scope, + statement, + false, + false, + true, + true, + null + ) ); const scope = instruction.scope; @@ -112,25 +122,36 @@ function process(statements, prior, options = {}) { .map((statement) => { return statement instanceof Instruction ? statement - : new Instruction(scope, statement, true, true, true); // TODO root = null? + : new Instruction( + scope, + statement, + true, + true, + true, + true, + null + ); }) .map((statement) => { statement.before = statement.before ?? instruction.before; statement.run = statement.run ?? instruction.run; statement.graph = statement.graph ?? instruction.graph; + statement.after = statement.after ?? instruction.after; statement.derivative = statement.derivative ?? instruction.derivative; return statement; }); - instructions = next.filter((i) => !i.root).concat(instructions); - priorities = next.filter((i) => i.root).concat(priorities); + instructions = next.concat(instructions); } if (instruction.graph) { statement.graph(instruction.scope); + } + + if (instruction.after) { + statement.after(instruction.scope); - // TODO Move this to after if (!instruction.derivative && !statement.asg) { if (statement.iof === "$EXPRESSION") { if (statement.tkns.wrt) { @@ -164,27 +185,17 @@ function process(statements, prior, options = {}) { .map((statement) => { return statement instanceof Instruction ? statement - : new Instruction( - scope, - statement, - true, - true, - true, - null, - true - ); + : new Instruction(scope, statement, true, true, true, true); }) .map((statement) => { statement.before = statement.before ?? instruction.before; statement.run = statement.run ?? instruction.run; statement.graph = statement.graph ?? instruction.graph; - statement.derivative = - statement.derivative ?? instruction.derivative; return statement; }); - instructions = next.filter((i) => !i.root).concat(instructions); - priorities = next.filter((i) => i.root).concat(priorities); + instructions = next.filter((i) => !i.priority).concat(instructions); + priorities = next.filter((i) => i.priority).concat(priorities); } } @@ -201,7 +212,7 @@ function process(statements, prior, options = {}) { continue; } - if (statement instanceof Node) { + if (statement instanceof NODE) { if (graph.retrieve(statement.key)) { Node.replace(statement.key, statement); } else { @@ -233,14 +244,14 @@ function process(statements, prior, options = {}) { if (n instanceof BLOCK || n instanceof IF) { let scope = new Scope(); dependents.push( - new Instruction(scope, n, false, true, false, null, true) + new Instruction(scope, n, false, true, false, false) ); dependents.push( - new Instruction(scope, n, false, false, true, null, true) + new Instruction(scope, n, false, false, true, true) ); } else { dependents.push( - new Instruction(s, n, false, true, false, null, true) + new Instruction(s, n, false, true, false, false) ); } }); @@ -251,7 +262,7 @@ function process(statements, prior, options = {}) { if (!instruction.statement.skip) { dependencies.forEach((source) => { const targetKey = statement.key; - Node.direct(source.key, targetKey, statement); + NODE.direct(source.key, targetKey, statement); }); }