Ejemplo n.º 1
0
/* Parse a number literal. */
static void lex_number(LexState *ls)
{
  StrScanFmt fmt;
  TValue *tv = &ls->tokenval;
  int c, xp = 'e';
  if (ls->current == '-' || ls->current == '+') {
    save_and_next(ls);
  }
  if ((c = ls->current) == '0') {
    save_and_next(ls);
    if ((ls->current | 0x20) == 'x') xp = 'p';
  }
  while (lj_char_isident(ls->current) || ls->current == '.' ||
	 ((ls->current == '-' || ls->current == '+') && (c | 0x20) == xp)) {
    c = ls->current;
    save_and_next(ls);
  }
  save(ls, '\0');
  fmt = lj_strscan_scan((const uint8_t *)ls->sb.buf, tv,
	  (LJ_DUALNUM ? STRSCAN_OPT_TOINT : STRSCAN_OPT_TONUM) |
	  (LJ_HASFFI ? (STRSCAN_OPT_LL|STRSCAN_OPT_IMAG) : 0));
  ls->token = TK_number;
  if (LJ_DUALNUM && fmt == STRSCAN_INT) {
    setitype(tv, LJ_TISNUM);
  } else if (fmt == STRSCAN_NUM) {
    /* Already in correct format. */
#if LJ_HASFFI
  } else if (fmt != STRSCAN_ERROR) {
    lua_State *L = ls->L;
    GCcdata *cd;
    lua_assert(fmt == STRSCAN_I64 || fmt == STRSCAN_U64 || fmt == STRSCAN_IMAG);
    if (!ctype_ctsG(G(L))) {
      ptrdiff_t oldtop = savestack(L, L->top);
      luaopen_ffi(L);  /* Load FFI library on-demand. */
      L->top = restorestack(L, oldtop);
    }
    if (fmt == STRSCAN_IMAG) {
      cd = lj_cdata_new_(L, CTID_COMPLEX_DOUBLE, 2*sizeof(double));
      ((double *)cdataptr(cd))[0] = 0;
      ((double *)cdataptr(cd))[1] = numV(tv);
    } else {
      cd = lj_cdata_new_(L, fmt==STRSCAN_I64 ? CTID_INT64 : CTID_UINT64, 8);
      *(uint64_t *)cdataptr(cd) = tv->u64;
    }
    lj_parse_keepcdata(ls, tv, cd);
#endif
  } else {
    lua_assert(fmt == STRSCAN_ERROR);
    lj_lex_error(ls, TK_number, LJ_ERR_XNUMBER);
  }
}
Ejemplo n.º 2
0
int treadnumber(const char * buf, ReadNumber * result, int allowsuffixes, int allowimag) {
	TValue o;
	StrScanFmt fmt;
    int opt = STRSCAN_OPT_TOINT;
    if(allowsuffixes)
        opt |= STRSCAN_OPT_LL | STRSCAN_OPT_C;
    if(allowimag)
        opt |= STRSCAN_OPT_IMAG;
    
	fmt = lj_strscan_scan((const uint8_t*)buf, &o, opt);
    result->flags = 0;
    switch(fmt) {
        case STRSCAN_ERROR:
            return 1;
        case STRSCAN_IMAG:
            /* terra doesn't have imag numbers, so allowimag will be false for terra code */
            break;
        case STRSCAN_NUM:
            result->d = o.n;
            break;
        case STRSCAN_INT:
            result->flags = F_ISINTEGER;
            result->i = o.i;
            break;
        case STRSCAN_U32:
            result->flags = F_ISINTEGER | F_ISUNSIGNED;
            result->i = o.i;
            break;
        case STRSCAN_I64:
            result->flags = F_ISINTEGER | F_IS8BYTES;
            result->i = o.u64;
            break;
        case STRSCAN_U64:
            result->flags = F_ISINTEGER | F_IS8BYTES | F_ISUNSIGNED;
            result->i = o.u64;
            break;
    }
    return 0;
}