File tree Expand file tree Collapse file tree 1 file changed +86
-0
lines changed Expand file tree Collapse file tree 1 file changed +86
-0
lines changed Original file line number Diff line number Diff line change @@ -31,3 +31,89 @@ const e = (x, v = []) =>
31
31
) ,
32
32
} [ x [ 0 ] ] ( ) ) ,
33
33
} [ typeof x ] ( ) )
34
+
35
+ // another
36
+
37
+ /**
38
+ * @param {string } expression
39
+ * @return {number }
40
+ */
41
+ const evaluate = function ( expression ) {
42
+ const tokens = tokenizer ( expression )
43
+ let i = 0
44
+ function exec ( scope ) {
45
+ let value = null
46
+ const next = tokens [ i ++ ]
47
+ if ( next === '(' ) {
48
+ scope = enter ( scope )
49
+ switch ( tokens [ i ++ ] ) {
50
+ case 'add' :
51
+ const a = exec ( scope )
52
+ const b = exec ( scope )
53
+ value = a + b
54
+ break
55
+ case 'mult' :
56
+ const x = exec ( scope )
57
+ const y = exec ( scope )
58
+ value = x * y
59
+ break
60
+ case 'let' :
61
+ while ( tokens [ i ] !== '(' && tokens [ i + 1 ] !== ')' ) {
62
+ scope . variables [ tokens [ i ++ ] ] = exec ( scope )
63
+ }
64
+ value = exec ( scope )
65
+ break
66
+ }
67
+ scope = exit ( scope )
68
+ i ++
69
+ } else if ( isNumber ( next ) ) {
70
+ value = Number ( next )
71
+ } else {
72
+ // Find variable in current scope otherwise go to parent
73
+ let t = scope
74
+ while ( t ) {
75
+ if ( next in t . variables ) {
76
+ value = t . variables [ next ]
77
+ break
78
+ }
79
+ t = t . parent
80
+ }
81
+ }
82
+ return value
83
+ }
84
+ return exec ( newScope ( ) )
85
+ }
86
+ function tokenizer ( expression ) {
87
+ const tokens = [ ]
88
+ let token = ''
89
+ for ( const c of expression ) {
90
+ if ( c === '(' || c === ')' ) {
91
+ if ( token ) tokens . push ( token )
92
+ tokens . push ( c )
93
+ token = ''
94
+ } else if ( c === ' ' ) {
95
+ if ( token ) tokens . push ( token )
96
+ token = ''
97
+ } else {
98
+ token += c
99
+ }
100
+ }
101
+ if ( token ) {
102
+ tokens . push ( token )
103
+ }
104
+ return tokens
105
+ }
106
+ function isNumber ( n ) {
107
+ return ! isNaN ( n )
108
+ }
109
+ function newScope ( ) {
110
+ return { parent : null , variables : { } }
111
+ }
112
+ function enter ( scope ) {
113
+ const next = newScope ( )
114
+ next . parent = scope
115
+ return next
116
+ }
117
+ function exit ( scope ) {
118
+ return scope . parent
119
+ }
You can’t perform that action at this time.
0 commit comments