diff --git a/lex.c b/lex.c index 9e3a0857..4cfc7e13 100644 --- a/lex.c +++ b/lex.c @@ -1,4 +1,4 @@ -char *rcs_lex = "$Id: lex.c,v 3.2 1997/04/14 15:30:29 roberto Exp roberto $"; +char *rcs_lex = "$Id: lex.c,v 3.4 1997/06/11 14:20:51 roberto Exp $"; #include @@ -23,17 +23,17 @@ char *rcs_lex = "$Id: lex.c,v 3.2 1997/04/14 15:30:29 roberto Exp roberto $"; static int current; /* look ahead character */ static Input input; /* input function */ -#define MAX_IFS 10 -/* "ifstate" keeps the state of each nested $if the lexical is -** dealing with. The first bit indicates whether the $if condition -** is false or true. The second bit indicates whether the lexical is -** inside the "then" part (0) or the "else" part (2) -*/ -static int ifstate[MAX_IFS]; /* 0 => then part - condition false */ - /* 1 => then part - condition true */ - /* 2 => else part - condition false */ - /* 3 => else part - condition true */ +#define MAX_IFS 5 + +/* "ifstate" keeps the state of each nested $if the lexical is dealing with. */ + +static struct { + int elsepart; /* true if its in the $else part */ + int condition; /* true if $if condition is true */ + int skip; /* true if part must be skiped */ +} ifstate[MAX_IFS]; + static int iflevel; /* level of nested $if's */ @@ -42,6 +42,8 @@ void lua_setinput (Input fn) current = '\n'; lua_linenumber = 0; iflevel = 0; + ifstate[0].skip = 0; + ifstate[0].elsepart = 1; /* to avoid a free $else */ input = fn; } @@ -117,10 +119,9 @@ static void skipspace (void) static int checkcond (char *buff) { - if (strcmp(buff, "nil") == 0) - return 0; - else if (strcmp(buff, "1") == 0) - return 1; + static char *opts[] = {"nil", "1"}; + int i = luaI_findstring(buff, opts); + if (i >= 0) return i; else if (isalpha((unsigned char)buff[0]) || buff[0] == '_') return luaI_globaldefined(buff); else { @@ -149,11 +150,9 @@ static void readname (char *buff) static void inclinenumber (void); -static void ifskip (int thisiflevel) +static void ifskip (void) { - if (thisiflevel < 0) return; - while (iflevel > thisiflevel && - (ifstate[thisiflevel] == 0 || ifstate[thisiflevel] == 3)) { + while (ifstate[iflevel].skip) { if (current == '\n') inclinenumber(); else if (current == 0) @@ -166,51 +165,60 @@ static void ifskip (int thisiflevel) static void inclinenumber (void) { static char *pragmas [] = - {"debug", "nodebug", "end", "ifnot", "if", "else", "endinput", NULL}; + {"debug", "nodebug", "endinput", "end", "ifnot", "if", "else", NULL}; next(); /* skip '\n' */ ++lua_linenumber; if (current == '$') { /* is a pragma? */ char buff[PRAGMASIZE+1]; int ifnot = 0; + int skip = ifstate[iflevel].skip; next(); /* skip $ */ readname(buff); switch (luaI_findstring(buff, pragmas)) { case 0: /* debug */ - lua_debug = 1; + if (!skip) lua_debug = 1; break; case 1: /* nodebug */ - lua_debug = 0; + if (!skip) lua_debug = 0; break; - case 2: /* end */ - if (--iflevel < 0) + case 2: /* endinput */ + if (!skip) { + current = 0; + iflevel = 0; /* to allow $endinput inside a $if */ + } + break; + case 3: /* end */ + if (iflevel-- == 0) luaI_auxsyntaxerror("unmatched $endif"); break; - case 3: /* ifnot */ + case 4: /* ifnot */ ifnot = 1; /* go through */ - case 4: /* if */ - if (iflevel == MAX_IFS) + case 5: /* if */ + if (iflevel == MAX_IFS-1) luaI_auxsyntaxerror("too many nested `$ifs'"); readname(buff); - ifstate[iflevel++] = checkcond(buff) ? !ifnot : ifnot; + iflevel++; + ifstate[iflevel].elsepart = 0; + ifstate[iflevel].condition = checkcond(buff) ? !ifnot : ifnot; + ifstate[iflevel].skip = skip || !ifstate[iflevel].condition; break; - case 5: /* else */ - if (iflevel <= 0 || (ifstate[iflevel-1] & 2)) + case 6: /* else */ + if (ifstate[iflevel].elsepart) luaI_auxsyntaxerror("unmatched $else"); - ifstate[iflevel-1] = ifstate[iflevel-1] | 2; - break; - case 6: /* endinput */ - current = 0; + ifstate[iflevel].elsepart = 1; + ifstate[iflevel].skip = + ifstate[iflevel-1].skip || ifstate[iflevel].condition; break; default: luaI_auxsynterrbf("invalid pragma", buff); } skipspace(); - if (current == '\n') /* pragma must end with a '\n' */ + if (current == '\n') /* pragma must end with a '\n' ... */ inclinenumber(); else if (current != 0) /* or eof */ luaI_auxsyntaxerror("invalid pragma format"); - ifskip(iflevel-1); + ifskip(); } }