Beispiel #1
0
def _num_minus(env, args):
    op = env.curr_evaling[0]  # XXX: to know the op
    retval = obtype.Token('int')
    retval.tacn = NewVar()
    env.emit(tac.assign(retval.tacn, 0))

    sll = 0
    if len(args) != 0:
        arg = args[0]
        arg = env.eval_(arg)
        if not arg.can_cast_to_type('int'):
            sll = obtype.sizeof_byshift(arg.vt)
            retval.vt = arg.vt
        env.emit(tac.assign(retval.tacn, arg.tacn))

    for arg in args[1:]:
        arg = env.eval_(arg)
        if not arg.can_cast_to_type('int'):
            print 'WARNING: op %r -- argument must be number -- %r' % (
                    op, arg)
            env.print_block()
        if sll != 0:
            tmp = NewVar()
            env.emit(tac.binary(tmp, arg.tacn, '<<', sll))
        else:
            tmp = arg.tacn
        env.emit(tac.binary(retval.tacn, retval.tacn, op.n, tmp))
    return retval
Beispiel #2
0
def _num_sumall(env, args):
    retval = obtype.Token('int')
    retval.tacn = NewVar()
    env.emit(tac.assign(retval.tacn, 1))
    for arg in args:
        arg = env.eval_(arg)
        if not arg.can_cast_to_type('int'):
            print 'WARNING: op *, argument must be number at * -- %r' % arg
            env.print_block()
        env.emit(tac.binary(retval.tacn, retval.tacn, '*', arg.tacn))
    return retval
Beispiel #3
0
def _nth(env, args):
    sym, idx = args
    sym = env.eval_(sym)
    idx = env.eval_(idx)
    if not sym.ptrp():
        print 'WARNING: dereferencing a non-pointer %r' % sym
        env.print_block()
    # bound checking?
    if not idx.can_cast_to_type('int'):
        print 'WARNING: array index is not an integer %r' % idx
        env.print_block()
    retval = obtype.Token(sym.vt[:-1])  # dereferencing
    retval.tacn = NewVar()

    # sizeof retval, to facilitate idx
    memsize = obtype.sizeof_byshift(retval.vt)
    tmpoffset = NewVar()
    env.emit(tac.binary(tmpoffset, idx.tacn, '<<', memsize))
    env.emit(tac.binary(tmpoffset, tmpoffset, '+', sym.tacn))
    env.emit(tac.load(retval.tacn, tmpoffset, 0))
    return retval
Beispiel #4
0
def _set_nthbang(env, args):
    sym, idx, val = map(env.eval_, args)
    if not sym.ptrp():
        print 'WARNING: dereferencing a non-pointer %r' % sym
        env.print_block()
    if not idx.can_cast_to_type('int'):
        print 'WARNING: array index is not an integer %r' % idx
        env.print_block()
    if not sym.vt[:-1] == val.vt:
        print 'WARNING: casting %r to %r at set-nth!' % (val.vt, sym.vt[:-1])
        env.print_block()

    memsize = obtype.sizeof_byshift(sym.vt[:-1])
    if memsize != 0:  # not zero: need to change
        tmpoffset = NewVar()
        env.emit(tac.binary(tmpoffset, idx.tacn, '<<', memsize))
        env.emit(tac.binary(tmpoffset, tmpoffset, '+', sym.tacn))
        env.emit(tac.store(tmpoffset, 0, val.tacn))  # *(p+c) = val
    else:  # zero: just do it
        env.emit(tac.store(sym.tacn, 0, val.tacn))

    return obtype.Token('void')
Beispiel #5
0
def _num_binop(env, args):
    op = env.curr_evaling[0]  # XXX: to know the op

    first, second = args
    first = env.eval_(first)
    second = env.eval_(second)
    if not (first.can_cast_to_type('int') and second.can_cast_to_type('int'))\
        and not (first.vt == second.vt):  # same type is also ok
        print 'WARNING: op %s, argument must be number -- %r %r' % (
                op, first, second)
        env.print_block()

    retval = obtype.Token('int')
    retval.tacn = NewVar()  # give a name and do tac binary op
    env.emit(tac.binary(retval.tacn, first.tacn, op.n, second.tacn))
    return retval