]> thyrsus.com Git - cupl.git/commitdiff
Arrange for reference counts.
authorEric S. Raymond <esr@thyrsus.com>
Thu, 3 Nov 1994 00:43:12 +0000 (00:43 +0000)
committerEric S. Raymond <esr@thyrsus.com>
Thu, 3 Nov 1994 00:43:12 +0000 (00:43 +0000)
cupl.h
cupl.l
interpret.c

diff --git a/cupl.h b/cupl.h
index 84a7dd6311ce0dc5365a3f9fc53330006433b890..f80b08dd193fb3274065a61e2e9d5f2396feeff0 100644 (file)
--- 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 fb106451c812d425bcf91f9e593796d9fa56c3f1..1ef53f0a49e7b362bbf05bc80818072d89c0e8ea 100644 (file)
--- 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;
index 98f58c2784af6bf542921521991fbcaf32bbb440..7185f9cf03cf984f6e563b86449d85c84574f83a 100644 (file)
@@ -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)