/* ** returns the `main' position of an element in a table (that is, the index ** of its hash value) ** ** Floating point numbers with integer value give the hash position of the ** integer (so they use the same table position). */ static Node *mainposition (const Table *t, const TValue *key) { switch (ttype(key)) { #ifdef LUA_TINT case LUA_TINT: return hashint(t,ivalue(key)); #endif case LUA_TNUMBER: { #ifdef LUA_TINT lua_Integer i; if (tt_integer_valued(key,&i)) return hashint(t, i); # ifdef LNUM_COMPLEX /* Complex numbers are hashed by their scalar part. Pure imaginary values * with scalar 0 or -0 should give same hash. */ if (nvalue_img_fast(key)!=0 && luai_numeq(nvalue_fast(key),0)) return gnode(t, 0); /* 0 and -0 to give same hash */ # endif #else if (luai_numeq(nvalue(key),0)) return gnode(t, 0); /* 0 and -0 to give same hash */ #endif return hashnum(t,nvalue_fast(key)); } case LUA_TSTRING: return hashstr(t, rawtsvalue(key)); case LUA_TBOOLEAN: return hashboolean(t, bvalue(key)); case LUA_TLIGHTUSERDATA: return hashpointer(t, pvalue(key)); default: return hashpointer(t, gcvalue(key)); } }
/* 's' is expected to be LUAI_MAXNUMBER2STR long (enough for any number) */ void luaO_num2buf( char *s, const TValue *o ) { lua_Number n; lua_assert( ttisnumber(o) ); /* Reason to handle integers differently is not only speed, but accuracy as * well. We want to make any integer tostring() without roundings, at all. */ #ifdef LUA_TINT if (ttisint(o)) { lua_integer2str( s, ivalue(o) ); return; } #endif n= nvalue_fast(o); lua_real2str(s, n); #ifdef LNUM_COMPLEX lua_Number n2= nvalue_img_fast(o); if (n2!=0) { /* Postfix with +-Ni */ int re0= (n == 0); char *s2= re0 ? s : strchr(s,'\0'); if ((!re0) && (n2>0)) *s2++= '+'; lua_real2str( s2, n2 ); strcat(s2,"i"); } #endif }
static void PrintConstant(const Proto* f, int i) { const TValue* o=&f->k[i]; switch (ttype(o)) { case LUA_TNIL: printf("nil"); break; case LUA_TBOOLEAN: printf(bvalue(o) ? "true" : "false"); break; case LUA_TINT: printf(LUA_INTEGER_FMT,ivalue(o)); break; case LUA_TNUMBER: #ifdef LNUM_COMPLEX // TBD: Do we get complex values here? { lua_Number b= nvalue_img_fast(o); printf( LUA_NUMBER_FMT "%s" LUA_NUMBER_FMT "i", nvalue_fast(o), b>=0 ? "+":"", b ); } #endif printf(LUA_NUMBER_FMT,nvalue_fast(o)); break; case LUA_TSTRING: PrintString(rawtsvalue(o)); break; default: /* cannot happen */ printf("? type=%d",ttype(o)); break; } }
int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) { int res; int tl= ttype(l); if (tl == ttype(r)) { switch(tl) { #ifdef LUA_TINT case LUA_TINT: return ivalue(l) < ivalue(r); #endif case LUA_TNUMBER: #ifdef LNUM_COMPLEX if ( (nvalue_img_fast(l)!=0) || (nvalue_img_fast(r)!=0) ) error_complex( L, l, r ); #endif return luai_numlt(nvalue_fast(l), nvalue_fast(r)); case LUA_TSTRING: return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0; } if ((res = call_orderTM(L, l, r, TM_LT)) != -1) return res; /* fall through to 'luaG_ordererror()' */ } #ifdef LUA_TINT else if (ttype_ext(l) == ttype_ext(r)) { lua_Integer tmp; /* Avoid accuracy losing casts: if 'r' is integer by value, do comparisons * in integer realm. Only otherwise cast 'l' to FP (which might change its * value). */ # ifdef LNUM_COMPLEX if ( (nvalue_img(l)!=0) || (nvalue_img(r)!=0) ) error_complex( L, l, r ); # endif if (tl==LUA_TINT) { /* l:int, r:num */ return tt_integer_valued(r,&tmp) ? (ivalue(l) < tmp) : luai_numlt( cast_num(ivalue(l)), nvalue_fast(r) ); } else { /* l:num, r:int */ return tt_integer_valued(l,&tmp) ? (tmp < ivalue(r)) : luai_numlt( nvalue_fast(l), cast_num(ivalue(r)) ); } } #endif return luaG_ordererror(L, l, r); }
static int lessequal (lua_State *L, const TValue *l, const TValue *r) { int res; int tl= ttype(l); if (tl == ttype(r)) { switch(tl) { #ifdef LUA_TINT case LUA_TINT: return ivalue(l) <= ivalue(r); #endif case LUA_TNUMBER: #ifdef LNUM_COMPLEX if ( (nvalue_img_fast(l)!=0) || (nvalue_img_fast(r)!=0) ) error_complex( L, l, r ); #endif return luai_numle(nvalue_fast(l), nvalue_fast(r)); case LUA_TSTRING: return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0; } if ((res = call_orderTM(L, l, r, TM_LE)) != -1) /* first try `le' */ return res; else if ((res = call_orderTM(L, r, l, TM_LT)) != -1) /* else try `lt' */ return !res; /* fall through to 'luaG_ordererror()' */ } #ifdef LUA_TINT else if (ttype_ext(l) == ttype_ext(r)) { lua_Integer tmp; # ifdef LNUM_COMPLEX if ( (nvalue_img(l)!=0) || (nvalue_img(r)!=0) ) error_complex( L, l, r ); # endif if (tl==LUA_TINT) { /* l:int, r:num */ return tt_integer_valued(r,&tmp) ? (ivalue(l) <= tmp) : luai_numle( cast_num(ivalue(l)), nvalue_fast(r) ); } else { /* l:num, r:int */ return tt_integer_valued(l,&tmp) ? (tmp <= ivalue(r)) : luai_numle( nvalue_fast(l), cast_num(ivalue(r)) ); } } #endif return luaG_ordererror(L, l, r); }
/* * If a LUA_TNUMBER has integer value, give it. */ int /*bool*/ tt_integer_valued( const TValue *o, lua_Integer *ref ) { lua_Number d; lua_Integer i; lua_assert( ttype(o)==LUA_TNUMBER ); lua_assert( ref ); #ifdef LNUM_COMPLEX if (nvalue_img_fast(o)!=0) return 0; #endif d= nvalue_fast(o); lua_number2integer(i, d); if (cast_num(i) == d) { *ref= i; return 1; } return 0; }