Annotation of 41BSD/cmd/cifplot/interpeter.c, revision 1.1.1.1

1.1       root        1: /*******************************************************************
                      2: *                                                                  *
                      3: *    File: CIFPLOT/interpeter.c                                    *
                      4: *    Written by Dan Fitzpatrick                                    *
                      5: *    copyright 1980 -- Regents of the University of California     *
                      6: *                                                                  *
                      7: ********************************************************************/
                      8: 
                      9: #include <stdio.h>
                     10: #include "defs.h"
                     11: #include "globals.h"
                     12: #include "parser_defs.h"
                     13: #include "structs.h"
                     14: #include "alloc.h"
                     15: 
                     16: IMPORT Command *FindSymbol();
                     17: IMPORT State();
                     18: IMPORT PrintCommand();
                     19: IMPORT Error();
                     20: IMPORT Command *AddCmd();
                     21: IMPORT Command *MakeSymbol();
                     22: IMPORT StoreSymbol();
                     23: IMPORT Error();
                     24: IMPORT Free();
                     25: IMPORT MakeBBox();
                     26: IMPORT transform *MakeTransform();
                     27: 
                     28: Execute(command)
                     29: Command *command;
                     30: /* Execute is called by the parser to interpet all the top
                     31:  * level commands.             */
                     32: {
                     33:     Command *q;
                     34:     int n;
                     35: 
                     36:     switch(command->type) {
                     37:        case COMMENT:
                     38:                /* Ignore comments */
                     39:                FreeCommand(command);
                     40:                break;
                     41:        case SYMBOL:
                     42:                /* Store symbols in the symbol table */
                     43:                n = State(command->Ctype.Symbl.SymNo);
                     44:                /* Only Store if it is not already stored */
                     45:                if( (n == NONEXIST) || (n == DELETED) )
                     46:                        StoreSymbol(command);
                     47:                /* If the symbol was previously called it's status
                     48:                 * becomes USED so we 'Examine' all it's commands */
                     49:                if(command->Ctype.Symbl.status == UNEXAMINED) {
                     50:                        command->Ctype.Symbl.status = ACTIVE;
                     51:                        for(q=command->Ctype.Symbl.CStart; q!=NIL; q=q->CLink)
                     52:                                Examine(q,command->Ctype.Symbl.SymNo);
                     53:                        command->Ctype.Symbl.status = USED;
                     54:                        }
                     55:                break;
                     56:        case ARRAY:
                     57:        case CALL:
                     58:                /* The call may use a new symbol so we call 'Examine'
                     59:                 * to compute bounding boxes and dependencies.   */
                     60:                Examine(command,-1);
                     61:                /* Fall through */
                     62:        default:
                     63:                /* Add the command to the pseudo-symbol 'prog' */
                     64:                prog = AddCmd(prog,command);
                     65:                break;
                     66:        }
                     67:     }
                     68: 
                     69: Examine(sym,n)
                     70: Command *sym;
                     71: int n;
                     72: /* 'Examine' sets up the data structures used to handle forward references
                     73:  * and symbol renaming. It is invoked any time a symbol becomes 'USED' or a
                     74:  * call is made on a symbol at the top level. (i.e. the call is not part of a 
                     75:  * symbol). It is called with a command and an integer n which is the symbol
                     76:  * the call is contained in. (If the call is at the top level n = -1)
                     77:  *
                     78:  * If the command is a call, the state of the symbol which is called is checked
                     79:  * to see if is UNUSED. Since this call changes the state of the symbol to
                     80:  * used this is recorded. Examine is called on all the commands of the symbol.
                     81:  * (This is necessary since 'Examine' must be called any time a symbol becomes
                     82:  * used.)
                     83:  *
                     84:  * The called symbol may be non-existent at the time of the call. (This is
                     85:  * an error condition since CIF requires all symbols definitions to be defined
                     86:  * before they are needed.) In this case a symbol header is created with the
                     87:  * status of 'UNDEFINED'.
                     88:  *
                     89:  * There are two other valid states the called symbol can be in, these are
                     90:  * 'USED' and 'UNDEFINED'. If the symbol is in some other state we know there
                     91:  * exists some inconsistancy in the data and the program is aborted.
                     92:  *
                     93:  * Thus far it appears that all examine does is call itself on other commands
                     94:  * whenever a symbol becomes used. The real work of this function, however,
                     95:  * is to record which symbol calls which. The number of the symbol that called
                     96:  * the symbol we are examining is passed as the parameter 'n'. If n is -1 we
                     97:  * are not interested in it. Any other value means this symbol was called by
                     98:  * symbol n. We then add symbol n to the symbol's 'backTrace' list. If the 
                     99:  * symbol is the redefined or deleted we know of all the dangling references
                    100:  * to this symbol.
                    101:  *
                    102:  * Further 'Examine' computes the bounding boxes for each command and checks
                    103:  * for recursion
                    104:  */
                    105: {
                    106:     Command *p,*q,*ptr;
                    107:     struct CCell *cell;
                    108:     char s[128];
                    109: 
                    110:     if (sym->type == ARRAY)
                    111:                Examine(sym->Ctype.Array.ACom,n);
                    112:     if (sym->type == CALL) {
                    113:                switch(State(sym->Ctype.Call.CallNo)) {
                    114:                        case NONEXIST:
                    115:                                sprintf(s,"Symbol %d Undefined",sym->Ctype.Call.CallNo);
                    116:                                Error(s,FATAL);
                    117:                                p = MakeSymbol(sym->Ctype.Call.CallNo,1,1);
                    118:                                p->Ctype.Symbl.status = UNDEFINED;
                    119:                                StoreSymbol(p);
                    120:                                ClearBBox(&(p->CBBox));
                    121:                                break;
                    122:                        case UNUSED:
                    123:                                p = FindSymbol(sym->Ctype.Call.CallNo);
                    124:                                p->Ctype.Symbl.status = ACTIVE;
                    125:                                for(q=p->Ctype.Symbl.CStart; q!=NIL; q=q->CLink)
                    126:                                        Examine(q,p->Ctype.Symbl.SymNo);
                    127:                                p->Ctype.Symbl.status = USED;
                    128:                                MakeBBox(&(p->CBBox),p);
                    129:                                break;
                    130:                        case USED:
                    131:                        case UNDEFINED:
                    132:                                p=FindSymbol(sym->Ctype.Call.CallNo);
                    133:                                break;
                    134:                        case ACTIVE:
                    135:                                sprintf(s,"Symbol %d Called Recursively",
                    136:                                              sym->Ctype.Call.CallNo);
                    137:                                Error(s,FATAL);
                    138:                                ClearBBox(&(sym->CBBox));
                    139:                                return;
                    140:                        default:
                    141:                                sprintf(s,"Symbol %d is in an illegal state\n",
                    142:                                        sym->Ctype.Call.CallNo);
                    143:                                Error(s,INTERNAL);
                    144:                        }
                    145:                if (n != -1) {
                    146:                    /* If symbol 'n' is not on the backtrace list for
                    147:                     * 'p' put it there. */
                    148:                    if(p->Ctype.Symbl.backTrace->CCNo != n) {
                    149:                        ptr = FindSymbol(n);
                    150:                        cell = (struct CCell *) palloc(sizeof(struct CCell));
                    151:                        cell->CCCom = ptr;
                    152:                        cell->CCNo = n;
                    153:                        cell->CCLink = p->Ctype.Symbl.backTrace;
                    154:                        p->Ctype.Symbl.backTrace = cell;
                    155:                        }
                    156:                    }
                    157:                /* Set the call commands Symbol pointer to symbol 'p' */
                    158:                sym->Ctype.Call.CSymb = p;
                    159:             }
                    160:     /* Compute the bounding box for command 'sym' */
                    161:     MakeBBox(&(sym->CBBox),sym);
                    162:     }
                    163: 
                    164: InitInter()
                    165: {
                    166:     int *i;
                    167:     InitLayers();
                    168:     InitSymbol();
                    169:     ident = MakeTransform();
                    170:     ident->refs = 1;
                    171:     i = (int *) ident;
                    172:     *(i-1) = 0;                /* cannot be freed */
                    173:     ZeroBBox(&GWindow);
                    174:     prog = MakeSymbol(-1,1,1);
                    175:     }
                    176: 
                    177: InterSummary()
                    178: {
                    179:     /* Compute bounding box for prog */
                    180:     struct BBox bb;
                    181:     Examine(prog,-1);
                    182:     if(GWindow.xmin > GWindow.xmax) {
                    183:        BBoxTransform(&GWindow,&(prog->CBBox),GlobalTransform);
                    184:        }
                    185:     if(debug > 3) PrintCommand(prog,stdout);
                    186:     if(debug) fprintf(stderr,"***Interpeter Summary***\n");
                    187:     if(debug) fprintf(stderr,"Window xmin %d, xmax %d, ymin %d, ymax %d\n",
                    188:                (int) prog->CBBox.xmin,(int) prog->CBBox.xmax,
                    189:                (int) prog->CBBox.ymin,(int) prog->CBBox.ymax);
                    190:     if(GWindow.xmax < GWindow.xmin || GWindow.ymax < GWindow.ymin) {
                    191:        fprintf(stderr,"Nothing to plot\n");
                    192:        abort();
                    193:        }
                    194:     }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.