#define PATH_MAX 1024
#endif
-#define MAXPERFORM 64 /* depth of perform stack */
-#define MAXVARS 1024 /* maximum variables */
-#define MAXNAME 10 /* maximum length of variable names */
-#define MAXSTR 256 /* maximum string size */
-
#ifndef CUPLDIR
#define CUPLDIR "/usr/lib/cupl/"
#endif /* CUPLDIR */
*/
typedef struct edon
{
- int type; /* type of NODE if *left || *right */
+ /* type of the node -- a YACC token type */
+ int type;
+
+ /* value elements of the node */
union
{
struct /* for parse-tree nodes */
scalar numval; /* for numbers */
- char *string; /* for string literals */
-
- struct /* for label values */
- {
- struct edon *dest;
- char *string;
- } l;
+ char *string; /* for strings and identifiers */
} u;
+
+ /* back-pointer to the symbol list, set if the node is an identifier */
+ struct lvar_t *syminf;
}
node;
node *node;
}
lvar;
-static lvar *idlist;
+extern lvar *idlist;
#define NOMEM "out of memory\n"
extern void interpret(node *tree);
extern int verbose;
+#define DEBUG_PARSEDUMP 1
+#define DEBUG_CHECKDUMP 2
+#define DEBUG_ALLOCATE 3
+
/* cupl.h ends here */
extern char *strdup(const char *s);
+lvar *idlist;
+
static node *intern_number(char *);
static node *intern_identifier(char *);
static node *intern_string(char *);
}
#ifdef PARSEDEBUG
- if (verbose >= 2)
+ if (verbose >= DEBUG_ALLOCATE)
(void) printf("intern: %9x (IDENTIFIER: %s)\n",
new, str);
#endif /* PARSEDEBUG */
new->u.numval = numval;
#ifdef PARSEDEBUG
- if (verbose >= 2)
+ if (verbose >= DEBUG_ALLOCATE)
(void) printf("intern: %9x (NUMBER: %f)\n", new, numval);
#endif /* PARSEDEBUG */
return(new);
new->u.string = strdup(str + 1);
#ifdef PARSEDEBUG
- if (verbose >= 2)
+ if (verbose >= DEBUG_ALLOCATE)
(void) printf("intern: %9x (STRING: '%s')\n",
new, new->u.string);
#endif /* PARSEDEBUG */
new->u.n.right = right;
#ifdef PARSEDEBUG
- if (verbose >= 2)
+ if (verbose >= DEBUG_ALLOCATE)
(void) printf("cons: %9x -> %9x %9x (%s)\n",
new, left, right, tokdump(op));
#endif /* PARSEDEBUG */
#include <stdio.h>
+#include <stdarg.h>
#include "cupl.h"
#include "tokens.h"
}
value;
-/* this structure represents a CUPL variable */
-typedef struct rav
-{
- char name[MAXNAME + 1]; /* name of variable */
- value value;
-}
-variable;
-
#ifdef PARSEDEBUG
/*
* Note: This prettyprint routine tries to keep cons lists of elements of the
else
{
(void) printf("%-20s", tokdump(tree->type));
- if (verbose >= 2)
+ if (verbose >= DEBUG_ALLOCATE)
(void) printf(" (%x -> %x, %x)",
tree,
tree->u.n.left,
}
#endif /* PARSEDEBUG */
+static void die(char *msg, ...)
+/* complain of a fatal error and die */
+{
+ va_list args;
+
+ va_start(args, msg);
+ vfprintf(stderr, msg, args);
+ va_end(args);
+
+ exit(1);
+}
+
+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;
+
+ /* mark labels */
+ 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++;
+ }
+
+ /* report on the number of labels */
+ if (verbose >= DEBUG_CHECKDUMP)
+ if (nlabels == 0)
+ (void) printf("No labels.\n");
+ else
+ {
+ (void) printf("Labels:");
+ for (lp = idlist; lp; lp = lp->next)
+ if (lp->islabel)
+ (void) printf(" %s", lp->node->u.string);
+ (void) printf("\n");
+ }
+}
+
void interpret(node *tree)
/* interpret a program parse tree */
{
#ifdef PARSEDEBUG
- if (verbose > 0)
+ if (verbose > DEBUG_PARSEDUMP)
prettyprint(tree, 0);
#endif /* PARSEDEBUG */
+
+ if (check_errors(tree))
+ return;
+
+ /* actual interpretation or compilation goes here */
}
/* interpret.c ends here */
for (; optind < argc; optind++)
if (execfile(argv[optind]))
break;
+ return(0);
}
/* main.c ends here */