Ejemplo n.º 1
0
/* Note: if called for unary operations, 'rc'=='rb'.
 */
static void Arith (lua_State *L, StkId ra, const TValue *rb,
                   const TValue *rc, TMS op) {
  TValue tempb, tempc;
  const TValue *b, *c;
  lua_Number nb,nc;

  if ((b = luaV_tonumber(rb, &tempb)) != NULL &&
      (c = luaV_tonumber(rc, &tempc)) != NULL) {

    /* Keep integer arithmetics in the integer realm, if possible.
     */
#ifdef LUA_TINT
    if (ttisint(b) && ttisint(c)) {
      lua_Integer ib = ivalue(b), ic = ivalue(c);
      lua_Integer *ri = &ra->value.i;
      ra->tt= LUA_TINT;  /* part of 'setivalue(ra)' */
      switch (op) {
        case TM_ADD: if (try_addint( ri, ib, ic)) return; break;
        case TM_SUB: if (try_subint( ri, ib, ic)) return; break;
        case TM_MUL: if (try_mulint( ri, ib, ic)) return; break;
        case TM_DIV: if (try_divint( ri, ib, ic)) return; break;
        case TM_MOD: if (try_modint( ri, ib, ic)) return; break;
        case TM_POW: if (try_powint( ri, ib, ic)) return; break;
        case TM_UNM: if (try_unmint( ri, ib)) return; break;
        default: lua_assert(0);
      }
    }
#endif
    /* Fallback to floating point, when leaving range. */

#ifdef LNUM_COMPLEX
    if ((nvalue_img(b)!=0) || (nvalue_img(c)!=0)) {
      lua_Complex r;
      if (op==TM_UNM) {
        r= -nvalue_complex_fast(b);     /* never an integer (or scalar) */
        setnvalue_complex_fast( ra, r );
      } else {
        lua_Complex bb= nvalue_complex(b), cc= nvalue_complex(c);
        switch (op) {
          case TM_ADD: r= bb + cc; break;
          case TM_SUB: r= bb - cc; break;
          case TM_MUL: r= bb * cc; break;
          case TM_DIV: r= bb / cc; break;
          case TM_MOD: 
            luaG_runerror(L, "attempt to use %% on complex numbers");  /* no return */
          case TM_POW: r= luai_vectpow( bb, cc ); break;
          default: lua_assert(0); r=0;
        }
        setnvalue_complex( ra, r );
      }
      return;
    }
#endif
    nb = nvalue(b); nc = nvalue(c);
    switch (op) {
      case TM_ADD: setnvalue(ra, luai_numadd(nb, nc)); return;
      case TM_SUB: setnvalue(ra, luai_numsub(nb, nc)); return;
      case TM_MUL: setnvalue(ra, luai_nummul(nb, nc)); return;
      case TM_DIV: setnvalue(ra, luai_numdiv(nb, nc)); return;
      case TM_MOD: setnvalue(ra, luai_nummod(nb, nc)); return;
      case TM_POW: setnvalue(ra, luai_numpow(nb, nc)); return;
      case TM_UNM: setnvalue(ra, luai_numunm(nb)); return;
      default: lua_assert(0);
    }
  }
  
  /* Either operand not a number */
  if (!call_binTM(L, rb, rc, ra, op))
    luaG_aritherror(L, rb, rc);
}
Ejemplo n.º 2
0
static int luaK_imagK (FuncState *fs, lua_Number r) {
  TValue o;
  setnvalue_complex(&o, r*I);
  return addk(fs, &o, &o);
}