changeset 74:a844c623c7df

Add support for Worker type
author Mike Pavone <pavone@retrodev.com>
date Thu, 01 Jul 2010 21:32:08 -0400
parents 6a1a7d5cc2d9
children 0083b2f7b3c7
files backendutils.rhope cbackend.rhope kernel.rhope nworker.rhope parser_old.rhope runtime/builtin.c runtime/builtin.h runtime/func.h runtime/worker.c runtime/worker.h testworkerlitcomplex.rhope testworkerlitsimple.rhope todo.txt
diffstat 13 files changed, 610 insertions(+), 77 deletions(-) [+]
line wrap: on
line diff
--- a/backendutils.rhope	Sat Jun 19 23:13:41 2010 -0400
+++ b/backendutils.rhope	Thu Jul 01 21:32:08 2010 -0400
@@ -96,22 +96,23 @@
 
 Blueprint Constant
 {
-	Value
+	Value
+	Need Addref
 }
 
 Constant[var:out]
 {
-	out <- [Build["Constant"]]Value <<[var]
+	out <- [[Build["Constant"]]Value <<[var]]Need Addref <<[Yes]
 }
 
 Make Op@Constant[const,func:out]
 {
-	out <- [func]Lookup Constant[[const]Value >>]
+	out <- [func]Lookup Constant[[const]Value >>, [const]Need Addref >>]
 }
 
 Strip Addref@Constant[op:out]
 {
-	out <- op
+	out <- [op]Need Addref <<[No]
 }
 
 Blueprint Result
@@ -287,4 +288,20 @@
 		,out <- If[[[type]Name >>] = [[compare]Name >>]]
 		{ out <- [[type]Variant >>] = [[compare]Variant >>] }
 	}
-}
+}
+
+Blueprint Worker Literal
+{
+	Name
+	Args
+}
+
Worker Literal[name:out]
+{
+	out <- [[Build["Worker Literal"]]Name <<[name]]Args <<[()]
+}
+
+Set Input@Worker Literal[worker,argnum,val:out]
+{
+	out <- [worker]Args <<[ [[worker]Args >>]Set[argnum, val] ]
+}
+
--- a/cbackend.rhope	Sat Jun 19 23:13:41 2010 -0400
+++ b/cbackend.rhope	Thu Jul 01 21:32:08 2010 -0400
@@ -242,8 +242,8 @@
 		If[[[ctype]Name >>]=["Blueprint"]]
 		{
 			out <- ""	
-		}{
-			If[[[ctype]Name >>]=["Array"]]
+		}{
+			[("Array","Worker")]Find[[ctype]Name >>]
 			{ oend <- "\nMObject(" }
 			{ oend <- "\nObject(" } 
 			out <- [Fold["_Type Def C Type", "OBegin", [ctype]Fields >>]]Append[ [[oend]Append[Escape Rhope Name[[ctype]Name >>]]]Append[")"] ]
@@ -264,8 +264,8 @@
 }
 
 Type Init@C Type[ctype,id,method reg,field reg:out]
-{
-	If[[[ctype]Name >>]=["Array"]]
+{
+	[("Array","Worker")]Find[[ctype]Name >>]
 	{ size <- "-1" }
 	{ 
 		[("Int64","Int32","Int16","Int8")]Find[[ctype]Name >>]
@@ -315,7 +315,7 @@
 C Type Registry[:out]
 {
 	out <- [[[Build["C Type Registry"]]Lookup << [
-			[[[[[[[[[[[[[[[[[Dictionary[]
+			[[[[[[[[[[[[[[[[[[Dictionary[]
 			]Set["UInt8", "TYPE_UINT8"]
 			]Set["UInt16", "TYPE_UINT16"]
 			]Set["UInt32", "TYPE_UINT32"]
@@ -329,7 +329,8 @@
 			]Set["Float64", "TYPE_FLOAT64"]
 			]Set["Real Number", "TYPE_FLOAT64"]
 			]Set["Blueprint", "TYPE_BLUEPRINT"]
-			]Set["Array", "TYPE_ARRAY"]
+			]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"]]
@@ -564,9 +565,15 @@
 	out <- [func]Add Statement[[dest]Append[" = NULL"]]
 }
 
-Lookup Constant@C Function[func,const:out]
+Lookup Constant@C Function[func,const,doaddref:out]
 {
-	out <- [["add_ref(_const_"]Append[Escape Rhope Name[const]]]Append[")"]
+	var <- ["_const_"]Append[Escape Rhope Name[const]]
+	If[doaddref]
+	{
+		out <- [["add_ref("]Append[var]]Append[")"]
+	}{
+		out <- Val[var]
+	}
 }
 
 Field Result@C Function[func,var,field:out]
@@ -681,16 +688,86 @@
 		]Append[val]
 		]Append[")"]
 	]
+}
+
+_Val Function Arg C[func,val,inputnum,worker:out]
+{
+	out <- [func]Add Raw Line[
+		[[[[[["VCSetParam("
+		]Append[worker]
+		]Append[", "]
+		]Append[inputnum]
+		]Append[", "]
+		]Append[val]
+		]Append[")"]
+	]
 }
 
 Method Call@C Function[func,method,args:out]
 {
 	out <- [func]Call[method,args]
+}
+
+Val Call@C Function[func,to call,args:out]
+{
+	worker <- Make Op[Strip Addref[to call], func]
+	rargs <- Map[args, ["Make Op"]Set Input[1, func]]
+
+	If[[[func]Last NumParams >>] = [-1]]
+	{
+		freed <- Val[func]
+	}{
+		freed <- [func]Add Raw Line["FreeCall"]
+	}
+	prepped <- [[freed]Add Raw Line[ 
+			[[[["VCPrepCall("
+				]Append[worker]
+				]Append[", "]
+				]Append[[rargs]Length]
+				]Append[")"] ]
+		]Last NumParams <<[[rargs]Length]
+	
+	
+	out <- [[[[Fold[["_Val Function Arg C"]Set Input[3, worker], prepped, rargs]
+	]Add Raw Line[
+		[[[[[[[["ValCall("
+		]Append[worker]
+		]Append[", "]
+		]Append[[rargs]Length]
+		]Append[", "]
+		]Append[[func]Resume Index >>]
+		]Append[", "]
+		]Append[Escape Rhope Name[[func]Name >>]]
+		]Append[")"]]
+	]Add Raw Line["DISPATCH"]
+	]Add Raw Line[
+		[[[["ValCallPostlude("
+		]Append[[func]Resume Index >>]
+		]Append[", "]
+		]Append[Escape Rhope Name[[func]Name >>]]
+		]Append[")"]]
+	]Resume Index <<[ [[func]Resume Index >>]+[1] ]
 }
 
 Call@C Function[func,name,args:out]
-{
-	out <- [func]Func Base[Escape Rhope Name[name],args, "Call"]
+{
+	If[[name]=["Call@Worker"]]
+	{
+		//TODO: Handle case when user explicitly calls the fully qualified version, but the type of the first arg isn't Worker
+		out <- [func]Val Call[[args]Index[0], Tail[args,1]]
+	}{
+		If[[name]=["Call"]]
+		{
+			to call <- [args]Index[0]
+			out <- [[[[[func]Add Raw Line[[["if (get_blueprint("]Append[Make Op[Strip Addref[to call], func]]]Append[")->type_id == TYPE_WORKER) {"]]
+			]Val Call[to call, Tail[args,1]]
+			]Add Raw Line["} else {"]
+			]Func Base["Call",args, "Call"]
+			]Add Raw Line["}"]
+		}{
+			out <- [func]Func Base[Escape Rhope Name[name],args, "Call"]
+		}
+	}
 }
 
 Func Base@C Function[func,tocall,args,type:out]
@@ -829,7 +906,7 @@
 
 _Set Outputs C[string,inputname,inputnum,func:out]
 {
-	out <- [string]Append[[[ [ ["\tRet("]Append[inputnum] ]Append[ [[", lv_"]Append[Escape Rhope Name[[func]Name >>]]]Append["->"]]]Append[inputname]]Append[")\n"]]
+	out <- [string]Append[[[ [ ["\tRet("]Append[inputnum] ]Append[ [[", lv_"]Append[Escape Rhope Name[[func]Name >>]]]Append["->"]]]Append[Escape Rhope Name[inputname]]]Append[")\n"]]
 }
 
 Set Outputs@C Function[func:out]
@@ -1070,29 +1147,28 @@
 _Consts C Program[text,value,name:out]
 {
 	out <- [text]Append[ [["object * _const_"]Append[Escape Rhope Name[name]]]Append[";\n"] ]
-}
-
-_Set Consts C Program[text,value,name,type reg:out]
-{
-	//TODO: Support more constant types
-	valtype <- Type Of[value]
+}
+
+Const Construct C[value,type reg:out]
+{
+	valtype <- Type Of[value]
 	[("Int32","Whole Number")]Find[valtype]
-	{
-		out <- [text]Append[[[[["\t_const_"]Append[Escape Rhope Name[name]]]Append[" = make_Int32("]]Append[value]]Append[");\n"]]
-	}{
+	{
+		out <- [["make_Int32("]Append[value]]Append[")"]
+	}{
 		If[[valtype] = ["Type Instance"]]
 		{
 			//TODO: Support parametric types
-			typeid <- [type reg]Type ID[[value]Name >>]
-			out <- [text]Append[[[[["\t_const_"]Append[Escape Rhope Name[name]]]Append[" = make_Blueprint("]]Append[typeid]]Append[");\n"]]
-		}{
+			typeid <- [type reg]Type ID[[value]Name >>]
+			out <- [["make_Blueprint("]Append[typeid]]Append[")"]
+		}{
 			If[[valtype] = ["Yes No"]]
 			{
 				If[value]
 				{
-					out <- [text]Append[[["\t_const_"]Append[Escape Rhope Name[name]]]Append[" = make_Bool(1);\n"]]
+					out <- "make_Bool(1)"
 				}{
-					out <- [text]Append[[["\t_const_"]Append[Escape Rhope Name[name]]]Append[" = make_Bool(0);\n"]]
+					out <- "make_Bool(0)"
 				}
 			}{
 				If[[valtype] = ["Machine Integer"]]
@@ -1101,24 +1177,83 @@
 					{ s <- "I" }
 					{ s <- "UI" }
 					
-					make <- [[[" = make_"]Append[s]]Append["nt"]]Append[[value]Size >>]
-					out <- [text]Append[ [[[[["\t_const_"]Append[Escape Rhope Name[name]]]Append[make]]Append["("]]Append[[value]Value >>]]Append[");\n"] ]
-				}{
-					out <- text
-				}
-			}
-		}
+					out <- [[[[[["make_"
+						]Append[s]
+						]Append["nt"]
+						]Append[[value]Size >>]
+						]Append["("]
+						]Append[[value]Value >>]
+						]Append[")"]
+				}{
+					If[[valtype] = ["String"]]
+					{
+						out <- [["make_String(\""]Append[ [[value]Replace["\\", "\\\\"]]Replace["\n", "\\n"]]]Append["\")"]
+					}{
+						If[[valtype]=["Worker Literal"]]
+						{
+							//TODO: Figure out how to fully support these in nested cases
+							//or workaround the problem higher up in the food chain
+							[[value]Args >>]Last
+							{ size <- [~]+[1] }
+							{ size <- "0" }
+							out <- [[[[[["make_Worker(FUNC_"
+									]Append[Escape Rhope Name[[value]Name >>]]
+									]Append[", "]
+									]Append[size]
+									]Append[", "]
+									]Append[[[value]Args >>]Length]
+									]Append[")"]
+						}{
+							out <- "UnhandledLiteralType"
+						}
+					}
+				}
+			}
+		}
+			
+	}
+}
+
+_Set Worker Params C[text,param,num,type reg,name:out]
+{
+	out <- [text]Append[
+		[[[[[["\t((object **)(((t_Worker *)_const_"
+			]Append[name]
+			]Append[")+1))["]
+			]Append[num]
+			]Append["] = "]
+			]Append[Const Construct C[param, type reg]]
+			]Append[";\n"] ]
+}
+
+_Set Consts C Program[text,value,name,type reg:out]
+{
+	valtype <- Type Of[value]
+	[("String","Worker Literal")]Find[valtype]
+	{
+		out <- text
+	}{
+		Const Construct C[value,type reg]
+		{ out <- [text]Append[ [[[["\t_const_"]Append[Escape Rhope Name[name]]]Append[" = "]]Append[~]]Append[";\n"] ] }
 	}
 }
 
 _Set Late Consts C[text,value,name,type reg:out]
 {
 	valtype <- Type Of[value]
-	If[[valtype] = ["String"]]
-	{
-		out <- [text]Append[ [[[["\t_const_"]Append[Escape Rhope Name[name]]]Append[" = make_String(\""]]Append[ [[value]Replace["\n", "\\n"]]Replace["\\", "\\\\"]]]Append["\");\n"] ]
-	}{
-		out <- text
+	[("String","Worker Literal")]Find[valtype]
+	{
+		Const Construct C[value,type reg]
+		{ init <- [text]Append[ [[[["\t_const_"]Append[Escape Rhope Name[name]]]Append[" = "]]Append[~]]Append[";\n"] ] }
+		
+		If[[valtype]=["Worker Literal"]]
+		{
+			out <- Fold[[["_Set Worker Params C"]Set Input[3, type reg]]Set Input[4, Escape Rhope Name[name]], init, [value]Args >>]
+		}{
+			out <- Val[init]
+		}
+	}{
+		out <- text
 	}
 }
 
@@ -1269,7 +1404,8 @@
 #include \"func.h\"
 #include \"integer.h\"
 #include \"blueprint.h\"
-#include \"array.h\"
+#include \"array.h\"
+#include \"worker.h\"
 #include \"bool.h\"\n\n"
 	out <- [[[[[[[[[[[[[[[headers
 		]Append[[program]Dispatch[all methods]]
@@ -1281,7 +1417,7 @@
 		]Append["\n
 uint16_t rhope(uint32_t func, object ** params, uint16_t numparams, uint16_t callspace)
 {
-	uint16_t resume,idx;
+	uint16_t resume,idx, vcparam_offset, last_vcparam;
 	context * ct;
 	calldata * cdata, *temp_cdata, *my_cdata;\n\nFuncDef(Build)\nFuncDef(BlueprintSP_Of)\n"]
 		]Append[Fold["Local Pointers", "", [program]Functions >>]]
@@ -1336,7 +1472,8 @@
 }
 
 #include \"builtin.c\"
-#include \"array.c\"
+#include \"array.c\"
+#include \"worker.c\"
 
 int main(int argc, char **argv)
 {
--- a/kernel.rhope	Sat Jun 19 23:13:41 2010 -0400
+++ b/kernel.rhope	Thu Jul 01 21:32:08 2010 -0400
@@ -146,6 +146,58 @@
 	_internal_array_allocboxed[size(Int32,Naked):out(Array)]
 	_internal_array_allocnaked[size(Int32,Naked),type(Blueprint):out(Array)]
 	_internal_blueprint_eq[left(Blueprint),right(Blueprint):out(Int32,Naked)]
+	_internal_worker_alloc[size(Int16,Naked):out(Worker)]
+	_internal_worker_setinput[worker(Worker,Boxed,Mutable),num(Int16,Naked),val:worker]
+	_internal_worker_getinput[worker(Worker),num(Int16,Naked):out]
+	_internal_worker_hasinput[worker(Worker),num(Int16,Naked):out(Int32,Naked)]
+}
+
+Blueprint Worker
+{
+	Index(Int32,Naked)
+	Size(Int16,Naked)
+	Count(Int16,Naked)
+}
+
+Get Input@Worker[worker(Worker),bindex(Int32):val,not populated]
+{
+	index <- [bindex]Trunc Int16
+	,not populated <- If[_internal_worker_hasinput[worker,index]]
+	{
+		val <- _internal_worker_getinput[worker,index]
+	}
+}
+
+_Copy Params[source(Worker),dest(Worker),cur(Int16):out(Worker)]
+{
+	If[[cur]<[[source]Size >>]]
+	{
+		[source]Get Input[cur]
+		{
+			next <- _internal_worker_setinput[dest, cur, ~]
+		}{
+			next <- Val[dest]
+		}
+		out <- _Copy Params[source, next, [cur]+[1i16]]
+	}{
+		out <- dest
+	}
+}
+
+Set Input@Worker[worker(Worker),bindex(Int32),val:out(Worker)]
+{
+	index <- [bindex]Trunc Int16
+	If[[index] < [[worker]Size >>]]
+	{
+		set <- _internal_worker_setinput[worker, index, val]
+	}{
+		set <- _internal_worker_setinput[
+			_Copy Params[worker, 
+				[ _internal_worker_alloc[[index]+[1i16]] ]Index <<[[worker]Index >>]
+				, 0i16]
+			, index, val]
+	}
+	out <- [set]Count <<[ [[set]Count >>]+[1i16] ]
 }
 
 =@Blueprint[left,right:out]
@@ -293,4 +345,9 @@
 	}
 }
 
+Call@Array[arr(Array),index(Int32):out]
+{
+	out <- [arr]Index[index]
+}
 
+
--- a/nworker.rhope	Sat Jun 19 23:13:41 2010 -0400
+++ b/nworker.rhope	Thu Jul 01 21:32:08 2010 -0400
@@ -192,22 +192,24 @@
 }
 
 Wire To@NWorker Node[node,from,output,pre input:out]
-{
+{
+	existing cons <- [[node]Wires To >>]Index[input] {}
+	{ existing cons <- () }
 	input <- [pre input]+[1]
 	out <- [node]Wires To <<[
 		[[node]Wires To >>]Set[input,
-			[[[node]Wires To >>]Index[input]
-			]Append[Node Ref[from,output]]
+			[existing cons]Append[Node Ref[from,output]]
 		]
 	]
 }
 
 Wire From@NWorker Node[node,to,input,output:out]
-{
+{
+	existing cons <- [[node]Wires From >>]Index[output] {}
+	{ exist cons <- () }
 	out <- [node]Wires From <<[
 		[[node]Wires From >>]Set[output,
-			[[[node]Wires From >>]Index[output]
-			]Append[Node Ref[to,input]]
+			[existing cons]Append[Node Ref[to,input]]
 		]
 	]
 }
@@ -344,25 +346,31 @@
 Infer Types Node[nodelist,node,index,prog,worker:out]
 {
 	If[[[node]Type >>] = ["const"]]
-	{
+	{
+		const type <- Type Of[[node]Data >>]
 		//Temporary hack
-		If[[Type Of[[node]Data >>]] = ["Whole Number"]]
+		If[[const type] = ["Whole Number"]]
 		{
 			outtype <- Type Instance["Int32"]
 		}{
-			If[[Type Of[[node]Data >>]] = ["Type Instance"]]
+			If[[const type] = ["Type Instance"]]
 			{
 				outtype <- Type Instance["Blueprint"]
 			}{
-				If[[Type Of[[node]Data >>]] = ["Machine Integer"]]
+				If[[const type] = ["Machine Integer"]]
 				{
 					If[[[node]Data >>]Signed? >>]
 					{ base <- "Int" }
 					{ base <- "UInt" }
 					
 					outtype <- Type Instance[[base]Append[ [[node]Data >>]Size >> ]]
-				}{
-					outtype <- Type Instance[Type Of[[node]Data >>]]
+				}{
+					If[[const type] = ["Worker Literal"]]
+					{
+						outtype <- Type Instance["Worker"]
+					}{
+						outtype <- Type Instance[const type]
+					}
 				}
 			}
 		}
@@ -637,8 +645,18 @@
 						{ s <- "i" }
 						{ s <- "u" }
 						datstring <- [[[[node]Data >>]Value >>]Append[s]]Append[[[node]Data >>]Size >>]
-					}{
-						datstring <- [node]Data >>
+					}{
+						If[[Type Of[[node]Data >>]] = ["Worker Literal"]]
+						{
+							If[[[[[node]Data >>]Args >>]Length] > [0]]
+							{
+								datstring <- [[["Arg "]Append[[noderef]Index >>]]Append[" "]]Append[[worker]Name >>]
+							}{
+								datstring <- [[node]Data >>]Name >>
+							}
+						}{
+							datstring <- [node]Data >>
+						}
 					}
 				}
 				out <- Constant[[[Type Of[[node]Data >>]]Append["_"]]Append[datstring]]
@@ -767,8 +785,18 @@
 						{ s <- "i" }
 						{ s <- "u" }
 						datstring <- [[[[node]Data >>]Value >>]Append[s]]Append[[[node]Data >>]Size >>]
-					}{
-						datstring <- [node]Data >>
+					}{
+						If[[Type Of[[node]Data >>]] = ["Worker Literal"]]
+						{
+							If[[[[[node]Data >>]Args >>]Length] > [0]]
+							{
+								datstring <- [[["Arg "]Append[node index]]Append[" "]]Append[[worker]Name >>]
+							}{
+								datstring <- [[node]Data >>]Name >>
+							}
+						}{
+							datstring <- [node]Data >>
+						}
 					}
 				}
 				nfunc <- [func]Register Constant[[[Type Of[[node]Data >>]]Append["_"]]Append[datstring], [node]Data >>]
@@ -1076,8 +1104,13 @@
 }
 
 _Compile Blueprint Methods[type,junk,name:out]
-{
-	out <- [type]Add Method[name]
+{
+	If[[[name]=["Call"]] And [[[type]Name >>] = ["Worker"]]]
+	{
+		out <- type
+	}{
+		out <- [type]Add Method[name]
+	}
 }
 
 Make Init[func,field:out]
@@ -1284,13 +1317,14 @@
 
 Register Builtins@NProgram[prog:out]
 {
-	registered <- [[[[[prog]Register Worker["Print", "rhope", 1, 1]
+	registered <- [[[[[[prog]Register Worker["Print", "rhope", 1, 1]
 	]Register Worker["If@Boolean", "rhope", 1, 2]
 	]Register Worker["Build", "rhope", 1, 1]
-	]Register Worker["Blueprint Of", "rhope", 1, 1]
+	]Register Worker["Blueprint Of", "rhope", 1, 1]
+	]Register Worker["Call@Worker", "rhope", 1, 2] //We're using 2 because we need to assume that the outputs are conditional
 	]Register Number Methods
 	
-	out <- [[[[registered]Bind Worker["If@Boolean",
+	out <- [[[[[registered]Bind Worker["If@Boolean",
 		[[[[[NWorker["rhope"]
 		]Inputs <<[("condition")]
 		]Input Types <<[ [()]Append[Type Instance["Boolean"]] ]
@@ -1317,7 +1351,14 @@
 		]Input Types <<[ [()]Append[Type Instance["Any Type"]]]
 		]Outputs <<[("type")]
 		]Output Types <<[ [()]Append[Type Instance["Blueprint"]]]
-		]Builtin? <<[Yes]]
+		]Builtin? <<[Yes]]
+	]Bind Worker["Call@Worker",
+		[[[[[NWorker["rhope"]
+		]Inputs <<[("worker")]
+		]Input Types <<[ [()]Append[Type Instance["Worker"]] ]
+		]Outputs <<[("ret1","ret2")]
+		]Output Types <<[ [[()]Append[Type Instance["Any Type"]]]Append[Type Instance["Any Type"]] ]
+		]Builtin? << [Yes]]
 }
 
 Find Worker@NProgram[prog, name:out,notfound]
--- a/parser_old.rhope	Sat Jun 19 23:13:41 2010 -0400
+++ b/parser_old.rhope	Thu Jul 01 21:32:08 2010 -0400
@@ -245,6 +245,72 @@
 	}
 }
 
+Check Question Mark[params, index:has mark,no mark]
+{
+	param,no mark <-[params]Index[index]
+	{
+		If[[Type Of[param]]=["Named Pipe Node"]]
+		{
+			has mark <-If[[[param]Name >>] = ["?"]] {}
+			{
+				has mark,no mark <- Check Question Mark[params, [index]+[1]]
+			}
+		}{
+			has mark,no mark <- Check Question Mark[params, [index]+[1]]
+		}
+	}
+}
+
+Collect Literal Inputs[literal, params, index, complex inputs:literal out,complex out]
+{
+	param <- [params]Index[index]
+	{
+		If[[Type Of[param]]=["Literal Node"]]
+		{
+			next literal <- [literal]Set Input[index, [param]Value >>]
+			next complex <- Val[complex inputs]
+		}{
+			,doset <- If[[Type Of[param]]=["Named Pipe Node"]]
+			{
+				,doset <- If[[[param]Name >>] = ["?"]]
+				{
+					//Question mark indicates unpopulated input
+					next complex <- Val[complex inputs]
+					next literal <- Val[literal]
+				}
+			}
+
+			Val[doset]
+			{
+				next complex <- [complex inputs]Set[index, param]
+				next literal <- Val[literal]
+			}
+		}
+		literal out, complex out <- Collect Literal Inputs[next literal, params, [index]+[1], next complex]
+	}{
+		literal out <- literal
+		complex out <- complex inputs
+	}
+}
+
+Do Set Input[literal,param,index:out]
+{
+	out <- New@Worker Node["Set Input", [[[()]Append[literal]]Append[New@Literal Node[index]]]Append[param]]
+}
+
+Check Worker Literals@Worker Node[node,program:out]
+{
+	new params <- Map[[node]Params >>, ["Check Worker Literals"]Set Input[1, program]]
+	Check Question Mark[new params, 0]
+	{
+		base literal, complex inputs <- Collect Literal Inputs[Worker Literal[[node]Name >>], new params, 0, ()]
+		new node <- Fold["Do Set Input", New@Literal Node[base literal], complex inputs]
+	}{
+		new node <- [node]Params <<[new params]
+	}
+	out <- [new node]Blocks <<[ Map[[node]Blocks >>, ["Map"]Set Input[1, ["Check Worker Literals"]Set Input[1, program]]] ]
+}
+
 Add Multi Wire[worker,ref,junk,end index,input num:out]
 {
 	out <- [worker]Add Wire[[ref]Index >>, [ref]Output Number >>, end index, input num]
@@ -252,11 +318,23 @@
 
 Add Param Wire[worker,param,input num,end index,blocks,parse worker,assignments:out]
 {
-	param worker, start index, output num <- [param]Add Wires[worker, blocks, parse worker, assignments] {}
+	Print[["Add Param Wire: "]Append[input num]]
+	{
+	param worker, start index, output num <- [param]Add Wires[worker, blocks, parse worker, assignments] { Print["got param worker"] }
 	{
+		Print[["got normal output for param: "]Append[input num]]
+		{
+			Print[["Start index: "]Append[start index]]
+			Print[["Output num: "]Append[output num]]
+			
 		out <- [param worker]Add Wire[start index, output num, end index, input num]
+		{ Print["Added param wire"] }
+		}
 	}{}{
+		Print["got multi output"]
 		out <- Fold[[["Add Multi Wire"]Set Input[3, end index]]Set Input[4, input num], param worker, ~]
+		{ Print["Added multi wire"] }
+	}
 	}
 }
 
@@ -326,16 +404,27 @@
 
 Add Wires@Worker Node[node,worker,blocks,parse worker,assignments:worker,index,num,unused]
 {
+	Print[["Add Wires@Worker Node: "]Append[[node]Name >>]]
+	{
 	worker,index,num <- Add Wires Worker or Field[node, worker, blocks, parse worker, assignments]
+	}
 }
 
 Add Wires Worker or Field[node,worker,blocks,parse worker,assignments:worker,index,num,unused]
 {
 	Fold[[["Assignments Add Wires"]Set Input[3, parse worker]]Set Input[4, [node]Index >>], worker, [node]Assignments >>]
-	{ 
+	{
+		Print["Assignments Add Wires done"] 
 		Fold[[[[["Add Block Wire"]Set Input[3, [node]Index >>]]Set Input[4, blocks]]Set Input[5, parse worker]]Set Input[6, assignments], ~, [node]Blocks >>]
 		{ 
-			params worker <- Fold[[[[["Add Param Wire"]Set Input[3, [node]Index >>]]Set Input[4, blocks]]Set Input[5, parse worker]]Set Input[6, assignments], ~, [node]Params >>] }}
+			Print["Add Block Wire done"]
+			params worker <- Fold[[[[["Add Param Wire"]Set Input[3, [node]Index >>]]Set Input[4, blocks]]Set Input[5, parse worker]]Set Input[6, assignments], ~, [node]Params >>] 
+			{ Print["Add Param Wire done"] 
+				index <- [node]Index >>
+				num <- 0
+			}
+		}
+	}
 	If[Has Block Params[[node]Params >>]]
 	{
 		worker <- Val[params worker]
@@ -347,8 +436,6 @@
 			worker <- Val[params worker]
 		}
 	}
-	index <- [node]Index >>
-	num <- 0
 }
 
 Blueprint Field Node
@@ -396,6 +483,13 @@
 	worker,index,num <- Add Wires Worker or Field[node, worker, blocks, parse worker, assignments]
 }
 
+Check Worker Literals@Field Node[node,program:out]
+{
+	new params <- Map[[node]Params >>, ["Check Worker Literals"]Set Input[1, program]]
+	out <- [[node]Blocks <<[ Map[[node]Blocks >>, ["Map"]Set Input[1, ["Check Worker Literals"]Set Input[1, program]]] ]
+		]Params <<[new params]
+}
+
 Blueprint Named Pipe Node
 {
 	Name
@@ -484,6 +578,11 @@
 	worker <- Fold[[[[["Add Block Wire"]Set Input[3, my index]]Set Input[4, blocks]]Set Input[5, parse worker]]Set Input[6, assignments], wires worker, [node]Blocks >>]
 }
 
+Check Worker Literals@Named Pipe Node[node,program:out]
+{
+	out <- [node]Blocks <<[ Map[[node]Blocks >>, ["Map"]Set Input[1, ["Check Worker Literals"]Set Input[1, program]]] ]
+}
+
 Blueprint Global Node
 {
 	Store
@@ -518,6 +617,11 @@
 	out <- Yes
 }
 
+Check Worker Literals@Global Node[node,program:out]
+{
+	out <- [node]Blocks <<[ Map[[node]Blocks >>, ["Map"]Set Input[1, ["Check Worker Literals"]Set Input[1, program]]] ]
+}
+
 Blueprint Literal Node
 {
 	Value
@@ -547,7 +651,16 @@
 
 Add Wires@Literal Node[node,worker,blocks,parse worker,assignments:worker,index,num,unused]
 {
+	Print[["Add Wires@Literal Node, Literal Type: "]Append[Type Of[[node]Value >>]]]
 	worker,index,num <- Add Wires Literal or Global[node, worker, blocks, parse worker, assignments]
+	{ Print["Got worker"] }
+	{ Print["got index"] }
+	{ Print["got num"] }
+}
+
+Check Worker Literals@Literal Node[node,program:out]
+{
+	out <- [node]Blocks <<[ Map[[node]Blocks >>, ["Map"]Set Input[1, ["Check Worker Literals"]Set Input[1, program]]] ]
 }
 
 Add Wires Literal or Global[node,worker,blocks,parse worker,junk:worker,index,num,unused]
@@ -1294,6 +1407,16 @@
 	}
 }
 
+Check Worker Literals@Parse Worker[worker,program:out]
+{
+	If[[Type Of[[worker]Trees >>]] = ["List"]]
+	{
+		out <- [worker]Trees <<[ Map[[worker]Trees >>, ["Check Worker Literals"]Set Input[1, program]] ]
+	}{
+		out <- worker
+	}
+}
+
 Add Workers[workers,name,program:out]
 {
 	prog,worker <- [program]New Worker[name]
@@ -1330,7 +1453,20 @@
 		}{
 			Print[["Transforming "]Append[name]]
 			trees, nworker, refs <- Add List to Worker[[worker]Trees >>, [NWorker["rhope"]]Uses[[worker]Uses Stores >>], prog, worker, Dictionary[]]
-			final nworker <- Fold[[["Add Wires Helper"]Set Input[3, worker]]Set Input[4, refs], nworker, trees]
+			{
+				,proceed <- If[[name] = ["Main"]]
+				{ Print["Added Trees to worker"]
+				{ proceed <- Pretty Print[trees, ""] }}
+				Val[proceed]
+				{
+				final nworker <- Fold[[["Add Wires Helper"]Set Input[3, worker]]Set Input[4, refs], nworker, trees]
+				{
+					If[[name] = ["Main"]]
+					{ Print["Added wires to worker"] }
+				}
+				}
+			}
+			
 		}
 		out <- [prog]Bind Worker[name, final nworker]
 }
@@ -1556,8 +1692,11 @@
 		Null[text, params, New@Parse Program[], 0]
 		{
 			Print["Parsing imports"]
-			tree <- Process Imports[~, params]
-			{ Print["Compiling"] }
+			Process Imports[~, params]
+			{
+				tree <- [~]Workers << [ Map[[~]Workers >>, ["Check Worker Literals"]Set Input[1, ~]] ]
+				{ Print["Compiling"] }
+			}
 			compiled <- [Tree to Program Native[tree]]Compile Program[C Program[]]
 			{ Print["Compiled program to backend"] }
 			outfile <- <String@File[ [fname]Append[".c"] ]
--- a/runtime/builtin.c	Sat Jun 19 23:13:41 2010 -0400
+++ b/runtime/builtin.c	Thu Jul 01 21:32:08 2010 -0400
@@ -115,5 +115,13 @@
 	t_Boolean * b = (t_Boolean *)new_object(TYPE_BOOLEAN);
 	b->Val = val != 0;
 	return (object*)b;
+}
+
+object * make_Worker(int32_t index, int16_t initialsize, int16_t initialcount)
+{
+	t_Worker * worker = (t_Worker *)_internal_worker_alloc(initialsize);
+	worker->payload.Index = index;
+	worker->payload.Count = initialcount;
+	return (object *)worker;
 }
 
--- a/runtime/builtin.h	Sat Jun 19 23:13:41 2010 -0400
+++ b/runtime/builtin.h	Thu Jul 01 21:32:08 2010 -0400
@@ -19,7 +19,8 @@
 	TYPE_FLOAT32,
 	TYPE_FLOAT64,
 	TYPE_BLUEPRINT,
-	TYPE_ARRAY,
+	TYPE_ARRAY,
+	TYPE_WORKER,
 	TYPE_METHODMISSINGEXCEPTION,
 	TYPE_FIELDMISSINGEXCEPTION,
 	TYPE_WRONGTYPEEXCEPTION,
--- a/runtime/func.h	Sat Jun 19 23:13:41 2010 -0400
+++ b/runtime/func.h	Thu Jul 01 21:32:08 2010 -0400
@@ -119,7 +119,39 @@
 
 #define PrepCall(callspace) cdata = alloc_cdata(ct, cdata, callspace);
 
-#define SetParam(num,value) cdata->params[num] = value;
+#define SetParam(num,value) cdata->params[num] = value;
+
+#define VCPrepCall(func,numparams) \
+	cdata = alloc_cdata(ct, cdata, numparams + ((t_Worker *)func)->payload.Count);\
+	vcparam_offset = 0;
+
+#define VCSetParam(func,num,value) \
+	while((num+vcparam_offset) < ((t_Worker *)func)->payload.Size && ((object **)(((t_Worker *)func)+1))[num+vcparam_offset])\
+	{\
+		cdata->params[num+vcparam_offset] = add_ref(((object **)(((t_Worker *)func)+1))[num+vcparam_offset]);\
+		++vcparam_offset;\
+	}\
+	cdata->params[num+vcparam_offset] = value;\
+	last_vcparam = num+vcparam_offset;
+
+#define ValCall(tocall,numparams,resumeto,myname)\
+	last_vcparam++;\
+	while(last_vcparam < ((t_Worker *)tocall)->payload.Size)\
+	{\
+		if (((object **)(((t_Worker *)tocall)+1))[last_vcparam]) \
+			cdata->params[last_vcparam] = add_ref(((object **)(((t_Worker *)tocall)+1))[last_vcparam]);\
+		++last_vcparam;\
+	}\
+	cdata->func = RES_  ## resumeto ## _ ## myname;\
+	cdata->num_params = numparams + ((t_Worker *)tocall)->payload.Count;\
+	cdata->vars = lv_ ## myname;\
+	func = ((t_Worker *)tocall)->payload.Index;
+
+#define ValCallPostlude(resumeto,myname)\
+r ## resumeto ## _ ## myname:\
+	my_cdata = cdata->lastframe;\
+	lv_ ## myname = cdata->vars;
+
 
 #define Call(tocall, numparams, resumeto, myname)\
 			cdata->func = RES_  ## resumeto ## _ ## myname;\
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/runtime/worker.c	Thu Jul 01 21:32:08 2010 -0400
@@ -0,0 +1,37 @@
+
+object * _internal_worker_alloc(int16_t size)
+{
+	t_Worker * worker = (t_Worker *)new_multisize(TYPE_WORKER, sizeof(nt_Worker)+sizeof(object *)*size);
+	worker->payload.Size = size;
+	return (object *)worker;
+}
+
+void _internal_worker_setinput(object * worker, int16_t num, object * val)
+{
+	//Client code is responsible for checking if we've allocated enough space
+	object **params = (object **)(((t_Worker *)worker)+1);
+	params[num] = val;
+}
+
+object * _internal_worker_getinput(object * worker, int16_t num)
+{
+	//Client code MUST check if input is populated before calling this function
+	object **params = (object **)(((t_Worker *)worker)+1);
+	object * ret = add_ref(params[num]);
+	release_ref(worker);
+	return ret;
+}
+
+int32_t _internal_worker_hasinput(object * worker, int16_t num)
+{
+	object **params = (object **)(((t_Worker *)worker)+1);
+	if(params[num])
+	{
+		release_ref(worker);
+		return 1;
+	} else {
+		release_ref(worker);
+		return 0;
+	}
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/runtime/worker.h	Thu Jul 01 21:32:08 2010 -0400
@@ -0,0 +1,14 @@
+#ifndef _WORKER_H_
+#define _WORKER_H_
+
+#include "object.h"
+#include "func.h"
+#include "builtin.h"	
+
+object * _internal_worker_alloc(int16_t size);
+void _internal_worker_setinput(object * worker, int16_t num, object * val);
+object * _internal_worker_getinput(object * worker, int16_t num);
+int32_t _internal_worker_hasinput(object * worker, int16_t num);
+
+
+#endif //_WORKER_H_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/testworkerlitcomplex.rhope	Thu Jul 01 21:32:08 2010 -0400
@@ -0,0 +1,6 @@
+
+Main[]
+{
+	foo <- [1]+[2]
+	Print[[[foo]+[?]]Call[1]]
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/testworkerlitsimple.rhope	Thu Jul 01 21:32:08 2010 -0400
@@ -0,0 +1,6 @@
+
+Main[]
+{
+	Print[[[1]+[?]]Call[2]]
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo.txt	Thu Jul 01 21:32:08 2010 -0400
@@ -0,0 +1,38 @@
+
+"Soon":
+	Tail call optimization
+	Fix Array and Worker memory leaks
+
+Needed for compiler to be self-hosting:
+	Finish implementation of String
+	Finish implementation of List
+	Add support for List literals in compiler
+	Implement Dictionary
+	Implement File	
+	Add support for implicit conversions
+	Tweak extendlib to work with language changes introduced with compiler
+	Tweak compiler to work with language changes introduced with compiler
+
+Needed for web site to work in compiler:
+	Pretty much everything needed for the compiler to be self-hosting
+	Implement Net Connection (or whatever the TCP connection type gets called)
+	Add support for multi-threaded execution in runtime (not strictly needed)
+	Add support for global stores to compiler/runtime
+	Tweak site to work with language changes introduced with compiler
+
+Other Stuff:
+	Add varargs and/or optional arguments
+	Add sugar to be able to call a variable without having to do "[var]Call[...]"
+	Implement "Call" on container types so you can do things like "somelist[2]"
+		and also uses containers as if they were workers (pass them to Fold,
+		Map, etc.). Call implementation should use varargs to allow some kind
+		of slice notation or fetching multiple values depending on type.
+	Support list literals that contain non-literals e.g. (1,foo,[bar]+[4])
+	Add Javascript backend
+	Add x86_64 backend (or maybe LLVM backend?)
+	Support construction of new workers at runtime
+	Get a REPL working on the new stack
+	Flesh out ideas for having limited I/O within transactions
+	Add module system
+	Exception support
+