From 0f16867d53aa0cf68ebac5aae110f6e5c34b05aa Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Thu, 3 Nov 1994 20:37:17 +0000 Subject: [PATCH] Label patching really works now, and we can prove it. --- cupl.h | 4 ++++ cupl.y | 24 ++++++++++++++++++++---- interpret.c | 40 +++++++++++++++++++++++++++++++--------- 3 files changed, 55 insertions(+), 13 deletions(-) diff --git a/cupl.h b/cupl.h index 87e2a2c..f889001 100644 --- 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 80dabe7..1ff74b6 100644 --- a/cupl.y +++ b/cupl.y @@ -25,6 +25,10 @@ author first. #include #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 */ diff --git a/interpret.c b/interpret.c index f6cf6c2..577d863 100644 --- a/interpret.c +++ b/interpret.c @@ -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); } -- 2.43.0