Пример #1
0
/*
	创建一个4元数
	mat.newQuaternion(x,y,z,w)
	mat.newQuaternion(mat3)
	mat.newQuaternion(axis,radian)
		axis是Vector3,radian是一个角度
	mat.newQuaternion()
*/
static int newQuaternion(lua_State* L)
{
	const char* meta = "mat.Quaternion";
	if( lua_isnumber(L,1) )
	{
		lua_bindComplete(L,meta,new Ogre::Quaternion(
			tonumber(1),tonumber(2),tonumber(3),tonumber(4)
			));
	}
	else if( lua_isuserdata(L,1) )
	{
		Ogre::Matrix3* m3 = (Ogre::Matrix3*)lua_isa(L,1,"Matrix3");
		if( m3 )
		{
			lua_bindComplete(L,meta,new Ogre::Quaternion(*m3));
		}
		else
		{
			Ogre::Vector3* v3 =  (Ogre::Vector3*)lua_cast(L,1,"Vector3");
			if( v3 )
			{
				lua_bindComplete(L,meta,new Ogre::Quaternion(Ogre::Radian(tonumber(2)),*v3));
			}
		}
	}
	else
	{
		lua_bindComplete(L,meta,new Ogre::Quaternion());
	}
	return 1;
}
Пример #2
0
static void lll_forprep (lua_State *L, TValue *ra)
{
    TValue *init = ra;
    TValue *plimit = ra + 1;
    TValue *pstep = ra + 2;
    lua_Integer ilimit;
    int stopnow;
    if (ttisinteger(init) && ttisinteger(pstep) &&
        forlimit(plimit, &ilimit, ivalue(pstep), &stopnow)) {
      /* all values are integer */
      lua_Integer initv = (stopnow ? 0 : ivalue(init));
      setivalue(plimit, ilimit);
      setivalue(init, initv - ivalue(pstep));
    }
    else {  /* try making all values floats */
      lua_Number ninit; lua_Number nlimit; lua_Number nstep;
      if (!tonumber(plimit, &nlimit))
        luaG_runerror(L, "'for' limit must be a number");
      setfltvalue(plimit, nlimit);
      if (!tonumber(pstep, &nstep))
        luaG_runerror(L, "'for' step must be a number");
      setfltvalue(pstep, nstep);
      if (!tonumber(init, &ninit))
        luaG_runerror(L, "'for' initial value must be a number");
      setfltvalue(init, luai_numsub(L, ninit, nstep));
    }
}
Пример #3
0
//处理两种情况,x,y,z和vec3
static Ogre::Vector3 get_vector3(lua_State* L,int n )
{
	if( lua_isnumber(L,n) )
	{
		return Ogre::Vector3(tonumber(n),tonumber(n+1),tonumber(n+2));
	}
	else
	{
		Ogre::Vector3* v3 = (Ogre::Vector3*)lua_cast(L,n,"Vector3");
		if( v3 )
			return *v3;
	}
	return Ogre::Vector3();
}
Пример #4
0
/*
 * Notes: split function into two copies, one with number checks + (init - step) + jmp,
 * and the other with the same number checks + slow error throwing code.
 */
void vm_OP_FORPREP_slow(lua_State *L, int a, int sbx) {
  TValue *base = L->base;
  TValue *ra = base + a;
  const TValue *init = ra;
  const TValue *plimit = ra+1;
  const TValue *pstep = ra+2;
  (void)sbx;
  if (!tonumber(init, ra))
    luaG_runerror(L, LUA_QL("for") " initial value must be a number");
  else if (!tonumber(plimit, ra+1))
    luaG_runerror(L, LUA_QL("for") " limit must be a number");
  else if (!tonumber(pstep, ra+2))
    luaG_runerror(L, LUA_QL("for") " step must be a number");
}
Пример #5
0
LUA_API int lua_isnumber (lua_State *L, int idx) {
#if LUA_REFCOUNT
  int ret;
  TObject n;
  const TObject *o = luaA_indexAcceptable(L, idx);
  setnilvalue2n(&n);
  ret = (o != NULL && tonumber(o, &n));
  setnilvalue(&n);
  return ret;
#else !LUA_REFCOUNT
  TObject n;
  const TObject *o = luaA_indexAcceptable(L, idx);
  return (o != NULL && tonumber(o, &n));
#endif LUA_REFCOUNT
}
Пример #6
0
void luaO_arith (lua_State *L, int op, const TValue *p1, const TValue *p2,
                 TValue *res) {
  switch (op) {
    case LUA_OPBAND: case LUA_OPBOR: case LUA_OPBXOR:
    case LUA_OPSHL: case LUA_OPSHR:
    case LUA_OPBNOT: {  /* operate only on integers */
      lua_Integer i1; lua_Integer i2;
      if (tointeger(p1, &i1) && tointeger(p2, &i2)) {
        setivalue(res, intarith(L, op, i1, i2));
        return;
      }
      else break;  /* go to the end */
    }
#ifndef _KERNEL
    case LUA_OPDIV: case LUA_OPPOW: {  /* operate only on floats */
      lua_Number n1; lua_Number n2;
      if (tonumber(p1, &n1) && tonumber(p2, &n2)) {
        setfltvalue(res, numarith(L, op, n1, n2));
        return;
      }
      else break;  /* go to the end */
    }
#endif
    default: {  /* other operations */
#ifndef _KERNEL
      lua_Number n1; lua_Number n2;
      if (ttisinteger(p1) && ttisinteger(p2)) {
        setivalue(res, intarith(L, op, ivalue(p1), ivalue(p2)));
        return;
      }
      else if (tonumber(p1, &n1) && tonumber(p2, &n2)) {
        setfltvalue(res, numarith(L, op, n1, n2));
        return;
      }
#else /* _KERNEL */
      lua_Integer i1; lua_Integer i2;
      if (tointeger(p1, &i1) && tointeger(p2, &i2)) {
        setivalue(res, intarith(L, op, i1, i2));
        return;
      }
#endif
      else break;  /* go to the end */
    }
  }
  /* could not perform raw operation; try metamethod */
  lua_assert(L != NULL);  /* should not fail when folding (compile time) */
  luaT_trybinTM(L, p1, p2, res, cast(TMS, (op - LUA_OPADD) + TM_ADD));
}
Пример #7
0
long int strtoi(char *s,int base,char **scan_end)
{
    int sign,value,overflow = 0;
    long int result = 0,oldresult;
    /* Evaluate sign */
    if (*s == '-') {
	sign = -1;
	s++;
    } else if (*s == '+') {
	sign = 1;
	s++;
    }
    else sign = 1;
    /* Skip trailing zeros */
    while (*s == '0') s++;
    /* Convert number */
    while (isnumber(*s,base)) {
	value = tonumber(*s++);
	if (value > base || value < 0) return(0);
	oldresult = result;
	result *= base;
	result += value;
	/* Detect overflow */
	if (oldresult > result) overflow = 1;
    }
    if (scan_end != 0L) *scan_end = s;
    if (overflow) result = INT_MAX;
    result *= sign;
    return(result);
}
Пример #8
0
l_noret luaG_opinterror (lua_State *L, const TValue *p1,
                         const TValue *p2, const char *msg) {
  lua_Number temp;
  if (!tonumber(p1, &temp))  /* first operand is wrong? */
    p2 = p1;  /* now second is wrong */
  luaG_typeerror(L, p2, msg);
}
Пример #9
0
float lua_getnumber(lua_Object object) {
	if (object == LUA_NOOBJECT)
		return 0.0f;
	if (tonumber(Address(object)))
		return 0.0f;
	else
		return (nvalue(Address(object)));
}
Пример #10
0
LUA_API lua_Number lua_tonumber (lua_State *L, int idx) {
  TObject n;
  const TObject *o = luaA_indexAcceptable(L, idx);
 #if LUA_REFCOUNT
  setnilvalue2n(&n);
  if (o != NULL && tonumber(o, &n)) {
    lua_Number theNumber = nvalue(o);
    setnilvalue(&n);
	return theNumber;
  }
#else !LUA_REFCOUNT
  if (o != NULL && tonumber(o, &n))
    return nvalue(o);
#endif LUA_REFCOUNT
  else
    return 0;
}
Пример #11
0
LUA_API lua_Number lua_tonumber (lua_State *L, int idx) {
  TObject n;
  const TObject *o = luaA_indexAcceptable(L, idx);
  if (o != NULL && tonumber(o, &n))
    return nvalue(o);
  else
    return 0;
}
Пример #12
0
int main()
{
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
	int ans,mod,now,len;
	now=1;
	int i=1;
	while(now<99999){
		ban1[i]=tochar(now,ban0[i]);
		i++;
		now<<=1;
	}
	while(gets(str1) && (str1[0]!='\n') ){

		gets(str2);
//printf("1 %s  %s  2\n",str1,str2);
		a=tonumber(str1);
		b=tonumber(str2);
		ans=a*b;
		now=1;
		//printf("%d %d %d \n",a,b,ans);
		while(b){
			mod=b&1;
			b>>=1;
			len=ban1[now];
			strcpy(tmp,ban0[now]);
			
			tmp[len++]=' ';
			if(mod){
				tmp[len++]='*';
			}
			while(len<34)tmp[len++]=' ';
			tmp[len]='\0';
			printf("%s",tmp);
			len=tochar(a,tmp);
			printf("%s \n",tmp);
			now++;
			a<<=1;
		}
		tochar(ans,tmp);
		printf("The solution is: %s\n",tmp);
	}
	//getchar();getchar();
return 0;
}
Пример #13
0
Файл: ltm.c Проект: AlexMax/d2k
void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2,
                    StkId res, TMS event) {
  if (!luaT_callbinTM(L, p1, p2, res, event)) {
    switch (event) {
      case TM_CONCAT:
        luaG_concaterror(L, p1, p2);
      case TM_IDIV: case TM_BAND: case TM_BOR: case TM_BXOR:
      case TM_SHL: case TM_SHR: case TM_BNOT: {
        lua_Number dummy;
        if (tonumber(p1, &dummy) && tonumber(p2, &dummy))
          luaG_tointerror(L, p1, p2);
        /* else go through */
      }
      default:
        luaG_aritherror(L, p1, p2);
    }
  }
}
Пример #14
0
LUA_API lua_Number lua_tonumberx (lua_State *L, int idx, int *pisnum) {
  lua_Number n;
  const TValue *o = index2addr(L, idx);
  int isnum = tonumber(o, &n);
  if (!isnum)
    n = 0;  /* call to 'tonumber' may change 'n' even if it fails */
  if (pisnum) *pisnum = isnum;
  return n;
}
Пример #15
0
/*
** return false if folding can raise an error
*/
static int validop (int op, TValue *v1, TValue *v2) {
  lua_Number a, b;
  lua_Integer i;
  cast_void(a); cast_void(b);  /* macro may not use its arguments */
  if (luai_numinvalidop(op, (cast_void(tonumber(v1, &a)), a),
                            (cast_void(tonumber(v2, &b)), b)))
    return 0;
  switch (op) {
    case LUA_OPIDIV:  /* division by 0 and conversion errors */
      return (tointeger(v1, &i) && tointeger(v2, &i) && i != 0);
    case LUA_OPBAND: case LUA_OPBOR: case LUA_OPBXOR:
    case LUA_OPSHL: case LUA_OPSHR: case LUA_OPBNOT:  /* conversion errors */
      return (tointeger(v1, &i) && tointeger(v2, &i));
    case LUA_OPMOD:  /* integer module by 0 */
      return !(ttisinteger(v1) && ttisinteger(v2) && ivalue(v2) == 0);
    default: return 1;  /* everything else is valid */
  }
}
Пример #16
0
/*
** try to convert a non-integer value to an integer
*/
int luaV_tointeger_ (const TValue *obj, lua_Integer *p) {
  lua_Number n;
  lua_assert(!ttisinteger(obj));
  if (tonumber(obj, &n)) {
    n = l_floor(n);
    return luaV_numtointeger(n, p);
  }
  else return 0;
}
Пример #17
0
void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2,
                    StkId res, TMS event) {
  if (!luaT_callbinTM(L, p1, p2, res, event)) {
    switch (event) {
      case TM_CONCAT:
        luaG_concaterror(L, p1, p2);
      /* call never returns, but to avoid warnings: *//* FALLTHROUGH */
      case TM_BAND: case TM_BOR: case TM_BXOR:
      case TM_SHL: case TM_SHR: case TM_BNOT: {
        lua_Number dummy;
        if (tonumber(p1, &dummy) && tonumber(p2, &dummy))
          luaG_tointerror(L, p1, p2);
        else
          luaG_opinterror(L, p1, p2, "perform bitwise operation on");
      }
      /* calls never return, but to avoid warnings: *//* FALLTHROUGH */
      default:
        luaG_opinterror(L, p1, p2, "perform arithmetic on");
    }
  }
}
Пример #18
0
LUA_API lua_Number lua_tonumberx (lua_State *L, int idx, int *isnum) {
  TValue n;
  const TValue *o = index2addr(L, idx);
  if (tonumber(o, &n)) {
    if (isnum) *isnum = 1;
    return nvalue(o);
  }
  else {
    if (isnum) *isnum = 0;
    return 0;
  }
}
Пример #19
0
/*
	Lua可以用3种方法创建一个Vec3向量
	v = mat.newVec3()
	v = mat.newVec3(x,y,z)
	v = mat.newVec3(v3)
*/
static int newVec3(lua_State* L)
{
	const char* meta = "mat.Vector3";
	if( lua_isnumber(L,1) )
	{
		lua_bindComplete(L,meta,new Ogre::Vector3(
			tonumber(1),tonumber(2),tonumber(3)));
	}
	else if( lua_isuserdata(L,1) )
	{
		Ogre::Vector3* v3 = (Ogre::Vector3*)lua_cast(L,1,"Vector3");
		if( v3 )
		{
			lua_bindComplete(L,meta,new Ogre::Vector3(*v3));
		}
	}
	else
	{
		lua_bindComplete(L,meta,new Ogre::Vector3(Ogre::Vector3::ZERO));
	}
	return 1;
}
Пример #20
0
int main () {
	int n, width;

	char *buffer = myalloc(100);
	char *s = myalloc(100);

	printf("Please input a number \n");
	getLine(buffer, 100);
	n = tonumber(buffer);

	printf("Please enter a width\n");
	getLine(buffer, 100);
	width = tonumber(buffer);

	printf("Setting number to fit width now... \n");
	itoa(n, s, width);
	printf("Padded number is %s \n", s);

	myfree(buffer);
	myfree(s);

	return 0;
}
Пример #21
0
int main(){
	int i;
	char buffer[100];
	printf("Please enter an integer\n");
	getLine(buffer, 100);
	i = tonumber (buffer);

	buffer[0] = '\0';
	tostring(i, buffer);

	printf("The number is %s \n", buffer);

	return 0;
}
Пример #22
0
int main()
{
    int start[9];
    int i;
    int product;
    struct node *tree = NULL;
    for (i = 0; i < 9; i++)
	start[i] = i+1;
    while (next(start, 9)) {
	product = tonumber(start+5, 4);
	if (product == tonumber(start, 1) * tonumber(start+1, 4) ||
	    product == tonumber(start, 2) * tonumber(start+2, 3) ||
	    product == tonumber(start, 3) * tonumber(start+3, 2) ||
	    product == tonumber(start, 4) * tonumber(start+4, 1))
	    tree = insert(tree, product);
    }

    printf("%d\n", sum_tree(tree));
    return 0;
}
Пример #23
0
LUA_API lua_Unsigned lua_tounsignedx (lua_State *L, int idx, int *isnum) {
  TValue n;
  const TValue *o = index2addr(L, idx);
  if (tonumber(o, &n)) {
    lua_Unsigned res;
    lua_Number num = nvalue(o);
    lua_number2unsigned(res, num);
    if (isnum) *isnum = 1;
    return res;
  }
  else {
    if (isnum) *isnum = 0;
    return 0;
  }
}
Пример #24
0
LUA_API lua_Integer lua_tointegerx (lua_State *L, int idx, int *isnum) {
  TValue n;
  const TValue *o = index2addr(L, idx);
  if (tonumber(o, &n)) {
    lua_Integer res;
    lua_Number num = nvalue(o);
    lua_number2integer(res, num);
    if (isnum) *isnum = 1;
    return res;
  }
  else {
    if (isnum) *isnum = 0;
    return 0;
  }
}
Пример #25
0
/*
** Try to convert a 'for' limit to an integer, preserving the
** semantics of the loop.
** (The following explanation assumes a non-negative step; it is valid
** for negative steps mutatis mutandis.)
** If the limit can be converted to an integer, rounding down, that is
** it.
** Otherwise, check whether the limit can be converted to a number.    If
** the number is too large, it is OK to set the limit as LUA_MAXINTEGER, ** which means no limit.    If the number is too negative, the loop
** should not run, because any initial integer value is larger than the
** limit. So, it sets the limit to LUA_MININTEGER. 'stopnow' corrects
** the extreme case when the initial value is LUA_MININTEGER, in which
** case the LUA_MININTEGER limit would still run the loop once.
*/
static int forlimit (const TValue *obj, lua_Integer *p, lua_Integer step, int *stopnow) {
    *stopnow = 0;    /* usually, let loops run */
    if (!luaV_tointeger(obj, p, (step < 0 ? 2 : 1))) {    /* not fit in integer? */
        lua_Number n;    /* try to convert to float */
        if (!tonumber(obj, &n)) /* cannot convert to float? */
            return 0;    /* not a number */
        if (luai_numlt(0, n)) {    /* if true, float is larger than max integer */
            *p = LUA_MAXINTEGER;
            if (step < 0) *stopnow = 1;
        }
        else {    /* float is smaller than min integer */
            *p = LUA_MININTEGER;
            if (step >= 0) *stopnow = 1;
        }
    }
    return 1;
}
Пример #26
0
StkId luaV_execute (lua_State *L) {
  LClosure *cl;
  TObject *k;
  const Instruction *pc;
 callentry:  /* entry point when calling new functions */
  L->ci->u.l.pc = &pc;
  if (L->hookmask & LUA_MASKCALL)
    luaD_callhook(L, LUA_HOOKCALL, -1);
 retentry:  /* entry point when returning to old functions */
  lua_assert(L->ci->state == CI_SAVEDPC ||
             L->ci->state == (CI_SAVEDPC | CI_CALLING));
  L->ci->state = CI_HASFRAME;  /* activate frame */
  pc = L->ci->u.l.savedpc;
  cl = &clvalue(L->base - 1)->l;
  k = cl->p->k;
  /* main loop of interpreter */
  for (;;) {
    const Instruction i = *pc++;
    StkId base, ra;
    if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) &&
        (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) {
      traceexec(L);
      if (L->ci->state & CI_YIELD) {  /* did hook yield? */
        L->ci->u.l.savedpc = pc - 1;
        L->ci->state = CI_YIELD | CI_SAVEDPC;
        return NULL;
      }
    }
    /* warning!! several calls may realloc the stack and invalidate `ra' */
    base = L->base;
    ra = RA(i);
    lua_assert(L->ci->state & CI_HASFRAME);
    lua_assert(base == L->ci->base);
    lua_assert(L->top <= L->stack + L->stacksize && L->top >= base);
    lua_assert(L->top == L->ci->top ||
         GET_OPCODE(i) == OP_CALL ||   GET_OPCODE(i) == OP_TAILCALL ||
         GET_OPCODE(i) == OP_RETURN || GET_OPCODE(i) == OP_SETLISTO);
    switch (GET_OPCODE(i)) {
      case OP_MOVE: {
        setobjs2s(ra, RB(i));
        break;
      }
      case OP_LOADK: {
        setobj2s(ra, KBx(i));
        break;
      }
      case OP_LOADBOOL: {
        setbvalue(ra, GETARG_B(i));
        if (GETARG_C(i)) pc++;  /* skip next instruction (if C) */
        break;
      }
      case OP_LOADNIL: {
        TObject *rb = RB(i);
        do {
          setnilvalue(rb--);
        } while (rb >= ra);
        break;
      }
      case OP_GETUPVAL: {
        int b = GETARG_B(i);
        setobj2s(ra, cl->upvals[b]->v);
        break;
      }
      case OP_GETGLOBAL: {
        TObject *rb = KBx(i);
        const TObject *v;
        lua_assert(ttisstring(rb) && ttistable(&cl->g));
        v = luaH_getstr(hvalue(&cl->g), tsvalue(rb));
        if (!ttisnil(v)) { setobj2s(ra, v); }
        else
          setobj2s(XRA(i), luaV_index(L, &cl->g, rb, 0));
        break;
      }
      case OP_GETTABLE: {
        StkId rb = RB(i);
        TObject *rc = RKC(i);
        if (ttistable(rb)) {
          const TObject *v = luaH_get(hvalue(rb), rc);
          if (!ttisnil(v)) { setobj2s(ra, v); }
          else
            setobj2s(XRA(i), luaV_index(L, rb, rc, 0));
        }
        else
          setobj2s(XRA(i), luaV_getnotable(L, rb, rc, 0));
        break;
      }
      case OP_SETGLOBAL: {
        lua_assert(ttisstring(KBx(i)) && ttistable(&cl->g));
        luaV_settable(L, &cl->g, KBx(i), ra);
        break;
      }
      case OP_SETUPVAL: {
        int b = GETARG_B(i);
        setobj(cl->upvals[b]->v, ra);  /* write barrier */
        break;
      }
      case OP_SETTABLE: {
        luaV_settable(L, ra, RKB(i), RKC(i));
        break;
      }
      case OP_NEWTABLE: {
        int b = GETARG_B(i);
        b = fb2int(b);
        sethvalue(ra, luaH_new(L, b, GETARG_C(i)));
        luaC_checkGC(L);
        break;
      }
      case OP_SELF: {
        StkId rb = RB(i);
        TObject *rc = RKC(i);
        runtime_check(L, ttisstring(rc));
        setobjs2s(ra+1, rb);
        if (ttistable(rb)) {
          const TObject *v = luaH_getstr(hvalue(rb), tsvalue(rc));
          if (!ttisnil(v)) { setobj2s(ra, v); }
          else
            setobj2s(XRA(i), luaV_index(L, rb, rc, 0));
        }
        else
          setobj2s(XRA(i), luaV_getnotable(L, rb, rc, 0));
        break;
      }
      case OP_ADD: {
        TObject *rb = RKB(i);
        TObject *rc = RKC(i);
        if (ttisnumber(rb) && ttisnumber(rc)) {
          setnvalue(ra, nvalue(rb) + nvalue(rc));
        }
        else
          Arith(L, ra, rb, rc, TM_ADD);
        break;
      }
      case OP_SUB: {
        TObject *rb = RKB(i);
        TObject *rc = RKC(i);
        if (ttisnumber(rb) && ttisnumber(rc)) {
          setnvalue(ra, nvalue(rb) - nvalue(rc));
        }
        else
          Arith(L, ra, rb, rc, TM_SUB);
        break;
      }
      case OP_MUL: {
        TObject *rb = RKB(i);
        TObject *rc = RKC(i);
        if (ttisnumber(rb) && ttisnumber(rc)) {
          setnvalue(ra, nvalue(rb) * nvalue(rc));
        }
        else
          Arith(L, ra, rb, rc, TM_MUL);
        break;
      }
      case OP_DIV: {
        TObject *rb = RKB(i);
        TObject *rc = RKC(i);
        if (ttisnumber(rb) && ttisnumber(rc)) {
          setnvalue(ra, nvalue(rb) / nvalue(rc));
        }
        else
          Arith(L, ra, rb, rc, TM_DIV);
        break;
      }
      case OP_POW: {
        Arith(L, ra, RKB(i), RKC(i), TM_POW);
        break;
      }
      case OP_UNM: {
        const TObject *rb = RB(i);
        TObject temp;
        if (tonumber(rb, &temp)) {
          setnvalue(ra, -nvalue(rb));
        }
        else {
          setnilvalue(&temp);
          if (!call_binTM(L, RB(i), &temp, ra, TM_UNM))
            luaG_aritherror(L, RB(i), &temp);
        }
        break;
      }
      case OP_NOT: {
        int res = l_isfalse(RB(i));  /* next assignment may change this value */
        setbvalue(ra, res);
        break;
      }
      case OP_CONCAT: {
        int b = GETARG_B(i);
        int c = GETARG_C(i);
        luaV_concat(L, c-b+1, c);  /* may change `base' (and `ra') */
        base = L->base;
        setobjs2s(RA(i), base+b);
        luaC_checkGC(L);
        break;
      }
      case OP_JMP: {
        dojump(pc, GETARG_sBx(i));
        break;
      }
      case OP_EQ: {
        if (equalobj(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++;
        else dojump(pc, GETARG_sBx(*pc) + 1);
        break;
      }
      case OP_LT: {
        if (luaV_lessthan(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++;
        else dojump(pc, GETARG_sBx(*pc) + 1);
        break;
      }
      case OP_LE: {
        if (luaV_lessequal(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++;
        else dojump(pc, GETARG_sBx(*pc) + 1);
        break;
      }
      case OP_TEST: {
        TObject *rb = RB(i);
        if (l_isfalse(rb) == GETARG_C(i)) pc++;
        else {
          setobjs2s(ra, rb);
          dojump(pc, GETARG_sBx(*pc) + 1);
        }
        break;
      }
      case OP_CALL:
      case OP_TAILCALL: {
        StkId firstResult;
        int b = GETARG_B(i);
        int nresults;
        if (b != 0) L->top = ra+b;  /* else previous instruction set top */
        nresults = GETARG_C(i) - 1;
        firstResult = luaD_precall(L, ra);
        if (firstResult) {
          if (firstResult > L->top) {  /* yield? */
            lua_assert(L->ci->state == (CI_C | CI_YIELD));
            (L->ci - 1)->u.l.savedpc = pc;
            (L->ci - 1)->state = CI_SAVEDPC;
            return NULL;
          }
          /* it was a C function (`precall' called it); adjust results */
          luaD_poscall(L, nresults, firstResult);
          if (nresults >= 0) L->top = L->ci->top;
        }
        else {  /* it is a Lua function */
          if (GET_OPCODE(i) == OP_CALL) {  /* regular call? */
            (L->ci-1)->u.l.savedpc = pc;  /* save `pc' to return later */
            (L->ci-1)->state = (CI_SAVEDPC | CI_CALLING);
          }
          else {  /* tail call: put new frame in place of previous one */
            int aux;
            base = (L->ci - 1)->base;  /* `luaD_precall' may change the stack */
            ra = RA(i);
            if (L->openupval) luaF_close(L, base);
            for (aux = 0; ra+aux < L->top; aux++)  /* move frame down */
              setobjs2s(base+aux-1, ra+aux);
            (L->ci - 1)->top = L->top = base+aux;  /* correct top */
            lua_assert(L->ci->state & CI_SAVEDPC);
            (L->ci - 1)->u.l.savedpc = L->ci->u.l.savedpc;
            (L->ci - 1)->u.l.tailcalls++;  /* one more call lost */
            (L->ci - 1)->state = CI_SAVEDPC;
            L->ci--;  /* remove new frame */
            L->base = L->ci->base;
          }
          goto callentry;
        }
        break;
      }
      case OP_RETURN: {
        CallInfo *ci = L->ci - 1;  /* previous function frame */
        int b = GETARG_B(i);
        if (b != 0) L->top = ra+b-1;
        lua_assert(L->ci->state & CI_HASFRAME);
        if (L->openupval) luaF_close(L, base);
        L->ci->state = CI_SAVEDPC;  /* deactivate current function */
        L->ci->u.l.savedpc = pc;
        /* previous function was running `here'? */
        if (!(ci->state & CI_CALLING)) {
          lua_assert((ci->state & CI_C) || ci->u.l.pc != &pc);
          return ra;  /* no: return */
        }
        else {  /* yes: continue its execution */
          int nresults;
          lua_assert(ci->u.l.pc == &pc &&
                     ttisfunction(ci->base - 1) &&
                     (ci->state & CI_SAVEDPC));
          lua_assert(GET_OPCODE(*(ci->u.l.savedpc - 1)) == OP_CALL);
          nresults = GETARG_C(*(ci->u.l.savedpc - 1)) - 1;
          luaD_poscall(L, nresults, ra);
          if (nresults >= 0) L->top = L->ci->top;
          goto retentry;
        }
      }
      case OP_FORLOOP: {
        lua_Number step, idx, limit;
        const TObject *plimit = ra+1;
        const TObject *pstep = ra+2;
        if (!ttisnumber(ra))
          luaG_runerror(L, "`for' initial value must be a number");
        if (!tonumber(plimit, ra+1))
          luaG_runerror(L, "`for' limit must be a number");
        if (!tonumber(pstep, ra+2))
          luaG_runerror(L, "`for' step must be a number");
        step = nvalue(pstep);
        idx = nvalue(ra) + step;  /* increment index */
        limit = nvalue(plimit);
        if (step > 0 ? idx <= limit : idx >= limit) {
          dojump(pc, GETARG_sBx(i));  /* jump back */
          chgnvalue(ra, idx);  /* update index */
        }
        break;
      }
      case OP_TFORLOOP: {
        int nvar = GETARG_C(i) + 1;
        StkId cb = ra + nvar + 2;  /* call base */
        setobjs2s(cb, ra);
        setobjs2s(cb+1, ra+1);
        setobjs2s(cb+2, ra+2);
        L->top = cb+3;  /* func. + 2 args (state and index) */
        luaD_call(L, cb, nvar);
        L->top = L->ci->top;
        ra = XRA(i) + 2;  /* final position of first result */
        cb = ra + nvar;
        do {  /* move results to proper positions */
          nvar--;
          setobjs2s(ra+nvar, cb+nvar);
        } while (nvar > 0);
        if (ttisnil(ra))  /* break loop? */
          pc++;  /* skip jump (break loop) */
        else
          dojump(pc, GETARG_sBx(*pc) + 1);  /* jump back */
        break;
      }
      case OP_TFORPREP: {  /* for compatibility only */
        if (ttistable(ra)) {
          setobjs2s(ra+1, ra);
          setobj2s(ra, luaH_getstr(hvalue(gt(L)), luaS_new(L, "next")));
        }
        dojump(pc, GETARG_sBx(i));
        break;
      }
      case OP_SETLIST:
      case OP_SETLISTO: {
        int bc;
        int n;
        Table *h;
        runtime_check(L, ttistable(ra));
        h = hvalue(ra);
        bc = GETARG_Bx(i);
        if (GET_OPCODE(i) == OP_SETLIST)
          n = (bc&(LFIELDS_PER_FLUSH-1)) + 1;
        else {
          n = L->top - ra - 1;
          L->top = L->ci->top;
        }
        bc &= ~(LFIELDS_PER_FLUSH-1);  /* bc = bc - bc%FPF */
        for (; n > 0; n--)
          setobj2t(luaH_setnum(L, h, bc+n), ra+n);  /* write barrier */
        break;
      }
      case OP_CLOSE: {
        luaF_close(L, ra);
        break;
      }
      case OP_CLOSURE: {
        Proto *p;
        Closure *ncl;
        int nup, j;
        p = cl->p->p[GETARG_Bx(i)];
        nup = p->nups;
        ncl = luaF_newLclosure(L, nup, &cl->g);
        ncl->l.p = p;
        for (j=0; j<nup; j++, pc++) {
          if (GET_OPCODE(*pc) == OP_GETUPVAL)
            ncl->l.upvals[j] = cl->upvals[GETARG_B(*pc)];
          else {
            lua_assert(GET_OPCODE(*pc) == OP_MOVE);
            ncl->l.upvals[j] = luaF_findupval(L, base + GETARG_B(*pc));
          }
        }
        setclvalue(ra, ncl);
        luaC_checkGC(L);
        break;
      }
    }
  }
}
Пример #27
0
LUA_API int lua_isnumber (lua_State *L, int idx) {
  TValue n;
  const TValue *o = index2addr(L, idx);
  return tonumber(o, &n);
}
Пример #28
0
/*
** Executes the given Lua function. Parameters are between [base,top).
** Returns n such that the the results are between [n,top).
*/
StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
  const Proto *const tf = cl->f.l;
  StkId top;  /* keep top local, for performance */
  const Instruction *pc = tf->code;
  TString **const kstr = tf->kstr;
  const lua_Hook linehook = L->linehook;
  infovalue(base-1)->pc = &pc;
  luaD_checkstack(L, tf->maxstacksize+EXTRA_STACK);
  if (tf->is_vararg)  /* varargs? */
    adjust_varargs(L, base, tf->numparams);
  else
    luaD_adjusttop(L, base, tf->numparams);
  top = L->top;
  /* main loop of interpreter */
  for (;;) {
    const Instruction i = *pc++;
    if (linehook)
      traceexec(L, base, top, linehook);
    switch (GET_OPCODE(i)) {
      case OP_END: {
        L->top = top;
        return top;
      }
      case OP_RETURN: {
        L->top = top;
        return base+GETARG_U(i);
      }
      case OP_CALL: {
        int nres = GETARG_B(i);
        if (nres == MULT_RET) nres = LUA_MULTRET;
        L->top = top;
        luaD_call(L, base+GETARG_A(i), nres);
        top = L->top;
        break;
      }
      case OP_TAILCALL: {
        L->top = top;
        luaD_call(L, base+GETARG_A(i), LUA_MULTRET);
        return base+GETARG_B(i);
      }
      case OP_PUSHNIL: {
        int n = GETARG_U(i);
        LUA_ASSERT(n>0, "invalid argument");
        do {
          ttype(top++) = LUA_TNIL;
        } while (--n > 0);
        break;
      }
      case OP_POP: {
        top -= GETARG_U(i);
        break;
      }
      case OP_PUSHINT: {
        ttype(top) = LUA_TNUMBER;
        nvalue(top) = (Number)GETARG_S(i);
        top++;
        break;
      }
      case OP_PUSHSTRING: {
        ttype(top) = LUA_TSTRING;
        tsvalue(top) = kstr[GETARG_U(i)];
        top++;
        break;
      }
      case OP_PUSHNUM: {
        ttype(top) = LUA_TNUMBER;
        nvalue(top) = tf->knum[GETARG_U(i)];
        top++;
        break;
      }
      case OP_PUSHNEGNUM: {
        ttype(top) = LUA_TNUMBER;
        nvalue(top) = -tf->knum[GETARG_U(i)];
        top++;
        break;
      }
      case OP_PUSHUPVALUE: {
        *top++ = cl->upvalue[GETARG_U(i)];
        break;
      }
      case OP_GETLOCAL: {
        *top++ = *(base+GETARG_U(i));
        break;
      }
      case OP_GETGLOBAL: {
        L->top = top;
        *top = *luaV_getglobal(L, kstr[GETARG_U(i)]);
        top++;
        break;
      }
      case OP_GETTABLE: {
        L->top = top;
        top--;
        *(top-1) = *luaV_gettable(L, top-1);
        break;
      }
      case OP_GETDOTTED: {
        ttype(top) = LUA_TSTRING;
        tsvalue(top) = kstr[GETARG_U(i)];
        L->top = top+1;
        *(top-1) = *luaV_gettable(L, top-1);
        break;
      }
      case OP_GETINDEXED: {
        *top = *(base+GETARG_U(i));
        L->top = top+1;
        *(top-1) = *luaV_gettable(L, top-1);
        break;
      }
      case OP_PUSHSELF: {
        TObject receiver;
        receiver = *(top-1);
        ttype(top) = LUA_TSTRING;
        tsvalue(top++) = kstr[GETARG_U(i)];
        L->top = top;
        *(top-2) = *luaV_gettable(L, top-2);
        *(top-1) = receiver;
        break;
      }
      case OP_CREATETABLE: {
        L->top = top;
        luaC_checkGC(L);
        hvalue(top) = luaH_new(L, GETARG_U(i));
        ttype(top) = LUA_TTABLE;
        top++;
        break;
      }
      case OP_SETLOCAL: {
        *(base+GETARG_U(i)) = *(--top);
        break;
      }
      case OP_SETGLOBAL: {
        L->top = top;
        luaV_setglobal(L, kstr[GETARG_U(i)]);
        top--;
        break;
      }
      case OP_SETTABLE: {
        StkId t = top-GETARG_A(i);
        L->top = top;
        luaV_settable(L, t, t+1);
        top -= GETARG_B(i);  /* pop values */
        break;
      }
      case OP_SETLIST: {
        int aux = GETARG_A(i) * LFIELDS_PER_FLUSH;
        int n = GETARG_B(i);
        Hash *arr = hvalue(top-n-1);
        L->top = top-n;  /* final value of `top' (in case of errors) */
        for (; n; n--)
          *luaH_setint(L, arr, n+aux) = *(--top);
        break;
      }
      case OP_SETMAP: {
        int n = GETARG_U(i);
        StkId finaltop = top-2*n;
        Hash *arr = hvalue(finaltop-1);
        L->top = finaltop;  /* final value of `top' (in case of errors) */
        for (; n; n--) {
          top-=2;
          *luaH_set(L, arr, top) = *(top+1);
        }
        break;
      }
      case OP_ADD: {
        if (tonumber(top-2) || tonumber(top-1))
          call_arith(L, top, TM_ADD);
        else
          nvalue(top-2) += nvalue(top-1);
        top--;
        break;
      }
      case OP_ADDI: {
        if (tonumber(top-1)) {
          ttype(top) = LUA_TNUMBER;
          nvalue(top) = (Number)GETARG_S(i);
          call_arith(L, top+1, TM_ADD);
        }
        else
          nvalue(top-1) += (Number)GETARG_S(i);
        break;
      }
      case OP_SUB: {
        if (tonumber(top-2) || tonumber(top-1))
          call_arith(L, top, TM_SUB);
        else
          nvalue(top-2) -= nvalue(top-1);
        top--;
        break;
      }
      case OP_MULT: {
        if (tonumber(top-2) || tonumber(top-1))
          call_arith(L, top, TM_MUL);
        else
          nvalue(top-2) *= nvalue(top-1);
        top--;
        break;
      }
      case OP_DIV: {
        if (tonumber(top-2) || tonumber(top-1))
          call_arith(L, top, TM_DIV);
        else
          nvalue(top-2) /= nvalue(top-1);
        top--;
        break;
      }
      case OP_POW: {
        if (!call_binTM(L, top, TM_POW))
          lua_error(L, "undefined operation");
        top--;
        break;
      }
      case OP_CONCAT: {
        int n = GETARG_U(i);
        luaV_strconc(L, n, top);
        top -= n-1;
        L->top = top;
        luaC_checkGC(L);
        break;
      }
      case OP_MINUS: {
        if (tonumber(top-1)) {
          ttype(top) = LUA_TNIL;
          call_arith(L, top+1, TM_UNM);
        }
        else
          nvalue(top-1) = -nvalue(top-1);
        break;
      }
      case OP_NOT: {
        ttype(top-1) =
           (ttype(top-1) == LUA_TNIL) ? LUA_TNUMBER : LUA_TNIL;
        nvalue(top-1) = 1;
        break;
      }
      case OP_JMPNE: {
        top -= 2;
        if (!luaO_equalObj(top, top+1)) dojump(pc, i);
        break;
      }
      case OP_JMPEQ: {
        top -= 2;
        if (luaO_equalObj(top, top+1)) dojump(pc, i);
        break;
      }
      case OP_JMPLT: {
        top -= 2;
        if (luaV_lessthan(L, top, top+1, top+2)) dojump(pc, i);
        break;
      }
      case OP_JMPLE: {  /* a <= b  ===  !(b<a) */
        top -= 2;
        if (!luaV_lessthan(L, top+1, top, top+2)) dojump(pc, i);
        break;
      }
      case OP_JMPGT: {  /* a > b  ===  (b<a) */
        top -= 2;
        if (luaV_lessthan(L, top+1, top, top+2)) dojump(pc, i);
        break;
      }
      case OP_JMPGE: {  /* a >= b  ===  !(a<b) */
        top -= 2;
        if (!luaV_lessthan(L, top, top+1, top+2)) dojump(pc, i);
        break;
      }
      case OP_JMPT: {
        if (ttype(--top) != LUA_TNIL) dojump(pc, i);
        break;
      }
      case OP_JMPF: {
        if (ttype(--top) == LUA_TNIL) dojump(pc, i);
        break;
      }
      case OP_JMPONT: {
        if (ttype(top-1) == LUA_TNIL) top--;
        else dojump(pc, i);
        break;
      }
      case OP_JMPONF: {
        if (ttype(top-1) != LUA_TNIL) top--;
        else dojump(pc, i);
        break;
      }
      case OP_JMP: {
        dojump(pc, i);
        break;
      }
      case OP_PUSHNILJMP: {
        ttype(top++) = LUA_TNIL;
        pc++;
        break;
      }
      case OP_FORPREP: {
        if (tonumber(top-1))
          lua_error(L, "`for' step must be a number");
        if (tonumber(top-2))
          lua_error(L, "`for' limit must be a number");
        if (tonumber(top-3))
          lua_error(L, "`for' initial value must be a number");
        if (nvalue(top-1) > 0 ?
            nvalue(top-3) > nvalue(top-2) :
            nvalue(top-3) < nvalue(top-2)) {  /* `empty' loop? */
          top -= 3;  /* remove control variables */
          dojump(pc, i);  /* jump to loop end */
        }
        break;
      }
      case OP_FORLOOP: {
        LUA_ASSERT(ttype(top-1) == LUA_TNUMBER, "invalid step");
        LUA_ASSERT(ttype(top-2) == LUA_TNUMBER, "invalid limit");
        if (ttype(top-3) != LUA_TNUMBER)
          lua_error(L, "`for' index must be a number");
        nvalue(top-3) += nvalue(top-1);  /* increment index */
        if (nvalue(top-1) > 0 ?
            nvalue(top-3) > nvalue(top-2) :
            nvalue(top-3) < nvalue(top-2))
          top -= 3;  /* end loop: remove control variables */
        else
          dojump(pc, i);  /* repeat loop */
        break;
      }
      case OP_LFORPREP: {
        Node *node;
        if (ttype(top-1) != LUA_TTABLE)
          lua_error(L, "`for' table must be a table");
        node = luaH_next(L, hvalue(top-1), &luaO_nilobject);
        if (node == NULL) {  /* `empty' loop? */
          top--;  /* remove table */
          dojump(pc, i);  /* jump to loop end */
        }
        else {
          top += 2;  /* index,value */
          *(top-2) = *key(node);
          *(top-1) = *val(node);
        }
        break;
      }
      case OP_LFORLOOP: {
        Node *node;
        LUA_ASSERT(ttype(top-3) == LUA_TTABLE, "invalid table");
        node = luaH_next(L, hvalue(top-3), top-2);
        if (node == NULL)  /* end loop? */
          top -= 3;  /* remove table, key, and value */
        else {
          *(top-2) = *key(node);
          *(top-1) = *val(node);
          dojump(pc, i);  /* repeat loop */
        }
        break;
      }
      case OP_CLOSURE: {
        L->top = top;
        luaV_Lclosure(L, tf->kproto[GETARG_A(i)], GETARG_B(i));
        top = L->top;
        luaC_checkGC(L);
        break;
      }
    }
  }
}
Пример #29
0
LUA_API int lua_isnumber (lua_State *L, int idx) {
  TObject n;
  const TObject *o = luaA_indexAcceptable(L, idx);
  return (o != NULL && tonumber(o, &n));
}
Пример #30
0
/*
** try to convert a value to an integer, rounding according to 'mode':
** mode == 0: accepts only integral values
** mode == 1: takes the floor of the number
** mode == 2: takes the ceil of the number
*/
int luaV_tointeger (const TValue *obj, lua_Integer *p, int mode) {
  TValue v;
 again:
#ifndef _KERNEL
  if (ttisfloat(obj)) {
    lua_Number n = fltvalue(obj);
    lua_Number f = l_floor(n);
    if (n != f) {  /* not an integral value? */
      if (mode == 0) return 0;  /* fails if mode demands integral value */
      else if (mode > 1)  /* needs ceil? */
        f += 1;  /* convert floor to ceil (remember: n != f) */
    }
    return lua_numbertointeger(f, p);
  }
  else if (ttisinteger(obj)) {
#else /* _KERNEL */
  if (ttisinteger(obj)) {
    UNUSED(mode);
#endif
    *p = ivalue(obj);
    return 1;
  }
  else if (cvt2num(obj) &&
            luaO_str2num(svalue(obj), &v) == vslen(obj) + 1) {
    obj = &v;
    goto again;  /* convert result from 'luaO_str2num' to an integer */
  }
  return 0;  /* conversion failed */
}


#ifndef _KERNEL
/*
** Try to convert a 'for' limit to an integer, preserving the
** semantics of the loop.
** (The following explanation assumes a non-negative step; it is valid
** for negative steps mutatis mutandis.)
** If the limit can be converted to an integer, rounding down, that is
** it.
** Otherwise, check whether the limit can be converted to a number.  If
** the number is too large, it is OK to set the limit as LUA_MAXINTEGER,
** which means no limit.  If the number is too negative, the loop
** should not run, because any initial integer value is larger than the
** limit. So, it sets the limit to LUA_MININTEGER. 'stopnow' corrects
** the extreme case when the initial value is LUA_MININTEGER, in which
** case the LUA_MININTEGER limit would still run the loop once.
*/
static int forlimit (const TValue *obj, lua_Integer *p, lua_Integer step,
                     int *stopnow) {
  *stopnow = 0;  /* usually, let loops run */
  if (!luaV_tointeger(obj, p, (step < 0 ? 2 : 1))) {  /* not fit in integer? */
    lua_Number n;  /* try to convert to float */
    if (!tonumber(obj, &n)) /* cannot convert to float? */
      return 0;  /* not a number */
    if (luai_numlt(0, n)) {  /* if true, float is larger than max integer */
      *p = LUA_MAXINTEGER;
      if (step < 0) *stopnow = 1;
    }
    else {  /* float is smaller than min integer */
      *p = LUA_MININTEGER;
      if (step >= 0) *stopnow = 1;
    }
  }
  return 1;
}