def record_var(obj): t = env.look(_venv, '_var_' + obj.children[0].children[0]) if t is None: error(obj.pos, 'no such variable %s:' % (obj.children[0])) elif t[1][0] != 'TY_RECORD': error(obj.pos, 'variable is not record : %s' % (obj.children[0])) index = find_record_index(t[1][1], obj.children[1]) if index is None: error(obj.pos, "no such record item : \'%s\'" % (obj.children[1])) return tree.Mem( tree.Binop( '+', build_IR_tree_exp(obj.children[0]), tree.Binop('*', tree.Const(index), tree.Const(frame.WORD_SIZE))), t[1][1][index][1])
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 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 binop_exp(obj): o = obj.children[1] e1 = build_IR_tree_exp(obj.children[0]) e2 = build_IR_tree_exp(obj.children[2]) if o in ['+', '-', '*', '/']: if (e1.ty != 'TY_INT') and (e2.ty != 'TY_INT'): error( obj.pos, 'unsupported operand type(s) for %s: \'%s\' and \'%s\'' % (o, e1.ty, e2.ty)) return tree.Binop(o, e1, e2, 'TY_INT') if o in ['<', '<=', '>', '>=', '<>', '=']: if ((type(e1.ty) is list) and (e1.ty[0] == 'TY_RECORD') and (e2.ty == 'TY_NIL')) \ or ((type(e2.ty) is list) and (e2.ty[0] == 'TY_RECORD') and (e1.ty == 'TY_NIL')): return tree.Binop(o, e1, e2, 'TY_INT') elif e1.ty != e2.ty: error( obj.pos, 'unsupported operand type(s) for %s: \'%s\' and \'%s\'' % (o, e1.ty, e2.ty)) # elif e1.ty not in ['TY_INT', 'TY_STRING']: # error(obj.pos, 'unsupported operand type(s) for %s: \'%s\' and \'%s\', only for int and string' % (o, e1.ty, e2.ty)) if e1.ty == 'TY_STRING': stmt = tree.Call(tree.Name("__strcmp__"), [e1, e2]) return tree.Binop(o, stmt, tree.Const(0), 'TY_INT') else: return tree.Binop(o, e1, e2, 'TY_INT')
def un_cx(obj, t, f): if obj.kind == 'ex': return tree.Cjump(['='], obj, tree.Const(0), tree.Name(t), tree.Name(f)) elif obj.kind == 'un': return None elif obj.kind == 'cx': return obj else: print("error kind of IRtree")
def array_sub(obj): var = build_IR_tree_exp(obj.children[0]) if var.ty[0] != 'TY_ARRAY': error(obj.pos, 'need array type not %s' % (var.ty)) return None sub = build_IR_tree_exp(obj.children[1]) if sub.ty != 'TY_INT': error(obj.pos, 'array sub need TY_INT not %s' % (sub.ty)) return None return tree.Mem( tree.Binop('+', var, tree.Binop('*', sub, tree.Const(frame.WORD_SIZE))), var.ty[1])
def expr(access, fp, ty='TY_INT'): if access[0] == 'InFrame': return tree.Mem(tree.Binop('+', tree.Temp(fp), tree.Const(access[1])), ty)
def simple_var(obj): var = env.look(_venv, '_var_' + obj.children[0]) if not var: error(obj.pos, 'variable not declare : %s' % (obj.children[0])) return tree.Const(0, 'TY_INT') return frame.expr(var[0][1], frame.fp(), var[1])
def nil_exp(obj): return tree.Const(0, 'TY_NIL')
def const_exp(obj): return tree.Const(obj.children[0], 'TY_INT')