|
|
1.1 root 1: #include "expr.pri"
2: #include "phrase.pri"
3: #include "frame.pub"
4: #include "parse.h"
5: #include "format.pub"
6: SRCFILE("phrase.c")
7: /* next three are for Phrase::memory() ! */
8: #include "symtab.pub"
9: #include "symbol.h"
10: #include "core.pub"
11: #include "process.pub"
12:
13: Phrase::Phrase(Frame *f, Phrase *s, Expr *e, long k)
14: {
15: trace( "%d.Phrase(%d,%d,%d,%d)", this, f, s, e, k );
16: frame = f;
17: sib = s;
18: expr = e;
19: key = k;
20: }
21:
22: Pad *Phrase::pad() { OK(0); return frame->pad; }
23:
24: void Phrase::setspy(long s)
25: {
26: trace( "%d.setspy(%d)", this, s ); VOK;
27: expr->setspy(s);
28: evaluate();
29: }
30:
31: void Phrase::reformat(int over)
32: {
33: trace( "%d.reformat(%d)", this, over ); VOK;
34: expr->reformat(over);
35: evaluate();
36: }
37:
38: void Phrase::derive(Expr *e)
39: {
40: char *error;
41: frame->freekey(key+2);
42: if( error = frame->makephrase(e,key+2) )
43: pad()->insert( key+1, SELECTLINE, error );
44: }
45:
46: void Phrase::applyunary(Op op)
47: {
48: trace( "%d.applyunary(%s)", this, OpName(op) ); VOK;
49: derive(E_Unary(op,expr));
50: }
51:
52: void Phrase::applybinary(Op op, Expr *e)
53: {
54: trace( "%d.applybinary(%s,%s)", this, OpName(op), e->text() ); VOK;
55: derive(E_Binary(expr,op,e));
56: }
57:
58: void Phrase::applydot(Var *v)
59: {
60: trace("%d.applydot(%s)", this, v->text()); VOK;
61: applybinary(O_DOT, E_Sym(v));
62: }
63:
64: void Phrase::applyarrow(Var *v)
65: {
66: trace("%d.applyarrow(%s)", this, v->text()); VOK;
67: applybinary(O_ARROW, E_Sym(v));
68: }
69:
70: void Phrase::allstar(UType *t)
71: {
72: trace("%d.allstar(%s)", this, t->text()); VOK;
73: t->show(SHOW);
74: applyunary(O_DEREF);
75: }
76:
77: void Phrase::alleval(UType *t)
78: {
79: trace("%d.alleval(%s)", this, t->text()); VOK;
80: t->show(SHOW);
81: evaluate();
82: }
83:
84: void Phrase::evaluate()
85: {
86: char *error;
87:
88: trace( "%d.evaluate()", this ); VOK;
89: if( error = frame->makephrase(expr,key) )
90: pad()->insert( key+1, SELECTLINE, error );
91: }
92:
93: int Phrase::changed(Bls &b)
94: {
95: Spy s;
96:
97: trace( "%d.changed()", this ); OK(0);
98: IF_LIVE( !expr->spy ) return 0;
99: s = *expr->spy;
100: expr->evaltext(frame,b);
101: if( !expr->spy || !strcmp(s.b.text, expr->spy->b.text) )
102: return 0;
103: evaluate();
104: return 1;
105: }
106:
107: char *Phrase::help()
108: {
109: trace( "%d.help()", this ); OK("Phrase::help");
110: switch( expr->op ){
111: case O_QSTRUCT:
112: case O_QENUM:
113: return "<id> { struct/enum name }";
114: case O_QINDEX:
115: Expr *e = E_Binary( expr->sub1, O_INDEX, E_Id("lo..hi") );
116: return sf( "<lo> [..<hi>] {eval %s}", e->text() );
117: default:
118: return sf( "<expr> {eval in this scope; $ is %s}", expr->text());
119: }
120: }
121:
122: char *Phrase::kbd(char *s)
123: {
124: trace( "%d.kbd(%s)", this, s ); OK("kbd");
125: pad()->removeline(key+1);
126: int q = expr->op == O_QINDEX;
127: Parse y( q ? G_DOTDOT : G_EXPR, q ? 0 : expr );
128: Expr *e = (Expr*)y.parse(s);
129: if( !e ){
130: pad()->insert(key+1, SELECTLINE, "%s: %s", y.error, s);
131: return 0;
132: }
133: switch( expr->op ){
134: case O_QINDEX:
135: plugqindex(e);
136: break;
137: case O_QSTRUCT:
138: plugqtype(e);
139: break;
140: case O_QENUM:
141: plugqtype(e);
142: break;
143: default:
144: derive(e);
145: }
146: return 0;
147: }
148:
149: void Phrase::plugqtype(Expr *e)
150: {
151: trace( "%d.plugqtype(%d)", this, e ); VOK;
152: if( e->edisc != E_ID ){
153: pad()->insert(key+1, SELECTLINE, "not an id: %s", e->text());
154: return;
155: }
156: UType *u = (UType*) frame->core->symtab()->idtosym(U_UTYPE, e->id);
157: if( !u ){
158: pad()->insert(key+1, SELECTLINE, "type not found: %s", e->id);
159: return;
160: }
161: applycast(&u->type);
162: }
163:
164: void Phrase::plugqindex(Expr *e)
165: {
166: trace( "%d.pluqindex(%d)", this, e ); VOK;
167: IF_LIVE( !expr || expr->op != O_QINDEX ) return;
168: switch( e->op ){
169: case O_RANGE:
170: { // cfront bug
171: Bls error;
172: e->evaltext(frame,error);
173: if( !e->evalerr ){
174: long i;
175: for( i = e->sub2->val.lng; i >= e->sub1->val.lng; --i )
176: derive( E_Binary(expr->sub1,O_INDEX,E_IConst(i)) );
177: break;
178: }
179: } // cfront bug
180: default:
181: derive( E_Binary(expr->sub1, O_INDEX, e) );
182: }
183: evaluate();
184: }
185:
186: void Phrase::numeric(long n)
187: {
188: trace( "%d.numeric(%d)", n ); VOK;
189: sprintf( Token, "%d", n);
190: plugqindex( E_IConst(n) );
191: }
192:
193: void Phrase::memory()
194: {
195: trace( "%d.memory()", this ); VOK;
196: IF_LIVE( !expr ) return;
197: frame->symtab()->core()->process()->openmemory(expr->val.lng);
198: }
199:
200: int Phrase::iscast()
201: {
202: trace( "%d.iscast()", this ); OK(0);
203: switch( expr ? expr->op : 0 ){
204: case O_QCAST:
205: case O_QSTRUCT:
206: case O_QENUM: return 1;
207: }
208: return 0;
209: }
210:
211: void Phrase::applycast(DType *d)
212: {
213: int i = 0;
214: trace( "%d.applycast(%d)", this, d ); VOK;
215: Expr *e = expr;
216: if( iscast() ){
217: i = e->val.lng;
218: e = e->sub1;
219: }
220: while( i-->0 ){
221: DType *ptr = new DType;
222: *ptr = d->incref();
223: d = ptr;
224: }
225: e = E_Unary(O_CAST, e);
226: e->type = *d;
227: derive(e);
228: }
229:
230: void Phrase::increfcast(long i)
231: {
232: trace("%d.increfcast(%d)", this, i); VOK;
233: if( !iscast() )
234: expr = E_Unary(O_QCAST, expr);
235: Expr *e = E_Unary(expr->op, expr->sub1);
236: e->val.lng += i; /* += ? */
237: derive(e);
238: }
239:
240: void Phrase::soretycast(long i, short qop)
241: {
242: trace( "%d.soretycast(%d,%d)", this, i, qop ); VOK;
243: if( !iscast() )
244: expr = E_Unary(O_QCAST, expr);
245: Expr *e = E_Unary(qop, expr->sub1);
246: e->val.lng = i + expr->val.lng;
247: derive(e);
248: }
249:
250: void Phrase::strcast(long i) { soretycast(i, O_QSTRUCT); }
251:
252: void Phrase::enumcast(long i) { soretycast(i, O_QENUM); }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.