def record_create(obj): t = env.look(_tenv, obj.children[0]) addr = tree.Temp(env.new_temp()) if not t: error(obj.pos, 'no such type : %s' % (obj.children[0])) return None if t[0] != 'TY_RECORD': error(obj.pos, 'type is not record : %s' % (obj.children[0])) return None size = len(t[1]) if len(obj.children[1]) != size: error( obj.pos, 'need %d items, but give %d items in record: %s' % (len(obj.children[1]), size, obj.children[0])) i = 0 record = [] while i < size: index = find_record_index(t[1], obj.children[1][i].children[0]) if index is None: error( obj.pos, "record create error, type %s has no such item : \'%s\'" % (obj.children[0], obj.children[1][i].children[0])) value = build_IR_tree_exp(obj.children[1][i]) location = tree.Binop('+', addr, tree.Const(index * frame.WORD_SIZE)) record.append(tree.Move(tree.Mem(location), value)) i += 1 alloc = tree.Call(tree.Name("__recordCreate__"), [size]) r = [tree.Move(addr, alloc)] + record return tree.Eseq(ir_seq_list(r), addr, t)
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 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 var_dec(obj): global _venv access = [_level, frame.alloc_local(frame.get_frame(_level), [True])] t = env.look(_tenv, obj.children[1]) value = build_IR_tree_exp(obj.children[2]) if obj.children[1] is None: t = value.ty elif t is None: error(obj.pos, "variable type error, no shch type : %s" % (obj.children[1])) return [] elif t != value.ty: error( obj.pos, "type error, the exprression is %s type not %s type" % (value.ty, t)) return [] if env.look(_venv, '_var_' + obj.children[0]): error(obj.pos, "variable redefined : %s" % (obj.children[0])) # 保存数组大小 if (t[0] == 'TY_ARRAY') and (len(t) == 2): # t += [obj.children[2].children[1].children[0]] t += [build_IR_tree_exp(obj.children[2].children[1])] env.enter(_venv, '_var_' + obj.children[0], [access, t]) return tree.Move(simple_var(obj), value)
def move_exp(obj): dst = build_IR_tree_exp(obj.children[0]) src = build_IR_tree_exp(obj.children[1]) if dst.ty != src.ty: error(obj.pos, "can not assign %s to %s" % (src.ty, dst.ty)) return tree.Move(dst, src)