def evaluate(self,node): """Evaluator function Evaluates the parse tree rooted at the current node Basically a giant if construct that decides what to do based on the type of node (as found by the string at node[0]) """ if DEBUG: print "Evaluating",node if self.cur_line>=len(self.parse_trees): #reached end of the list of parse trees return None if node[0]=='STMT': # statement line=self.cur_line self.evaluate(node[1]) if self.cur_line==line: self.evaluate(node[-1]) elif node[0]=='DIM': # declaration name=node[1][1] # gets the name of the identifier only (e.g. in myvar and myvar(3,3), myvar is the name) id_node=node[1] # parse tree rooted at id_node represents an identifier # not specifying a data type makes it INTEGER by default if len(node)>2: datatype=DATA_TYPES[node[2]] else: datatype=DATA_TYPES['INTEGER'] # declaring two variables with the same name (or the name of a predefined function) is not allowed if name in self.variables: raise InterpreterError("Runtime Error: %s already declared"%name) if len(id_node)==2: # scalar: simply create a new Variable var=Variable(name,datatype,datatype(0)) #print "creating scalar %s"%name,var.__class__ else: # array: get dimensions by evaluating the list following the name and create a MultiArray dimensions=self.evaluate(id_node[-1]) var=MultiArray(dimensions, name, datatype,datatype(0)) self.variables[name]=var self.cur_line+=1 elif node[0]=='LET': # assignment varname=node[1][1] # left hand side value=self.evaluate(node[2]) # right hand side #print "got value ",value #if DEBUG: # print value if varname not in self.variables: rhs_type=get_type(value,value) #print ">>>>>>",rhs_type if len(node[1])==2: # not an array: automatic declaration ##print "+++++",DATA_TYPES[rhs_type] var=Variable(varname,DATA_TYPES[rhs_type],cast(DATA_TYPES[rhs_type],ctypes.c_long(0))) #print "value: ",var.value else: # array raise InterpreterError("Cannot assign to undeclared array %s: "%varname) self.variables[varname]=var #print "just assigned ",varname," to ", var.value.__class__ else: var=self.variables[varname] if len(node[1])==2: # not an array: simple assignment #print "type: ", var.type #print "value: ", value if var.type!=value.__class__: #print "here" var.value=var.type(REQUIRED_PY_TYPE[var.type](value.value)) else: var.value=value else: # array: figure out indices first and then try to assign coords=self.evaluate(node[1][-1]) try: var.set_(coords,var.type(REQUIRED_PY_TYPE[var.type](value.value))) except AttributeError,e: raise InterpreterError("Cannot assign to %s"%varname) #print "checking: ",self.variables[varname].value self.cur_line+=1