|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.