|
|
1.1 root 1: #include "expr.pri"
2: #include "gram.h"
3: #include "symbol.h"
4: #include "format.pub"
5: #include "frame.pri"
6: #include "phrase.pub"
7: #include "symtab.pub"
8: #include "core.pub"
9: #include <CC/signal.h> /* floating point exceptions */
10: SRCFILE("expr.c")
11:
12: #ifdef V9
13: #define SIG_TYP SIG_ARG_TYP
14: #endif
15:
16: char *OpName(Op op)
17: {
18: switch(op){
19: case O_DEREF: return "*";
20: case O_REF: return "&";
21: case O_INDEX: return "[]";
22: case O_DOT: return ".";
23: case O_ARROW: return "->";
24: case O_PLUS: return "+";
25: case O_MINUS: return "-";
26: case O_MULT: return "*";
27: case O_DIV: return "/";
28: case O_CALL: return "()";
29: case O_MOD: return "%";
30: case O_ASSIGN: return "=";
31: case O_COMMA: return ",";
32: case O_SIZEOF: return "sizeof";
33: case O_TYPEOF: return "typeof";
34: case O_QINDEX: return "[?]";
35: case O_CAST: return "(cast)";
36: case O_QCAST: return " ?";
37: case O_QSTRUCT: return "struct ?";
38: case O_QENUM: return "enum ?";
39: case O_EQ: return "==";
40: case O_NE: return "!=";
41: case O_LT: return "<";
42: case O_GT: return ">";
43: case O_LE: return "<=";
44: case O_GE: return ">=";
45: case O_LOGAND: return "&&";
46: case O_LOGOR: return "||";
47: case O_LOGNOT: return "!";
48: case O_BITAND: return "&";
49: case O_BITOR: return "|";
50: case O_BITXOR: return "^";
51: case O_1SCOMP: return "~";
52: case O_FABS: return "fabs";
53: case O_ENV: return "{}";
54: case O_RANGE: return "..";
55: case O_SPECIAL: return "special";
56: case O_LSHIFT: return "<<";
57: case O_RSHIFT: return ">>";
58: default: return Name( "Op=%d", op );
59: }
60: }
61:
62: int Prec( Op op ) /* for Expr::text() - not gram.y */
63: {
64: switch(op){
65: case O_ENV: return 1;
66: case O_CALL:
67: case O_INDEX:
68: case O_DOT:
69: case O_ARROW: return 2;
70: case O_MULT:
71: case O_DIV:
72: case O_MOD: return 3;
73: case O_PLUS:
74: case O_MINUS: return 4;
75: case O_LSHIFT:
76: case O_RSHIFT: return 5;
77: case O_LT:
78: case O_GT:
79: case O_LE:
80: case O_GE: return 6;
81: case O_EQ:
82: case O_NE: return 7;
83: case O_BITAND: return 8;
84: case O_BITXOR: return 9;
85: case O_BITOR: return 10;
86: case O_LOGAND: return 11;
87: case O_LOGOR: return 12;
88: case O_ASSIGN: return 13;
89: case O_COMMA: return 14;
90: case O_RANGE: return 15;
91: default: return 16;
92: }
93: }
94:
95: Expr *E_Id(char *id ) { return new Expr(E_ID,0,0,0,0,id,0,0); }
96:
97: Expr *E_Sym(Symbol *s ) { return new Expr(E_SYMNODE,0,0,0,0,0,0,s); }
98:
99: Expr *E_Unary(Op unary, Expr *sub) { return new Expr(E_UNARY,unary,sub,0,0,0,0,0); }
100:
101: Expr *E_Binary(Expr*l,Op binary,Expr*r)
102: { return new Expr(E_BINARY,binary,l,r,0,0,0,0); }
103:
104: Expr *E_IConst(long i) { return new Expr(E_LCONST,0,0,0,i,Token,LONG,0); }
105:
106: Expr *E_DConst(double d) { return new Expr(E_DCONST,0,0,0,d,Token,DOUBLE,0); }
107:
108: char *Expr::floaterror()
109: {
110: return val.floaterror();
111: }
112:
113: char *Expr::under(Expr *e)
114: {
115: if( e->edisc != E_BINARY || Prec(e->op) < Prec(op) ) return e->text();
116: return sf( "(%s)", e->text() );
117: }
118:
119: Expr::Expr() {}
120:
121: Expr::Expr( EDisc d, Op o, Expr* s1, Expr* s2, Cslfd c, char* s, int t, Symbol *v)
122: {
123: type.pcc = t;
124: edisc = d;
125: op = o;
126: sub1 = s1;
127: sub2 = s2;
128: val = c;
129: id = s ? sf("%s",s) : "";
130: sym = v;
131: evalerr = 0;
132: spy = 0;
133: addr = 0;
134: bitaddr = 0;
135: trace( "Expr(edisc=%d,op=%s,sub1=%d,sub2=%d,val.lng=%d,id=%s,symbol=%d",
136: edisc, OpName(op), sub1, sub2, val.lng, id?id:"", v);
137: }
138:
139: char *Expr::left(Expr *e)
140: {
141: switch( e->edisc ){
142: case E_BINARY: switch( e->op ){
143: case O_INDEX:
144: case O_DOT:
145: case O_ARROW: return e->text();
146: }
147: case E_UNARY: return sf( "(%s)", e->text() );
148: default: return e->text();
149: }
150: }
151:
152: char *Expr::textunary()
153: {
154: trace( "%d.textunary()", this ); OK("textunary");
155: switch( op ){
156: case O_QCAST:
157: case O_QSTRUCT:
158: case O_QENUM:
159: return sf("(%0.*s%s )%s",val.lng,"*******",OpName(op),sub1->text());
160: case O_CAST:
161: return sf("(%s)%s",type.text(),sub1->text());
162: case O_QINDEX:
163: return sf( "%s[ ? ]", left(sub1) );
164: case O_SIZEOF:
165: case O_TYPEOF:
166: case O_FABS:
167: case O_SPECIAL:
168: return sf( "%s(%s)", OpName(op), sub1->text() );
169: }
170: if( sub1->edisc==E_BINARY && Prec(sub1->op)>=Prec(O_MULT) )
171: return sf( "%s(%s)", OpName(op), sub1->text() );
172: return sf( "%s%s", OpName(op), sub1->text() );
173: }
174:
175: char *Expr::textbinary()
176: {
177: trace( "%d.textbinary()", this ); OK("textbinary");
178: switch( op ){
179: case O_ENV:
180: return sf( "{%s}%s", sub1->text(), sub2->text() );
181: case O_COMMA: /* ??? */
182: return sf( "%s,%s", sub1->text(), sub2->text() );
183: case O_CALL:
184: return sf( "%s(%s)", sub1->text(), sub2?sub2->text():"" );
185: case O_ASSIGN:
186: return sf("(%s:=%s)", left(sub1), sub2->text() );
187: case O_INDEX:
188: return sf("%s[%s]", left(sub1), sub2->text() );
189: case O_DOT:
190: case O_ARROW:
191: return sf("%s%s%s", left(sub1), OpName(op), sub2->text());
192: }
193: if( sub1->edisc==E_BINARY && Prec(sub1->op) == Prec(op) )
194: return sf("%s%s%s", sub1->text(), OpName(op), under(sub2));
195: return sf("%s%s%s", under(sub1), OpName(op), under(sub2));
196: }
197:
198: char *Expr::text()
199: {
200: trace( "%d.text()", this ); OK("text");
201: switch( edisc ){
202: case E_DCONST: if( !id || !*id ) return sf( "%g", val.dbl );
203: case E_LCONST: if( !id || !*id ) return sf( "%d", val.lng );
204: case E_ID: return id;
205: case E_UNARY: return textunary();
206: case E_BINARY: return textbinary();
207: case E_SYMNODE:
208: if( !sym || !sym->_text ) return "<symbol>";
209: return sym->_text;
210: }
211: return "<expr>";
212: }
213:
214: int Expr::format()
215: {
216: trace( "%d.format() %s %s", this, text(), type.text() ); OK(F_HEX);
217: return type.format();
218: }
219:
220: void Expr::reformat(int over, int stars)
221: {
222: trace("%d.reformat(0x%X,%d) %s %s",this,over,stars,text(),type.text()); VOK;
223: switch( edisc ){
224: case E_ID: break; // shut up cfront
225: case E_LCONST:
226: case E_DCONST:
227: type.reformat(over);
228: return;
229: case E_SYMNODE:
230: IF_LIVE(!sym) return;
231: ((Var*)sym)->type.reformat(over,stars);
232: return;
233: case E_UNARY:
234: switch( op ){
235: case O_REF:
236: case O_SIZEOF:
237: case O_CAST:
238: type.reformat(over,stars);
239: return;
240: case O_DEREF:
241: sub1->reformat(over,stars+1);
242: return;
243: case O_MINUS:
244: case O_1SCOMP:
245: case O_LOGNOT:
246: sub1->reformat(over,stars);
247: return;
248: }
249: case E_BINARY:
250: switch( op ){
251: case O_DIV:
252: case O_MULT:
253: case O_MOD:
254: case O_PLUS:
255: case O_MINUS:
256: case O_BITAND:
257: case O_BITOR:
258: case O_BITXOR:
259: sub1->reformat(over,stars); /* fall thru */
260: case O_ARROW:
261: case O_DOT:
262: case O_COMMA:
263: sub2->reformat(over,stars);
264: return;
265: case O_ASSIGN:
266: case O_ENV:
267: case O_LSHIFT:
268: case O_RSHIFT:
269: sub1->reformat(over,stars);
270: return;
271: case O_INDEX:
272: sub1->reformat(over,stars+1);
273: return;
274: case O_CALL:
275: Func *func = (Func*) sub1->sym;
276: if( func->ok() )
277: func->type.decref()->reformat(over,stars);
278: return;
279: }
280: }
281: }
282:
283: char *Expr::ascii(Frame *frame, int limit )
284: {
285: static char buf[256];
286: char *raw, *fail = "fail"; // fail is unique
287: Bls esc( "\"" );
288: int i;
289:
290: trace("%d.ascii(%d)", this, frame); OK("ascii");
291: if( !val.lng ) return "0";
292: raw = frame->peekstring(val.lng, fail);
293: if( raw == fail ) return "<string error>";
294: for( i = 0; raw[i] && i<limit; ++i )
295: esc.af( "%s", FmtByte(raw[i]) );
296: if( raw[i] ) esc.af("...");
297: sprintf(buf, "%s\"", esc.text);
298: return buf;
299: }
300:
301: char *Expr::enumformat()
302: {
303: Var *m;
304:
305: trace( "%d.enumformat()", this ); OK("enumformat");
306: TypMems tm(type.utype());
307: while( m = tm.gen() )
308: if( m->range.lo == val.lng )
309: return m->text();
310: return sf( "(enum %s)%d", type.utype()?type.utype()->text():"?", val.lng );
311: }
312:
313: char *Expr::utypeformat(Frame *frame, Bls &build)
314: {
315: Var *m, g(0,0,0,0,"$pi.Expr::utypeformat");
316: int i = 0;
317: Expr e; /* use constructor to guarantee zeros? */
318:
319: trace("%d.utypeformat(%d,%d)", this, frame, &build); OK("utypeformat");
320: build.af("{");
321: TypMems tm(type.utype());
322: while( m = tm.gen() ) if( m->showorhide==SHOW ){
323: Bls local;
324: g = *m;
325: g._disc = U_GLB;
326: DType t = g.type;
327: e.bitaddr = 0;
328: if( t.pcc==BITS || t.pcc==UBITS ){
329: e.bitaddr = g.range.lo;
330: g.range.lo = 0;
331: }
332: g.range.lo += addr;
333: e.edisc = E_SYMNODE;
334: e.sym = &g;
335: e.spy = 0;
336: e.op = 0;
337: build.af( "%s%s", i++?",":"", e.evaltext(frame,local) );
338: }
339: build.af( "}" );
340: return build.text;
341: }
342:
343: char *Expr::evaltextcomma(Frame *frame, Bls &build)
344: {
345: trace("%d.evaltextcomma(%d,%d)",this,frame,&build);OK("evaltextcomma");
346: sub1->evaltext(frame,build);
347: if( evalerr = sub1->evalerr ) return build.text;
348: build.af(", ");
349: sub2->evaltext(frame,build);
350: evalerr = sub2->evalerr;
351: type = sub2->type;
352: val = sub2->val;
353: return build.text;
354: }
355:
356: char *Expr::evaltext(Frame *frame, Bls &build)
357: {
358: trace( "%d.evaltext(%d,%d)", this, frame, &build ); OK("evaltext");
359: evalerr = 0;
360: doevaltext(frame, build);
361: if( evalerr ) setspy(0);
362: if( spy ) spy->b = build.text;
363: return build.text;
364: }
365:
366: char *Expr::doevaltext(Frame *frame, Bls &build)
367: {
368: char *error, *t;
369: Format form(0, frame->core->symtab());
370:
371: trace( "%d.doevaltext(%d,%d)", this, frame, &build ); OK("doevaltext");
372: switch( op ){
373: case O_QINDEX:
374: case O_QCAST:
375: case O_QENUM:
376: case O_QSTRUCT:
377: build.af( "%s", text() );
378: return build.text;
379: }
380: if( op == O_COMMA ) return evaltextcomma(frame,build);
381: if( error = eval(frame) ){
382: build.af( "%s: %s", text(), error );
383: evalerr = 1;
384: return build.text;
385: }
386: if( spy ) build.af(">>> ");
387: build.af( "%s", text() );
388: if( type.pcc == VOID ){
389: build.af( "=void" );
390: return build.text;
391: }
392: form.format = format();
393: if( form.format&(F_DOUBLE|F_FLOAT) && val.floaterror() ){
394: build.af( "=<%s>", val.floaterror() );
395: form.format &= ~(F_DOUBLE|F_FLOAT);
396: form.format |= F_NONE;
397: }
398: if( form.format&F_ARY ) val.lng = addr;
399: if( *(t = form.f(val.lng,val.dbl)) )
400: build.af( "=%s", t );
401: if( form.format&F_UTYPE ){
402: build.af( "=");
403: utypeformat(frame,build);
404: }
405: if( form.format&F_ENUM )
406: build.af( "=%s", enumformat() );
407: if( form.format&F_STRING )
408: build.af( "=%s", ascii(frame, form.format&F_LONGSTRING?200:20) );
409: return build.text;
410: }
411:
412: char *Expr::getval( Frame *frame ) /* addr already fixed */
413: {
414: trace( "%d.getval(%d)", this, frame ); OK("getval");
415: if( sym ){
416: switch( sym->disc() ){
417: case U_FUNC:
418: type = ((Func*)sym)->type;
419: break;
420: default:
421: type = ((Var*)sym)->type;
422: ((Var*)sym)->show(SHOW);
423: }
424: }
425: if( !addr ) return "addressing error: 0";
426: addr += (bitaddr>>5)*4;
427: if( type.isscalar() ){
428: Cslfd *m = frame->peek(addr,0);
429: if( !m ) return sf( "addressing error: 0x%X", addr );
430: val = *m;
431: }
432: if( type.isscalar() ) switch( type.pcc ){
433: case BITS:
434: case UBITS: val.lng = (val.lng>>(bitaddr&31));
435: int power = 1<<type.dim;
436: val.lng &= power-1;
437: if( type.pcc==BITS && val.lng&(power>>1) )
438: val.lng |= ~(power-1);
439: addr = 0; break;
440: case CHAR: val.lng = (char) val.chr; break;
441: case UCHAR: val.lng = (unsigned char) val.chr; break;
442: case SHORT: val.lng = (short) val.sht; break;
443: case USHORT: val.lng = (unsigned short) val.sht; break;
444: case FLOAT: val.dbl = val.flt; break;
445: }
446: trace( "%s %d %d %s", sym?sym->_text:"", addr, val.lng, type.text() );
447: return 0;
448: }
449:
450: char *Expr::invalidoperands(char *more)
451: {
452: trace( "%d.invalidoperands()", this ); OK("invalidoperands");
453: char *colon = more ? ": " : "";
454: if( !more ) more = "";
455: return sf( "invalid operand(s) of %s%s%s", OpName(op), colon, more );
456: }
457:
458: char *Expr::eval(Frame *frame)
459: {
460: trace( "%d.eval(%d)", this, frame ); OK("eval");
461: switch(op){
462: case O_QINDEX:
463: case O_QCAST:
464: case O_QSTRUCT:
465: case O_QENUM:
466: return "? stops evaluation";
467: }
468: switch( edisc ){
469: case E_DCONST:
470: case E_LCONST:
471: return 0; /* should all be there! */
472: case E_UNARY:
473: return evalunary(frame);
474: case E_BINARY:
475: return evalbinary(frame);
476: case E_ID:
477: if( !(sym = frame->idtosym(id)) )
478: return enumid(frame);
479: edisc = E_SYMNODE; /* fall thru */
480: case E_SYMNODE:
481: if( !sym ) return "symbol table error";
482: addr = frame->locate((Var*)sym);
483: return getval(frame);
484: default:
485: return "not an expression";
486: }
487: }
488:
489: char *Expr::enumid(Frame *frame)
490: {
491: trace("%d.enumid(%s)", this, id); OK("enumid");
492: UType *u; Var *v;
493: for( u = frame->symtab()->utypelist(); u; u = (UType*) u->rsib ){
494: if( u->type.pcc != ENUMTY ) continue;
495: TypMems tm(u);
496: while( v = tm.gen() ) if( !strcmp(id, v->_text) ){
497: edisc = E_LCONST;
498: val.lng = v->range.lo;
499: addr = 0;
500: type.pcc = LONG;
501: return 0;
502: }
503: }
504: return sf("not found: %s", id);
505: }
506:
507: char *Expr::evalindex(Frame *frame, Expr *ap, long i)
508: {
509: long size = 0;
510:
511: trace( "%d.index(%d,%d,%d)", this, frame, ap, i); OK("evalindex");
512: if( ap && ap->type.decref() ){
513: type = *ap->type.decref();
514: size = type.size_of();
515: }
516: if( !size ) return "cannot determine size for []";
517: addr = ap->type.isptr() ? ap->val.lng : ap->addr;
518: if( !addr ) return "zero pointer for []";
519: addr += size * i;
520: return getval(frame);
521: }
522:
523: char *Expr::evaldotarrow(Frame *frame)
524: {
525: DType t;
526:
527: trace( "%d.evaldotarrow(%d)", this, frame ); OK("evaldotarrow");
528: addr = 0;
529: t = sub1->type;
530: if( op == O_DOT )
531: addr = sub1->addr;
532: else {
533: if( !t.isptr() ) return invalidoperands("not a pointer");
534: t = *t.decref();
535: addr = sub1->val.lng;
536: }
537: if( !t.isstrun() ) return invalidoperands("not a struct/union");
538: if( !addr ) return invalidoperands("zero address");
539: if( sub2->edisc == E_ID && t.utype() ){
540: TypMems tm(t.utype());
541: while( sub2->sym = tm.gen() )
542: if( !strcmp(sub2->sym->text(), sub2->id) ) break;
543: if( !sub2->sym ) return sf("not found: %s", sub2->id);
544: sub2->edisc = E_SYMNODE;
545: }
546: if( sub2->edisc != E_SYMNODE ) return invalidoperands();
547: sym = sub2->sym;
548: t = ((Var*)sym)->type;
549: if( t.pcc==BITS || t.pcc==UBITS )
550: bitaddr = sym->range.lo;
551: else
552: addr += sym->range.lo;
553: return getval(frame);
554: }
555:
556: Expr *Expr::actual(int a)
557: {
558: int m;
559: trace( "%d.actual(%d)", this, a );
560: if( !this ) return 0;
561: if( op != O_COMMA ) return a == 1 ? this : 0;
562: for( m = 0; sub1->actual(m+1); ++m ) {}
563: return a<=m ? sub1->actual(a) : sub2->actual(a-m);
564: }
565:
566: char *Expr::evalcall(Frame *frame)
567: {
568: char *error = 0;
569: long i, nargs = 1, argwords = 0, regloc;
570: Var *formal;
571: Func *func;
572: Frame *called = 0;
573:
574: trace( "%d.evalcall(%d)", this, frame ); OK("evalcall");
575: if( !sub1 )return "<fcn call>";
576: switch( sub1->edisc ){
577: default: return "<fcn call>";
578: case E_ID:
579: sub1->sym = frame->symtab()->idtosym( U_FUNC, sub1->id );
580: case E_SYMNODE:
581: func = (Func*) sub1->sym;
582: }
583: if( !func ) return sf( "not a function: %s", sub1->id );
584: while( sub2->actual(nargs) )
585: if( !(formal = func->argument(nargs)) )
586: return "too many args in function call";
587: else {
588: argwords += (formal->type.size_of()+3)/4; /* vax & 32 */
589: ++nargs;
590: }
591: if( func->argument(nargs) )
592: return "too few args in function call";
593: --nargs;
594: Core *core = frame->core;
595: if( !core->online() )
596: return "cannot call function in dump";
597: Context *cc = core->newContext();
598: if( cc->error ){
599: delete cc;
600: return cc->error;
601: }
602: called = new Frame(core);
603: called->ap = core->apforcall(argwords*4);
604: if( !called->ap )
605: { error = "function calling is broken"; goto Restore; }
606: for( i = 1; i <= nargs; ++i ){
607: Expr *e;
608: e = E_Binary(E_Sym(func->argument(i)), O_ASSIGN, sub2->actual(i));
609: if( error = e->sub1->eval(called) )
610: { error = sf("formal arg: %s", error); goto Restore; }
611: if( error = e->sub2->eval(frame) )
612: { error = sf("actual arg: %s", error); goto Restore; }
613: if( error = e->evalassign(called) )
614: { error = sf("arg assign: %s", error); goto Restore; }
615: }
616: if( error = core->docall(func->range.lo, argwords) )
617: goto Restore;
618: type = *func->type.decref();
619: regloc = core->returnregloc();
620: if( !regloc)
621: { error = "function return error"; goto Restore; }
622: if( type.isstrun() )
623: switch( type.size_of() ){
624: case 1:
625: case 2:
626: case 4: addr = regloc;
627: break;
628: default:
629: addr = core->peek(regloc)->lng;
630: }
631: else
632: val = *core->peek(regloc); /* doubles? */
633: Restore:
634: if( called ) delete called;
635: cc->restore();
636: if( cc->error && !error )
637: error = cc->error;
638: delete cc;
639: return error;
640: }
641:
642: char *Expr::evalenv(Frame *frame)
643: {
644: Frame *env = frame ? frame->caller() : 0;
645: char *error;
646:
647: trace( "%d.evalenv(%d)", this, frame ); OK("evalenv");
648: for( ; env; env = env->caller() )
649: if( !strcmp(env->func->_text,sub2->text()) )
650: break;
651: if( !env ){
652: Frame sta(frame->core);
653: sta.func = (Func*) sta.core->symtab()->idtosym(U_FUNC,sub2->text());
654: if( sta.func ) env = &sta;
655: }
656: if( !env ) return sf( "not found: %s()", sub2->text() );
657: if( error = sub1->eval(env) ) return error;
658: type = sub1->type;
659: val = sub1->val;
660: addr = sub1->addr;
661: return 0;
662: }
663:
664: char *Expr::evalrange()
665: {
666: const int range = 32;
667: trace( "%d.evalrange()", this ); OK("evalrange");
668: if( !sub1->type.isintegral()
669: || !sub2->type.isintegral()
670: || sub2->val.lng < sub1->val.lng )
671: return invalidoperands();
672: if( sub2->val.lng > sub1->val.lng+range )
673: return sf( "range may not exceed %d", range );
674: return 0;
675: }
676:
677: void Expr::catchfpe() /* VAX: put down operands that must succeed */
678: { /* and restart the instruction */
679: *fp1 = *fp2 = 1.0;
680: fpe = "floating point exception";
681: }
682:
683: char *Expr::evalflop() /* VAX host */
684: {
685: char *error;
686: trace( "%d.evalflop()", this ); OK("evalflop");
687: if( !sub1->type.isreal() || !sub2->type.isreal() )
688: return invalidoperands();
689: if( (error = sub1->floaterror())
690: || (error = sub2->floaterror()) )
691: return invalidoperands(error);
692: type.pcc = DOUBLE;
693: double l = sub1->val.dbl; double r = sub2->val.dbl;
694: fp1 = &l;
695: fp2 = &r;
696: fpe = 0;
697: signal(SIGFPE, (SIG_TYP)&Expr::catchfpe);
698: switch( op ){
699: case O_MULT: val.dbl = l*r; break;
700: case O_DIV: val.dbl = l/r; break;
701: case O_PLUS: val.dbl = l+r; break;
702: case O_MINUS: val.dbl = l-r; break;
703: }
704: signal(SIGFPE, (SIG_TYP)SIG_DFL);
705: return fpe;
706: }
707:
708: char *Expr::evalbinary(Frame *frame)
709: {
710: char *error;
711: long size;
712:
713: trace( "%d.evalbinary(%d)", this, frame ); OK("evalbinary");
714: IF_LIVE( edisc!=E_BINARY ) return "<binary expr>";
715: switch( op ){
716: case O_CALL: return evalcall(frame);
717: case O_ENV: return evalenv(frame);
718: }
719: if( error = sub1->eval(frame) ) return error;
720: type.pcc = LONG;
721: type.over = sub1->type.over;
722: if( op==O_DOT || op==O_ARROW ) return evaldotarrow(frame);
723: if( (sub1->type.isintegral() && op==O_LOGAND && !sub1->val.lng)
724: || (sub1->type.isintegral() && op==O_LOGOR && sub1->val.lng) ){
725: val = sub1->val.lng != 0;
726: return 0;
727: }
728: if( error = sub2->eval(frame) ) return error;
729: type.over |= sub2->type.over;
730: switch( op ){
731: case O_RANGE:
732: return evalrange();
733: case O_COMMA:
734: type = sub2->type;
735: val = sub2->val;
736: return 0;
737: case O_ASSIGN:
738: return evalassign(frame);
739: case O_MULT:
740: case O_DIV:
741: if( sub1->type.isreal() || sub2->type.isreal() )
742: return evalflop();
743: case O_MOD:
744: if( sub1->type.isintegral() && sub2->type.isintegral() ){
745: long l = sub1->val.lng, r = sub2->val.lng;
746: if( op==O_MULT ){
747: val.lng = l * r;
748: return 0;
749: }
750: if( r == 0 ) return "zero divide";
751: if( op == O_MOD ) val.lng = l % r;
752: if( op == O_DIV ) val.lng = l / r;
753: return 0;
754: }
755: return invalidoperands();
756: case O_LOGAND:
757: case O_LOGOR:
758: case O_BITAND:
759: case O_BITOR:
760: case O_BITXOR:
761: case O_LSHIFT:
762: case O_RSHIFT:
763: if( sub1->type.isscalar() && sub2->type.isscalar() ){
764: long l = sub1->val.lng, r = sub2->val.lng;
765: switch( op ){
766: case O_LOGAND: val.lng = l && r; return 0;
767: case O_LOGOR: val.lng = l || r; return 0;
768: case O_BITAND: val.lng = l & r; return 0;
769: case O_BITOR: val.lng = l | r; return 0;
770: case O_BITXOR: val.lng = l ^ r; return 0;
771: case O_LSHIFT: val.lng = l << r; return 0;
772: case O_RSHIFT: val.lng = l >> r; return 0;
773: }
774: return "internal error: && || & | ^ >> <<";
775: }
776: return invalidoperands();
777: case O_EQ:
778: case O_NE:
779: case O_LT:
780: case O_GT:
781: case O_LE:
782: case O_GE:
783: type.pcc = LONG;
784: if( sub1->type.isreal() || sub2->type.isreal() ){
785: if( !sub1->type.isreal() || sub1->floaterror()
786: || !sub2->type.isreal() || sub2->floaterror() )
787: return invalidoperands();
788: double l = sub1->val.dbl; double r = sub2->val.dbl; /*C++*/
789: switch( op ){
790: case O_EQ: val.lng = l == r; return 0;
791: case O_NE: val.lng = l != r; return 0;
792: case O_LT: val.lng = l < r; return 0;
793: case O_GT: val.lng = l > r; return 0;
794: case O_LE: val.lng = l <= r; return 0;
795: case O_GE: val.lng = l >= r; return 0;
796: }
797: return "internal floating relation error";
798: }
799: if( sub1->type.isscalar() && sub2->type.isscalar() ){
800: long l = sub1->val.lng, r = sub2->val.lng;
801: switch( op ){
802: case O_EQ: val.lng = l == r; return 0;
803: case O_NE: val.lng = l != r; return 0;
804: case O_LT: val.lng = l < r; return 0;
805: case O_GT: val.lng = l > r; return 0;
806: case O_LE: val.lng = l <= r; return 0;
807: case O_GE: val.lng = l >= r; return 0;
808: }
809: return "internal fixed point relation error";
810: }
811: return invalidoperands();
812: case O_PLUS:
813: case O_MINUS:
814: if( sub1->type.isreal() || sub2->type.isreal() )
815: return evalflop();
816: if( sub1->type.isary() ){
817: sub1->val.lng = sub1->addr;
818: sub1->type = sub1->type.decref()->incref();
819: }
820: if( sub2->type.isary() ){
821: sub2->val.lng = sub2->addr;
822: sub2->type = sub2->type.decref()->incref();
823: }
824: if( sub1->type.isptr() && sub2->type.isintegral() ){
825: size = sub1->type.decref()->size_of();
826: if( !size ) return "pointer arithmetic error";
827: if( op == O_MINUS ) size = -size;
828: val.lng = sub1->val.lng + size*sub2->val.lng;
829: type = sub1->type;
830: return 0;
831: }
832: if( sub1->type.isintegral() && sub2->type.isintegral() ){
833: if( op==O_PLUS ) val.lng = sub1->val.lng+sub2->val.lng;
834: if( op==O_MINUS) val.lng = sub1->val.lng-sub2->val.lng;
835: return 0;
836: }
837: if( op == O_PLUS && sub2->type.isptr() && sub1->type.isintegral() ){
838: size = sub2->type.decref()->size_of();
839: if( !size ) return "pointer arithmetic error";
840: val.lng = sub2->val.lng + size*sub1->val.lng;
841: type = sub2->type;
842: return 0;
843: }
844: if( op == O_MINUS && sub1->type.isptr() && sub2->type.isptr() ){
845: size = sub1->type.decref()->size_of();
846: if( !size || size!=sub2->type.decref()->size_of() )
847: return "pointer-pointer size error";
848: val.lng = (sub1->val.lng - sub2->val.lng)/size;
849: type.over |= sub2->type.over;
850: return 0;
851: }
852: return invalidoperands();
853: case O_INDEX:
854: trace( "%s %s", sub1->type.text(), sub2->type.text() );
855: if( sub1->type.isaryorptr() && sub2->type.isintegral() )
856: return evalindex(frame,sub1,sub2->val.lng);
857: if( sub2->type.isaryorptr() && sub1->type.isintegral() )
858: return evalindex(frame,sub2,sub1->val.lng);
859: return invalidoperands();
860: default:
861: return "binary operator not implemented";
862: }
863: }
864:
865: char *Expr::evalcast()
866: {
867: trace( "%d.evalcast()", this, ); OK("<cast>");
868: IF_LIVE( !type.isscalar() || !sub1->type.isscalar() ) return "cast error";
869: if( type.isptr() ){
870: if( sub1->type.isreal() ) return "can't cast float to ptr";
871: val.lng = sub1->val.lng;
872: return 0;
873: }
874: if( type.isreal() ){
875: if( sub1->floaterror() ) return sub1->floaterror();
876: val.dbl = sub1->val.dbl;
877: if( !sub1->type.isreal() ) val.dbl = sub1->val.lng;
878: return 0;
879: }
880: val.lng = sub1->val.lng;
881: switch( sub1->type.pcc ){
882: case CHAR: val.lng = sub1->val.chr; break;
883: case SHORT: val.lng = sub1->val.sht; break;
884: }
885: addr = sub1->addr;
886: if( sub1->type.isreal() ){
887: if( sub1->floaterror() ) return sub1->floaterror();
888: val.lng = (long) sub1->val.dbl;
889: }
890: return 0;
891: }
892:
893: char *Expr::evalunary(Frame *frame)
894: {
895: char *error;
896:
897: trace( "%d.evalunary(%d)", this, frame ); OK("<unary expr>");
898: IF_LIVE( edisc!=E_UNARY ) return "<unary expr>";
899: if( error = sub1->eval(frame) ) return error;
900: switch( op ){
901: case O_SPECIAL:
902: type = sub1->type;
903: addr = sub1->addr;
904: val = sub1->val;
905: if( type.isptr() ){
906: type = *type.decref();
907: addr = val.lng;
908: }
909: if( !type.pcc == STRTY || !type.utype() || !addr )
910: return invalidoperands();
911: error = frame->special( type.utype()->text(), addr );
912: { // cfront bug
913: DType nulltype;
914: type = nulltype;
915: } // cfront bug
916: type.pcc = VOID;
917: addr = 0;
918: return error;
919: case O_1SCOMP:
920: case O_LOGNOT:
921: if( !sub1->type.isscalar() || sub1->type.isreal() )
922: return invalidoperands();
923: type.pcc = LONG;
924: if( op == O_1SCOMP ) val.lng = ~sub1->val.lng;
925: if( op == O_LOGNOT ) val.lng = !sub1->val.lng;
926: return 0;
927: case O_FABS:
928: { // cfront bug
929: double fabs(double);
930: if( !sub1->type.isreal() || sub1->floaterror() )
931: return invalidoperands();
932: type.pcc = DOUBLE;
933: val.dbl = fabs(sub1->val.dbl); /* cannot fail? */
934: return 0;
935: } // cfront bug
936: case O_MINUS:
937: if( sub1->type.isintegral() ){
938: type.pcc = LONG;
939: val.lng = -sub1->val.lng;
940: return 0;
941: }
942: if( sub1->type.isreal() && !sub1->floaterror() ){
943: type.pcc = DOUBLE;
944: val.dbl = -sub1->val.dbl;
945: return 0;
946: }
947: return invalidoperands();
948: case O_CAST:
949: return evalcast();
950: case O_SIZEOF:
951: addr = 0;
952: if( !(val.lng = sub1->type.size_of())) return "sizeof error";
953: type.pcc = UNSIGNED;
954: return 0;
955: case O_TYPEOF:
956: return sub1->type.text();
957: case O_DEREF:
958: if( !sub1->type.isptr() ) return "unary * applied to non-pointer";
959: addr = sub1->val.lng;
960: type = *sub1->type.decref();
961: return getval(frame);
962: case O_REF:
963: if( !sub1->addr ) return "unary & applied to non-lvalue";
964: addr = 0;
965: int o = type.over;
966: type = sub1->type.incref();
967: type.over = o;
968: val.lng = sub1->addr;
969: return 0;
970: default:
971: return "unary operator not implemented";
972: }
973: }
974:
975: Index Expr::castcarte()
976: {
977: static Index *ix;
978: static short bt[] = { DOUBLE, FLOAT, LONG, SHORT, CHAR, 0 };
979: Menu m;
980: DType *base, *ptr;
981:
982: trace( "%d.castcarte()", this ); OK(ZIndex);
983: if (!ix)
984: ix = new Index(0,0);
985: if( !ix->null() ) return *ix;
986: Action a = (Action)&Phrase::applycast;
987: int t;
988: for( t = 0; bt[t]; ++t ){
989: base = new DType();
990: base->pcc = bt[t];
991: ptr = new DType;
992: *ptr = base->incref();
993: m.first( sf( "%s\240", ptr->text() ), a, (long) ptr );
994: m.first( sf( " %s\240", base->text()), a, (long) base );
995: }
996: Action i = (Action)&Phrase::increfcast;
997: Action e = (Action)&Phrase::enumcast;
998: Action s = (Action)&Phrase::strcast;
999: m.last( " * ? ", i, 1 );
1000: m.last( " enum ? ", e, 0 );
1001: m.last( " *struct ? ", s, 1 );
1002: return *ix = m.index("cast $");
1003: }
1004:
1005: Index Expr::carte(Frame *f)
1006: {
1007: Menu m;
1008:
1009: trace( "%d.carte()", this ); OK(ZIndex);
1010: m.last( "eval $", (Action)&Phrase::evaluate );
1011: if( evalerr || op==O_TYPEOF )
1012: return m.index();
1013: switch( op ){
1014: case O_QCAST:
1015: return castcarte();
1016: case O_QSTRUCT:
1017: return f ? f->symtab()->utypecarte(STRTY) : ZIndex;
1018: case O_QENUM:
1019: return f ? f->symtab()->utypecarte(ENUMTY) : ZIndex;
1020: case O_QINDEX:
1021: return NumericRange( -2, 20 );
1022: }
1023: if( !spy )
1024: m.first( "spy on $", (Action) &Phrase::setspy, 1 );
1025: else
1026: m.first( "unspy $", (Action) &Phrase::setspy, 0 );
1027: if( addr ) m.last( "& $", (Action)&Phrase::applyunary, (long)O_REF );
1028: if( val.lng )
1029: m.last( "mem .=$ ", (Action)&Phrase::memory );
1030: if( type.isscalar() ) m.last(castcarte());
1031: m.last(type.carte());
1032: return m.index();
1033: }
1034:
1035: void Expr::setspy(long s)
1036: {
1037: trace( "%d.setspy(%d)", this, s ); VOK;
1038: if( !s && spy ){
1039: delete spy;
1040: spy = 0;
1041: } else if( s )
1042: spy = new Spy;
1043: }
1044:
1045: char *Expr::evalassign(Frame *frame)
1046: {
1047: char *error;
1048:
1049: trace( "%d.evalassign(%d)", this, frame ); OK("evalassign");
1050: if( !sub1->addr ) return "lhs of = does not yield an lvalue";
1051: if( sub2->type.isary() && sub2->addr ){
1052: sub2->type.pcc = PTR;
1053: sub2->val.lng = sub2->addr;
1054: }
1055: if( sub1->type.isscalar() && sub2->type.isscalar() ){
1056: DType type1 = sub1->type, type2 = sub2->type;
1057: long addr1 = sub1->addr, size1 = type1.size_of();
1058: Cslfd *val2 = &sub2->val;
1059: if( type1.isreal() || type1.isreal() ){
1060: if( !type1.isreal() || !type2.isreal() )
1061: return invalidoperands("mixed mode");
1062: error = frame->pokedbl(addr1, val2->dbl, type1.size_of());
1063: } else
1064: error = frame->poke(addr1, val2->lng, type1.size_of());
1065: if( error )
1066: return sf( "%s: 0x%X", error, sub1->addr );
1067: if( error = sub1->eval(frame) )
1068: return error;
1069: type = sub1->type;
1070: val = sub1->val;
1071: addr = 0;
1072: return 0;
1073: }
1074: if( sub1->type.isstrun() && sub2->type.isstrun() ){
1075: UType *u1 = sub1->type.utype(), *u2 = sub2->type.utype();
1076: if( !u1
1077: || !u2
1078: || u1->type.pcc != u2->type.pcc
1079: || strcmp(u1->type.text(), u2->type.text()) )
1080: return "incompatible struct/union =";
1081: if( !sub2->addr )
1082: return "rhs of struct/union = does not yield an lvalue";
1083: error = frame->blockmove(sub2->addr,sub1->addr,u1->type.size_of());
1084: type = sub1->type;
1085: val = 0;
1086: addr = sub1->addr;
1087: return error;
1088: }
1089: return "invalid asssignment";
1090: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.