From e0036cba812b00cf21ea7f413dd4409928c8d7a9 Mon Sep 17 00:00:00 2001 From: jberg Date: Sun, 14 Jul 2019 17:16:57 -0700 Subject: [PATCH] tweak 2 arg operatores and coercion (#810) --- .../src/maki-interpreter/virtualMachine.js | 62 +++++++------------ 1 file changed, 21 insertions(+), 41 deletions(-) diff --git a/experiments/modern/src/maki-interpreter/virtualMachine.js b/experiments/modern/src/maki-interpreter/virtualMachine.js index 9bb0e969..c596ac67 100644 --- a/experiments/modern/src/maki-interpreter/virtualMachine.js +++ b/experiments/modern/src/maki-interpreter/virtualMachine.js @@ -13,7 +13,7 @@ function coerceTypes(var1, var2, val1, val2) { async function interpret(start, program, stack = [], { logger = null }) { const { commands, methods, variables, classes, offsetToCommand } = program; - function twoArgOperator(operator) { + function twoArgCoercingOperator(operator) { const a = stack.pop(); const b = stack.pop(); let aValue = a instanceof Variable ? a.getValue() : a; @@ -23,6 +23,15 @@ async function interpret(start, program, stack = [], { logger = null }) { stack.push(operator(bValue, aValue)); } + function twoArgOperator(operator) { + const a = stack.pop(); + const b = stack.pop(); + const aValue = a instanceof Variable ? a.getValue() : a; + const bValue = b instanceof Variable ? b.getValue() : b; + + stack.push(operator(bValue, aValue)); + } + // Run all the commands that are safe to run. Increment this number to find // the next bug. let i = start; @@ -52,32 +61,32 @@ async function interpret(start, program, stack = [], { logger = null }) { } // == case 8: { - twoArgOperator((b, a) => b === a); + twoArgCoercingOperator((b, a) => b === a); break; } // != case 9: { - twoArgOperator((b, a) => b !== a); + twoArgCoercingOperator((b, a) => b !== a); break; } // > case 10: { - twoArgOperator((b, a) => b > a); + twoArgCoercingOperator((b, a) => b > a); break; } // >= case 11: { - twoArgOperator((b, a) => b >= a); + twoArgCoercingOperator((b, a) => b >= a); break; } // < case 12: { - twoArgOperator((b, a) => b < a); + twoArgCoercingOperator((b, a) => b < a); break; } // <= case 13: { - twoArgOperator((b, a) => b <= a); + twoArgCoercingOperator((b, a) => b <= a); break; } // jumpIf @@ -190,11 +199,7 @@ async function interpret(start, program, stack = [], { logger = null }) { } // + (add) case 64: { - const a = stack.pop(); - const b = stack.pop(); - stack.push(b.getValue() + a.getValue()); - // TODO: Why can't we use twoArgOperator here? - // twoArgOperator((b, a) => b + a); + twoArgOperator((b, a) => b + a); break; } // - (subtract) @@ -204,13 +209,7 @@ async function interpret(start, program, stack = [], { logger = null }) { } // * (multiply) case 66: { - const a = stack.pop(); - const b = stack.pop(); - const aValue = a instanceof Variable ? a.getValue() : a; - const bValue = b instanceof Variable ? b.getValue() : b; - stack.push(bValue * aValue); - // TODO: Why can't we use twoArgOperator here? - // twoArgOperator((b, a) => b * a); + twoArgOperator((b, a) => b * a); break; } // / (divide) @@ -224,12 +223,11 @@ async function interpret(start, program, stack = [], { logger = null }) { const b = stack.pop(); const aValue = a instanceof Variable ? a.getValue() : a; let bValue = b instanceof Variable ? b.getValue() : b; + // Need to coerce LHS if not int, RHS is always int (enforced by compiler) if (b.type === "FLOAT" || b.type === "DOUBLE") { bValue = Math.floor(bValue); } stack.push(bValue % aValue); - // TODO: Why can't we use twoArgOperator here? - // twoArgOperator((b, a) => b % a); break; } // & (binary and) @@ -258,30 +256,12 @@ async function interpret(start, program, stack = [], { logger = null }) { } // logAnd (&&) case 80: { - const a = stack.pop(); - const aValue = a instanceof Variable ? a.getValue() : a; - if (!aValue) { - stack.push(false); - break; - } - - const b = stack.pop(); - const bValue = b instanceof Variable ? b.getValue() : b; - stack.push(!!bValue); + twoArgOperator((b, a) => b && a); break; } // logOr || case 81: { - const a = stack.pop(); - const aValue = a instanceof Variable ? a.getValue() : a; - if (aValue) { - stack.push(true); - break; - } - - const b = stack.pop(); - const bValue = b instanceof Variable ? b.getValue() : b; - stack.push(!!bValue); + twoArgOperator((b, a) => b || a); break; } // <<