11let 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+
6989let 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