|
|
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.