Annotation of parser3/src/main/execute.C, revision 1.54
1.1 paf 1: /*
1.54 ! paf 2: $Id: execute.C,v 1.53 2001/03/06 15:02:48 paf Exp $
1.1 paf 3: */
4:
1.8 paf 5: #include "pa_array.h"
1.1 paf 6: #include "code.h"
1.11 paf 7: #include "pa_request.h"
1.15 paf 8: #include "pa_vstring.h"
1.22 paf 9: #include "pa_vhash.h"
1.23 paf 10: #include "pa_vunknown.h"
1.34 paf 11: #include "pa_vcframe.h"
12: #include "pa_vmframe.h"
1.38 paf 13: #include "pa_vobject.h"
1.49 paf 14: #include "pa_vdouble.h"
1.54 ! paf 15: #include "pa_vbool.h"
1.1 paf 16:
17: #include <stdio.h>
18:
1.24 paf 19: #define PUSH(value) stack.push(value)
20: #define POP() static_cast<Value *>(stack.pop())
1.32 paf 21: #define POP_NAME() static_cast<Value *>(stack.pop())->as_string()
1.24 paf 22:
1.11 paf 23:
1.1 paf 24: char *opcode_name[]={
1.49 paf 25: // literals
1.52 paf 26: "VALUE", "CODE", "CLASS",
1.49 paf 27:
28: // actions
1.51 paf 29: "WITH_SELF", "WITH_ROOT", "WITH_READ", "WITH_WRITE",
1.1 paf 30: "CONSTRUCT",
1.18 paf 31: "WRITE",
32: "GET_ELEMENT", "GET_ELEMENT__WRITE",
1.1 paf 33: "CREATE_EWPOOL", "REDUCE_EWPOOL",
34: "CREATE_RWPOOL", "REDUCE_RWPOOL",
1.49 paf 35: "CREATE_SWPOOL", "REDUCE_SWPOOL",
1.1 paf 36: "GET_METHOD_FRAME",
37: "STORE_PARAM",
1.51 paf 38: "CALL",
1.49 paf 39:
40: // expression ops: unary
41: "NEG", "INV", "NOT", "DEF", "IN", "FEXISTS",
42: // expression ops: binary
43: "SUB", "ADD", "MUL", "DIV", "MOD",
44: "BIN_AND", "BIN_OR",
45: "LOG_AND", "LOG_OR",
46: "NUM_LT", "NUM_GT", "NUM_LE", "NUM_GE", "NUM_EQ", "NUM_NE",
47: "STR_LT", "STR_GT", "STR_LE", "STR_GE", "STR_EQ", "STR_NE",
48: "XOR"
1.1 paf 49: };
50:
1.9 paf 51: void dump(int level, const Array& ops) {
1.23 paf 52: if(0){
53: int size=ops.size();
1.46 paf 54: //fprintf(stderr, "size=%d\n", size);
1.23 paf 55: for(int i=0; i<size; i++) {
56: Operation op;
57: op.cast=ops.quick_get(i);
1.46 paf 58: fprintf(stderr, "%8X\n", op.cast);
1.23 paf 59: }
60: }
61:
1.9 paf 62: int size=ops.size();
1.46 paf 63: //fprintf(stderr, "size=%d\n", size);
1.1 paf 64: for(int i=0; i<size; i++) {
1.23 paf 65: Operation op;
66: op.cast=ops.quick_get(i);
1.46 paf 67: fprintf(stderr, "%*s%s", level*4, "", opcode_name[op.code]);
1.1 paf 68:
1.52 paf 69: if(op.code==OP_VALUE) {
70: Value *value=static_cast<Value *>(ops.quick_get(++i));
71: fprintf(stderr, " \"%s\" %s", value->get_string()->cstr(), value->type());
1.15 paf 72: }
1.38 paf 73: if(op.code==OP_CLASS) {
74: VClass *vclass=static_cast<VClass *>(ops.quick_get(++i));
1.46 paf 75: fprintf(stderr, " \"%s\"", vclass->name().cstr());
1.38 paf 76: }
1.46 paf 77: fprintf(stderr, "\n");
1.1 paf 78:
1.32 paf 79: if(op.code==OP_CODE) {
1.10 paf 80: const Array *local_ops=reinterpret_cast<const Array *>(ops.quick_get(++i));
1.9 paf 81: dump(level+1, *local_ops);
1.1 paf 82: }
83: }
84: }
85:
1.32 paf 86: void Request::execute(const Array& ops) {
1.30 paf 87: if(1) {
1.51 paf 88: fputs("source----------------------------\n", stderr);
1.12 paf 89: dump(0, ops);
1.51 paf 90: fputs("execution-------------------------\n", stderr);
1.12 paf 91: }
92:
1.11 paf 93: int size=ops.size();
1.46 paf 94: //fprintf(stderr, "size=%d\n", size);
1.11 paf 95: for(int i=0; i<size; i++) {
1.23 paf 96: Operation op;
97: op.cast=ops.quick_get(i);
1.46 paf 98: fprintf(stderr, "%d:%s", stack.top(), opcode_name[op.code]);
1.11 paf 99:
1.23 paf 100: switch(op.code) {
1.51 paf 101: // param in next instruction
1.52 paf 102: case OP_VALUE:
1.32 paf 103: {
1.52 paf 104: Value *value=static_cast<Value *>(ops.quick_get(++i));
105: fprintf(stderr, " \"%s\" %s", value->get_string()->cstr(), value->type());
106: PUSH(value);
1.32 paf 107: break;
108: }
109: case OP_CODE:
110: {
111: const Array *local_ops=reinterpret_cast<const Array *>(ops.quick_get(++i));
1.46 paf 112: fprintf(stderr, " (%d)\n", local_ops->size());
1.38 paf 113: dump(1, *local_ops);
1.32 paf 114: Junction& j=*NEW Junction(pool(),
1.45 paf 115: *self, 0, 0,
1.34 paf 116: root,rcontext,wcontext,local_ops);
1.32 paf 117:
118: Value *value=NEW VJunction(j);
119: PUSH(value);
120: break;
121: }
1.38 paf 122: case OP_CLASS:
123: {
124: VClass *vclass=static_cast<VClass *>(ops.quick_get(++i));
1.46 paf 125: fprintf(stderr, " \"%s\"", vclass->name().cstr());
1.38 paf 126: PUSH(vclass);
127: break;
128: }
1.32 paf 129:
1.51 paf 130: // OP_WITH
1.37 paf 131: case OP_WITH_SELF:
132: {
133: PUSH(self);
134: break;
135: }
136: case OP_WITH_ROOT:
1.11 paf 137: {
1.37 paf 138: PUSH(root);
1.13 paf 139: break;
1.11 paf 140: }
1.15 paf 141: case OP_WITH_READ:
142: {
1.24 paf 143: PUSH(rcontext);
1.20 paf 144: break;
145: }
1.37 paf 146: case OP_WITH_WRITE:
1.20 paf 147: {
1.37 paf 148: PUSH(wcontext);
1.20 paf 149: break;
150: }
1.37 paf 151:
1.51 paf 152: // OTHER ACTIONS BUT WITHs
1.37 paf 153: case OP_CONSTRUCT:
1.20 paf 154: {
1.37 paf 155: Value *value=POP();
156: String& name=POP_NAME();
157: Value *ncontext=POP();
158: value->set_name(name);
159: ncontext->put_element(name, value);
1.15 paf 160: break;
161: }
1.18 paf 162: case OP_WRITE:
1.13 paf 163: {
1.24 paf 164: Value *value=POP();
1.14 paf 165: wcontext->write(value);
1.13 paf 166: break;
1.14 paf 167: }
1.13 paf 168:
1.15 paf 169: case OP_GET_ELEMENT:
1.11 paf 170: {
1.17 paf 171: Value *value=get_element();
1.24 paf 172: PUSH(value);
1.17 paf 173: break;
174: }
175:
1.18 paf 176: case OP_GET_ELEMENT__WRITE:
1.17 paf 177: {
178: Value *value=get_element();
179: wcontext->write(value);
180: break;
181: }
182:
1.32 paf 183:
1.17 paf 184: case OP_CREATE_EWPOOL:
185: {
1.24 paf 186: PUSH(wcontext);
1.43 paf 187: wcontext=NEW WWrapper(pool(), 0 /* empty */, true /* constructing */);
1.17 paf 188: break;
189: }
190: case OP_REDUCE_EWPOOL:
191: {
1.36 paf 192: Value *value=wcontext->result();
1.25 paf 193: wcontext=static_cast<WContext *>(POP());
1.24 paf 194: PUSH(value);
1.13 paf 195: break;
1.15 paf 196: }
1.13 paf 197:
1.26 paf 198: case OP_CREATE_RWPOOL:
199: {
200: Value *ncontext=POP();
201: PUSH(rcontext);
202: rcontext=ncontext;
203: PUSH(wcontext);
1.43 paf 204: wcontext=NEW WWrapper(pool(), ncontext, false /* not constructing */);
1.26 paf 205: break;
206: }
207: case OP_REDUCE_RWPOOL:
208: {
209: String *string=wcontext->get_string();
1.50 paf 210: Value *value=string?NEW VString(*string):NEW VString(pool());
1.26 paf 211: wcontext=static_cast<WContext *>(POP());
212: rcontext=POP();
213: PUSH(value);
214: break;
215: }
1.49 paf 216: case OP_CREATE_SWPOOL:
217: {
218: PUSH(wcontext);
1.50 paf 219: wcontext=NEW WWrapper(pool(), 0 /* empty */, false /* not constructing */);
1.49 paf 220: break;
221: }
222: case OP_REDUCE_SWPOOL:
223: {
224: // from "$a $b" part of expression taking only string value,
225: // ignoring any other content of wcontext
226: String *string=wcontext->get_string();
1.50 paf 227: Value *value=string?NEW VString(*string):NEW VString(pool());
228: wcontext=static_cast<WContext *>(POP());
1.49 paf 229: PUSH(value);
230: break;
231: }
232:
1.51 paf 233: // CALL
1.28 paf 234: case OP_GET_METHOD_FRAME:
235: {
1.32 paf 236: Value *value=POP();
1.28 paf 237: // [self/class?;params;local;code/native_code](name)
1.32 paf 238: Junction *junction=value->get_junction();
1.31 paf 239: if(!junction)
1.28 paf 240: THROW(0,0,
1.42 paf 241: &value->name(),
1.39 paf 242: "type is '%s', can not call it (must be method or junction)",
1.38 paf 243: value->type());
1.28 paf 244: //unless(method) method=operators.get_method[...;code/native_code](name)
1.34 paf 245: VMethodFrame *frame=NEW VMethodFrame(pool(), *junction);
1.28 paf 246: PUSH(frame);
247: break;
248: }
249: case OP_STORE_PARAM:
250: {
251: Value *value=POP();
1.34 paf 252: VMethodFrame *frame=static_cast<VMethodFrame *>(stack[0]);
1.28 paf 253: frame->store_param(value);
1.29 paf 254: break;
255: }
256:
257: case OP_CALL:
258: {
1.46 paf 259: fprintf(stderr, "->\n");
1.34 paf 260: VMethodFrame *frame=static_cast<VMethodFrame *>(POP());
261: frame->fill_unspecified_params();
1.45 paf 262: PUSH(self);
263: PUSH(root);
264: PUSH(rcontext);
265: PUSH(wcontext);
266:
1.38 paf 267: VClass *called_class=frame->junction.self.get_class();
1.43 paf 268: // constructing?
269: if(wcontext->constructing()) { // yes
1.41 paf 270: // constructor call: $some(^class:method(..))
1.50 paf 271: frame->write(self=NEW VObject(pool(), *called_class));
1.43 paf 272: } else { // no
1.47 paf 273: // context is object or class & is it my class or my parent's class?
1.44 paf 274: VClass *read_class=rcontext->get_class();
275: if(read_class && read_class->is_or_derived_from(*called_class)) // yes
1.46 paf 276: self=rcontext; // class dynamic call
1.44 paf 277: else // no
278: self=&frame->junction.self; // static or simple dynamic call
1.38 paf 279: }
1.45 paf 280: frame->set_self(*self);
1.29 paf 281: root=rcontext=wcontext=frame;
1.47 paf 282: {
1.48 paf 283: // take object or class from any wrappers
284: VAliased *aliased=self->get_aliased();
285: // substitute class alias to the class they are called AS
1.47 paf 286: Temp_alias temp_alias(*aliased, *frame->junction.vclass);
287: execute(frame->junction.method->code);
288: }
1.36 paf 289: Value *value=wcontext->result();
1.45 paf 290:
291: wcontext=static_cast<WContext *>(POP());
292: rcontext=POP();
293: root=POP();
294: self=static_cast<VAliased *>(POP());
1.29 paf 295: wcontext->write(value);
1.46 paf 296: fprintf(stderr, "<-returned");
1.49 paf 297: break;
298: }
299:
1.51 paf 300: // EXPRESSION
1.53 paf 301: case OP_ADD:
302: {
303: Value *b=POP();
304: Value *a=POP();
305: Value *value=NEW VDouble(pool(),
306: a->get_double() +
307: b->get_double());
308: PUSH(value);
309: break;
310: }
311: case OP_SUB:
312: {
313: Value *b=POP();
314: Value *a=POP();
315: Value *value=NEW VDouble(pool(),
316: a->get_double() -
317: b->get_double());
318: PUSH(value);
319: break;
320: }
1.49 paf 321: case OP_MUL:
322: {
323: Value *b=POP();
324: Value *a=POP();
325: Value *value=NEW VDouble(pool(),
326: a->get_double() *
1.53 paf 327: b->get_double());
328: PUSH(value);
329: break;
330: }
331: case OP_DIV:
332: {
333: Value *b=POP();
334: Value *a=POP();
335: Value *value=NEW VDouble(pool(),
336: a->get_double() /
1.49 paf 337: b->get_double());
1.54 ! paf 338: PUSH(value);
! 339: break;
! 340: }
! 341: case OP_NEG:
! 342: {
! 343: Value *operand=POP();
! 344: Value *value=NEW VDouble(pool(), -operand->get_double());
! 345: PUSH(value);
! 346: break;
! 347: }
! 348: case OP_INV:
! 349: {
! 350: Value *operand=POP();
! 351: Value *value=NEW VDouble(pool(),
! 352: ~static_cast<int>(operand->get_double()));
! 353: PUSH(value);
! 354: break;
! 355: }
! 356: case OP_NOT:
! 357: {
! 358: Value *operand=POP();
! 359: Value *value=NEW VBool(pool(), !operand->get_bool());
1.49 paf 360: PUSH(value);
1.28 paf 361: break;
362: }
363:
1.11 paf 364: default:
1.46 paf 365: fprintf(stderr, "\tTODO");
1.11 paf 366: break;
367: }
1.46 paf 368: fprintf(stderr, "\n");
1.11 paf 369: }
1.1 paf 370: }
1.17 paf 371:
372: Value *Request::get_element() {
1.32 paf 373: String& name=POP_NAME();
1.24 paf 374: Value *ncontext=POP();
1.32 paf 375: Value *value=ncontext->get_element(name);
1.21 paf 376:
1.32 paf 377: if(value) {
378: Junction *junction=value->get_junction();
1.36 paf 379: if(junction && junction->code) { // is it a code-junction?
1.32 paf 380: // autocalc it
1.46 paf 381: fprintf(stderr, "ja->\n");
1.45 paf 382: PUSH(self);
383: PUSH(root);
384: PUSH(rcontext);
385: PUSH(wcontext);
386:
1.34 paf 387: // almost plain wwrapper about junction wcontext,
388: // BUT intercepts string writes
389: VCodeFrame frame(pool(), *junction->wcontext); wcontext=&frame;
390: self=&junction->self;
1.32 paf 391: root=junction->root;
392: rcontext=junction->rcontext;
393: execute(*junction->code);
1.35 paf 394: // CodeFrame soul:
1.36 paf 395: // string writes were intercepted
396: // returning them as the result of getting code-junction
1.42 paf 397: value=NEW VString(*frame.get_string());
1.45 paf 398:
399: wcontext=static_cast<WContext *>(POP());
400: rcontext=POP();
401: root=POP();
402: self=static_cast<VAliased *>(POP());
1.46 paf 403: fprintf(stderr, "<-ja returned");
1.32 paf 404: }
405: } else {
1.23 paf 406: value=NEW VUnknown(pool());
1.25 paf 407: value->set_name(name);
1.22 paf 408: }
1.17 paf 409: return value;
1.34 paf 410: }
E-mail: