C:/Users/Dennis/src/lang/bertrand/BERTRAND/bertrand/prep.c

Go to the documentation of this file.
00001 /********************************************************************
00002  *
00003  * Interpret proprocessor statements.
00004  * Initialize operator tables for scanner and parser.                           
00005  *
00006  * Each statement begins with a pound sign (#) in column one,
00007  * and runs to the end of the line.  Comments are allowed.
00008  *
00009  * Valid statements are:
00010  * #op          operator definition
00011  * #operator       "         "
00012  * #type        type definition
00013  * #primtive    add supertype information
00014  * #include     cause scanner to start reading from another file
00015  * #load        like include, but file has been compiled (not implemented)
00016  * #line        change line number for error messages
00017  * #trace       set tracing level
00018  * #quiet       turn all tracing off
00019  *
00020  * Other statements, including other C preprocessor statements,
00021  * may be added in the future.
00022  *
00023  * Entry point is function "preprocess".
00024  *
00025  ********************************************************************/
00026 
00027 #include "def.h"
00028 
00029 extern char token_prval[];      /* preprocessor statement from scanner */
00030 static int token_pos;           /* position in statement */
00031 
00032 /* Character input class translation */
00033 extern char *trans;     /* from scanner.c */
00034 
00035 /********************************************************************
00036  *
00037  * token_get:   Return next token from string.
00038  *
00039  * entry:       Accesses the global variable token_prval
00040  *              (from scanner.c) which it modifies.  Also
00041  *              uses the static variable token_pos, which
00042  *              should have been initialized to zero before
00043  *              the first call to token_get.
00044  *
00045  * exit:        Returns a pointer to the next token in token_prval.
00046  *              This token is null terminated by inserting a
00047  *              null into token_prval.
00048  *              Returns null if there are no more tokens.
00049  *
00050  * A token is defined as either a whitespace delimited string of
00051  * characters, or an arbitrary string of characters inside of double
00052  * quotes.  No string escapes are currently recognized inside of
00053  * strings, so, for example, it is impossible to have a token contain
00054  * both a blank and a double quote.  A comment begins with two
00055  * periods, and runs to the end of the line.
00056  *
00057  ********************************************************************/
00058 static char *
00059 token_get()
00060 {
00061 register char *pos = token_prval + token_pos;
00062 char *tpos = NULL;              /* starting position of token */
00063 
00064 while (C_WS == trans[*pos]) pos++;      /* skip whitespace */
00065 /* if comment, then no more tokens */
00066 if (C_PER == trans[*pos] && C_PER == trans[pos[1]]) return NULL;
00067 if (C_EOF == trans[*pos] || C_NL == trans[*pos]) return NULL;
00068 else if (C_DQ == trans[*pos]) { /* quoted token */
00069     tpos = ++pos;               /* skip quote */
00070     while (C_DQ != trans[*pos] && C_NL != trans[*pos]) pos++;
00071     if (C_NL == trans[*pos]) error("unterminated string");
00072     *pos++ = '\0';      /* null terminate token (overwrite quote) */
00073     }
00074 else {                  /* unquoted token */
00075     tpos = pos++;       /* address of token */
00076     while (C_WS != trans[*pos] && C_NL != trans[*pos]) pos++;
00077     *pos++ = '\0';      /* null terminate token */
00078     }
00079 token_pos = pos - token_prval;
00080 return tpos;
00081 }
00082 
00083 /********************************************************************
00084  *
00085  * Operator definitions.
00086  *
00087  * In an operator definition the following keywords are recognized:
00088  *
00089  * unary                unary (default prefix)
00090  * prefix               unary prefix
00091  * postfix              unary postfix
00092  * infix                binary infix (default nonassociative)
00093  * binary               binary infix (default nonassociative)
00094  * left                 binary infix left associative
00095  * right                binary infix right associative
00096  * nonassoc             binary infix nonassociative
00097  * nonassociative       binary infix nonassociative
00098  * non                  binary infix nonassociative
00099  * associative          no-op
00100  * outfix               unary outfix
00101  * matchfix             unary outfix
00102  * nullary              nullary
00103  * precedence           no-op
00104  * supertype            no-op
00105  * 
00106  * The default arity is nullary.
00107  * A number is interpreted as a precedence (default 0).
00108  * Operator names are any non-keyword name, or one or two special characters.
00109  * Outfix takes two operators.
00110  * An operator may optionally have a single supertype.
00111  * Nullary and outfix do not take a precedence.
00112  * A numeric field beginning with a pound sign (#) indicates a special
00113  * operator.  Some special operators are evaluated at parse time
00114  * (such as ":" for labels, or "()" for changing evaluation order).
00115  * Other special operators control evaluation at run time
00116  * (such as [ ], to prevent evaluation).
00117  *
00118  * Examples:
00119  * #op + binary left associative precedence 45 ... standard plus operator
00120  * #op - left 45        ... identical definition for minus
00121  * #op true             ... nullary and precedence=0 assumed
00122  * #op false nullary supertype 'boolean  ... supertype
00123  * #operator ( ) #1     ... outfix, parser reduce function number 1
00124  *
00125  ********************************************************************/
00126 
00127 #define DEFAULT_PREC 0
00128 
00129 /* lists of operator definitions, from ops.c */
00130 extern OP *single_op, *double_op, *name_op, *type_op;
00131 
00132 /********************************************************************
00133  * 
00134  * op_create:   Allocate operator and check for valid name.
00135  *
00136  * entry:       The operator name to be checked.
00137  *              Pass in arity of this operator
00138  *
00139  * exit:        Operator node, inserted into operator tables.
00140  *              Arity and pname fields filled in.
00141  *              Returns pointer to node.
00142  *              Error exit if invalid name, or too many symbols.
00143  *
00144  * A valid operator is either an alphanumeric name or a symbol.
00145  * Symbols can be one or two characters long.
00146  *
00147  ********************************************************************/
00148 static OP *
00149 op_create(opn, arity)
00150 char *opn;      /* operator name */
00151 short arity;
00152 {
00153 register int l;         /* length of name */
00154 int class;
00155 OP *op;
00156 OP *op_new();           /* from ops.c */
00157 void op_put();          /* from ops.c */
00158 
00159 class = trans[opn[0]];
00160 if (C_ALPH == class) {          /* alphanumeric operator */
00161     for (l = 1; C_EOF != (class = trans[opn[l]]); l++) {
00162         if (C_ALPH != class && C_NUM != class) {
00163             fprintf(stderr, "operator: %s\n", opn);
00164             error("invalid alphanumeric operator name");
00165             }
00166         }
00167     op = op_new(l);             /* allocate operator node */
00168     strcpy(op->pname, opn);     /* copy operator name */
00169     op->arity = arity;
00170     op_put(&name_op, op);       /* insert into linked list */
00171     }
00172 else if (C_SPC == class) {
00173     class = trans[opn[1]];
00174     if (C_EOF == class) {       /* single special char operator */
00175         op = op_new(1);         /* allocate operator node */
00176         strcpy(op->pname, opn); /* copy operator name */
00177         op->arity = arity;
00178         op_put(&single_op, op); /* insert into linked list */
00179         }
00180     else if (C_SPC == class) {
00181         class = trans[opn[2]];
00182         if (C_EOF == class) {
00183             op = op_new(2);             /* allocate operator node */
00184             strcpy(op->pname, opn);     /* copy operator name */
00185             op->arity = arity;
00186             op_put(&double_op, op);     /* insert into linked list */
00187             }
00188         else {
00189             fprintf(stderr, "operator: %s\n", opn);
00190             error("operator name contains more than two symbols");
00191             }
00192         }
00193     else {
00194         fprintf(stderr, "operator: %s\n", opn);
00195         error("invalid symbol in operator name");
00196         }
00197     }
00198 else {
00199     fprintf(stderr, "operator: %s\n", opn);
00200     error("invalid operator name, or misspelled keyword");
00201     }
00202 return op;
00203 }
00204 
00205 /********************************************************************
00206  *
00207  * Convert precedence of operator to numberic value.
00208  * This would be a generic routine for converting strings to numbers,
00209  * except that it checks for a valid precedence.
00210  *
00211  * entry:       string containing precedence.
00212  *
00213  * exit:        numeric value of precedence.
00214  *
00215  ********************************************************************/
00216 static short
00217 prec_conv(s) 
00218 char *s;                        /* input string */
00219 {
00220 long prec = 0;                  /* precedence */
00221 int i = 0;                      /* position in string */
00222 
00223 while (C_NUM == trans[s[i]]) prec = 10 * prec + s[i++] - '0';
00224 
00225 if (C_EOF != trans[s[i]]) {
00226     fprintf(stderr,"field: %s\n", s);
00227     error("invalid precedence field");
00228     }
00229 
00230 if (prec > BIG_SHORT) {
00231     printf("Precedence = %d; Maximum allowable = %ld\n", prec, BIG_SHORT);
00232     error("Precedence of operator exceeds maximum allowable");
00233     }
00234 
00235 return (short) prec;
00236 }
00237 
00238 /********************************************************************
00239  *
00240  * op_define:   Read and interpret an operator definition.
00241  *
00242  ********************************************************************/
00243 static void
00244 op_define()
00245 {
00246 register char *tok;     /* current token */
00247 char *op_name = NULL;   /* defined operator name */
00248 char *other_op_name = NULL;     /* outfix requires two operator names */
00249 char *supertype = NULL;
00250 char *prfun = NULL;     /* parser reduce function number */
00251 short arity = -1;       /* number of arguments (see def.h) */
00252 short kind = -1;        /* i.e., postfix vs. prefix */
00253 short precedence = -1;
00254 OP *op;
00255 char *arity_name();     /* from ops.c */
00256 
00257 for ( ; NULL != (tok = token_get()); ) {        /* do until end of statement */
00258     if (tok[0] == '#') {        /* special information for operator */
00259         if (prfun) error("multiple special reduce functions not allowed");
00260         prfun = tok;
00261         }
00262     else if (C_NUM == trans[tok[0]]) {  /* precedence */
00263         precedence = prec_conv(tok);
00264         }
00265     else if (C_SQ == trans[tok[0]]) {   /* supertype */
00266         if (supertype) {
00267             fprintf(stderr, "first supertype: %s, second supertype: %s\n",
00268                 supertype, tok);
00269             error("multiple supertypes not allowed");
00270             }
00271         supertype = tok;
00272         }
00273     else if (0==strcmp(tok, "left")) {
00274         if (arity == -1 || arity == BINARY) arity = LEFT;
00275         else {
00276             fprintf(stderr, "keyword %s applied to op of arity %s\n",
00277                 tok, arity_name(arity));
00278             error("bad operator specification");
00279             }
00280         }
00281     else if (0==strcmp(tok, "right")) {
00282         if (arity == -1 || arity == BINARY) arity = RIGHT;
00283         else {
00284             fprintf(stderr, "keyword %s applied to op of arity %s\n",
00285                 tok, arity_name(arity));
00286             error("bad operator specification");
00287             }
00288         }
00289     else if (0==strcmp(tok, "prefix")) {
00290         if (arity == -1 || arity == UNARY) arity = PREFIX;
00291         else {
00292             fprintf(stderr, "keyword %s applied to op of arity %s\n",
00293                 tok, arity_name(arity));
00294             error("bad operator specification");
00295             }
00296         }
00297     else if (0==strcmp(tok, "postfix")) {
00298         if (arity == -1 || arity == UNARY) arity = POSTFIX;
00299         else {
00300             fprintf(stderr, "keyword %s applied to op of arity %s\n",
00301                 tok, arity_name(arity));
00302             error("bad operator specification");
00303             }
00304         }
00305     else if (0==strcmp(tok, "nullary")) {
00306         if (arity == -1) arity = NULLARY;
00307         else {
00308             fprintf(stderr, "keyword %s applied to op of arity %s\n",
00309                 tok, arity_name(arity));
00310             error("bad operator specification");
00311             }
00312         }
00313     else if (0==strcmp(tok, "nonassoc") ||
00314         0==strcmp(tok, "nonassociative") ||
00315         0==strcmp(tok, "non")) {
00316         if (arity == -1 || arity == BINARY) arity = NONASSOC;
00317         else {
00318             fprintf(stderr, "keyword %s applied to op of arity %s\n",
00319                 tok, arity_name(arity));
00320             error("bad operator specification");
00321             }
00322         }
00323     else if (0==strcmp(tok, "outfix") || 0==strcmp(tok, "matchfix")) {
00324         if (arity == -1 || arity == UNARY) arity = OUTFIX1;
00325         else {
00326             fprintf(stderr, "keyword %s applied to op of arity %s\n",
00327                 tok, arity_name(arity));
00328             error("bad operator specification");
00329             }
00330         }
00331     else if (0==strcmp(tok, "unary")) {
00332         if (arity == -1) arity = UNARY;
00333         else if (!(arity & UNARY)) {
00334             fprintf(stderr, "keyword %s applied to op of arity %s\n",
00335                 tok, arity_name(arity));
00336             error("bad operator specification");
00337             }
00338         }
00339     else if (0==strcmp(tok, "infix") || 0==strcmp(tok, "binary")) {
00340         if (arity == -1) arity = BINARY;
00341         else if (!(arity & BINARY)) {
00342             fprintf(stderr, "keyword %s applied to op of arity %s\n",
00343                 tok, arity_name(arity));
00344             error("bad operator specification");
00345             }
00346         }
00347     else if (0==strcmp(tok, "associative")) ;   /* no-op */
00348     else if (0==strcmp(tok, "precedence")) ;    /* no-op */
00349     else if (0==strcmp(tok, "supertype")) ;     /* no-op */
00350     else {              /* operator name */
00351         if (!op_name) op_name = tok;
00352         else if (!other_op_name) other_op_name = tok;
00353         else {
00354             fprintf(stderr, "operators: %s, %s, %s\n",
00355                 op_name, other_op_name, tok);
00356             error("too many operator names, or invalid keyword");
00357             }
00358         }
00359     }   /* end of for loop */
00360 /* now sort everything out */
00361 if (arity == -1) {      /* arity not specified */
00362     if (!other_op_name) arity = NULLARY;        /* default is nullary */
00363     else arity = OUTFIX1;       /* unless two operators */
00364     }
00365 else if (arity == UNARY) arity = PREFIX;
00366 else if (arity == BINARY) arity = NONASSOC;
00367 /* validity checks */
00368 if (precedence != -1 && arity == NULLARY) {
00369     fprintf(stderr, "operator: %s, precedence: %d\n", op_name, precedence);
00370     error("a nullary operator may not have a precedence");
00371     }
00372 if (precedence != -1 && arity == OUTFIX1) {
00373     fprintf(stderr, "operators: %s %s, precedence: %d\n",
00374         op_name, other_op_name, precedence);
00375     error("an outfix operator may not have a precedence");
00376     }
00377 /* check operator names */
00378 if (op_name) op = op_create(op_name, arity);
00379 else {
00380     error("no operator name specified in operator definition");
00381     }
00382 if (arity == OUTFIX1) {
00383     if (other_op_name) {
00384         op->other = op_create(other_op_name, OUTFIX2);
00385         op->other->other = op;  /* link outfix2 to outfix1 */
00386         }
00387     else {
00388         fprintf(stderr, "first operator: %s\n", op_name);
00389         error("outfix operator requires two operator names");
00390         }
00391     }
00392 else if (other_op_name) {       /* only single name should be specified */
00393     fprintf(stderr, "operator: %s, second operator: %s\n",
00394         op_name, other_op_name);
00395     error("multiple operator names defined, or invalid keyword");
00396     }
00397 if (arity == NULLARY) op->precedence = BIG_SHORT;
00398 else if (arity == OUTFIX1) op->precedence = 0;
00399 else if (precedence == -1) op->precedence = DEFAULT_PREC;
00400 else op->precedence = precedence;
00401 if (supertype) {
00402     OP *sop;
00403     for (sop = type_op; sop; sop = sop->next) {
00404         if (0==strcmp(sop->pname, supertype+1)) break;
00405         }
00406     if (sop) op->super = sop;
00407     else {
00408         fprintf(stderr,"type: %s\n", supertype);
00409         error("supertype is invalid type");
00410         }
00411     }
00412 if (prfun) {
00413     int snum;
00414     snum = atoi(prfun+1);
00415     if (snum == 0) error("invalid parser reduce function");
00416     else op->eval = -snum;
00417     }
00418 #ifdef DEBUG
00419 printf("operator %s defined, arity = %s, precedence = %d\n",
00420     op->pname, arity_name(op->arity), op->precedence);
00421 if (op->arity == OUTFIX1)
00422     printf("other operator %s defined, arity = %s, precedence = %d\n",
00423     op->other->pname, arity_name(op->other->arity), op->other->precedence);
00424 #endif
00425 }
00426 
00427 /********************************************************************
00428  *
00429  * Type definitions.
00430  *
00431  * A type definition is just one or two type names.
00432  * The second type name is a supertype.
00433  * The keyword "supertype" is optional.
00434  *
00435  * Examples:
00436  * #type 'line
00437  * #type 'point supertype 'line
00438  * #type 'even 'integer
00439  *
00440  ********************************************************************/
00441 static void
00442 type_define()
00443 {
00444 register OP *ty;
00445 register char *tok;
00446 int len;
00447 OP *sop;
00448 OP *op_new();           /* from ops.c */
00449 
00450 tok = token_get();
00451 if (tok[0] != '\'') {
00452     fprintf(stderr,"type: %s\n", tok);
00453     error("type must begin with a single quote");
00454     }
00455 if (tok[1] == '\0') error("cannot define null type");
00456 len = strlen(tok);
00457 ty = op_new(len-1);     /* skip single quote */
00458 strcpy(ty->pname, tok+1);
00459 ty->arity = OP_NAME;
00460 ty->precedence = 0;
00461 ty->other = (OP *) NULL;
00462 ty->super = (OP *) NULL;
00463 op_put(&type_op, ty);
00464 
00465 tok = token_get();
00466 if (tok) {      /* supertype */
00467     if (0==strcmp(tok, "supertype")) {
00468         tok = token_get();
00469         if (!tok) {
00470             error("no supertype following supertype keyword");
00471             }
00472         }
00473     if (tok[0] != '\'') {
00474         fprintf(stderr,"supertype: %s\n", tok);
00475         error("supertype must begin with a single quote");
00476         }
00477     for (sop = type_op; sop; sop = sop->next) {
00478         if (0==strcmp(sop->pname, tok+1)) break;
00479         }
00480     if (sop) ty->super = sop;
00481     else {
00482         fprintf(stderr,"type: %s\n", tok);
00483         error("supertype is invalid type");
00484         }
00485     }
00486 tok = token_get();
00487 if (tok) error("invalid type definition");
00488 #ifdef DEBUG
00489 printf("type '%s defined, arity = %s", ty->pname, arity_name(ty->arity));
00490 if (ty->super) printf(", supertype = '%s\n", ty->super->pname);
00491 else printf("\n");
00492 #endif
00493 }
00494 
00495 /********************************************************************
00496  *
00497  * Primitive definitions.
00498  *
00499  * Similar to a type definition, except the type or operator already
00500  * exists (typically it is a primitive to the system).
00501  * A primitive definition is just a type or operator name,
00502  * followed by a supertype name (the keyword "supertype" is optional).
00503  * There is no point to a primitive definition without a supertype.
00504  * This directive can also be used to add supertype information to an
00505  * operator or type declared previously.
00506  *
00507  * Examples:
00508  * #primitive 'constant supertype 'number
00509  * #primitive 'positive 'constant
00510  *
00511  ********************************************************************/
00512 static void
00513 primitive_define()
00514 {
00515 register OP *prim;      /* the primitive */
00516 register char *tok;     /* tokens from statement */
00517 register OP *sop;       /* supertype */
00518 
00519 tok = token_get();
00520 if (tok[0] == '\'') {
00521     for (prim = type_op; prim; prim = prim->next) {
00522         if (0==strcmp(prim->pname, tok+1)) break;
00523         }
00524     if (!prim) {
00525         fprintf(stderr, "primitive type: %s\n", tok);
00526         error("primitive not found");
00527         }
00528     }
00529 else if (C_ALPH == trans[tok[0]]) {
00530     for (prim = name_op; prim; prim = prim->next) {
00531         if (0==strcmp(prim->pname, tok)) break;
00532         }
00533     if (!prim) {
00534         fprintf(stderr, "alphanumeric primitive: %s\n", tok);
00535         error("primitive not found");
00536         }
00537     }
00538 else if (tok[1] == '\0') {
00539     for (prim = single_op; prim; prim = prim->next) {
00540         if (0==strcmp(prim->pname, tok)) break;
00541         }
00542     if (!prim) {
00543         fprintf(stderr, "special character primitive: %s\n", tok);
00544         error("primitive not found");
00545         }
00546     }
00547 else if (tok[2] == '\0') {
00548     for (prim = double_op; prim; prim = prim->next) {
00549         if (0==strcmp(prim->pname, tok)) break;
00550         }
00551     if (!prim) {
00552         fprintf(stderr, "double special character primitive: %s\n", tok);
00553         error("primitive not found");
00554         }
00555     }
00556 else {
00557     fprintf(stderr, "unknown primitive: %s\n", tok);
00558     error("primitive not found");
00559     }
00560 if (prim->super) {
00561     fprintf(stderr, "primitive: %s, supertype: %s\n", tok, prim->super->pname);
00562     error("primitive already has a supertype");
00563     }
00564 
00565 /* look for supertype */
00566 tok = token_get();
00567 if (tok) {      /* supertype */
00568     if (0==strcmp(tok, "supertype")) {
00569         tok = token_get();
00570         if (!tok) {
00571             error("no supertype following supertype keyword");
00572             }
00573         }
00574     if (tok[0] != '\'') {
00575         fprintf(stderr,"supertype: %s\n", tok);
00576         error("supertype must begin with a single quote");
00577         }
00578     for (sop = type_op; sop; sop = sop->next) {
00579         if (0==strcmp(sop->pname, tok+1)) break;
00580         }
00581     if (sop) prim->super = sop;
00582     else {
00583         fprintf(stderr,"type: %s, supertype: %s\n", tok, prim->super->pname);
00584         error("supertype is invalid type");
00585         }
00586     }
00587 else {
00588     fprintf(stderr, "primitive: %s\n", tok);
00589     error("no supertype specified for primitive");
00590     }
00591 tok = token_get();
00592 if (tok) error("invalid primitive definition");
00593 #ifdef DEBUG
00594 printf("primitive %s defined, arity = %s", ty->pname, arity_name(ty->arity));
00595 if (ty->super) printf(", supertype = '%s\n", ty->super->pname);
00596 else printf("\n");
00597 #endif
00598 }
00599 
00600 /********************************************************************
00601  *
00602  * Include and load statements.
00603  *
00604  * An #include causes the scanner to textually include the specified
00605  * file.  Includes can be nested.
00606  * A #load is similar to an include, except that the file to be loaded
00607  * has already been precompiled.  NOT IMPLEMENTED YET.
00608  * Included files are searched for first in the current directory,
00609  * then in the directory called libdir, which defaults to the value
00610  * LIBDIR (#defined in def.h) or the UNIX environment variable BERTRAND,
00611  * if it is defined.
00612  * If a file name contains spaces, it should be enclosed in double quotes.
00613  * A file name inside of double quotes may not contain any double quotes.
00614  *
00615  * Examples (assuming UNIX file conventions):
00616  * #include thisfile
00617  * #include dir1/dir2/file
00618  * #include /root/dir/file
00619  * #include "a file"    .. not a typical UNIX file name
00620  *
00621  ********************************************************************/
00622 void
00623 file_push()
00624 {
00625 extern int filespushed;         /* all from scanner.c */
00626 extern FILE *infiles[];
00627 extern FILE *infile;
00628 extern char *infilenames[];
00629 extern char *infilename;
00630 extern int inlinenos[];
00631 extern int verboses[];
00632 extern int lineno;
00633 char *tok;
00634 char *char_copy();              /* from util.c */
00635 extern char *libdir;            /* from main.c */
00636 
00637 tok = token_get();
00638 if (!tok) error("no include file name specified");
00639 infiles[filespushed] = infile;
00640 infilenames[filespushed] = infilename;
00641 inlinenos[filespushed] = lineno;
00642 verboses[filespushed] = verbose;
00643 infile = fopen(tok, "r");
00644 if (NULL == infile) {
00645     char fbuf[256];
00646     strcpy(fbuf, libdir);
00647     strcat(fbuf, tok);
00648     infile = fopen(fbuf, "r");
00649     if (NULL == infile) {
00650         fprintf(stderr, "include file: %s\n", tok);
00651         error("file not found");
00652         }
00653     }
00654 infilename = char_copy(tok);
00655 verbose = FALSE;
00656 lineno = 1;
00657 filespushed++;
00658 #ifdef DEBUG
00659 printf("now reading from file %s\n", infilename);
00660 #endif
00661 }
00662 
00663 
00664 void
00665 load_file()
00666 {
00667 error("#load not implemented");
00668 }
00669 
00670 /********************************************************************
00671  *
00672  * preprocess:  Interpret preprocessor statements.
00673  *
00674  * entry:       String containing preprocessor statement is global
00675  *              variable token_prval from scanner.
00676  *
00677  * exit:        Side effects, depending upon type of statement.
00678  *              Error exit if invalid statement, syntax error, etc.
00679  *
00680  ********************************************************************/
00681 void
00682 preprocess()
00683 {
00684 char *tok;
00685 extern int lineno;      /* from scanner.c */
00686 
00687 token_pos = 0;
00688 tok = token_get();
00689 if (!tok) return;       /* null statement, ignore */
00690 if (0 == strcmp(tok, "op") || 0 == strcmp(tok, "operator")) op_define();
00691 else if (0 == strcmp(tok, "type")) type_define();
00692 else if (0 == strcmp(tok, "primitive")) primitive_define();
00693 else if (0 == strcmp(tok, "include")) file_push();
00694 else if (0 == strcmp(tok, "load")) load_file();
00695 else if (0 == strcmp(tok, "line")) {
00696     tok = token_get();
00697     if (tok) {
00698         if (C_NUM == trans[tok[0]]) lineno = atoi(tok);
00699         }
00700     }
00701 else if (0 == strcmp(tok, "trace")) {
00702     tok = token_get();
00703     if (tok && (C_NUM == trans[tok[0]])) verbose = atoi(tok);
00704     else verbose = 1;
00705     }
00706 else if (0 == strcmp(tok, "quiet")) verbose = 0;
00707 else {
00708     fprintf(stderr, "preprocessor statement keyword: #%s\n", tok);
00709     error("invalid preprocessor statement");
00710     }
00711 }

Generated on Fri Jan 25 09:58:43 2008 for Bertrand by  doxygen 1.5.4