File:  [parser3project] / parser3 / src / main / execute.C
Revision 1.31: download - view: text, annotated - select for diffs - revision graph
Fri Feb 23 21:59:07 2001 UTC (25 years, 4 months ago) by paf
Branches: MAIN
CVS tags: HEAD
get_method RIP. junctions everywhere. call with junctions0

/*
  $Id: execute.C,v 1.31 2001/02/23 21:59:07 paf Exp $
*/

#include "pa_array.h" 
#include "code.h"
#include "pa_request.h"
#include "pa_vstring.h"
#include "pa_vhash.h"
#include "pa_vunknown.h"
#include "pa_vframe.h"
#include "pa_wwrapper.h"

#include <stdio.h>

#define PUSH(value) stack.push(value)
#define POP() static_cast<Value *>(stack.pop())
#define POP_SR() static_cast<Value *>(stack.pop())->as_string()


char *opcode_name[]={
	"STRING",  "CODE_ARRAY",
	"WITH_ROOT",	"WITH_SELF",	"WITH_READ",	"WITH_WRITE",
	"CONSTRUCT",
	"EXPRESSION_EVAL",	"MODIFY_EVAL",
	"WRITE",
	"GET_ELEMENT",	"GET_ELEMENT__WRITE",
	"CREATE_EWPOOL",	"REDUCE_EWPOOL",
	"CREATE_RWPOOL",	"REDUCE_RWPOOL",
	"GET_METHOD_FRAME",
	"CREATE_JUNCTION",
	"STORE_PARAM",
	"CALL"
};

void dump(int level, const Array& ops) {
	if(0){
		int size=ops.size();
		//printf("size=%d\n", size);
		for(int i=0; i<size; i++) {
			Operation op;
			op.cast=ops.quick_get(i);
			printf("%8X\n", op.cast);
		}
	}

	int size=ops.size();
	//printf("size=%d\n", size);
	for(int i=0; i<size; i++) {
		Operation op;
		op.cast=ops.quick_get(i);
		printf("%*s%s", level*4, "", opcode_name[op.code]);

		if(op.code==OP_STRING) {
			VString *vstring=static_cast<VString *>(ops.quick_get(++i));
			printf(" \"%s\"", vstring->get_string()->cstr());
		}
		printf("\n");

		if(op.code==OP_CODE_ARRAY) {
			const Array *local_ops=reinterpret_cast<const Array *>(ops.quick_get(++i));
			dump(level+1, *local_ops);
		}
	}
}

void Request::execute(Array& ops) {
	if(1) {
		puts("---------------------------");
		dump(0, ops);
		puts("---------------------------");
	}

	int size=ops.size();
	//printf("size=%d\n", size);
	for(int i=0; i<size; i++) {
		Operation op;
		op.cast=ops.quick_get(i);
		printf("%d:%s", stack.top(), opcode_name[op.code]);

		if(op.code==OP_CODE_ARRAY) {
			const Array *local_ops=reinterpret_cast<const Array *>(ops.quick_get(++i));
			//dump(level+1, *local_ops);
		}
		
		switch(op.code) {
		case OP_WITH_WRITE: 
			{
				PUSH(wcontext);
				break;
			}
		case OP_WITH_READ: 
			{
				PUSH(rcontext);
				break;
			}
		case OP_WITH_ROOT: 
			{
				PUSH(root);
				break;
			}
		case OP_WITH_SELF: 
			{
				PUSH(self);
				break;
			}
			
		case OP_STRING:
			{
				VString *vstring=static_cast<VString *>(ops.quick_get(++i));
				printf(" \"%s\"", vstring->get_string()->cstr());
				PUSH(vstring);
				break;
			}
			
		case OP_CONSTRUCT:
			{
				Value *value=POP();
				String& name=POP_SR();
				Value *ncontext=POP();
				value->set_name(name);
				ncontext->put_element(name, value);
				break;
			}
			
		case OP_WRITE:
			{
				Value *value=POP();
				wcontext->write(value);
				break;
			}
			
		case OP_GET_ELEMENT:
			{
				Value *value=get_element();
				PUSH(value);
				break;
			}

		case OP_GET_ELEMENT__WRITE:
			{
				Value *value=get_element();
				wcontext->write(value);
				break;
			}

		case OP_CREATE_EWPOOL:
			{
				PUSH(wcontext);
				wcontext=NEW WWrapper(pool(), 0 /* empty */);
				break;
			}
		case OP_REDUCE_EWPOOL:
			{
				Value *value=wcontext->value();
				wcontext=static_cast<WContext *>(POP());
				PUSH(value);
				break;
			}
			
		case OP_CREATE_RWPOOL:
			{
				Value *ncontext=POP();
				PUSH(rcontext);
				rcontext=ncontext;
				PUSH(wcontext);
				wcontext=NEW WWrapper(pool(), ncontext);
				break;
			}
		case OP_REDUCE_RWPOOL:
			{
				String *string=wcontext->get_string();
				Value *value=NEW VString(string);
				wcontext=static_cast<WContext *>(POP());
				rcontext=POP();
				PUSH(value);
				break;
			}

		case OP_GET_METHOD_FRAME:
			{
				Value *vjunction=POP();
				// [self/class?;params;local;code/native_code](name)
				Junction *junction=vjunction->get_junction();

				if(!junction)
					THROW(0,0,
						vjunction->name(),
						"not a method");

				//unless(method) method=operators.get_method[...;code/native_code](name)
				VFrame *frame=NEW VFrame(pool(), *junction);
				PUSH(frame);
				break;
			}
		case OP_STORE_PARAM:
			{
				Value *value=POP();
				VFrame *frame=static_cast<VFrame *>(stack[0]);
				frame->store_param(value);
				break;
			}

		case OP_CALL:
			{
				printf("->\n");
				VFrame *frame=static_cast<VFrame *>(POP());
				PUSH(root);  PUSH(self);  PUSH(rcontext);  PUSH(wcontext);
				//left_class=ncontext.get_class()
				//right_class=frame.self.get_class()
				//self=f(left_class[thoughts' food], right_self[junction], right_class[static], wcontext.value()[dynamic], new(right_class)[construct])
				self=frame->junction.self;
				frame->set_self(self);
				root=rcontext=wcontext=frame;
				execute(frame->junction.method->code);
				Value *value=wcontext->value();
				wcontext=static_cast<WContext *>(POP());  rcontext=POP();  self=POP();  root=POP();
				wcontext->write(value);
				printf("<-returned");
				break;
			}


		default:
			printf("\tTODO");
			break;
		}
		printf("\n");
	}
}

Value *Request::get_element() {
	String& name=POP_SR();
	Value *ncontext=POP();
	Value *value=ncontext->get_element(name); // name áûâàåò method, òîãäà âûäà¸ò new junction(ÀÂÒÎÂÛ×ÈÑËßÒÜ=false, root,self,rcontext,wcontext,code)
	// name áûâàåò èìÿ junction, òîãäà èëè îñòàâëÿåò â ïîêîå, èëè âû÷èñëÿåò â çàâèñèìîñòè îò ôëàãà ÀÂÒÎÂÛ×ÈÑËßÒÜ

	if(!value) {
		value=NEW VUnknown(pool());
		value->set_name(name);
	}
	return value;
}

E-mail: