|
|
1.1 root 1: /*
2: * mjm: calloc() -> kalloc() so no conflict with Unix calloc();
3: * and kalloc() calls malloc; also new OUT
4: */
5: #define UNDEF (undefin)
6: #define NOTFOUND (-1)
7: #define OUT (0) /* mjm: out of storage for malloc() */
8: #define PUTOK 1
9: #define PUTBAD 0
10: #define SYNAMEL 8
11: #define AREASIZN (504/sizeof(dummynode))
12: #define AREASIZE sizeof(**ixb)
13: static struct node {
14: int lefta,leftn;
15: int righta,rightn;
16: int value;
17: char nn[SYNAMEL];
18: } dummynode;
19: static struct area {
20: int areaname;
21: int altered;
22: struct node nodes[AREASIZN];
23: };
24:
25: struct head {
26: int nodenew,areanew,lvalid;
27: int lstart;
28: struct head *lnext;
29: };
30:
31: static struct area *buff,**ixb;
32: static struct head *lhead;
33: static int fp;
34: static int oldlv;
35: /* the value to return for undefined symbol, set in rhccomp.c */
36: extern int undefin;
37: extern char *symtout;
38: extern int outcore;
39:
40: /* return the value of a symbol s, starting from area a */
41: static getval(s,a)
42: struct area *a;
43: char *s;
44: {
45: int n,c,at;
46: n=0;
47: while(c=sycomp(s,a->nodes[n].nn)) {
48: if(c<0) {
49: if((at=a->nodes[n].lefta)==0) return(NOTFOUND);
50: n=a->nodes[n].leftn;
51: }
52: else {
53: if((at=a->nodes[n].righta)==0) return(NOTFOUND);
54: n=a->nodes[n].rightn;
55: }
56: if(at!=a->areaname) a=fetcha(at);
57: }
58: return(a->nodes[n].value);
59: }
60:
61: /* define a symbol s with value v starting in area a */
62: static putval(s,a,v)
63: int v;
64: struct area *a;
65: char *s;
66: {
67: int n,c,at;
68: n=0;
69: while(c=sycomp(s,a->nodes[n].nn)) {
70: if(c<0) {
71: if((at=a->nodes[n].lefta)==0) {
72: return(putlink(s,a,v,n,'l'));
73: }
74: n=a->nodes[n].leftn;
75: }
76: else {
77: if((at=a->nodes[n].righta)==0) {
78: return(putlink(s,a,v,n,'r'));
79: }
80: n=a->nodes[n].rightn;
81: }
82: if(at!=a->areaname) a=fetcha(at);
83: }
84: return(PUTBAD);
85: }
86:
87: /* initial call here: set up size in bytes of symtab buffers */
88: symtab(size)
89: int size;
90: {
91: int i;
92: buff=kalloc(size);
93: ixb=kalloc(2*sizeof(buff)+(sizeof(buff)*size)/AREASIZE); /* mjm: 2->sizeof */
94: if((fp=creat(symtout,0666))<0) abt("can't create file for symtab");
95: close(fp);
96: if((fp=open(symtout,2))<0) abt("can't re-open file for symtab");
97: lhead=kalloc(sizeof(*lhead));
98: lhead->lnext = lhead->nodenew = lhead->lvalid = 0;
99: lhead->lstart=lhead->areanew=1;
100: oldlv=0;
101: for(i=0; AREASIZE*(i+1)<=size; i++) {
102: ixb[i]= &buff[i];
103: buff[i].areaname=0; buff[i].altered=0;
104: }
105: ixb[i]=0;
106: }
107:
108: /* define the current level of symbol definition */
109: definelv(lv)
110: int lv;
111: {
112: struct head *lnew;
113: if(lv>oldlv) {
114: lnew=kalloc(sizeof(*lhead));
115: lnew->lnext=lhead;
116: if(lhead->nodenew) {
117: lnew->areanew=lhead->areanew+1;
118: }
119: else {
120: lnew->areanew=lhead->areanew;
121: }
122: lnew->nodenew=lnew->lvalid=0;
123: lnew->lstart=lnew->areanew;
124: lhead=lnew;
125: }
126: if(lv<oldlv) {
127: lnew=lhead->lnext;
128: free(lhead);
129: lhead=lnew;
130: }
131: oldlv=lv;
132: }
133:
134: /* define a symbol */
135: definesy(s,v)
136: char *s;
137: int v;
138: {
139: struct area *a;
140: if(lhead->lvalid) return(putval(s,fetcha(lhead->lstart),v));
141: else {
142: lhead->lvalid=1;
143: lhead->nodenew=1;
144: a=fetcha(lhead->lstart);
145: return(putnv(s,a,v,0));
146: }
147: }
148:
149: /* get a symbol value at current level or below */
150: gettype(s)
151: char *s;
152: {
153: struct head *h;
154: int i;
155: h=lhead;
156: while(h) {
157: if(h->lvalid)
158: if((i=getval(s,fetcha(h->lstart)))!=NOTFOUND)return(i);
159: h=h->lnext;
160: }
161: return(UNDEF);
162: }
163: static putnv(s,a,v,n) /* put a new node at n in a */
164: int v,n;
165: struct area *a;
166: char *s;
167: {
168: struct node *nq;
169: int i;
170: char *s2;
171: a->altered=1;
172: s2=(nq= &a->nodes[n])->nn;
173: i=0;
174: while(i++<SYNAMEL&&(*s2++= *s++));
175: nq->lefta=nq->righta=0;
176: nq->value=v;
177: return(PUTOK);
178: }
179:
180: static putlink(s,a,v,n,lr) /* put new node and link to ... */
181: char *s;
182: struct area *a;
183: int v,n,lr;
184: {
185: a->altered=1;
186: if(lr=='l') {
187: a->nodes[n].leftn=lhead->nodenew;
188: a->nodes[n].lefta=lhead->areanew;
189: }
190: else {
191: a->nodes[n].rightn=lhead->nodenew;
192: a->nodes[n].righta=lhead->areanew;
193: }
194: a=fetcha(lhead->areanew);
195: putnv(s,a,v,lhead->nodenew);
196: if(++lhead->nodenew>=AREASIZN) {
197: lhead->nodenew=0;
198: lhead->areanew++;
199: }
200: return(PUTOK);
201: }
202:
203: /* check out strings */
204: static sycomp(s1,s2)
205: char *s1,*s2;
206: {
207: int i;
208: for(i=0; i<SYNAMEL&&(*s1||*s2); i++)
209: if(*s1++!= *s2++)
210: return(*--s1- *--s2);
211: return(0);
212: }
213:
214: /* dynamic disk reader-writer */
215: static fetcha(ta)
216: int ta;
217: {
218: struct area *it;
219: int i;
220: long lonk;
221: for(i=0; it=ixb[i]; i++)
222: if(it->areaname==ta) break;
223: if(it==0) {
224: it= ixb[--i];
225: if(it->altered) {
226: lseek(fp,(lonk=it->areaname)<<9,0);
227: write(fp,it,AREASIZE);
228: }
229: lseek(fp,(lonk=ta)<<9,0);
230: read(fp,it,AREASIZE);
231: it->altered=0;
232: it->areaname=ta;
233: }
234: while(i-->0) ixb[i+1]=ixb[i];
235: return(*ixb=it);
236: }
237:
238: static kalloc(sz)
239: int sz;
240: { /* mjm: made malloc arg always even */
241: if((sz=malloc((sz+1)&~01)) != OUT)
242: return(sz);
243: abt("out of storage in symtab");
244: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.