Annotation of parser3/src/main/execute.C, revision 1.50
1.1 paf 1: /*
1.50 ! paf 2: $Id: execute.C,v 1.49 2001/03/06 12:22:58 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.1 paf 15:
16: #include <stdio.h>
17:
1.24 paf 18: #define PUSH(value) stack.push(value)
19: #define POP() static_cast<Value *>(stack.pop())
1.32 paf 20: #define POP_NAME() static_cast<Value *>(stack.pop())->as_string()
1.24 paf 21:
1.11 paf 22:
1.1 paf 23: char *opcode_name[]={
1.49 paf 24: // literals
1.38 paf 25: "STRING", "CODE", "CLASS",
1.49 paf 26:
27: // actions
1.1 paf 28: "WITH_ROOT", "WITH_SELF", "WITH_READ", "WITH_WRITE",
29: "CONSTRUCT",
30: "EXPRESSION_EVAL", "MODIFY_EVAL",
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",
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.23 paf 69: if(op.code==OP_STRING) {
1.19 paf 70: VString *vstring=static_cast<VString *>(ops.quick_get(++i));
1.46 paf 71: fprintf(stderr, " \"%s\"", vstring->get_string()->cstr());
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.46 paf 88: fputs("source----------------------------", stderr);
1.12 paf 89: dump(0, ops);
1.46 paf 90: fputs("execution-------------------------", 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.32 paf 101: // param in next instruction
102: case OP_STRING:
103: {
104: VString *vstring=static_cast<VString *>(ops.quick_get(++i));
1.46 paf 105: fprintf(stderr, " \"%s\"", vstring->get_string()->cstr());
1.32 paf 106: PUSH(vstring);
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:
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:
152: // ...
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.37 paf 162: // TODO: OP_EXPRESSION_EVAL, OP_MODIFY_EVAL,
1.18 paf 163: case OP_WRITE:
1.13 paf 164: {
1.24 paf 165: Value *value=POP();
1.14 paf 166: wcontext->write(value);
1.13 paf 167: break;
1.14 paf 168: }
1.13 paf 169:
1.15 paf 170: case OP_GET_ELEMENT:
1.11 paf 171: {
1.17 paf 172: Value *value=get_element();
1.24 paf 173: PUSH(value);
1.17 paf 174: break;
175: }
176:
1.18 paf 177: case OP_GET_ELEMENT__WRITE:
1.17 paf 178: {
179: Value *value=get_element();
180: wcontext->write(value);
181: break;
182: }
183:
1.32 paf 184:
1.17 paf 185: case OP_CREATE_EWPOOL:
186: {
1.24 paf 187: PUSH(wcontext);
1.43 paf 188: wcontext=NEW WWrapper(pool(), 0 /* empty */, true /* constructing */);
1.17 paf 189: break;
190: }
191: case OP_REDUCE_EWPOOL:
192: {
1.36 paf 193: Value *value=wcontext->result();
1.25 paf 194: wcontext=static_cast<WContext *>(POP());
1.24 paf 195: PUSH(value);
1.13 paf 196: break;
1.15 paf 197: }
1.13 paf 198:
1.26 paf 199: case OP_CREATE_RWPOOL:
200: {
201: Value *ncontext=POP();
202: PUSH(rcontext);
203: rcontext=ncontext;
204: PUSH(wcontext);
1.43 paf 205: wcontext=NEW WWrapper(pool(), ncontext, false /* not constructing */);
1.26 paf 206: break;
207: }
208: case OP_REDUCE_RWPOOL:
209: {
210: String *string=wcontext->get_string();
1.50 ! paf 211: Value *value=string?NEW VString(*string):NEW VString(pool());
1.26 paf 212: wcontext=static_cast<WContext *>(POP());
213: rcontext=POP();
214: PUSH(value);
215: break;
216: }
1.49 paf 217: case OP_CREATE_SWPOOL:
218: {
219: PUSH(wcontext);
1.50 ! paf 220: wcontext=NEW WWrapper(pool(), 0 /* empty */, false /* not constructing */);
1.49 paf 221: break;
222: }
223: case OP_REDUCE_SWPOOL:
224: {
225: // from "$a $b" part of expression taking only string value,
226: // ignoring any other content of wcontext
227: String *string=wcontext->get_string();
1.50 ! paf 228: Value *value=string?NEW VString(*string):NEW VString(pool());
! 229: wcontext=static_cast<WContext *>(POP());
1.49 paf 230: PUSH(value);
231: break;
232: }
233:
1.26 paf 234:
1.37 paf 235: // CALL
1.28 paf 236: case OP_GET_METHOD_FRAME:
237: {
1.32 paf 238: Value *value=POP();
1.28 paf 239: // [self/class?;params;local;code/native_code](name)
1.32 paf 240: Junction *junction=value->get_junction();
1.31 paf 241: if(!junction)
1.28 paf 242: THROW(0,0,
1.42 paf 243: &value->name(),
1.39 paf 244: "type is '%s', can not call it (must be method or junction)",
1.38 paf 245: value->type());
1.28 paf 246: //unless(method) method=operators.get_method[...;code/native_code](name)
1.34 paf 247: VMethodFrame *frame=NEW VMethodFrame(pool(), *junction);
1.28 paf 248: PUSH(frame);
249: break;
250: }
251: case OP_STORE_PARAM:
252: {
253: Value *value=POP();
1.34 paf 254: VMethodFrame *frame=static_cast<VMethodFrame *>(stack[0]);
1.28 paf 255: frame->store_param(value);
1.29 paf 256: break;
257: }
258:
259: case OP_CALL:
260: {
1.46 paf 261: fprintf(stderr, "->\n");
1.34 paf 262: VMethodFrame *frame=static_cast<VMethodFrame *>(POP());
263: frame->fill_unspecified_params();
1.45 paf 264: PUSH(self);
265: PUSH(root);
266: PUSH(rcontext);
267: PUSH(wcontext);
268:
1.38 paf 269: VClass *called_class=frame->junction.self.get_class();
1.43 paf 270: // constructing?
271: if(wcontext->constructing()) { // yes
1.41 paf 272: // constructor call: $some(^class:method(..))
1.50 ! paf 273: frame->write(self=NEW VObject(pool(), *called_class));
1.43 paf 274: } else { // no
1.47 paf 275: // context is object or class & is it my class or my parent's class?
1.44 paf 276: VClass *read_class=rcontext->get_class();
277: if(read_class && read_class->is_or_derived_from(*called_class)) // yes
1.46 paf 278: self=rcontext; // class dynamic call
1.44 paf 279: else // no
280: self=&frame->junction.self; // static or simple dynamic call
1.38 paf 281: }
1.45 paf 282: frame->set_self(*self);
1.29 paf 283: root=rcontext=wcontext=frame;
1.47 paf 284: {
1.48 paf 285: // take object or class from any wrappers
286: VAliased *aliased=self->get_aliased();
287: // substitute class alias to the class they are called AS
1.47 paf 288: Temp_alias temp_alias(*aliased, *frame->junction.vclass);
289: execute(frame->junction.method->code);
290: }
1.36 paf 291: Value *value=wcontext->result();
1.45 paf 292:
293: wcontext=static_cast<WContext *>(POP());
294: rcontext=POP();
295: root=POP();
296: self=static_cast<VAliased *>(POP());
1.29 paf 297: wcontext->write(value);
1.46 paf 298: fprintf(stderr, "<-returned");
1.49 paf 299: break;
300: }
301:
302: case OP_MUL:
303: {
304: Value *b=POP();
305: Value *a=POP();
306: Value *value=NEW VDouble(pool(),
307: a->get_double() *
308: b->get_double());
309: PUSH(value);
1.28 paf 310: break;
311: }
312:
1.11 paf 313: default:
1.46 paf 314: fprintf(stderr, "\tTODO");
1.11 paf 315: break;
316: }
1.46 paf 317: fprintf(stderr, "\n");
1.11 paf 318: }
1.1 paf 319: }
1.17 paf 320:
321: Value *Request::get_element() {
1.32 paf 322: String& name=POP_NAME();
1.24 paf 323: Value *ncontext=POP();
1.32 paf 324: Value *value=ncontext->get_element(name);
1.21 paf 325:
1.32 paf 326: if(value) {
327: Junction *junction=value->get_junction();
1.36 paf 328: if(junction && junction->code) { // is it a code-junction?
1.32 paf 329: // autocalc it
1.46 paf 330: fprintf(stderr, "ja->\n");
1.45 paf 331: PUSH(self);
332: PUSH(root);
333: PUSH(rcontext);
334: PUSH(wcontext);
335:
1.34 paf 336: // almost plain wwrapper about junction wcontext,
337: // BUT intercepts string writes
338: VCodeFrame frame(pool(), *junction->wcontext); wcontext=&frame;
339: self=&junction->self;
1.32 paf 340: root=junction->root;
341: rcontext=junction->rcontext;
342: execute(*junction->code);
1.35 paf 343: // CodeFrame soul:
1.36 paf 344: // string writes were intercepted
345: // returning them as the result of getting code-junction
1.42 paf 346: value=NEW VString(*frame.get_string());
1.45 paf 347:
348: wcontext=static_cast<WContext *>(POP());
349: rcontext=POP();
350: root=POP();
351: self=static_cast<VAliased *>(POP());
1.46 paf 352: fprintf(stderr, "<-ja returned");
1.32 paf 353: }
354: } else {
1.23 paf 355: value=NEW VUnknown(pool());
1.25 paf 356: value->set_name(name);
1.22 paf 357: }
1.17 paf 358: return value;
1.34 paf 359: }
E-mail: