コード例 #1
0
ファイル: llex.c プロジェクト: bcrist/lua
/*
** this function is quite liberal in what it accepts, as 'luaO_str2num'
** will reject ill-formed numerals.
*/
static int read_numeral (LexState *ls, SemInfo *seminfo) {
  TValue obj;
  const char *expo = "Ee";
  int first = ls->current;
  lua_assert(lisdigit(ls->current));
  save_and_next(ls);
  if (first == '0' && check_next2(ls, "xX"))  /* hexadecimal? */
    expo = "Pp";
  for (;;) {
    if (check_next2(ls, expo))  /* exponent part? */
      check_next2(ls, "-+");  /* optional exponent sign */
    if (lisxdigit(ls->current))
      save_and_next(ls);
    else if (ls->current == '.')
      save_and_next(ls);
    else break;
  }
  save(ls, '\0');
  if (luaO_str2num(luaZ_buffer(ls->buff), &obj) == 0)  /* format error? */
    lexerror(ls, "malformed number", TK_FLT);
  if (ttisinteger(&obj)) {
    seminfo->i = ivalue(&obj);
    return TK_INT;
  }
  else {
    lua_assert(ttisfloat(&obj));
    seminfo->r = fltvalue(&obj);
    return TK_FLT;
  }
}
コード例 #2
0
/*
** this function is quite liberal in what it accepts, as 'luaO_str2num'
** will reject ill-formed numerals.
*/
static int read_numeral (LexState *ls, SemInfo *seminfo) {
  TValue obj;
  const char *expo = "Ee";
  int first = ls->current;
  lua_assert(lisdigit(ls->current));
  save_and_next(ls);
  if (first == '0' && check_next2(ls, "xX"))  /* hexadecimal? */
    expo = "Pp";
  for (;;) {
    if (check_next2(ls, expo))  /* exponent part? */
      check_next2(ls, "-+");  /* optional exponent sign */
    if (lisxdigit(ls->current))
      save_and_next(ls);
    else if (ls->current == '.')
      save_and_next(ls);
    else break;
  }
  save(ls, '\0');
  buffreplace(ls, '.', ls->decpoint);  /* follow locale for decimal point */
  if (!buff2num(ls->buff, &obj))  /* format error? */
    trydecpoint(ls, &obj); /* try to update decimal point separator */
  if (ttisinteger(&obj)) {
    seminfo->i = ivalue(&obj);
    return TK_INT;
  }
  else {
    lua_assert(ttisfloat(&obj));
    seminfo->r = fltvalue(&obj);
    return TK_FLT;
  }
}
コード例 #3
0
ファイル: lvm.c プロジェクト: UniTN-Mechatronics/lua
int luaV_tonumber_ (const TValue *obj, lua_Number *n) {
  lua_assert(!ttisfloat(obj));
  if (ttisinteger(obj)) {
    *n = cast_num(ivalue(obj));
    return 1;
  }
  else
    return (ttisstring(obj) && luaO_str2d(svalue(obj), tsvalue(obj)->len, n));
}
コード例 #4
0
ファイル: lvm.c プロジェクト: hongzhidao/yet-another-lua
/*
** Similar to 'tonumber', but does not attempt to convert strings and
** ensure correct precision (no extra bits). Used in comparisons.
*/
static int tofloat (const TValue *obj, lua_Number *n) {
  if (ttisfloat(obj)) *n = fltvalue(obj);
  else if (ttisinteger(obj)) {
    volatile lua_Number x = cast_num(ivalue(obj));  /* avoid extra precision */
    *n = x;
  }
  else {
    *n = 0;  /* to avoid warnings */
    return 0;
  }
  return 1;
}
コード例 #5
0
ファイル: lvm.c プロジェクト: hongzhidao/yet-another-lua
/*
** Try to convert a value to a float. Check 'isinteger' first, because
** in general the float case is already handled by the macro 'tonumber'.
*/
int luaV_tonumber_ (const TValue *obj, lua_Number *n) {
  TValue v;
 again:
  if (ttisinteger(obj)) {
    *n = cast_num(ivalue(obj));
    return 1;
  }
  else if (ttisfloat(obj)) {
    *n = fltvalue(obj);
    return 1;
  }
  else if (cvt2num(obj) &&  /* string convertible to number? */
            luaO_str2num(svalue(obj), &v) == tsvalue(obj)->len + 1) {
    obj = &v;
    goto again;  /* convert result from 'luaO_str2num' to a float */
  }
  return 0;  /* conversion failed */
}
コード例 #6
0
ファイル: lvm.c プロジェクト: ajinkya93/netbsd-src
/*
** Return 'l <= r', for numbers.
*/
static int LEnum (const TValue *l, const TValue *r) {
  if (ttisinteger(l)) {
    lua_Integer li = ivalue(l);
    if (ttisinteger(r))
      return li <= ivalue(r);  /* both are integers */
    else  /* 'l' is int and 'r' is float */
      return LEintfloat(li, fltvalue(r));  /* l <= r ? */
  }
  else {
    lua_Number lf = fltvalue(l);  /* 'l' must be float */
    if (ttisfloat(r))
      return luai_numle(lf, fltvalue(r));  /* both are float */
    else if (luai_numisnan(lf))  /* 'r' is int and 'l' is float */
      return 0;  /*  NaN <= i is always false */
    else  /* without NaN, (l <= r)  <-->  not(r < l) */
      return !LTintfloat(ivalue(r), lf);  /* not (r < l) ? */
  }
}
コード例 #7
0
ファイル: lvm.c プロジェクト: SwadicalRag/lau
/*
** 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:
    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)) {
        *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 */
}
コード例 #8
0
ファイル: lvm.c プロジェクト: fgken/netbsd-src
/*
** 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;
}