tokdump.o: tokdump.c toktab.h
lexer.o: lexer.c tokens.h cupl.h
interpret.o: interpret.c tokens.h cupl.h
-interpret.o: interpret.c tokens.h nodetype.h cupl.h
-execute.o: execute.c tokens.h nodetype.h cupl.h
+interpret.o: interpret.c tokens.h cupl.h
+execute.o: execute.c tokens.h cupl.h
monitor.o: monitor.c tokens.h cupl.h
toktab.h: tokens.h
#define NULLNODE (node *)NULL
+#define car u.n.left
+#define cdr u.n.right
+
#define for_cdr(x, t) for (x = (t); x; x = x->u.n.right)
/* this structure represents a CUPL value */
}
/* break the link to the data */
- if (!data)
- warn("no data supplied\n");
- else if (last)
+ if (data && last)
last->cdr = cons(END, NULLNODE, NULLNODE);
/* first, setjmp so we can use STOP to exit */
#include <stdio.h>
#include "cupl.h"
#include "tokens.h"
-#include "nodetype.h"
+
+/* nodetype.h -- macros that describe the semantics of nodes */
+
+/*
+ * Define token classes for consistency checks here. The theory is
+ * that by separating this from the tree-traversal machinery below, we
+ * may be able to parametrize for different source languages someday.
+ */
+/* does the node represent an atom? */
+#define ATOMIC(n) ((n) == IDENTIFIER || (n) == NUMBER || (n) == STRING)
+/* does the node reference a statement label? */
+#define SLABELREF(n) ((n) == GO || (n) == OG)
+/* does the node reference a block label? */
+#define BLABELREF(n) ((n) == PERFORM)
+/* does the node set a variable? */
+#define VARSET(n) ((n) == LET || (n) == READ || (n) == ITERATE)
+/* does the (non-VARSET) node refer to its left operand as a variable? */
+#define LEFTREF(n) ((n) != FOR && (n) != GO && (n) != OG && (n) != LABEL \
+ && (n) != ALLOCATE && (n) != WATCH \
+ && (n) != ITERATE && (n) != FROM \
+ && (n) != PERFORM)
+/* does the (non-VARSET) node refer to its right operand? */
+#define RIGHTREF(n) ((n) != PERFORM)
+
+/* nodetype.h ends here */
#ifdef PARSEDEBUG
/*