#include "defs.h" STRING scanfor(); INT m_pr; /* Lookup tag in tree 'root' if simple. * If tag is a pattern or generator * then lookup in global tree. * Generate tags in 'root' if required */ TAG gentag(s, root) STRING s; TAG *root; { generate(s,root); return(gettag(s, ((gen(s)<0)?root:&GENTAG))); } TAG gettag(s, root) STRING s; TAG *root; { REG TAG *tp=lookup(s,root); REG TAG t; if(newtag) t=addtag(s, tp); else t = *tp; return(t); } TAG *lookup(s, root) STRING s; TAG *root; { REG TAG scan = *root; REG TAG *prev = root; INT LR; newtag=0; if(chkid(s)) { errmsg(s, "illegal name\n"); errjmp(); } while(scan!=nil(TAG)) { if((LR=cmpstr(s, scan->tc))==0) return(prev); elif(LR<0) prev = &(scan->l); else prev = &(scan->r); scan = *prev; } newtag=1; return(prev); } TAG addtag(s, prev) STRING s; TAG *prev; { /* add new node */ REG TAG t=CHEAT(TAG,getheap(0)); REG INT L=movstr(s, t->tc)-(t->tc); heaprnd(L+TAGSIZ+1); inittag(t); *prev=t; return(t); } ITEM newname; walk(tag) TAG tag; { if(tag==nil(TAG)) return; walk(tag->l); print("%E%16t%s", tag->tc); endline(); walk(tag->r); } l_walk(tag) TAG tag; { if(tag==nil(TAG)) return; l_walk(tag->l); print(".h %s", tag->tc); print(" %d", tag->flg); print(" %d\n", tag->lev); l_walk(tag->r); } t_walk(tag) TAG tag; { if(tag==nil(TAG)) return; t_walk(tag->l); print("%E%s\n", tag->tc); if(CHEAT(TAG*,tag->val) == &tag->nxt) { p_walk(*CHEAT(TAG*, tag->val)); } elif(tag->val) { print("%E ="); } elif(tag->nxt) { DEF d = CHEAT(DEF, tag->nxt); print("%E parameters:\n"); m_pr=0; m_walk(d->d_pin); print("%E\n\tsignals:\n"); m_pr=1; m_walk(d->d_sig); print("%E\n\tchips:\n"); c_scan(d->d_chips); } print("%E\n"); t_walk(tag->r); } p_walk(tag) TAG tag; { if(tag==nil(TAG)) return; p_walk(tag->l); print("%E%16t%d", tag->val); print("%E,%s", tag->tc); endline(); p_walk(tag->r); } m_walk(tag) TAG tag; { if(tag==nil(TAG)) return; m_walk(tag->l); print("%E%16t%s", tag->tc); if(m_pr && tag->val) { print("%E,%s", tag->val->tc); } endline(); m_walk(tag->r); } c_scan(chp) CHP chp; { while(chp!=nil(CHP)) { print("%E%16t%s", chp->c_tag->tc); print("%E,%s", chp->c_type->tc); endline(); chp=chp->c_next; } } endline() { if(charpos(standout)>=96) print("%E\n"); } TAG *g_root; g_walk(tag) TAG tag; { if(tag==nil(TAG)) return; g_walk(tag->l); generate(tag->tc, g_root); g_walk(tag->r); } generate(as, root) STRING as; TAG *root; { REG CHAR c; REG STRING s=as; STRING s1, s2; TAG *oldroot; TAG locroot=nil(TAG); INT more; if(number(s)) return(0); if(gen(s)==0) return(0); while(c = *s) { if(c=='[' || c=='<') { CHAR save=c; CHAR ket=(c=='<' ? '>' : ']'); *s=0; s1=s; s2 = ++s; while((c = *s2) && c!=ket) s2++; if(c==ket) s2++; /* check s2 for more [] */ more=gen(s2)==1; if(more) { oldroot=root; root= &locroot; } /* generate this lot */ if(save=='[') { INT prev=0; while((c = *s++) && c!=']') { if( (c=='-') && (*s!=']') && *s && prev) { while(prev++ < *s) { concat(as,prev,s2); gettag(newname, root); } prev=0; } else { concat(as,c,s2); prev=c; gettag(newname, root); } } } else{ INT a, b, c, max=0; s=scanfor(s, &a, ':', &max); s=scanfor(s, &b, ':', &max); s=scanfor(s, &c, '>', &max); if(c<0) { c=b; b=1; } while(a<=c) { /* make number */ CHAR numbuf[3*INTWIDTH]; char *np; itos(a,numbuf,max); np=movstr(as,newname); np=movstr(numbuf,np); np=movstr(s2,np); gettag(newname, root); a+=b; } } *s1=save; /* recurse if needed */ if(more) { g_root = oldroot; g_walk(locroot); root=oldroot; } return(1); } s++; } gettag(as, root); return(1); } TAG s_chain; STRING s_tag; TAG find(s, tag) STRING s; REG TAG tag; { if(s==nil(STRING)) bad("name required"); s_chain=nil(TAG); search(s, tag); s_tag=s; return(s_chain); } notnil(x) REG TAG x; { if(x==nil(TAG)) { errmsg(s_tag, "not found\n"); } } search(p, tree) STRING p; TAG tree; { if(tree==nil(TAG)) return; search(p, tree->r); if(match(tree->tc, p)) { tree->nxt=s_chain; s_chain=tree; } search(p, tree->l); } inittag(t) REG TAG t; { t->nxt=t->l=t->r=nil(TAG); t->val=g_val; t->flg=0; t->lev=level; } /* * convert integer to chars in s[] */ itos(i,s,max) INT i; STRING s; { while(--max >0 ) { *s++ = (i/10)+48; i%=10; } *s++ = i+48; *s++ = 0; }