Add token literals to the lua parser

This commit is contained in:
2026-02-19 00:11:44 -05:00
parent 1fd06f0628
commit 7039c43065
8 changed files with 58 additions and 3 deletions

View File

@@ -342,6 +342,13 @@ int luaK_numberK (FuncState *fs, lua_Number r) {
}
int luaK_lightuserdataK (FuncState *fs, void *p) {
TValue o;
setpvalue(&o, p);
return addk(fs, &o, &o);
}
static int boolK (FuncState *fs, int b) {
TValue o;
setbvalue(&o, b);

View File

@@ -53,6 +53,7 @@ LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n);
LUAI_FUNC void luaK_checkstack (FuncState *fs, int n);
LUAI_FUNC int luaK_stringK (FuncState *fs, TString *s);
LUAI_FUNC int luaK_numberK (FuncState *fs, lua_Number r);
LUAI_FUNC int luaK_lightuserdataK (FuncState *fs, void *p);
LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e);
LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e);
LUAI_FUNC void luaK_exp2anyregup (FuncState *fs, expdesc *e);

View File

@@ -39,7 +39,7 @@ static const char *const luaX_tokens [] = {
"in", "local", "nil", "not", "or", "repeat",
"return", "then", "true", "until", "while",
"..", "...", "==", ">=", "<=", "~=", "::", "<eof>",
"<number>", "<name>", "<string>"
"<number>", "<name>", "<string>", "<token>"
};
@@ -93,6 +93,7 @@ static const char *txtToken (LexState *ls, int token) {
case TK_NAME:
case TK_STRING:
case TK_NUMBER:
case TK_TOKEN:
save(ls, '\0');
return luaO_pushfstring(ls->L, LUA_QS, luaZ_buffer(ls->buff));
default:
@@ -485,6 +486,28 @@ static int llex (LexState *ls, SemInfo *seminfo) {
case EOZ: {
return TK_EOS;
}
case '@': { /* token literal */
size_t tokval = 0;
int toklen = 0;
save_and_next(ls);
while (1) {
char c = (char)ls->current;
size_t digit;
if (c >= '0' && c <= '9') digit = (size_t)(c - '0') + 1;
else if (c >= 'a' && c <= 'z') digit = (size_t)(c - 'a') + 11;
else if (c >= 'A' && c <= 'Z') digit = (size_t)(c - 'A') + 11;
else break;
tokval = tokval * 37 + digit;
toklen++;
save_and_next(ls);
}
if (toklen == 0 || toklen > 12 || ls->current == '_')
lexerror(ls, "invalid token literal", TK_TOKEN);
/* Pad to fixed width of 12 digits. */
for (int i = toklen; i < 12; i++) tokval *= 37;
seminfo->p = (void *)tokval;
return TK_TOKEN;
}
default: {
if (lislalpha(ls->current)) { /* identifier or reserved word? */
TString *ts;

View File

@@ -27,7 +27,7 @@ enum RESERVED {
TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE,
/* other terminal symbols */
TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_DBCOLON, TK_EOS,
TK_NUMBER, TK_NAME, TK_STRING
TK_NUMBER, TK_NAME, TK_STRING, TK_TOKEN
};
/* number of reserved words */
@@ -37,6 +37,7 @@ enum RESERVED {
typedef union {
lua_Number r;
TString *ts;
void *p; /* for token (lightuserdata) literals */
} SemInfo; /* semantics information */

View File

@@ -947,6 +947,10 @@ static void simpleexp (LexState *ls, expdesc *v) {
codestring(ls, v, ls->t.seminfo.ts);
break;
}
case TK_TOKEN: {
init_exp(v, VK, luaK_lightuserdataK(ls->fs, ls->t.seminfo.p));
break;
}
case TK_NIL: {
init_exp(v, VNIL, 0);
break;