From: Eric S. Raymond Date: Thu, 3 Nov 1994 00:01:34 +0000 (+0000) Subject: First sanity checks are now working. X-Git-Tag: 1-2~106 X-Git-Url: http://thyrsus.com/gitweb/?a=commitdiff_plain;h=366439c173c2e1b4a2c3f0d1157a8e67d702eb4f;p=cupl.git First sanity checks are now working. --- diff --git a/cupl.h b/cupl.h index 447e0cb..84a7dd6 100644 --- a/cupl.h +++ b/cupl.h @@ -7,11 +7,6 @@ #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 */ @@ -37,7 +32,10 @@ typedef double scalar; */ 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 */ @@ -48,14 +46,11 @@ typedef struct edon 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; @@ -69,7 +64,7 @@ typedef struct lvar_t node *node; } lvar; -static lvar *idlist; +extern lvar *idlist; #define NOMEM "out of memory\n" @@ -78,4 +73,8 @@ extern void yyerror(const char *errmsg); extern void interpret(node *tree); extern int verbose; +#define DEBUG_PARSEDUMP 1 +#define DEBUG_CHECKDUMP 2 +#define DEBUG_ALLOCATE 3 + /* cupl.h ends here */ diff --git a/cupl.l b/cupl.l index 51068f5..fb10645 100644 --- a/cupl.l +++ b/cupl.l @@ -11,6 +11,8 @@ extern char *strdup(const char *s); +lvar *idlist; + static node *intern_number(char *); static node *intern_identifier(char *); static node *intern_string(char *); @@ -118,7 +120,7 @@ static node *intern_identifier(char *str) } #ifdef PARSEDEBUG - if (verbose >= 2) + if (verbose >= DEBUG_ALLOCATE) (void) printf("intern: %9x (IDENTIFIER: %s)\n", new, str); #endif /* PARSEDEBUG */ @@ -142,7 +144,7 @@ static node *intern_number(char *str) 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); @@ -165,7 +167,7 @@ static node *intern_string(char *str) 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 */ diff --git a/cupl.y b/cupl.y index 08d7697..742086e 100644 --- a/cupl.y +++ b/cupl.y @@ -272,7 +272,7 @@ node *left, *right; /* child nodes */ 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 */ diff --git a/interpret.c b/interpret.c index ee81c7b..98f58c2 100644 --- a/interpret.c +++ b/interpret.c @@ -1,4 +1,5 @@ #include +#include #include "cupl.h" #include "tokens.h" @@ -21,14 +22,6 @@ typedef struct } 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 @@ -57,7 +50,7 @@ static void prettyprint(node *tree, int indent) else { (void) printf("%-20s", tokdump(tree->type)); - if (verbose >= 2) + if (verbose >= DEBUG_ALLOCATE) (void) printf(" (%x -> %x, %x)", tree, tree->u.n.left, @@ -71,13 +64,65 @@ static void prettyprint(node *tree, int indent) } #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 */ diff --git a/main.c b/main.c index 403d0eb..d7a6349 100644 --- a/main.c +++ b/main.c @@ -77,6 +77,7 @@ char *argv[]; for (; optind < argc; optind++) if (execfile(argv[optind])) break; + return(0); } /* main.c ends here */