]> thyrsus.com Git - cupl.git/commitdiff
Label patching really works now, and we can prove it.
authorEric S. Raymond <esr@thyrsus.com>
Thu, 3 Nov 1994 20:37:17 +0000 (20:37 +0000)
committerEric S. Raymond <esr@thyrsus.com>
Thu, 3 Nov 1994 20:37:17 +0000 (20:37 +0000)
cupl.h
cupl.y
interpret.c

diff --git a/cupl.h b/cupl.h
index 87e2a2c758ada7780771f756fba914b2085112d1..f8890011ffa7ec67f971c789b06de34e2b0b4f9a 100644 (file)
--- a/cupl.h
+++ b/cupl.h
@@ -51,6 +51,10 @@ typedef struct edon
 
     /* back-pointer to the symbol list, set if the node is an identifier */
     struct lvar_t      *syminf;    
+
+#ifdef PARSEDEBUG
+    int number;                /* statement number, if this is a STATEMENT node */
+#endif /* PARSEDEBUG */
 }
 node;
 
diff --git a/cupl.y b/cupl.y
index 80dabe7cd8ead0972dba4913bbf52e45da4b6249..1ff74b62972329cea5c789cf559b091c24cc957f 100644 (file)
--- a/cupl.y
+++ b/cupl.y
@@ -25,6 +25,10 @@ author first.
 #include <setjmp.h>
 
 #define        NULLNODE        (node *)NULL
+
+#ifdef PARSEDEBUG
+static int statement_count;
+#endif /* PARSEDEBUG */
 %}
 
 %start program
@@ -84,10 +88,22 @@ author first.
 /* a program description consists of a sequence of statements */
 program :    prog                      {interpret($1);}
 
-prog   :    command prog               {$$ = cons(STATEMENT, $1, $2);}
-       |    IDENTIFIER command prog    {$$ = cons(STATEMENT, 
-                                               cons(LABEL, $1, $2), $3);}
-       |    /* EMPTY */                {$$ = (node *)NULL;}
+prog   :    command prog
+               {
+                   $$ = cons(STATEMENT, $1, $2);
+#ifdef PARSEDEBUG
+                   $$->number = ++statement_count;
+#endif /* PARSEDEBUG */
+               }
+       |    IDENTIFIER command prog
+               {
+                   $$ = cons(STATEMENT, cons(LABEL, $1, $2), $3);
+#ifdef PARSEDEBUG
+                   $$->number = ++statement_count;
+#endif /* PARSEDEBUG */
+               }
+       |    /* EMPTY */
+               {$$ = (node *)NULL;}
        ;
 
 /* statement syntax */
index f6cf6c21476d041a8b345146df43a587d531455e..577d8639317094f1cf98f62eebe1d8ee035e1e5d 100644 (file)
@@ -63,9 +63,15 @@ static void prettyprint(node *tree, int indent)
        (void) printf("IDENTIFIER: %s\n", tree->u.string);
     else if (tree->type == STRING)
        (void) printf("STRING: '%s'\n", tree->u.string);
+    else if (tree->type == STATEMENT && indent > 0)
+       (void) printf("-> STATEMENT %d\n", tree->number);
     else
     {
-       (void) printf("%-20s", tokdump(tree->type));
+       if (tree->type == STATEMENT)
+           (void) printf("STATEMENT %2d       ", tree->number);
+       else
+           (void) printf("%-20s", tokdump(tree->type));
+
        if (verbose >= DEBUG_ALLOCATE)
            (void) printf("                          (%x -> %x, %x)",
                          tree,
@@ -248,16 +254,16 @@ static bool r_label_rewrite(node *tp)
        if (left && left->type == IDENTIFIER && left->syminf->labelref)
        {
 #ifdef ODEBUG
-           (void) printf("patching label reference to %s\n", left->u.string);
+           (void) printf("patching label left reference to %s\n", left->u.string);
 #endif /* ODEBUG */
-           left = left->syminf->target;
+           tp->u.n.left = left->syminf->target;
        }
        if (right && right->type == IDENTIFIER && right->syminf->labelref)
        {
 #ifdef ODEBUG
-           (void) printf("patching label reference to %s\n", right->u.string);
+           (void) printf("patching label right reference to %s\n", right->u.string);
 #endif /* ODEBUG */
-           right = right->syminf->target;
+           tp->u.n.right = right->syminf->target;
        }
     }
 
@@ -305,15 +311,31 @@ static void rewrite(node *tree)
 void interpret(node *tree)
 /* interpret a program parse tree */
 {
+    if (check_errors(tree))
+       return;
+    rewrite(tree);
+
 #ifdef PARSEDEBUG
+    /* statement conses are made in reverse order; deal with this */
+    {
+       node    *np;
+       int statement_count = 0;
+
+       for_cdr(np, tree)
+       {
+           if (np->type == STATEMENT)
+               ++statement_count;
+       }
+
+       for_cdr(np, tree)
+           if (np->type == STATEMENT)
+               np->number = statement_count - np->number + 1;
+    }
+
     if (verbose >= DEBUG_PARSEDUMP)
        prettyprint(tree, 0);
 #endif /* PARSEDEBUG */
 
-    if (check_errors(tree))
-       return;
-    rewrite(tree);
-
     execute(tree);
 }