    Enhancements to NEdit macro parsing

    Available as a patch:

    http://sourceforge.net/tracker/index.php?func=detail&aid=1249914&group_id=11005&atid=311005
	    [ 1249914 ] Enhancements to NEdit macro parsing
	    parseEnhance2.diff	 2005-08-03 18:51

    This patch adds the following features to NEdit's macro language:
    - the conditional expression
	        <B>(</B> key <B>! in</B> array <B>)</B>
      acts as the logical opposite of
	        <B>(</B> key <B>in</B> array <B>)</B>
    - the do ... while loop has been lifted from C, as
	        <B>do</B> <I>block-or-statement</I> <B>while (</B> condition <B>)</B>
    - N8 Gray's "optional semicolons for statement termination" (SF patch
      1185506) has been included
    - added a few productions to group assignment increment/decrement
      operators
    - allowed for linebreaks in places where their statement-terminating
      behaviour makes no sense, ie in argument lists, after prefix or binary
      operators, after keywords <B>if</B>, <B>while</B>, <B>for</B> and
      <B>do</B> (They are also allowed in the comma-separated simple-statements
      in the <B>for</B> loop's initialisation and iteration phrases) and after
      opening parentheses; you only need "\" in a few cases now, in particular
      when concatenating strings on different lines
    - general reformatting of the parse.y file to "condense" the smaller
      code blocks (this undoes some of Steve LoBasso's reformatting from
      some time ago) - I think this enhances the grammar productions over
      the injected code

diff -ur nedit_official nedit_mod
diff -ur nedit_official/source/parse.y nedit_mod/source/parse.y
--- nedit_official/source/parse.y	2007-01-12 17:17:42.000000000 +0100
+++ nedit_mod/source/parse.y	2007-01-15 17:43:21.656250000 +0100
@@ -58,17 +58,22 @@
     Symbol *sym;
     Inst *inst;
     int nArgs;
+    enum operations oper;
 }
 %token <sym> NUMBER STRING SYMBOL
 %token DELETE ARG_LOOKUP
-%token IF WHILE ELSE FOR BREAK CONTINUE RETURN
-%type <nArgs> arglist
-%type <inst> cond comastmts for while else and or arrayexpr
+%token IF WHILE DO ELSE FOR BREAK CONTINUE RETURN
+%type <nArgs> arglistopt arglist
+%type <inst> cond comastmts comastmtlst for while do else and or arrayexpr mark
 %type <sym> evalsym
+%type <oper> operassign incrdecr
+%token <oper> '=' ADDEQ SUBEQ MULEQ DIVEQ MODEQ ANDEQ OREQ
+%token <oper> INCR DECR
 
 %nonassoc IF_NO_ELSE
 %nonassoc ELSE
 
+%nonassoc ';'
 %nonassoc SYMBOL ARG_LOOKUP
 %right    '=' ADDEQ SUBEQ MULEQ DIVEQ MODEQ ANDEQ OREQ
 %left     CONCAT
@@ -108,197 +113,150 @@
 stmts:      stmt
             | stmts stmt
             ;
-stmt:       simpstmt '\n' blank
-            | IF '(' cond ')' blank block %prec IF_NO_ELSE {
-                SET_BR_OFF($3, GetPC());
+stmtend:    '\n' | ';'
+            ;
+mark:       /* nothing */ { $$ = GetPC(); } /* record instruction address */
+            ;
+stmt:       ';' blank
+            | simpstmt stmtend blank
+            | IF blank '(' cond ')' blank block %prec IF_NO_ELSE {
+                SET_BR_OFF($4, GetPC());
             }
-            | IF '(' cond ')' blank block else blank block %prec ELSE {
-                SET_BR_OFF($3, ($7+1)); SET_BR_OFF($7, GetPC());
+            | IF blank '(' cond ')' blank block else block %prec ELSE {
+                SET_BR_OFF($4, ($8+1)); SET_BR_OFF($8, GetPC());
             }
             | while '(' cond ')' blank block {
                 ADD_OP(OP_BRANCH); ADD_BR_OFF($1);
                 SET_BR_OFF($3, GetPC()); FillLoopAddrs(GetPC(), $1);
             }
+            | do block WHILE blank '(' mark cond ')' stmtend blank {
+                ADD_OP(OP_BRANCH); ADD_BR_OFF($1);
+                SET_BR_OFF($7, GetPC()); FillLoopAddrs(GetPC(), $6);
+            }
             | for '(' comastmts ';' cond ';' comastmts ')' blank block {
                 FillLoopAddrs(GetPC()+2+($7-($5+1)), GetPC());
                 SwapCode($5+1, $7, GetPC());
                 ADD_OP(OP_BRANCH); ADD_BR_OFF($3); SET_BR_OFF($5, GetPC());
             }
-            | for '(' SYMBOL IN arrayexpr ')' {
+            | for '(' blank SYMBOL IN blank arrayexpr blank ')' {
                 Symbol *iterSym = InstallIteratorSymbol();
                 ADD_OP(OP_BEGIN_ARRAY_ITER); ADD_SYM(iterSym);
-                ADD_OP(OP_ARRAY_ITER); ADD_SYM($3); ADD_SYM(iterSym); ADD_BR_OFF(0);
+                ADD_OP(OP_ARRAY_ITER); ADD_SYM($4); ADD_SYM(iterSym); ADD_BR_OFF(0);
             }
                 blank block {
-                    ADD_OP(OP_BRANCH); ADD_BR_OFF($5+2);
-                    SET_BR_OFF($5+5, GetPC());
-                    FillLoopAddrs(GetPC(), $5+2);
+                    ADD_OP(OP_BRANCH); ADD_BR_OFF($7+2);
+                    SET_BR_OFF($7+5, GetPC());
+                    FillLoopAddrs(GetPC(), $7+2);
             }
-            | BREAK '\n' blank {
+            | BREAK stmtend blank {
                 ADD_OP(OP_BRANCH); ADD_BR_OFF(0);
                 if (AddBreakAddr(GetPC()-1)) {
                     yyerror("break outside loop"); YYERROR;
                 }
             }
-            | CONTINUE '\n' blank {
+            | CONTINUE stmtend blank {
                 ADD_OP(OP_BRANCH); ADD_BR_OFF(0);
                 if (AddContinueAddr(GetPC()-1)) {
                     yyerror("continue outside loop"); YYERROR;
                 }
             }
-            | RETURN expr '\n' blank {
+            | RETURN expr stmtend blank {
                 ADD_OP(OP_RETURN);
             }
-            | RETURN '\n' blank {
+            | RETURN stmtend blank {
                 ADD_OP(OP_RETURN_NO_VAL);
             }
             ;
-simpstmt:   SYMBOL '=' expr {
+
+operassign:   ADDEQ { $$ = OP_ADD; }
+            | SUBEQ { $$ = OP_SUB; }
+            | MULEQ { $$ = OP_MUL; }
+            | DIVEQ { $$ = OP_DIV; }
+            | MODEQ { $$ = OP_MOD; }
+            | ANDEQ { $$ = OP_BIT_AND; }
+            | OREQ  { $$ = OP_BIT_OR; }
+            ;
+incrdecr:     INCR { $$ = OP_INCR; }
+            | DECR { $$ = OP_DECR; }
+            ;
+
+simpstmt:   /* simple variable assignment, op-assignment, incr/decrement */
+            SYMBOL '=' blank expr {
                 ADD_OP(OP_ASSIGN); ADD_SYM($1);
             }
-            | evalsym ADDEQ expr {
-                ADD_OP(OP_ADD); ADD_OP(OP_ASSIGN); ADD_SYM($1);
-            }
-            | evalsym SUBEQ expr {
-                ADD_OP(OP_SUB); ADD_OP(OP_ASSIGN); ADD_SYM($1);
-            }
-            | evalsym MULEQ expr {
-                ADD_OP(OP_MUL); ADD_OP(OP_ASSIGN); ADD_SYM($1);
-            }
-            | evalsym DIVEQ expr {
-                ADD_OP(OP_DIV); ADD_OP(OP_ASSIGN); ADD_SYM($1);
+            | evalsym operassign blank expr {
+                ADD_OP($2); ADD_OP(OP_ASSIGN); ADD_SYM($1);
             }
-            | evalsym MODEQ expr {
-                ADD_OP(OP_MOD); ADD_OP(OP_ASSIGN); ADD_SYM($1);
+            | incrdecr blank SYMBOL {
+                ADD_OP(OP_PUSH_SYM); ADD_SYM($3); ADD_OP($1);
+                ADD_OP(OP_ASSIGN); ADD_SYM($3);
             }
-            | evalsym ANDEQ expr {
-                ADD_OP(OP_BIT_AND); ADD_OP(OP_ASSIGN); ADD_SYM($1);
-            }
-            | evalsym OREQ expr {
-                ADD_OP(OP_BIT_OR); ADD_OP(OP_ASSIGN); ADD_SYM($1);
+            | SYMBOL incrdecr {
+                ADD_OP(OP_PUSH_SYM); ADD_SYM($1); ADD_OP($2);
+                ADD_OP(OP_ASSIGN); ADD_SYM($1);
             }
-            | DELETE arraylv '[' arglist ']' {
+            /* delete array entry simple statement */
+            | DELETE arraylv '[' arglistopt ']' {
                 ADD_OP(OP_ARRAY_DELETE); ADD_IMMED($4);
             }
-            | initarraylv '[' arglist ']' '=' expr {
-                ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED($3);
-            }
-            | initarraylv '[' arglist ']' ADDEQ expr {
-                ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED(1); ADD_IMMED($3);
-                ADD_OP(OP_ADD);
-                ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED($3);
-            }
-            | initarraylv '[' arglist ']' SUBEQ expr {
-                ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED(1); ADD_IMMED($3);
-                ADD_OP(OP_SUB);
-                ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED($3);
-            }
-            | initarraylv '[' arglist ']' MULEQ expr {
-                ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED(1); ADD_IMMED($3);
-                ADD_OP(OP_MUL);
+            /* array entry assignment, op-assignment, incr/decrement */
+            | initarraylv '[' arglistopt ']' '=' expr {
                 ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED($3);
             }
-            | initarraylv '[' arglist ']' DIVEQ expr {
+            | initarraylv '[' arglistopt ']' operassign blank expr {
                 ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED(1); ADD_IMMED($3);
-                ADD_OP(OP_DIV);
+                ADD_OP($5);
                 ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED($3);
             }
-            | initarraylv '[' arglist ']' MODEQ expr {
-                ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED(1); ADD_IMMED($3);
-                ADD_OP(OP_MOD);
-                ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED($3);
-            }
-            | initarraylv '[' arglist ']' ANDEQ expr {
-                ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED(1); ADD_IMMED($3);
-                ADD_OP(OP_BIT_AND);
-                ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED($3);
-            }
-            | initarraylv '[' arglist ']' OREQ expr {
-                ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED(1); ADD_IMMED($3);
-                ADD_OP(OP_BIT_OR);
-                ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED($3);
-            }
-            | initarraylv '[' arglist ']' INCR {
+            | initarraylv '[' arglistopt ']' incrdecr {
                 ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED(0); ADD_IMMED($3);
-                ADD_OP(OP_INCR);
+                ADD_OP($5);
                 ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED($3);
             }
-            | initarraylv '[' arglist ']' DECR {
-                ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED(0); ADD_IMMED($3);
-                ADD_OP(OP_DECR);
-                ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED($3);
+            | incrdecr blank initarraylv '[' arglistopt ']' {
+                ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED(0); ADD_IMMED($5);
+                ADD_OP($1);
+                ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED($5);
             }
-            | INCR initarraylv '[' arglist ']' {
-                ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED(0); ADD_IMMED($4);
-                ADD_OP(OP_INCR);
-                ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED($4);
-            }
-            | DECR initarraylv '[' arglist ']' {
-                ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED(0); ADD_IMMED($4);
-                ADD_OP(OP_DECR);
-                ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED($4);
-            }
-            | SYMBOL '(' arglist ')' {
+            /* function call */
+            | SYMBOL '(' arglistopt ')' {
                 ADD_OP(OP_SUBR_CALL);
                 ADD_SYM(PromoteToGlobal($1)); ADD_IMMED($3);
             }
-            | INCR SYMBOL {
-                ADD_OP(OP_PUSH_SYM); ADD_SYM($2); ADD_OP(OP_INCR);
-                ADD_OP(OP_ASSIGN); ADD_SYM($2);
-            }
-            | SYMBOL INCR {
-                ADD_OP(OP_PUSH_SYM); ADD_SYM($1); ADD_OP(OP_INCR);
-                ADD_OP(OP_ASSIGN); ADD_SYM($1);
-            }
-            | DECR SYMBOL {
-                ADD_OP(OP_PUSH_SYM); ADD_SYM($2); ADD_OP(OP_DECR);
-                ADD_OP(OP_ASSIGN); ADD_SYM($2);
-            }
-            | SYMBOL DECR {
-                ADD_OP(OP_PUSH_SYM); ADD_SYM($1); ADD_OP(OP_DECR);
-                ADD_OP(OP_ASSIGN); ADD_SYM($1);
-            }
             ;
+
 evalsym:    SYMBOL {
                 $$ = $1; ADD_OP(OP_PUSH_SYM); ADD_SYM($1);
             }
             ;
-comastmts:  /* nothing */ {
-                $$ = GetPC();
-            }
-            | simpstmt {
-                $$ = GetPC();
-            }
-            | comastmts ',' simpstmt {
-                $$ = GetPC();
-            }
+comastmts:    blank             { $$ = GetPC(); }
+            | blank comastmtlst { $$ = $2; }
             ;
-arglist:    /* nothing */ {
-                $$ = 0;
-            }
-            | expr {
-                $$ = 1;
-            }
-            | arglist ',' expr {
-                $$ = $1 + 1;
-            }
+comastmtlst:                        simpstmt blank { $$ = GetPC(); }
+            | comastmtlst ',' blank simpstmt blank { $$ = GetPC(); }
+            ;
+
+arglistopt:   blank   { $$ = 0; }
+            | arglist { $$ = $1; }
             ;
+arglist:                  blank expr blank { $$ = 1; }
+            | arglist ',' blank expr blank { $$ = $1 + 1; }
+            ;
+
 expr:       numexpr %prec CONCAT
-            | expr numexpr %prec CONCAT {
-                ADD_OP(OP_CONCAT);
-            }
+            | expr numexpr %prec CONCAT { ADD_OP(OP_CONCAT); }
             ;
 initarraylv:    SYMBOL {
                     ADD_OP(OP_PUSH_ARRAY_SYM); ADD_SYM($1); ADD_IMMED(1);
                 }
-                | initarraylv '[' arglist ']' {
+                | initarraylv '[' arglistopt ']' {
                     ADD_OP(OP_ARRAY_REF); ADD_IMMED($3);
                 }
                 ;
 arraylv:    SYMBOL {
                 ADD_OP(OP_PUSH_ARRAY_SYM); ADD_SYM($1); ADD_IMMED(0);
             }
-            | arraylv '[' arglist ']' {
+            | arraylv '[' arglistopt ']' {
                 ADD_OP(OP_ARRAY_REF); ADD_IMMED($3);
             }
             ;
@@ -306,123 +264,79 @@
                 $$ = GetPC();
             }
             ;
-numexpr:    NUMBER {
-                ADD_OP(OP_PUSH_SYM); ADD_SYM($1);
-            }
-            | STRING {
-                ADD_OP(OP_PUSH_SYM); ADD_SYM($1);
-            }
-            | SYMBOL {
-                ADD_OP(OP_PUSH_SYM); ADD_SYM($1);
-            }
-            | SYMBOL '(' arglist ')' {
+numexpr:      '(' blank expr blank ')'
+            | NUMBER { ADD_OP(OP_PUSH_SYM); ADD_SYM($1); }
+            | STRING { ADD_OP(OP_PUSH_SYM); ADD_SYM($1); }
+            | SYMBOL { ADD_OP(OP_PUSH_SYM); ADD_SYM($1); }
+            | SYMBOL '(' arglistopt ')' {
                 ADD_OP(OP_SUBR_CALL);
                 ADD_SYM(PromoteToGlobal($1)); ADD_IMMED($3);
                 ADD_OP(OP_FETCH_RET_VAL);
             }
-            | '(' expr ')'
-            | ARG_LOOKUP '[' numexpr ']' {
-               ADD_OP(OP_PUSH_ARG);
-            }
-            | ARG_LOOKUP '[' ']' {
-               ADD_OP(OP_PUSH_ARG_COUNT);
-            }
-            | ARG_LOOKUP {
-               ADD_OP(OP_PUSH_ARG_ARRAY);
-            }
-            | numexpr '[' arglist ']' {
+            | ARG_LOOKUP '[' blank numexpr blank ']' { ADD_OP(OP_PUSH_ARG); }
+            | ARG_LOOKUP '[' blank ']'          { ADD_OP(OP_PUSH_ARG_COUNT); }
+            | ARG_LOOKUP                        { ADD_OP(OP_PUSH_ARG_ARRAY); }
+            | numexpr '[' arglistopt ']' {
                 ADD_OP(OP_ARRAY_REF); ADD_IMMED($3);
             }
-            | numexpr '+' numexpr {
-                ADD_OP(OP_ADD);
-            }
-            | numexpr '-' numexpr {
-                ADD_OP(OP_SUB);
-            }
-            | numexpr '*' numexpr {
-                ADD_OP(OP_MUL);
-            }
-            | numexpr '/' numexpr {
-                ADD_OP(OP_DIV);
-            }
-            | numexpr '%' numexpr {
-                ADD_OP(OP_MOD);
-            }
-            | numexpr POW numexpr {
-                ADD_OP(OP_POWER);
-            }
-            | '-' numexpr %prec UNARY_MINUS  {
-                ADD_OP(OP_NEGATE);
-            }
-            | numexpr GT numexpr  {
-                ADD_OP(OP_GT);
-            }
-            | numexpr GE numexpr  {
-                ADD_OP(OP_GE);
-            }
-            | numexpr LT numexpr  {
-                ADD_OP(OP_LT);
-            }
-            | numexpr LE numexpr  {
-                ADD_OP(OP_LE);
-            }
-            | numexpr EQ numexpr  {
-                ADD_OP(OP_EQ);
-            }
-            | numexpr NE numexpr  {
-                ADD_OP(OP_NE);
-            }
-            | numexpr '&' numexpr {
-                ADD_OP(OP_BIT_AND);
-            }
-            | numexpr '|' numexpr  {
-                ADD_OP(OP_BIT_OR);
-            }
-            | numexpr and numexpr %prec AND {
+            | '-' blank numexpr %prec UNARY_MINUS { ADD_OP(OP_NEGATE); }
+            | NOT blank numexpr                   { ADD_OP(OP_NOT); }
+            | numexpr '+' blank numexpr           { ADD_OP(OP_ADD); }
+            | numexpr '-' blank numexpr           { ADD_OP(OP_SUB); }
+            | numexpr '*' blank numexpr           { ADD_OP(OP_MUL); }
+            | numexpr '/' blank numexpr           { ADD_OP(OP_DIV); }
+            | numexpr '%' blank numexpr           { ADD_OP(OP_MOD); }
+            | numexpr POW blank numexpr           { ADD_OP(OP_POWER); }
+            | numexpr GT  blank numexpr           { ADD_OP(OP_GT); }
+            | numexpr GE  blank numexpr           { ADD_OP(OP_GE); }
+            | numexpr LT  blank numexpr           { ADD_OP(OP_LT); }
+            | numexpr LE  blank numexpr           { ADD_OP(OP_LE); }
+            | numexpr EQ  blank numexpr           { ADD_OP(OP_EQ); }
+            | numexpr NE  blank numexpr           { ADD_OP(OP_NE); }
+            | numexpr '&' blank numexpr           { ADD_OP(OP_BIT_AND); }
+            | numexpr '|' blank numexpr           { ADD_OP(OP_BIT_OR); }
+            | numexpr and blank numexpr %prec AND {
                 ADD_OP(OP_AND); SET_BR_OFF($2, GetPC());
             }
-            | numexpr or numexpr %prec OR {
+            | numexpr or blank numexpr %prec OR {
                 ADD_OP(OP_OR); SET_BR_OFF($2, GetPC());
             }
-            | NOT numexpr {
-                ADD_OP(OP_NOT);
-            }
-            | INCR SYMBOL {
-                ADD_OP(OP_PUSH_SYM); ADD_SYM($2); ADD_OP(OP_INCR);
-                ADD_OP(OP_DUP); ADD_OP(OP_ASSIGN); ADD_SYM($2);
+            | incrdecr blank SYMBOL %prec INCR {
+                ADD_OP(OP_PUSH_SYM); ADD_SYM($3); ADD_OP($1);
+                ADD_OP(OP_DUP); ADD_OP(OP_ASSIGN); ADD_SYM($3);
             }
-            | SYMBOL INCR {
+            | SYMBOL incrdecr %prec INCR {
                 ADD_OP(OP_PUSH_SYM); ADD_SYM($1); ADD_OP(OP_DUP);
-                ADD_OP(OP_INCR); ADD_OP(OP_ASSIGN); ADD_SYM($1);
+                ADD_OP($2); ADD_OP(OP_ASSIGN); ADD_SYM($1);
             }
-            | DECR SYMBOL {
-                ADD_OP(OP_PUSH_SYM); ADD_SYM($2); ADD_OP(OP_DECR);
-                ADD_OP(OP_DUP); ADD_OP(OP_ASSIGN); ADD_SYM($2);
-            }
-            | SYMBOL DECR {
-                ADD_OP(OP_PUSH_SYM); ADD_SYM($1); ADD_OP(OP_DUP);
-                ADD_OP(OP_DECR); ADD_OP(OP_ASSIGN); ADD_SYM($1);
+            | numexpr IN blank numexpr {
+                ADD_OP(OP_IN_ARRAY);
             }
-            | numexpr IN numexpr {
+            | numexpr NOT IN blank numexpr %prec IN {
                 ADD_OP(OP_IN_ARRAY);
+                ADD_OP(OP_NOT);
             }
             ;
-while:  WHILE {
+while:  WHILE blank {
+            $$ = GetPC(); StartLoopAddrList();
+        }
+        ;
+do:     DO blank {
             $$ = GetPC(); StartLoopAddrList();
         }
         ;
-for:    FOR {
+for:    FOR blank {
             StartLoopAddrList(); $$ = GetPC();
         }
         ;
-else:   ELSE {
+else:   ELSE blank {
             ADD_OP(OP_BRANCH); $$ = GetPC(); ADD_BR_OFF(0);
         }
         ;
-cond:   /* nothing */ {
+cond:   blank {
             ADD_OP(OP_BRANCH_NEVER); $$ = GetPC(); ADD_BR_OFF(0);
         }
-        | numexpr {
+        | blank numexpr blank {
             ADD_OP(OP_BRANCH_FALSE); $$ = GetPC(); ADD_BR_OFF(0);
         }
         ;
@@ -543,6 +457,7 @@
             }
             *p = '\0';
             if (!strcmp(symName, "while")) return WHILE;
+            if (!strcmp(symName, "do")) return DO;
             if (!strcmp(symName, "if")) return IF;
             if (!strcmp(symName, "else")) return ELSE;
             if (!strcmp(symName, "for")) return FOR;
