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

SVN User <[email protected]> Wed, 28 Apr 2004 18:42:46 -0400
Newsgroups gmane.comp.lang.prothon.cvs
Message-ID <[email protected]>
Author: mark
Date: 2004-04-28 18:42:43 -0400 (Wed, 28 Apr 2004)
New Revision: 427

Added:
   trunk/pr/object.pr
Modified:
   trunk/STATUS.txt
   trunk/include/prothon/prothon.h
   trunk/include/prothon/prothon_dll.h
   trunk/pr/new.pr
   trunk/src/bytecodes.h
   trunk/src/interp.c
   trunk/src/object.c
   trunk/src/object.h
   trunk/src/parser.h
   trunk/src/parser_routines.c
   trunk/src/prothon.y
   trunk/src/src.vcproj
Log:
added object keyword and object.pr

Modified: trunk/STATUS.txt
===================================================================
--- trunk/STATUS.txt	2004-04-28 07:22:11 UTC (rev 426)
+++ trunk/STATUS.txt	2004-04-28 22:42:43 UTC (rev 427)
@@ -1,9 +1,10 @@
 
 ----------------------- TO-DO (highest priority first) ------------------------
 
+--- object keyword
+
 --- Extend closures to all enclosing functions
 
---- New delgation
 --- Bound methods - binding - calling
 
 --- Add missing string functions
@@ -11,10 +12,6 @@
 --- add support for APR_BINARY in File.c ('b' flag)
 --- support any object that supports file methods in stdxxx (duck std)
 
---- move PARAM_STAR and PARAM_STAR_STAR to right side of pair
-
---- finish Prosist
-
 --- help() in interactive console()
 
 --- -d -m -l cmd-line options missing
@@ -34,6 +31,8 @@
 
 --- Does simple 1+2 expr evaluation create objects?  If so, need shortcuts to speed it up
 
+--- move PARAM_STAR and PARAM_STAR_STAR to right side of pair
+
 --- clean up prt_code_line mess with some cleaner coding technique
 
 --- reduce array of act params passed to function to only odd entries
@@ -44,20 +43,8 @@
 
 ---------------- Ideas to consider for inclusion ------------------------------
 
-change def to func?
+--- make print a function ?
 
-object keyword
-
-Point = proto(base1, base2):
-func  = def(arg1, arg2):
-
-o = Obj(bases=Object, args):
-f = Func(args):
-
-o = base.new(args)
-o = base.create(args)
-o = base.instance(args)
-
 How do we add "properties"?
 
 Full unicode support like Java -- store compressed ucs4 ?
@@ -66,9 +53,6 @@
 
 remove \ continuation ?
 
---- make print a function ?
-
-
 Python add-on C module adapter for Prothon
 Swig or other (what GTK port used?) backend
 auto python -> prothon source converter

Modified: trunk/include/prothon/prothon.h
===================================================================
--- trunk/include/prothon/prothon.h	2004-04-28 07:22:11 UTC (rev 426)
+++ trunk/include/prothon/prothon.h	2004-04-28 22:42:43 UTC (rev 427)
@@ -291,7 +291,7 @@
 	OBJ_ENUM_COUNT
 } obj_enum_t;
 
-extern obj_p OBJ_[OBJ_ENUM_COUNT];
+extern obj_p OBJ[OBJ_ENUM_COUNT];
 
 // Use OBJ(OBJNAME) to access well-known objects
 // example:  OBJ(OBJECT) or OBJ(PR_TRUE)

Modified: trunk/include/prothon/prothon_dll.h
===================================================================
--- trunk/include/prothon/prothon_dll.h	2004-04-28 07:22:11 UTC (rev 426)
+++ trunk/include/prothon/prothon_dll.h	2004-04-28 22:42:43 UTC (rev 427)
@@ -146,7 +146,7 @@
 	int			(*get_obj_rdacc)(obj_p obj);
 	int			(*get_obj_wracc)(obj_p obj);
 				
-	obj_p* 				OBJ_;
+	obj_p* 				OBJ;
 	sym_id_entry_t* 	sym_id_table;
 
 } pr_services_t;
@@ -271,7 +271,7 @@
 #define obj_malloc			(*services->obj_malloc)
 #define obj_realloc			(*services->obj_realloc)
 #define obj_free			(*services->obj_free)
-#define OBJ(x) 				(services->OBJ_[x])
+#define OBJ(x) 				(services->OBJ[x])
 #define SYM(symenum)  		(services->sym_id_table[symenum].id)
 #define read_lock			(*services->read_lock)
 #define read_unlock			(*services->read_unlock)	

Modified: trunk/pr/new.pr
===================================================================
--- trunk/pr/new.pr	2004-04-28 07:22:11 UTC (rev 426)
+++ trunk/pr/new.pr	2004-04-28 22:42:43 UTC (rev 427)
@@ -7,11 +7,11 @@
 
 p = Object()
 with p:
-	$x = None
-	def $__init__(x):
-		$x = x
-	def $__str__():
-		return '*'+$x+'*'
+    $x = None
+    def $__init__(x):
+        $x = x
+    def $__str__():
+        return '*'+$x+'*'
 
 print
 print 'Should print ...'
Added: trunk/pr/object.pr
===================================================================
--- trunk/pr/object.pr	2004-04-28 07:22:11 UTC (rev 426)
+++ trunk/pr/object.pr	2004-04-28 22:42:43 UTC (rev 427)
@@ -0,0 +1,22 @@
+#!/usr/bin/env prothon
+
+# object.pr
+
+object Point(Object):
+	$x = 0; $y = 0
+	def $__init__(x, y):
+		$x=x; $y=y
+	def $move(xofs, yofs):
+		$x += xofs; $y += yofs
+		print $
+	def $__str__():
+		return '<'+$x+':'+$y+'>'
+		
+print
+print "Should print..."
+print '<5:50>'
+print '<15:150>'
+print
+p = Point(5, 50)
+print p
+p.move(10, 100)
Modified: trunk/src/bytecodes.h
===================================================================
--- trunk/src/bytecodes.h	2004-04-28 07:22:11 UTC (rev 426)
+++ trunk/src/bytecodes.h	2004-04-28 22:42:43 UTC (rev 427)
@@ -115,6 +115,16 @@
 // |opcode|object-id|object-id|...|
 OP_PUSH,
 
+// OBJ(protos)
+// Push new execution frame identical to last except with self set to
+// a new object (usually a prototype) made with prototypes from list protos.
+// New obj also stored at destination reference location on stack.
+// stack length is ((num proto refs)+1)*2 since ref is two stack items
+// stack: dst-ref, proto-ref2, proto-ref3, ... proto-refN -> <empty>
+// param: total word count == 3
+// |opcode|func-obj|Num proto refs|
+OP_OBJ,
+
 // WITH (self)
 // Push new execution frame identical to last except with self
 // equal to top-of-stack.  Similar to a call.
@@ -141,7 +151,6 @@
 // |opcode|# of fparam pairs|func-obj|
 OP_GEN,
 
-
 /********/ OP_PARAM_WORDS_BOUNDARY, /********/ 
 
 //*** Note: A ref (2 words on stack) is:

Modified: trunk/src/interp.c
===================================================================
--- trunk/src/interp.c	2004-04-28 07:22:11 UTC (rev 426)
+++ trunk/src/interp.c	2004-04-28 22:42:43 UTC (rev 427)
@@ -662,6 +662,8 @@
 		}
 }
 
+#define IF_EXC_BREAK if (intrp_exobj) break
+
 //******************************** exec_loop **********************************
 obj_p exec_loop(isp ist){
 	obj_p  func_obj, temp = NULL;
@@ -839,7 +841,7 @@
 				fr_sp -= param;
 				for (i=0; i < param; i+=2) {
 					dict_add(ist, dict_obj, fr_stack[fr_sp+i], fr_stack[fr_sp+i+1]);
-					if (intrp_exobj) break;
+					IF_EXC_BREAK;
 				}
 				fr_push(dict_obj);
 			}	break;
@@ -936,14 +938,14 @@
 				exc_proto = fr_tos;
 				fr_sp--;
 				if (!has_proto_QUES(ist, exc_waiting, exc_proto)) { // need to support list XXX
-					if (intrp_exobj) break;
+					IF_EXC_BREAK;
 #ifdef TRACE_INTERPRETER
 					trace_step(frame);
 #endif
 					fr_pc += param;
 					continue;
 				}
-				if (intrp_exobj) break;
+				IF_EXC_BREAK;
 				if (exc_obj_label && exc_obj_label != OBJ(NONE))
 					set_attr(ist, frame->locals, exc_obj_label, exc_waiting);
 				exc_waiting = 0;
@@ -979,36 +981,36 @@
 				if ((func_obj = fr_stack[fr_sp])->data_type == DATA_TYPE_FUNCPTR){
 					obj_p res;
 					clist_p plist = get_func_params(ist, func_obj, param*2, fr_stack+fr_sp+1);
-					pre_call_lock(ist, frame->locals, plist); if (intrp_exobj) break;
+					pre_call_lock(ist, frame->locals, plist); IF_EXC_BREAK;
 					res = ((pr_func*)(func_obj->data.ptr))
 								(ist, frame->self, 
 								(plist ? clist_len(plist) : 0), 
 								(plist ? (obj_p*)plist->items : NULL),
 								frame->locals);
-					if (intrp_exobj) break;
+					IF_EXC_BREAK;
 					post_call_unlock(ist, frame->locals, plist);
 					free_clist(plist);
 					fr_push(res);
 				} else if (has_proto_QUES(ist, func_obj, OBJ(FUNC_PROTO))) {
 					obj_p new_locals, syn_self;
 					frame_p new_frame;
-					if (intrp_exobj) break;
+					IF_EXC_BREAK;
 					new_locals = NEW_OBJ(NULL);
-					syn_self = get_attr(ist, func_obj, SYM(__SELF__)); if (intrp_exobj) break;
+					syn_self = get_attr(ist, func_obj, SYM(__SELF__)); IF_EXC_BREAK;
 					new_frame = create_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, new_locals, func_obj, param*2, fr_stack+fr_sp+1);
-					if (intrp_exobj) break;
+					IF_EXC_BREAK;
 					switch_frame = new_frame;
 				} else if (has_proto_QUES(ist, func_obj, OBJ(GEN_PROTO))) {
 					frame_p tmp_frame;
-					if (intrp_exobj) break;
+					IF_EXC_BREAK;
 					tmp_frame = func_obj->data.ptr;
 					frame->next_frame = tmp_frame;
 					load_frame_params(ist, tmp_frame->locals, func_obj, param*2, fr_stack+fr_sp+1);
-					if (intrp_exobj) break;
+					IF_EXC_BREAK;
 					fr_push(func_obj);
 				} else {
 					memmove(fr_stack+fr_sp+2, fr_stack+fr_sp+1, (param*2) * sizeof(obj_p));
@@ -1017,18 +1019,48 @@
 					goto get_func;
 				}
 			}	break;
+			case OP_OBJ: {
+				int i, num_protos = (int)(intptr_t) fr_data(2);
+				obj_p new_obj;
+				fr_sp -= (num_protos+1)*2;
+				if (num_protos == 0) new_obj = new_object(ist, NULL);
+				else {
+					obj_p psym = fr_stack[fr_sp+3];
+					obj_p proto = get_proto_attr(ist, fr_stack[fr_sp+2], psym, NULL, NULL); IF_EXC_BREAK;
+					if (!proto) {
+						raise_exception(ist, OBJ(NAME_EXC), "prototype %s not found", symch(ist, psym));
+						goto end_op_obj;
+					}
+					new_obj = new_object(ist, proto);
+				}
+				for (i=1; i < num_protos; i++) {
+					obj_p psym = fr_stack[fr_sp+(i+1)*2+1];
+					obj_p proto = get_proto_attr(ist, fr_stack[fr_sp+(i+1)*2], psym, NULL, NULL);
+					if (ist->exception_obj) goto end_op_obj;
+					if (!proto) {
+						raise_exception(ist, OBJ(NAME_EXC), "prototype %s not found", symch(ist, psym));
+						goto end_op_obj;
+					}
+					ins_proto(ist, new_obj, proto, 0x7fffffff);
+					if (ist->exception_obj) goto end_op_obj;
+				}
+				set_attr(ist, fr_stack[fr_sp], fr_stack[fr_sp+1], new_obj); IF_EXC_BREAK;
+				del_unlock(new_obj);
+				call_func0(ist, new_obj, SYM(__INIT__)); IF_EXC_BREAK;
+				fr_push(new_obj);
+			} // fall into OP_WITH on purpose
 			case OP_WITH:
 				fr_sp--;
 				switch_frame = create_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;
-				break;
+end_op_obj:		break;
 			case OP_SUPERCALL:
 				super_flag = TRUE;
 				goto op_call;
 			case OP_CALL: {
-				super_flag = FALSE; // p 0x09ab660  newObj 0x09ab7a0  -> 0x009ab780 (wrong proto)
+				super_flag = FALSE;
 op_call:
 				fr_sp -= 2+(2*param);
 				if (has_proto_QUES(ist, fr_stack[fr_sp+1], OBJ(SUPER_PROTO))) {
@@ -1050,7 +1082,7 @@
 					switch_frame = new_frame;
 					break;
 				}
-				if (intrp_exobj) break;
+				IF_EXC_BREAK;
 get_func:
 				if (!fr_stack[fr_sp]) {
 					raise_exception(ist, OBJ(INTERPRETER_EXC), "reference to non-existant self object");
@@ -1058,7 +1090,7 @@
 				}
 				func_obj = get_proto_attr(ist, fr_stack[fr_sp], fr_stack[fr_sp+1], NULL, NULL);
 got_func:
-				if (intrp_exobj) break;
+				IF_EXC_BREAK;
 				if (!func_obj) {
 					raise_exception(ist, OBJ(FUNCNOTFOUND_EXC),
 							"Function %s not found",
@@ -1068,45 +1100,45 @@
 				if (func_obj->data_type == DATA_TYPE_FUNCPTR){
 					obj_p res, 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 (intrp_exobj) break;
-					pre_call_lock(ist, slf, plist);  if (intrp_exobj) break;
+					IF_EXC_BREAK;
+					pre_call_lock(ist, slf, plist);  IF_EXC_BREAK;
 					res = ((pr_func*)(func_obj->data.ptr))
 								(ist, slf, 
 								(plist ? clist_len(plist) : 0), 
 								(plist ? (obj_p*)plist->items : NULL),
 								frame->dyn_locals);
-					if (intrp_exobj) break;
+					IF_EXC_BREAK;
 					post_call_unlock(ist, slf, plist);
 					free_clist(plist);
-					if (intrp_exobj) break;
+					IF_EXC_BREAK;
 					fr_push(res);
 				} else if (has_proto_QUES(ist, func_obj, OBJ(FUNC_PROTO))) {
 					obj_p new_locals, syn_self;
 					frame_p new_frame;
-					if (intrp_exobj) break;
+					IF_EXC_BREAK;
 					new_locals = NEW_OBJ(NULL);
-					syn_self = get_attr(ist, func_obj, SYM(__SELF__)); if (intrp_exobj) break;
+					syn_self = get_attr(ist, func_obj, SYM(__SELF__)); IF_EXC_BREAK;
 					new_frame = create_frame(	ist, syn_self,  super_flag? frame->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, new_locals, func_obj, param*2, fr_stack+fr_sp+2);
-					if (intrp_exobj) break;
+					IF_EXC_BREAK;
 					switch_frame = new_frame;
 				} else if (has_proto_QUES(ist, func_obj, OBJ(GEN_PROTO))) {
 					frame_p tmp_frame;
-					if (intrp_exobj) break;
+					IF_EXC_BREAK;
 					tmp_frame = func_obj->data.ptr;
 					frame->next_frame = tmp_frame;
 					load_frame_params(ist, tmp_frame->locals, func_obj, param*2, fr_stack+fr_sp+2);
-					if (intrp_exobj) break;
+					IF_EXC_BREAK;
 					fr_push(func_obj);
 				} else {
 					obj_p value;
 					if (fr_stack[fr_sp+1] != SYM(__CALL__)) {
 						value = get_proto_attr(ist, fr_stack[fr_sp],
 								fr_stack[fr_sp+1], NULL, NULL);
-						if (intrp_exobj) break;
+						IF_EXC_BREAK;
 						if (value) {
 							fr_stack[fr_sp]   = value;
 							fr_stack[fr_sp+1] = SYM(__CALL__);
@@ -1134,7 +1166,7 @@
 			}	break;
 			case OP_RETURN:
 				return_value = do_return(ist, frame, &switch_frame, &free_frame, return_value);
-				if (intrp_exobj) break;
+				IF_EXC_BREAK;
 				return_flag = fr_ccall;
 				break;
 			case OP_IMPORT:    
@@ -1185,7 +1217,7 @@
 				for (i=0; i < param; i++) 
 					if (fr_stack[fr_sp+i]) {
 						obj_p str_obj = call_func0(ist, fr_stack[fr_sp+i], SYM(__STR__));
-						if (intrp_exobj) break;
+						IF_EXC_BREAK;
 						printf("%s ", pr_strptr(str_obj));
 					} else if (i == param-1) goto endcase;
 				printf("\n");
@@ -1708,6 +1740,8 @@
 		break;
 	case OP_GEN: fprintf(fout,"%4d %20s(%4d) %s", pc, "OP_GEN", param, codedata(str, code, op, param, pc));
 		break;
+	case OP_OBJ: fprintf(fout,"%4d %20s(%4d) %s", pc, "OP_OBJ", param, codedata(str, code, op, param, pc));
+		break;
 	case OP_WITH: fprintf(fout,"%4d %20s(%4d) %s", pc, "OP_WITH", param, codedata(str, code, op, param, pc));
 		break;
 	case OP_OBJCALL: fprintf(fout,"%4d %20s(%4d) %s", pc, "OP_OBJCALL", param, codedata(str, code, op, param, pc));

Modified: trunk/src/object.c
===================================================================
--- trunk/src/object.c	2004-04-28 07:22:11 UTC (rev 426)
+++ trunk/src/object.c	2004-04-28 22:42:43 UTC (rev 427)
@@ -97,7 +97,7 @@
 }
 #endif
 
-obj_p OBJ_[OBJ_ENUM_COUNT];
+obj_p OBJ[OBJ_ENUM_COUNT];
 
 //********************************* object_store_init ***************************
 void object_store_init(isp ist, int nop2){
@@ -163,7 +163,7 @@
 	dll_services.obj_malloc		  = obj_malloc;
 	dll_services.obj_realloc      = obj_realloc;
 	dll_services.obj_free		  = obj_free;
-	dll_services.OBJ_			  = OBJ_;
+	dll_services.OBJ			  = OBJ;
 	dll_services.sym_id_table	  = sym_id_table;
 	dll_services.pr_malloc	      = pr_malloc;
 	dll_services.pr_realloc		  = pr_realloc;	

Modified: trunk/src/object.h
===================================================================
--- trunk/src/object.h	2004-04-28 07:22:11 UTC (rev 426)
+++ trunk/src/object.h	2004-04-28 22:42:43 UTC (rev 427)
@@ -84,14 +84,13 @@
 
 obj_p list_append_no_lock(obj_p list_obj, obj_p item);
 
-
 void init_symbol(isp ist);
 
 extern pr_services_t dll_services;
 
 // Use OBJ(OBJNAME) to access well-known object pointer
 // example:  OBJ(OBJECT) or OBJ(PR_TRUE)
-#define OBJ(x) OBJ_[x]
+#define OBJ(x) OBJ[x]
 
 // Use SYM(__XXX__) instead of sym(ist, "__xxx__") for speed.
 #define SYM(symenum)  (sym_id_table[symenum].id)

Modified: trunk/src/parser.h
===================================================================
--- trunk/src/parser.h	2004-04-28 07:22:11 UTC (rev 426)
+++ trunk/src/parser.h	2004-04-28 22:42:43 UTC (rev 427)
@@ -174,6 +174,7 @@
 code_p label_eq_expr_to_param(void* param, char* label, code_p expr);
 code_p label_to_attrref(void* param, char* label);
 code_p label_to_formparm(void* param, char* label);
+code_p lbl_proto_body_to_obj(void* param, code_p label, clist_p protos, code_p body);
 code_p new_dict(void* param, clist_p lst);
 code_p new_tuple_list(void* param, clist_p lst, int tuple_flag);
 code_p none(void* param);

Modified: trunk/src/parser_routines.c
===================================================================
--- trunk/src/parser_routines.c	2004-04-28 07:22:11 UTC (rev 426)
+++ trunk/src/parser_routines.c	2004-04-28 22:42:43 UTC (rev 427)
@@ -71,7 +71,7 @@
 #define debug_retrn(line_no,res)  res
 #endif
 
-#define INTRP (((parse_state*) param)->ist)
+#define IST (((parse_state*) param)->ist)
 
 //********************************* new_parse_state ***************************
 parse_state* new_parse_state(isp ist, FILE* stream, char* in_buf) {
@@ -183,8 +183,8 @@
 	}
 }
 
-//********************************* add_code_to *******************************
-void add_code_to(code_p newcode, code_p res, int *k){
+//********************************* add_code *******************************
+void add_code(code_p newcode, code_p res, int *k){
 	add_code_flg(newcode, res, k, TRUE);
 }
 
@@ -278,16 +278,16 @@
 	return debug_retrn(__LINE__, p1);
 }
 clist_p label_to_import_path(void* param, char* label){
-	return new_clist_1(sym(INTRP, label));
+	return new_clist_1(sym(IST, label));
 }
 clist_p append_label_to_import_path(void* param, clist_p list, char* label){
-	return clist_append(list, sym(INTRP, label));
+	return clist_append(list, sym(IST, label));
 }
 clist_p import_path_to_import_param(void* param, clist_p list){
 	return ins_clist(new_clist_1(list), NULL, 1);	
 }
 clist_p import_path_as_label_to_import_param(void* param, clist_p list, char* label){
-	return ins_clist(new_clist_1(list), sym(INTRP, label), 1);	
+	return ins_clist(new_clist_1(list), sym(IST, label), 1);	
 }
 clist_p new_import_param(void* param, clist_p list){
 	return new_clist_1(list);
@@ -356,31 +356,31 @@
 		p = new_code(param, 2, 2, 2, OP_PUSH_GLOBAL_REF);
 	else
 		p = new_code(param, 2, 2, 2, OP_PUSH_LOCAL_REF);
-	p->code_data[1].data = sym(INTRP, label);
+	p->code_data[1].data = sym(IST, label);
 	return debug_retrn(__LINE__, p);
 }
 code_p ds_label_to_attrref(void* param, char* label){
 	code_p p;
 	p = new_code(param, 2, 2, 2, OP_PUSH_SELF_REF);
-	p->code_data[1].data = sym(INTRP, label);
+	p->code_data[1].data = sym(IST, label);
 	return debug_retrn(__LINE__, p);
 }
 code_p caret_label_to_attrref(void* param, char* label){
 	code_p p;
 	p = new_code(param, 2, 2, 2, OP_PUSH_SUPER_REF);
-	p->code_data[1].data = sym(INTRP, label);
+	p->code_data[1].data = sym(IST, label);
 	return debug_retrn(__LINE__, p);
 }
 code_p amp_label_to_attrref(void* param, char* label){
 	code_p p;
 	p = new_code(param, 2, 2, 2, OP_PUSH_SYN_REF);
-	p->code_data[1].data = sym(INTRP, label);
+	p->code_data[1].data = sym(IST, label);
 	return debug_retrn(__LINE__, p);
 }
 code_p at_label_to_attrref(void* param, char* label){
 	code_p p;
 	p = new_code(param, 2, 2, 2, OP_PUSH_DYN_REF);
-	p->code_data[1].data = sym(INTRP, label);
+	p->code_data[1].data = sym(IST, label);
 	return debug_retrn(__LINE__, p);
 }
 code_p obj_label_to_attrref(void* param, code_p obj, char* label){
@@ -388,7 +388,7 @@
 	obj = pr_realloc(obj, sizeof(code)+(obj->len)*sizeof(code_t));
 	obj->code_data[obj->len-2].bytecode.opcode = OP_PUSH;
 	obj->code_data[obj->len-2].bytecode.param = 2;
-	obj->code_data[obj->len-1].data = sym(INTRP, label);
+	obj->code_data[obj->len-1].data = sym(IST, label);
 	obj->stack_depth += 1;
 	obj->max_stack_depth = max(obj->max_stack_depth, obj->stack_depth);
 	return debug_retrn(__LINE__, obj);
@@ -406,9 +406,9 @@
 	for(i=0; i < llen; i++)
 		calc_code(clist_item(parms,i), &len, &stack_depth, &max_stack_depth);
 	res = new_code(param, len+1, stack_depth, max_stack_depth, 0);
-	add_code_to(obj, res, &k);
+	add_code(obj, res, &k);
 	for(i=0; i < llen; i++)
-		add_code_to(clist_item(parms,i), res, &k);
+		add_code(clist_item(parms,i), res, &k);
 	res->code_data[k].bytecode.opcode  = OP_OBJCALL;
 	res->code_data[k++].bytecode.param = clist_len(parms);
 	res->stack_depth -= 2*llen;
@@ -425,9 +425,9 @@
 	for(i=0; i < llen; i++)
 		calc_code(clist_item(parms,i), &len, &stack_depth, &max_stack_depth);
 	res = new_code(param, len+1, stack_depth, max_stack_depth, 0);
-	add_code_to(attr_ref, res, &k);
+	add_code(attr_ref, res, &k);
 	for(i=0; i < llen; i++)
-		add_code_to(clist_item(parms,i), res, &k);
+		add_code(clist_item(parms,i), res, &k);
 	res->code_data[k].bytecode.opcode  = OP_CALL;
 	res->code_data[k++].bytecode.param = clist_len(parms);
 	res->stack_depth -= 1+(2*llen);
@@ -444,10 +444,10 @@
 	for(i=0; i < llen; i++)
 		calc_code(clist_item(parms,i), &len, &stack_depth, &max_stack_depth);
 	res = new_code(param, len+2, stack_depth, max_stack_depth, 0);
-	add_code_to(attr_ref, res, &k);
+	add_code(attr_ref, res, &k);
 	res->code_data[k++].bytecode.opcode = OP_DEREF;
 	for(i=0; i < llen; i++)
-		add_code_to(clist_item(parms,i), res, &k);
+		add_code(clist_item(parms,i), res, &k);
 	res->code_data[k  ].bytecode.opcode = OP_OBJCALL;
 	res->code_data[k++].bytecode.param  = clist_len(parms);
 	res->stack_depth -= 1+(2*llen);
@@ -464,12 +464,12 @@
 	for(i=0; i < llen; i++)
 		calc_code(clist_item(parms,i), &len, &stack_depth, &max_stack_depth);
 	res = new_code(param, len+1, stack_depth, max_stack_depth, 0);
-	add_code_to(obj, res, &k);
+	add_code(obj, res, &k);
 	res->code_data[k  ].bytecode.opcode = OP_PUSH;
 	res->code_data[k++].bytecode.param = 2;
-	res->code_data[k++].data = sym(INTRP, label);
+	res->code_data[k++].data = sym(IST, label);
 	for(i=0; i < llen; i++)
-		add_code_to(clist_item(parms,i), res, &k);
+		add_code(clist_item(parms,i), res, &k);
 	res->code_data[k  ].bytecode.opcode = OP_SUPERCALL;
 	res->code_data[k++].bytecode.param  = clist_len(parms);
 	res->stack_depth -= 1+(2*llen);
@@ -479,7 +479,7 @@
 code_p label_to_formparm(void* param, char* label){
 	code_p res = new_code(param, 3, 2, 2, OP_PUSH);
 	res->code_data[0].bytecode.param = 3;
-	res->code_data[1].data = sym(INTRP, label);
+	res->code_data[1].data = sym(IST, label);
 	res->code_data[2].data = PARAM_NORMAL;
 	return debug_retrn(__LINE__, res);
 }
@@ -491,21 +491,45 @@
 	memmove(expr->code_data+2, expr->code_data, ((expr->len)-2)*sizeof(code_t));
 	expr->code_data[0].bytecode.opcode = OP_PUSH;
 	expr->code_data[0].bytecode.param  = 2;
-	expr->code_data[1].data = sym(INTRP, label);
+	expr->code_data[1].data = sym(IST, label);
 	return debug_retrn(__LINE__, expr);
 }
+code_p lbl_proto_body_to_obj(void* param, code_p ref, clist_p protos, code_p body) {
+	obj_p func;
+	code_p res;
+	int code_len, llen = clist_len(protos);
+	int i, k=0, len=0, stack_depth=0, max_stack_depth=0;
+	calc_code(ref, &len, &stack_depth, &max_stack_depth);
+	for (i=0; i < llen; i++)
+		calc_code(clist_item(protos, i),&len, &stack_depth, &max_stack_depth);
+	len += 3;
+	res = new_code(param, len, stack_depth, max_stack_depth, 0);
+	add_code(ref, res, &k);
+	for (i=0; i < llen; i++)
+		add_code(clist_item(protos, i), res, &k);
+	res->code_data[k  ].bytecode.opcode = OP_OBJ;
+	res->code_data[k++].bytecode.param = 3;
+	func = new_object(IST, OBJ(FUNC_PROTO));
+	code_len = sizeof(code) + body->len * sizeof(code_t);
+	memmove(obj_malloc(func, code_len), body, code_len);
+	res->code_data[k++].data = func;
+	res->code_data[k++].num  = llen;
+	assert(k = len);
+	res->stack_depth -= (llen+1)*2-1;
+	return res;
+}
 code_p star_ref_to_formparm(void* param, char* label){
 	code_p res = new_code(param, 3, 2, 2, OP_PUSH);
 	res->code_data[0].bytecode.param = 3;
 	res->code_data[1].data = PARAM_STAR;
-	res->code_data[2].data = sym(INTRP, label);
+	res->code_data[2].data = sym(IST, label);
 	return debug_retrn(__LINE__, res);
 }
 code_p star_star_ref_to_formparm(void* param, char* label){
 	code_p res = new_code(param, 3, 2, 2, OP_PUSH);
 	res->code_data[0].bytecode.param = 3;
 	res->code_data[1].data = PARAM_STAR_STAR;
-	res->code_data[2].data = sym(INTRP, label);
+	res->code_data[2].data = sym(IST, label);
 	return debug_retrn(__LINE__, res);
 }
 code_p expr_to_sparm(void* param, code_p p1){
@@ -522,7 +546,7 @@
 }
 void add_slice(code_p res, code_p p, int *k, int parm_cnt, int count){
 	if (p && p->len)
-		add_code_to(p, res, k);
+		add_code(p, res, k);
 	else {
 		res->code_data[(*k)  ].bytecode.opcode = OP_PUSH;
 		res->code_data[(*k)++].bytecode.param  = 2;
@@ -581,7 +605,7 @@
 		len += 7;
 		res = new_code(param, len, stack_depth, max_stack_depth, 0);
 		res->cmp_expr = TRUE;
-		add_code_to(lparm, res, &k);
+		add_code(lparm, res, &k);
 		res->code_data[k  ].bytecode.opcode = OP_BEQ;
 		res->code_data[k  ].bytecode.param  = res->len-k;
 		k++;
@@ -607,10 +631,10 @@
 		res = new_code(param, len, stack_depth, max_stack_depth, 0);
 got_lparm:
 		if (!have_lparm)
-			add_code_to(lparm, res, &k);			
+			add_code(lparm, res, &k);			
 		if (have_cmp_op) {
 			res->cmp_expr = TRUE;
-			add_code_to(rparm, res, &k);
+			add_code(rparm, res, &k);
 			res->code_data[k++].bytecode.opcode = OP_SWAP;
 		}
 		res->code_data[k  ].bytecode.opcode = OP_PUSH;
@@ -621,7 +645,7 @@
 			res->code_data[k  ].bytecode.opcode = OP_DUPLICATE;
 			res->code_data[k++].bytecode.param  = -4;
 		} else
-			add_code_to(rparm, res, &k);
+			add_code(rparm, res, &k);
 		res->code_data[k  ].bytecode.opcode = OP_CALL;
 		res->code_data[k++].bytecode.param  = 1;
 		if (have_cmp_op)
@@ -636,7 +660,7 @@
 	code_p res = new_code( param,  lparm->len + 7 + rparm->len + 2, 1, 
 				          max( max( lparm->max_stack_depth, 
 				          lparm->stack_depth+1+rparm->max_stack_depth ), 3 ), 0 );
-	add_code_to(lparm, res, &k);
+	add_code(lparm, res, &k);
 	res->code_data[k  ].bytecode.opcode = OP_DUPLICATE;
 	res->code_data[k++].bytecode.param  = -1;
 	res->code_data[k  ].bytecode.opcode = OP_PUSH;
@@ -650,7 +674,7 @@
 		(andor_flg == OR_FLAG? OBJ(PR_TRUE) : OBJ(PR_FALSE));
 	res->code_data[k  ].bytecode.opcode = OP_POP;
 	res->code_data[k++].bytecode.param  = 2;
-	add_code_to(rparm, res, &k);
+	add_code(rparm, res, &k);
 	res->code_data[k  ].bytecode.opcode = OP_BR;
 	res->code_data[k++].bytecode.param  = 2;
 	res->code_data[k  ].bytecode.opcode = OP_POP;
@@ -698,21 +722,21 @@
 	if (els->len)
 		calc_code(els, &len, &stack_depth, &max_stack_depth);
 	res = new_code(param, len, stack_depth, max_stack_depth, 0);
-	add_code_to(ifex, res, &k);
+	add_code(ifex, res, &k);
 	add_skip_code1(body, res, &k);
-	add_code_to(body, res, &k);
+	add_code(body, res, &k);
 	add_skip_code2(res->len - k, res, &k);
 	for(i=0; i < clist_len(elif); i++){
 		clist_p eil = clist_item(elif,i);
 		code_p pexpr = clist_item(eil,0);
 		code_p pbody = clist_item(eil,1);
-		add_code_to(pexpr, res, &k);
+		add_code(pexpr, res, &k);
 		add_skip_code1(pbody, res, &k);
-		add_code_to(pbody, res, &k);
+		add_code(pbody, res, &k);
 		add_skip_code2(res->len - k, res, &k);
 	}
 	if (els->len)
-		add_code_to(els, res, &k);
+		add_code(els, res, &k);
 	assert(k == res->len);
 	return debug_retrn(__LINE__, res);
 }
@@ -794,7 +818,7 @@
 	assert(clist_len(loc_list) >= 1);
 	end_loc  = clist_pop_num(loc_list);
 
-	add_code_to(ifexpr, res, k);
+	add_code(ifexpr, res, k);
 	res->code_data[(*k)  ].bytecode.opcode = OP_PUSH;
 	res->code_data[(*k)++].bytecode.param  = 2;
 	res->code_data[(*k)++].data = SYM(__BOOL__QUES);
@@ -812,7 +836,7 @@
 			add_for_clause( param, res, k, itemexpr, clist_item(lcc, lccp),
 			                lccp+1, lcc, stk_ofs-1, loc_list );
 	} else {
-		add_code_to(itemexpr, res, k);
+		add_code(itemexpr, res, k);
 		res->code_data[*k    ].bytecode.opcode = OP_APPEND;
 		res->code_data[(*k)++].bytecode.param  = stk_ofs-2;
 		assert(clist_len(loc_list) == 0);
@@ -875,9 +899,9 @@
 			printf("For variable not local: %s\n",s);
 			pr_exit(1);
 		}
-		clist_item(forlst,i) = sym(INTRP, clist_item(forlst,i));
+		clist_item(forlst,i) = sym(IST, clist_item(forlst,i));
 	}
-	add_code_to(expr, res, k);
+	add_code(expr, res, k);
 	res->code_data[*k    ].bytecode.opcode = OP_PUSH;
 	res->code_data[(*k)++].bytecode.param  = 2;
 	res->code_data[(*k)++].data = SYM(__ITER__);
@@ -908,7 +932,7 @@
 			add_for_clause( param, res, k, itemexpr, clist_item(lcc, lccp),
 			                lccp+1, lcc, stk_ofs-1, loc_list );
 	} else {
-		add_code_to(itemexpr, res, k);
+		add_code(itemexpr, res, k);
 		res->code_data[*k    ].bytecode.opcode = OP_APPEND;
 		res->code_data[(*k)++].bytecode.param  = stk_ofs-2;
 		assert(clist_len(loc_list) == 0);
@@ -963,7 +987,7 @@
 			printf("For variable not local: %s\n",s);
 			pr_exit(1);
 		}
-		clist_item(targets,i) = sym(INTRP, clist_item(targets,i));
+		clist_item(targets,i) = sym(IST, clist_item(targets,i));
 	}
 	calc_code(expr, &len, &stack_depth, &max_stack_depth); 
 	len += 4;			
@@ -980,7 +1004,7 @@
 	len++;
 	end_loc  = len;
 	res = new_code(param, len, stack_depth, max_stack_depth+2, 0);
-	add_code_to(expr, res, &k);
+	add_code(expr, res, &k);
 	res->code_data[k  ].bytecode.opcode = OP_PUSH;
 	res->code_data[k++].bytecode.param  = 2;
 	res->code_data[k++].data = SYM(__ITER__);
@@ -1004,7 +1028,7 @@
 	res->code_data[k  ].bytecode.opcode = OP_SEQ_ASSIGN;
 	res->code_data[k++].bytecode.param  = llen-1;
 	assert(body_loc == k);
-	add_code_to(body, res, &k);
+	add_code(body, res, &k);
 	res->code_data[k  ].bytecode.opcode = OP_BR;
 	res->code_data[k  ].bytecode.param  = loop_loc - k;
 	k++;
@@ -1022,7 +1046,7 @@
 	res->code_data[k  ].bytecode.param  = end_els_loc - k;
 	k++;
 	if (els->len)
-		add_code_to(els, res, &k);
+		add_code(els, res, &k);
 	assert(end_els_loc == k);
 	res->code_data[k++].bytecode.opcode = OP_RERAISE;
 	assert(end_loc == k);
@@ -1046,7 +1070,7 @@
 	len++;
 	end_loc = len;
 	res = new_code(param, len, stack_depth, max_stack_depth, 0);
-	add_code_to(rparm, res, &k);
+	add_code(rparm, res, &k);
 	res->code_data[k++].bytecode.opcode = OP_SAVE_TMP;
 	res->code_data[k  ].bytecode.opcode = OP_TRYEXCEPT;
 	res->code_data[k  ].bytecode.param  = end_icall_loc - k;
@@ -1082,7 +1106,7 @@
 	res->code_data[k++].bytecode.opcode = OP_RESTORE_TMP;
 	res->code_data[k  ].bytecode.opcode = OP_CALL;
 	res->code_data[k++].bytecode.param  = 1;
-	add_code_to(ref, res, &k);
+	add_code(ref, res, &k);
 	res->code_data[k  ].bytecode.opcode = OP_ASSIGN;
 	res->code_data[k++].bytecode.param  = 1;
 	res->code_data[k  ].bytecode.opcode = OP_POP;
@@ -1111,7 +1135,7 @@
 	end_loc  = len;
 	res = new_code(param, len, stack_depth, max_stack_depth, 0);
 	assert(loop_loc == k);
-	add_code_to(expr, res, &k);
+	add_code(expr, res, &k);
 	res->code_data[k  ].bytecode.opcode = OP_PUSH;
 	res->code_data[k++].bytecode.param  = 2;
 	res->code_data[k++].data = SYM(__BOOL__QUES);
@@ -1124,7 +1148,7 @@
 	res->code_data[k  ].bytecode.opcode = OP_POP;
 	res->code_data[k++].bytecode.param  = 1;
 	assert(body_loc == k);
-	add_code_to(body, res, &k);
+	add_code(body, res, &k);
 	res->code_data[k  ].bytecode.opcode = OP_BR;
 	res->code_data[k  ].bytecode.param  = loop_loc - k;
 	k++;
@@ -1135,7 +1159,7 @@
 	res->code_data[k  ].bytecode.opcode = OP_POP;
 	res->code_data[k++].bytecode.param  = 1;
 	if (els->len)
-		add_code_to(els, res, &k);
+		add_code(els, res, &k);
 	assert(end_loc == k);
 	return debug_retrn(__LINE__, res);
 }
@@ -1150,7 +1174,7 @@
 	len++;
 	pop_loc = len;
 	res = new_code(param, len+1, stack_depth, max_stack_depth, 0);
-	add_code_to(cond, res, &k);
+	add_code(cond, res, &k);
 	res->code_data[k  ].bytecode.opcode = OP_PUSH;
 	res->code_data[k++].bytecode.param  = 2;
 	res->code_data[k++].data = SYM(__BOOL__QUES);
@@ -1162,7 +1186,7 @@
 	res->code_data[k++].data = OBJ(PR_TRUE);
 	res->code_data[k  ].bytecode.opcode = OP_POP;
 	res->code_data[k++].bytecode.param  = 1;
-	add_code_to(exc, res, &k);
+	add_code(exc, res, &k);
 	res->code_data[k++].bytecode.opcode = OP_RAISE;
 	assert(pop_loc == k);
 	res->code_data[k  ].bytecode.opcode = OP_POP;
@@ -1204,13 +1228,13 @@
 	}
 	res = new_code(param, len, stack_depth, max_stack_depth, 0);
 	if (name)
-		add_code_to(name, res, &k);
+		add_code(name, res, &k);
 	if (params)
 		for(i=0; i < llen; i++)
-			add_code_to(clist_item(params,i), res, &k);
+			add_code(clist_item(params,i), res, &k);
 	if (self)
-		add_code_to(self, res, &k);
-	func = new_object(INTRP, OBJ(FUNC_PROTO));
+		add_code(self, res, &k);
+	func = new_object(IST, OBJ(FUNC_PROTO));
 	code_len = blen * sizeof(code_t);
 	memmove(obj_malloc(func, code_len), body, code_len);
 	switch (flg) {
@@ -1230,7 +1254,7 @@
 	}
 	assert(res->len == k);
 	if (body->doc_flg)
-		set_attr(INTRP, func, SYM(__DOC__), (obj_p)(body->code_data[1].data));
+		set_attr(IST, func, SYM(__DOC__), (obj_p)(body->code_data[1].data));
 	return debug_retrn(__LINE__, res);
 }
 code_p print_arglist(void* param, clist_p list){
@@ -1250,7 +1274,7 @@
 	for(i=0; i < clist_len(list); i++){
 		code_p p = (code_p)clist_item(list,i);
 		if(p)
-			add_code_to(p, res, &k);
+			add_code(p, res, &k);
 		else {
 			res->code_data[k  ].bytecode.opcode = OP_PUSH;
 			res->code_data[k++].bytecode.param  = 2;
@@ -1270,7 +1294,7 @@
 		calc_code((code_p)clist_item(lst,i), &len, &stack_depth, &max_stack_depth);
 	res = new_code(param, len, stack_depth, max_stack_depth, 0);
 	for(i=0; i < clist_len(lst); i++)
-		add_code_to(clist_item(lst,i), res, &k);
+		add_code(clist_item(lst,i), res, &k);
 	res->code_data[k  ].bytecode.opcode = 
 					(tuple_flag == NEW_TUPLE_ ? OP_NEWTUPLE : OP_NEWLIST);
 	res->code_data[k++].bytecode.param  = clist_len(lst);
@@ -1292,8 +1316,8 @@
 		clist_p pl = (clist_p)clist_item(lst,i);
 		code_p key = (code_p)clist_item(pl,0);
 		code_p val = (code_p)clist_item(pl,1);
-		add_code_to(key, res, &k);
-		add_code_to(val, res, &k);
+		add_code(key, res, &k);
+		add_code(val, res, &k);
 		pr_free(pl);
 	}
 	res->code_data[k  ].bytecode.opcode = OP_NEWDICT;
@@ -1310,7 +1334,7 @@
 	res = new_code(param, len, stack_depth, max_stack_depth, OP_PUSH);
 	res->code_data[k++].bytecode.param = 2;
 	res->code_data[k++].data = word;
-	add_code_to(expr, res, &k);
+	add_code(expr, res, &k);
 	assert(res->len == k);
 	return debug_retrn(__LINE__, res);
 }
@@ -1318,7 +1342,7 @@
 	return debug_retrn(__LINE__, word_expr_to_param(param, PARAM_NORMAL, expr));
 }
 code_p label_eq_expr_to_param(void* param, char* label, code_p expr){
-	return debug_retrn(__LINE__, word_expr_to_param(param, sym(INTRP, label), expr));
+	return debug_retrn(__LINE__, word_expr_to_param(param, sym(IST, label), expr));
 }
 code_p star_seq_to_param(void* param, code_p expr){
 	return debug_retrn(__LINE__, word_expr_to_param(param, PARAM_STAR, expr));
@@ -1328,7 +1352,7 @@
 }
 code_p int_to_obj(void* param, i64_t num){
 	code_p res;
-	obj_p obj = new_object(INTRP, OBJ(INT_PROTO));
+	obj_p obj = new_object(IST, OBJ(INT_PROTO));
 	*((i64_t*) obj_malloc(obj, sizeof(i64_t))) = num;
 	res = new_code(param, 2, 1, 1, OP_PUSH);
 	res->code_data[0].bytecode.param = 2;
@@ -1338,7 +1362,7 @@
 }
 code_p float_to_obj(void* param, double num, int imag_flag){
 	code_p res;
-	obj_p obj = new_object(INTRP, 
+	obj_p obj = new_object(IST, 
 		(imag_flag == NEW_IMAG? OBJ(IMAG_PROTO) : OBJ(FLOAT_PROTO)) );
 	*((double*) obj_malloc(obj, sizeof(double))) = num;
 	res = new_code(param, 2, 1, 1, OP_PUSH);
@@ -1351,7 +1375,7 @@
 	code_p p = new_code(param, 2, 1, 1, OP_PUSH);
 	pr_str_p obj_str;
 	size_t len = strlen(str);
-	obj_p obj = new_object(INTRP, 
+	obj_p obj = new_object(IST, 
 			(long_flag == NEW_LONG? OBJ(LONG_PROTO) : OBJ(STRING_PROTO)) );
 	if (len < IMMEDIATE_DATA_LEN) {
 		obj->data_type    = DATA_TYPE_IMMDATA;
@@ -1383,7 +1407,7 @@
 	res = new_code(param, len, stack_depth, max_stack_depth, 0);
 	res->assign_parm_cnt = rlen;
 	for(i=0; i < rlen; i++)
-		add_code_to(clist_item(right,i), res, &k);
+		add_code(clist_item(right,i), res, &k);
 	assert(k==res->len);
 	return debug_retrn(__LINE__, res);
 }
@@ -1403,7 +1427,7 @@
 	res = new_code(param, len, stack_depth, max_stack_depth, 0);
 	res->assign_parm_cnt = rlen;
 	for(i=0; i < llen; i++)
-		add_code_to(clist_item(left,i), res, &k);
+		add_code(clist_item(left,i), res, &k);
 	res->code_data[k  ].bytecode.opcode = (seq_expand ? OP_SEQ_ASSIGN : OP_ASSIGN);
 	res->code_data[k++].bytecode.param  = llen;
 	res->stack_depth -= llen*2;
@@ -1429,11 +1453,11 @@
 	int k=0, len=3, stack_depth=1, max_stack_depth = 1;
 	calc_code(expr, &len, &stack_depth, &max_stack_depth);
 	res = new_code(param, len, stack_depth, max_stack_depth, 0);
-	add_code_to(expr, res, &k);
+	add_code(expr, res, &k);
 	res->code_data[k  ].bytecode.opcode = OP_PUSH;
 	res->code_data[k++].bytecode.param  = 2;
 	if (label)
-		res->code_data[k++].data = sym(INTRP, label);
+		res->code_data[k++].data = sym(IST, label);
 	else
 		res->code_data[k++].data = OBJ(NONE);
 	res->code_data[k  ].bytecode.opcode = OP_EXCEPT;
@@ -1460,20 +1484,20 @@
 	res->code_data[k  ].bytecode.opcode = OP_TRYEXCEPT;
 	res->code_data[k  ].bytecode.param  = except_loc - k;
 	k++;
-	add_code_to(body, res, &k);
+	add_code(body, res, &k);
 	res->code_data[k  ].bytecode.opcode = OP_BR;
 	res->code_data[k  ].bytecode.param  = els_loc - k;
 	k++;
 	assert(except_loc == k);
 	for (i = 0; i < llen; i++, k++) {
-		add_code_to(clist_item(except_list,i), res, &k);
+		add_code(clist_item(except_list,i), res, &k);
 		res->code_data[k  ].bytecode.opcode = OP_BR;
 		res->code_data[k  ].bytecode.param  = end_loc - k;
 	}
 	res->code_data[k++].bytecode.opcode = OP_RERAISE;
 	assert(els_loc == k);
 	if (els)
-		add_code_to(els, res, &k);
+		add_code(els, res, &k);
 	assert(end_loc == k);
 	return debug_retrn(__LINE__, res);
 }
@@ -1484,8 +1508,8 @@
 	calc_code(final, &len, &stack_depth, &max_stack_depth);
 	res = new_code(param, len, stack_depth, max_stack_depth, OP_TRYFINALLY);
 	res->code_data[k++].bytecode.param = body->len+1;
-	add_code_to(body, res, &k);
-	add_code_to(final, res, &k);
+	add_code(body, res, &k);
+	add_code(final, res, &k);
 	res->code_data[k++].bytecode.opcode = OP_RERAISE;
 	assert(res->len == k);
 	return debug_retrn(__LINE__, res);

Modified: trunk/src/prothon.y
===================================================================
--- trunk/src/prothon.y	2004-04-28 07:22:11 UTC (rev 426)
+++ trunk/src/prothon.y	2004-04-28 22:42:43 UTC (rev 427)
@@ -60,9 +60,9 @@
 #define YYDEBUG 1
 #define YYERROR_VERBOSE 1
 
-#define alloca pr_malloc
-#define YYLEX_PARAM   yylex_param
-#define YYPARSE_PARAM yylex_param
+#define alloca			pr_malloc
+#define YYLEX_PARAM		yylex_param
+#define YYPARSE_PARAM	yylex_param
 
 #define INITIAL_STRING_ALLOC 1024
 
@@ -86,7 +86,7 @@
 	double		float_type;
 	char*		str_type;
 	code_p		code_type;
-	clist_p	list_type;
+	clist_p		list_type;
 }
 
 %{
@@ -109,6 +109,7 @@
 %nonassoc GEN      
 %nonassoc IF        
 %nonassoc IMPORT    
+%nonassoc OBJ_      
 %nonassoc PASS      
 %nonassoc PRINT     
 %nonassoc RAISE     
@@ -202,7 +203,7 @@
 			formal_params elif mul_elif list_params
 			list_params2 for_refs for_refs1 for_refs2 arg_list
 			arg_list2 tuple_params tuple_params2 for_lc_clause
-			lc_clauses if_lc_clause
+			lc_clauses if_lc_clause protos proto_refs
 
 %type <code_type>	statement_block statement mul_statement
 			mul_statements compound_statement expr obj
@@ -210,7 +211,7 @@
 			def_statement import_statement small_statement
 			if_statement while_statement for_statement gen_ref
 			try_except_statement except else_except
-			try_finally_statement def_ref print_statement
+			try_finally_statement obj_ref def_ref print_statement
 			assert_statement target_param attr_ref unbound_ref
 			ass_add_statement ass_sub_statement
 			ass_mul_statement ass_div_statement
@@ -222,7 +223,7 @@
 			function_param break_statement return_statement
 			yield_statement with_statement continue_statement
 			del_statement del_tgt exec_statement
-			raise_statement list_comp
+			raise_statement obj_statement list_comp proto_ref
 
 					
 					
@@ -250,7 +251,7 @@
 	;
 compound_statement: 
 		if_statement 		 | while_statement       |  def_statement    | with_statement |
-		try_except_statement | try_finally_statement |  for_statement
+		try_except_statement | try_finally_statement |  for_statement	 | obj_statement
 	;
 small_statement: 
 		expr		   	   | assignment_statement |
@@ -359,7 +360,7 @@
 except:
 		EXCEPT_ compound_body										{ $$ = expr_label_body_to_except(yylex_param, exceptall(yylex_param), NULL, $2); }
 	|	EXCEPT_ expr compound_body									{ $$ = expr_label_body_to_except(yylex_param, $2, NULL, $3); }
-	|	EXCEPT_ expr ',' LABEL compound_body							{ $$ = expr_label_body_to_except(yylex_param, $2, $4, $5); }
+	|	EXCEPT_ expr ',' LABEL compound_body						{ $$ = expr_label_body_to_except(yylex_param, $2, $4, $5); }
 	;
 else_except:
 		/* empty string */											{ $$ = none(yylex_param); }
@@ -371,6 +372,32 @@
 with_statement:
 		WITH obj compound_body										{ $$ = ref_parm_body_to_def(yylex_param, NULL, NULL, $2, $3, WTH_FLG); }						
 	;
+obj_statement:	
+		obj_ref '('  protos ')' compound_body						{ $$ = lbl_proto_body_to_obj(yylex_param, $1, $3, $5); }
+	;
+obj_ref:
+		OBJ_ LABEL													{ $$ = label_to_attrref(yylex_param, $2);		state->defdoc_flag=1; }
+	|	OBJ_ '$' LABEL								%prec UDOT		{ $$ = ds_label_to_attrref(yylex_param, $3);	state->defdoc_flag=1; }
+	|	OBJ_ '^' LABEL								%prec UCARET	{ $$ = caret_label_to_attrref(yylex_param, $3);	state->defdoc_flag=1; }
+	|	OBJ_ '&' LABEL								%prec UAMP		{ $$ = amp_label_to_attrref(yylex_param, $3);	state->defdoc_flag=1; }
+	|	OBJ_ '@' LABEL												{ $$ = at_label_to_attrref(yylex_param, $3);	state->defdoc_flag=1; }
+	|	OBJ_ obj '.' LABEL											{ $$ = obj_label_to_attrref(yylex_param, $2, $4);state->defdoc_flag=1; }
+	;				
+protos:
+		/*none*/													{ $$ = empty_list(yylex_param); }
+	|	proto_refs														
+	;																
+proto_refs:
+		proto_ref													{ $$ = new_list(yylex_param, $1); }
+	|	proto_refs ',' proto_ref									{ $$ = append_list(yylex_param, $1, $3); }
+	;
+proto_ref:
+		LABEL														{ $$ = label_to_attrref(yylex_param, $1); }
+	|	'$' LABEL								%prec UDOT			{ $$ = ds_label_to_attrref(yylex_param, $2); }
+	|	'^' LABEL								%prec UCARET		{ $$ = caret_label_to_attrref(yylex_param, $2); }
+	|	'&' LABEL								%prec UAMP			{ $$ = amp_label_to_attrref(yylex_param, $2); }
+	|	'@' LABEL													{ $$ = at_label_to_attrref(yylex_param, $2); }
+	;				
 def_statement:	
 		def_ref '('  formal_params ')' compound_body				{ $$ = ref_parm_body_to_def(yylex_param, $1, $3, NULL, $5, DEF_FLG); }
 	|	gen_ref '('  formal_params ')' compound_body				{ $$ = ref_parm_body_to_def(yylex_param, $1, $3, NULL, $5, GEN_FLG); }
@@ -1115,6 +1142,7 @@
 		if (!strcmp(str_ptr,"gen")) 	return GEN;		
 		if (!strcmp(str_ptr,"if")) 		return IF;
 		if (!strcmp(str_ptr,"import")) 	return IMPORT;
+		if (!strcmp(str_ptr,"object")) 	return OBJ_;
 		if (!strcmp(str_ptr,"pass")) 	return PASS;
 		if (!strcmp(str_ptr,"print")) 	return PRINT;
 		if (!strcmp(str_ptr,"raise")) 	return RAISE;

Modified: trunk/src/src.vcproj
===================================================================
--- trunk/src/src.vcproj	2004-04-28 07:22:11 UTC (rev 426)
+++ trunk/src/src.vcproj	2004-04-28 22:42:43 UTC (rev 427)
@@ -277,6 +277,9 @@
 				RelativePath="..\pr\modint.pr">
 			</File>
 			<File
+				RelativePath="..\pr\object.pr">
+			</File>
+			<File
 				RelativePath="..\pr\oops.pr">
 			</File>
 			<File