rev 446 - in trunk: . include/prothon pr src

SVN User <[email protected]> Sun, 02 May 2004 23:22:59 -0400
Newsgroups gmane.comp.lang.prothon.cvs
Message-ID <[email protected]>
Author: mark
Date: 2004-05-02 23:22:56 -0400 (Sun, 02 May 2004)
New Revision: 446

Added:
   trunk/pr/bind.pr
   trunk/pr/bug2.pr
   trunk/pr/cache.pr
   trunk/pr/fixed.pr
Modified:
   trunk/STATUS.txt
   trunk/include/prothon/prothon.h
   trunk/pr/test.pr
   trunk/src/builtins-core.c
   trunk/src/interp.c
   trunk/src/object.c
   trunk/src/symbol.c
Log:
added Func.bind() and bind.pr

Modified: trunk/STATUS.txt
===================================================================
--- trunk/STATUS.txt	2004-05-02 19:12:53 UTC (rev 445)
+++ trunk/STATUS.txt	2004-05-03 03:22:56 UTC (rev 446)
@@ -1,16 +1,12 @@
 
 ----------------------- TO-DO (highest priority first) ------------------------
 
+--- add ^ as an obj
+
 --- Add missing string functions
 
---- def _call_(*args, **kwds):
-		newObj = Proto($)
-	    initObj = newObj._init_(*args, **kwds):
-	    if initObj is None:  return newObj
-	    return initObj
+--- add func.bind(obj)
 
---- add obj.bind(obj.func)
-
 --- fix str-to-obj in parser for '\000abc'.len()
 
 --- fix bug1.pr and bug2.pr

Modified: trunk/include/prothon/prothon.h
===================================================================
--- trunk/include/prothon/prothon.h	2004-05-02 19:12:53 UTC (rev 445)
+++ trunk/include/prothon/prothon.h	2004-05-03 03:22:56 UTC (rev 446)
@@ -264,40 +264,41 @@
 	LIST_PROTO,			// 12 List
 	DICT_PROTO,			// 13 Dict
 	FUNC_PROTO,			// 14 Func
-	HASH_PROTO,			// 15 Hash
-	SLICE_PROTO,		// 16 Slice
-	SUPER_PROTO,		// 17 Super
-	GEN_PROTO,			// 18 gen (generator)
-	THREAD_PROTO,		// 19 Thread
-	MUTEX_PROTO,		// 20 Mutex
+	METHOD_PROTO,		// 15 Method
+	HASH_PROTO,			// 16 Hash
+	SLICE_PROTO,		// 17 Slice
+	SUPER_PROTO,		// 18 Super
+	GEN_PROTO,			// 19 gen (generator)
+	THREAD_PROTO,		// 20 Thread
+	MUTEX_PROTO,		// 21 Mutex
 
 // Exceptions
-	EXCEPTION,			//  21 Exception
-	INTERNAL_EXC,		//  22 InternalError
-	PARSEERROR_EXC,		//  23
-	INTERPRETER_EXC,	//  24
-	ASSERTION_EXC,		//  25 AssertionError
-	NAME_EXC,			//  26 NameError
-	INDEX_EXC,			//  27 IndexError
-	TYPE_EXC,			//  28 TypeError
-	MUTABLE_EXC,		//	29 Mutable Error
-	DIVIDEZERO_EXC,		//  30
-	OUTOFMEMORY_EXC,	//  31
-	IOEXCEPTION,		//  32
-	FUNCNOTFOUND_EXC,	//  33
-	FILENOTFOUND_EXC,	//  34
-	STOP_ITERATION_EXC,	//  35
-	LOCK_EXC,			//  36
-	PERMISSION_EXC,		//  37
+	EXCEPTION,			//  22 Exception
+	INTERNAL_EXC,		//  23 InternalError
+	PARSEERROR_EXC,		//  24
+	INTERPRETER_EXC,	//  25
+	ASSERTION_EXC,		//  26 AssertionError
+	NAME_EXC,			//  27 NameError
+	INDEX_EXC,			//  28 IndexError
+	TYPE_EXC,			//  29 TypeError
+	MUTABLE_EXC,		//	30 Mutable Error
+	DIVIDEZERO_EXC,		//  31
+	OUTOFMEMORY_EXC,	//  32
+	IOEXCEPTION,		//  33
+	FUNCNOTFOUND_EXC,	//  34
+	FILENOTFOUND_EXC,	//  35
+	STOP_ITERATION_EXC,	//  36
+	LOCK_EXC,			//  37
+	PERMISSION_EXC,		//  38
 
 // constants
-	ZERO_INT,			//  38
-	MAX_INT,			//  39 MaxInt
+	ZERO_INT,			//  39
+	MAX_INT,			//  40 MaxInt
 
 // Containers
-	ROOT_GLOBALS,		//  40 Root_Globals
-	SYMBOLS,			//  41 Symbols_dict
-	MODULES,			//  42 Modules
+	ROOT_GLOBALS,		//  41 Root_Globals
+	SYMBOLS,			//  42 Symbols_dict
+	MODULES,			//  43 Modules
 
 	OBJ_ENUM_COUNT
 } obj_enum_t;
@@ -407,6 +408,7 @@
 	__TOSTORPROXY__,
 	__FROMSTORPROXY__,
 	__CALL__,
+	__BINDOBJ__,
 
 	SYM_ENUM_COUNT
 } sym_enum_t;
@@ -901,6 +903,16 @@
 	} (var) = pr_strptr((index > 0 ? parms[((index)-1)*2+1] : list_item(ist, parms[1], -index))); }
 	
 
+#define FUNC___PARAM(index, var)	/* obj_p var; */						\
+{	if (!has_proto_QUES(ist, (index > 0 ? parms[((index)-1)*2+1] :			\
+								list_item(ist, parms[1], -index)) ,			\
+							OBJ(FUNC_PROTO))) {								\
+		raise_exception(ist, OBJ(TYPE_EXC),									\
+				"expected a function obj in parameter " #index);			\
+		return NULL;														\
+	}																		\
+	(var) = (index > 0 ? parms[((index)-1)*2+1] : list_item(ist, parms[1], -index));	}
+
 #define FLOAT__PARAM(index, var)	/* double var; */						\
 {	if (!has_proto_QUES(ist, (index > 0 ? parms[((index)-1)*2+1] : list_item(ist, parms[1], -index)) , OBJ(FLOAT_PROTO))) {					\
 		raise_exception(ist, OBJ(TYPE_EXC),									\

Added: trunk/pr/bind.pr
===================================================================
--- trunk/pr/bind.pr	2004-05-02 19:12:53 UTC (rev 445)
+++ trunk/pr/bind.pr	2004-05-03 03:22:56 UTC (rev 446)
@@ -0,0 +1,31 @@
+#!/usr/bin/env prothon
+
+def func():
+	print $
+	
+bf33 = func.bind(33)
+bf66 = func.bind(66)
+print bf33				#   <func:93b7c0:bound:33> 
+print bf66				#	<func:93b7e0:bound:66>
+
+bf33()					# 33
+bf66()					# 66
+with 99: bf33()			# 33
+with 99: bf66()			# 66
+
+print bf33				#   <func:93b7c0:bound:33>
+print bf33.__bindObj__	#	33
+del bf33.__bindObj__
+print bf33				#  <func:93b7c0>
+
+print bf66				#  <func:93b7e0:bound:66> 
+
+bf66 = bf66.bind(11)	#  <func:93b7e0:bound:66> 
+print bf66				#  <func:93bbc0:bound:11>
+bf66 = bf66.bind()
+print bf66				#  <func:93bc80>
+
+
+
+
+
Added: trunk/pr/bug2.pr
===================================================================
--- trunk/pr/bug2.pr	2004-05-02 19:12:53 UTC (rev 445)
+++ trunk/pr/bug2.pr	2004-05-03 03:22:56 UTC (rev 446)
@@ -0,0 +1,40 @@
+#!/usr/bin/env prothon
+
+# cache.pr
+
+#!/usr/bin/env prothon
+
+object ModInt(Int):	
+	$modulo	= 10
+	def	$__init__(i=0):	
+		return ^__init__(i % $modulo)
+	def	$__add__(other):
+		if $modulo != other.modulo:	
+			raise TypeError	
+		return ^__call__(^__add__(other) % $modulo)	
+
+object Mod16Int(ModInt):
+	$modulo	= 16
+
+object Mod16IntC(Mod16Int):	
+	$cache = {}	
+	def	$__init__(i):
+		i =	i %	$modulo	
+		if i in	$cache:	
+			print 'cache obj', $cache[i], $cache[i].protoList()
+			return $cache[i]
+		obj	= Mod16Int(i)
+		print 'new obj', obj, obj.protoList()
+		$cache[i] =	obj	
+		return obj
+
+i =	Mod16IntC(27)
+j =	Mod16IntC(8)
+k =	Mod16IntC(8)
+print """
+
+should print
+
+11 + 8 = 03	
+"""	
+print "%i +	%i + %i	= %02i"	% (i, j, k,	(i + j + k))
Added: trunk/pr/cache.pr
===================================================================
--- trunk/pr/cache.pr	2004-05-02 19:12:53 UTC (rev 445)
+++ trunk/pr/cache.pr	2004-05-03 03:22:56 UTC (rev 446)
@@ -0,0 +1,43 @@
+#!/usr/bin/env prothon
+
+# cache.pr
+
+#!/usr/bin/env prothon
+
+object ModInt(Int):	
+	$modulo	= 10
+	def	$__init__(i=0):	
+		^__init__(i % $modulo)
+	def	$__add__(other):
+		print ">>>", $, other
+		if $modulo != other.modulo:	
+			raise TypeError	
+		return ^__call__(^__add__(other) % $modulo)	
+
+object Mod16Int(ModInt):
+	$modulo	= 16
+
+object Mod16IntC(Mod16Int):	
+	$cache = {}	
+	def	$__init__(i):
+		i =	i %	$modulo	
+		if i in	$cache:	
+			$__init__($cache[i])
+		else:
+			obj	= Mod16Int(i)
+			$cache[i] =	obj	
+			$__init__(obj)
+
+i =	Mod16IntC(27)
+
+print i + i
+
+/*
+j =	Mod16IntC(8)
+k =	Mod16IntC(8)
+
+n = i+i
+print 'n', n
+
+print "%i +	%i + %i	= %02i"	% (i, j, k,	(i + j + k))
+*/
\ No newline at end of file

Added: trunk/pr/fixed.pr
===================================================================
--- trunk/pr/fixed.pr	2004-05-02 19:12:53 UTC (rev 445)
+++ trunk/pr/fixed.pr	2004-05-03 03:22:56 UTC (rev 446)
@@ -0,0 +1,35 @@
+#!/usr/bin/env prothon
+
+object Fixed(Int):
+    $dp = 2 
+    $divisor = 100
+    
+    def $__call__(n=0, decimalplaces=2):
+        obj = Proto($)
+        obj.dp = decimalplaces
+        obj.divisor = 10
+        obj.__init__(n)   # binary data init here 
+        return obj
+
+object PrettyPrintFixed(Fixed): 
+
+    def $__init__(n):
+        ^__init__(n)
+        # Set default print format width.
+        $setPrintWidth($dp+5)
+        
+    def $setPrintWidth(wid):
+        # Create string comprehension "%W.Pf"
+        # where W is wid and P  is $dp
+        $pattern =  "%%%i.%if" % (wid, $dp) 
+        print $pattern
+        
+    def $__str__(): 
+        return  $pattern % ($ / $divisor)
+print """
+This should print
+
+%6.1f 
+123456.7 
+"""
+print PrettyPrintFixed(1234567, 1)
Modified: trunk/pr/test.pr
===================================================================
--- trunk/pr/test.pr	2004-05-02 19:12:53 UTC (rev 445)
+++ trunk/pr/test.pr	2004-05-03 03:22:56 UTC (rev 446)
@@ -1 +1,31 @@
 #!/usr/bin/env prothon
+
+def func():
+	print $
+	
+bf33 = func.bind(33)
+bf66 = func.bind(66)
+print bf33				#   <func:93b7c0:bound:33> 
+print bf66				#	<func:93b7e0:bound:66>
+
+bf33()					# 33
+bf66()					# 66
+with 99: bf33()			# 33
+with 99: bf66()			# 66
+
+print bf33				#   <func:93b7c0:bound:33>
+print bf33.__bindObj__	#	33
+del bf33.__bindObj__
+print bf33				#  <func:93b7c0>
+
+print bf66				#  <func:93b7e0:bound:66> 
+
+bf66 = bf66.bind(11)	#  <func:93b7e0:bound:66> 
+print bf66				#  <func:93bbc0:bound:11>
+bf66 = bf66.bind()
+print bf66				#  <func:93bc80>
+
+
+
+
+

Modified: trunk/src/builtins-core.c
===================================================================
--- trunk/src/builtins-core.c	2004-05-02 19:12:53 UTC (rev 445)
+++ trunk/src/builtins-core.c	2004-05-03 03:22:56 UTC (rev 446)
@@ -72,6 +72,7 @@
 MODULE_DECLARE(Gen);
 MODULE_DECLARE(Seq);
 MODULE_DECLARE(Func);
+MODULE_DECLARE(Method);
 
 // ***************************** Object *********************************
 
@@ -672,10 +673,39 @@
 MODULE_START(Func)
 {
 	Func_OBJ = OBJ(FUNC_PROTO);
+	MODULE_ADD_TO_OBJ(Func, OBJ(OBJECT), "Func");
 	MODULE_SET_DOC(Func, "function object prototype");
 	set_obj_id(Func_OBJ, *, Function);
+
+	Method_OBJ = OBJ(METHOD_PROTO);
+	MODULE_ADD_TO_OBJ(Method, OBJ(OBJECT), "Method");
+	MODULE_SET_DOC(Method, "method object prototype");
+	set_obj_id(Method_OBJ, *, Method);
 }
 
+DEF(Func, __str__, NULL) {
+	obj_p bobj;
+	char str[128];
+	apr_snprintf(str, sizeof(str), "<func:%x", (unsigned long)(intptr_t) self);
+	if (self->data_type == DATA_TYPE_FUNCPTR)
+		strcat(str, ":c");
+	if (bobj = get_attr(ist, self, SYM(__BINDOBJ__))) {
+		strcat(str, ":bound:");
+		strcat(str, as_str(ist, bobj));
+	}
+	strcat(str, ">");
+	return new_string_obj(ist, str);
+}
+
+DEF(Func, bind, FPARM1(obj, OBJ(NONE))) {
+	obj_p bind_obj = copy_object(ist, self);
+	if (parms[1] == OBJ(NONE))
+		del_attr(ist, bind_obj, SYM(__BINDOBJ__));
+	else
+		set_attr(ist, bind_obj, SYM(__BINDOBJ__), parms[1]);
+	return bind_obj;
+}
+
 DEF(Func, __cDataLen__, NULL) {
 	return NEW_INT(sizeof(code) + ((code_p)(self->data.ptr))->len * sizeof(code_t));
 }
@@ -754,6 +784,8 @@
 	MODULE_ADD_SYM(Gen, __iter__);
 
 	MODULE_SUB_INIT(Func);
+	MODULE_ADD_SYM(Func, __str__);
+	MODULE_ADD_SYM(Func, bind);
 	MODULE_ADD_SYM(Func, __cDataLen__);
 	MODULE_ADD_SYM(Func, __objList__);
 

Modified: trunk/src/interp.c
===================================================================
--- trunk/src/interp.c	2004-05-02 19:12:53 UTC (rev 445)
+++ trunk/src/interp.c	2004-05-03 03:22:56 UTC (rev 446)
@@ -990,25 +990,29 @@
 			case OP_OBJCALL: {
 				fr_sp -= 1+2*param;
 				if ((func_obj = fr_stack[fr_sp])->data_type == DATA_TYPE_FUNCPTR){
-					obj_p res;
+					obj_p res, self;
 					clist_p plist = get_func_params(ist, func_obj, param*2, fr_stack+fr_sp+1);
-					pre_call_lock(ist, frame->locals, plist); IF_EXC_BREAK;
+					if (! (self = get_attr(ist, func_obj, SYM(__BINDOBJ__))) )
+						self = frame->self; IF_EXC_BREAK;
+					pre_call_lock(ist, self, plist); IF_EXC_BREAK;
 					res = ((pr_func*)(func_obj->data.ptr))
-								(ist, frame->self, 
+								(ist, self, 
 								(plist ? clist_len(plist) : 0), 
 								(plist ? (obj_p*)plist->items : NULL),
 								frame->locals);
 					IF_EXC_BREAK;
-					post_call_unlock(ist, frame->locals, plist);
+					post_call_unlock(ist, self, plist);
 					free_clist(plist);
 					fr_push(res);
 				} else if (has_proto_QUES(ist, func_obj, OBJ(FUNC_PROTO))) {
-					obj_p new_locals, syn_self;
+					obj_p new_locals, syn_self, self;
 					frame_p new_frame;
 					IF_EXC_BREAK;
 					new_locals = NEW_OBJ(NULL);
 					syn_self = get_attr(ist, func_obj, SYM(__SYN_SELF__)); IF_EXC_BREAK;
-					new_frame = create_frame( ist, syn_self, frame->self, NULL, NULL,	
+					if (! (self = get_attr(ist, func_obj, SYM(__BINDOBJ__))) )
+						self = frame->self;   IF_EXC_BREAK;
+					new_frame = create_frame( ist, syn_self, self, NULL, NULL,	
 											  frame->locals, new_locals, func_obj, NULL );
 					fr_next = new_frame;
 					new_frame->prev_frame = frame;
@@ -1108,27 +1112,31 @@
 					break;
 				}
 				if (func_obj->data_type == DATA_TYPE_FUNCPTR){
-					obj_p res, slf = super_flag? frame->self : fr_stack[fr_sp];
+					obj_p res, self, slf = super_flag? frame->self : fr_stack[fr_sp];
 					clist_p plist = get_func_params(ist, func_obj, param*2, fr_stack+fr_sp+2);
 					IF_EXC_BREAK;
-					pre_call_lock(ist, slf, plist);  IF_EXC_BREAK;
+					if (! (self = get_attr(ist, func_obj, SYM(__BINDOBJ__))) )
+						self = slf;   IF_EXC_BREAK;
+					pre_call_lock(ist, self, plist);  IF_EXC_BREAK;
 					res = ((pr_func*)(func_obj->data.ptr))
-								(ist, slf, 
+								(ist, self, 
 								(plist ? clist_len(plist) : 0), 
 								(plist ? (obj_p*)plist->items : NULL),
 								frame->dyn_locals);
 					IF_EXC_BREAK;
-					post_call_unlock(ist, slf, plist);
+					post_call_unlock(ist, self, plist);
 					free_clist(plist);
 					IF_EXC_BREAK;
 					fr_push(res);
 				} else if (has_proto_QUES(ist, func_obj, OBJ(FUNC_PROTO))) {
-					obj_p new_locals, syn_self;
+					obj_p new_locals, syn_self, self;
 					frame_p new_frame;
 					IF_EXC_BREAK;
 					new_locals = NEW_OBJ(NULL);
 					syn_self = get_attr(ist, func_obj, SYM(__SYN_SELF__)); IF_EXC_BREAK;
-					new_frame = create_frame(	ist, syn_self,  super_flag? frame->self : fr_stack[fr_sp], NULL, NULL, 
+					if (! (self = get_attr(ist, func_obj, SYM(__BINDOBJ__))) )
+						self = super_flag? frame->self : fr_stack[fr_sp];   IF_EXC_BREAK;
+					new_frame = create_frame(	ist, syn_self,  self, NULL, NULL, 
 												frame->locals, new_locals, func_obj, NULL );
 					fr_next = new_frame;
 					new_frame->prev_frame = frame;
@@ -1352,20 +1360,22 @@
 		}
 	}
 	if (func_obj->data_type == DATA_TYPE_FUNCPTR) {
-		obj_p res;
+		obj_p res, aself;
 		clist_p plist = get_func_params( ist, func_obj, parm_cnt, lbl_val_arr);
-		pre_call_lock(ist, self, plist); if (intrp_exobj) return NULL;
+		if (! (aself = get_attr(ist, func_obj, SYM(__BINDOBJ__))) )
+			aself = self;     if_exc_return 0;
+		pre_call_lock(ist, aself, plist); if (intrp_exobj) return NULL;
 		res = ((pr_func*)(func_obj->data.ptr)) 
-								(ist, self, (plist ? clist_len(plist) : 0), 
+								(ist, aself, (plist ? clist_len(plist) : 0), 
 								(plist ? (obj_p*)plist->items : NULL), dyn_locals);
 		if (intrp_exobj) return NULL;
-		post_call_unlock(ist, self, plist);
+		post_call_unlock(ist, aself, plist);
 		free_clist(plist);
 		if (!func_sym) del_unlock(self);
 		return res;
 	} else if (has_proto_QUES(ist, func_obj, OBJ(FUNC_PROTO))) {
 		frame_p frame, new_frame;
-		obj_p new_locals, syn_self; 
+		obj_p new_locals, syn_self, aself; 
 		if (!ist) {
 			raise_exception(ist, OBJ(INTERNAL_EXC), "Illegal function call to Prothon function");
 			if (!func_sym) del_unlock(self);
@@ -1382,7 +1392,9 @@
 			if (!func_sym) del_unlock(self);
 			return 0;
 		}
-		new_frame = create_frame(	ist, syn_self, self, NULL, NULL, dyn_locals, 
+		if (! (aself = get_attr(ist, func_obj, SYM(__BINDOBJ__))) )
+			aself = self;   if_exc_return 0;
+		new_frame = create_frame(	ist, syn_self, aself, NULL, NULL, dyn_locals, 
 			                        new_locals, func_obj, NULL );
 		new_frame->called_from_c = TRUE;
 		ist->frame->next_frame = new_frame;

Modified: trunk/src/object.c
===================================================================
--- trunk/src/object.c	2004-05-02 19:12:53 UTC (rev 445)
+++ trunk/src/object.c	2004-05-03 03:22:56 UTC (rev 446)
@@ -226,6 +226,7 @@
 	OBJ(STRING_PROTO)       = NEW_OBJ(NULL);
 	OBJ(DICT_PROTO)         = NEW_OBJ(NULL);
 	OBJ(FUNC_PROTO)         = NEW_OBJ(NULL);
+	OBJ(METHOD_PROTO)       = NEW_OBJ(OBJ(FUNC_PROTO));
 
 	OBJ(SYMBOLS)            = NEW_DICT(SYM_ENUM_COUNT+100);
 

Modified: trunk/src/symbol.c
===================================================================
--- trunk/src/symbol.c	2004-05-02 19:12:53 UTC (rev 445)
+++ trunk/src/symbol.c	2004-05-03 03:22:56 UTC (rev 446)
@@ -151,7 +151,8 @@
 	{ "copy",			0 },
 	{ "__toStorProxy__",  0 },
 	{ "__fromStorProxy__", 0},
-	{ "__call__", 0}
+	{ "__call__",       0},
+	{ "__bindObj__",    0}
 };
 
 typedef struct trie_node_s* trie_p;