2 ** $Id: llex.c,v 1.36 1999/06/17 17:04:03 roberto Exp $
4 ** See Copyright Notice in lua.h
23 #define next(LS) (LS->current = zgetc(LS->lex_z))
26 #define save(c) luaL_addchar(c)
27 #define save_and_next(LS) (save(LS->current), next(LS))
30 char *reserved
[] = {"and", "do", "else", "elseif", "end", "function",
31 "if", "local", "nil", "not", "or", "repeat", "return", "then",
35 void luaX_init (void) {
37 for (i
=0; i
<(sizeof(reserved
)/sizeof(reserved
[0])); i
++) {
38 TaggedString
*ts
= luaS_new(reserved
[i
]);
39 ts
->head
.marked
= FIRST_RESERVED
+i
; /* reserved word (always > 255) */
46 void luaX_syntaxerror (LexState
*ls
, char *s
, char *token
) {
48 luaL_chunkid(buff
, zname(ls
->lex_z
), sizeof(buff
));
51 luaL_verror("%.100s;\n last token read: `%.50s' at line %d in %.80s",
52 s
, token
, ls
->linenumber
, buff
);
56 void luaX_error (LexState
*ls
, char *s
) {
58 luaX_syntaxerror(ls
, s
, luaL_buffer());
62 void luaX_token2str (int token
, char *s
) {
68 strcpy(s
, reserved
[token
-FIRST_RESERVED
]);
72 static void luaX_invalidchar (LexState
*ls
, int c
) {
74 sprintf(buff
, "0x%02X", c
);
75 luaX_syntaxerror(ls
, "invalid control char", buff
);
79 static void firstline (LexState
*LS
)
81 int c
= zgetc(LS
->lex_z
);
83 while ((c
=zgetc(LS
->lex_z
)) != '\n' && c
!= EOZ
) /* skip first line */;
88 void luaX_setinput (LexState
*LS
, ZIO
*z
)
93 LS
->ifstate
[0].skip
= 0;
94 LS
->ifstate
[0].elsepart
= 1; /* to avoid a free $else */
104 ** =======================================================
106 ** =======================================================
110 #define PRAGMASIZE 80 /* arbitrary limit */
113 static void skipspace (LexState
*LS
) {
114 while (LS
->current
== ' ' || LS
->current
== '\t' || LS
->current
== '\r')
119 static int checkcond (LexState
*LS
, char *buff
) {
120 static char *opts
[] = {"nil", "1", NULL
};
121 int i
= luaL_findstring(buff
, opts
);
122 if (i
>= 0) return i
;
123 else if (isalpha((unsigned char)buff
[0]) || buff
[0] == '_')
124 return luaS_globaldefined(buff
);
126 luaX_syntaxerror(LS
, "invalid $if condition", buff
);
127 return 0; /* to avoid warnings */
132 static void readname (LexState
*LS
, char *buff
) {
135 while (isalnum(LS
->current
) || LS
->current
== '_') {
136 if (i
>= PRAGMASIZE
) {
137 buff
[PRAGMASIZE
] = 0;
138 luaX_syntaxerror(LS
, "pragma too long", buff
);
140 buff
[i
++] = (char)LS
->current
;
147 static void inclinenumber (LexState
*LS
);
150 static void ifskip (LexState
*LS
) {
151 while (LS
->ifstate
[LS
->iflevel
].skip
) {
152 if (LS
->current
== '\n')
154 else if (LS
->current
== EOZ
)
155 luaX_error(LS
, "input ends inside a $if");
161 static void inclinenumber (LexState
*LS
) {
162 static char *pragmas
[] =
163 {"debug", "nodebug", "endinput", "end", "ifnot", "if", "else", NULL
};
164 next(LS
); /* skip '\n' */
166 if (LS
->current
== '$') { /* is a pragma? */
167 char buff
[PRAGMASIZE
+1];
169 int skip
= LS
->ifstate
[LS
->iflevel
].skip
;
170 next(LS
); /* skip $ */
172 switch (luaL_findstring(buff
, pragmas
)) {
174 if (!skip
) L
->debug
= 1;
176 case 1: /* nodebug */
177 if (!skip
) L
->debug
= 0;
179 case 2: /* endinput */
182 LS
->iflevel
= 0; /* to allow $endinput inside a $if */
186 if (LS
->iflevel
-- == 0)
187 luaX_syntaxerror(LS
, "unmatched $end", "$end");
193 if (LS
->iflevel
== MAX_IFS
-1)
194 luaX_syntaxerror(LS
, "too many nested $ifs", "$if");
197 LS
->ifstate
[LS
->iflevel
].elsepart
= 0;
198 LS
->ifstate
[LS
->iflevel
].condition
= checkcond(LS
, buff
) ? !ifnot
: ifnot
;
199 LS
->ifstate
[LS
->iflevel
].skip
= skip
|| !LS
->ifstate
[LS
->iflevel
].condition
;
202 if (LS
->ifstate
[LS
->iflevel
].elsepart
)
203 luaX_syntaxerror(LS
, "unmatched $else", "$else");
204 LS
->ifstate
[LS
->iflevel
].elsepart
= 1;
205 LS
->ifstate
[LS
->iflevel
].skip
= LS
->ifstate
[LS
->iflevel
-1].skip
||
206 LS
->ifstate
[LS
->iflevel
].condition
;
209 luaX_syntaxerror(LS
, "unknown pragma", buff
);
212 if (LS
->current
== '\n') /* pragma must end with a '\n' ... */
214 else if (LS
->current
!= EOZ
) /* or eof */
215 luaX_syntaxerror(LS
, "invalid pragma format", buff
);
223 ** =======================================================
225 ** =======================================================
230 static int read_long_string (LexState
*LS
) {
233 switch (LS
->current
) {
235 luaX_error(LS
, "unfinished long string");
236 return EOS
; /* to avoid warnings */
239 if (LS
->current
== '[') {
246 if (LS
->current
== ']') {
247 if (cont
== 0) goto endloop
;
260 save_and_next(LS
); /* skip the second ']' */
261 LS
->seminfo
.ts
= luaS_newlstr(L
->Mbuffer
+(L
->Mbuffbase
+2),
262 L
->Mbuffnext
-L
->Mbuffbase
-4);
267 int luaX_lex (LexState
*LS
) {
270 switch (LS
->current
) {
272 case ' ': case '\t': case '\r': /* CR: to avoid problems with DOS */
282 if (LS
->current
!= '-') return '-';
283 do { next(LS
); } while (LS
->current
!= '\n' && LS
->current
!= EOZ
);
289 if (LS
->current
!= '[') return '[';
291 save_and_next(LS
); /* pass the second '[' */
292 return read_long_string(LS
);
297 if (LS
->current
!= '=') return '=';
298 else { save_and_next(LS
); return EQ
; }
302 if (LS
->current
!= '=') return '<';
303 else { save_and_next(LS
); return LE
; }
307 if (LS
->current
!= '=') return '>';
308 else { save_and_next(LS
); return GE
; }
312 if (LS
->current
!= '=') return '~';
313 else { save_and_next(LS
); return NE
; }
317 int del
= LS
->current
;
319 while (LS
->current
!= del
) {
320 switch (LS
->current
) {
323 luaX_error(LS
, "unfinished string");
324 return EOS
; /* to avoid warnings */
326 next(LS
); /* do not save the '\' */
327 switch (LS
->current
) {
328 case 'a': save('\a'); next(LS
); break;
329 case 'b': save('\b'); next(LS
); break;
330 case 'f': save('\f'); next(LS
); break;
331 case 'n': save('\n'); next(LS
); break;
332 case 'r': save('\r'); next(LS
); break;
333 case 't': save('\t'); next(LS
); break;
334 case 'v': save('\v'); next(LS
); break;
335 case '\n': save('\n'); inclinenumber(LS
); break;
337 if (isdigit(LS
->current
)) {
341 c
= 10*c
+ (LS
->current
-'0');
343 } while (++i
<3 && isdigit(LS
->current
));
344 if (c
!= (unsigned char)c
)
345 luaX_error(LS
, "escape sequence too large");
348 else { /* handles \, ", ', and ? */
360 save_and_next(LS
); /* skip delimiter */
361 LS
->seminfo
.ts
= luaS_newlstr(L
->Mbuffer
+(L
->Mbuffbase
+1),
362 L
->Mbuffnext
-L
->Mbuffbase
-2);
368 if (LS
->current
== '.')
371 if (LS
->current
== '.')
374 return DOTS
; /* ... */
376 else return CONC
; /* .. */
378 else if (!isdigit(LS
->current
)) return '.';
379 goto fraction
; /* LS->current is a digit: goes through to number */
381 case '0': case '1': case '2': case '3': case '4':
382 case '5': case '6': case '7': case '8': case '9':
385 } while (isdigit(LS
->current
));
386 if (LS
->current
== '.') {
388 if (LS
->current
== '.') {
391 "ambiguous syntax (decimal point x string concatenation)");
395 while (isdigit(LS
->current
))
397 if (toupper(LS
->current
) == 'E') {
398 save_and_next(LS
); /* read 'E' */
399 save_and_next(LS
); /* read '+', '-' or first digit */
400 while (isdigit(LS
->current
))
404 LS
->seminfo
.r
= luaO_str2d(L
->Mbuffer
+L
->Mbuffbase
);
405 if (LS
->seminfo
.r
< 0)
406 luaX_error(LS
, "invalid numeric format");
411 luaX_error(LS
, "input ends inside a $if");
415 if (LS
->current
!= '_' && !isalpha(LS
->current
)) {
418 luaX_invalidchar(LS
, c
);
422 else { /* identifier or reserved word */
426 } while (isalnum(LS
->current
) || LS
->current
== '_');
428 ts
= luaS_new(L
->Mbuffer
+L
->Mbuffbase
);
429 if (ts
->head
.marked
>= FIRST_RESERVED
)
430 return ts
->head
.marked
; /* reserved word */