def get_var(self, name, location='local'): try: if location == 'global': self.global_frame.local_vars[name] elif location == 'local': '''search order: <local -> global>''' try: self.top_frame.local_vars[name] except: self.global_frame.local_vars[name] except KeyError: error(self.__now_line, 'name {0} is not defind')
def general_operation(self, mode): l = self.pop_top_frame_stack() r = self.pop_top_frame_stack() return { 'add' : lambda l, r:l + r, 'sub' : lambda l, r:r - l, 'muit': lambda l, r:l * r, 'div' : lambda l, r:r / l, 'floor' : lambda l, r : r // l }.get(mode, lambda _, __ : error(self.__now_line, 'Unknown mode:{0}'.format(mode)))(l, r)
def call_func(self, argv): func_obj = self.pop_top_frame_stack() if isinstance(func_obj, pobj.PoozNormalFunction): error(self.__now_line, 'target is not a pooz function!') self.opblock_stack.append(func_obj.call()) self.state = STATE_FUNCTION args = self.get_arguments() #get arguments from top stack if len(args) != len(func_obj.params): self.push_error(pobj.PoozErrorObject('Need {0} but found {1}'.format(len(func_obj.params), len(args)))) return #push new frame self.push_frame(PoozFrame(func_obj)) #push var into top frame for i in range(len(args)): self.top_frame.local_var[func_obj.params[i]] = args[i]
def comp_op(self, argv): a = self.pop_top_frame_stack() b = self.pop_top_frame_stack() res = { 1 : lambda a, b : a > b, # > 2 : lambda a, b : a < b, # < 3 : lambda a, b : a >= b, # >= 4 : lambda a, b : a <= b, # <= 5 : lambda a, b : a == b, # == }.get(self.to_number(argv), lambda : error(self.__now_line, 'Operater index {0}'.format(argv))) self.push_top_frame_stack(res)
def run(self, opblock): '''opblock should be PoozOpBlock object''' max_line_num = opblock.last_line.line_no func_op_lnptr = 0 #mainloop while True: if self.state == STATE_NORMAL and self.lnptr <= max_line_num: #normal mode if self.lnptr in opblock: self.execute_instructions(opblock[self.lnptr]) self.lnptr += 1 elif self.state == STATE_FUNCTION: #function mode if func_op_lnptr in self.top_opblock and func_op_lnptr <= self.opblock_max_line_num: self.execute_instructions(self.top_opblock[func_op_lnptr]) elif func_op_lnptr > self.opblock_max_line_num: error(self.__now_line, 'line number out of opblock ({0} but now is {1})' .format(self.opblock_max_line_num, func_op_lnptr)) func_op_lnptr += 1
def get_const(self, index): index = self.to_number(index) try: return self.consts[index] except IndexError: error(self.__now_line, 'Index {0}'.format(index))