def for_exp(obj): start = env.new_label() loop = env.new_label() done = env.new_label() env.begin_scope(_venv) access = [_level, frame.alloc_local(frame.get_frame(_level), [True])] if env.look(_venv, '_var_' + obj.children[0]): error(obj.pos, "for's variable redefined : %s" % (obj.children[0])) env.enter(_venv, '_var_' + obj.children[0], [access, 'TY_INT']) var = frame.expr(access[1], frame.fp()) e1 = build_IR_tree_exp(obj.children[1]) e2 = build_IR_tree_exp(obj.children[2]) e3 = build_IR_tree_exp(obj.children[3]) if e3.ty != 'TY_VOID': error(obj.pos, "for's body must be TY_VOID, unsupport %s type" % (e2.ty)) env.end_scope(_venv) return ir_seq_list([ tree.Move(var, e1), tree.Label(start), tree.Cjump(['<='], var, e2, tree.Name(loop), tree.Name(done)), tree.Label(loop), e3, tree.Move(var, tree.Binop('+', var, tree.Const(1))), tree.Jump(tree.Name(start), [start]), tree.Label(done) ])
def if_then_else_exp(obj): t = env.new_label() f = env.new_label() done = env.new_label() result = env.new_temp() e1 = build_IR_tree_exp(obj.children[0]) if e1.ty != 'TY_INT': error(obj.pos, "if condition must be int not %s" % (e1.ty)) e2 = build_IR_tree_exp(obj.children[1]) e3 = build_IR_tree_exp(obj.children[2]) if (e2.ty != e3.ty) \ and not(((type(e2.ty) is list) and (e2.ty[0] == 'TY_RECORD') and (e3.ty == 'TY_NIL')) \ or ((type(e3.ty) is list) and (e3.ty[0] == 'TY_RECORD') and (e2.ty == 'TY_NIL'))): error(obj.pos, "then type : %s doesn't match else type : %s" % (e2.ty, e3.ty)) return tree.Eseq( ir_seq_list([ un_cx(e1, t, f), tree.Label(t), tree.Move(tree.Mem(result), e2), tree.Jump(tree.Name(done), [done]), tree.Label(f), tree.Move(tree.Mem(result), e3), tree.Label(done) ]), tree.Temp(result), e2.ty)
def if_then_exp(obj): t = env.new_label() f = env.new_label() e1 = build_IR_tree_exp(obj.children[0]) if e1.ty != 'TY_INT': error(obj.pos, "if condition must be int not %s" % (e1.ty)) e2 = build_IR_tree_exp(obj.children[1]) if e2.ty != 'TY_VOID': error(obj.pos, "if then's body must be TY_VOID, unsupport %s type" % (e2.ty)) return ir_seq_list([un_cx(e1, t, f), tree.Label(t), e2, tree.Label(f)])
def fun_dec(obj): global _level _level += 1 if env.look(_venv, '_func_' + obj.children[0]): error(obj.pos, "function redefined : %s" % (obj.children[0])) fun_label = env.new_label() formals = para_list(obj.children[1]) if obj.children[2] is None: result_type = 'TY_VOID' else: result_type = env.look(_tenv, obj.children[2]) frame.new_level_item(_level, fun_label, form_escape_list(obj.children[1])) env.enter(_venv, '_func_' + obj.children[0], [_level, fun_label, formals, result_type]) env.begin_scope(_venv) # fieldList = [] # for item in obj.children[1]: # build_IR_tree_dec(item) i = 0 while i < len(obj.children[1]): access = [_level, frame.get_frame(_level)['formals'][i]] env.enter( _venv, '_var_' + obj.children[1][i].children[0], [access, env.look(_tenv, obj.children[1][i].children[1])]) i += 1 body = build_IR_tree_exp(obj.children[3]) env.end_scope(_venv) frame.add_function(obj.children[0], _level - 1, frame.get_frame(_level), body) _level -= 1 return []
def init_venv(): frame.new_level_item(_level, env.new_label(), []) l1 = env.new_label() frame.new_level_item(_level + 1, l1, []) env.enter(_venv, env.symbol('_func_print'), [_level + 1, l1, ['TY_STRING'], 'TY_VOID']) l2 = env.new_label() frame.new_level_item(_level + 1, l2, []) env.enter(_venv, env.symbol('_func_getchar'), [_level + 1, l2, [], 'TY_STRING']) l3 = env.new_label() frame.new_level_item(_level + 1, l3, []) env.enter(_venv, env.symbol('_func_ord'), [_level + 1, l3, ['TY_STRING'], 'TY_INT']) l4 = env.new_label() frame.new_level_item(_level + 1, l4, []) env.enter(_venv, env.symbol('_func_chr'), [_level + 1, l4, ['TY_INT'], 'TY_STRING'])
def while_exp(obj): start = env.new_label() loop = env.new_label() done = env.new_label() e1 = build_IR_tree_exp(obj.children[0]) if e1.ty != 'TY_INT': error(obj.pos, "while's condition must be int not %s" % (e1.ty)) e2 = build_IR_tree_exp(obj.children[1]) if e2.ty != 'TY_VOID': error(obj.pos, "while's body must be TY_VOID, unsupport %s type" % (e2.ty)) return ir_seq_list([ tree.Label(start), un_cx(e1, loop, done), tree.Label(loop), e2, tree.Jump(tree.Name(start), [start]), tree.Label(done) ])
def get_level(level): new_level_item(level, env.new_label(), []) return _level[level]