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
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
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
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')
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