diff options
| -rw-r--r-- | lex.c | 80 |
1 files changed, 44 insertions, 36 deletions
| @@ -1,4 +1,4 @@ | |||
| 1 | char *rcs_lex = "$Id: lex.c,v 3.2 1997/04/14 15:30:29 roberto Exp roberto $"; | 1 | char *rcs_lex = "$Id: lex.c,v 3.4 1997/06/11 14:20:51 roberto Exp $"; |
| 2 | 2 | ||
| 3 | 3 | ||
| 4 | #include <ctype.h> | 4 | #include <ctype.h> |
| @@ -23,17 +23,17 @@ char *rcs_lex = "$Id: lex.c,v 3.2 1997/04/14 15:30:29 roberto Exp roberto $"; | |||
| 23 | static int current; /* look ahead character */ | 23 | static int current; /* look ahead character */ |
| 24 | static Input input; /* input function */ | 24 | static Input input; /* input function */ |
| 25 | 25 | ||
| 26 | #define MAX_IFS 10 | ||
| 27 | 26 | ||
| 28 | /* "ifstate" keeps the state of each nested $if the lexical is | 27 | #define MAX_IFS 5 |
| 29 | ** dealing with. The first bit indicates whether the $if condition | 28 | |
| 30 | ** is false or true. The second bit indicates whether the lexical is | 29 | /* "ifstate" keeps the state of each nested $if the lexical is dealing with. */ |
| 31 | ** inside the "then" part (0) or the "else" part (2) | 30 | |
| 32 | */ | 31 | static struct { |
| 33 | static int ifstate[MAX_IFS]; /* 0 => then part - condition false */ | 32 | int elsepart; /* true if its in the $else part */ |
| 34 | /* 1 => then part - condition true */ | 33 | int condition; /* true if $if condition is true */ |
| 35 | /* 2 => else part - condition false */ | 34 | int skip; /* true if part must be skiped */ |
| 36 | /* 3 => else part - condition true */ | 35 | } ifstate[MAX_IFS]; |
| 36 | |||
| 37 | static int iflevel; /* level of nested $if's */ | 37 | static int iflevel; /* level of nested $if's */ |
| 38 | 38 | ||
| 39 | 39 | ||
| @@ -42,6 +42,8 @@ void lua_setinput (Input fn) | |||
| 42 | current = '\n'; | 42 | current = '\n'; |
| 43 | lua_linenumber = 0; | 43 | lua_linenumber = 0; |
| 44 | iflevel = 0; | 44 | iflevel = 0; |
| 45 | ifstate[0].skip = 0; | ||
| 46 | ifstate[0].elsepart = 1; /* to avoid a free $else */ | ||
| 45 | input = fn; | 47 | input = fn; |
| 46 | } | 48 | } |
| 47 | 49 | ||
| @@ -117,10 +119,9 @@ static void skipspace (void) | |||
| 117 | 119 | ||
| 118 | static int checkcond (char *buff) | 120 | static int checkcond (char *buff) |
| 119 | { | 121 | { |
| 120 | if (strcmp(buff, "nil") == 0) | 122 | static char *opts[] = {"nil", "1"}; |
| 121 | return 0; | 123 | int i = luaI_findstring(buff, opts); |
| 122 | else if (strcmp(buff, "1") == 0) | 124 | if (i >= 0) return i; |
| 123 | return 1; | ||
| 124 | else if (isalpha((unsigned char)buff[0]) || buff[0] == '_') | 125 | else if (isalpha((unsigned char)buff[0]) || buff[0] == '_') |
| 125 | return luaI_globaldefined(buff); | 126 | return luaI_globaldefined(buff); |
| 126 | else { | 127 | else { |
| @@ -149,11 +150,9 @@ static void readname (char *buff) | |||
| 149 | static void inclinenumber (void); | 150 | static void inclinenumber (void); |
| 150 | 151 | ||
| 151 | 152 | ||
| 152 | static void ifskip (int thisiflevel) | 153 | static void ifskip (void) |
| 153 | { | 154 | { |
| 154 | if (thisiflevel < 0) return; | 155 | while (ifstate[iflevel].skip) { |
| 155 | while (iflevel > thisiflevel && | ||
| 156 | (ifstate[thisiflevel] == 0 || ifstate[thisiflevel] == 3)) { | ||
| 157 | if (current == '\n') | 156 | if (current == '\n') |
| 158 | inclinenumber(); | 157 | inclinenumber(); |
| 159 | else if (current == 0) | 158 | else if (current == 0) |
| @@ -166,51 +165,60 @@ static void ifskip (int thisiflevel) | |||
| 166 | static void inclinenumber (void) | 165 | static void inclinenumber (void) |
| 167 | { | 166 | { |
| 168 | static char *pragmas [] = | 167 | static char *pragmas [] = |
| 169 | {"debug", "nodebug", "end", "ifnot", "if", "else", "endinput", NULL}; | 168 | {"debug", "nodebug", "endinput", "end", "ifnot", "if", "else", NULL}; |
| 170 | next(); /* skip '\n' */ | 169 | next(); /* skip '\n' */ |
| 171 | ++lua_linenumber; | 170 | ++lua_linenumber; |
| 172 | if (current == '$') { /* is a pragma? */ | 171 | if (current == '$') { /* is a pragma? */ |
| 173 | char buff[PRAGMASIZE+1]; | 172 | char buff[PRAGMASIZE+1]; |
| 174 | int ifnot = 0; | 173 | int ifnot = 0; |
| 174 | int skip = ifstate[iflevel].skip; | ||
| 175 | next(); /* skip $ */ | 175 | next(); /* skip $ */ |
| 176 | readname(buff); | 176 | readname(buff); |
| 177 | switch (luaI_findstring(buff, pragmas)) { | 177 | switch (luaI_findstring(buff, pragmas)) { |
| 178 | case 0: /* debug */ | 178 | case 0: /* debug */ |
| 179 | lua_debug = 1; | 179 | if (!skip) lua_debug = 1; |
| 180 | break; | 180 | break; |
| 181 | case 1: /* nodebug */ | 181 | case 1: /* nodebug */ |
| 182 | lua_debug = 0; | 182 | if (!skip) lua_debug = 0; |
| 183 | break; | 183 | break; |
| 184 | case 2: /* end */ | 184 | case 2: /* endinput */ |
| 185 | if (--iflevel < 0) | 185 | if (!skip) { |
| 186 | current = 0; | ||
| 187 | iflevel = 0; /* to allow $endinput inside a $if */ | ||
| 188 | } | ||
| 189 | break; | ||
| 190 | case 3: /* end */ | ||
| 191 | if (iflevel-- == 0) | ||
| 186 | luaI_auxsyntaxerror("unmatched $endif"); | 192 | luaI_auxsyntaxerror("unmatched $endif"); |
| 187 | break; | 193 | break; |
| 188 | case 3: /* ifnot */ | 194 | case 4: /* ifnot */ |
| 189 | ifnot = 1; | 195 | ifnot = 1; |
| 190 | /* go through */ | 196 | /* go through */ |
| 191 | case 4: /* if */ | 197 | case 5: /* if */ |
| 192 | if (iflevel == MAX_IFS) | 198 | if (iflevel == MAX_IFS-1) |
| 193 | luaI_auxsyntaxerror("too many nested `$ifs'"); | 199 | luaI_auxsyntaxerror("too many nested `$ifs'"); |
| 194 | readname(buff); | 200 | readname(buff); |
| 195 | ifstate[iflevel++] = checkcond(buff) ? !ifnot : ifnot; | 201 | iflevel++; |
| 202 | ifstate[iflevel].elsepart = 0; | ||
| 203 | ifstate[iflevel].condition = checkcond(buff) ? !ifnot : ifnot; | ||
| 204 | ifstate[iflevel].skip = skip || !ifstate[iflevel].condition; | ||
| 196 | break; | 205 | break; |
| 197 | case 5: /* else */ | 206 | case 6: /* else */ |
| 198 | if (iflevel <= 0 || (ifstate[iflevel-1] & 2)) | 207 | if (ifstate[iflevel].elsepart) |
| 199 | luaI_auxsyntaxerror("unmatched $else"); | 208 | luaI_auxsyntaxerror("unmatched $else"); |
| 200 | ifstate[iflevel-1] = ifstate[iflevel-1] | 2; | 209 | ifstate[iflevel].elsepart = 1; |
| 201 | break; | 210 | ifstate[iflevel].skip = |
| 202 | case 6: /* endinput */ | 211 | ifstate[iflevel-1].skip || ifstate[iflevel].condition; |
| 203 | current = 0; | ||
| 204 | break; | 212 | break; |
| 205 | default: | 213 | default: |
| 206 | luaI_auxsynterrbf("invalid pragma", buff); | 214 | luaI_auxsynterrbf("invalid pragma", buff); |
| 207 | } | 215 | } |
| 208 | skipspace(); | 216 | skipspace(); |
| 209 | if (current == '\n') /* pragma must end with a '\n' */ | 217 | if (current == '\n') /* pragma must end with a '\n' ... */ |
| 210 | inclinenumber(); | 218 | inclinenumber(); |
| 211 | else if (current != 0) /* or eof */ | 219 | else if (current != 0) /* or eof */ |
| 212 | luaI_auxsyntaxerror("invalid pragma format"); | 220 | luaI_auxsyntaxerror("invalid pragma format"); |
| 213 | ifskip(iflevel-1); | 221 | ifskip(); |
| 214 | } | 222 | } |
| 215 | } | 223 | } |
| 216 | 224 | ||
