def FnExpression(self, node): expr_result, expr_jump_stmt = self.accept(node.expr) arguments_result, arguments_jump_stmt = self.accept(node.arguments) if all(argument.__class__ is ast.Const for argument in node.arguments.childs): if expr_result.__class__ is Function: node.result = expr_result.run(*arguments_result) else: if not node.initialized: node.body = expr_result.body.clone() func_scope = SymbolTable(expr_result, self.global_scope) self.push_scope(func_scope) for i, parameter in enumerate( expr_result.parameterGroup.childs): func_scope.define(parameter.name, parameter.type, parameter.linespan[0], arguments_result[i], None) node.initialized = True body_result, body_jump_stmt = self.accept(node.body) self.pop_scope() node.result = body_result if self.get_scope().is_pure_function( expr_result.name) and node.result is not None: self.replace(node, ast.Const(node.result, node.linespan)) else: self.set_used(expr_result.name) return node.result, None else: self.set_used(expr_result.name) return None, None
def FnExpression(self, node): expr_terminated, expr_result, expr_jump_stmt = self.accept(node.expr) if not expr_terminated: return False, None, None arguments_terminated, arguments_result, arguments_jump_stmt = self.accept( node.arguments) if not arguments_terminated: return False, None, None if expr_result.__class__ is Function: node.result = expr_result.run(*arguments_result) else: if not node.initialized: node.body = expr_result.body.clone() func_scope = SymbolTable(expr_result, self.global_scope) self.push_scope(func_scope, node.body.linespan[0]) for i, parameter in enumerate( expr_result.parameterGroup.childs): func_scope.define(parameter.name, parameter.type, parameter.linespan[0], arguments_result[i]) node.initialized = True body_terminated, body_result, body_jump_stmt = self.accept( node.body) if not body_terminated: return False, None, None self.pop_scope() node.result = body_result node.terminated = True return node.terminated, node.result, None
def ConditionalStatement(self, node): expr_result, expr_jump_stmt = self.accept(node.expr) if expr_result or (not node.else_section.is_empty()): self.push_scope(SymbolTable(node, self.get_scope())) self.accept(node.then_section) self.pop_scope() if not node.else_section.is_empty(): self.push_scope(SymbolTable(node, self.get_scope())) self.accept(node.else_section) self.pop_scope() return node.result, None
def __init__(self, debug=False): self.global_scope = SymbolTable(ast.EmptyNode(), globalFunctionTable) self.scopes = [self.global_scope] self.linenos = [1] self.line_num = 0 self.debug = debug self.runtime_error = False
def ConditionalStatement(self, node): expr_terminated, expr_result, expr_jump_stmt = self.accept(node.expr) if not expr_terminated: return False, None, None if expr_result or (not node.else_section.is_empty()): section = node.then_section if expr_result else node.else_section if not section.scope_pushed: self.push_scope(SymbolTable(node, self.get_scope()), section.linespan[0]) self.update_lineno(section.linespan[0]) section.scope_pushed = True to_return, terminated, result, jump_stmt = self.visit_with_linecount( section) if to_return: if jump_stmt is not None: self.pop_scope() node.terminated = terminated node.result = result return node.terminated, node.result, jump_stmt self.pop_scope() self.line_num -= 1 self.update_lineno(node.linespan[1]) node.terminated = True return node.terminated, node.result, None
def FnDeclaration(self, node): scope = self.get_scope() scope.define(node.name, node.type, node.linespan[0], node, node) func_scope = SymbolTable(node, self.global_scope) if node.name != 'main': self.push_scope(func_scope) if not node.parameterGroup.is_empty(): for i, parameter in enumerate(node.parameterGroup.childs): func_scope.define(parameter.name, parameter.type, parameter.linespan[0], None) self.accept(node.body) if node.name != 'main': self.pop_scope() else: self.set_used('main') return node.result, None
def FnDeclaration(self, node): if not node.visited: scope = self.get_scope() scope.define(node.name, node.type, node.linespan[0], node) if node.name == 'main': func_scope = SymbolTable(node, self.global_scope) if not node.parameterGroup.is_empty(): for i, parameter in enumerate(node.parameterGroup.childs): func_scope.define(parameter.name, parameter.type, parameter.linespan[0]) if not node.body.visited: self.update_lineno(node.body.linespan[0]) terminated, result, jump_stmt = self.accept(node.body) if not terminated: return False, None, None node.terminated = True return node.terminated, node.result, None
def __init__(self, debug=False, mark_used=False): self.global_scope = SymbolTable(ast.EmptyNode(), globalFunctionTable) self.scopes = [self.global_scope] self.debug = debug self.runtime_error = False self.freeze_constant_folding = False self.freeze_set_constant = False self.check_constant_outer = False self.check_constant_self = False self.mark_used = mark_used
def LoopStatement(self, node): prev_check_constant_outer = self.check_constant_outer prev_check_constant_self = self.check_constant_self self.check_constant_outer = False self.check_constant_self = True node.save_origin() scope = self.get_scope() self.push_scope(SymbolTable(node, scope)) if node.init_stmt is not None: prev_freeze_set_constant = self.freeze_set_constant self.freeze_set_constant = True self.accept(node.init_stmt) self.freeze_set_constant = prev_freeze_set_constant for iter in range(2): expr_result, expr_jump_stmt = self.accept(node.expr) if expr_jump_stmt is not None: node.result = expr_result return node.result, expr_jump_stmt result, jump_stmt = self.accept(node.section) if jump_stmt is not None: if isinstance(jump_stmt, ast.Return): self.pop_scope() node.result = result return node.result, jump_stmt elif isinstance(jump_stmt, ast.Break): self.pop_scope() return None, None elif isinstance(jump_stmt, ast.Continue): pass else: raise ValueError if node.term_stmt is not None: self.accept(node.term_stmt) self.check_constant_self = prev_check_constant_self self.check_constant_outer = True node.save_origin() node.load_origin() self.check_constant_outer = prev_check_constant_outer self.pop_scope() return None, None
class Interpreter: def __init__(self): pass symbol_table = SymbolTable() scope_level = 0 pc = 0 result = [] @classmethod def interpret(cls, quaternions): try: cls.symbol_table.new_table() while cls.pc < len(quaternions): cls.quaternion_analysis(quaternions[cls.pc]) cls.symbol_table.delete_table() temp = cls.result cls.pc = 0 cls.scope_level = 0 cls.result = [] return temp except Exception as e: print(e) @classmethod def quaternion_analysis(cls, quaternion): try: instr_type = quaternion.get_first() # 跳转 if instr_type == Quaternion.GO: # 符合跳转条件 if quaternion.get_second( ) is None or cls.symbol_table.get_symbol_value( quaternion.get_second()).get_value() == False: cls.pc = cls.get_value(quaternion.get_forth()).get_value() return elif instr_type == Quaternion.READ: input_content = raw_input() req_type = cls.symbol_table.get_symbol_type( cls.get_identify(quaternion.get_forth())) if req_type in [SymbolItem.INT, SymbolItem.ARRAY_INT]: value = cls.parse_input(input_content) if value.get_type() == SymbolItem.INT: cls.set_value(quaternion.get_forth(), value) else: raise ErrorInterpret("输入类型不匹配") elif req_type in [SymbolItem.DOUBLE, SymbolItem.ARRAY_DOU]: value = cls.parse_input(input_content) cls.set_value(quaternion.get_forth(), value) elif instr_type == Quaternion.WRITE: index = -1 forth = quaternion.get_forth() if type(forth) == int: cls.result.append(forth) else: if cls.is_array(forth): index = cls.get_array_index(quaternion.get_forth()) cls.result.append( cls.symbol_table.get_symbol_value( quaternion.get_forth(), index).get_value()) elif instr_type == Quaternion.IN: cls.scope_level += 1 elif instr_type == Quaternion.OUT: cls.symbol_table.pop(cls.scope_level) cls.scope_level -= 1 elif instr_type == Quaternion.INT: if quaternion.get_third() is not None: symbol = SymbolItem(quaternion.get_forth(), SymbolItem.ARRAY_INT, s_level=cls.scope_level) symbol.get_value().set_value( quaternion.get_third()) # maybe not work cls.symbol_table.insert(symbol) else: int_value = 0 if quaternion.get_second() is not None: int_value = Value(SymbolItem.INT, int(quaternion.get_second())) symbol = SymbolItem(quaternion.get_forth(), SymbolItem.INT, int_value, cls.scope_level) cls.symbol_table.insert(symbol) elif instr_type == Quaternion.DOUBLE: if quaternion.get_third() is not None: symbol = SymbolItem(quaternion.get_forth(), SymbolItem.ARRAY_DOU, s_level=cls.scope_level) symbol.get_value().set_value( quaternion.get_third()) # maybe not work cls.symbol_table.insert(symbol) else: int_value = 0 if quaternion.get_second() is not None: int_value = Value(SymbolItem.INT, quaternion.get_second()) symbol = SymbolItem(quaternion.get_forth(), SymbolItem.DOUBLE, int_value, cls.scope_level) cls.symbol_table.insert(symbol) elif instr_type == Quaternion.ASSIGN: value = cls.get_value(quaternion.get_second()) cls.set_value(quaternion.get_forth(), value) elif instr_type == Quaternion.PLUS: cls.set_value( quaternion.get_forth(), cls.get_value(quaternion.get_second()).plus( cls.get_value(quaternion.get_third()))) elif instr_type == Quaternion.MINUS: if quaternion.get_third() is not None: cls.set_value( quaternion.get_forth(), cls.get_value(quaternion.get_second()).minus( cls.get_value(quaternion.get_third()))) else: cls.set_value( quaternion.get_forth(), Value.negative(cls.get_value(quaternion.get_second()))) elif instr_type == Quaternion.MUL: cls.set_value( quaternion.get_forth(), cls.get_value(quaternion.get_second()).multiple( cls.get_value(quaternion.get_third()))) elif instr_type == Quaternion.DIV: cls.set_value( quaternion.get_forth(), cls.get_value(quaternion.get_second()).division( cls.get_value(quaternion.get_third()))) elif instr_type == Quaternion.GT: cls.set_value( quaternion.get_forth(), cls.get_value(quaternion.get_second()).greater( cls.get_value(quaternion.get_third()))) elif instr_type == Quaternion.GET: cls.set_value( quaternion.get_forth(), cls.get_value(quaternion.get_second()).greater_equal( cls.get_value(quaternion.get_third()))) elif instr_type == Quaternion.LT: cls.set_value( quaternion.get_forth(), cls.get_value(quaternion.get_second()).less( cls.get_value(quaternion.get_third()))) elif instr_type == Quaternion.LET: cls.set_value( quaternion.get_forth(), cls.get_value(quaternion.get_second()).less_equal( cls.get_value(quaternion.get_third()))) elif instr_type == Quaternion.EQ: cls.set_value( quaternion.get_forth(), cls.get_value(quaternion.get_second()).equal( cls.get_value(quaternion.get_third()))) elif instr_type == Quaternion.NEQ: cls.set_value( quaternion.get_forth(), cls.get_value(quaternion.get_second()).not_equal( cls.get_value(quaternion.get_third()))) cls.pc += 1 except ErrorInterpret as e: print(e.content) # 取值,1 , b[1] @classmethod def get_value(cls, str_id): try: if type(str_id) == float: value = Value(SymbolItem.DOUBLE, str_id) return value elif type(str_id) == int: value = Value(SymbolItem.INT, str_id) return value index = -1 if cls.is_array(str_id): index = cls.get_array_index(str_id) return cls.symbol_table.get_symbol_value(cls.get_identify(str_id), index) except ErrorInterpret as e: print(e.content) # 赋值,a = 2 a[2] = 2 @classmethod def set_value(cls, str_id, value): try: index = cls.get_array_index(str_id) if cls.is_array(str_id) else -1 ident = cls.get_identify(str_id) symbol_type = cls.symbol_table.get_symbol_type(ident) if symbol_type == SymbolItem.INT: if value.get_type() == SymbolItem.INT: cls.symbol_table.set_symbol_value(ident, value) elif value.get_type() == SymbolItem.DOUBLE: raise ErrorInterpret("表达式{0}与变量类型不匹配".format(str_id)) elif symbol_type == SymbolItem.DOUBLE: cls.symbol_table.set_symbol_value(ident, value.to_double()) elif symbol_type == SymbolItem.ARRAY_INT: if cls.symbol_table.get_symbol_value( ident, index).get_type() == SymbolItem.ARRAY_INT: cls.symbol_table.set_symbol_value(ident, value.get_value(), index) else: raise ErrorInterpret("表达式{0}与变量类型不匹配".format(str_id)) elif symbol_type == SymbolItem.ARRAY_DOU: cls.symbol_table.set_symbol_value(ident, float(value.get_value()), index) elif symbol_type == SymbolItem.TEMP: cls.symbol_table.set_symbol_value(ident, value) except ErrorInterpret as e: print(e.content) @classmethod def is_array(cls, str_id): return str_id.endswith("]") @classmethod def get_array_index(cls, str_id): return int(str_id[str_id.index("[") + 1:str_id.index("]")]) @classmethod def get_identify(cls, str_id): if cls.is_array(str_id): return int(str_id[0:str_id.index("[")]) return str_id @classmethod def parse_input(cls, content): try: if re.match('-?([0-9]+.[0-9]+)', content): value = Value(SymbolItem.DOUBLE, string.atof(content)) return value elif re.match('-?[0-9]+]', content): value = Value(SymbolItem.INT, string.atoi(content)) return value raise ErrorInterpret("输入非法") except ErrorInterpret as e: print(e.content)
class Generator: def __init__(self): pass symbol_table = SymbolTable() codes = [] lineCount = -1 scope_level = 0 @classmethod def generate(cls, node_list): cls.symbol_table.new_table() for i in node_list: cls.translate_switch(i) cls.symbol_table.delete_table() temp = cls.codes cls.codes = [] return temp @classmethod def translate_switch(cls, node): while True: node_type = node.get_type() if node_type == Node.IF_STMT: cls.translate_if(node) elif node_type == Node.WHILE_STMT: cls.translate_while(node) elif node_type == Node.READ_STMT: cls.translate_read(node) elif node_type == Node.WRITE_STMT: cls.translate_write(node) elif node_type == Node.DECLARE_STMT: cls.translate_declare(node) elif node_type == Node.ASSIGN_STMT: cls.translate_assign(node) cls.symbol_table.clear_temp_name() if node.get_next() is not None: node = node.get_next() continue break @classmethod def translate_if(cls, node): false_go = Quaternion(Quaternion.GO, cls.translate_exp(node.get_left())) cls.codes.append(false_go) cls.lineCount += 1 cls.codes.append(Quaternion(Quaternion.IN)) # 进入语句块 cls.lineCount += 1 # 代码层级加一 cls.scope_level += 1 # 处理这一层级 cls.translate_switch(node.get_middle()) # 清除局部变量 cls.symbol_table.pop(cls.scope_level) # 代码层级恢复 cls.scope_level -= 1 cls.codes.append(Quaternion(Quaternion.OUT)) cls.lineCount += 1 # 判断else部分子节点是否存在 if node.get_right() is not None: out_go = Quaternion(Quaternion.GO) cls.codes.append(out_go) cls.lineCount += 1 false_go.set_forth(str(cls.lineCount + 1)) cls.codes.append(Quaternion(Quaternion.IN)) cls.lineCount += 1 cls.scope_level += 1 cls.translate_switch(node.get_right()) cls.symbol_table.pop(cls.scope_level) cls.scope_level -= 1 cls.codes.append(Quaternion(Quaternion.OUT)) cls.lineCount += 1 out_go.set_forth(str(cls.lineCount + 1)) else: false_go.set_forth(str(cls.lineCount + 1)) @classmethod def translate_while(cls, node): go_line = cls.lineCount + 1 false_go = Quaternion(Quaternion.GO, cls.translate_exp(node.get_left())) cls.codes.append(false_go) cls.lineCount += 1 cls.codes.append(Quaternion(Quaternion.IN)) cls.lineCount += 1 cls.scope_level += 1 cls.translate_switch(node.get_middle()) cls.symbol_table.pop(cls.scope_level) cls.scope_level -= 1 cls.codes.append(Quaternion(Quaternion.OUT)) cls.lineCount += 1 cls.codes.append(Quaternion(Quaternion.GO, None, None, go_line)) cls.lineCount += 1 false_go.set_forth(cls.lineCount + 1) @classmethod def translate_read(cls, node): try: # 变量类型 var_type = cls.symbol_table.get_symbol_type( node.get_left().get_value()) if var_type in [SymbolItem.INT, SymbolItem.DOUBLE]: cls.codes.append( Quaternion(first=Quaternion.READ, forth=node.get_left().get_value())) cls.lineCount += 1 return elif var_type in [SymbolItem.ARRAY_INT, SymbolItem.ARRAY_DOU]: cls.codes.append( Quaternion(first=Quaternion.READ, forth=node.get_left().get_left() + "[" + cls.translate_exp(node.get_left().get_left()) + "]")) cls.lineCount += 1 return raise ErrorInterpret("语句有误") except ErrorInterpret as e: print(e.content) @classmethod def translate_write(cls, node): cls.codes.append( Quaternion(first=Quaternion.WRITE, forth=cls.translate_exp(node.get_left()))) cls.lineCount += 1 @classmethod def translate_declare(cls, node): var = node.get_left() if var.get_left() is None: value = None if node.get_middle() is not None: value = cls.translate_exp(node.get_middle()) if var.get_data_type() == Token.INT: cls.codes.append( Quaternion(Quaternion.INT, value, None, var.get_value())) cls.lineCount += 1 symbol = SymbolItem(s_name=var.get_value(), s_type=SymbolItem.INT, s_level=cls.scope_level) cls.symbol_table.insert(symbol) elif var.get_data_type() == Token.DOUBLE: cls.codes.append( Quaternion(Quaternion.DOUBLE, value, None, var.get_value())) cls.lineCount += 1 symbol = SymbolItem(s_name=var.get_value(), s_type=SymbolItem.DOUBLE, s_level=cls.scope_level) cls.symbol_table.insert(symbol) else: # 数组 len = cls.translate_exp(var.get_left()) if var.get_data_type() == Token.INT: cls.codes.append( Quaternion(Quaternion.INT, None, len, var.get_value())) cls.lineCount += 1 symbol = SymbolItem(s_name=var.get_value(), s_type=SymbolItem.ARRAY_INT, s_level=cls.scope_level) cls.symbol_table.insert(symbol) elif var.get_data_type() == Token.DOUBLE: cls.codes.append( Quaternion(Quaternion.DOUBLE, None, len, var.get_value())) cls.lineCount += 1 symbol = SymbolItem(s_name=var.get_value(), s_type=SymbolItem.ARRAY_DOU, s_level=cls.scope_level) cls.symbol_table.insert(symbol) # 赋值 @classmethod def translate_assign(cls, node): value = cls.translate_exp(node.get_middle()) var = node.get_left() if var.get_left() is None: cls.codes.append( Quaternion(Quaternion.ASSIGN, value, None, var.get_value())) cls.lineCount += 1 else: index = cls.translate_exp(var.get_left()) cls.codes.append( Quaternion(Quaternion.ASSIGN, value, None, var.get_value() + "[" + index + "]")) cls.lineCount += 1 @classmethod def translate_exp(cls, sub_node): try: if sub_node.get_type() == Node.EXP: data_type = sub_node.get_data_type() if data_type == Token.LOGIC_EXP: return cls.translate_logic_exp(sub_node) elif data_type == Token.MULTI_TERM_EXP: return cls.translate_multi_term_exp(sub_node) elif data_type == Token.TERM_EXP: return cls.translate_term_exp(sub_node) raise ErrorInterpret("表达式非法") elif sub_node.get_type() == Node.FACTOR: if sub_node.get_data_type() == Token.MINUS: temp = cls.symbol_table.get_temp_symbol().get_name() cls.codes.append( Quaternion(Quaternion.MINUS, cls.translate_exp(sub_node.get_left()), None, temp)) cls.lineCount += 1 return temp return cls.translate_exp(sub_node.get_left()) elif sub_node.get_type() == Node.VAR: if sub_node.get_left() is None: if cls.symbol_table.get_symbol_type( sub_node.get_value()) in [ SymbolItem.INT, SymbolItem.DOUBLE ]: return sub_node.get_value() # 数组 else: if cls.symbol_table.get_symbol_type( sub_node.get_value()) in [ SymbolItem.ARRAY_INT, SymbolItem.ARRAY_DOU ]: temp = cls.symbol_table.get_temp_symbol().get_name() index = cls.translate_exp(sub_node.get_left()) cls.codes.append( Quaternion( Quaternion.ASSIGN, sub_node.get_value() + "[" + index + "]", None, temp)) cls.lineCount += 1 return temp elif sub_node.get_type() == Node.LITERAL: return sub_node.get_value() raise ErrorInterpret("表达式非法") except ErrorInterpret as e: print(e.content) @classmethod def translate_logic_exp(cls, node): try: temp = cls.symbol_table.get_temp_symbol().get_name() data_type = node.get_middle().get_data_type() if data_type == Token.GT: cls.codes.append( Quaternion(Quaternion.GT, cls.translate_exp(node.get_left()), cls.translate_exp(node.get_right()), temp)) elif data_type == Token.GET: cls.codes.append( Quaternion(Quaternion.GET, cls.translate_exp(node.get_left()), cls.translate_exp(node.get_right()), temp)) elif data_type == Token.LT: cls.codes.append( Quaternion(Quaternion.LT, cls.translate_exp(node.get_left()), cls.translate_exp(node.get_right()), temp)) elif data_type == Token.LET: cls.codes.append( Quaternion(Quaternion.LET, cls.translate_exp(node.get_left()), cls.translate_exp(node.get_right()), temp)) elif data_type == Token.EQ: cls.codes.append( Quaternion(Quaternion.EQ, cls.translate_exp(node.get_left()), cls.translate_exp(node.get_right()), temp)) elif data_type == Token.NEQ: cls.codes.append( Quaternion(Quaternion.NEQ, cls.translate_exp(node.get_left()), cls.translate_exp(node.get_right()), temp)) else: raise ErrorInterpret("逻辑运算非法") cls.lineCount += 1 return temp except ErrorInterpret as e: print(e.content) @classmethod def translate_multi_term_exp(cls, node): try: temp = cls.symbol_table.get_temp_symbol().get_name() data_type = node.get_middle().get_data_type() if data_type == Token.PLUS: cls.codes.append( Quaternion(Quaternion.PLUS, cls.translate_exp(node.get_left()), cls.translate_exp(node.get_right()), temp)) elif data_type == Token.MINUS: cls.codes.append( Quaternion(Quaternion.MINUS, cls.translate_exp(node.get_left()), cls.translate_exp(node.get_right()), temp)) else: raise ErrorInterpret("算数运算错误") cls.lineCount += 1 return temp except ErrorInterpret as e: print(e.content) @classmethod def translate_term_exp(cls, node): try: op = cls.get_op(node.get_middle().get_data_type()) temp = cls.symbol_table.get_temp_symbol().get_name() if node.get_right().get_type() == Node.FACTOR: cls.codes.append( Quaternion(op, cls.translate_exp(node.get_left()), cls.translate_exp(node.get_right()), temp)) cls.lineCount += 1 else: cls.codes.append( Quaternion(op, cls.translate_exp(node.get_left()), cls.translate_exp(node.get_left().get_right()), temp)) cls.lineCount += 1 node = node.get_right() while node.get_right( ) is not None and node.get_right().get_type() != Node.FACTOR: op = cls.get_op(node.get_middle().get_data_type()) temp2 = cls.symbol_table.get_temp_symbol().get_name() cls.codes.append( Quaternion( op, temp, cls.translate_exp(node.get_right().get_left()), temp2)) cls.lineCount += 1 node = node.get_right() temp = temp2 op = cls.get_op(node.get_middle().get_data_type()) temp2 = cls.symbol_table.get_temp_symbol().get_name() cls.codes.append( Quaternion(op, temp, cls.translate_exp(node.get_right()), temp2)) cls.lineCount += 1 temp = temp2 return temp except ErrorInterpret as e: print(e.content) @classmethod def get_op(cls, op): if op == Token.MUL: return Quaternion.MUL elif op == Token.DIV: return Quaternion.DIV
def LoopStatement(self, node): if not node.visited: node.save_origin() scope = self.get_scope() self.push_scope(SymbolTable(node, scope), node.get_excutable_lineno() + 1) if node.init_stmt is not None: init_stmt_terminated, init_stmt_result, init_stmt_jump_stmt = self.accept( node.init_stmt) if not init_stmt_terminated: return False, None, None while True: to_return, expr_terminated, expr_result, expr_jump_stmt = self.visit_with_linecount( node.expr) if to_return: node.terminated = expr_terminated node.result = expr_result return node.terminated, node.result, expr_jump_stmt if not expr_result: self.pop_scope() node.terminated = True self.update_lineno(node.linespan[1]) self.line_num -= 1 return node.terminated, node.result, None to_return, terminated, result, jump_stmt = self.visit_with_linecount( node.section) if to_return: if jump_stmt is not None: if isinstance(jump_stmt, ast.Return): self.pop_scope() self.update_lineno(node.linespan[1]) node.terminated = terminated node.result = result return node.terminated, node.result, jump_stmt elif isinstance(jump_stmt, ast.Break): self.pop_scope() self.update_lineno(node.linespan[1]) node.terminated = terminated return node.terminated, None, None elif isinstance(jump_stmt, ast.Continue): pass else: raise ValueError else: node.terminated = terminated return node.terminated, None, None if node.term_stmt is not None: term_stmt_terminated, term_stmt_result, term_stmt_jump_stmt = self.accept( node.term_stmt) if (not term_stmt_terminated): return False, None, None self.update_lineno(node.linespan[0]) self.line_num -= 1 node.load_origin()
import sys from model.ast import TypeNode, EmptyNode from model.symbol_table import SymbolTable import codecs class Function: def __init__(self, function, name): self.function = function self.name = name def run(self, *args): return self.function(*args) def printf(format, *args): format_ = codecs.escape_decode(format)[0].decode('unicode_escape') return sys.stdout.write(format_ % args) globalFunctionTable = SymbolTable(EmptyNode()) globalFunctionTable.define('printf', TypeNode(), 0, Function(printf, 'printf')) globalFunctionTable.set_pure_function('printf', False)