diff -r 55beab95170f src/Makefile --- a/src/Makefile Mon Jul 15 19:07:40 2019 +0300 +++ b/src/Makefile Mon Jul 15 20:37:19 2019 +0300 @@ -7,7 +7,8 @@ PLAT= none CC= gcc -std=gnu99 -CFLAGS= -O2 -Wall -Wextra -DLUA_COMPAT_5_3 $(SYSCFLAGS) $(MYCFLAGS) +#CFLAGS= -O2 -Wall -Wextra -DLUA_COMPAT_5_3 $(SYSCFLAGS) $(MYCFLAGS) +CFLAGS= -O2 -Wall -Wextra $(SYSCFLAGS) $(MYCFLAGS) LDFLAGS= $(SYSLDFLAGS) $(MYLDFLAGS) LIBS= -lm $(SYSLIBS) $(MYLIBS) diff -r 55beab95170f src/llex.c --- a/src/llex.c Mon Jul 15 19:07:40 2019 +0300 +++ b/src/llex.c Mon Jul 15 20:37:19 2019 +0300 @@ -41,7 +41,7 @@ "and", "break", "do", "else", "elseif", "end", "false", "for", "function", "goto", "if", "in", "local", "nil", "not", "or", "repeat", - "return", "then", "true", "until", "while", + "return", "then", "true", "until", "pure", "while", "//", "..", "...", "==", ">=", "<=", "~=", "<<", ">>", "::", "", "", "", "", "" diff -r 55beab95170f src/llex.h --- a/src/llex.h Mon Jul 15 19:07:40 2019 +0300 +++ b/src/llex.h Mon Jul 15 20:37:19 2019 +0300 @@ -28,7 +28,7 @@ TK_AND = FIRST_RESERVED, TK_BREAK, TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION, TK_GOTO, TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT, - TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE, + TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_PURE, TK_WHILE, /* other terminal symbols */ TK_IDIV, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_SHL, TK_SHR, diff -r 55beab95170f src/lparser.c --- a/src/lparser.c Mon Jul 15 19:07:40 2019 +0300 +++ b/src/lparser.c Mon Jul 15 20:37:19 2019 +0300 @@ -367,10 +367,14 @@ markupval(fs, v); /* local will be used as an upval */ } else { /* not found as local at current level; try upvalues */ + if (fs->pure) { + var->k=VFORBIDDEN; + return; + } int idx = searchupvalue(fs, n); /* try existing upvalues */ if (idx < 0) { /* not found? */ singlevaraux(fs->prev, n, var, 0); /* try upper levels */ - if (var->k == VVOID) /* not found? */ + if (var->k == VVOID || var->k == VFORBIDDEN) /* not found? */ return; /* it is a global */ /* else was LOCAL or UPVAL */ idx = newupvalue(fs, n, var); /* will be a new upvalue */ @@ -389,9 +393,17 @@ TString *varname = str_checkname(ls); FuncState *fs = ls->fs; singlevaraux(fs, varname, var, 1); + if (var->k == VFORBIDDEN) { + var->k = VVOID; + const char *msg = "no access to '%s'"; + msg = luaO_pushfstring(ls->L, msg, getstr(varname)); + luaK_semerror(ls, msg); /* error */ + return; + } if (var->k == VVOID) { /* global name? */ expdesc key; singlevaraux(fs, ls->envn, var, 1); /* get environment variable */ + if (var->k == VFORBIDDEN) var->k = VVOID; lua_assert(var->k != VVOID); /* this one must exist */ codestring(ls, &key, varname); /* key is variable name */ luaK_indexed(fs, var, &key); /* env[varname] */ @@ -667,6 +679,7 @@ fs->nlocvars = 0; fs->nactvar = 0; fs->needclose = 0; + fs->pure = 0; fs->firstlocal = ls->dyd->actvar.n; fs->firstlabel = ls->dyd->label.n; fs->bl = NULL; @@ -924,6 +937,10 @@ } parlist(ls); checknext(ls, ')'); + if (ls->t.token==TK_PURE) { + luaX_next(ls); /* skip pure */ + new_fs.pure=1; + } statlist(ls); new_fs.f->lastlinedefined = ls->linenumber; check_match(ls, TK_END, TK_FUNCTION, line); diff -r 55beab95170f src/lparser.h --- a/src/lparser.h Mon Jul 15 19:07:40 2019 +0300 +++ b/src/lparser.h Mon Jul 15 20:37:19 2019 +0300 @@ -25,6 +25,7 @@ typedef enum { VVOID, /* when 'expdesc' describes the last expression a list, this kind means an empty list (so, no expression) */ + VFORBIDDEN, /* access forbidden */ VNIL, /* constant nil */ VTRUE, /* constant true */ VFALSE, /* constant false */ @@ -141,6 +142,7 @@ lu_byte freereg; /* first free register */ lu_byte iwthabs; /* instructions issued since last absolute line info */ lu_byte needclose; /* function needs to close upvalues when returning */ + lu_byte pure; } FuncState; diff -r 55beab95170f src/lua.h --- a/src/lua.h Mon Jul 15 19:07:40 2019 +0300 +++ b/src/lua.h Mon Jul 15 20:37:19 2019 +0300 @@ -18,7 +18,7 @@ #define LUA_VERSION_MAJOR "5" #define LUA_VERSION_MINOR "4" -#define LUA_VERSION_RELEASE "0" +#define LUA_VERSION_RELEASE "0+pure" #define LUA_VERSION_NUM 504 #define LUA_VERSION_RELEASE_NUM (LUA_VERSION_NUM * 100 + 0)