@@ -73,6 +73,7 @@ function evaluateControlItem(
7373 stash : Stash
7474) : void {
7575 if ( isInstr ( item ) ) {
76+ console . log ( 'DEBUG: Evaluating instruction:' , item . instrType ) ;
7677 evaluateInstruction ( item , context , control , stash ) ;
7778 } else if ( isStatementSequence ( item ) ) {
7879 // Handle StatementSequence by pushing all expressions in reverse order
@@ -81,6 +82,7 @@ function evaluateControlItem(
8182 control . push ( seq . body [ i ] ) ;
8283 }
8384 } else {
85+ console . log ( 'DEBUG: Evaluating expression:' , item . constructor . name ) ;
8486 evaluateExpression ( item as Expression , context , control , stash ) ;
8587 }
8688}
@@ -100,6 +102,7 @@ function evaluateExpression(
100102 stash : Stash
101103) : void {
102104 if ( expr instanceof Atomic . NumericLiteral ) {
105+ console . log ( 'DEBUG: Evaluating NumericLiteral:' , expr . value ) ;
103106 stash . push ( { type : 'number' , value : parseFloat ( expr . value ) } ) ;
104107 } else if ( expr instanceof Atomic . ComplexLiteral ) {
105108 try {
@@ -121,13 +124,22 @@ function evaluateExpression(
121124 stash . push ( value ) ;
122125 } else if ( expr instanceof Atomic . Definition ) {
123126 // Push the value to be evaluated, then the define instruction
124- control . push ( expr . value ) ;
127+ // The value will be evaluated first, then the define instruction will use the result
128+ console . log ( 'DEBUG: Definition - expr.value type:' , expr . value . constructor . name ) ;
129+ console . log ( 'DEBUG: Definition - expr.value:' , expr . value ) ;
130+
131+ // Push the define instruction AFTER the value evaluation
132+ // This ensures the value is evaluated and pushed to stash before define runs
133+ console . log ( 'DEBUG: Pushing define instruction after value evaluation' ) ;
125134 control . push ( instr . createDefineInstr ( expr . name . name , expr . value ) ) ;
135+ control . push ( expr . value ) ;
126136 } else if ( expr instanceof Atomic . Reassignment ) {
127137 // Push the value to be evaluated, then the set instruction
128138 control . push ( expr . value ) ;
129139 control . push ( instr . createSetInstr ( expr . name . name , expr . value ) ) ;
130140 } else if ( expr instanceof Atomic . Application ) {
141+ console . log ( 'DEBUG: Evaluating Application with' , expr . operands . length , 'operands' ) ;
142+
131143 // Push the application instruction first (so it's executed last)
132144 control . push ( instr . createAppInstr ( expr . operands . length , expr ) ) ;
133145
@@ -139,11 +151,13 @@ function evaluateExpression(
139151 control . push ( expr . operands [ i ] ) ;
140152 }
141153 } else if ( expr instanceof Atomic . Conditional ) {
142- // Push test, consequent, alternate, then branch instruction
154+ console . log ( 'DEBUG: Evaluating Conditional expression' ) ;
155+ // Push branch instruction AFTER test evaluation
156+ // This ensures test is evaluated and pushed to stash before branch runs
157+ control . push ( instr . createBranchInstr ( expr . consequent , expr . alternate ) ) ;
143158 control . push ( expr . test ) ;
144159 control . push ( expr . consequent ) ;
145160 control . push ( expr . alternate ) ;
146- control . push ( instr . createBranchInstr ( expr . consequent , expr . alternate ) ) ;
147161 } else if ( expr instanceof Atomic . Lambda ) {
148162 // Create closure
149163 const closure : Value = {
@@ -214,9 +228,17 @@ function evaluateInstruction(
214228 switch ( instruction . instrType ) {
215229 case InstrType . DEFINE : {
216230 const value = stash . pop ( ) ;
217- if ( ! value ) throw new Error ( 'No value to define' ) ;
231+ if ( ! value ) {
232+ console . error ( 'DEBUG: Stash is empty when define instruction runs' ) ;
233+ console . error ( 'DEBUG: Stash size:' , stash . size ( ) ) ;
234+ console . error ( 'DEBUG: Define instruction:' , instruction ) ;
235+ throw new Error ( 'No value to define' ) ;
236+ }
218237 const defineInstr = instruction as DefineInstr ;
238+ console . log ( 'DEBUG: Defining' , defineInstr . name , 'with value:' , value ) ;
219239 context . environment . define ( defineInstr . name , value ) ;
240+ // Push void value to indicate successful definition
241+ stash . push ( { type : 'void' } ) ;
220242 break ;
221243 }
222244
@@ -229,15 +251,18 @@ function evaluateInstruction(
229251 }
230252
231253 case InstrType . APPLICATION : {
254+ console . log ( 'DEBUG: Executing APPLICATION instruction' ) ;
232255 const appInstr = instruction as AppInstr ;
233256 const operator = stash . pop ( ) ;
234257 if ( ! operator ) throw new Error ( 'No operator for application' ) ;
258+ console . log ( 'DEBUG: Operator:' , operator ) ;
235259
236260 const args : Value [ ] = [ ] ;
237261 for ( let i = 0 ; i < appInstr . numOfArgs ; i ++ ) {
238262 const arg = stash . pop ( ) ;
239263 if ( arg ) args . unshift ( arg ) ;
240264 }
265+ console . log ( 'DEBUG: Arguments:' , args ) ;
241266
242267 if ( operator . type === 'closure' ) {
243268 // Apply closure
@@ -262,13 +287,21 @@ function evaluateInstruction(
262287 }
263288
264289 case InstrType . BRANCH : {
290+ console . log ( 'DEBUG: Executing BRANCH instruction' ) ;
265291 const test = stash . pop ( ) ;
266- if ( ! test ) throw new Error ( 'No test value for branch' ) ;
292+ if ( ! test ) {
293+ console . error ( 'DEBUG: No test value for branch - stash is empty' ) ;
294+ console . error ( 'DEBUG: Stash size:' , stash . size ( ) ) ;
295+ throw new Error ( 'No test value for branch' ) ;
296+ }
297+ console . log ( 'DEBUG: Test value:' , test ) ;
267298 const branchInstr = instruction as BranchInstr ;
268299
269300 if ( test . type === 'boolean' && test . value ) {
301+ console . log ( 'DEBUG: Taking consequent branch' ) ;
270302 control . push ( branchInstr . consequent ) ;
271303 } else if ( branchInstr . alternate ) {
304+ console . log ( 'DEBUG: Taking alternate branch' ) ;
272305 control . push ( branchInstr . alternate ) ;
273306 }
274307 break ;
0 commit comments