Annotation of parser3/src/main/execute.C, revision 1.34
1.1 paf 1: /*
1.34 ! paf 2: $Id: execute.C,v 1.33 2001/02/24 09:00:11 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.1 paf 13:
14: #include <stdio.h>
15:
1.24 paf 16: #define PUSH(value) stack.push(value)
17: #define POP() static_cast<Value *>(stack.pop())
1.32 paf 18: #define POP_NAME() static_cast<Value *>(stack.pop())->as_string()
1.24 paf 19:
1.11 paf 20:
1.1 paf 21: char *opcode_name[]={
1.32 paf 22: "STRING", "CODE",
1.1 paf 23: "WITH_ROOT", "WITH_SELF", "WITH_READ", "WITH_WRITE",
24: "CONSTRUCT",
25: "EXPRESSION_EVAL", "MODIFY_EVAL",
1.18 paf 26: "WRITE",
27: "GET_ELEMENT", "GET_ELEMENT__WRITE",
1.1 paf 28: "CREATE_EWPOOL", "REDUCE_EWPOOL",
29: "CREATE_RWPOOL", "REDUCE_RWPOOL",
30: "GET_METHOD_FRAME",
31: "STORE_PARAM",
32: "CALL"
33: };
34:
1.9 paf 35: void dump(int level, const Array& ops) {
1.23 paf 36: if(0){
37: int size=ops.size();
1.27 paf 38: //printf("size=%d\n", size);
1.23 paf 39: for(int i=0; i<size; i++) {
40: Operation op;
41: op.cast=ops.quick_get(i);
42: printf("%8X\n", op.cast);
43: }
44: }
45:
1.9 paf 46: int size=ops.size();
1.27 paf 47: //printf("size=%d\n", size);
1.1 paf 48: for(int i=0; i<size; i++) {
1.23 paf 49: Operation op;
50: op.cast=ops.quick_get(i);
51: printf("%*s%s", level*4, "", opcode_name[op.code]);
1.1 paf 52:
1.23 paf 53: if(op.code==OP_STRING) {
1.19 paf 54: VString *vstring=static_cast<VString *>(ops.quick_get(++i));
55: printf(" \"%s\"", vstring->get_string()->cstr());
1.15 paf 56: }
1.1 paf 57: printf("\n");
58:
1.32 paf 59: if(op.code==OP_CODE) {
1.10 paf 60: const Array *local_ops=reinterpret_cast<const Array *>(ops.quick_get(++i));
1.9 paf 61: dump(level+1, *local_ops);
1.1 paf 62: }
63: }
64: }
65:
1.32 paf 66: void Request::execute(const Array& ops) {
1.30 paf 67: if(1) {
1.32 paf 68: puts("source----------------------------");
1.12 paf 69: dump(0, ops);
1.32 paf 70: puts("execution-------------------------");
1.12 paf 71: }
72:
1.11 paf 73: int size=ops.size();
1.27 paf 74: //printf("size=%d\n", size);
1.11 paf 75: for(int i=0; i<size; i++) {
1.23 paf 76: Operation op;
77: op.cast=ops.quick_get(i);
78: printf("%d:%s", stack.top(), opcode_name[op.code]);
1.11 paf 79:
1.23 paf 80: switch(op.code) {
1.32 paf 81: // param in next instruction
82: case OP_STRING:
83: {
84: VString *vstring=static_cast<VString *>(ops.quick_get(++i));
85: printf(" \"%s\"", vstring->get_string()->cstr());
86: PUSH(vstring);
87: break;
88: }
89: case OP_CODE:
90: {
91: const Array *local_ops=reinterpret_cast<const Array *>(ops.quick_get(++i));
92: printf(" (%d)", local_ops->size());
93: Junction& j=*NEW Junction(pool(),
1.34 ! paf 94: *self,
1.32 paf 95: 0,
1.34 ! paf 96: root,rcontext,wcontext,local_ops);
1.32 paf 97:
98: Value *value=NEW VJunction(j);
99: PUSH(value);
100: break;
101: }
102:
103: // OP_WITH
1.11 paf 104: case OP_WITH_WRITE:
105: {
1.24 paf 106: PUSH(wcontext);
1.13 paf 107: break;
1.11 paf 108: }
1.15 paf 109: case OP_WITH_READ:
110: {
1.24 paf 111: PUSH(rcontext);
1.20 paf 112: break;
113: }
114: case OP_WITH_ROOT:
115: {
1.24 paf 116: PUSH(root);
1.20 paf 117: break;
118: }
119: case OP_WITH_SELF:
120: {
1.24 paf 121: PUSH(self);
1.15 paf 122: break;
123: }
1.13 paf 124:
1.32 paf 125: // ...
1.18 paf 126: case OP_WRITE:
1.13 paf 127: {
1.24 paf 128: Value *value=POP();
1.14 paf 129: wcontext->write(value);
1.13 paf 130: break;
1.14 paf 131: }
1.13 paf 132:
1.15 paf 133: case OP_GET_ELEMENT:
1.11 paf 134: {
1.17 paf 135: Value *value=get_element();
1.24 paf 136: PUSH(value);
1.17 paf 137: break;
138: }
139:
1.18 paf 140: case OP_GET_ELEMENT__WRITE:
1.17 paf 141: {
142: Value *value=get_element();
143: wcontext->write(value);
144: break;
145: }
146:
1.32 paf 147: case OP_CONSTRUCT:
148: {
149: Value *value=POP();
150: String& name=POP_NAME();
151: Value *ncontext=POP();
152: value->set_name(name);
153: ncontext->put_element(name, value);
154: break;
155: }
156:
1.17 paf 157: case OP_CREATE_EWPOOL:
158: {
1.24 paf 159: PUSH(wcontext);
1.29 paf 160: wcontext=NEW WWrapper(pool(), 0 /* empty */);
1.17 paf 161: break;
162: }
163: case OP_REDUCE_EWPOOL:
164: {
1.34 ! paf 165: Value *value=wcontext->value_or_string();
1.25 paf 166: wcontext=static_cast<WContext *>(POP());
1.24 paf 167: PUSH(value);
1.13 paf 168: break;
1.15 paf 169: }
1.13 paf 170:
1.26 paf 171: case OP_CREATE_RWPOOL:
172: {
173: Value *ncontext=POP();
174: PUSH(rcontext);
175: rcontext=ncontext;
176: PUSH(wcontext);
1.29 paf 177: wcontext=NEW WWrapper(pool(), ncontext);
1.26 paf 178: break;
179: }
180: case OP_REDUCE_RWPOOL:
181: {
182: String *string=wcontext->get_string();
183: Value *value=NEW VString(string);
184: wcontext=static_cast<WContext *>(POP());
185: rcontext=POP();
186: PUSH(value);
187: break;
188: }
189:
1.28 paf 190: case OP_GET_METHOD_FRAME:
191: {
1.32 paf 192: Value *value=POP();
1.28 paf 193: // [self/class?;params;local;code/native_code](name)
1.32 paf 194: Junction *junction=value->get_junction();
1.31 paf 195: if(!junction)
1.28 paf 196: THROW(0,0,
1.32 paf 197: value->name(),
198: "is not a method or a junction (it is '%s'), can not call it",
199: value->type());
1.28 paf 200: //unless(method) method=operators.get_method[...;code/native_code](name)
1.34 ! paf 201: VMethodFrame *frame=NEW VMethodFrame(pool(), *junction);
1.28 paf 202: PUSH(frame);
203: break;
204: }
205: case OP_STORE_PARAM:
206: {
207: Value *value=POP();
1.34 ! paf 208: VMethodFrame *frame=static_cast<VMethodFrame *>(stack[0]);
1.28 paf 209: frame->store_param(value);
1.29 paf 210: break;
211: }
212:
213: case OP_CALL:
214: {
215: printf("->\n");
1.34 ! paf 216: VMethodFrame *frame=static_cast<VMethodFrame *>(POP());
! 217: frame->fill_unspecified_params();
! 218: PUSH(self); PUSH(root); PUSH(rcontext); PUSH(wcontext);
1.29 paf 219: //left_class=ncontext.get_class()
220: //right_class=frame.self.get_class()
221: //self=f(left_class[thoughts' food], right_self[junction], right_class[static], wcontext.value()[dynamic], new(right_class)[construct])
1.34 ! paf 222: self=&frame->junction.self; // TODO: не всегда frame..self
1.29 paf 223: frame->set_self(self);
224: root=rcontext=wcontext=frame;
1.31 paf 225: execute(frame->junction.method->code);
1.29 paf 226: Value *value=wcontext->value();
1.32 paf 227: wcontext=static_cast<WContext *>(POP()); rcontext=POP(); root=POP(); self=POP();
1.29 paf 228: wcontext->write(value);
229: printf("<-returned");
1.28 paf 230: break;
231: }
232:
233:
1.11 paf 234: default:
1.16 paf 235: printf("\tTODO");
1.11 paf 236: break;
237: }
1.16 paf 238: printf("\n");
1.11 paf 239: }
1.1 paf 240: }
1.17 paf 241:
242: Value *Request::get_element() {
1.32 paf 243: String& name=POP_NAME();
1.24 paf 244: Value *ncontext=POP();
1.32 paf 245: Value *value=ncontext->get_element(name);
1.21 paf 246:
1.32 paf 247: if(value) {
248: Junction *junction=value->get_junction();
249: if(junction && junction->code) { // is it a code junction?
250: // autocalc it
251: printf("ja->\n");
252: PUSH(self); PUSH(root); PUSH(rcontext); PUSH(wcontext);
1.34 ! paf 253: // almost plain wwrapper about junction wcontext,
! 254: // BUT intercepts string writes
! 255: VCodeFrame frame(pool(), *junction->wcontext); wcontext=&frame;
! 256: self=&junction->self;
1.32 paf 257: root=junction->root;
258: rcontext=junction->rcontext;
259: execute(*junction->code);
1.34 ! paf 260: // CodeFrame soul: string writes intercepted
! 261: String *code_string_result=frame.get_string();
1.32 paf 262: wcontext=static_cast<WContext *>(POP()); rcontext=POP(); root=POP(); self=POP();
1.34 ! paf 263: // writing string result to current context
! 264: wcontext->write(code_string_result);
1.32 paf 265: printf("<-ja returned");
266: }
267: } else {
1.23 paf 268: value=NEW VUnknown(pool());
1.25 paf 269: value->set_name(name);
1.22 paf 270: }
1.17 paf 271: return value;
1.34 ! paf 272: }
E-mail: