rev 296 - in trunk: include/prothon pr src

SVN User <[email protected]>
Newsgroups gmane.comp.lang.prothon.cvs
Message-ID <[email protected]>
Author: mark
Date: 2004-04-06 18:43:52 -0400 (Tue, 06 Apr 2004)
New Revision: 296

Modified:
   trunk/include/prothon/prothon.h
   trunk/pr/meow.pr
   trunk/src/interp.c
   trunk/src/interp.h
   trunk/src/object.c
   trunk/src/symbol.c
Log:
Fixed super ( ^ ), all delegation is finished

Modified: trunk/include/prothon/prothon.h
===================================================================
--- trunk/include/prothon/prothon.h	2004-04-06 18:33:17 UTC (rev 295)
+++ trunk/include/prothon/prothon.h	2004-04-06 22:43:52 UTC (rev 296)
@@ -351,6 +351,7 @@
 	__GLOBALS__,
 	__SYN_LOCALS__,
 	__LOCALS__,
+	__SELF__,
 	RPARAM,
 	PARAM1,
 	PARAM2,
@@ -446,7 +447,7 @@
 // of prototypes.  This is used for "super" searches.
 // The ist param may return an exception object if proto pointers are missing 
 // or have a circular reference.  See section "INTERPRETER STATE".
-obj_p get_proto_attr(isp ist, obj_p object, obj_p key, obj_p *proto_pp, int second);
+obj_p get_proto_attr(isp ist, obj_p object, obj_p key, obj_p *proto_pp, obj_p super_obj);
 
 // DEL_ATTR: Find attr in object that matches a key and delete it.
 // Much like get-attr, except that when an attr is found it is deleted.

Modified: trunk/pr/meow.pr
===================================================================
--- trunk/pr/meow.pr	2004-04-06 18:33:17 UTC (rev 295)
+++ trunk/pr/meow.pr	2004-04-06 22:43:52 UTC (rev 296)
@@ -1,20 +1,36 @@
 #!/usr/bin/env prothon
 
-Mammal = Object()
-with Mammal:
+Animal = Object()
+with Animal:
    def .describe():
-       print "I am a mammal."
+       print "I am an animal."
        .make_noise()
    def .make_noise():
-     print "I make some kind of noise."
+     print "I make animal noise."
    
+Mammal = Animal()
+with Mammal:
+   def .describe():
+          print "I am a mammal."
+          f = Animal.describe		# any of these will work
+          f()						# super call type 1
+          (Animal.describe)()		# super call type 2
+          ^describe()				# super call type 3 
+          .make_noise()
+   def .make_noise():
+     print "I make mammal noise."
+   
 Cat = Mammal()
 with Cat:
      def .describe():
           print "I am a cat."
-          (Mammal.describe)()         #  <--  super call
+          f = Mammal.describe		# any of these will work
+          f()						# super call type 1
+          (Mammal.describe)()		# super call type 2
+          ^describe()				# super call type 3 
+          .make_noise()
      def .make_noise():
-       print "I go meow."
+       print "meow"
 
 c = Cat()
 c.describe()

Modified: trunk/src/interp.c
===================================================================
--- trunk/src/interp.c	2004-04-06 18:33:17 UTC (rev 295)
+++ trunk/src/interp.c	2004-04-06 22:43:52 UTC (rev 296)
@@ -95,7 +95,7 @@
 }
 
 //******************************** new_exec_frame *****************************
-exec_frame_t* new_exec_frame( isp ist, obj_p self, obj_p globals, 
+exec_frame_t* new_exec_frame( isp ist, obj_p syn_self, obj_p self, obj_p globals, 
 							           obj_p syn_locals, obj_p dyn_locals, obj_p locals, 
 							           obj_p func_obj, code* code_in ) {
 	exec_frame_t* frame;
@@ -106,6 +106,7 @@
 	flen = sizeof(exec_frame_t) + (code->max_stack_depth+STACK_PADDING) * sizeof(obj_p);
 	frame = pr_malloc(flen);
 	memset(frame, 0, flen);
+	frame->syn_self			= syn_self;
 	frame->self				= self;
 	frame->globals			= (func_obj ? get_attr(ist, func_obj, SYM(__GLOBALS__))    : globals);
 	frame->syn_locals		= (func_obj ? get_attr(ist, func_obj, SYM(__SYN_LOCALS__)) : syn_locals);
@@ -741,6 +742,7 @@
 				memcpy( ((list_p)(obj_data_p(fparams_obj)))->item, 
 						fr_stack+fr_sp+2, fparams_len*sizeof(list_item_t) );
 				listlen(fparams_obj) = fparams_len;
+				set_attr(ist, func,       SYM(__SELF__),    frame->self);
 				set_attr(ist, func,    SYM(__FPARAMS__),    fparams_obj);
 				set_attr(ist, func,    SYM(__GLOBALS__), frame->globals);
 				set_attr(ist, func, SYM(__SYN_LOCALS__),  frame->locals);
@@ -755,7 +757,7 @@
 #endif
 				if (op == OP_GEN) {
 					exec_frame_t* new_frame = new_exec_frame( ist, 
-							frame->self, NULL, NULL,
+							NULL, frame->self, NULL, NULL,
 							frame->dyn_locals, frame->locals, func, NULL );
 					new_frame->gen_marker = TRUE;
 					func->data.ptr = new_frame;
@@ -839,7 +841,7 @@
 				}
 				state = parse_file_or_string(ist, NULL, strch(str_obj));
 				if (!state || !(code = (state->parse_results))) break;
-				new_frame = new_exec_frame(	ist, frame->self, frame->globals, frame->syn_locals, 
+				new_frame = new_exec_frame(	ist, NULL, frame->self, frame->globals, frame->syn_locals, 
 						                         frame->dyn_locals, frame->locals, NULL, code    );
 				new_frame->globals    = frame->globals;
 				new_frame->syn_locals = frame->syn_locals;
@@ -862,16 +864,13 @@
 					free_clist(plist);
 					fr_push(res);
 				} else if (has_proto_QUES(ist, func_obj, OBJ(FUNC_PROTO))) {
-					obj_p new_locals;
+					obj_p new_locals, syn_self;
 					exec_frame_t* new_frame;
 					if (intrp_exobj) break;
 					new_locals = new_object(ist, NULL);
-					new_frame = new_exec_frame(	ist, 
-												frame->self,		    // self
-												NULL, NULL,			
-												frame->locals,		    // dyn_locals,
-												new_locals,				// locals,
-												func_obj, NULL );
+					syn_self = get_attr(ist, func_obj, SYM(__SELF__)); if (intrp_exobj) break;
+					new_frame = new_exec_frame(	ist, syn_self, frame->self, NULL, NULL,			
+												frame->locals, new_locals, func_obj, NULL );
 					fr_next = new_frame;
 					new_frame->prev_frame = frame;
 					load_frame_params(ist, frame, func_obj, param*2, fr_stack+fr_sp+1);
@@ -897,7 +896,7 @@
 			}	break;
 			case OP_WITH:
 				fr_sp--;
-				switch_frame = new_exec_frame( ist, fr_stack[fr_sp], frame->globals, frame->syn_locals, 
+				switch_frame = new_exec_frame( ist, NULL, fr_stack[fr_sp], frame->globals, frame->syn_locals, 
 											        frame->dyn_locals, frame->locals, fr_data(1), NULL );
 				switch_frame->prev_frame = frame;
 				frame->next_frame = switch_frame;
@@ -905,7 +904,7 @@
 			case OP_CALL: {
 				fr_sp -= 2+(2*param);
 				if (has_proto_QUES(ist, fr_stack[fr_sp+1], OBJ(SUPER_PROTO))) {
-					func_obj = get_proto_attr(ist, fr_stack[fr_sp], fr_stack[fr_sp+1]->data.ptr, NULL, TRUE);
+					func_obj = get_proto_attr(ist, fr_stack[fr_sp], fr_stack[fr_sp+1]->data.ptr, NULL, frame->syn_self);
 					goto got_func;
 				}
 				if (!has_proto_QUES(ist, fr_stack[fr_sp+1], OBJ(SYMBOL_PROTO))) {
@@ -925,7 +924,7 @@
 				}
 				if (intrp_exobj) break;
 get_func:
-				func_obj = get_proto_attr(ist, fr_stack[fr_sp], fr_stack[fr_sp+1], NULL, FALSE);
+				func_obj = get_proto_attr(ist, fr_stack[fr_sp], fr_stack[fr_sp+1], NULL, NULL);
 got_func:
 				if (intrp_exobj) break;
 				if (!func_obj) {
@@ -952,16 +951,13 @@
 					else
 						fr_push(res);
 				} else if (has_proto_QUES(ist, func_obj, OBJ(FUNC_PROTO))) {
-					obj_p new_locals;
+					obj_p new_locals, syn_self;
 					exec_frame_t* new_frame;
 					if (intrp_exobj) break;
 					new_locals = new_object(ist, NULL);
-					new_frame = new_exec_frame(	ist, 
-						                        fr_stack[fr_sp],		// self
-												NULL, NULL, 
-												frame->locals,		    // dyn_locals,
-												new_locals,				// locals,
-												func_obj, NULL );
+					syn_self = get_attr(ist, func_obj, SYM(__SELF__)); if (intrp_exobj) break;
+					new_frame = new_exec_frame(	ist, syn_self,  fr_stack[fr_sp], NULL, NULL, 
+												frame->locals, new_locals, func_obj, NULL );
 					fr_next = new_frame;
 					new_frame->prev_frame = frame;
 					load_frame_params(ist, frame, func_obj, param*2, fr_stack+fr_sp+2);
@@ -979,7 +975,7 @@
 					obj_p value;
 					if (fr_stack[fr_sp+1] != SYM(__INIT__)) {
 						value = get_proto_attr(ist, fr_stack[fr_sp],
-								fr_stack[fr_sp+1], NULL, FALSE);
+								fr_stack[fr_sp+1], NULL, NULL);
 						if (intrp_exobj) break;
 						if (value) {
 							memmove(&fr_stack[fr_sp+3], &fr_stack[fr_sp+2], param*2*sizeof(obj_p));
@@ -1175,7 +1171,7 @@
 				 int parm_cnt, obj_p* lbl_val_arr, obj_p dyn_locals ) {
     obj_p func_obj;
 	if (func_sym) {
-		func_obj = get_proto_attr(ist, self, func_sym, NULL, FALSE); if_exc_return NULL;
+		func_obj = get_proto_attr(ist, self, func_sym, NULL, NULL); if_exc_return NULL;
 		if (!func_obj) {
 			if (!ist) {
 				printf("Internal error with exceptions disabled: Function not found: \"%s\"", as_str(ist, func_sym));
@@ -1203,7 +1199,7 @@
 		return res;
 	} else if (has_proto_QUES(ist, func_obj, OBJ(FUNC_PROTO))) {
 		exec_frame_t *frame, *new_frame;
-		obj_p new_locals; 
+		obj_p new_locals, syn_self; 
 		if (!ist) {
 			raise_exception(ist, OBJ(INTERNAL_EXC), "Illegal function call to Prothon function");
 			if (!func_sym) del_unlock(self);
@@ -1215,7 +1211,13 @@
 		}
 		frame = ist->frame;
 		new_locals = new_object(ist, NULL);
-		new_frame = new_exec_frame(	ist, self, NULL, NULL, dyn_locals, new_locals, func_obj, NULL );
+		syn_self = get_attr(ist, func_obj, SYM(__SELF__));
+		if (intrp_exobj) {
+			if (!func_sym) del_unlock(self);
+			return 0;
+		}
+		new_frame = new_exec_frame(	ist, syn_self, self, NULL, NULL, dyn_locals, 
+			                        new_locals, func_obj, NULL );
 		new_frame->called_from_c = TRUE;
 		ist->frame->next_frame = new_frame;
 		new_frame->prev_frame = ist->frame;
@@ -1302,18 +1304,18 @@
 #endif
 	if (frame_p && *frame_p) {
 		frame = *frame_p;
-		new_frame = new_exec_frame( ist, frame->self, frame->globals, 
-						frame->syn_locals, frame->dyn_locals, frame->locals, NULL, code );
+		new_frame = new_exec_frame( ist, NULL, frame->self, frame->globals, 
+						            frame->syn_locals, frame->dyn_locals, frame->locals, NULL, code );
 		pr_free(*frame_p);
 		frame = NULL;
 	} else {
 		frame = ist->frame;
 		if (frame)
-			new_frame = new_exec_frame( ist, frame->self, frame->globals, 
+			new_frame = new_exec_frame( ist, NULL, frame->self, frame->globals, 
 						frame->syn_locals, frame->dyn_locals, frame->locals, NULL, code );
 		else {
 			new_locals = new_object(ist, NULL);
-			new_frame = new_exec_frame( ist, OBJ(ROOT_GLOBALS), OBJ(ROOT_GLOBALS), 
+			new_frame = new_exec_frame( ist, NULL, OBJ(ROOT_GLOBALS), OBJ(ROOT_GLOBALS), 
 										new_locals, new_locals, new_locals, NULL, code );
 		}
 	}
@@ -1367,7 +1369,7 @@
 	frame = ist->frame;
 	new_locals = new_object(ist, NULL);
 	set_attr(ist, module, SYM(__LOCALS__), new_locals);
-	new_frame = new_exec_frame( ist, module, module, dest_module, dyn_locals, new_locals, NULL, code );
+	new_frame = new_exec_frame( ist, NULL, module, module, dest_module, dyn_locals, new_locals, NULL, code );
 	new_frame->called_from_c = TRUE;
 	if (frame) ist->frame->next_frame = new_frame;
 	new_frame->prev_frame = ist->frame;

Modified: trunk/src/interp.h
===================================================================
--- trunk/src/interp.h	2004-04-06 18:33:17 UTC (rev 295)
+++ trunk/src/interp.h	2004-04-06 22:43:52 UTC (rev 296)
@@ -78,6 +78,7 @@
 	int			calling_init;
 	int			do_not_free;
 	int			gen_marker;
+	obj_p		syn_self;
 	obj_p		self;
 	obj_p		syn_locals;
 	obj_p		dyn_locals;

Modified: trunk/src/object.c
===================================================================
--- trunk/src/object.c	2004-04-06 18:33:17 UTC (rev 295)
+++ trunk/src/object.c	2004-04-06 22:43:52 UTC (rev 296)
@@ -622,19 +622,20 @@
 //********************************* get_proto_attr *****************************
 // same as get_attr but will look in all protos for key as well
 // if proto_pp not null, then will return proto obj that attr was found in
-obj_p get_proto_attr(isp ist, obj_p objid, obj_p key, obj_p *proto_pp, int second) {
+// if super_obj specified, then only objects after super_obj searched
+obj_p get_proto_attr(isp ist, obj_p objid, obj_p key, obj_p *proto_pp, obj_p super_obj) {
 	obj_p  obj=objid, proto, res;
 	int i, j, len;
 	clist_t *pao_list;
 	if (proto_pp) *proto_pp = NULL;
 	while (TRUE){
 		rdlock_rtrn(obj) NULL;
-		if( (res = get_attr(ist, obj, key)) || obj == OBJ(OBJECT) ) {
-			if (!second) {
-				read_unlock(ist, obj);
-				break;
-			} else second = FALSE;
+		if((!super_obj && (res = get_attr(ist, obj, key))) || obj == OBJ(OBJECT)) {
+			read_unlock(ist, obj);
+			break;
 		}
+		if (obj == super_obj)
+			super_obj = NULL;
 		if ((len = proto_len(ist, obj)) == 1) {
 			proto = proto_item(ist, obj, 0);
 			read_unlock(ist, obj);
@@ -686,25 +687,28 @@
 			return NULL;
 		}
 		clist_append(pao_list, OBJ(OBJECT));
-		for (j = clist_len(pao_list)-1; j > 0; j--)
-			if ((proto = clist_item(pao_list,j)))
-				for(i=0; i < j; i++)
+		for (j = clist_len(pao_list)-1; j > 0; j--) {
+			if ((proto = clist_item(pao_list,j))) {
+				for(i=0; i < j; i++) {
 					if(clist_item(pao_list,i) == proto) {
 						read_unlock(ist, proto);
 						clist_item(pao_list,i) = NULL;
 					}
-		for (i=0; i < clist_len(pao_list); i++)
-			if ( (obj = clist_item(pao_list,i)) && 
-					(res = get_attr(ist, obj, key)) ) {
-				if (proto_pp) {
-					if (!second) {
-						*proto_pp = obj;
-						clist_read_unlock(ist, pao_list);
-						free_clist(pao_list);
-						return res;
-					} else second = FALSE;
 				}
 			}
+		}
+		for (i=0; i < clist_len(pao_list); i++) {
+			if ((obj = clist_item(pao_list,i))) {
+				if (!super_obj && (res = get_attr(ist, obj, key))) {
+					if (proto_pp) *proto_pp = obj;
+					clist_read_unlock(ist, pao_list);
+					free_clist(pao_list);
+					return res;
+				}
+				if (obj == super_obj)
+					super_obj = NULL;
+			}
+		}
 		clist_read_unlock(ist, pao_list);
 		free_clist(pao_list);
 		res = NULL;
@@ -863,7 +867,7 @@
 	if (has_proto_QUES(ist, ref_key, OBJ(SYMBOL_PROTO))) {
 		obj_p res;
 		if_exc_return NULL;
-		res = get_proto_attr(ist, ref_self, ref_key, NULL, FALSE);
+		res = get_proto_attr(ist, ref_self, ref_key, NULL, NULL);
 		if (!res) {
 			raise_exception(ist, OBJ(NAME_EXC), "Attribute %s not found",
 					symch(ist, ref_key));
@@ -876,7 +880,7 @@
         return call_func(ist, ref_self, SYM(__GETITEM__), 2, param, 0);
 	} else if (has_proto_QUES(ist, ref_key, OBJ(SUPER_PROTO))) {
 		if_exc_return NULL;
-        return get_proto_attr(ist, ref_self, ref_key->data.ptr, NULL, TRUE);
+        return get_proto_attr(ist, ref_self, ref_key->data.ptr, NULL, NULL);
 	} else {
 		raise_exception(ist, OBJ(INTERNAL_EXC), "Invalid reference type");
 		return NULL;
@@ -896,7 +900,7 @@
 	} else if (has_proto_QUES(ist, ref_key, OBJ(SUPER_PROTO))) {
 		obj_p proto_list_obj, proto_obj; if_exc_return;
 		proto_list_obj = proto_list(ist, ref_self); if_exc_return;
-        get_proto_attr(ist, list_item(ist, proto_list_obj,1), ref_key->data.ptr, &proto_obj, FALSE);
+        get_proto_attr(ist, list_item(ist, proto_list_obj,1), ref_key->data.ptr, &proto_obj, NULL);
 		if_exc_return;
 		if (!proto_obj) proto_obj = list_item(ist, proto_list_obj,1);
 		set_attr(ist, proto_obj, ref_key->data.ptr, value);
@@ -918,7 +922,7 @@
 	} else if (has_proto_QUES(ist, ref_key, OBJ(SUPER_PROTO))) {
 		obj_p proto_list_obj, proto_obj; if_exc_return;
 		proto_list_obj = proto_list(ist, ref_self); if_exc_return;
-        get_proto_attr(ist, list_item(ist, proto_list_obj,1), ref_key->data.ptr, &proto_obj, FALSE);
+        get_proto_attr(ist, list_item(ist, proto_list_obj,1), ref_key->data.ptr, &proto_obj, NULL);
 		if_exc_return;
 		if (proto_obj) del_attr(ist, proto_obj, ref_key->data.ptr);
 	} else {

Modified: trunk/src/symbol.c
===================================================================
--- trunk/src/symbol.c	2004-04-06 18:33:17 UTC (rev 295)
+++ trunk/src/symbol.c	2004-04-06 22:43:52 UTC (rev 296)
@@ -124,6 +124,7 @@
 	{ "__globals__",    0 },
 	{ "__syn_locals__",	0 },
 	{ "__locals__",		0 },
+	{ "__self__",		0 },
 	{ "rparam",			0 },
 	{ "param1",			0 },
 	{ "param2",			0 },
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.