rev 648 - in trunk: include/prothon pr/test src

SVN User <[email protected]> Mon, 21 Jun 2004 04:58:14 -0400
Newsgroups gmane.comp.lang.prothon.cvs
Message-ID <[email protected]>
Author: mark
Date: 2004-06-21 04:58:11 -0400 (Mon, 21 Jun 2004)
New Revision: 648

Modified:
   trunk/include/prothon/prothon.h
   trunk/pr/test/test.pr
   trunk/src/interp.c
   trunk/src/interp.h
   trunk/src/object.c
   trunk/src/parser_routines.c
Log:
default param values are now computed at call time,
working for f(), broken for obj.f() right now

Modified: trunk/include/prothon/prothon.h
===================================================================
--- trunk/include/prothon/prothon.h	2004-06-20 07:28:50 UTC (rev 647)
+++ trunk/include/prothon/prothon.h	2004-06-21 08:58:11 UTC (rev 648)
@@ -328,6 +328,7 @@
 	ITER_PROTO,			// 
 	THREAD_PROTO,		//   Thread
 	MUTEX_PROTO,		//   Mutex
+	PARMPTR_PROTO,		//
   
 // Exceptions
 	EXCEPTION,			//    Exception

Modified: trunk/pr/test/test.pr
===================================================================
--- trunk/pr/test/test.pr	2004-06-20 07:28:50 UTC (rev 647)
+++ trunk/pr/test/test.pr	2004-06-21 08:58:11 UTC (rev 648)
@@ -1,3 +1,14 @@
 #!/usr/bin/env prothon
 
-print DateTime(100000000000000000)
+y = 1
+
+def f(x=y):
+	print x
+	
+f()
+
+y=2
+
+f()
+
+

Modified: trunk/src/interp.c
===================================================================
--- trunk/src/interp.c	2004-06-20 07:28:50 UTC (rev 647)
+++ trunk/src/interp.c	2004-06-21 08:58:11 UTC (rev 648)
@@ -55,6 +55,7 @@
 
 #include <stdlib.h>
 #include <stdio.h>
+#include "parser.h"
 #include "interp.h"
 #include <prothon/prothon_dll.h>
 
@@ -100,7 +101,16 @@
 	fflush(tfout);
 }
 
-//******************************** create_frame *****************************
+//******************************** new_parmptr_obj ****************************
+obj_p new_parmptr_obj(isp ist, int ofs) {
+	obj_p new_obj = new_object(ist, OBJ(PARMPTR_PROTO));
+	SET_TYPE_IF_EXC(OBJ(PARMPTR_PROTO), new_obj, DATA_TYPE_IMMDATA) return NULL;
+	new_obj->data.i64 = ofs;
+	set_immutable(new_obj);
+	return new_obj;
+}
+
+//******************************** create_frame *******************************
 frame_p create_frame( isp ist, obj_p self, obj_p syn_locals, obj_p dyn_locals, 
 							   obj_p locals, obj_p func_obj, code_p code_in, char* name ) {
     obj_p prev_scope;
@@ -112,6 +122,7 @@
 	flen = sizeof(frame_t) + ( code ? (code->max_stack_depth+STACK_PADDING) * sizeof(obj_p) : 0 );
 	frame = pr_malloc(flen);
 	memset(frame, 0, flen);
+	frame->fparam_proc_state_idx = -1;
 
 	frame->func_name		  = name;
 	if (func_obj) {
@@ -405,7 +416,7 @@
 				fparam_proc_state->free_label_list_key = value;
 				fparam_proc_state->free_label_list_obj = NEW_DICT(10);
 			} else {
-				if (value) pstate = 1;
+				if (value != OBJ(NODEF)) pstate = 1;
 				clist_append(fparam_proc_state->lbl_val_list, label);
 				clist_append(fparam_proc_state->lbl_val_list, value);
 			}
@@ -483,38 +494,22 @@
 	return NULL;
 }
 
-//******************************** load_frame_params **************************
-void load_frame_params( isp ist,
-						obj_p locals, 
-					    obj_p func_obj, 
-					    int parm_cnt, obj_p *actparams) {
-	int i, llen;
+//******************************** get_frame_params **************************
+fparam_proc_state_t get_frame_params( isp ist,
+									  obj_p func_obj, 
+									  int parm_cnt, obj_p *actparams) {
 	fparam_proc_state_t fparam_proc_state;
 	switch (map_params(ist, &fparam_proc_state, func_obj, parm_cnt, actparams))
 		   {case 1: goto fparmerr; case 2: goto paramerr;}
-   	llen = fparam_proc_state.lbl_val_list ?
-		   clist_len(fparam_proc_state.lbl_val_list)/2 : 0;
-	for (i=0; i < llen; i++) {
-		if (!clist_item(fparam_proc_state.lbl_val_list, 2*i+1)) goto paramerr;
-		set_attr(ist,  locals, clist_item(fparam_proc_state.lbl_val_list, i*2), 
-			              clist_item(fparam_proc_state.lbl_val_list,(i*2)+1) );
-	}
-	if (fparam_proc_state.free_pos_list_key)
-		set_attr(ist,  locals, fparam_proc_state.free_pos_list_key, 
-			              fparam_proc_state.free_pos_list_obj );
-	if (fparam_proc_state.free_label_list_key)
-		set_attr(ist,  locals, fparam_proc_state.free_label_list_key, 
-			              fparam_proc_state.free_label_list_obj );
-	free_clist(fparam_proc_state.lbl_val_list);
-	return;
+	return fparam_proc_state;
 fparmerr:
 	free_clist(fparam_proc_state.lbl_val_list);
 	raise_exception(ist, OBJ(INTERPRETER_EXC), "Formal parameter sequence error");
-	return;
+	return fparam_proc_state;
 paramerr:
 	free_clist(fparam_proc_state.lbl_val_list);
 	raise_exception(ist, OBJ(INTERPRETER_EXC), "Parameters passed don't match formal parameters");
-	return;
+	return fparam_proc_state;
 }
 
 //******************************** add_frame_to_exception *********************
@@ -964,7 +959,6 @@
 						raise_exception( ist, OBJ(INTERPRETER_EXC), "attribute %s not found", 
 																	as_str(ist, key) );
 						break;
-						dump(ist, "!dump-obj.txt", OBJ(OBJECT));
 					}
 					fr_push(att);
 				}
@@ -1036,11 +1030,10 @@
 				fr_sp -= fparams_len+2;
 				if (fparams_len) {
 					obj_p fparams_obj = NEW_LIST(fparams_len);
-					pr_assert(sizeof(obj_p) == sizeof(obj_p));
 					memcpy( ((list_p)(obj_dataptr(fparams_obj)))->item, 
 							fr_stack+fr_sp+2, fparams_len*sizeof(obj_p) );
 					listlen(fparams_obj) = fparams_len;
-					set_attr(ist, func,    SYM(FPARAMS_),  fparams_obj);
+					set_attr(ist, func, SYM(FPARAMS_), fparams_obj);
 				}
 				set_attr(ist, func, SYM(PREVSCOPE_),  frame->locals);
 				set_attr(ist, func, SYM(CONT_),       fr_stack[fr_sp]);
@@ -1176,13 +1169,16 @@
 				fr_push(bound_meth);
 			}	break;
 			case OP_OBJCALL: {
+				if (frame->fparam_proc_state_idx >= 0) {
+					clist_item( frame->fparam_proc_state.lbl_val_list,
+						       (frame->fparam_proc_state_idx*2)+1 ) = fr_pop;
+				}
 				fr_sp -= 2+2*param;
 				func_obj = fr_stack[fr_sp];
 				if (func_obj->data_type == DATA_TYPE_EXTPTR) {
 					obj_p res, self;
 					clist_p plist;
 					if (!func_obj->data.ptr) goto no_func_ptr;
-					plist = get_func_params(ist, func_obj, param*2, fr_stack+fr_sp+2);
 					if ( !(self = fr_stack[fr_sp+1]) &&
 						 !(self = get_attr(ist, func_obj, SYM(BINDOBJ_))) &&
 						 !(self = frame->self) &&
@@ -1190,6 +1186,7 @@
 						 raise_exception(ist, OBJ(INTERNAL_EXC), "no self for this function");
 						 break;
 					}
+					plist = get_func_params(ist, func_obj, param*2, fr_stack+fr_sp+2);
 					IF_EXC_BREAK;
 					pre_call_lock(ist, self, plist); IF_EXC_BREAK;
 					res = ((pr_func*)(func_obj->data.ptr))
@@ -1204,10 +1201,51 @@
 				} else if ( func_obj != OBJ(FUNC_PROTO) && 
 					        has_proto(ist, func_obj, OBJ(FUNC_PROTO)) ) {
 					obj_p new_locals, self;
+					int llen;
 					frame_p new_frame;
 					IF_EXC_BREAK;
 					if (!func_obj->data.ptr) goto no_func_ptr;
+					if (frame->fparam_proc_state_idx == -1) {
+						frame->fparam_proc_state = 
+								get_frame_params(ist, func_obj, param*2, fr_stack+fr_sp+2);
+						IF_EXC_BREAK;
+					}
+					llen = frame->fparam_proc_state.lbl_val_list ?
+									clist_len(frame->fparam_proc_state.lbl_val_list)/2 : 0;
+					for (i=frame->fparam_proc_state_idx+1; i < llen; i++) {
+						obj_p parm = clist_item(frame->fparam_proc_state.lbl_val_list, 2*i+1);
+						if (!parm) {
+							raise_exception(ist, OBJ(INTERPRETER_EXC), "Parameters passed don't match formal parameters");
+							free_clist(frame->fparam_proc_state.lbl_val_list);
+							frame->fparam_proc_state_idx = -1;
+							goto break_loc;
+						}
+						if (has_proto(ist, parm, OBJ(PARMPTR_PROTO))) {
+							frame_p new_frame;
+							code_p codep = (void*)(((char*)func_obj->data.ptr)+parm->data.i64);
+							new_frame = create_frame( ist, frame->self, frame->syn_locals, frame->dyn_locals,
+						                                   frame->locals, NULL, codep, NULL );							
+							fr_next = new_frame;
+							new_frame->prev_frame = frame;
+							switch_frame = new_frame;
+							fr_sp += 2+2*param;
+							fr_push(OBJ(NONE));
+							frame->fparam_proc_state_idx = i;
+							goto break_loc;
+						}
+					}
+					frame->fparam_proc_state_idx = -1;
 					new_locals = NEW_OBJ(NULL);
+					for (i=0; i < llen; i++)
+						set_attr(ist, new_locals, clist_item(frame->fparam_proc_state.lbl_val_list, i*2), 
+								      clist_item(frame->fparam_proc_state.lbl_val_list,(i*2)+1) );
+					if (frame->fparam_proc_state.free_pos_list_key)
+						set_attr(ist, new_locals, frame->fparam_proc_state.free_pos_list_key, 
+									  frame->fparam_proc_state.free_pos_list_obj );
+					if (frame->fparam_proc_state.free_label_list_key)
+						set_attr(ist, new_locals, frame->fparam_proc_state.free_label_list_key, 
+									  frame->fparam_proc_state.free_label_list_obj );
+					free_clist(frame->fparam_proc_state.lbl_val_list);
 					if ( !(self = fr_stack[fr_sp+1]) &&
 						 !(self = get_attr(ist, func_obj, SYM(BINDOBJ_))) &&
 						 !(self = frame->self) &&
@@ -1220,8 +1258,6 @@
 						                      new_locals, func_obj, NULL, NULL );
 					fr_next = new_frame;
 					new_frame->prev_frame = frame;
-					load_frame_params(ist, new_locals, func_obj, param*2, fr_stack+fr_sp+2);
-					IF_EXC_BREAK;
 					switch_frame = new_frame;
 					fr_push(OBJ(NONE));
 				} else if (has_proto(ist, func_obj, OBJ(GEN_PROTO))) {
@@ -1230,13 +1266,15 @@
 					obj_p new_locals;
 
 					IF_EXC_BREAK;
+
 					new_locals = NEW_OBJ(NULL);
+					get_frame_params(ist, func_obj, param*2, fr_stack+fr_sp+2);
+					IF_EXC_BREAK;
+
 					genp->frame = create_frame( ist, NULL, NULL, frame->locals,
 												new_locals, func_obj, codep, NULL );
 					genp->frame->gen_marker = func_obj;
 					frame->next_frame = genp->frame;
-					load_frame_params(ist, genp->frame->locals, func_obj, param*2, fr_stack+fr_sp+2);
-					IF_EXC_BREAK;
 					fr_push(func_obj);
 				} else {
 					memmove(fr_stack+fr_sp+2, fr_stack+fr_sp+1, (param*2+1) * sizeof(obj_p));
@@ -1414,7 +1452,7 @@
 						                           new_locals, func_obj, NULL, NULL );
 					fr_next = new_frame;
 					new_frame->prev_frame = frame;
-					load_frame_params(ist, new_locals, func_obj, param*2, fr_stack+fr_sp+3);
+					get_frame_params(ist, func_obj, param*2, fr_stack+fr_sp+3);
 					IF_EXC_BREAK;
 					switch_frame = new_frame;
 					fr_push(OBJ(NONE));
@@ -1428,7 +1466,7 @@
 												new_locals, func_obj, codep, NULL );
 					genp->frame->gen_marker = func_obj;
 					frame->next_frame = genp->frame;
-					load_frame_params(ist, genp->frame->locals, func_obj, param*2, fr_stack+fr_sp+3);
+					get_frame_params(ist, func_obj, param*2, fr_stack+fr_sp+3);
 					IF_EXC_BREAK;
 					fr_push(func_obj);
 				} else {
@@ -1478,7 +1516,7 @@
 						obj_p str_obj = call_func0(ist, fr_stack[fr_sp+i], SYM(STR_));
 						IF_EXC_BREAK;
 						printf("%s ", pr2c_strptr(ist, str_obj));
-					} else if (i == param-1) goto endcase;
+					} else if (i == param-1) goto break_loc;
 				printf("\n");
 			}   break;
 			case OP_IMPORT:    
@@ -1537,12 +1575,12 @@
 				raise_exception(ist, OBJ(INTERNAL_EXC), "Bad opcode: %d", op);
 			}
 		}
-endcase:
+break_loc:
 
 #ifdef TRACE_INTERPRETER
 		if (trace_interpreter) trace_step(frame);
 #endif
-		if (!intrp_exobj) {
+		if (!intrp_exobj && frame->fparam_proc_state_idx == -1) {
 			if (op < OP_PARAM_WORDS_BOUNDARY)
 				fr_pc += param;
 			else if (op < OP_TWO_WORDS_BOUNDARY)
@@ -1719,7 +1757,7 @@
 		new_frame->called_from_c = TRUE;
 		ist->frame->next_frame = new_frame;
 		new_frame->prev_frame = ist->frame;
-		load_frame_params( ist, new_locals, func_obj, parm_cnt, lbl_val_arr);
+		get_frame_params( ist, func_obj, parm_cnt, lbl_val_arr);
 		ist->frame = new_frame;
 		if (intrp_exobj) {
 			if (!func_sym) del_unlock(self);
@@ -1989,7 +2027,7 @@
 	new_frame = create_frame(ist, thread_module, thread_module, NULL, new_locals, func_obj, NULL , NULL);
 	new_frame->called_from_c = TRUE;
 	new_frame->prev_frame = NULL;
-	load_frame_params( ist, new_locals, func_obj, parm_cnt, lbl_val_arr);
+	get_frame_params( ist, func_obj, parm_cnt, lbl_val_arr);
 	if (intrp_exobj) {
 		printf("User thread exception");
 		check_exceptions(ist);

Modified: trunk/src/interp.h
===================================================================
--- trunk/src/interp.h	2004-06-20 07:28:50 UTC (rev 647)
+++ trunk/src/interp.h	2004-06-21 08:58:11 UTC (rev 648)
@@ -75,24 +75,36 @@
 #define INITIAL_EXCEPTION_STACK_SIZE	10
 #define EXCEPTION_STACK_GROWTH_FACTOR	2
 
+typedef struct {
+	int			pos_ptr;
+	clist_p		lbl_val_list;
+	int*		occupied_list;
+	obj_p		free_pos_list_key;
+	obj_p		free_pos_list_obj;
+	obj_p		free_label_list_key;
+	obj_p		free_label_list_obj;
+} fparam_proc_state_t;
+
 typedef struct frame_t {
-	frame_p		next_frame;
-	frame_p		prev_frame;
-	int			called_from_c;
-	int			do_not_free;
-	obj_p		gen_marker;
-	obj_p		func;
-	obj_p		syn_self;
-	obj_p		self;
-	obj_p		syn_locals;
-	obj_p		dyn_locals;
-	obj_p		locals;
-	int			pc;
-	code_p		code;
-	clist_p		exc_stack;
-	int			stack_ptr;
-	char*		func_name;
-	obj_p		stack[];
+	frame_p				next_frame;
+	frame_p				prev_frame;
+	int					called_from_c;
+	int					do_not_free;
+	obj_p				gen_marker;
+	obj_p				func;
+	obj_p				syn_self;
+	obj_p				self;
+	obj_p				syn_locals;
+	obj_p				dyn_locals;
+	obj_p				locals;
+	int					pc;
+	code_p				code;
+	clist_p				exc_stack;
+	int					stack_ptr;
+	char*				func_name;
+	fparam_proc_state_t fparam_proc_state;
+	int					fparam_proc_state_idx;
+	obj_p				stack[];
 } frame_t;
 
 typedef struct {
@@ -104,16 +116,6 @@
 #define intrp_exobj		(ist? ist->exception_obj : NULL)
 
 typedef struct {
-	int			pos_ptr;
-	clist_p		lbl_val_list;
-	int*		occupied_list;
-	obj_p		free_pos_list_key;
-	obj_p		free_pos_list_obj;
-	obj_p		free_label_list_key;
-	obj_p		free_label_list_obj;
-} fparam_proc_state_t;
-
-typedef struct {
 	code_p		codep;
 	frame_p		frame;
 } gen_t;
@@ -133,6 +135,9 @@
 				 obj_p module_in, char* exec_string );
 obj_p exec_loop(isp ist);
 
+
+obj_p new_parmptr_obj(isp ist, int ofs);
+
 #define fr_next			(frame->next_frame)
 #define fr_prev			(frame->prev_frame)
 #define fr_ccall		(frame->called_from_c)

Modified: trunk/src/object.c
===================================================================
--- trunk/src/object.c	2004-06-20 07:28:50 UTC (rev 647)
+++ trunk/src/object.c	2004-06-21 08:58:11 UTC (rev 648)
@@ -232,6 +232,7 @@
 	OBJ(SUPER_PROTO)         = NEW_OBJ(NULL);
 	OBJ(THREAD_PROTO)       = NEW_OBJ(NULL);
 	OBJ(MUTEX_PROTO)        = NEW_OBJ(NULL);
+	OBJ(PARMPTR_PROTO)      = NEW_OBJ(NULL);
 	OBJ(ROOT_GLOBALS)       = NEW_OBJ(NULL);
 	OBJ(MODULES)            = NEW_OBJ(NULL);
 	OBJ(EXCEPTION)          = NEW_OBJ(NULL);

Modified: trunk/src/parser_routines.c
===================================================================
--- trunk/src/parser_routines.c	2004-06-20 07:28:50 UTC (rev 647)
+++ trunk/src/parser_routines.c	2004-06-21 08:58:11 UTC (rev 648)
@@ -57,6 +57,7 @@
 #include <stdio.h>
 #include <memory.h>
 #include <string.h>
+#include "interp.h"
 #include "parser.h"
 #include "bytecodes.h"
 
@@ -590,7 +591,7 @@
 }
 code_p label_eq_expr_to_formparm(void* param, obj_p label, code_p expr) {
 	data_size_t data_size;
-	expr->len += 2;
+	expr->len += 5;
 	expr->stack_depth++;
 	expr->max_stack_depth++;
 	data_size = sizeof(code)+(expr->len)*sizeof(code_t);
@@ -600,6 +601,10 @@
 	expr->code_data[0].bytecode.opcode = OP_PUSH;
 	expr->code_data[0].bytecode.param  = 2;
 	expr->code_data[1].data = sym(IST, pr2c_strptr(IST, label));
+	expr->code_data[expr->len-3].bytecode.opcode = OP_SWAP;
+	expr->code_data[expr->len-2].bytecode.opcode = OP_POP;
+	expr->code_data[expr->len-2].bytecode.param  = 1;
+	expr->code_data[expr->len-1].bytecode.opcode = OP_RETURN;
 	return debug_retrn(__LINE__, expr);
 }
 code_p lbl_proto_body_to_obj(void* param, code_p ref, clist_p protos, code_p body) {
@@ -1288,11 +1293,14 @@
 	pr_assert(res->len == k);
 	return debug_retrn(__LINE__, res);
 }
+
 code_p ref_parm_body_to_def(void* param, code_p name, clist_p params, code_p self, code_p body, int flg) { 
 	code *res;
 	obj_p func;
-	int i, code_len, k=0, len=2, stack_depth=0, max_stack_depth=0;
-	int blen, llen=0, opcode = OP_NOP, pcnt = 0, depth_dec = 0;
+	int i, k=0, len=2, stack_depth=0, max_stack_depth=0;
+	int blen, llen=0, opcode = OP_NOP, pcnt = 0, depth_dec = 0, param_funcs_len = 0;
+	int hdr_in_codet = sizeof(code)/sizeof(code_t);
+	code_t *baseptr, *ptr;
 
 	if (params) llen = clist_len(params);
 	if (flg != OP_WITH) {
@@ -1309,19 +1317,33 @@
 	k=0;
 	if (name)
 		calc_code(name, &len, &stack_depth, &max_stack_depth); 
-
 	if (params) {
+		for(i=0; i < llen; i++) {
+			code_p param = (code_p)clist_item(params,i); 
+			if (param->len > 3) param_funcs_len += hdr_in_codet+param->len;
+		}
+	}
+	blen = hdr_in_codet + body->len;
+	func = new_object(IST, OBJ(FUNC_PROTO));
+	baseptr = ptr = obj_malloc(IST, OBJ(FUNC_PROTO), func, (blen+param_funcs_len)*sizeof(code_t));
+	memcpy(ptr, body, blen * sizeof(code_t));
+	if (params) {
+		ptr += blen;
 		len++;
-		for(i=0; i < llen; i++)
-			calc_code( (code_p)clist_item(params,i), 
-						&len, &stack_depth, &max_stack_depth ); 
+		for(i=0; i < llen; i++) {
+			code_p param = (code_p)clist_item(params,i); 
+			if (param->len == 3) {
+				calc_code( (code_p)clist_item(params,i), 
+						    &len, &stack_depth, &max_stack_depth ); 
+			} else {
+				len += 3;
+				max_stack_depth = max(max_stack_depth, stack_depth+2);
+				stack_depth += 2;
+				memcpy(ptr, param, (hdr_in_codet+param->len)*sizeof(code_t));
+				ptr += hdr_in_codet+param->len;
+			}
+		}
 	}
-
-	blen = sizeof(code)/sizeof(code_t) + body->len;
-	func = new_object(IST, OBJ(FUNC_PROTO));
-	code_len = blen * sizeof(code_t);
-	memmove(obj_malloc(IST, OBJ(FUNC_PROTO), func, code_len), body, code_len);
-
 	if (self) {
 		calc_code(self, &len, &stack_depth, &max_stack_depth); 
 		len++;
@@ -1329,9 +1351,21 @@
 	res = new_code(param, len, stack_depth, max_stack_depth, 0);
 	if (name)
 		add_code(name, res, &k);
-	if (params)
-		for(i=0; i < llen; i++)
-			add_code(clist_item(params,i), res, &k);
+	if (params) {
+		ptr = baseptr + blen;
+		for(i=0; i < llen; i++) {
+			code_p parm = (code_p)clist_item(params,i); 
+			if (parm->len == 3) {
+				add_code(parm, res, &k);
+			} else {
+				res->code_data[k  ].bytecode.opcode = OP_PUSH;
+				res->code_data[k++].bytecode.param  = 3;
+				res->code_data[k++].data = parm->code_data[1].data;
+				res->code_data[k++].data = new_parmptr_obj(IST, (int)(ptr-baseptr)*sizeof(code_t));
+				ptr += hdr_in_codet+parm->len;
+			}
+		}
+	}			
 	if (self)
 		add_code(self, res, &k);
 	switch (flg) {