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