Unify command tokens: remove TK_COMMAND_INTERP and TK_INTERACTIVE_INTERP

Use cmd_mode (already on LexState) to signal whether interpolation
follows, instead of separate *_INTERP token variants. This eliminates
duplicate simple/interpolated code paths in the parser — commandexp()
and interactivestat() now each use a single unified loop that checks
cmd_mode != 0. A shared parseinterp() helper handles each ${expr}
interpolation cycle.
This commit is contained in:
Cormac Shannon
2026-03-12 23:01:31 +00:00
parent f09a033160
commit 5135b16375
3 changed files with 80 additions and 160 deletions

10
llex.c
View File

@@ -50,8 +50,8 @@ static const char *const luaX_tokens [] = {
"//", "..", "...", "==", ">=", "<=", "~=",
"<<", ">>", "::", "<eof>",
"<number>", "<integer>", "<name>", "<string>",
"<command>", "<command_interp>", "<envvar>",
"<interactive>", "<interactive_interp>"
"<command>", "<envvar>",
"<interactive>"
};
@@ -475,8 +475,8 @@ static void read_string (LexState *ls, int del, SemInfo *seminfo) {
** Called initially when '`' is seen, and also continued via
** luaX_readcommandcont() after the parser processes an interpolated
** expression.
** Returns TK_COMMAND if the string is complete (closing ` found),
** or TK_COMMAND_INTERP if an interpolation ${...} was found.
** Returns TK_COMMAND or TK_INTERACTIVE in all cases.
** When an interpolation ${...} is found, cmd_mode remains non-zero.
*/
static int read_command_body (LexState *ls, SemInfo *seminfo) {
int interactive = (ls->cmd_mode == 2);
@@ -513,7 +513,7 @@ static int read_command_body (LexState *ls, SemInfo *seminfo) {
seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff),
luaZ_bufflen(ls->buff));
ls->saved_cmd_mode = ls->cmd_mode; /* save for readcommandcont */
return interactive ? TK_INTERACTIVE_INTERP : TK_COMMAND_INTERP;
return interactive ? TK_INTERACTIVE : TK_COMMAND;
}
else {
save(ls, '$'); /* not an interpolation, keep literal '$' */