diff options
| -rw-r--r-- | llex.c | 179 | ||||
| -rw-r--r-- | llex.h | 13 | ||||
| -rw-r--r-- | llimits.h | 14 |
3 files changed, 40 insertions, 166 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: llex.c,v 1.60 2000/05/24 18:04:17 roberto Exp roberto $ | 2 | ** $Id: llex.c,v 1.61 2000/05/25 18:59:59 roberto Exp roberto $ |
| 3 | ** Lexical Analyzer | 3 | ** Lexical Analyzer |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -96,152 +96,56 @@ static void luaX_invalidchar (LexState *ls, int c) { | |||
| 96 | } | 96 | } |
| 97 | 97 | ||
| 98 | 98 | ||
| 99 | static void firstline (LexState *LS) | 99 | static const char *readname (lua_State *L, LexState *LS) { |
| 100 | { | ||
| 101 | int c = zgetc(LS->z); | ||
| 102 | if (c == '#') | ||
| 103 | while ((c=zgetc(LS->z)) != '\n' && c != EOZ) /* skip first line */; | ||
| 104 | zungetc(LS->z); | ||
| 105 | } | ||
| 106 | |||
| 107 | |||
| 108 | void luaX_setinput (lua_State *L, LexState *LS, ZIO *z) { | ||
| 109 | LS->L = L; | ||
| 110 | LS->current = '\n'; | ||
| 111 | LS->lookahead.token = TK_EOS; /* no look-ahead token */ | ||
| 112 | LS->linenumber = 0; | ||
| 113 | LS->iflevel = 0; | ||
| 114 | LS->ifstate[0].skip = 0; | ||
| 115 | LS->ifstate[0].elsepart = 1; /* to avoid a free $else */ | ||
| 116 | LS->z = z; | ||
| 117 | LS->fs = NULL; | ||
| 118 | firstline(LS); | ||
| 119 | luaL_resetbuffer(L); | 100 | luaL_resetbuffer(L); |
| 101 | do { | ||
| 102 | save_and_next(L, LS); | ||
| 103 | } while (isalnum(LS->current) || LS->current == '_'); | ||
| 104 | save(L, '\0'); | ||
| 105 | return L->Mbuffer+L->Mbuffbase; | ||
| 120 | } | 106 | } |
| 121 | 107 | ||
| 122 | 108 | ||
| 123 | 109 | static void inclinenumber (LexState *LS) { | |
| 124 | /* | ||
| 125 | ** ======================================================= | ||
| 126 | ** PRAGMAS | ||
| 127 | ** ======================================================= | ||
| 128 | */ | ||
| 129 | |||
| 130 | static void skipspace (LexState *LS) { | ||
| 131 | while (LS->current == ' ' || LS->current == '\t' || LS->current == '\r') | ||
| 132 | next(LS); | ||
| 133 | } | ||
| 134 | |||
| 135 | |||
| 136 | static int globaldefined (lua_State *L, const char *name) { | ||
| 137 | const TObject *value = luaH_getglobal(L, name); | ||
| 138 | return ttype(value) != TAG_NIL; | ||
| 139 | } | ||
| 140 | |||
| 141 | |||
| 142 | static int checkcond (lua_State *L, LexState *LS, const char *buff) { | ||
| 143 | static const char *const opts[] = {"nil", "1", NULL}; | ||
| 144 | int i = luaL_findstring(buff, opts); | ||
| 145 | if (i >= 0) return i; | ||
| 146 | else if (isalpha((unsigned char)buff[0]) || buff[0] == '_') | ||
| 147 | return globaldefined(L, buff); | ||
| 148 | else { | ||
| 149 | luaX_syntaxerror(LS, "invalid $if condition", buff); | ||
| 150 | return 0; /* to avoid warnings */ | ||
| 151 | } | ||
| 152 | } | ||
| 153 | |||
| 154 | |||
| 155 | static void readname (LexState *LS, char *buff) { | ||
| 156 | int i = 0; | ||
| 157 | skipspace(LS); | ||
| 158 | while (isalnum(LS->current) || LS->current == '_') { | ||
| 159 | if (i >= PRAGMASIZE) { | ||
| 160 | buff[PRAGMASIZE] = 0; | ||
| 161 | luaX_syntaxerror(LS, "pragma too long", buff); | ||
| 162 | } | ||
| 163 | buff[i++] = (char)LS->current; | ||
| 164 | next(LS); | ||
| 165 | } | ||
| 166 | buff[i] = 0; | ||
| 167 | } | ||
| 168 | |||
| 169 | |||
| 170 | static void inclinenumber (lua_State *L, LexState *LS); | ||
| 171 | |||
| 172 | |||
| 173 | static void ifskip (lua_State *L, LexState *LS) { | ||
| 174 | while (LS->ifstate[LS->iflevel].skip) { | ||
| 175 | if (LS->current == '\n') | ||
| 176 | inclinenumber(L, LS); | ||
| 177 | else if (LS->current == EOZ) | ||
| 178 | luaX_error(LS, "input ends inside a $if", TK_EOS); | ||
| 179 | else next(LS); | ||
| 180 | } | ||
| 181 | } | ||
| 182 | |||
| 183 | |||
| 184 | static void inclinenumber (lua_State *L, LexState *LS) { | ||
| 185 | static const char *const pragmas [] = | ||
| 186 | {"debug", "nodebug", "endinput", "end", "ifnot", "if", "else", NULL}; | ||
| 187 | next(LS); /* skip '\n' */ | 110 | next(LS); /* skip '\n' */ |
| 188 | ++LS->linenumber; | 111 | ++LS->linenumber; |
| 189 | luaX_checklimit(LS, LS->linenumber, MAX_INT, "lines in a chunk"); | 112 | luaX_checklimit(LS, LS->linenumber, MAX_INT, "lines in a chunk"); |
| 113 | } | ||
| 114 | |||
| 115 | |||
| 116 | static void checkpragma (lua_State *L, LexState *LS) { | ||
| 117 | static const char *const pragmas [] = {"debug", "nodebug", NULL}; | ||
| 190 | if (LS->current == '$') { /* is a pragma? */ | 118 | if (LS->current == '$') { /* is a pragma? */ |
| 191 | char buff[PRAGMASIZE+1]; | 119 | switch (luaL_findstring(readname(L, LS)+1, pragmas)) { |
| 192 | int ifnot = 0; | ||
| 193 | int skip = LS->ifstate[LS->iflevel].skip; | ||
| 194 | next(LS); /* skip $ */ | ||
| 195 | readname(LS, buff); | ||
| 196 | switch (luaL_findstring(buff, pragmas)) { | ||
| 197 | case 0: /* debug */ | 120 | case 0: /* debug */ |
| 198 | if (!skip) L->debug = 1; | 121 | L->debug = 1; |
| 199 | break; | 122 | break; |
| 200 | case 1: /* nodebug */ | 123 | case 1: /* nodebug */ |
| 201 | if (!skip) L->debug = 0; | 124 | L->debug = 0; |
| 202 | break; | ||
| 203 | case 2: /* endinput */ | ||
| 204 | if (!skip) { | ||
| 205 | LS->current = EOZ; | ||
| 206 | LS->iflevel = 0; /* to allow $endinput inside a $if */ | ||
| 207 | } | ||
| 208 | break; | ||
| 209 | case 3: /* end */ | ||
| 210 | if (LS->iflevel-- == 0) | ||
| 211 | luaX_syntaxerror(LS, "unmatched $end", "$end"); | ||
| 212 | break; | ||
| 213 | case 4: /* ifnot */ | ||
| 214 | ifnot = 1; | ||
| 215 | /* go through */ | ||
| 216 | case 5: /* if */ | ||
| 217 | if (LS->iflevel == MAX_IFS-1) | ||
| 218 | luaX_syntaxerror(LS, "too many nested $ifs", "$if"); | ||
| 219 | readname(LS, buff); | ||
| 220 | LS->iflevel++; | ||
| 221 | LS->ifstate[LS->iflevel].elsepart = 0; | ||
| 222 | LS->ifstate[LS->iflevel].condition = checkcond(L, LS, buff) ? !ifnot : ifnot; | ||
| 223 | LS->ifstate[LS->iflevel].skip = skip || !LS->ifstate[LS->iflevel].condition; | ||
| 224 | break; | ||
| 225 | case 6: /* else */ | ||
| 226 | if (LS->ifstate[LS->iflevel].elsepart) | ||
| 227 | luaX_syntaxerror(LS, "unmatched $else", "$else"); | ||
| 228 | LS->ifstate[LS->iflevel].elsepart = 1; | ||
| 229 | LS->ifstate[LS->iflevel].skip = LS->ifstate[LS->iflevel-1].skip || | ||
| 230 | LS->ifstate[LS->iflevel].condition; | ||
| 231 | break; | 125 | break; |
| 232 | default: | 126 | default: |
| 233 | luaX_syntaxerror(LS, "unknown pragma", buff); | 127 | luaX_error(LS, "unknown pragma", TK_STRING); |
| 234 | } | 128 | } |
| 235 | skipspace(LS); | ||
| 236 | if (LS->current == '\n') /* pragma must end with a '\n' ... */ | ||
| 237 | inclinenumber(L, LS); | ||
| 238 | else if (LS->current != EOZ) /* or eof */ | ||
| 239 | luaX_syntaxerror(LS, "invalid pragma format", buff); | ||
| 240 | ifskip(L, LS); | ||
| 241 | } | 129 | } |
| 242 | } | 130 | } |
| 243 | 131 | ||
| 244 | 132 | ||
| 133 | void luaX_setinput (lua_State *L, LexState *LS, ZIO *z) { | ||
| 134 | LS->L = L; | ||
| 135 | LS->lookahead.token = TK_EOS; /* no look-ahead token */ | ||
| 136 | LS->z = z; | ||
| 137 | LS->fs = NULL; | ||
| 138 | LS->linenumber = 1; | ||
| 139 | next(LS); /* read first char */ | ||
| 140 | if (LS->current == '#') { | ||
| 141 | do { /* skip first line */ | ||
| 142 | next(LS); | ||
| 143 | } while (LS->current != '\n' && LS->current != EOZ); | ||
| 144 | } | ||
| 145 | else checkpragma(L, LS); | ||
| 146 | } | ||
| 147 | |||
| 148 | |||
| 245 | 149 | ||
| 246 | /* | 150 | /* |
| 247 | ** ======================================================= | 151 | ** ======================================================= |
| @@ -275,7 +179,7 @@ static void read_long_string (lua_State *L, LexState *LS) { | |||
| 275 | continue; | 179 | continue; |
| 276 | case '\n': | 180 | case '\n': |
| 277 | save(L, '\n'); | 181 | save(L, '\n'); |
| 278 | inclinenumber(L, LS); | 182 | inclinenumber(LS); |
| 279 | continue; | 183 | continue; |
| 280 | default: | 184 | default: |
| 281 | save_and_next(L, LS); | 185 | save_and_next(L, LS); |
| @@ -304,7 +208,7 @@ static void read_string (lua_State *L, LexState *LS, int del) { | |||
| 304 | case 'r': save(L, '\r'); next(LS); break; | 208 | case 'r': save(L, '\r'); next(LS); break; |
| 305 | case 't': save(L, '\t'); next(LS); break; | 209 | case 't': save(L, '\t'); next(LS); break; |
| 306 | case 'v': save(L, '\v'); next(LS); break; | 210 | case 'v': save(L, '\v'); next(LS); break; |
| 307 | case '\n': save(L, '\n'); inclinenumber(L, LS); break; | 211 | case '\n': save(L, '\n'); inclinenumber(LS); break; |
| 308 | case '0': case '1': case '2': case '3': case '4': | 212 | case '0': case '1': case '2': case '3': case '4': |
| 309 | case '5': case '6': case '7': case '8': case '9': { | 213 | case '5': case '6': case '7': case '8': case '9': { |
| 310 | int c = 0; | 214 | int c = 0; |
| @@ -343,7 +247,8 @@ int luaX_lex (LexState *LS) { | |||
| 343 | continue; | 247 | continue; |
| 344 | 248 | ||
| 345 | case '\n': | 249 | case '\n': |
| 346 | inclinenumber(L, LS); | 250 | inclinenumber(LS); |
| 251 | checkpragma(L, LS); | ||
| 347 | continue; | 252 | continue; |
| 348 | 253 | ||
| 349 | case '-': | 254 | case '-': |
| @@ -432,8 +337,6 @@ int luaX_lex (LexState *LS) { | |||
| 432 | return TK_NUMBER; | 337 | return TK_NUMBER; |
| 433 | 338 | ||
| 434 | case EOZ: | 339 | case EOZ: |
| 435 | if (LS->iflevel > 0) | ||
| 436 | luaX_error(LS, "input ends inside a $if", TK_EOS); | ||
| 437 | return TK_EOS; | 340 | return TK_EOS; |
| 438 | 341 | ||
| 439 | case '_': goto tname; | 342 | case '_': goto tname; |
| @@ -447,13 +350,7 @@ int luaX_lex (LexState *LS) { | |||
| 447 | return c; | 350 | return c; |
| 448 | } | 351 | } |
| 449 | tname: { /* identifier or reserved word */ | 352 | tname: { /* identifier or reserved word */ |
| 450 | TString *ts; | 353 | TString *ts = luaS_new(L, readname(L, LS)); |
| 451 | luaL_resetbuffer(L); | ||
| 452 | do { | ||
| 453 | save_and_next(L, LS); | ||
| 454 | } while (isalnum(LS->current) || LS->current == '_'); | ||
| 455 | save(L, '\0'); | ||
| 456 | ts = luaS_new(L, L->Mbuffer+L->Mbuffbase); | ||
| 457 | if (ts->marked >= RESERVEDMARK) /* reserved word? */ | 354 | if (ts->marked >= RESERVEDMARK) /* reserved word? */ |
| 458 | return ts->marked-RESERVEDMARK+FIRST_RESERVED; | 355 | return ts->marked-RESERVEDMARK+FIRST_RESERVED; |
| 459 | LS->t.seminfo.ts = ts; | 356 | LS->t.seminfo.ts = ts; |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: llex.h,v 1.26 2000/05/24 18:04:17 roberto Exp roberto $ | 2 | ** $Id: llex.h,v 1.27 2000/05/25 18:59:59 roberto Exp roberto $ |
| 3 | ** Lexical Analyzer | 3 | ** Lexical Analyzer |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -35,15 +35,6 @@ enum RESERVED { | |||
| 35 | #define NUM_RESERVED ((int)(TK_WHILE-FIRST_RESERVED+1)) | 35 | #define NUM_RESERVED ((int)(TK_WHILE-FIRST_RESERVED+1)) |
| 36 | 36 | ||
| 37 | 37 | ||
| 38 | /* `ifState' keeps the state of each nested $if the lexical is dealing with. */ | ||
| 39 | |||
| 40 | struct ifState { | ||
| 41 | int elsepart; /* true if it's in the $else part */ | ||
| 42 | int condition; /* true if $if condition is true */ | ||
| 43 | int skip; /* true if part must be skipped */ | ||
| 44 | }; | ||
| 45 | |||
| 46 | |||
| 47 | typedef struct Token { | 38 | typedef struct Token { |
| 48 | int token; | 39 | int token; |
| 49 | union { | 40 | union { |
| @@ -60,8 +51,6 @@ typedef struct LexState { | |||
| 60 | struct lua_State *L; | 51 | struct lua_State *L; |
| 61 | struct zio *z; /* input stream */ | 52 | struct zio *z; /* input stream */ |
| 62 | int linenumber; /* input line counter */ | 53 | int linenumber; /* input line counter */ |
| 63 | int iflevel; /* level of nested $if's (for lexical analysis) */ | ||
| 64 | struct ifState ifstate[MAX_IFS]; | ||
| 65 | } LexState; | 54 | } LexState; |
| 66 | 55 | ||
| 67 | 56 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: llimits.h,v 1.6 2000/04/26 13:43:25 roberto Exp roberto $ | 2 | ** $Id: llimits.h,v 1.7 2000/05/24 13:54:49 roberto Exp roberto $ |
| 3 | ** Limits, basic types, and some other "instalation-dependent" definitions | 3 | ** Limits, basic types, and some other "instalation-dependent" definitions |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -179,18 +179,6 @@ typedef unsigned long Instruction; | |||
| 179 | #endif | 179 | #endif |
| 180 | 180 | ||
| 181 | 181 | ||
| 182 | /* maximum depth of nested $ifs */ | ||
| 183 | #ifndef MAX_IFS | ||
| 184 | #define MAX_IFS 5 /* arbitrary limit */ | ||
| 185 | #endif | ||
| 186 | |||
| 187 | |||
| 188 | /* maximum size of a pragma line */ | ||
| 189 | #ifndef PRAGMASIZE | ||
| 190 | #define PRAGMASIZE 80 /* arbitrary limit */ | ||
| 191 | #endif | ||
| 192 | |||
| 193 | |||
| 194 | /* maximum lookback to find a real constant (for code generation) */ | 182 | /* maximum lookback to find a real constant (for code generation) */ |
| 195 | #ifndef LOOKBACKNUMS | 183 | #ifndef LOOKBACKNUMS |
| 196 | #define LOOKBACKNUMS 20 /* arbitrary constant */ | 184 | #define LOOKBACKNUMS 20 /* arbitrary constant */ |
