11import { StmtNS , ExprNS } from '../ast-types' ;
22import { PyContext } from './py_context' ;
33import { PyControl , PyControlItem } from './py_control' ;
4- import { PyNode , Instr , InstrType , UnOpInstr , BinOpInstr , BoolOpInstr } from './py_types' ;
4+ import { PyNode , Instr , InstrType , UnOpInstr , BinOpInstr , BoolOpInstr , AssmtInstr } from './py_types' ;
55import { Stash , Value , ErrorValue } from './stash' ;
66import { IOptions } from '..' ;
77import * as instr from './py_instrCreator' ;
@@ -10,6 +10,7 @@ import { TokenType } from '../tokens';
1010import { Token } from '../tokenizer' ;
1111import { Result , Finished , CSEBreak , Representation } from '../types' ;
1212import { toPythonString } from '../stdlib'
13+ import { pyGetVariable , pyDefineVariable } from './py_utils' ;
1314
1415type CmdEvaluator = (
1516 command : PyControlItem ,
@@ -149,20 +150,44 @@ const pyCmdEvaluators: { [type: string]: CmdEvaluator } = {
149150 } ,
150151
151152 'Variable' : ( command , context , control , stash , isPrelude ) => {
152- const variable = command as ExprNS . Variable ;
153- const name = variable . name . lexeme ;
154- // For now, we only handle built in constants.
155- // In a future commit, we will look up variables in the environment.
153+ const variableNode = command as ExprNS . Variable ;
154+ const name = variableNode . name . lexeme ;
155+
156156 if ( name === 'True' ) {
157157 stash . push ( { type : 'bool' , value : true } ) ;
158158 } else if ( name === 'False' ) {
159159 stash . push ( { type : 'bool' , value : false } ) ;
160160 } else {
161- // Throw an error for undefined variables for now
162- throw new Error ( `NameError: name '${ name } ' is not defined` ) ;
161+ // if not built in, look up in environment
162+ const value = pyGetVariable ( context , name , variableNode )
163+ stash . push ( value ) ;
163164 }
164165 } ,
165166
167+ 'Compare' : ( command , context , control , stash , isPrelude ) => {
168+ const compareNode = command as ExprNS . Compare ;
169+ // For now, we only handle simple, single comparisons.
170+ const opStr = mapOperatorToPyOperator ( compareNode . operator ) ;
171+ const op_instr = instr . binOpInstr ( opStr , compareNode ) ;
172+ control . push ( op_instr ) ;
173+ control . push ( compareNode . right ) ;
174+ control . push ( compareNode . left ) ;
175+ } ,
176+
177+ 'Assign' : ( command , context , control , stash , isPrelude ) => {
178+ const assignNode = command as StmtNS . Assign ;
179+
180+ const assmtInstr = instr . assmtInstr (
181+ assignNode . name . lexeme ,
182+ false ,
183+ true ,
184+ assignNode
185+ ) ;
186+
187+ control . push ( assmtInstr ) ;
188+ control . push ( assignNode . value ) ;
189+ } ,
190+
166191 /**
167192 * Instruction Handlers
168193 */
@@ -242,4 +267,13 @@ const pyCmdEvaluators: { [type: string]: CmdEvaluator } = {
242267 throw new Error ( `Unsupported boolean operator: ${ instr . symbol } ` ) ;
243268 }
244269 } ,
270+
271+ [ InstrType . ASSIGNMENT ] : ( command , context , control , stash , isPrelude ) => {
272+ const instr = command as AssmtInstr ;
273+ const value = stash . pop ( ) ; // Get the evaluated value from the stash
274+
275+ if ( value ) {
276+ pyDefineVariable ( context , instr . symbol , value ) ;
277+ }
278+ } ,
245279} ;
0 commit comments