aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2024-10-19 00:35:11 +0800
committerLi Jin <dragon-fly@qq.com>2024-10-19 00:35:11 +0800
commit1334c0ae67fdf4cb1377e0e7a3ef291f5cf694c0 (patch)
tree8bd3fbeb396fd2fce6e5b34c3ee10f4923feca72 /src
parent05da3cbfa3689e6c229c41156d0dd08ab554cd77 (diff)
downloadyuescript-1334c0ae67fdf4cb1377e0e7a3ef291f5cf694c0.tar.gz
yuescript-1334c0ae67fdf4cb1377e0e7a3ef291f5cf694c0.tar.bz2
yuescript-1334c0ae67fdf4cb1377e0e7a3ef291f5cf694c0.zip
Fixed issue #174.
Diffstat (limited to 'src')
-rw-r--r--src/3rdParty/lua/lauxlib.c28
-rw-r--r--src/3rdParty/lua/lcode.c6
-rw-r--r--src/3rdParty/lua/ldebug.c41
-rw-r--r--src/3rdParty/lua/ldo.c4
-rw-r--r--src/3rdParty/lua/lgc.c2
-rw-r--r--src/3rdParty/lua/liolib.c27
-rw-r--r--src/3rdParty/lua/lmathlib.c2
-rw-r--r--src/3rdParty/lua/loslib.c2
-rw-r--r--src/3rdParty/lua/lstring.c2
-rw-r--r--src/3rdParty/lua/lua.h34
-rw-r--r--src/3rdParty/lua/luaconf.h2
-rw-r--r--src/3rdParty/lua/lundump.h2
-rw-r--r--src/3rdParty/lua/lvm.c4
-rw-r--r--src/yuescript/yue_ast.cpp2
-rw-r--r--src/yuescript/yue_ast.h3
-rw-r--r--src/yuescript/yue_compiler.cpp37
-rw-r--r--src/yuescript/yue_parser.cpp2
17 files changed, 128 insertions, 72 deletions
diff --git a/src/3rdParty/lua/lauxlib.c b/src/3rdParty/lua/lauxlib.c
index 4ca6c65..923105e 100644
--- a/src/3rdParty/lua/lauxlib.c
+++ b/src/3rdParty/lua/lauxlib.c
@@ -80,6 +80,7 @@ static int pushglobalfuncname (lua_State *L, lua_Debug *ar) {
80 int top = lua_gettop(L); 80 int top = lua_gettop(L);
81 lua_getinfo(L, "f", ar); /* push function */ 81 lua_getinfo(L, "f", ar); /* push function */
82 lua_getfield(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE); 82 lua_getfield(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE);
83 luaL_checkstack(L, 6, "not enough stack"); /* slots for 'findfield' */
83 if (findfield(L, top + 1, 2)) { 84 if (findfield(L, top + 1, 2)) {
84 const char *name = lua_tostring(L, -1); 85 const char *name = lua_tostring(L, -1);
85 if (strncmp(name, LUA_GNAME ".", 3) == 0) { /* name start with '_G.'? */ 86 if (strncmp(name, LUA_GNAME ".", 3) == 0) { /* name start with '_G.'? */
@@ -249,11 +250,13 @@ LUALIB_API int luaL_fileresult (lua_State *L, int stat, const char *fname) {
249 return 1; 250 return 1;
250 } 251 }
251 else { 252 else {
253 const char *msg;
252 luaL_pushfail(L); 254 luaL_pushfail(L);
255 msg = (en != 0) ? strerror(en) : "(no extra info)";
253 if (fname) 256 if (fname)
254 lua_pushfstring(L, "%s: %s", fname, strerror(en)); 257 lua_pushfstring(L, "%s: %s", fname, msg);
255 else 258 else
256 lua_pushstring(L, strerror(en)); 259 lua_pushstring(L, msg);
257 lua_pushinteger(L, en); 260 lua_pushinteger(L, en);
258 return 3; 261 return 3;
259 } 262 }
@@ -732,9 +735,12 @@ static const char *getF (lua_State *L, void *ud, size_t *size) {
732 735
733 736
734static int errfile (lua_State *L, const char *what, int fnameindex) { 737static int errfile (lua_State *L, const char *what, int fnameindex) {
735 const char *serr = strerror(errno); 738 int err = errno;
736 const char *filename = lua_tostring(L, fnameindex) + 1; 739 const char *filename = lua_tostring(L, fnameindex) + 1;
737 lua_pushfstring(L, "cannot %s %s: %s", what, filename, serr); 740 if (err != 0)
741 lua_pushfstring(L, "cannot %s %s: %s", what, filename, strerror(err));
742 else
743 lua_pushfstring(L, "cannot %s %s", what, filename);
738 lua_remove(L, fnameindex); 744 lua_remove(L, fnameindex);
739 return LUA_ERRFILE; 745 return LUA_ERRFILE;
740} 746}
@@ -787,6 +793,7 @@ LUALIB_API int luaL_loadfilex (lua_State *L, const char *filename,
787 } 793 }
788 else { 794 else {
789 lua_pushfstring(L, "@%s", filename); 795 lua_pushfstring(L, "@%s", filename);
796 errno = 0;
790 lf.f = fopen(filename, "r"); 797 lf.f = fopen(filename, "r");
791 if (lf.f == NULL) return errfile(L, "open", fnameindex); 798 if (lf.f == NULL) return errfile(L, "open", fnameindex);
792 } 799 }
@@ -796,6 +803,7 @@ LUALIB_API int luaL_loadfilex (lua_State *L, const char *filename,
796 if (c == LUA_SIGNATURE[0]) { /* binary file? */ 803 if (c == LUA_SIGNATURE[0]) { /* binary file? */
797 lf.n = 0; /* remove possible newline */ 804 lf.n = 0; /* remove possible newline */
798 if (filename) { /* "real" file? */ 805 if (filename) { /* "real" file? */
806 errno = 0;
799 lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */ 807 lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */
800 if (lf.f == NULL) return errfile(L, "reopen", fnameindex); 808 if (lf.f == NULL) return errfile(L, "reopen", fnameindex);
801 skipcomment(lf.f, &c); /* re-read initial portion */ 809 skipcomment(lf.f, &c); /* re-read initial portion */
@@ -803,6 +811,7 @@ LUALIB_API int luaL_loadfilex (lua_State *L, const char *filename,
803 } 811 }
804 if (c != EOF) 812 if (c != EOF)
805 lf.buff[lf.n++] = c; /* 'c' is the first character of the stream */ 813 lf.buff[lf.n++] = c; /* 'c' is the first character of the stream */
814 errno = 0;
806 status = lua_load(L, getF, &lf, lua_tostring(L, -1), mode); 815 status = lua_load(L, getF, &lf, lua_tostring(L, -1), mode);
807 readstatus = ferror(lf.f); 816 readstatus = ferror(lf.f);
808 if (filename) fclose(lf.f); /* close file (even in case of errors) */ 817 if (filename) fclose(lf.f); /* close file (even in case of errors) */
@@ -933,7 +942,7 @@ LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) {
933LUALIB_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) { 942LUALIB_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) {
934 luaL_checkstack(L, nup, "too many upvalues"); 943 luaL_checkstack(L, nup, "too many upvalues");
935 for (; l->name != NULL; l++) { /* fill the table with given functions */ 944 for (; l->name != NULL; l++) { /* fill the table with given functions */
936 if (l->func == NULL) /* place holder? */ 945 if (l->func == NULL) /* placeholder? */
937 lua_pushboolean(L, 0); 946 lua_pushboolean(L, 0);
938 else { 947 else {
939 int i; 948 int i;
@@ -1025,9 +1034,14 @@ static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
1025} 1034}
1026 1035
1027 1036
1037/*
1038** Standard panic funcion just prints an error message. The test
1039** with 'lua_type' avoids possible memory errors in 'lua_tostring'.
1040*/
1028static int panic (lua_State *L) { 1041static int panic (lua_State *L) {
1029 const char *msg = lua_tostring(L, -1); 1042 const char *msg = (lua_type(L, -1) == LUA_TSTRING)
1030 if (msg == NULL) msg = "error object is not a string"; 1043 ? lua_tostring(L, -1)
1044 : "error object is not a string";
1031 lua_writestringerror("PANIC: unprotected error in call to Lua API (%s)\n", 1045 lua_writestringerror("PANIC: unprotected error in call to Lua API (%s)\n",
1032 msg); 1046 msg);
1033 return 0; /* return to Lua to abort */ 1047 return 0; /* return to Lua to abort */
diff --git a/src/3rdParty/lua/lcode.c b/src/3rdParty/lua/lcode.c
index caac6ba..8761614 100644
--- a/src/3rdParty/lua/lcode.c
+++ b/src/3rdParty/lua/lcode.c
@@ -776,7 +776,8 @@ void luaK_dischargevars (FuncState *fs, expdesc *e) {
776 break; 776 break;
777 } 777 }
778 case VLOCAL: { /* already in a register */ 778 case VLOCAL: { /* already in a register */
779 e->u.info = e->u.var.ridx; 779 int temp = e->u.var.ridx;
780 e->u.info = temp; /* (can't do a direct assignment; values overlap) */
780 e->k = VNONRELOC; /* becomes a non-relocatable value */ 781 e->k = VNONRELOC; /* becomes a non-relocatable value */
781 break; 782 break;
782 } 783 }
@@ -1283,8 +1284,9 @@ void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
1283 if (t->k == VUPVAL && !isKstr(fs, k)) /* upvalue indexed by non 'Kstr'? */ 1284 if (t->k == VUPVAL && !isKstr(fs, k)) /* upvalue indexed by non 'Kstr'? */
1284 luaK_exp2anyreg(fs, t); /* put it in a register */ 1285 luaK_exp2anyreg(fs, t); /* put it in a register */
1285 if (t->k == VUPVAL) { 1286 if (t->k == VUPVAL) {
1287 int temp = t->u.info; /* upvalue index */
1286 lua_assert(isKstr(fs, k)); 1288 lua_assert(isKstr(fs, k));
1287 t->u.ind.t = t->u.info; /* upvalue index */ 1289 t->u.ind.t = temp; /* (can't do a direct assignment; values overlap) */
1288 t->u.ind.idx = k->u.info; /* literal short string */ 1290 t->u.ind.idx = k->u.info; /* literal short string */
1289 t->k = VINDEXUP; 1291 t->k = VINDEXUP;
1290 } 1292 }
diff --git a/src/3rdParty/lua/ldebug.c b/src/3rdParty/lua/ldebug.c
index b1f16ac..591b352 100644
--- a/src/3rdParty/lua/ldebug.c
+++ b/src/3rdParty/lua/ldebug.c
@@ -31,7 +31,7 @@
31 31
32 32
33 33
34#define noLuaClosure(f) ((f) == NULL || (f)->c.tt == LUA_VCCL) 34#define LuaClosure(f) ((f) != NULL && (f)->c.tt == LUA_VLCL)
35 35
36 36
37static const char *funcnamefromcall (lua_State *L, CallInfo *ci, 37static const char *funcnamefromcall (lua_State *L, CallInfo *ci,
@@ -254,7 +254,7 @@ LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
254 254
255 255
256static void funcinfo (lua_Debug *ar, Closure *cl) { 256static void funcinfo (lua_Debug *ar, Closure *cl) {
257 if (noLuaClosure(cl)) { 257 if (!LuaClosure(cl)) {
258 ar->source = "=[C]"; 258 ar->source = "=[C]";
259 ar->srclen = LL("=[C]"); 259 ar->srclen = LL("=[C]");
260 ar->linedefined = -1; 260 ar->linedefined = -1;
@@ -288,29 +288,31 @@ static int nextline (const Proto *p, int currentline, int pc) {
288 288
289 289
290static void collectvalidlines (lua_State *L, Closure *f) { 290static void collectvalidlines (lua_State *L, Closure *f) {
291 if (noLuaClosure(f)) { 291 if (!LuaClosure(f)) {
292 setnilvalue(s2v(L->top.p)); 292 setnilvalue(s2v(L->top.p));
293 api_incr_top(L); 293 api_incr_top(L);
294 } 294 }
295 else { 295 else {
296 int i;
297 TValue v;
298 const Proto *p = f->l.p; 296 const Proto *p = f->l.p;
299 int currentline = p->linedefined; 297 int currentline = p->linedefined;
300 Table *t = luaH_new(L); /* new table to store active lines */ 298 Table *t = luaH_new(L); /* new table to store active lines */
301 sethvalue2s(L, L->top.p, t); /* push it on stack */ 299 sethvalue2s(L, L->top.p, t); /* push it on stack */
302 api_incr_top(L); 300 api_incr_top(L);
303 setbtvalue(&v); /* boolean 'true' to be the value of all indices */ 301 if (p->lineinfo != NULL) { /* proto with debug information? */
304 if (!p->is_vararg) /* regular function? */ 302 int i;
305 i = 0; /* consider all instructions */ 303 TValue v;
306 else { /* vararg function */ 304 setbtvalue(&v); /* boolean 'true' to be the value of all indices */
307 lua_assert(GET_OPCODE(p->code[0]) == OP_VARARGPREP); 305 if (!p->is_vararg) /* regular function? */
308 currentline = nextline(p, currentline, 0); 306 i = 0; /* consider all instructions */
309 i = 1; /* skip first instruction (OP_VARARGPREP) */ 307 else { /* vararg function */
310 } 308 lua_assert(GET_OPCODE(p->code[0]) == OP_VARARGPREP);
311 for (; i < p->sizelineinfo; i++) { /* for each instruction */ 309 currentline = nextline(p, currentline, 0);
312 currentline = nextline(p, currentline, i); /* get its line */ 310 i = 1; /* skip first instruction (OP_VARARGPREP) */
313 luaH_setint(L, t, currentline, &v); /* table[line] = true */ 311 }
312 for (; i < p->sizelineinfo; i++) { /* for each instruction */
313 currentline = nextline(p, currentline, i); /* get its line */
314 luaH_setint(L, t, currentline, &v); /* table[line] = true */
315 }
314 } 316 }
315 } 317 }
316} 318}
@@ -339,7 +341,7 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
339 } 341 }
340 case 'u': { 342 case 'u': {
341 ar->nups = (f == NULL) ? 0 : f->c.nupvalues; 343 ar->nups = (f == NULL) ? 0 : f->c.nupvalues;
342 if (noLuaClosure(f)) { 344 if (!LuaClosure(f)) {
343 ar->isvararg = 1; 345 ar->isvararg = 1;
344 ar->nparams = 0; 346 ar->nparams = 0;
345 } 347 }
@@ -925,12 +927,12 @@ int luaG_traceexec (lua_State *L, const Instruction *pc) {
925 } 927 }
926 pc++; /* reference is always next instruction */ 928 pc++; /* reference is always next instruction */
927 ci->u.l.savedpc = pc; /* save 'pc' */ 929 ci->u.l.savedpc = pc; /* save 'pc' */
928 counthook = (--L->hookcount == 0 && (mask & LUA_MASKCOUNT)); 930 counthook = (mask & LUA_MASKCOUNT) && (--L->hookcount == 0);
929 if (counthook) 931 if (counthook)
930 resethookcount(L); /* reset count */ 932 resethookcount(L); /* reset count */
931 else if (!(mask & LUA_MASKLINE)) 933 else if (!(mask & LUA_MASKLINE))
932 return 1; /* no line hook and count != 0; nothing to be done now */ 934 return 1; /* no line hook and count != 0; nothing to be done now */
933 if (ci->callstatus & CIST_HOOKYIELD) { /* called hook last time? */ 935 if (ci->callstatus & CIST_HOOKYIELD) { /* hook yielded last time? */
934 ci->callstatus &= ~CIST_HOOKYIELD; /* erase mark */ 936 ci->callstatus &= ~CIST_HOOKYIELD; /* erase mark */
935 return 1; /* do not call hook again (VM yielded, so it did not move) */ 937 return 1; /* do not call hook again (VM yielded, so it did not move) */
936 } 938 }
@@ -952,7 +954,6 @@ int luaG_traceexec (lua_State *L, const Instruction *pc) {
952 if (L->status == LUA_YIELD) { /* did hook yield? */ 954 if (L->status == LUA_YIELD) { /* did hook yield? */
953 if (counthook) 955 if (counthook)
954 L->hookcount = 1; /* undo decrement to zero */ 956 L->hookcount = 1; /* undo decrement to zero */
955 ci->u.l.savedpc--; /* undo increment (resume will increment it again) */
956 ci->callstatus |= CIST_HOOKYIELD; /* mark that it yielded */ 957 ci->callstatus |= CIST_HOOKYIELD; /* mark that it yielded */
957 luaD_throw(L, LUA_YIELD); 958 luaD_throw(L, LUA_YIELD);
958 } 959 }
diff --git a/src/3rdParty/lua/ldo.c b/src/3rdParty/lua/ldo.c
index bd8d965..ea05295 100644
--- a/src/3rdParty/lua/ldo.c
+++ b/src/3rdParty/lua/ldo.c
@@ -792,6 +792,10 @@ static void resume (lua_State *L, void *ud) {
792 lua_assert(L->status == LUA_YIELD); 792 lua_assert(L->status == LUA_YIELD);
793 L->status = LUA_OK; /* mark that it is running (again) */ 793 L->status = LUA_OK; /* mark that it is running (again) */
794 if (isLua(ci)) { /* yielded inside a hook? */ 794 if (isLua(ci)) { /* yielded inside a hook? */
795 /* undo increment made by 'luaG_traceexec': instruction was not
796 executed yet */
797 lua_assert(ci->callstatus & CIST_HOOKYIELD);
798 ci->u.l.savedpc--;
795 L->top.p = firstArg; /* discard arguments */ 799 L->top.p = firstArg; /* discard arguments */
796 luaV_execute(L, ci); /* just continue running Lua code */ 800 luaV_execute(L, ci); /* just continue running Lua code */
797 } 801 }
diff --git a/src/3rdParty/lua/lgc.c b/src/3rdParty/lua/lgc.c
index 253a289..5817f9e 100644
--- a/src/3rdParty/lua/lgc.c
+++ b/src/3rdParty/lua/lgc.c
@@ -1713,7 +1713,7 @@ static void fullinc (lua_State *L, global_State *g) {
1713 /* finish any pending sweep phase to start a new cycle */ 1713 /* finish any pending sweep phase to start a new cycle */
1714 luaC_runtilstate(L, bitmask(GCSpause)); 1714 luaC_runtilstate(L, bitmask(GCSpause));
1715 luaC_runtilstate(L, bitmask(GCSpropagate)); /* start new cycle */ 1715 luaC_runtilstate(L, bitmask(GCSpropagate)); /* start new cycle */
1716 g->gcstate = GCSenteratomic; /* go straight to atomic phase ??? */ 1716 g->gcstate = GCSenteratomic; /* go straight to atomic phase */
1717 luaC_runtilstate(L, bitmask(GCScallfin)); /* run up to finalizers */ 1717 luaC_runtilstate(L, bitmask(GCScallfin)); /* run up to finalizers */
1718 /* estimate must be correct after a full GC cycle */ 1718 /* estimate must be correct after a full GC cycle */
1719 lua_assert(g->GCestimate == gettotalbytes(g)); 1719 lua_assert(g->GCestimate == gettotalbytes(g));
diff --git a/src/3rdParty/lua/liolib.c b/src/3rdParty/lua/liolib.c
index b08397d..c5075f3 100644
--- a/src/3rdParty/lua/liolib.c
+++ b/src/3rdParty/lua/liolib.c
@@ -245,8 +245,8 @@ static int f_gc (lua_State *L) {
245*/ 245*/
246static int io_fclose (lua_State *L) { 246static int io_fclose (lua_State *L) {
247 LStream *p = tolstream(L); 247 LStream *p = tolstream(L);
248 int res = fclose(p->f); 248 errno = 0;
249 return luaL_fileresult(L, (res == 0), NULL); 249 return luaL_fileresult(L, (fclose(p->f) == 0), NULL);
250} 250}
251 251
252 252
@@ -272,6 +272,7 @@ static int io_open (lua_State *L) {
272 LStream *p = newfile(L); 272 LStream *p = newfile(L);
273 const char *md = mode; /* to traverse/check mode */ 273 const char *md = mode; /* to traverse/check mode */
274 luaL_argcheck(L, l_checkmode(md), 2, "invalid mode"); 274 luaL_argcheck(L, l_checkmode(md), 2, "invalid mode");
275 errno = 0;
275 p->f = fopen(filename, mode); 276 p->f = fopen(filename, mode);
276 return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1; 277 return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1;
277} 278}
@@ -292,6 +293,7 @@ static int io_popen (lua_State *L) {
292 const char *mode = luaL_optstring(L, 2, "r"); 293 const char *mode = luaL_optstring(L, 2, "r");
293 LStream *p = newprefile(L); 294 LStream *p = newprefile(L);
294 luaL_argcheck(L, l_checkmodep(mode), 2, "invalid mode"); 295 luaL_argcheck(L, l_checkmodep(mode), 2, "invalid mode");
296 errno = 0;
295 p->f = l_popen(L, filename, mode); 297 p->f = l_popen(L, filename, mode);
296 p->closef = &io_pclose; 298 p->closef = &io_pclose;
297 return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1; 299 return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1;
@@ -300,6 +302,7 @@ static int io_popen (lua_State *L) {
300 302
301static int io_tmpfile (lua_State *L) { 303static int io_tmpfile (lua_State *L) {
302 LStream *p = newfile(L); 304 LStream *p = newfile(L);
305 errno = 0;
303 p->f = tmpfile(); 306 p->f = tmpfile();
304 return (p->f == NULL) ? luaL_fileresult(L, 0, NULL) : 1; 307 return (p->f == NULL) ? luaL_fileresult(L, 0, NULL) : 1;
305} 308}
@@ -567,6 +570,7 @@ static int g_read (lua_State *L, FILE *f, int first) {
567 int nargs = lua_gettop(L) - 1; 570 int nargs = lua_gettop(L) - 1;
568 int n, success; 571 int n, success;
569 clearerr(f); 572 clearerr(f);
573 errno = 0;
570 if (nargs == 0) { /* no arguments? */ 574 if (nargs == 0) { /* no arguments? */
571 success = read_line(L, f, 1); 575 success = read_line(L, f, 1);
572 n = first + 1; /* to return 1 result */ 576 n = first + 1; /* to return 1 result */
@@ -660,6 +664,7 @@ static int io_readline (lua_State *L) {
660static int g_write (lua_State *L, FILE *f, int arg) { 664static int g_write (lua_State *L, FILE *f, int arg) {
661 int nargs = lua_gettop(L) - arg; 665 int nargs = lua_gettop(L) - arg;
662 int status = 1; 666 int status = 1;
667 errno = 0;
663 for (; nargs--; arg++) { 668 for (; nargs--; arg++) {
664 if (lua_type(L, arg) == LUA_TNUMBER) { 669 if (lua_type(L, arg) == LUA_TNUMBER) {
665 /* optimization: could be done exactly as for strings */ 670 /* optimization: could be done exactly as for strings */
@@ -678,7 +683,8 @@ static int g_write (lua_State *L, FILE *f, int arg) {
678 } 683 }
679 if (l_likely(status)) 684 if (l_likely(status))
680 return 1; /* file handle already on stack top */ 685 return 1; /* file handle already on stack top */
681 else return luaL_fileresult(L, status, NULL); 686 else
687 return luaL_fileresult(L, status, NULL);
682} 688}
683 689
684 690
@@ -703,6 +709,7 @@ static int f_seek (lua_State *L) {
703 l_seeknum offset = (l_seeknum)p3; 709 l_seeknum offset = (l_seeknum)p3;
704 luaL_argcheck(L, (lua_Integer)offset == p3, 3, 710 luaL_argcheck(L, (lua_Integer)offset == p3, 3,
705 "not an integer in proper range"); 711 "not an integer in proper range");
712 errno = 0;
706 op = l_fseek(f, offset, mode[op]); 713 op = l_fseek(f, offset, mode[op]);
707 if (l_unlikely(op)) 714 if (l_unlikely(op))
708 return luaL_fileresult(L, 0, NULL); /* error */ 715 return luaL_fileresult(L, 0, NULL); /* error */
@@ -719,19 +726,25 @@ static int f_setvbuf (lua_State *L) {
719 FILE *f = tofile(L); 726 FILE *f = tofile(L);
720 int op = luaL_checkoption(L, 2, NULL, modenames); 727 int op = luaL_checkoption(L, 2, NULL, modenames);
721 lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE); 728 lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE);
722 int res = setvbuf(f, NULL, mode[op], (size_t)sz); 729 int res;
730 errno = 0;
731 res = setvbuf(f, NULL, mode[op], (size_t)sz);
723 return luaL_fileresult(L, res == 0, NULL); 732 return luaL_fileresult(L, res == 0, NULL);
724} 733}
725 734
726 735
727 736
728static int io_flush (lua_State *L) { 737static int io_flush (lua_State *L) {
729 return luaL_fileresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL); 738 FILE *f = getiofile(L, IO_OUTPUT);
739 errno = 0;
740 return luaL_fileresult(L, fflush(f) == 0, NULL);
730} 741}
731 742
732 743
733static int f_flush (lua_State *L) { 744static int f_flush (lua_State *L) {
734 return luaL_fileresult(L, fflush(tofile(L)) == 0, NULL); 745 FILE *f = tofile(L);
746 errno = 0;
747 return luaL_fileresult(L, fflush(f) == 0, NULL);
735} 748}
736 749
737 750
@@ -773,7 +786,7 @@ static const luaL_Reg meth[] = {
773** metamethods for file handles 786** metamethods for file handles
774*/ 787*/
775static const luaL_Reg metameth[] = { 788static const luaL_Reg metameth[] = {
776 {"__index", NULL}, /* place holder */ 789 {"__index", NULL}, /* placeholder */
777 {"__gc", f_gc}, 790 {"__gc", f_gc},
778 {"__close", f_gc}, 791 {"__close", f_gc},
779 {"__tostring", f_tostring}, 792 {"__tostring", f_tostring},
diff --git a/src/3rdParty/lua/lmathlib.c b/src/3rdParty/lua/lmathlib.c
index f140d62..4381063 100644
--- a/src/3rdParty/lua/lmathlib.c
+++ b/src/3rdParty/lua/lmathlib.c
@@ -352,7 +352,7 @@ static lua_Number I2d (Rand64 x) {
352 SRand64 sx = (SRand64)(trim64(x) >> shift64_FIG); 352 SRand64 sx = (SRand64)(trim64(x) >> shift64_FIG);
353 lua_Number res = (lua_Number)(sx) * scaleFIG; 353 lua_Number res = (lua_Number)(sx) * scaleFIG;
354 if (sx < 0) 354 if (sx < 0)
355 res += 1.0; /* correct the two's complement if negative */ 355 res += l_mathop(1.0); /* correct the two's complement if negative */
356 lua_assert(0 <= res && res < 1); 356 lua_assert(0 <= res && res < 1);
357 return res; 357 return res;
358} 358}
diff --git a/src/3rdParty/lua/loslib.c b/src/3rdParty/lua/loslib.c
index ad5a927..ba80d72 100644
--- a/src/3rdParty/lua/loslib.c
+++ b/src/3rdParty/lua/loslib.c
@@ -155,6 +155,7 @@ static int os_execute (lua_State *L) {
155 155
156static int os_remove (lua_State *L) { 156static int os_remove (lua_State *L) {
157 const char *filename = luaL_checkstring(L, 1); 157 const char *filename = luaL_checkstring(L, 1);
158 errno = 0;
158 return luaL_fileresult(L, remove(filename) == 0, filename); 159 return luaL_fileresult(L, remove(filename) == 0, filename);
159} 160}
160 161
@@ -162,6 +163,7 @@ static int os_remove (lua_State *L) {
162static int os_rename (lua_State *L) { 163static int os_rename (lua_State *L) {
163 const char *fromname = luaL_checkstring(L, 1); 164 const char *fromname = luaL_checkstring(L, 1);
164 const char *toname = luaL_checkstring(L, 2); 165 const char *toname = luaL_checkstring(L, 2);
166 errno = 0;
165 return luaL_fileresult(L, rename(fromname, toname) == 0, NULL); 167 return luaL_fileresult(L, rename(fromname, toname) == 0, NULL);
166} 168}
167 169
diff --git a/src/3rdParty/lua/lstring.c b/src/3rdParty/lua/lstring.c
index e921dd0..9775735 100644
--- a/src/3rdParty/lua/lstring.c
+++ b/src/3rdParty/lua/lstring.c
@@ -224,7 +224,7 @@ TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
224 return internshrstr(L, str, l); 224 return internshrstr(L, str, l);
225 else { 225 else {
226 TString *ts; 226 TString *ts;
227 if (l_unlikely(l >= (MAX_SIZE - sizeof(TString))/sizeof(char))) 227 if (l_unlikely(l * sizeof(char) >= (MAX_SIZE - sizeof(TString))))
228 luaM_toobig(L); 228 luaM_toobig(L);
229 ts = luaS_createlngstrobj(L, l); 229 ts = luaS_createlngstrobj(L, l);
230 memcpy(getlngstr(ts), str, l * sizeof(char)); 230 memcpy(getlngstr(ts), str, l * sizeof(char));
diff --git a/src/3rdParty/lua/lua.h b/src/3rdParty/lua/lua.h
index 040cc8e..f050dac 100644
--- a/src/3rdParty/lua/lua.h
+++ b/src/3rdParty/lua/lua.h
@@ -1,7 +1,7 @@
1/* 1/*
2** $Id: lua.h $ 2** $Id: lua.h $
3** Lua - A Scripting Language 3** Lua - A Scripting Language
4** Lua.org, PUC-Rio, Brazil (www.lua.org) 4** Lua.org, PUC-Rio, Brazil (http://www.lua.org)
5** See Copyright Notice at the end of this file 5** See Copyright Notice at the end of this file
6*/ 6*/
7 7
@@ -13,19 +13,20 @@
13#include <stddef.h> 13#include <stddef.h>
14 14
15 15
16#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2023 Lua.org, PUC-Rio" 16#include "luaconf.h"
17#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes"
18
19 17
20#define LUA_VERSION_MAJOR_N 5
21#define LUA_VERSION_MINOR_N 4
22#define LUA_VERSION_RELEASE_N 6
23 18
24#define LUA_VERSION_NUM (LUA_VERSION_MAJOR_N * 100 + LUA_VERSION_MINOR_N) 19#define LUA_VERSION_MAJOR "5"
25#define LUA_VERSION_RELEASE_NUM (LUA_VERSION_NUM * 100 + LUA_VERSION_RELEASE_N) 20#define LUA_VERSION_MINOR "4"
21#define LUA_VERSION_RELEASE "7"
26 22
23#define LUA_VERSION_NUM 504
24#define LUA_VERSION_RELEASE_NUM (LUA_VERSION_NUM * 100 + 7)
27 25
28#include "luaconf.h" 26#define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
27#define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE
28#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2024 Lua.org, PUC-Rio"
29#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes"
29 30
30 31
31/* mark for precompiled code ('<esc>Lua') */ 32/* mark for precompiled code ('<esc>Lua') */
@@ -495,19 +496,8 @@ struct lua_Debug {
495/* }====================================================================== */ 496/* }====================================================================== */
496 497
497 498
498#define LUAI_TOSTRAUX(x) #x
499#define LUAI_TOSTR(x) LUAI_TOSTRAUX(x)
500
501#define LUA_VERSION_MAJOR LUAI_TOSTR(LUA_VERSION_MAJOR_N)
502#define LUA_VERSION_MINOR LUAI_TOSTR(LUA_VERSION_MINOR_N)
503#define LUA_VERSION_RELEASE LUAI_TOSTR(LUA_VERSION_RELEASE_N)
504
505#define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
506#define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE
507
508
509/****************************************************************************** 499/******************************************************************************
510* Copyright (C) 1994-2023 Lua.org, PUC-Rio. 500* Copyright (C) 1994-2024 Lua.org, PUC-Rio.
511* 501*
512* Permission is hereby granted, free of charge, to any person obtaining 502* Permission is hereby granted, free of charge, to any person obtaining
513* a copy of this software and associated documentation files (the 503* a copy of this software and associated documentation files (the
diff --git a/src/3rdParty/lua/luaconf.h b/src/3rdParty/lua/luaconf.h
index acebe29..33bb580 100644
--- a/src/3rdParty/lua/luaconf.h
+++ b/src/3rdParty/lua/luaconf.h
@@ -261,7 +261,7 @@
261/* 261/*
262** LUA_IGMARK is a mark to ignore all after it when building the 262** LUA_IGMARK is a mark to ignore all after it when building the
263** module name (e.g., used to build the luaopen_ function name). 263** module name (e.g., used to build the luaopen_ function name).
264** Typically, the sufix after the mark is the module version, 264** Typically, the suffix after the mark is the module version,
265** as in "mod-v1.2.so". 265** as in "mod-v1.2.so".
266*/ 266*/
267#define LUA_IGMARK "-" 267#define LUA_IGMARK "-"
diff --git a/src/3rdParty/lua/lundump.h b/src/3rdParty/lua/lundump.h
index bc71ced..a97676c 100644
--- a/src/3rdParty/lua/lundump.h
+++ b/src/3rdParty/lua/lundump.h
@@ -21,7 +21,7 @@
21/* 21/*
22** Encode major-minor version in one byte, one nibble for each 22** Encode major-minor version in one byte, one nibble for each
23*/ 23*/
24#define LUAC_VERSION (LUA_VERSION_MAJOR_N*16+LUA_VERSION_MINOR_N) 24#define LUAC_VERSION (((LUA_VERSION_NUM / 100) * 16) + LUA_VERSION_NUM % 100)
25 25
26#define LUAC_FORMAT 0 /* this is the official format */ 26#define LUAC_FORMAT 0 /* this is the official format */
27 27
diff --git a/src/3rdParty/lua/lvm.c b/src/3rdParty/lua/lvm.c
index 4d71cff..fcd24e1 100644
--- a/src/3rdParty/lua/lvm.c
+++ b/src/3rdParty/lua/lvm.c
@@ -92,7 +92,7 @@ static int l_strton (const TValue *obj, TValue *result) {
92 if (!cvt2num(obj)) /* is object not a string? */ 92 if (!cvt2num(obj)) /* is object not a string? */
93 return 0; 93 return 0;
94 else { 94 else {
95 TString *st = tsvalue(obj); 95 TString *st = tsvalue(obj);
96 return (luaO_str2num(getstr(st), result) == tsslen(st) + 1); 96 return (luaO_str2num(getstr(st), result) == tsslen(st) + 1);
97 } 97 }
98} 98}
@@ -661,7 +661,7 @@ void luaV_concat (lua_State *L, int total) {
661 /* collect total length and number of strings */ 661 /* collect total length and number of strings */
662 for (n = 1; n < total && tostring(L, s2v(top - n - 1)); n++) { 662 for (n = 1; n < total && tostring(L, s2v(top - n - 1)); n++) {
663 size_t l = tsslen(tsvalue(s2v(top - n - 1))); 663 size_t l = tsslen(tsvalue(s2v(top - n - 1)));
664 if (l_unlikely(l >= (MAX_SIZE/sizeof(char)) - tl)) { 664 if (l_unlikely(l >= MAX_SIZE - sizeof(TString) - tl)) {
665 L->top.p = top - total; /* pop strings to avoid wasting stack */ 665 L->top.p = top - total; /* pop strings to avoid wasting stack */
666 luaG_runerror(L, "string length overflow"); 666 luaG_runerror(L, "string length overflow");
667 } 667 }
diff --git a/src/yuescript/yue_ast.cpp b/src/yuescript/yue_ast.cpp
index a454908..7f0dd07 100644
--- a/src/yuescript/yue_ast.cpp
+++ b/src/yuescript/yue_ast.cpp
@@ -490,7 +490,7 @@ std::string If_t::to_string(void* ud) const {
490std::string While_t::to_string(void* ud) const { 490std::string While_t::to_string(void* ud) const {
491 auto info = reinterpret_cast<YueFormat*>(ud); 491 auto info = reinterpret_cast<YueFormat*>(ud);
492 str_list temp{ 492 str_list temp{
493 type->to_string(ud) + ' ' + condition->to_string(ud)}; 493 type->to_string(ud) + ' ' + condition->to_string(ud) + (assignment ? assignment->to_string(ud) : std::string())};
494 if (body.is<Statement_t>()) { 494 if (body.is<Statement_t>()) {
495 temp.back() += " do "s + body->to_string(ud); 495 temp.back() += " do "s + body->to_string(ud);
496 } else { 496 } else {
diff --git a/src/yuescript/yue_ast.h b/src/yuescript/yue_ast.h
index 8063517..92d67ac 100644
--- a/src/yuescript/yue_ast.h
+++ b/src/yuescript/yue_ast.h
@@ -337,8 +337,9 @@ AST_END(WhileType)
337AST_NODE(While) 337AST_NODE(While)
338 ast_ptr<true, WhileType_t> type; 338 ast_ptr<true, WhileType_t> type;
339 ast_ptr<true, Exp_t> condition; 339 ast_ptr<true, Exp_t> condition;
340 ast_ptr<false, Assignment_t> assignment;
340 ast_sel<true, Block_t, Statement_t> body; 341 ast_sel<true, Block_t, Statement_t> body;
341 AST_MEMBER(While, &type, &condition, &body) 342 AST_MEMBER(While, &type, &condition, &assignment, &body)
342AST_END(While) 343AST_END(While)
343 344
344AST_NODE(Repeat) 345AST_NODE(Repeat)
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp
index c29513e..77a4967 100644
--- a/src/yuescript/yue_compiler.cpp
+++ b/src/yuescript/yue_compiler.cpp
@@ -75,7 +75,7 @@ static std::unordered_set<std::string> Metamethods = {
75 "close"s // Lua 5.4 75 "close"s // Lua 5.4
76}; 76};
77 77
78const std::string_view version = "0.25.5"sv; 78const std::string_view version = "0.25.6"sv;
79const std::string_view extension = "yue"sv; 79const std::string_view extension = "yue"sv;
80 80
81class CompileError : public std::logic_error { 81class CompileError : public std::logic_error {
@@ -1585,7 +1585,8 @@ private:
1585 } 1585 }
1586 goto metamethod53; 1586 goto metamethod53;
1587 } 1587 }
1588 case 504: { 1588 case 504:
1589 case 505: {
1589 if (name == "ipairs"sv) { 1590 if (name == "ipairs"sv) {
1590 throw CompileError("metamethod is not supported since Lua 5.4"sv, x); 1591 throw CompileError("metamethod is not supported since Lua 5.4"sv, x);
1591 } 1592 }
@@ -5038,7 +5039,7 @@ private:
5038#ifndef YUE_NO_MACRO 5039#ifndef YUE_NO_MACRO
5039 return LUA_VERSION_NUM; 5040 return LUA_VERSION_NUM;
5040#else 5041#else
5041 return 504; 5042 return 505;
5042#endif // YUE_NO_MACRO 5043#endif // YUE_NO_MACRO
5043 } 5044 }
5044 5045
@@ -8080,7 +8081,7 @@ private:
8080 } 8081 }
8081 8082
8082 void addDoToLastLineReturn(ast_node* body) { 8083 void addDoToLastLineReturn(ast_node* body) {
8083 if (auto block = ast_cast<Block_t>(body); body && !block->statements.empty()) { 8084 if (auto block = ast_cast<Block_t>(body); block && !block->statements.empty()) {
8084 auto last = static_cast<Statement_t*>(block->statements.back()); 8085 auto last = static_cast<Statement_t*>(block->statements.back());
8085 if (last->content.is<Return_t>()) { 8086 if (last->content.is<Return_t>()) {
8086 auto doNode = last->new_ptr<Do_t>(); 8087 auto doNode = last->new_ptr<Do_t>();
@@ -10271,6 +10272,34 @@ private:
10271 } 10272 }
10272 10273
10273 void transformWhile(While_t* whileNode, str_list& out) { 10274 void transformWhile(While_t* whileNode, str_list& out) {
10275 if (whileNode->assignment) {
10276 auto x = whileNode;
10277 auto repeat = x->new_ptr<Repeat_t>();
10278 repeat->condition.set(toAst<Exp_t>("false"sv, x));
10279 auto ifNode = x->new_ptr<If_t>();
10280 auto ifCond = x->new_ptr<IfCond_t>();
10281 bool isUntil = _parser.toString(whileNode->type) == "until"sv;
10282 ifNode->type.set(toAst<IfType_t>(isUntil ? "unless"sv : "if"sv, x));
10283 ifCond->condition.set(whileNode->condition);
10284 ifCond->assignment.set(whileNode->assignment);
10285 ifNode->nodes.push_back(ifCond);
10286 ifNode->nodes.push_back(whileNode->body);
10287 ifNode->nodes.push_back(toAst<Statement_t>("break"sv, x));
10288 auto simpleValue = x->new_ptr<SimpleValue_t>();
10289 simpleValue->value.set(ifNode);
10290 auto exp = newExp(simpleValue, x);
10291 auto expList = x->new_ptr<ExpList_t>();
10292 expList->exprs.push_back(exp);
10293 auto expListAssign = x->new_ptr<ExpListAssign_t>();
10294 expListAssign->expList.set(expList);
10295 auto stmt = x->new_ptr<Statement_t>();
10296 stmt->content.set(expListAssign);
10297 auto body = x->new_ptr<Body_t>();
10298 body->content.set(stmt);
10299 repeat->body.set(body);
10300 transformRepeat(repeat, out);
10301 return;
10302 }
10274 str_list temp; 10303 str_list temp;
10275 pushScope(); 10304 pushScope();
10276 bool isUntil = _parser.toString(whileNode->type) == "until"sv; 10305 bool isUntil = _parser.toString(whileNode->type) == "until"sv;
diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp
index d7af780..c917255 100644
--- a/src/yuescript/yue_parser.cpp
+++ b/src/yuescript/yue_parser.cpp
@@ -383,7 +383,7 @@ YueParser::YueParser() {
383 If = IfType >> space >> IfCond >> space >> opt_body_with("then") >> *if_else_if >> -if_else; 383 If = IfType >> space >> IfCond >> space >> opt_body_with("then") >> *if_else_if >> -if_else;
384 384
385 WhileType = (expr("while") | "until") >> not_alpha_num; 385 WhileType = (expr("while") | "until") >> not_alpha_num;
386 While = WhileType >> space >> disable_do_chain_arg_table_block_rule(Exp) >> space >> opt_body_with("do"); 386 While = WhileType >> space >> disable_do_chain_arg_table_block_rule(Exp >> -(space >> Assignment)) >> space >> opt_body_with("do");
387 Repeat = key("repeat") >> space >> Body >> line_break >> *space_break >> check_indent_match >> space >> key("until") >> space >> Exp; 387 Repeat = key("repeat") >> space >> Body >> line_break >> *space_break >> check_indent_match >> space >> key("until") >> space >> Exp;
388 388
389 for_key = pl::user(key("for"), [](const item_t& item) { 389 for_key = pl::user(key("for"), [](const item_t& item) {