rev 650 - in trunk: . pr/test src

SVN User <[email protected]> Tue, 22 Jun 2004 22:23:17 -0400
Newsgroups gmane.comp.lang.prothon.cvs
Message-ID <[email protected]>
Author: mark
Date: 2004-06-22 22:23:14 -0400 (Tue, 22 Jun 2004)
New Revision: 650

Added:
   trunk/pr/test/default.pr
Modified:
   trunk/STATUS.txt
   trunk/pr/test/test.pr
   trunk/src/builtins-core.c
   trunk/src/interp.c
   trunk/src/interp.h
Log:
default formal params are now live, added default.pr

Modified: trunk/STATUS.txt
===================================================================
--- trunk/STATUS.txt	2004-06-22 21:57:29 UTC (rev 649)
+++ trunk/STATUS.txt	2004-06-23 02:23:14 UTC (rev 650)
@@ -1,6 +1,13 @@
 
 ----------------------- TO-DO (highest priority first) ------------------------
 
+--- finish live formal param defaults, bugs, and easy changes
+--- evaluate default expressions on every function call
+
+--- fix raise command
+--- change proto() to newObject() 
+--- *args should be a tuple
+
 --- Python regrets from Paul and print proposal
 	http://www.prothon.org/pipermail/prothon-user/2004-June/001970.html
 	http://www.prothon.org/pipermail/prothon-user/2004-June/001991.html
@@ -8,13 +15,9 @@
 --- pretty print
 	http://www.prothon.org/pipermail/prothon-user/2004-June/002112.html
 
---- evaluate default expressions on every function call
-
 --- OSThread, Thread, and Gate
 --- lock keyword?
 
---- change proto() to newObject() 
-
 --- implement 1xc3fe ?
 --- implement taint attribute on strings, unTaint() method, respect in .fmt, eval, exec
 
@@ -44,9 +47,10 @@
 --- GNU message catalog _"abc" strings
 --- change all strings to resource file
 
---- Add properties methods: get_,  set_, delete_
+--- Add properties methods: prop keyword, get_,  set_, delete_, wildcards
 
 --- getAttr(name), setAttr(name, value), delAttr(name)
+
 --- add conditional expression "if C then x else y"
 
 --- support list and dictionary object params directly in string.fmt() ???
@@ -84,8 +88,6 @@
 
 --- switch mro method to C3
 
---- test += on modifiable type, i.e. __iadd__ type calls
-
 --- C API for profiling
 
 --- credit Ruby

Added: trunk/pr/test/default.pr
===================================================================
--- trunk/pr/test/default.pr	2004-06-22 21:57:29 UTC (rev 649)
+++ trunk/pr/test/default.pr	2004-06-23 02:23:14 UTC (rev 650)
@@ -0,0 +1,37 @@
+#!/usr/bin/env prothon
+
+def err(n):
+	print "\n test {n} failed".fmt()
+	sys.exit(1)
+
+z=0
+def f(x=y):
+	outer.z = x
+	
+y=1
+f(0)
+if z != 0: err(1)
+
+y=2
+f()
+if z != 2: err(2)
+
+y=3
+f()
+if z != 3: err(3)
+
+n=[]
+n.g=f
+y=4
+n.g(9)
+if z != 9: err(4)
+
+n.g()
+y=5
+t = Thread(f)
+Sleep(1.0)
+if z != 5: err(5)
+
+print """
+all tests passed
+"""


Property changes on: trunk/pr/test/default.pr
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: trunk/pr/test/test.pr
===================================================================
--- trunk/pr/test/test.pr	2004-06-22 21:57:29 UTC (rev 649)
+++ trunk/pr/test/test.pr	2004-06-23 02:23:14 UTC (rev 650)
@@ -1,14 +1,37 @@
 #!/usr/bin/env prothon
 
-y = 1
+def err(n):
+	print "\n test {n} failed".fmt()
+	sys.exit(1)
 
+z=0
 def f(x=y):
-	print x
+	outer.z = x
 	
-f()
+y=1
+f(0)
+if z != 0: err(1)
 
 y=2
+f()
+if z != 2: err(2)
 
+y=3
 f()
+if z != 3: err(3)
 
+n=[]
+n.g=f
+y=4
+n.g(9)
+if z != 9: err(4)
 
+n.g()
+y=5
+t = Thread(f)
+Sleep(1.0)
+if z != 5: err(5)
+
+print """
+all tests passed
+"""

Modified: trunk/src/builtins-core.c
===================================================================
--- trunk/src/builtins-core.c	2004-06-22 21:57:29 UTC (rev 649)
+++ trunk/src/builtins-core.c	2004-06-23 02:23:14 UTC (rev 650)
@@ -361,7 +361,7 @@
 	return call_func1(ist, parms[1], SYM(RNOTIN__QUES), self);
 }
 
-DEF(Object, CurrentThread, NULL) {
+DEF(Object, currentThread, NULL) {
 	return os_thread_2_obj(apr_os_thread_current());
 }
 
@@ -962,7 +962,7 @@
 	MODULE_ADD_SYM(Object, ge__QUES);
 	MODULE_ADD_SYM(Object, in__QUES);
 	MODULE_ADD_SYM(Object, notIn__QUES);
-	MODULE_ADD_SYM(Object, CurrentThread);
+	MODULE_ADD_SYM(Object, currentThread);
 	MODULE_ADD_SYM(Object, Sleep);
 	MODULE_ADD_SYM(Object, range);
 	MODULE_ADD_SYM(Object, toStorProxy_);

Modified: trunk/src/interp.c
===================================================================
--- trunk/src/interp.c	2004-06-22 21:57:29 UTC (rev 649)
+++ trunk/src/interp.c	2004-06-23 02:23:14 UTC (rev 650)
@@ -495,21 +495,53 @@
 }
 
 //******************************** 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;}
-	return fparam_proc_state;
+frame_p get_frame_params( isp ist, int* idx, fparam_proc_state_t* fparam_proc_state,
+			              obj_p* new_locals, obj_p func_obj, int parm_cnt, obj_p *actparams ) {
+	int i, llen;
+	if ((*idx) == -1) {
+		(*new_locals) = NEW_OBJ(NULL);
+		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=(*idx)+1; i < llen; i++) {
+		obj_p parm = clist_item((*fparam_proc_state).lbl_val_list, 2*i+1);
+		if (!parm) goto paramerr;
+		if (has_proto(ist, parm, OBJ(PARMPTR_PROTO))) {
+			obj_p eval_locals;
+			code_p codep = (void*)(((char*)func_obj->data.ptr)+parm->data.i64);
+			if (!func_obj) goto evalerr;
+			eval_locals = get_attr(ist, func_obj, SYM(PREVSCOPE_));
+			if (!eval_locals) goto evalerr;
+			(*idx) = i;
+			return create_frame( ist, NULL, NULL, (*new_locals), 
+				                 eval_locals, NULL, codep, NULL );							
+		}
+	}
+	(*idx) = -1;
+	for (i=0; i < llen; i++)
+		set_attr(ist, (*new_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, (*new_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, (*new_locals), (*fparam_proc_state).free_label_list_key, 
+						(*fparam_proc_state).free_label_list_obj );
+	goto done;
+evalerr:
+	raise_exception(ist, OBJ(INTERNAL_EXC), "default value not allowed here");
+	goto done;
 fparmerr:
-	free_clist(fparam_proc_state.lbl_val_list);
 	raise_exception(ist, OBJ(INTERPRETER_EXC), "Formal parameter sequence error");
-	return fparam_proc_state;
+	goto done;
 paramerr:
-	free_clist(fparam_proc_state.lbl_val_list);
 	raise_exception(ist, OBJ(INTERPRETER_EXC), "Parameters passed don't match formal parameters");
-	return fparam_proc_state;
+done:
+	(*idx) = -1;
+	free_clist((*fparam_proc_state).lbl_val_list);
+	return NULL;
 }
 
 //******************************** add_frame_to_exception *********************
@@ -731,21 +763,24 @@
 obj_p do_return( isp ist, frame_p frame, 
 				 frame_p *switch_frame, frame_p *free_frame, obj_p return_value ){
 	obj_p res = NULL;
+	if (fr_pc == fr_code->len && fr_sp == 0)
+		fr_push(OBJ(NONE));
+	if (fr_sp != 1) {
+		raise_exception(ist, OBJ(INTERNAL_EXC), "stack != 1 at return call");
+		return NULL;
+	}
 	if (fr_prev) {
-		if (fr_pc == fr_code->len && fr_sp == 0)
-			fr_push(OBJ(NONE));
-		if (fr_sp != 1) {
-			raise_exception(ist, OBJ(INTERNAL_EXC), "stack != 1 at return call");
-			return NULL;
-		}
 		if (fr_ccall) 
 			res = fr_tos;
 		else 
 			fr_prev->stack[fr_prev->stack_ptr-1] = fr_tos;
 		*switch_frame = fr_prev;
 		(*switch_frame)->next_frame = NULL;
-	} else
+	} else {
+		if (fr_ccall) 
+			res = fr_tos;
 		*switch_frame = DONE_FRAME_FLAG;
+	}
 	if (frame->gen_marker) {
 		if (frame->prev_frame) (frame->prev_frame->stack_ptr)--;
 		raise_exception(ist, OBJ(STOP_ITERATION_EXC), NULL);
@@ -1200,52 +1235,22 @@
 					fr_push(res);
 				} else if ( func_obj != OBJ(FUNC_PROTO) && 
 					        has_proto(ist, func_obj, OBJ(FUNC_PROTO)) ) {
-					obj_p new_locals, self;
-					int llen;
+					obj_p self;
 					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;
+					new_frame = get_frame_params( ist, &(frame->fparam_proc_state_idx), 
+						                               &(frame->fparam_proc_state), 
+									                   &(frame->new_locals), func_obj, param*2, fr_stack+fr_sp+2 );
+					IF_EXC_BREAK;
+					if (new_frame) {
+						fr_next = new_frame;
+						new_frame->prev_frame = frame;
+						switch_frame = new_frame;
+						fr_sp += 2+(2*param);
+						fr_push(OBJ(NONE));
+						goto break_loc;
 					}
-					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) &&
@@ -1255,7 +1260,7 @@
 					}
 					IF_EXC_BREAK;
 					new_frame = create_frame( ist, self, NULL, frame->locals, 
-						                      new_locals, func_obj, NULL, NULL );
+						                      frame->new_locals, func_obj, NULL, NULL );
 					fr_next = new_frame;
 					new_frame->prev_frame = frame;
 					switch_frame = new_frame;
@@ -1263,16 +1268,20 @@
 				} else if (has_proto(ist, func_obj, OBJ(GEN_PROTO))) {
 					gen_p  genp  = func_obj->data.ptr;
 					code_p codep = genp->codep;
-					obj_p new_locals;
-
+					frame_p new_frame = get_frame_params( ist, &(frame->fparam_proc_state_idx), 
+													   &(frame->fparam_proc_state), 
+									                   &(frame->new_locals), func_obj, param*2, fr_stack+fr_sp+2 );
 					IF_EXC_BREAK;
-
-					new_locals = NEW_OBJ(NULL);
-					get_frame_params(ist, func_obj, param*2, fr_stack+fr_sp+2);
-					IF_EXC_BREAK;
-
+					if (new_frame) {
+						fr_next = new_frame;
+						new_frame->prev_frame = frame;
+						switch_frame = new_frame;
+						fr_sp += 2+(2*param);
+						fr_push(OBJ(NONE));
+						goto break_loc;
+					}
 					genp->frame = create_frame( ist, NULL, NULL, frame->locals,
-												new_locals, func_obj, codep, NULL );
+												frame->new_locals, func_obj, codep, NULL );
 					genp->frame->gen_marker = func_obj;
 					frame->next_frame = genp->frame;
 					fr_push(func_obj);
@@ -1351,6 +1360,10 @@
 end_op_obj:		break;
 			case OP_CALL: {
 				obj_p name_obj;
+				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 -= 3+(2*param);
 				name_obj = fr_stack[fr_sp+1];
 				if (has_proto(ist, name_obj, OBJ(SUPER_PROTO))) {
@@ -1434,11 +1447,22 @@
 					fr_push(res);
 				} else if ( func_obj != OBJ(FUNC_PROTO) && 
 					        has_proto(ist, func_obj, OBJ(FUNC_PROTO)) ) {
-					obj_p new_locals, self;
+					obj_p self;
 					frame_p new_frame;
 					IF_EXC_BREAK;
 					if (!func_obj->data.ptr) goto no_func_ptr2;
-					new_locals = NEW_OBJ(NULL);
+					new_frame = get_frame_params( ist, &(frame->fparam_proc_state_idx), 
+													   &(frame->fparam_proc_state), 
+									                   &(frame->new_locals), func_obj, param*2, fr_stack+fr_sp+3);
+					IF_EXC_BREAK;
+					if (new_frame) {
+						fr_next = new_frame;
+						new_frame->prev_frame = frame;
+						switch_frame = new_frame;
+						fr_sp += 3+(2*param);
+						fr_push(OBJ(NONE));
+						goto break_loc;
+					}
 					if ( !(self = fr_stack[fr_sp+2]) &&
 						 !(self = get_attr(ist, func_obj, SYM(BINDOBJ_))) &&
 						 !(self = fr_stack[fr_sp]) &&
@@ -1449,25 +1473,32 @@
 					}
 					IF_EXC_BREAK;
 					new_frame = create_frame( ist, self, NULL, frame->locals, 
-						                           new_locals, func_obj, NULL, NULL );
+						                           frame->new_locals, func_obj, NULL, NULL );
 					fr_next = new_frame;
 					new_frame->prev_frame = frame;
-					get_frame_params(ist, func_obj, param*2, fr_stack+fr_sp+3);
-					IF_EXC_BREAK;
 					switch_frame = new_frame;
 					fr_push(OBJ(NONE));
 				} else if (has_proto(ist, func_obj, OBJ(GEN_PROTO))) {
 					gen_p  genp  = func_obj->data.ptr;
 					code_p codep = genp->codep;
-					obj_p new_locals;
+					frame_p new_frame;
 					IF_EXC_BREAK;
-					new_locals = NEW_OBJ(NULL);
-					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;
-					get_frame_params(ist, func_obj, param*2, fr_stack+fr_sp+3);
+					new_frame = get_frame_params( ist, &(frame->fparam_proc_state_idx), 
+													   &(frame->fparam_proc_state), 
+									                   &(frame->new_locals), func_obj, param*2, fr_stack+fr_sp+3);
 					IF_EXC_BREAK;
+					if (new_frame) {
+						fr_next = new_frame;
+						new_frame->prev_frame = frame;
+						switch_frame = new_frame;
+						fr_sp += 3+(2*param);
+						fr_push(OBJ(NONE));
+						goto break_loc;
+					}
+					genp->frame = create_frame( ist, NULL, NULL, frame->locals,
+												frame->new_locals, func_obj, codep, NULL );
 					fr_push(func_obj);
 				} else {
 					obj_p value;
@@ -1735,6 +1766,9 @@
 		        has_proto(ist, func_obj, OBJ(FUNC_PROTO)) ) {
 		frame_p frame, new_frame;
 		obj_p new_locals, aself; 
+		int idx;
+		fparam_proc_state_t fps;
+
 		if (!ist) {
 			raise_exception(ist, OBJ(INTERNAL_EXC), "Illegal function call to Prothon function");
 			if (!func_sym) del_unlock(self);
@@ -1745,19 +1779,21 @@
 			return 0;
 		}
 		frame = ist->frame;
-		new_locals = NEW_OBJ(NULL);
 		if (intrp_exobj) {
 			if (!func_sym) del_unlock(self);
 			return 0;
 		}
 		if (! (aself = get_attr(ist, func_obj, SYM(BINDOBJ_))) )
 			aself = self;   if_exc_return 0;
-		new_frame = create_frame(	ist, aself, NULL, NULL, 
-			                        new_locals, func_obj, NULL, NULL );
+		if (get_frame_params(ist, &idx, &fps, &new_locals, func_obj, parm_cnt, lbl_val_arr)) {
+			raise_exception(ist, OBJ(INTERNAL_EXC), "default values not allowed in call_func");
+			return NULL;
+		}
+		new_frame = create_frame( ist, aself, NULL, NULL, 
+			                      new_locals, func_obj, NULL, NULL );
 		new_frame->called_from_c = TRUE;
 		ist->frame->next_frame = new_frame;
 		new_frame->prev_frame = ist->frame;
-		get_frame_params( ist, func_obj, parm_cnt, lbl_val_arr);
 		ist->frame = new_frame;
 		if (intrp_exobj) {
 			if (!func_sym) del_unlock(self);
@@ -2011,6 +2047,8 @@
 	obj_p thread_obj = register_thread(handle);
 	pr_thread_p thread_p = thread_obj->data.ptr;
 	isp ist = thread_p->ist;
+	int idx = -1;
+	fparam_proc_state_t fps;
 
 	parm_cnt = (int) list_len(ist, uthread->params) * 2;
 	if (parm_cnt > MAX_NUM_PARAMS) {
@@ -2022,12 +2060,17 @@
 		lbl_val_arr[i]   = NULL;
 		lbl_val_arr[i+1] = list_item(ist, uthread->params, i/2);
 	}
-	new_locals = NEW_OBJ(NULL);
 	thread_module = NEW_OBJ(NULL);
+	while (new_frame = get_frame_params( ist, &idx, &fps, &new_locals, func_obj, parm_cnt, lbl_val_arr)) {
+		new_frame->called_from_c = TRUE;
+		new_frame->prev_frame = NULL;
+		ist->frame = new_frame;
+		clist_item(fps.lbl_val_list, (idx*2)+1) = exec_loop(ist);
+		if (ist->exception_obj) goto done;
+	}
 	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;
-	get_frame_params( ist, func_obj, parm_cnt, lbl_val_arr);
 	if (intrp_exobj) {
 		printf("User thread exception");
 		check_exceptions(ist);
@@ -2036,6 +2079,7 @@
 	}
 	ist->frame = new_frame;
 	exec_loop(ist);
+done:
 	check_exceptions(ist);
 	thread_p->running = FALSE;
 	return NULL;

Modified: trunk/src/interp.h
===================================================================
--- trunk/src/interp.h	2004-06-22 21:57:29 UTC (rev 649)
+++ trunk/src/interp.h	2004-06-23 02:23:14 UTC (rev 650)
@@ -104,6 +104,7 @@
 	char*				func_name;
 	fparam_proc_state_t fparam_proc_state;
 	int					fparam_proc_state_idx;
+	obj_p				new_locals;
 	obj_p				stack[];
 } frame_t;