|
|
1.1 root 1: #include "univ.h"
2: #include "dtype.pri"
3: #include "symbol.h"
4: #include "symtab.pub"
5: #include "srctext.pub"
6: #include "core.pub"
7: #include "process.pub"
8: #include "bpts.pub"
9: #include "phrase.pub"
10: #include "parse.h"
11: #include "format.pub"
12: SRCFILE("symbol.c")
13:
14: int Symbol::disc() { trace( "%d.disc()", this ); return U_ERROR; }
15: int Var::disc() { return _disc; }
16:
17: int Symbol::ok()
18: {
19: if( !this ) return 0;
20: switch( disc() ){
21: case U_ARG:
22: case U_AUT:
23: case U_BLOCK:
24: case U_FST:
25: case U_FUNC:
26: case U_GLB:
27: case U_MOT:
28: case U_REG:
29: case U_SOURCE:
30: case U_STA:
31: case U_STMT:
32: case U_UTYPE:
33: return 1;
34: }
35: return 0;
36: }
37:
38: int Var::ok()
39: {
40: if( !this ) return 0;
41: switch( disc() ){
42: case U_ARG:
43: case U_AUT:
44: case U_FST:
45: case U_GLB:
46: case U_MOT:
47: case U_STA:
48: return 1;
49: }
50: return 0;
51: }
52:
53:
54: Symbol::Symbol( Symbol *up, Symbol *left, char *t )
55: {
56: trace( "%d.Symbol(%d ^%d <%d %s)", this, up, left, t );
57: _text = t;
58: parent = up;
59: if( left ) left->rsib = this;
60: this->lsib = left;
61: }
62:
63: Stmt::Stmt(SymTab *stab, Block *up, Stmt *left ):(up,left,"<stmt>")
64: {
65: if(stab) stab->enter(this);
66: process = stab ? stab->core()->process(): 0;
67: condition = 0;
68: condtext = 0;
69: }
70:
71: Block::Block(SymTab *stab, Symbol *up, Block *left, char *t ):(up,left,t) {}
72:
73: BlkVars::BlkVars(Block *i) { VOK; b = i; v = 0; }
74:
75: Var *BlkVars::gen()
76: {
77: trace( "%d.gen() %d %d", this, v, b ); OK(0);
78: if(v) v = (Var*)v->rsib;
79: while( !v && b && b->disc()==U_BLOCK ){
80: v = b->var;
81: b = (Block*)b->parent;
82: }
83: trace( "%s", v->dump() );
84: return v;
85: }
86:
87: Source::Source(SymTab *stab, Source *left, char *t, long c):(0,left,t)
88: {
89: symtab = stab;
90: blk = new Block( stab, this, 0, sf("%s.sta_blk",t) );
91: srctext = new SrcText(this,c);
92: #ifndef V9
93: bsdp = 0;
94: #endif
95: }
96:
97: UType::UType(SymTab *stab, long b, long s, char *id):(0,0,id)
98: {
99: trace( "%d.UType(%d,%d,%d,%s)", this, stab, b, s, id );
100: begin = b;
101: size = s;
102: symtab = stab;
103: #ifndef V9
104: encode = 0;
105: #endif
106: canspecial = stab->core()->specialop(_text);
107: if( stab ) stab->enter(this);
108: }
109:
110: #ifndef V9
111: UType::UType(SymTab *stab, char *enc, char *id, BsdType *bs):(0,0,id)
112: {
113: encode = enc;
114: symtab = stab;
115: bsdp = bs;
116: canspecial = stab->core()->specialop(_text);
117: if( stab ) stab->enter(this);
118: }
119: #endif
120:
121: Var::Var(SymTab *stab, Block *up, Var *left, UDisc d, char* id):(up,left,id)
122: {
123: if( (_disc = d)<=TOSYM && stab ) stab->enter( this );
124: }
125:
126: Func::Func(SymTab *stab, Source *up, Func *left, long i, char* id):(up,left,id)
127: {
128: begin = i;
129: if( stab ) stab->enter( this );
130: }
131:
132: char *Symbol::dump()
133: {
134: static char t[128];
135:
136: if( !this ) return "0";
137: sprintf(t,"%d %s %s %d %d",this,DiscName(disc()),_text,range.lo,range.hi);
138: return t;
139: }
140:
141: int Func::regused(int r)
142: {
143: trace("%d.regused(%d)", this, r); OK(0);
144: Var *v;
145: BlkVars bv(blk());
146: while( v = bv.gen() )
147: if( v->disc()==U_REG && v->range.lo==r ) return 1;
148: return 0;
149: }
150:
151: void Func::gather()
152: {
153: Source *src = source();
154:
155: trace("%d.gather() %s", this, dump() ); VOK;
156: if( _blk = src->symtab->gatherfunc(this) )
157: _blk->parent = src->blk;
158: else
159: _blk = src->blk;
160: }
161:
162: char* Var::fmtlist()
163: {
164: trace("%d.fmtlist()", this); OK("");
165: static Bls *b;
166: if( !b ) b = new Bls;
167: b->clear();
168: long f = type.format();
169: for( long bit = 1; bit; bit <<= 1 ) if( bit&f ){
170: char *fn = FmtName(bit); // yuck
171: do b->af("%c", *fn); // yuck
172: while ( *fn++ != ' ' ); // yuck
173: }
174: return b->text;
175: }
176:
177: void Var::showutype(UType *u)
178: {
179: trace("%d.showutype(%d)", this, u); VOK;
180: u->show(LEAVE, SELECTLINE);
181: }
182:
183: void Var::reformat(long o)
184: {
185: trace("%d.reformat(0X%x)", this, o); VOK;
186: type.reformat(o);
187: show(SHOW, SELECTLINE);
188: }
189:
190: Index Var::carte()
191: {
192: trace("%d.carte()", this); OK(ZIndex);
193: Menu m;
194: if( showorhide==SHOW )
195: m.last(" hide ", (Action)&Var::show, HIDE);
196: else
197: m.last(" show ", (Action)&Var::show, SHOW);
198: long f = type.formatset();
199: long o = type.format();
200: if( f ){
201: Menu s;
202: for( long bit = 1; bit; bit <<= 1 ) if( bit & f ){
203: long b = bit;
204: if( b&o ) b |= F_TURNOFF;
205: s.last(FmtName(b), (Action)&Var::reformat, (long)b);
206: }
207: m.last(s.index("format"));
208: }
209: DType *d = &type;
210: while( d->isaryorptr() ) d = d->decref();
211: if( d->isstrun() && d->utype()){
212: UType *u = d->utype();
213: m.last(u->type.text(), (Action)&Var::showutype, (long)u);
214: }
215: return m.index();
216: }
217:
218: void Var::show(int soh, Attrib a)
219: {
220: trace("%d.display(%d)", this, soh); VOK;
221: if( _disc != U_MOT ) return;
222: UType *u = (UType*) parent;
223: if( !u ) return;
224: TypMems g(u);
225: Var *v;
226: for( long k = (long) u; v = g.gen(); ++k )
227: if( v == this ) break;
228: if( soh != LEAVE ) showorhide = soh;
229: SymTab *symtab = u->symtab;
230: if( !symtab ) return;
231: Pad *pad = symtab->pad();
232: if( !pad ) return;
233: Index ix = carte();
234: char *mark = showorhide==SHOW ? ">>>" : "";
235: pad->insert(k+1, a, (PadRcv*)this ,ix,
236: "%s\t%s\t%s;\t%s", mark, type.text(), text(), fmtlist());
237: }
238:
239: void UType::show(int soh, Attrib a)
240: {
241: trace("%d.display()", this); VOK;
242: TypMems g(this);
243: Var *v;
244: long k = (long) this;
245: while( v = g.gen() ){
246: v->show(soh);
247: ++k;
248: }
249: Pad *pad = symtab->pad();
250: if( !pad ) return;
251: Menu m;
252: m.first("hide all", (Action)&UType::show, HIDE);
253: m.first("show all", (Action)&UType::show, SHOW);
254: pad->insert((long)this, a, (PadRcv*)this, m, "%s {", type.text());
255: pad->insert(++k, 0, (PadRcv*)this, m, "} %s", type.text());
256: pad->insert(++k, "");
257: }
258:
259: void UType::gather()
260: {
261: trace("%d.gather()", this); VOK;
262: mem = symtab->gatherutype(this);
263: if( !mem )
264: return;
265: TypMems g(this);
266: Var *v;
267: for( int i = 1; v = g.gen(); ++i ){
268: v->parent = this;
269: if( i <= 2 ) v->showorhide = SHOW;
270: }
271: if( type.isstrun() ) show();
272: }
273:
274: Source *Symbol::source()
275: {
276: trace( "%d.source() %s", this, dump() );
277: return !this ? 0 : disc() == U_SOURCE ? (Source*)this : parent->source();
278: }
279:
280: char *Symbol::text(long) { OK("Symbol::text"); return _text; }
281:
282: char *Source::text(long) { OK("Source::text"); return basename(_text); }
283:
284: Stmt *Func::stmt(long pc)
285: {
286: Stmt *s, *r;
287:
288: trace( "%d.stmt(%d)", this, pc ); OK(0);
289: for( s = blk()->stmt; s; s = r ){
290: r = (Stmt*)s->rsib;
291: if( !r || r->range.lo>pc ) break;
292: }
293: return s && s->range.lo<=pc ? s : 0;
294: }
295:
296: TypMems::TypMems(UType *i) { ut = i; v = 0; }
297:
298: Var *TypMems::gen()
299: {
300: trace( "%d.gen()", this ); OK(0);
301: if( ut ){
302: if( !ut->mem ) ut->gather();
303: v = ut->mem;
304: ut = 0;
305: } else if( v )
306: v = (Var*)v->rsib;
307: trace( "%s", v->dump() );
308: return v;
309: }
310:
311: Block *Func::blk()
312: {
313: OK(0);
314: if(!_blk) gather();
315: return _blk;
316: }
317:
318: Block *Func::blk(long pc)
319: {
320: Stmt *s;
321:
322: trace( "%d.blk(%d)", this, pc ); OK(0);
323: if( !pc || !(s = stmt(pc)) || !s->parent ) return blk();
324: return (Block*) s->parent;
325: }
326:
327: Var *Func::argument(int a)
328: {
329: trace( "%d.argument(%d)", this, a ); OK(0);
330: BlkVars bv(blk());
331: Var *v;
332: int i = 0;
333: while( v = bv.gen() )
334: if( v->disc()==U_ARG && ++i==a ) return v;
335: return 0;
336: }
337:
338: char *Func::text(long)
339: {
340: return sf( "%s()", this ? _text : "?" );
341: }
342:
343: char *Stmt::text(long pc) // pass in a Bls argument?
344: {
345: char buf[256]; // use a Bls instead
346:
347: trace("%d.text(%d)", this, pc); OK("Stmt::text");
348: Source *src = source();
349: if( !src ) return sf( "pc=%d", range.lo );
350: sprintf( buf, "%s:%d", src->text(), lineno );
351: if( pc && range.lo < pc )
352: strcatfmt( buf, "+%u", pc-range.lo );
353: return sf("%s", buf);
354: }
355:
356: char *Stmt::journal(Bls &b)
357: {
358: trace("%d.journal(%d)", this, &b); OK("Stmt::journal");
359:
360: b.af("%s %s %s%s", text(), condtext->text, func()->text(), srcline());
361: return b.text;
362: }
363:
364: char *Stmt::srcline()
365: {
366: trace("%d.srcline()", this); OK( "Stmt::srcline");
367: Source *s = source();
368: if( !s || !s->srctext ) return "";
369: return s->srctext->srcline(lineno);
370: }
371:
372: void Stmt::select(long svp)
373: {
374: trace( "%d.select(%d)", this, svp ); VOK;
375: Source *src = source();
376: if( src ) src->srctext->select(lineno, svp);
377: else asmblr();
378: }
379:
380: char *Stmt::contextsearch(char *pat, int dir)
381: {
382: trace( "%d.conetxtsearch(%s,%d)", this, pat?pat:"", dir); OK("search");
383: Source *src = source();
384: if( src )
385: return src->srctext->contextsearch(lineno, pat, dir);
386: return "can't search";
387: }
388:
389: Pad *Stmt::srcpad() { return source()->srctext->pad; }
390:
391: void Stmt::error(char *s)
392: {
393: trace( "%d.error(%s)", this, s ); VOK;
394: Line l;
395: l.text = s;
396: l.object = this;
397: l.attributes |= SELECTLINE;
398: l.key = lineno;
399: srcpad()->insert( l );
400: }
401:
402: char *Stmt::kbd(char *s)
403: {
404: Parse y(G_EXPR, 0);
405: trace( "%d.kbd(%s)", this, s ); OK("kbd");
406: if( condition != Q_BPT ){
407: switch( *s ){
408: case '/': return contextsearch(s+1, 1);
409: case '?': return contextsearch(s+1, -1);
410: }
411: process->openframe( range.lo, s );
412: return 0;
413: }
414: Expr *newcond = (Expr*)y.parse(s);
415: if( newcond ){
416: conditional(newcond);
417: // condition = newcond;
418: // if( !condtext ) condtext = new Bls;
419: // condtext->clear();
420: // condtext->af("%s", newcond->text() );
421: dobpt(1);
422: select();
423: } else {
424: dobpt(0);
425: error( sf("%s: %s", y.error, s) );
426: }
427: return 0;
428: }
429:
430: char *Stmt::help()
431: {
432: trace( "%d.help()", this );
433: return condition == Q_BPT
434: ? "<expr> {breakpoint condition}"
435: : "<expr> {eval in frame} | [/?]<string> {search}";
436: }
437:
438: void Stmt::conditional(Expr *e)
439: {
440: trace( "%d.conditional()", this ); VOK;
441: condition = e;
442: if( !condtext ) condtext = new Bls;
443: condtext->clear();
444: condtext->af("%s", condition==Q_BPT ? "?" : condition->text() );
445: select();
446: }
447:
448: Stmt *Source::stmtafter(int l)
449: {
450: trace( "%d.stmtafter(%d)", this, l ); OK(0);
451:
452: if( !linefunc ) return 0;
453: while( l < linefunc->lines.lo && linefunc->lsib ){
454: linefunc = (Func*) linefunc->lsib;
455: linestmt = 0;
456: }
457: while( l > linefunc->lines.hi && linefunc->rsib ){
458: linefunc = (Func*) linefunc->rsib;
459: linestmt = 0;
460: }
461: if( !linestmt && !(linestmt = linefunc->blk()->stmt) )
462: return 0;
463: while ( linestmt->lsib &&
464: (l < linestmt->lineno || l <= ((Stmt*)linestmt->lsib)->lineno) )
465: linestmt = (Stmt*) linestmt->lsib;
466: while( l > linestmt->lineno && linestmt->rsib )
467: linestmt = (Stmt*) linestmt->rsib;
468: return linestmt;
469: }
470:
471: Func *Stmt::func()
472: {
473: trace("%d.func()", this); OK(0);
474: Source *src = source();
475: if( !src ) return 0;
476: return (Func*) src->symtab->loctosym(U_FUNC, range.lo);
477: }
478:
479: void Stmt::asmblr()
480: {
481: trace( "%d.asmblr() %d", this, process ); VOK;
482: if( process ) process->openasm(range.lo);
483: }
484:
485: void Stmt::settrace()
486: {
487: trace("%d.settrace()", this); VOK;
488: static Expr *zero = 0;
489: // bpts()->pad->makecurrent();
490: conditional(E_IConst(0));
491: dobpt(1);
492: }
493:
494: void Stmt::dobpt(int setorclr)
495: {
496: trace( "%d.dobpt(%d) %d", this, setorclr, process ); VOK;
497: if( condition == Q_BPT ){
498: condtext = 0;
499: condition = 0;
500: if( setorclr )
501: process->bpts()->set( this );
502: else
503: select();
504: } else {
505: if( setorclr )
506: process->bpts()->set( this );
507: else {
508: if( condtext ) delete condtext;
509: condtext = 0;
510: condition = 0;
511: process->bpts()->clr( this );
512: }
513: }
514: }
515:
516: void Stmt::openframe()
517: {
518: trace( "%d.openframe()", this ); VOK;
519: process->openframe( range.lo );
520: }
521:
522: Index UType::carte(Op op)
523: {
524: Menu m;
525: Var *v;
526: TypMems tm(this);
527: long n = 0;
528: char *on = (char*) OpName(op);
529: Action a = op==O_ARROW ? (Action)&Phrase::applyarrow : (Action)&Phrase::applydot; // C++ bug (Action)
530:
531: trace( "%d.carte(%s)", this, on ); OK(ZIndex);
532: if( canspecial )
533: m.last( canspecial, (Action)&Phrase::applyunary, O_SPECIAL );
534: while( v = tm.gen() ){
535: Bls field( "$%s%s\240", on, v->_text );
536: m.sort( field.text, a, (long) v );
537: ++n;
538: }
539: a = op==O_ARROW ? (Action)&Phrase::allstar : (Action)&Phrase::alleval;
540: m.first(sf("$%s*",on), a, (long)this);
541: return m.index(n>4 ? sf("$%sid",on) : 0);
542: }
543:
544: Source::~Source()
545: {
546: #ifndef V9
547: if( bsdp )
548: delete bsdp;
549: #endif
550: }
551:
552: Stmt::~Stmt() {}
553:
554: UType::~UType()
555: {
556: #ifndef V9
557: if (encode)
558: delete encode;
559: #endif
560: }
561:
562: Var::~Var() { /* on the stack in Expr */ }
563:
564: Func::~Func()
565: {
566: type.free();
567: }
568:
569: Block::~Block()
570: {
571: while( var ){
572: var->type.free();
573: delete var;
574: var = (Var*)var->rsib;
575: }
576: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.