Skip to content

Commit abea98b

Browse files
committed
support recursion
1 parent 86e72a8 commit abea98b

1 file changed

Lines changed: 29 additions & 8 deletions

File tree

interpret.js

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,22 @@
11
let program = [
22
{
33
fn: {
4-
'max': [['a', 'b'], [
5-
{
6-
if: { '>': [{ val: 'a' }, { val: 'b' }] },
7-
then: [{ val: 'a' }],
8-
else: [{ val: 'b' }]
4+
'fibonacci': [['n'], [
5+
{
6+
if: { '<=': [{ val: 'n' }, 1] },
7+
then: [{ val: 'n' }],
8+
else: [{
9+
'+': [
10+
{ 'fibonacci': [{ '-': [{ val: 'n' }, 1] }] },
11+
{ 'fibonacci': [{ '-': [{ val: 'n' }, 2] }] },
12+
]
13+
}]
914
}
1015
]]
1116
}
1217
},
1318
{
14-
print: { max: [3, 5] }
19+
print: { fibonacci: [6] }
1520
}
1621
]
1722

@@ -24,6 +29,8 @@ let binaryOperators = {
2429
'-': (a, b) => { return a - b },
2530
'*': (a, b) => { return a * b },
2631
'>': (a, b) => { return a > b },
32+
'>=': (a, b) => { return a >= b },
33+
'<=': (a, b) => { return a <= b },
2734
'<': (a, b) => { return a < b },
2835
'==': (a, b) => { return a == b },
2936
'||': (a, b) => { return a || b },
@@ -66,13 +73,27 @@ let fnStatement = (stmt, key, state) => {
6673
state.vars[fnName] = { args: fnArgs, body: fnBody }
6774
}
6875

76+
let resolveVarName = (varName, currentState) => {
77+
if (typeof currentState.vars[varName] !== 'undefined') {
78+
return currentState.vars[varName];
79+
} else {
80+
if (currentState.parent != null) {
81+
return resolveVarName(varName, currentState.parent);
82+
} else {
83+
throw new Error(`could not find: ${varName}`);
84+
}
85+
}
86+
87+
}
88+
6989
let fnExec = (stmt, key, state) => {
7090
let fnName = key;
7191
let fnArgs = stmt[fnName];
72-
let fn = state.vars[fnName];
92+
let fn = resolveVarName(fnName, state); //find in current or parent states
7393
let newState = { vars: {}, parent: state };
94+
newState.vars[fnName] = fn; //attach current function defn to its own local state
7495
for (let [index, argName] of fn.args.entries()) {
75-
newState.vars[argName] = fnArgs[index];
96+
newState.vars[argName] = exec(fnArgs[index],state);
7697
}
7798
return interpret(fn.body, newState);
7899
}

0 commit comments

Comments
 (0)