changeset 75:0083b2f7b3c7

Partially working implementation of List. Modified build scripts to allow use of other compilers. Fixed some bugs involving method implementations on different types returning different numbers of outputs. Added Fold to the 'builtins' in the comipler.
author Mike Pavone <pavone@retrodev.com>
date Tue, 06 Jul 2010 07:52:59 -0400
parents a844c623c7df
children 004f0fc8941f
files backendutils.rhope cbackend.rhope compile ctobin extendlib.rhope functional.rhope kernel.rhope list.rhope nworker.rhope parser_old.rhope runtime/func.h testlist.rhope
diffstat 12 files changed, 699 insertions(+), 76 deletions(-) [+]
line wrap: on
line diff
--- a/backendutils.rhope	Thu Jul 01 21:32:08 2010 -0400
+++ b/backendutils.rhope	Tue Jul 06 07:52:59 2010 -0400
@@ -1,7 +1,7 @@
 
 Escape Rhope Name NU[name:escaped]
 {
-	escaped <- [[[[[[[[[[[[[[[name]Replace["_","UN_"]
+	escaped <- [[[[[[[[[[[[[[[[[[[[name]Replace["_","UN_"]
 		]Replace["@","AT_"]
 		]Replace[" ","SP_"]
 		]Replace[":","CN_"]
@@ -15,7 +15,12 @@
 		]Replace["(","LP_"]
 		]Replace[")","RP_"]
 		]Replace["!","NT_"]
-		]Replace["=","EQ_"]
+		]Replace["=","EQ_"]
+		]Replace["'","PR_"]
+		]Replace["\"","DP_"]
+		]Replace["\t","TB_"]
+		]Replace[",", "CM_"]
+		]Replace[".", "PD_"]
 }
 
 Escape Rhope Name[name:escaped]
@@ -135,6 +140,26 @@
 	out <- op
 }
 
+Blueprint Check Result
+{
+	Output Num
+}
+
+Check Result[num:out]
+{
+	out <- [Build["Check Result"]]Output Num <<[num]
+}
+
+Make Op@Check Result[result,func:out]
+{
+	out <- [func]Checked Result Reference[[result]Output Num>>]
+}
+
+Strip Addref@Check Result[op:out]
+{
+	out <- op
+}
+
 Make Condition[op:out]
 {
 	If[[Type Of[op]]=["OrValue"]]
--- a/cbackend.rhope	Thu Jul 01 21:32:08 2010 -0400
+++ b/cbackend.rhope	Tue Jul 06 07:52:59 2010 -0400
@@ -236,7 +236,13 @@
 {
 	If[[[[ctype]Fields >>]Length] = [1]]
 	{
-		out <- [[[_Type Def C Type["typedef struct {\n\tobject _SP_header;\n\t", [[ctype]Fields >>]Index[0]]]Append["\n} t_"]]Append[[ctype]Name >>]]Append[";"]
+		out <- [[[[_Type Def C Type["typedef struct {\n\tobject _SP_header;\n\t", [[ctype]Fields >>]Index[0]]]Append["\n} t_"]]Append[Escape Rhope Name[[ctype]Name >>]]]Append[";"]
+					]Append[ 
+						[[[["typedef "
+							]Append[Rhope Type to C[ [[[ctype]Fields >>]Index[0]]Index[1] ]]
+							]Append[" nt_"]
+							]Append[Escape Rhope Name[[ctype]Name >>]]
+							]Append[";"] ]
 	}{
 		//HACK!!!
 		If[[[ctype]Name >>]=["Blueprint"]]
@@ -316,24 +322,24 @@
 {
 	out <- [[[Build["C Type Registry"]]Lookup << [
 			[[[[[[[[[[[[[[[[[[Dictionary[]
-			]Set["UInt8", "TYPE_UINT8"]
-			]Set["UInt16", "TYPE_UINT16"]
-			]Set["UInt32", "TYPE_UINT32"]
-			]Set["UInt64", "TYPE_UINT64"]
-			]Set["Int8", "TYPE_INT8"]
-			]Set["Int16", "TYPE_INT16"]
-			]Set["Int32", "TYPE_INT32"]
-			]Set["Int64", "TYPE_INT64"]
-			]Set["Boolean", "TYPE_BOOLEAN"]
-			]Set["Float32", "TYPE_FLOAT32"]
-			]Set["Float64", "TYPE_FLOAT64"]
-			]Set["Real Number", "TYPE_FLOAT64"]
-			]Set["Blueprint", "TYPE_BLUEPRINT"]
-			]Set["Array", "TYPE_ARRAY"]
-			]Set["Worker", "TYPE_WORKER"]
-			]Set["Method Missing Exception", "TYPE_METHODMISSINGEXCEPTION"]
-			]Set["Field Missing Exception", "TYPE_FIELDMISSINGEXCEPTION"]
-			]Set["Wrong Type Exception", "TYPE_WRONGTYPEEXCEPTION"]]
+			]Set["UInt8", "TYPE_UINT8"]			//1
+			]Set["UInt16", "TYPE_UINT16"]		//2
+			]Set["UInt32", "TYPE_UINT32"]		//3
+			]Set["UInt64", "TYPE_UINT64"]		//4
+			]Set["Int8", "TYPE_INT8"]			//5
+			]Set["Int16", "TYPE_INT16"]			//6
+			]Set["Int32", "TYPE_INT32"]			//7
+			]Set["Int64", "TYPE_INT64"]			//8
+			]Set["Boolean", "TYPE_BOOLEAN"]		//9
+			]Set["Float32", "TYPE_FLOAT32"]		//10
+			]Set["Float64", "TYPE_FLOAT64"]		//11
+			]Set["Real Number", "TYPE_FLOAT64"]	//12
+			]Set["Blueprint", "TYPE_BLUEPRINT"]	//13
+			]Set["Array", "TYPE_ARRAY"]			//14
+			]Set["Worker", "TYPE_WORKER"]		//15
+			]Set["Method Missing Exception", "TYPE_METHODMISSINGEXCEPTION"]	//16
+			]Set["Field Missing Exception", "TYPE_FIELDMISSINGEXCEPTION"]	//17
+			]Set["Wrong Type Exception", "TYPE_WRONGTYPEEXCEPTION"]]		//18
 		]Definitions << [Dictionary[]]
 		]Next ID <<[0]
 }
@@ -883,12 +889,28 @@
 		]Add Raw Line["}"]
 		]Resume Index <<[[stream]Resume Index >>]
 
+}
+
+Discard Outputs@C Function[func,first to discard:out]
+{
+	out <- [[[[[func
+		]Add Raw Line[[["for(idx = "]Append[first to discard]]Append["; idx < cdata->num_params; ++idx)"]]
+		]Add Raw Line["{"]
+		]Add Raw Line["	if (cdata->params[idx])"]
+		]Add Raw Line["		release_ref(cdata->params[idx]);"]
+		]Add Raw Line["}"]
 }
 
 Result Reference@C Function[func,output:out]
 {
 	out <- [["cdata->params["]Append[output]]Append["]"]
-}
+}
+
+Checked Result Reference@C Function[func,output:out]
+{
+	out <- [[[["("]Append[output]]Append[" < cdata->num_params ? cdata->params["]]Append[output]]Append["] : NULL)"]
+}
+
 
 If Null Else@C Function[func,left,right:out]
 {
@@ -1187,7 +1209,7 @@
 				}{
 					If[[valtype] = ["String"]]
 					{
-						out <- [["make_String(\""]Append[ [[value]Replace["\\", "\\\\"]]Replace["\n", "\\n"]]]Append["\")"]
+						out <- [["make_String(\""]Append[ [[[value]Replace["\\", "\\\\"]]Replace["\n", "\\n"]]Replace["\"", "\\\""] ]]Append["\")"]
 					}{
 						If[[valtype]=["Worker Literal"]]
 						{
@@ -1415,7 +1437,7 @@
 					constants]]
 		]Append[Fold[["_Text C Program"]Set Input[2, [program]Type Registry >>], "", Filter[[program]Functions >>, "Not Native"]]]
 		]Append["\n
-uint16_t rhope(uint32_t func, object ** params, uint16_t numparams, uint16_t callspace)
+int32_t rhope(uint32_t func, object ** params, uint16_t numparams, uint16_t callspace)
 {
 	uint16_t resume,idx, vcparam_offset, last_vcparam;
 	context * ct;
@@ -1426,7 +1448,7 @@
 	cdata = alloc_cdata(ct, NULL, callspace);
 	cdata->num_params = numparams;
 	for(idx = 0; idx < numparams; ++idx)
-		cdata->params[0-idx] = params[idx];
+		cdata->params[idx] = params[idx];
 	cdata->func = END;
 DISPATCH\n"]
 		]Append[Fold[["Method Dispatch"]Set Input[3, [program]Type Registry >>], "", all methods]]
@@ -1457,7 +1479,7 @@
 		]Append["
 DO_END:
 	for(idx = 0; idx < cdata->num_params; ++idx)	
-		params[idx] = cdata->params[0-idx];
+		params[idx] = cdata->params[idx];
 	free_context(ct);
 	return cdata->num_params;
 
@@ -1468,7 +1490,7 @@
 		printf(\"%d\\n\", cdata->func);
 		cdata = cdata->lastframe;
 	}
-	return 0;
+	return -1;
 }
 
 #include \"builtin.c\"
@@ -1477,14 +1499,33 @@
 
 int main(int argc, char **argv)
 {
-	blueprint * bp;
+	blueprint * bp;
+	int numret;
+	int idx;
+	object * inout[2];
 	register_builtin_types();\n\n"]
 		]Append[ [[program]Type Registry >>]Type Inits[[program]Method Registry >>, [program]Field Registry >>] ]
 		]Append[Fold[["_Set Consts C Program"]Set Input[3, [program]Type Registry >>], "", constants]]
 		]Append[Fold[["_Set Late Consts C"]Set Input[3, [program]Type Registry >>], "", constants]]
-		]Append["
-	rhope(FUNC_Main, NULL, 0, 0);
-	return 0;
+		]Append["
+	rhope(FUNC_List, inout, 0, 1);
+	for (idx = 0; idx < argc; ++idx)
+	{
+		inout[1] = make_String(argv[idx]);
+		rhope(FUNC_Append, inout, 2, 2);
+	}
+	numret = rhope(FUNC_Main, inout, 1, 1);
+	if (!numret)
+		return 0;
+	if (numret < 0)
+		return numret;
+	if (get_blueprint(inout[0])->type_id == TYPE_INT32)
+		return ((t_Int32 *)inout[0])->Num;
+
+	rhope(FUNC_If, inout, 1, 2);
+	if (inout[0])
+		return 0;
+	return 1;
 }\n\n"]
 
 }
--- a/compile	Thu Jul 01 21:32:08 2010 -0400
+++ b/compile	Tue Jul 06 07:52:59 2010 -0400
@@ -11,13 +11,14 @@
 	exit 1
 fi
 
-cp runtime/* build/
-cp "$1.c" build/
-cd build
-bin=`echo $1 | sed s/\.rhope//`
+./ctobin $@
+#cp runtime/* build/
+#cp "$1.c" build/
+#cd build
+#bin=`echo $1 | sed s/\.rhope//`
+#
+#if test -f "$bin"; then
+#	rm "$bin"
+#fi
+#gcc -Wformat=0 -o $bin $2 "$1.c" blueprint.c context.c fixed_alloc.c object.c
 
-if test -f "$bin"; then
-	rm "$bin"
-fi
-gcc -Wformat=0 -o $bin $2 "$1.c" blueprint.c context.c fixed_alloc.c object.c
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ctobin	Tue Jul 06 07:52:59 2010 -0400
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+if test ! -f "$1.c"; then
+	echo "C file missing! Maybe you need to do a full compile?"
+	exit 1
+fi
+
+cp runtime/* build/
+cp "$1.c" build/
+cd build
+bin=`echo $1 | sed s/\.rhope//`
+
+if test -f "$bin"; then
+	rm "$bin"
+fi
+
+if test -z $CC; then
+	CC="gcc"
+fi
+
+$CC -o $bin $2 "$1.c" blueprint.c context.c fixed_alloc.c object.c
+
--- a/extendlib.rhope	Thu Jul 01 21:32:08 2010 -0400
+++ b/extendlib.rhope	Tue Jul 06 07:52:59 2010 -0400
@@ -164,6 +164,16 @@
 	}
 }
 
+Min[a,b:min]
+{
+	If[[a] < [b]]
+	{
+		min <- a
+	}{
+		min <- b
+	}
+}
+
 Count Substring[string,substring:out]
 {
 	out <- Max[[[[string]Split[substring]]Length] - [1], 0]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/functional.rhope	Tue Jul 06 07:52:59 2010 -0400
@@ -0,0 +1,30 @@
+
+_Fold[list,index,current,worker:out]
+{
+	Print["_Fold"]
+	{ Print[index]
+	{
+	newval <- [worker]Call[current, [list]Index[index], index]
+	
+	[list]Next[index]
+	{
+		out <- _Fold[list, ~, newval, worker]
+	}{
+		out <- Val[newval]
+	}
+	}}
+}
+
+Fold[worker,start,list:out]
+{
+	Print["Fold"]
+	[list]First
+	{
+		Print["Got first"]
+		out <- _Fold[list, ~, start, worker]
+	}{
+		Print["no first"]
+		out <- start
+	}
+}
+
--- a/kernel.rhope	Thu Jul 01 21:32:08 2010 -0400
+++ b/kernel.rhope	Tue Jul 06 07:52:59 2010 -0400
@@ -1,3 +1,6 @@
+Import string.rhope
+Import list.rhope
+Import functional.rhope
 
 Val[in:out]
 {
@@ -345,9 +348,31 @@
 	}
 }
 
+Length@Array[arr:out]
+{
+	out <- [arr]Length >>
+}
+
 Call@Array[arr(Array),index(Int32):out]
 {
 	out <- [arr]Index[index]
 }
 
+And[left,right:out]
+{
+	,out <- If[left]
+	{
+		out,out <- If[right]
+	}
+}
 
+Or[left,right:out]
+{
+	out <- If[left] {}
+	{
+		out <- right
+	}
+}
+
+
+
--- a/list.rhope	Thu Jul 01 21:32:08 2010 -0400
+++ b/list.rhope	Tue Jul 06 07:52:59 2010 -0400
@@ -9,16 +9,23 @@
 	out, not found <- [[list]Buffer >>]Index[index]
 }
 
-Set@List Leaf[list,index,value:out]
+Set@List Leaf[list,index,value:out,invalid index]
 {
 	If[[index] < [0]]
 	{
+		rev index <- [[[list]Buffer >>]Length >>]+[index]
+		invalid index <- If[[rev index] < [0]] {}
+		{
+			out,invalid index <- [list]Set[rev index, value]
+		}
+			
 	}{
-		If[[index] > [[[list]Buffer >>]Length >>]]
+		len <- [[list]Buffer >>]Length >>
+		If[[index] > [len]]
 		{
 			makeleft <- Yes
 		}{
-			If[[index] > [7]]
+			If[[[index] > [7]] And [[index] >= [len]]]
 			{
 				makeleft <- Yes
 			}{
@@ -39,6 +46,65 @@
 	}
 }
 
+_Right Set@List Leaf[list,index,val:out,didn't set]
+{
+	len <- [[list]Buffer >>]Length >>
+	do it <- If[[index] < [len]] {}
+	{
+		,didn't set <- If[[index]=[len]]
+		{
+			didn't set,do it <- If[[index]>[7]]
+		}
+	}
+	Val[do it]
+	{
+		out <- [list]Set[index,val]
+	}
+}
+
+Length@List Leaf[list:out]
+{
+	out <- [[list]Buffer >>]Length >>
+}
+
+Last@List Leaf[list:out,none]
+{
+	len <- [[list]Buffer >>]Length >>
+	,none <-If[len]
+	{
+		out <- [len]-[1]
+	}
+}
+
+Append@List Leaf[list,val:out]
+{
+	[list]Last
+	{ index <- [~]+[1] }
+	{ index <- 0 }
+	out <- [list]Set[index, val]
+}
+
+First@List Leaf[list:out,none]
+{
+	Print["First@List Leaf"]
+	[[list]Buffer >>]Index[0]
+	{ out <- 0 }
+	{ none <- Yes }
+}
+
+Next@List Leaf[list,index:next,none]
+{
+	Print["Next@List Leaf"]
+	{ Print[index]
+	{
+	pos next <- [index]+[1]
+	,none <- If[[pos next] < [[list]Length]]
+	{
+		next <- Val[pos next]
+	}
+	}}
+}
+
 Blueprint List
 {
 	Buffer
@@ -69,10 +135,165 @@
 	}
 }
 
-Set@List[list,index,val:out,not found]
+Length@List[list:out]
 {
-	
+	out <- [list]Length >>
 }
 
+Set@List[list,index,val:out,invalid index]
+{
+	If[[index] < [0]]
+	{
+		, invalid index <- [list]Last
+		{ rev index <- [[~]+[1]]+[index] }
+		invalid index <- If[[rev index] < [0]] {}
+		{ out,invalid index <- [list]Set[rev index, val] }
+		
+	}{
+		If[[index]<[[list]Offset >>]]
+		{
+			lsize <- [[list]Left >>]Length
+			[[list]Left >>]Set[index, val]
+			{
+				out <- [[list]Left <<[~]
+					]Length <<[ [[list]Length >>]+[[[~]Length]-[lsize]] ]
+			}
+		}{	
+			
+			If[[index]<[[list]Right Offset >>]]
+			{
+				off index <- [index]-[[list]Offset >>]
+				bsize <- [[list]Buffer >>]Length >>
+				If[[off index]>[bsize]]
+				{
+					If[[[list]Right >>]Length]
+					{
+						my end <- [[list]Offset >>]+[[[list]Buffer >>]Length]
+						nroffset <- [[[index]-[my end]]/[2]]+[my end]
+						nright <- out <- [[[[[[Build[List()]
+							]Buffer << [[Array[]]Append[val]]
+							]Left << [List[]]
+							]Right << [[list]Right >>]
+							]Offset << [[index]-[nroffset]]
+							]Right Offset <<[ [[list]Right Offset>>]-[nroffset] ]
+							]Length << [ [[[list]Right >>]Length]+[1] ]
 
-			
+						out <- [[[list]Right <<[nright]
+							]Length <<[ [[list]Length >>]+[1] ]
+							]Right Offset <<[nroffset]
+					}{
+						
+						out <- [[[list]Right <<[ [[list]Right >>]Set[0, val] ]
+							]Right Offset <<[index]
+							]Length <<[ [[list]Length >>]+[1] ]
+					}
+				}{
+					[[list]Buffer >>]Set[off index, val]
+					{
+						out <- [[list]Buffer <<[~]
+							]Length <<[ [[list]Length >>]+[[[~]Length >>]-[bsize]] ]
+					}
+				}
+			}{
+				rsize <- [[list]Right>>]Length
+				adj ind <- [index]-[[list]Right Offset>>]
+				If[[[[list]Left>>]Length] > [rsize]]
+				{
+					[[list]Right >>]Set[adj ind, val]
+					{
+						out <- [[list]Right <<[~]
+							]Length <<[ [[list]Length >>]+[[[~]Length]-[rsize]] ]
+					}
+				}{
+					[[list]Right >>]_Right Set[adj ind, val]
+					{
+						out <- [[list]Right <<[~]
+							]Length <<[ [[list]Length >>]+[[[~]Length]-[rsize]] ]
+					}{
+						out <- [[[[[[Build[List()]
+							]Buffer << [[Array[]]Append[val]]
+							]Left << [list]
+							]Right << [List[]]
+							]Offset << [index]
+							]Right Offset <<[[index]+[8i32]]
+							]Length << [ [[list]Length]+[1] ]
+					}
+				}
+			}
+		}
+	}
+}
+
+_Right Set@List[list,index,val:out,didn't set]
+{
+	If[[[list]Right Offset >>]>[index]]
+	{
+		out <- [list]Set[index, val]
+	}{
+		out,did'nt set <- [list]_Right Set[[index]-[[list]Right Offset >>], val]
+	}
+}
+
+Last@List[list:out,none]
+{
+	[[list]Right >>]Last 
+	{ out <- [~]+[[list]Right Offset >>] }
+	{ out <- [[[[list]Buffer >>]Length >>]-[1]]+[[list]Offset >>] }
+}
+
+Append@List[list,val:out]
+{
+	[list]Last
+	{ index <- [~]+[1] }
+	{ index <- 0 }
+	out <- [list]Set[index, val]
+}
+
+First@List[list:out,none]
+{
+	Print["First@List"]
+	If[[[list]Left >>]Length]
+	{
+		out <- [[list]Left >>]First
+	}{
+		out <- [list]Offset >>
+	}
+}
+
+Next@List[list,index:next,none]
+{
+	Print["Next@List"]
+	{ Print[index]
+	{ Print[[list]Offset >>]
+	{
+	If[[index] < [[[list]Offset >>]-[1]]]
+	{
+		Print["Left"]
+		next <- [[list]Left >>]Next[index] {}
+		{ next <- Offset >>[list] }
+	}{
+		If[[index] < [[list]Right Offset >>]]
+		{
+			Print["Middle"]
+			pos next <- [index]+[1]
+			If[[pos next] < [[[[list]Buffer >>]Length >>]+[[list]Offset >>]]]
+			{
+				next <- Val[pos next]
+			}{
+				Print["Middle done going Right instead"]
+				,none <- [[list]Right >>]First
+				{ next <- [~]+[[list]Right Offset >>] }
+				{
+					Print["First on right returned none"]
+					{ Print[[[list]Right >>]Length] }
+				}
+			}
+		}{
+			Print["right"]
+			,none <- [[list]Right >>]Next[[index]-[[list]Right Offset >>]]
+			{ next <- [~]+[[list]Right Offset >>] }
+		}
+	}
+	}}}
+}
+
--- a/nworker.rhope	Thu Jul 01 21:32:08 2010 -0400
+++ b/nworker.rhope	Tue Jul 06 07:52:59 2010 -0400
@@ -149,14 +149,16 @@
 {
 	Name
 	Convention
-	Inputs
-	Outputs
+	Inputs
+	Min Inputs
+	Outputs
+	Min Outputs
 	Is Method?
 }
 
 Worker Ref[name,convention,inputs,outputs,ismethod?:out]
 {
-	out <- [[[[[Build["Worker Ref"]]Name <<[name]]Convention <<[convention]]Inputs <<[inputs]]Outputs <<[outputs]]Is Method? <<[ismethod?]
+	out <- [[[[[[[Build["Worker Ref"]]Name <<[name]]Convention <<[convention]]Inputs <<[inputs]]Outputs <<[outputs]]Is Method? <<[ismethod?]]Min Inputs <<[inputs]]Min Outputs <<[outputs]
 }
 
 Blueprint Node Ref
@@ -182,9 +184,11 @@
 {
 	Type
 	Data
-	Inputs
+	Inputs
+	Min Inputs
 	Input Types
-	Outputs
+	Outputs
+	Min Outputs
 	Output Types
 	Wires From
 	Wires To
@@ -257,11 +261,13 @@
 
 NWorker Node[type,data,inputs,outputs:out]
 {
-	out <- [[[[[[[[[Build["NWorker Node"]
+	out <- [[[[[[[[[[[Build["NWorker Node"]
 		]Type <<[type]
 		]Data <<[data]
-		]Inputs <<[inputs]
-		]Outputs <<[outputs]
+		]Inputs <<[inputs]
+		]Min Inputs <<[inputs]
+		]Outputs <<[outputs]
+		]Min Outputs <<[outputs]
 		]Wires From <<[List of Lists[outputs]]
 		]Wires To <<[List of Lists[[inputs]+[1]]]
 		]Conditions <<[AndSet[]]
@@ -294,6 +300,12 @@
 {
 	out <- [worker]Nodes <<[[[worker]Nodes >>]Append[NWorker Node[type,data,inputs,outputs]]]
 	node index <- [[worker]Nodes >>]Length
+}
+
+Add Full Node@NWorker[worker,type,data,inputs,min inputs,outputs,min outputs:out,node index]
+{
+	out <- [worker]Nodes <<[[[worker]Nodes >>]Append[ [[NWorker Node[type,data,inputs,outputs]]Min Inputs <<[min inputs]]Min Outputs <<[min outputs] ]]
+	node index <- [[worker]Nodes >>]Length
 }
 
 Propagate Type[nodelist,dest,prog,worker,type:out]
@@ -461,7 +473,7 @@
 
 Add Worker Call@NWorker[worker,tocall:out,node index]
 {
-	out, node index <- [worker]Add Node["call",tocall,[tocall]Inputs >>,[tocall]Outputs >>]
+	out, node index <- [worker]Add Full Node["call",tocall,[tocall]Inputs >>, [tocall]Min Inputs >>,[tocall]Outputs >>, [tocall]Min Outputs >>]
 }
 
 Add Constant@NWorker[worker,constant:out,node index]
@@ -717,27 +729,67 @@
 		]Move[Result[num], out var]
 	*/
 	out <- [func]Move[Result[num], out var]	
+}
+
+Save Maybe Result[func,num,node index:out]
+{
+	out var <- [[["__result_"]Append[node index]]Append["_"]]Append[num]
+	out <- [func]Move[Check Result[num], out var]
+}
+
+Max Used Output[node,cur:out]
+{
+	If[[cur] < [0]]
+	{
+		out <- cur
+	}{
+		[[[node]Wires From >>]Index[cur]]Index[0]
+		{
+			out <- cur
+		}{
+			out <- Max Used Output[node, [cur]-[1]]
+		}
+	}
 }
 
 Compile Call Node[node,program,func,inputs,node index:out]
 {
 	If[[[node]Type >>] = ["getfield"]]
 	{
-		with call <- [func]Get Field Call[[node]Data >>, [inputs]Index[0]]
+		with call <- [func]Get Field Call[[node]Data >>, [inputs]Index[0]]
+		save outs <- [node]Outputs >>
+		out <- Val[after save]
 	}{
 		If[[[node]Type >>] = ["setfield"]]
 		{
-			with call <- [func]Set Field Call[[node]Data >>, [inputs]Index[0], [inputs]Index[1]]
+			with call <- [func]Set Field Call[[node]Data >>, [inputs]Index[0], [inputs]Index[1]]
+			save outs <- [node]Outputs >>
+			out <- Val[after save]
 		}{
 			[program]Method?[[[node]Data >>]Name >>]
 			{
 				with call <- [func]Method Call[[[node]Data >>]Name >>, inputs]
 			}{
 				with call <- [func]Call[[[node]Data >>]Name >>, inputs]
+			}
+			first unused <- [Max Used Output[node, [[node]Outputs >>]-[1]]]+[1]
+			If[[first unused] > [[node]Min Outputs >>]]
+			{
+				save outs <- [node]Min Outputs >>
+				after maybe <- Fold[["Save Maybe Result"]Set Input[2, node index], after save, Range[save outs, first unused]]
+			}{
+				save outs <- Val[first unused]
+				after maybe <- Val[after save]
+			}
+			If[[first unused] < [[node]Outputs >>]]
+			{
+				out <- [after maybe]Discard Outputs[first unused]
+			}{
+				out <- Val[after maybe]
 			}
 		}
 	}
-	out <- Fold[["Save Result"]Set Input[2, node index], with call, Range[0, [node]Outputs >>]]
+	after save <- Fold[["Save Result"]Set Input[2, node index], with call, Range[0, save outs]]
 }
 
 Compile Node@NWorker[worker,program,func,nodes,current:out,out worker]
@@ -870,8 +922,14 @@
 Node Result Vars[vars,node,index:out]
 {
 	[("call","getfield","setfield")]Find[[node]Type >>]
-	{
-		out <- Fold[["Result Var"]Set Input[2, index], vars, Range[0, [node]Outputs >>]]
+	{
+		If[[[node]Type >>]=["call"]]
+		{
+			save outs <- [Max Used Output[node, [[node]Outputs >>]-[1]]]+[1]
+		}{
+			save outs <- [node]Outputs >>
+		}
+		out <- Fold[["Result Var"]Set Input[2, index], vars, Range[0, save outs]]
 	}{
 		out <- vars
 	}
@@ -1300,19 +1358,26 @@
 }
 
 Register Worker@NProgram[prog, name, convention, inputs, outputs: out]
-{
+{
+	[[prog]Worker Refs >>]Index[name]
+	{
+		ref <- [[[[~]Inputs <<[ Max[[~]Inputs >>, inputs] ]
+		]Min Inputs <<[ Min[[~]Min Inputs >>, inputs] ]
+		]Outputs <<[ Max[[~]Outputs >>, outputs] ]
+		]Min Outputs <<[ Min[[~]Min Outputs >>, outputs] ]
+	}{
+		ref <- Worker Ref[name, convention, inputs, outputs, No]
+	}
 	after reg <- [prog]Worker Refs <<[ 
-		[ [prog]Worker Refs >> ]Set[name, 
-			Worker Ref[name, convention, inputs, outputs, No]
-		]
-	]
-		parts <- [name]Split["@"]
-		[parts]Index[1]
-		{
-			out <- [after reg]Register Method@NProgram[[parts]Index[0], convention, inputs, outputs]
-		}{
-			out <- Val[after reg]
-		}
+		[ [prog]Worker Refs >> ]Set[name, ref]
	]
+
+	parts <- [name]Split["@"]
+	[parts]Index[1]
+	{
+		out <- [after reg]Register Method@NProgram[[parts]Index[0], convention, inputs, outputs]
+	}{
+		out <- Val[after reg]
+	}
 }
 
 Register Builtins@NProgram[prog:out]
--- a/parser_old.rhope	Thu Jul 01 21:32:08 2010 -0400
+++ b/parser_old.rhope	Tue Jul 06 07:52:59 2010 -0400
@@ -127,7 +127,7 @@
 {
 	out <- [[[Build["Parse Program"]
 	]Workers <<[Dictionary[]]
-	]Imports <<[[[Dictionary[]]Set["kernel.rhope", Yes]]Set["string.rhope", Yes]]
+	]Imports <<[[Dictionary[]]Set["kernel.rhope", Yes]]
 	]Blueprints <<[Dictionary[]]
 }
 
@@ -1452,7 +1452,7 @@
 			
 		}{
 			Print[["Transforming "]Append[name]]
-			trees, nworker, refs <- Add List to Worker[[worker]Trees >>, [NWorker["rhope"]]Uses[[worker]Uses Stores >>], prog, worker, Dictionary[]]
+			trees, nworker, refs <- Add List to Worker[[worker]Trees >>, [[NWorker["rhope"]]Uses[[worker]Uses Stores >>]]Outputs <<[ [worker]Outputs >> ], prog, worker, Dictionary[]]
 			{
 				,proceed <- If[[name] = ["Main"]]
 				{ Print["Added Trees to worker"]
--- a/runtime/func.h	Thu Jul 01 21:32:08 2010 -0400
+++ b/runtime/func.h	Tue Jul 06 07:52:59 2010 -0400
@@ -105,8 +105,8 @@
 #define Param(num,convtypeid) \
 	if(get_blueprint(cdata->params[num])->type_id != convtypeid)\
 	{\
-		puts("uh oh, need conversion and that's not implemented yet!");\
-		exit(1);\
+		printf("uh oh, need conversion from type %d to type %d for param %d and that's not implemented yet!", get_blueprint(cdata->params[num])->type_id, convtypeid, num);\
+		goto _exception;\
 	}
 
 #define CopiedParam(num,convtypeid) Param(num,convtypeid) cdata->params[num] = copy_object(cdata->params[num]);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/testlist.rhope	Tue Jul 06 07:52:59 2010 -0400
@@ -0,0 +1,183 @@
+
+Make List[list, cur, num:out]
+{
+	If[[cur]=[num]]
+	{ out <- list }
+	{
+		out <- Make List[[list]Append[cur], [cur]+[1], num]
+	}
+}
+
+Make List Step[list, cur index, curval, num, step:out]
+{
+	Print["Make List Step"]
+	{ Print[cur index]
+	{ Print[curval]
+	{
+	If[[curval]=[num]]
+	{ out <- list }
+	{
+		next <- [list]Set[cur index, curval]
+		Print[[next]Length]
+		{
+		out <- Make List Step[next, [cur index]+[step], [curval]+[1], num, step]
+		}
+	}
+	}}}
+}
+
+Sum[list,index,cur:out]
+{
+	[list]Index[index]
+	{
+		out <- Sum[list,[index]+[1],[cur]+[~]]
+	}{
+		out <- cur
+	}
+}
+
+Calc Sum[num:out]
+{
+	If[[[[num]/[2]]*[2]] = [num]]
+	{
+		out <- [[num]-[1]]*[[num]/[2]]
+	}{
+		out <- [[[num]-[2]]*[[[num]-[1]]/[2]]]+[[num]-[1]]
+	}
+}
+
+Test Size[size:out]
+{
+	list <- Make List[List[], 0, size]
+
+	If[[[list]Length] != [size]]
+	{
+		out <- No
+		Print["Length should be:"]
+		{ Print[size]
+		{ Print["but was:"]
+		{ Print[[list]Length] }}}
+	}{
+		tlast <- [size]-[1]
+		If[[[list]Last] != [tlast]]
+		{
+			out <- No
+			Print["Last should be:"]
+			{ Print[tlast]
+			{ Print["but was:"]
+			{ Print[[list]Last] }}}
+		}{
+			sum <- Sum[list,0,0]
+			ssum <- Calc Sum[size]
+			If[[sum]=[ssum]]
+			{
+				out <- Yes
+				Print["Test succeeded for size:"]
+				{ Print[size] }
+			}{
+				out <- No
+				Print["Sum is:"]
+				{ Print[sum]
+				{ Print["but should be:"]
+				{ Print[ssum] }}}
+			}
+		}
+	}
+}
+
+Do Test[size:success,failure]
+{
+	success <- If[Test Size[size]] {}
+	{ failure <- size }
+}
+
+Test Next[size,step:success,failure]
+{
+	list <- Make List Step[List[], 0, 0, size, step]
+	
+	If[[[list]Length] != [size]]
+	{
+		failure <- size
+		Print["Length should be:"]
+		{ Print[size]
+		{ Print["but was:"]
+		{ Print[[list]Length] }}}
+	}{
+		sum <- Fold[+[?], 0, list]
+		ssum <- Calc Sum[size]
+		If[[sum]=[ssum]]
+		{
+			success <- Yes
+			Print["Test succeeded for size:"]
+			{ Print[size] }
+		}{
+			failure <- size
+			Print["Sum is:"]
+			{ Print[sum]
+			{ Print["but should be:"]
+			{ Print[ssum] }}}
+		}
+	}
+}
+
+Test First[index:success,failure]
+{
+	f <- [[List[]]Set[index, 0]]First
+	{
+		success <- If[[~]=[index]] {}
+		{ 
+			Print["First returned:"]
+			{ Print[f]
+			{ Print["Should have returned:"]
+			{ Print[index] }}}
+			failure <- index
+		}
+	}{
+		Print["First set \"none\" output on List with 1 element at index:"]
+		{ Print[index] }
+		failure <- index
+	}
+}
+
+Main[:out]
+{
+	,out <- Do Test[8i32]
+	{ ,out <- Do Test[16i32]
+	{ ,out <- Do Test[24i32]
+	{ ,out <- Do Test[32i32]
+	{ 
+		Print["Basic append/retrieve tests succeeded"]
+		do ftest <- Yes
+	}}}}
+
+	Val[do ftest]
+	{
+		[List[]]First
+		{
+			Print["Calling First on empty list populated first output!"]
+			out <- 33i32
+		}{
+			Test First[0i32]
+			{
+				,out <- Test First[7i32]
+				{ ,out <- Test First[15i32]
+				{ ,out <- Test First[23i32]
+				{ ,out <- Test First[31i32] 
+				{
+					Print["Tests of First method successful"]
+					,out <- Test Next[33i32, 1i32]
+					{ ,out <- Test Next[5i32, 2i32]
+					{ ,out <- Test Next[17i32, 3i32]
+					{
+						Print["Test of Next method successful"]
+						out <- 0i32
+					}}}
+				}
+				}}}
+			}{
+				out <- 1i32
+			}
+		}
+	}
+}
+