예제 #1
0
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)
예제 #2
0
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)
예제 #3
0
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)
    ])
예제 #4
0
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)
예제 #5
0
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)