]> thyrsus.com Git - cupl.git/commitdiff
Recursion seems to work OK.
authorEric S. Raymond <esr@thyrsus.com>
Fri, 4 Nov 1994 17:31:13 +0000 (17:31 +0000)
committerEric S. Raymond <esr@thyrsus.com>
Fri, 4 Nov 1994 17:31:13 +0000 (17:31 +0000)
Makefile
cupl.h
execute.c

index 29f5a8dc16c45cdb978a9a7b7b19663d9511c184..559c1a95ea55bded03faf71c7c3565f66b0bbbaa 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -10,7 +10,7 @@ SOURCES = cupl.[ylh] tokdump.c main.c interpret.c execute.c monitor.c nodetype.h
 
 MODULES = main.o grammar.o lexer.o interpret.o tokdump.o execute.o monitor.o
 cupl: $(MODULES)
-       $(CC) $(MODULES) -o cupl
+       $(CC) $(MODULES) -lm -o cupl
 
 lexer.c: cupl.l
        lex $(LFLAGS) cupl.l
diff --git a/cupl.h b/cupl.h
index 22a352d80b8c237aaca23e4424f449530d394e00..ce67466ca2bd7e62e7df35076110e815bfa32826 100644 (file)
--- a/cupl.h
+++ b/cupl.h
@@ -67,6 +67,7 @@ typedef struct
     int                rank;                   /* 0, 1, or 2 */
     int                width, depth;           /* dimensions */
     scalar     *elements;              /* elements */
+    int                refcount;               /* how many copies are there? */
 }
 value;
 
@@ -106,6 +107,16 @@ extern void execute(node *tree);
 /* monitor.c */
 extern void die(char *msg, ...);
 extern void warn(char *msg, ...);
+extern void make_scalar(value *v, scalar n);
+extern value copy_value(value);
+extern void deallocate_value(value *);
+extern value cupl_add(value, value);
+extern value cupl_multiply(value, value);
+extern value cupl_subtract(value, value);
+extern value cupl_divide(value, value);
+extern value cupl_power(value, value);
+extern value cupl_uminus(value);
+extern value cupl_sqrt(value);
 
 #define DEBUG_PARSEDUMP        1
 #define DEBUG_CHECKDUMP        2
index 4e8f29b1f29017afe41a9d2387354ea6189cd037..dbd4f80f467be714289519a082baebc4220b2fd1 100644 (file)
--- a/execute.c
+++ b/execute.c
@@ -19,6 +19,7 @@ handed off to execute().
 
 #define car    u.n.left
 #define cdr    u.n.right
+#define EVAL_WRAP
 
 static node *pc;       /* the statement node to evaluate next */
 static node *data;     /* pointer to *DATA item to be grabbed next */
@@ -114,20 +115,15 @@ static void cupl_write(node *tp)
     }
 }
 
-static void make_scalar(value *v, scalar i)
-/* initialize a scalar value element */
-{
-    v->width = v->depth = 1;
-    v->elements = (scalar *)malloc(sizeof(scalar));
-    v->elements[0] = i;
-}
-
 static value cupl_eval(node *tree)
 /* recursively evaluate a CUPL parse tree */
 {
     value      leftside, rightside, result;
     node       *np;
 
+    if (verbose >= DEBUG_ALLOCATE)
+       (void) printf("Evaluating %9x (%s)\n", tree, tokdump(tree->type));
+
     switch(tree->type)
     {
     case NUMBER:
@@ -135,22 +131,70 @@ static value cupl_eval(node *tree)
        return(result);
 
     case IDENTIFIER:
-       return(tree->syminf->value);
+       result = EVAL_WRAP(tree->syminf->value);
+       return(result);
 
     case READ:
        for_cdr(np, tree)
            cupl_read(np->car);
-       break;
+       return(result);         /* garbage value */
 
     case WRITE:
        needspace(0);
        for_cdr(np, tree)
            cupl_write(np->car);
        needspace(-1);
-       break;
+       return(result);         /* garbage value */
+
+    case LET:
+       deallocate_value(&(tree->car->syminf->value));
+       tree->car->syminf->value = EVAL_WRAP(cupl_eval(tree->cdr));
+       return(result);         /* garbage value */
+
+    case PLUS:
+       leftside = EVAL_WRAP(cupl_eval(tree->car));
+       rightside = EVAL_WRAP(cupl_eval(tree->cdr));
+       result = cupl_add(leftside, rightside);
+       return(result);
+
+    case MULTIPLY:
+       leftside = EVAL_WRAP(cupl_eval(tree->car));
+       rightside = EVAL_WRAP(cupl_eval(tree->cdr));
+       result = cupl_multiply(leftside, rightside);
+       return(result);
+
+    case MINUS:
+       leftside = EVAL_WRAP(cupl_eval(tree->car));
+       rightside = EVAL_WRAP(cupl_eval(tree->cdr));
+       result = cupl_subtract(leftside, rightside);
+       return(result);
+
+    case DIVIDE:
+       leftside = EVAL_WRAP(cupl_eval(tree->car));
+       rightside = EVAL_WRAP(cupl_eval(tree->cdr));
+       result = cupl_add(leftside, rightside);
+       return(result);
+
+    case POWER:
+       leftside = EVAL_WRAP(cupl_eval(tree->car));
+       rightside = EVAL_WRAP(cupl_eval(tree->cdr));
+       result = cupl_power(leftside, rightside);
+       return(result);
+
+    case UMINUS:
+       rightside = EVAL_WRAP(cupl_eval(tree->cdr));
+       result = cupl_uminus(rightside);
+       return(result);
+
+    case SQRT:
+       rightside = EVAL_WRAP(cupl_eval(tree->cdr));
+       result = cupl_sqrt(rightside);
+       return(result);
 
     default:
-       die("unknown node type %d (%s), cannot execute\n",tokdump(tree->type));
+       die("unknown node type %d (%s), cannot execute\n",
+           tree->type,
+           tokdump(tree->type));
        break;
     }
 }