delete MAkefile target links on realclean
[nedit-bw.git] / parseEnhance2.diff
blob1c49bbca3f6796df46c9830cf56a8916a895a254
1 ---
3 source/parse.y | 442 ++++++++++++++++++++-------------------------------------
4 1 file changed, 161 insertions(+), 281 deletions(-)
6 diff --quilt old/source/parse.y new/source/parse.y
7 --- old/source/parse.y
8 +++ new/source/parse.y
9 @@ -83,17 +83,21 @@ static int nextSymIsField = 0;
11 %union {
12 Symbol *sym;
13 Inst *inst;
14 int nArgs;
15 + enum operations oper;
17 %token <sym> NUMBER STRING SYMBOL FIELD
18 %token DELETE ARG_LOOKUP
19 -%token IF WHILE ELSE FOR BREAK CONTINUE RETURN
20 -%type <nArgs> arglist catlist
21 -%type <inst> cond comastmts for while else and or arrayexpr
22 +%token IF WHILE DO ELSE FOR BREAK CONTINUE RETURN
23 +%type <nArgs> arglistopt arglist catlist
24 +%type <inst> cond comastmts comastmtlst for while do else and or arrayexpr mark
25 %type <sym> evalsym
26 +%type <oper> operassign incrdecr
27 +%token <oper> '=' ADDEQ SUBEQ MULEQ DIVEQ MODEQ ANDEQ OREQ
28 +%token <oper> INCR DECR
30 %nonassoc IF_NO_ELSE
31 %nonassoc ELSE
33 %nonassoc ';'
34 @@ -137,36 +141,42 @@ block: '{' blank stmts '}' blank
35 stmts: stmt
36 | stmts stmt
38 stmtend: '\n' | ';'
40 +mark: /* nothing */ { $$ = GetPC(); } /* record instruction address */
41 + ;
42 stmt: ';' blank
43 | simpstmt stmtend blank
44 - | IF '(' cond ')' blank block %prec IF_NO_ELSE {
45 - SET_BR_OFF($3, GetPC());
46 + | IF blank '(' cond ')' blank block %prec IF_NO_ELSE {
47 + SET_BR_OFF($4, GetPC());
49 - | IF '(' cond ')' blank block else blank block %prec ELSE {
50 - SET_BR_OFF($3, ($7+1)); SET_BR_OFF($7, GetPC());
51 + | IF blank '(' cond ')' blank block else block %prec ELSE {
52 + SET_BR_OFF($4, ($8+1)); SET_BR_OFF($8, GetPC());
54 | while '(' cond ')' blank block {
55 ADD_OP(OP_BRANCH); ADD_BR_OFF($1);
56 SET_BR_OFF($3, GetPC()); FillLoopAddrs(GetPC(), $1);
58 + | do block WHILE blank '(' mark cond ')' stmtend blank {
59 + ADD_OP(OP_BRANCH); ADD_BR_OFF($1);
60 + SET_BR_OFF($7, GetPC()); FillLoopAddrs(GetPC(), $6);
61 + }
62 | for '(' comastmts ';' cond ';' comastmts ')' blank block {
63 FillLoopAddrs(GetPC()+2+($7-($5+1)), GetPC());
64 SwapCode($5+1, $7, GetPC());
65 ADD_OP(OP_BRANCH); ADD_BR_OFF($3); SET_BR_OFF($5, GetPC());
67 - | for '(' SYMBOL IN arrayexpr ')' {
68 + | for '(' blank SYMBOL IN blank arrayexpr blank ')' {
69 Symbol *iterSym = InstallIteratorSymbol();
70 ADD_OP(OP_BEGIN_ARRAY_ITER); ADD_SYM(iterSym);
71 - ADD_OP(OP_ARRAY_ITER); ADD_SYM($3); ADD_SYM(iterSym); ADD_BR_OFF(0);
72 + ADD_OP(OP_ARRAY_ITER); ADD_SYM($4); ADD_SYM(iterSym); ADD_BR_OFF(0);
74 blank block {
75 - ADD_OP(OP_BRANCH); ADD_BR_OFF($5+2);
76 - SET_BR_OFF($5+5, GetPC());
77 - FillLoopAddrs(GetPC(), $5+2);
78 + ADD_OP(OP_BRANCH); ADD_BR_OFF($7+2);
79 + SET_BR_OFF($7+5, GetPC());
80 + FillLoopAddrs(GetPC(), $7+2);
82 | BREAK stmtend blank {
83 ADD_OP(OP_BRANCH); ADD_BR_OFF(0);
84 if (AddBreakAddr(GetPC()-1)) {
85 yyerror("break outside loop"); YYERROR;
86 @@ -183,229 +193,130 @@ stmt: ';' blank
88 | RETURN stmtend blank {
89 ADD_OP(OP_RETURN_NO_VAL);
92 -simpstmt: SYMBOL '=' expr {
94 +operassign: ADDEQ { $$ = OP_ADD; }
95 + | SUBEQ { $$ = OP_SUB; }
96 + | MULEQ { $$ = OP_MUL; }
97 + | DIVEQ { $$ = OP_DIV; }
98 + | MODEQ { $$ = OP_MOD; }
99 + | ANDEQ { $$ = OP_BIT_AND; }
100 + | OREQ { $$ = OP_BIT_OR; }
102 +incrdecr: INCR { $$ = OP_INCR; }
103 + | DECR { $$ = OP_DECR; }
106 +simpstmt: /* simple variable assignment, op-assignment, incr/decrement */
107 + SYMBOL '=' blank expr {
108 ADD_OP(OP_ASSIGN); ADD_SYM($1);
110 - | evalsym ADDEQ expr {
111 - ADD_OP(OP_ADD); ADD_OP(OP_ASSIGN); ADD_SYM($1);
113 - | evalsym SUBEQ expr {
114 - ADD_OP(OP_SUB); ADD_OP(OP_ASSIGN); ADD_SYM($1);
116 - | evalsym MULEQ expr {
117 - ADD_OP(OP_MUL); ADD_OP(OP_ASSIGN); ADD_SYM($1);
118 + | evalsym operassign blank expr {
119 + ADD_OP($2); ADD_OP(OP_ASSIGN); ADD_SYM($1);
121 - | evalsym DIVEQ expr {
122 - ADD_OP(OP_DIV); ADD_OP(OP_ASSIGN); ADD_SYM($1);
123 + | incrdecr blank SYMBOL {
124 + ADD_OP(OP_PUSH_SYM); ADD_SYM($3); ADD_OP($1);
125 + ADD_OP(OP_ASSIGN); ADD_SYM($3);
127 - | evalsym MODEQ expr {
128 - ADD_OP(OP_MOD); ADD_OP(OP_ASSIGN); ADD_SYM($1);
130 - | evalsym ANDEQ expr {
131 - ADD_OP(OP_BIT_AND); ADD_OP(OP_ASSIGN); ADD_SYM($1);
133 - | evalsym OREQ expr {
134 - ADD_OP(OP_BIT_OR); ADD_OP(OP_ASSIGN); ADD_SYM($1);
135 + | SYMBOL incrdecr {
136 + ADD_OP(OP_PUSH_SYM); ADD_SYM($1); ADD_OP($2);
137 + ADD_OP(OP_ASSIGN); ADD_SYM($1);
139 - | DELETE arraylv '[' arglist ']' {
140 + /* delete array entry simple statement */
141 + | DELETE arraylv '[' arglistopt ']' {
142 ADD_OP(OP_ARRAY_DELETE); ADD_IMMED($4);
144 | DELETE arraylv dot field {
145 ADD_OP(OP_ARRAY_DELETE); ADD_IMMED(1);
147 -/* array[index] assignment */
148 - | initarraylv '[' arglist ']' '=' expr {
149 - ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED($3);
151 - | initarraylv '[' arglist ']' ADDEQ expr {
152 - ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED(1); ADD_IMMED($3);
153 - ADD_OP(OP_ADD);
154 - ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED($3);
156 - | initarraylv '[' arglist ']' SUBEQ expr {
157 - ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED(1); ADD_IMMED($3);
158 - ADD_OP(OP_SUB);
159 + /* array[index] assignment, op-assignment, incr/decrement */
160 + | initarraylv '[' arglistopt ']' '=' blank expr {
161 ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED($3);
163 - | initarraylv '[' arglist ']' MULEQ expr {
164 + | initarraylv '[' arglistopt ']' operassign blank expr {
165 ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED(1); ADD_IMMED($3);
166 - ADD_OP(OP_MUL);
167 + ADD_OP($5);
168 ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED($3);
170 - | initarraylv '[' arglist ']' DIVEQ expr {
171 - ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED(1); ADD_IMMED($3);
172 - ADD_OP(OP_DIV);
173 - ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED($3);
175 - | initarraylv '[' arglist ']' MODEQ expr {
176 - ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED(1); ADD_IMMED($3);
177 - ADD_OP(OP_MOD);
178 - ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED($3);
180 - | initarraylv '[' arglist ']' ANDEQ expr {
181 - ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED(1); ADD_IMMED($3);
182 - ADD_OP(OP_BIT_AND);
183 - ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED($3);
185 - | initarraylv '[' arglist ']' OREQ expr {
186 - ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED(1); ADD_IMMED($3);
187 - ADD_OP(OP_BIT_OR);
188 - ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED($3);
190 - | initarraylv '[' arglist ']' INCR {
191 + | initarraylv '[' arglistopt ']' incrdecr {
192 ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED(0); ADD_IMMED($3);
193 - ADD_OP(OP_INCR);
194 + ADD_OP($5);
195 ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED($3);
197 - | initarraylv '[' arglist ']' DECR {
198 - ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED(0); ADD_IMMED($3);
199 - ADD_OP(OP_DECR);
200 - ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED($3);
201 + | incrdecr blank initarraylv '[' arglistopt ']' {
202 + ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED(0); ADD_IMMED($5);
203 + ADD_OP($1);
204 + ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED($5);
206 - | INCR initarraylv '[' arglist ']' {
207 - ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED(0); ADD_IMMED($4);
208 - ADD_OP(OP_INCR);
209 - ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED($4);
211 - | DECR initarraylv '[' arglist ']' {
212 - ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED(0); ADD_IMMED($4);
213 - ADD_OP(OP_DECR);
214 - ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED($4);
216 -/* array.field assignment */
217 - | initarraylv dot field '=' expr {
218 + /* array.field assignment, op-assignment, incr/decrement */
219 + | initarraylv dot field '=' blank expr {
220 ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED(1);
222 - | initarraylv dot field ADDEQ expr {
223 - ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED(1); ADD_IMMED(1);
224 - ADD_OP(OP_ADD);
225 + | initarraylv dot field operassign blank expr {
226 + ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED(1);ADD_IMMED(1);
227 + ADD_OP($4);
228 ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED(1);
230 - | initarraylv dot field SUBEQ expr {
231 - ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED(1); ADD_IMMED(1);
232 - ADD_OP(OP_SUB);
233 - ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED(1);
235 - | initarraylv dot field MULEQ expr {
236 - ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED(1); ADD_IMMED(1);
237 - ADD_OP(OP_MUL);
238 - ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED(1);
240 - | initarraylv dot field DIVEQ expr {
241 - ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED(1); ADD_IMMED(1);
242 - ADD_OP(OP_DIV);
243 - ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED(1);
245 - | initarraylv dot field MODEQ expr {
246 - ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED(1); ADD_IMMED(1);
247 - ADD_OP(OP_MOD);
248 - ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED(1);
250 - | initarraylv dot field ANDEQ expr {
251 - ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED(1); ADD_IMMED(1);
252 - ADD_OP(OP_BIT_AND);
253 - ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED(1);
255 - | initarraylv dot field OREQ expr {
256 - ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED(1); ADD_IMMED(1);
257 - ADD_OP(OP_BIT_OR);
258 - ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED(1);
260 - | initarraylv dot field INCR {
261 - ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED(0); ADD_IMMED(1);
262 - ADD_OP(OP_INCR);
263 - ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED(1);
265 - | initarraylv dot field DECR {
266 - ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED(0); ADD_IMMED(1);
267 - ADD_OP(OP_DECR);
268 - ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED(1);
270 - | INCR initarraylv dot field {
271 + | initarraylv dot field incrdecr {
272 ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED(0); ADD_IMMED(1);
273 - ADD_OP(OP_INCR);
274 + ADD_OP($4);
275 ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED(1);
277 - | DECR initarraylv dot field {
278 + | incrdecr blank initarraylv dot field {
279 ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED(0); ADD_IMMED(1);
280 - ADD_OP(OP_DECR);
281 + ADD_OP($1);
282 ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED(1);
284 - | SYMBOL '(' arglist ')' {
285 + /* function call */
286 + | SYMBOL '(' arglistopt ')' {
287 ADD_OP(OP_SUBR_CALL);
288 ADD_SYM(PromoteToGlobal($1)); ADD_IMMED($3);
290 - | INCR SYMBOL {
291 - ADD_OP(OP_PUSH_SYM); ADD_SYM($2); ADD_OP(OP_INCR);
292 - ADD_OP(OP_ASSIGN); ADD_SYM($2);
294 - | SYMBOL INCR {
295 - ADD_OP(OP_PUSH_SYM); ADD_SYM($1); ADD_OP(OP_INCR);
296 - ADD_OP(OP_ASSIGN); ADD_SYM($1);
298 - | DECR SYMBOL {
299 - ADD_OP(OP_PUSH_SYM); ADD_SYM($2); ADD_OP(OP_DECR);
300 - ADD_OP(OP_ASSIGN); ADD_SYM($2);
302 - | SYMBOL DECR {
303 - ADD_OP(OP_PUSH_SYM); ADD_SYM($1); ADD_OP(OP_DECR);
304 - ADD_OP(OP_ASSIGN); ADD_SYM($1);
308 evalsym: SYMBOL {
309 $$ = $1; ADD_OP(OP_PUSH_SYM); ADD_SYM($1);
312 -comastmts: /* nothing */ {
313 - $$ = GetPC();
315 - | simpstmt {
316 - $$ = GetPC();
318 - | comastmts ',' simpstmt {
319 - $$ = GetPC();
321 +comastmts: blank { $$ = GetPC(); }
322 + | blank comastmtlst { $$ = $2; }
324 -arglist: /* nothing */ {
325 - $$ = 0;
327 - | expr {
328 - $$ = 1;
330 - | arglist ',' expr {
331 - $$ = $1 + 1;
333 +comastmtlst: simpstmt blank { $$ = GetPC(); }
334 + | comastmtlst ',' blank simpstmt blank { $$ = GetPC(); }
337 +arglistopt: blank { $$ = 0; }
338 + | arglist { $$ = $1; }
340 +arglist: blank expr blank { $$ = 1; }
341 + | arglist ',' blank expr blank { $$ = $1 + 1; }
343 +catlist: numexpr %prec CONCAT { $$ = 1; }
344 + | catlist numexpr %prec CONCAT { $$ = $1 + 1; }
346 -catlist: numexpr %prec CONCAT {
347 - $$ = 1;
349 - | catlist numexpr %prec CONCAT {
350 - $$ = $1 + 1;
352 expr: catlist {
353 if ($1 > 1) {
354 ADD_OP(OP_CONCAT); ADD_IMMED($1);
358 initarraylv: SYMBOL {
359 ADD_OP(OP_PUSH_ARRAY_SYM); ADD_SYM($1); ADD_IMMED(1);
361 - | initarraylv '[' arglist ']' {
362 + | initarraylv '[' arglistopt ']' {
363 ADD_OP(OP_ARRAY_REF); ADD_IMMED($3);
365 | initarraylv dot field {
366 ADD_OP(OP_ARRAY_REF); ADD_IMMED(1);
369 arraylv: SYMBOL {
370 ADD_OP(OP_PUSH_ARRAY_SYM); ADD_SYM($1); ADD_IMMED(0);
372 - | arraylv '[' arglist ']' {
373 + | arraylv '[' arglistopt ']' {
374 ADD_OP(OP_ARRAY_REF); ADD_IMMED($3);
376 | arraylv dot field {
377 ADD_OP(OP_ARRAY_REF); ADD_IMMED(1);
379 @@ -421,134 +332,86 @@ field: FIELD {
381 arrayexpr: numexpr {
382 $$ = GetPC();
385 -numexpr: NUMBER {
386 - ADD_OP(OP_PUSH_SYM); ADD_SYM($1);
388 - | STRING {
389 - ADD_OP(OP_PUSH_SYM); ADD_SYM($1);
391 - | SYMBOL {
392 - ADD_OP(OP_PUSH_SYM); ADD_SYM($1);
394 - | SYMBOL '(' arglist ')' {
395 +numexpr: '(' blank expr blank ')'
396 + | NUMBER { ADD_OP(OP_PUSH_SYM); ADD_SYM($1); }
397 + | STRING { ADD_OP(OP_PUSH_SYM); ADD_SYM($1); }
398 + | SYMBOL { ADD_OP(OP_PUSH_SYM); ADD_SYM($1); }
399 + | SYMBOL '(' arglistopt ')' {
400 ADD_OP(OP_SUBR_CALL);
401 ADD_SYM(PromoteToGlobal($1)); ADD_IMMED($3);
402 ADD_OP(OP_FETCH_RET_VAL);
404 - | '(' expr ')'
405 - | ARG_LOOKUP '[' numexpr ']' {
406 - ADD_OP(OP_PUSH_ARG);
408 - | ARG_LOOKUP '[' ']' {
409 - ADD_OP(OP_PUSH_ARG_COUNT);
411 - | ARG_LOOKUP {
412 - ADD_OP(OP_PUSH_ARG_ARRAY);
414 - | numexpr '[' arglist ']' {
415 + | ARG_LOOKUP '[' blank numexpr blank ']' { ADD_OP(OP_PUSH_ARG); }
416 + | ARG_LOOKUP '[' blank ']' { ADD_OP(OP_PUSH_ARG_COUNT); }
417 + | ARG_LOOKUP { ADD_OP(OP_PUSH_ARG_ARRAY); }
418 + | numexpr '[' arglistopt ']' {
419 ADD_OP(OP_ARRAY_REF); ADD_IMMED($3);
421 | numexpr dot field {
422 ADD_OP(OP_ARRAY_REF); ADD_IMMED(1);
424 - | numexpr '+' numexpr {
425 - ADD_OP(OP_ADD);
427 - | numexpr '-' numexpr {
428 - ADD_OP(OP_SUB);
430 - | numexpr '*' numexpr {
431 - ADD_OP(OP_MUL);
433 - | numexpr '/' numexpr {
434 - ADD_OP(OP_DIV);
436 - | numexpr '%' numexpr {
437 - ADD_OP(OP_MOD);
439 - | numexpr POW numexpr {
440 - ADD_OP(OP_POWER);
442 - | '-' numexpr %prec UNARY_MINUS {
443 - ADD_OP(OP_NEGATE);
445 - | numexpr GT numexpr {
446 - ADD_OP(OP_GT);
448 - | numexpr GE numexpr {
449 - ADD_OP(OP_GE);
451 - | numexpr LT numexpr {
452 - ADD_OP(OP_LT);
454 - | numexpr LE numexpr {
455 - ADD_OP(OP_LE);
457 - | numexpr EQ numexpr {
458 - ADD_OP(OP_EQ);
460 - | numexpr NE numexpr {
461 - ADD_OP(OP_NE);
463 - | numexpr '&' numexpr {
464 - ADD_OP(OP_BIT_AND);
466 - | numexpr '|' numexpr {
467 - ADD_OP(OP_BIT_OR);
469 - | numexpr and numexpr %prec AND {
470 + | '-' blank numexpr %prec UNARY_MINUS { ADD_OP(OP_NEGATE); }
471 + | NOT blank numexpr { ADD_OP(OP_NOT); }
472 + | numexpr '+' blank numexpr { ADD_OP(OP_ADD); }
473 + | numexpr '-' blank numexpr { ADD_OP(OP_SUB); }
474 + | numexpr '*' blank numexpr { ADD_OP(OP_MUL); }
475 + | numexpr '/' blank numexpr { ADD_OP(OP_DIV); }
476 + | numexpr '%' blank numexpr { ADD_OP(OP_MOD); }
477 + | numexpr POW blank numexpr { ADD_OP(OP_POWER); }
478 + | numexpr GT blank numexpr { ADD_OP(OP_GT); }
479 + | numexpr GE blank numexpr { ADD_OP(OP_GE); }
480 + | numexpr LT blank numexpr { ADD_OP(OP_LT); }
481 + | numexpr LE blank numexpr { ADD_OP(OP_LE); }
482 + | numexpr EQ blank numexpr { ADD_OP(OP_EQ); }
483 + | numexpr NE blank numexpr { ADD_OP(OP_NE); }
484 + | numexpr '&' blank numexpr { ADD_OP(OP_BIT_AND); }
485 + | numexpr '|' blank numexpr { ADD_OP(OP_BIT_OR); }
486 + | numexpr and blank numexpr %prec AND {
487 ADD_OP(OP_AND); SET_BR_OFF($2, GetPC());
489 - | numexpr or numexpr %prec OR {
490 + | numexpr or blank numexpr %prec OR {
491 ADD_OP(OP_OR); SET_BR_OFF($2, GetPC());
493 - | NOT numexpr {
494 - ADD_OP(OP_NOT);
496 - | INCR SYMBOL {
497 - ADD_OP(OP_PUSH_SYM); ADD_SYM($2); ADD_OP(OP_INCR);
498 - ADD_OP(OP_DUP); ADD_OP(OP_ASSIGN); ADD_SYM($2);
500 - | SYMBOL INCR {
501 - ADD_OP(OP_PUSH_SYM); ADD_SYM($1); ADD_OP(OP_DUP);
502 - ADD_OP(OP_INCR); ADD_OP(OP_ASSIGN); ADD_SYM($1);
504 - | DECR SYMBOL {
505 - ADD_OP(OP_PUSH_SYM); ADD_SYM($2); ADD_OP(OP_DECR);
506 - ADD_OP(OP_DUP); ADD_OP(OP_ASSIGN); ADD_SYM($2);
507 + | incrdecr blank SYMBOL %prec INCR {
508 + ADD_OP(OP_PUSH_SYM); ADD_SYM($3); ADD_OP($1);
509 + ADD_OP(OP_DUP); ADD_OP(OP_ASSIGN); ADD_SYM($3);
511 - | SYMBOL DECR {
512 + | SYMBOL incrdecr %prec INCR {
513 ADD_OP(OP_PUSH_SYM); ADD_SYM($1); ADD_OP(OP_DUP);
514 - ADD_OP(OP_DECR); ADD_OP(OP_ASSIGN); ADD_SYM($1);
515 + ADD_OP($2); ADD_OP(OP_ASSIGN); ADD_SYM($1);
517 - | numexpr IN numexpr {
518 + | numexpr IN blank numexpr {
519 ADD_OP(OP_IN_ARRAY);
521 - | numexpr NOT IN numexpr {
522 + | numexpr NOT IN blank numexpr %prec IN {
523 ADD_OP(OP_IN_ARRAY);
524 ADD_OP(OP_NOT);
527 -while: WHILE {
528 +while: WHILE blank {
529 + $$ = GetPC(); StartLoopAddrList();
532 +do: DO blank {
533 $$ = GetPC(); StartLoopAddrList();
536 -for: FOR {
537 +for: FOR blank {
538 StartLoopAddrList(); $$ = GetPC();
541 -else: ELSE {
542 +else: ELSE blank {
543 ADD_OP(OP_BRANCH); $$ = GetPC(); ADD_BR_OFF(0);
546 -cond: /* nothing */ {
547 +cond: blank {
548 ADD_OP(OP_BRANCH_NEVER); $$ = GetPC(); ADD_BR_OFF(0);
550 - | numexpr {
551 + | blank numexpr blank {
552 ADD_OP(OP_BRANCH_FALSE); $$ = GetPC(); ADD_BR_OFF(0);
555 and: AND {
556 ADD_OP(OP_DUP); ADD_OP(OP_BRANCH_FALSE); $$ = GetPC();
557 @@ -568,11 +431,10 @@ blank: /* nothing */
558 | blank '\n'
561 %% /* User Subroutines Section */
565 ** Parse a null terminated string and create a program from it (this is the
566 ** parser entry point). The program created by this routine can be
567 ** executed using ExecuteProgram. Returns program on success, or NULL
568 ** on failure. If the command failed, the error message is returned
569 @@ -610,42 +472,50 @@ Program *ParseMacro(char *expr, char **m
570 *msg = "";
571 *stoppedAt = InPtr;
572 return prog;
576 -static int yylex(void)
577 +static char skipWhitespace(void)
579 - int i, len;
580 - Symbol *s;
581 - static DataValue value = {NO_TAG, {0}};
582 - static char escape[] = "\\\"ntbrfave";
583 -#ifdef EBCDIC_CHARSET
584 - static char replace[] = "\\\"\n\t\b\r\f\a\v\x27"; /* EBCDIC escape */
585 -#else
586 - static char replace[] = "\\\"\n\t\b\r\f\a\v\x1B"; /* ASCII escape */
587 -#endif
589 /* skip whitespace, backslash-newline combinations, and comments, which are
590 all considered whitespace */
591 for (;;) {
592 if (*InPtr == '\\' && *(InPtr + 1) == '\n')
593 InPtr += 2;
594 else if (*InPtr == ' ' || *InPtr == '\t')
595 InPtr++;
596 - else if (*InPtr == '#')
597 + else if (*InPtr == '#') {
598 + InPtr++;
599 while (*InPtr != '\n' && *InPtr != '\0') {
600 /* Comments stop at escaped newlines */
601 if (*InPtr == '\\' && *(InPtr + 1) == '\n') {
602 InPtr += 2;
603 break;
605 InPtr++;
606 - } else
609 + else
610 break;
612 + return *InPtr;
615 +static int yylex(void)
617 + int len;
618 + Symbol *s;
619 + static DataValue value = {NO_TAG, {0}};
620 + static char escape[] = "\\\"ntbrfave";
621 +#ifdef EBCDIC_CHARSET
622 + static char replace[] = "\\\"\n\t\b\r\f\a\v\x27"; /* EBCDIC escape */
623 +#else
624 + static char replace[] = "\\\"\n\t\b\r\f\a\v\x1B"; /* ASCII escape */
625 +#endif
626 + int result;
628 + skipWhitespace();
630 /* return end of input at the end of the string */
631 if (*InPtr == '\0') {
632 return 0;
634 @@ -676,10 +546,11 @@ static int yylex(void)
635 else
636 *p++ = *InPtr++;
638 *p = '\0';
639 if (!strcmp(symName, "while")) return WHILE;
640 + if (!strcmp(symName, "do")) return DO;
641 if (!strcmp(symName, "if")) return IF;
642 if (!strcmp(symName, "else")) return ELSE;
643 if (!strcmp(symName, "for")) return FOR;
644 if (!strcmp(symName, "break")) return BREAK;
645 if (!strcmp(symName, "continue")) return CONTINUE;
646 @@ -817,11 +688,12 @@ static int yylex(void)
647 yylval.sym = InstallStringConstSymbol(string);
648 return STRING;
651 /* process remaining two character tokens or return single char as token */
652 - switch(*InPtr++) {
653 + result = *InPtr++;
654 + switch (result) {
655 case '>': return follow('=', GE, GT);
656 case '<': return follow('=', LE, LT);
657 case '=': return follow('=', EQ, '=');
658 case '!': return follow('=', NE, NOT);
659 case '+': return follow2('+', INCR, '=', ADDEQ, '+');
660 @@ -830,10 +702,18 @@ static int yylex(void)
661 case '&': return follow2('&', AND, '=', ANDEQ, '&');
662 case '*': return follow2('*', POW, '=', MULEQ, '*');
663 case '/': return follow('=', DIVEQ, '/');
664 case '%': return follow('=', MODEQ, '%');
665 case '^': return POW;
666 + case '\n':
667 + case '(':
668 + case '[': {
669 + /* skip newline ( whitespace* newline )* */
670 + while (skipWhitespace() == '\n')
671 + ++InPtr;
672 + return result; /* but return what we started with */
674 default: return *(InPtr-1);