diff options
-rw-r--r-- | src/lapi.js | 8 | ||||
-rw-r--r-- | src/llex.js | 4 | ||||
-rw-r--r-- | src/lobject.js | 40 | ||||
-rw-r--r-- | src/lvm.js | 10 |
4 files changed, 36 insertions, 26 deletions
diff --git a/src/lapi.js b/src/lapi.js index c1952dd..3726af0 100644 --- a/src/lapi.js +++ b/src/lapi.js @@ -812,14 +812,14 @@ const lua_compare = function(L, index1, index2, op) { }; const lua_stringtonumber = function(L, s) { - let tv = lobject.luaO_str2num(s); - if (tv) { + let tv = new TValue(); + let sz = lobject.luaO_str2num(s, tv); + if (sz !== 0) { L.stack[L.top] = tv; L.top++; assert(L.top <= L.ci.top, "stack overflow"); - return s.length+1; } - return 0; + return sz; }; const f_call = function(L, ud) { diff --git a/src/llex.js b/src/llex.js index 19f2c05..464c98e 100644 --- a/src/llex.js +++ b/src/llex.js @@ -236,8 +236,8 @@ const read_numeral = function(ls, seminfo) { // save(ls, 0); - let obj = lobject.luaO_str2num(ls.buff.buffer); - if (obj === false) /* format error? */ + let obj = new lobject.TValue(); + if (lobject.luaO_str2num(ls.buff.buffer, obj) === 0) /* format error? */ lexerror(ls, defs.to_luastring("malformed number", true), R.TK_FLT); if (obj.ttisinteger()) { seminfo.i = obj.value; diff --git a/src/lobject.js b/src/lobject.js index 91078ed..d816323 100644 --- a/src/lobject.js +++ b/src/lobject.js @@ -406,8 +406,10 @@ const lua_strx2number = function(s) { e += exp1; } if (neg) r = -r; - while (ljstype.lisspace(s[i])) i++; /* skip trailing spaces */ - return i === s.length ? luaconf.ldexp(r, e) : null; /* Only valid if nothing left is s*/ + return { + n: luaconf.ldexp(r, e), + i: i + }; }; const lua_str2number = function(s) { @@ -416,15 +418,20 @@ const lua_str2number = function(s) { } catch (e) { return null; } - /* parseFloat ignores trailing junk, validate with regex first */ - if (!/^[\t\v\f \n\r]*[+-]?([0-9]+\.?[0-9]*|\.[0-9]*)([eE][+-]?[0-9]+)?[\t\v\f \n\r]*$/.test(s)) + /* use a regex to validate number and also to get length + parseFloat ignores trailing junk */ + let r = /^[\t\v\f \n\r]*[+-]?(?:[0-9]+\.?[0-9]*|\.[0-9]*)(?:[eE][+-]?[0-9]+)?/.exec(s); + if (!r) return null; - let flt = parseFloat(s); - return !isNaN(flt) ? flt : null; + let flt = parseFloat(r[0]); + return !isNaN(flt) ? { n: flt, i: r[0].length } : null; }; const l_str2dloc = function(s, mode) { - return mode === 'x' ? lua_strx2number(s) : lua_str2number(s); + let result = mode === 'x' ? lua_strx2number(s) : lua_str2number(s); /* try to convert */ + if (result === null) return null; + while (ljstype.lisspace(s[result.i])) result.i++; /* skip trailing spaces */ + return (result.i === s.length || s[result.i] === 0) ? result : null; /* OK if no trailing characters */ }; const l_str2d = function(s) { @@ -470,24 +477,27 @@ const l_str2int = function(s) { } } while (ljstype.lisspace(s[i])) i++; /* skip trailing spaces */ - if (empty || (i !== s.length)) return null; /* something wrong in the numeral */ + if (empty || (i !== s.length && s[i] !== 0)) return null; /* something wrong in the numeral */ else { - return (neg ? -a : a)|0; + return { + n: (neg ? -a : a)|0, + i: i + }; } }; -const luaO_str2num = function(s) { +const luaO_str2num = function(s, o) { let s2i = l_str2int(s); - if (s2i !== null) { /* try as an integer */ - return new TValue(CT.LUA_TNUMINT, s2i); + o.setivalue(s2i.n); + return s2i.i+1; } else { /* else try as a float */ s2i = l_str2d(s); - if (s2i !== null) { - return new TValue(CT.LUA_TNUMFLT, s2i); + o.setfltvalue(s2i.n); + return s2i.i+1; } else - return false; /* conversion failed */ + return 0; /* conversion failed */ } }; @@ -762,8 +762,8 @@ const luaV_tointeger = function(obj, mode) { } else if (obj.ttisinteger()) { return obj.value; } else if (cvt2num(obj)) { - let v = lobject.luaO_str2num(obj.svalue()); - if (v !== false) + let v = new lobject.TValue(); + if (lobject.luaO_str2num(obj.svalue(), v) === (obj.vslen() + 1)) return luaV_tointeger(v, mode); } @@ -778,9 +778,9 @@ const tonumber = function(o) { if (o.ttnov() === CT.LUA_TNUMBER) return o.value; - if (cvt2num(o)) { /* string convertible to number? */ - let v = lobject.luaO_str2num(o.svalue()); - if (v !== false) + if (cvt2num(o)) { /* string convertible to number? */ + let v = new lobject.TValue(); + if (lobject.luaO_str2num(o.svalue(), v) === (o.vslen() + 1)) return v.value; } |