aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>1997-04-12 12:01:49 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>1997-04-12 12:01:49 -0300
commita8cd072c76da0a9f11c86d3e44766ecf97a3f402 (patch)
treee09a88712f89434691c4ea1931b3534c57657fda
parent83e9897cf0c7a8172be162b0413f30b892932dc6 (diff)
downloadlua-a8cd072c76da0a9f11c86d3e44766ecf97a3f402.tar.gz
lua-a8cd072c76da0a9f11c86d3e44766ecf97a3f402.tar.bz2
lua-a8cd072c76da0a9f11c86d3e44766ecf97a3f402.zip
nested "$if's", "$else", and "$if" constants (nil & 1).
-rw-r--r--lex.c142
1 files changed, 103 insertions, 39 deletions
diff --git a/lex.c b/lex.c
index 3c8da4c2..8740f1e2 100644
--- a/lex.c
+++ b/lex.c
@@ -1,4 +1,4 @@
1char *rcs_lex = "$Id: lex.c,v 2.45 1997/04/01 21:23:20 roberto Exp roberto $"; 1char *rcs_lex = "$Id: lex.c,v 2.46 1997/04/07 14:48:53 roberto Exp roberto $";
2 2
3 3
4#include <ctype.h> 4#include <ctype.h>
@@ -22,6 +22,18 @@ char *rcs_lex = "$Id: lex.c,v 2.45 1997/04/01 21:23:20 roberto Exp roberto $";
22 22
23static int current; /* look ahead character */ 23static int current; /* look ahead character */
24static Input input; /* input function */ 24static Input input; /* input function */
25
26#define MAX_IFS 10
27
28/* "ifstate" keeps the state of each nested $if the lexical is
29** dealing with. The first bit indicates whether the $if condition
30** is false or true. The second bit indicates whether the lexical is
31** inside the "then" part (0) or the "else" part (2)
32*/
33static int ifstate[MAX_IFS]; /* 0 => then part - condition false */
34 /* 1 => then part - condition true */
35 /* 2 => else part - condition false */
36 /* 3 => else part - condition true */
25static int iflevel; /* level of nested $if's */ 37static int iflevel; /* level of nested $if's */
26 38
27 39
@@ -33,11 +45,15 @@ void lua_setinput (Input fn)
33 input = fn; 45 input = fn;
34} 46}
35 47
36static void luaI_auxsyntaxerror (char *s, char *token) 48
49static void luaI_auxsyntaxerror (char *s)
50{
51 luaL_verror("%s;\n> at line %d in file %s",
52 s, lua_linenumber, lua_parsedfile);
53}
54
55static void luaI_auxsynterrbf (char *s, char *token)
37{ 56{
38 if (token == NULL)
39 luaL_verror("%s;\n> at line %d in file %s",
40 s, lua_linenumber, lua_parsedfile);
41 if (token[0] == 0) 57 if (token[0] == 0)
42 token = "<eof>"; 58 token = "<eof>";
43 luaL_verror("%s;\n> last token read: \"%s\" at line %d in file %s", 59 luaL_verror("%s;\n> last token read: \"%s\" at line %d in file %s",
@@ -46,7 +62,7 @@ static void luaI_auxsyntaxerror (char *s, char *token)
46 62
47void luaI_syntaxerror (char *s) 63void luaI_syntaxerror (char *s)
48{ 64{
49 luaI_auxsyntaxerror(s, luaI_buffer(1)); 65 luaI_auxsynterrbf(s, luaI_buffer(1));
50} 66}
51 67
52 68
@@ -87,27 +103,74 @@ void luaI_addReserved (void)
87} 103}
88 104
89 105
106/*
107** Pragma handling
108*/
109
110#define PRAGMASIZE 20
111
112static void skipspace (void)
113{
114 while (current == ' ' || current == '\t') next();
115}
116
117
118static int checkcond (char *buff)
119{
120 if (strcmp(buff, "nil") == 0)
121 return 0;
122 else if (strcmp(buff, "1") == 0)
123 return 1;
124 else if (isalpha((unsigned char)buff[0]))
125 return luaI_globaldefined(buff);
126 else {
127 luaI_auxsynterrbf("invalid $if condition", buff);
128 return 0; /* to avoid warnings */
129 }
130}
131
132
90static void readname (char *buff) 133static void readname (char *buff)
91{ 134{
92 int i = 0; 135 int i = 0;
93 while (current == ' ') next(); 136 skipspace();
94 while (isalnum((unsigned char)current)) { 137 while (isalnum((unsigned char)current)) {
95 if (i >= MINBUFF) luaI_syntaxerror("pragma too long"); 138 if (i >= PRAGMASIZE) {
139 buff[PRAGMASIZE] = 0;
140 luaI_auxsynterrbf("pragma too long", buff);
141 }
96 buff[i++] = current; 142 buff[i++] = current;
97 next(); 143 next();
98 } 144 }
99 buff[i] = 0; 145 buff[i] = 0;
100 if (!isalpha(buff[0]) || (current != 0 && !isspace(current)))
101 luaI_auxsyntaxerror("invalid pragma format", NULL);
102} 146}
103 147
104static int inclinenumber (void) 148
149static void inclinenumber (void);
150
151
152static void ifskip (int thisiflevel)
153{
154 while (iflevel > thisiflevel &&
155 (ifstate[thisiflevel] == 0 || ifstate[thisiflevel] == 3)) {
156 if (current == '\n')
157 inclinenumber();
158 else if (current == 0)
159 luaI_auxsyntaxerror("input ends inside a $if");
160 else next();
161 }
162}
163
164
165static void inclinenumber (void)
105{ 166{
106 static char *pragmas [] = {"debug", "nodebug", "endif", "ifnil", "if", NULL}; 167 static char *pragmas [] =
107 int ifnil = 0; 168 {"debug", "nodebug", "end", "ifnot", "if", "else", NULL};
169 next(); /* skip '\n' */
108 ++lua_linenumber; 170 ++lua_linenumber;
109 if (current == '$') { /* is a pragma? */ 171 if (current == '$') { /* is a pragma? */
110 char buff[MINBUFF+1]; 172 char buff[PRAGMASIZE+1];
173 int ifnot = 0;
111 next(); /* skip $ */ 174 next(); /* skip $ */
112 readname(buff); 175 readname(buff);
113 switch (luaI_findstring(buff, pragmas)) { 176 switch (luaI_findstring(buff, pragmas)) {
@@ -117,34 +180,35 @@ static int inclinenumber (void)
117 case 1: /* nodebug */ 180 case 1: /* nodebug */
118 lua_debug = 0; 181 lua_debug = 0;
119 break; 182 break;
120 case 2: /* endif */ 183 case 2: /* end */
121 if (--iflevel < 0) 184 if (--iflevel < 0)
122 luaI_auxsyntaxerror("too many $endif's", NULL); 185 luaI_auxsyntaxerror("unmatched $endif");
123 break; 186 break;
124 case 3: /* ifnil */ 187 case 3: /* ifnot */
125 ifnil = 1; 188 ifnot = 1;
126 /* go through */ 189 /* go through */
127 case 4: { /* if */ 190 case 4: /* if */
128 int thisiflevel = iflevel++; 191 if (iflevel == MAX_IFS)
192 luaI_auxsyntaxerror("too many nested `$ifs'");
129 readname(buff); 193 readname(buff);
130 if ((ifnil && luaI_globaldefined(buff)) || 194 ifstate[iflevel++] = checkcond(buff) ? !ifnot : ifnot;
131 (!ifnil && !luaI_globaldefined(buff))) { /* skip the $if? */
132 do {
133 if (current == '\n') {
134 next();
135 inclinenumber();
136 }
137 else if (current == 0)
138 luaI_auxsyntaxerror("input ends inside a $if", NULL);
139 else next();
140 } while (iflevel > thisiflevel);
141 }
142 break; 195 break;
143 } 196 case 5: /* else */
144 default: luaI_auxsyntaxerror("invalid pragma", buff); 197 if (iflevel <= 0 || (ifstate[iflevel-1] & 2))
198 luaI_auxsyntaxerror("unmatched $else");
199 ifstate[iflevel-1] = ifstate[iflevel-1] | 2;
200 break;
201 default:
202 luaI_auxsynterrbf("invalid pragma", buff);
145 } 203 }
204 skipspace();
205 if (current == '\n') /* pragma must end with a '\n' */
206 inclinenumber();
207 else if (current != 0) /* or eof */
208 luaI_auxsyntaxerror("invalid pragma format");
209 if (iflevel > 0)
210 ifskip(iflevel-1);
146 } 211 }
147 return lua_linenumber;
148} 212}
149 213
150static int read_long_string (char *yytext, int buffsize) 214static int read_long_string (char *yytext, int buffsize)
@@ -178,7 +242,7 @@ static int read_long_string (char *yytext, int buffsize)
178 } 242 }
179 continue; 243 continue;
180 case '\n': 244 case '\n':
181 save_and_next(); 245 save('\n');
182 inclinenumber(); 246 inclinenumber();
183 continue; 247 continue;
184 default: 248 default:
@@ -209,8 +273,8 @@ int luaY_lex (void)
209 switch (current) 273 switch (current)
210 { 274 {
211 case '\n': 275 case '\n':
212 next(); 276 inclinenumber();
213 linelasttoken = inclinenumber(); 277 linelasttoken = lua_linenumber;
214 continue; 278 continue;
215 279
216 case ' ': case '\t': case '\r': /* CR: to avoid problems with DOS */ 280 case ' ': case '\t': case '\r': /* CR: to avoid problems with DOS */
@@ -274,7 +338,7 @@ int luaY_lex (void)
274 case 'n': save('\n'); next(); break; 338 case 'n': save('\n'); next(); break;
275 case 't': save('\t'); next(); break; 339 case 't': save('\t'); next(); break;
276 case 'r': save('\r'); next(); break; 340 case 'r': save('\r'); next(); break;
277 case '\n': save_and_next(); inclinenumber(); break; 341 case '\n': save('\n'); inclinenumber(); break;
278 default : save_and_next(); break; 342 default : save_and_next(); break;
279 } 343 }
280 break; 344 break;