From 1bed83a207380a597325a4ceeb28d503e866078c Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Thu, 3 Nov 1994 00:43:12 +0000 Subject: [PATCH] Arrange for reference counts. --- cupl.h | 9 +++++--- cupl.l | 2 +- interpret.c | 60 +++++++++++++++++++++++++++++++++++++++++++---------- 3 files changed, 56 insertions(+), 15 deletions(-) diff --git a/cupl.h b/cupl.h index 84a7dd6..f80b08d 100644 --- a/cupl.h +++ b/cupl.h @@ -58,10 +58,13 @@ node; typedef struct lvar_t { struct lvar_t *next; - int refcount; - int setcount; - bool islabel; node *node; + + /* information used for consistency checks */ + int labeldef; + int labelref; + int assigned; + int used; } lvar; extern lvar *idlist; diff --git a/cupl.l b/cupl.l index fb10645..1ef53f0 100644 --- a/cupl.l +++ b/cupl.l @@ -113,7 +113,7 @@ static node *intern_identifier(char *str) new->u.string = strdup(str); /* link it into the recognition list */ - n = (lvar *)malloc(sizeof(lvar)); + n = (lvar *)calloc(sizeof(lvar), 1); n->next = idlist; n->node = new; idlist = n; diff --git a/interpret.c b/interpret.c index 98f58c2..7185f9c 100644 --- a/interpret.c +++ b/interpret.c @@ -3,6 +3,8 @@ #include "cupl.h" #include "tokens.h" +#define ATOMIC(n) ((n) == IDENTIFIER || (n) == NUMBER || (n) == STRING) + /* this structure represents a CUPL value */ typedef struct { @@ -76,39 +78,75 @@ static void die(char *msg, ...) exit(1); } +static bool r_mark_labels(node *tree) +/* record label references */ +{ + /* mark label definitions */ + if (tree->type == STATEMENT && tree->u.n.left->type == LABEL) + tree->u.n.left->u.n.left->syminf->labeldef++; + + /* mark label references */ + if (tree->type == GO || tree->type == OG || tree->type == PERFORM) + tree->u.n.left->syminf->labelref++; + + return(TRUE); +} + +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 */ { node *n; lvar *lp; - int nlabels = 0; - /* make backpointers */ - for (lp = idlist; lp; lp = lp->next) - lp->node->syminf = lp; +#define for_symbols(s) for (s = idlist; s; s = s->next) - /* mark labels */ + /* simple sanity check */ for (n = tree; n; n = n->u.n.right) if (n->type != STATEMENT) die("internal error: non-STATEMENT at top level"); - else if (n->u.n.left->type == LABEL) - { - n->u.n.left->u.n.left->syminf->islabel = TRUE; - nlabels++; - } + + /* make backpointers */ + for_symbols(lp) + lp->node->syminf = lp; + + /* mark labels */ + recursive_apply(tree, r_mark_labels); /* report on the number of labels */ if (verbose >= DEBUG_CHECKDUMP) + { + int nlabels = 0; + + for (lp = idlist; lp; lp = lp->next) + if (lp->labeldef) + nlabels++; + if (nlabels == 0) (void) printf("No labels.\n"); else { (void) printf("Labels:"); for (lp = idlist; lp; lp = lp->next) - if (lp->islabel) + if (lp->labeldef) (void) printf(" %s", lp->node->u.string); (void) printf("\n"); } + } } void interpret(node *tree) -- 2.43.0