@@ -72,22 +72,23 @@ const hasOwnProperty = (object: unknown, propertyKey: PropertyKey) => (
7272 Object . prototype . hasOwnProperty . call ( object , propertyKey )
7373) ;
7474
75- const generate = ( expression : Expression < Complex > ) : ( variables : Bindings ) => Value => {
75+ const generate = ( expression : Expression < Complex > , constants : Bindings ) :
76+ ( variables : Bindings ) => Value => {
7677 const { type } = expression ;
7778
7879 switch ( type ) {
7980 case 'BinaryExpression' : {
8081 const operator = binary [ expression . operator ] ;
81- const left = generate ( expression . left ) ;
82- const right = generate ( expression . right ) ;
82+ const left = generate ( expression . left , constants ) ;
83+ const right = generate ( expression . right , constants ) ;
8384 return ( variables ) => operator (
8485 asComplexOrThrow ( left ( variables ) ) ,
8586 asComplexOrThrow ( right ( variables ) ) ,
8687 ) ;
8788 }
8889 case 'CallExpression' : {
89- const callee = generate ( expression . callee ) ;
90- const args = expression . arguments . map ( generate ) ;
90+ const callee = generate ( expression . callee , constants ) ;
91+ const args = expression . arguments . map ( ( argument ) => generate ( argument , constants ) ) ;
9192 return ( variables ) => asFunctionOrThrow ( callee ( variables ) ) . apply (
9293 undefined ,
9394 args . map ( ( argument ) => asComplexOrThrow ( argument ( variables ) ) ) ,
@@ -97,7 +98,11 @@ const generate = (expression: Expression<Complex>): (variables: Bindings) => Val
9798 const { name } = expression ;
9899 return ( variables ) => {
99100 if ( ! hasOwnProperty ( variables , name ) ) {
100- throw new ReferenceError ( `${ name } is not defined` ) ;
101+ if ( ! hasOwnProperty ( constants , name ) ) {
102+ throw new ReferenceError ( `${ name } is not defined` ) ;
103+ }
104+
105+ return constants [ name ] ;
101106 }
102107
103108 return variables [ name ] ;
@@ -109,7 +114,7 @@ const generate = (expression: Expression<Complex>): (variables: Bindings) => Val
109114 }
110115 case 'UnaryExpression' : {
111116 const operator = unary [ expression . operator ] ;
112- const argument = generate ( expression . argument ) ;
117+ const argument = generate ( expression . argument , constants ) ;
113118 return ( variables ) => operator ( asComplexOrThrow ( argument ( variables ) ) ) ;
114119 }
115120 default :
@@ -144,7 +149,7 @@ const asLiteralIfConstant = (
144149 return expression ;
145150 }
146151
147- const evaluate = generate ( expression ) ;
152+ const evaluate = generate ( expression , constants ) ;
148153 return { type : 'Literal' , value : asComplexOrThrow ( evaluate ( constants ) ) } ;
149154} ;
150155
@@ -183,10 +188,10 @@ const transform = (expression: Expression<number>, constants: Bindings): Express
183188 }
184189} ;
185190
186- const compile = ( expression : string , constants : Bindings = { } ) : ( variables : Bindings ) => Value => {
191+ const compile = ( expression : string , constants : Bindings = { } ) : ( variables ? : Bindings ) => Value => {
187192 const record = Object . assign ( { } , bindings , constants ) ;
188- const evaluate = generate ( transform ( parse ( expression ) , record ) ) ;
189- return ( variables ) => evaluate ( Object . assign ( { } , record , variables ) ) ;
193+ const evaluate = generate ( transform ( parse ( expression ) , record ) , record ) ;
194+ return ( variables = { } ) => evaluate ( variables ) ;
190195} ;
191196
192197export default compile ;
0 commit comments