diff options
author | Benoit Giannangeli <benoit.giannangeli@boursorama.fr> | 2017-03-20 16:15:36 +0100 |
---|---|---|
committer | Benoit Giannangeli <benoit.giannangeli@boursorama.fr> | 2017-03-20 16:15:36 +0100 |
commit | 5f5ba74ace8a956ae48a9f0b182a157052c2546e (patch) | |
tree | 93381379f3711fd5ad67015d686dbfd518c0eef5 /src/lstrlib.js | |
parent | 645437b8e0846635f886520bb679a79ec1849c09 (diff) | |
download | fengari-5f5ba74ace8a956ae48a9f0b182a157052c2546e.tar.gz fengari-5f5ba74ace8a956ae48a9f0b182a157052c2546e.tar.bz2 fengari-5f5ba74ace8a956ae48a9f0b182a157052c2546e.zip |
string.gsub
Diffstat (limited to 'src/lstrlib.js')
-rw-r--r-- | src/lstrlib.js | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/src/lstrlib.js b/src/lstrlib.js index cedb403..9caa3cc 100644 --- a/src/lstrlib.js +++ b/src/lstrlib.js @@ -1221,12 +1221,52 @@ const str_match = function(L) { return str_find_aux(L, 0); }; +/* state for 'gmatch' */ +class GMatchState { + constructor() { + this.src = NaN; /* current position */ + this.p = NaN; /* pattern */ + this.lastmatch = NaN; /* end of last match */ + this.ms = new MatchState(); /* match state */ + } +} + +const gmatch_aux = function(L) { + let gm = lapi.lua_touserdata(L, lua.lua_upvalueindex(3)); + gm.ms.L = L; + for (let src = 0; src < gm.ms.src_end; src++) { + reprepstate(gm.ms); + let e; + if ((e = match(gm.ms, src, gm.p)) !== null && e !== gm.lastmatch) { + gm.src = gm.lastmatch = e; + return push_captures(gm.ms, src, e); + } + } + return 0; /* not found */ +}; + +const str_gmatch = function(L) { + let s = lauxlib.luaL_checkstring(L, 1); + let p = lauxlib.luaL_checkstring(L, 2); + let ls = s.length; + let lp = p.length; + lapi.lua_settop(L, 2); /* keep them on closure to avoid being collected */ + let gm = lapi.lua_newuserdata(L, new GMatchState()); + prepstate(gm.ms, L, s, ls, p, lp); + gm.src = s; + gm.p = p; + gm.lastmatch = null; + lapi.lua_pushcclosure(L, gmatch_aux, 3); + return 1; +}; + const strlib = { "byte": str_byte, "char": str_char, "dump": str_dump, "find": str_find, "format": str_format, + "gmatch": str_gmatch, "len": str_len, "lower": str_lower, "match": str_match, |