From f3755dbe994f3873a13db0510348acd39e6c9f3a Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Thu, 3 Nov 1994 14:58:27 +0000 Subject: [PATCH] Label resolution doesn't go crazy. --- cupl.h | 3 +++ interpret.c | 62 ++++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 50 insertions(+), 15 deletions(-) diff --git a/cupl.h b/cupl.h index ae39c01..2faeeb5 100644 --- a/cupl.h +++ b/cupl.h @@ -54,6 +54,8 @@ typedef struct edon } node; +#define for_cdr(np, tree) for (np = tree; np; np = tree->u.n.right) + /* this structure represents a CUPL value */ typedef struct { @@ -70,6 +72,7 @@ typedef struct lvar_t struct lvar_t *next; /* link to next variable */ node *node; /* variable's symbol info */ value value; /* variable's value */ + node *target; /* target node, if label */ /* information used for consistency checks */ int labeldef; diff --git a/interpret.c b/interpret.c index 362f55b..0cc92dc 100644 --- a/interpret.c +++ b/interpret.c @@ -104,6 +104,21 @@ static void die(char *msg, ...) exit(1); } +static bool recursive_apply(node *tree, bool (*fun)(node *)) +/* apply fun recursively to tree, short-circuiting on FALSE return */ +{ + if (tree == (node *)NULL) + return(TRUE); + + if (ATOMIC(tree->type)) + return(fun(tree)); + else if (recursive_apply(tree->u.n.left, fun) && recursive_apply(tree->u.n.right, fun)) + return(fun(tree)); + else + return(FALSE); + +} + static bool r_mark_labels(node *tp) /* record label references */ { @@ -155,21 +170,6 @@ static bool r_mark_labels(node *tp) return(TRUE); } -static bool recursive_apply(node *tree, bool (*fun)(node *)) -/* apply fun recursively to tree, short-circuiting on FALSE return */ -{ - if (tree == (node *)NULL) - return(TRUE); - - if (ATOMIC(tree->type)) - return(fun(tree)); - else if (recursive_apply(tree->u.n.left, fun) && recursive_apply(tree->u.n.right, fun)) - return(fun(tree)); - else - return(FALSE); - -} - static bool check_errors(node *tree) /* look for inconsistencies in a program parse tree */ { @@ -231,6 +231,37 @@ static bool check_errors(node *tree) } } +static bool r_label_rewrite(node *tp) +/* resolve label references */ +{ + /* + * KISS -- this code may do extra work, but it needs no special + * knowledge about node types. + */ + node *left = tp->u.n.left; + node *right = tp->u.n.right; + + if (left && left->type == IDENTIFIER && left->syminf->labelref) + left = left->syminf->target; + + if (right && right->type == IDENTIFIER && right->syminf->labelref) + right = right->syminf->target; +} + +static void rewrite(node *tree) +/* resolve labels */ +{ + node *np; + + /* first, make a pointer from each label to its destination statement */ + for_cdr(np, tree) + if (np->u.n.left->type == LABEL) + np->u.n.left->syminf->target = np; + + /* now, hack label references to eliminate name references */ + recursive_apply(tree, r_label_rewrite); +} + void interpret(node *tree) /* interpret a program parse tree */ { @@ -241,6 +272,7 @@ void interpret(node *tree) if (check_errors(tree)) return; + rewrite(tree); execute(tree); } -- 2.43.0