changeset 102:2f6f0867fd68

Added files I forgot to add in a previous commit
author Mike Pavone <pavone@retrodev.com>
date Tue, 10 Aug 2010 20:55:52 -0400
parents f4fc0a98088a
children 7428aa5d6ade
files array.rhope nworker_c.rhope
diffstat 2 files changed, 1837 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/array.rhope	Tue Aug 10 20:55:52 2010 -0400
@@ -0,0 +1,248 @@
+
+Blueprint Array
+{
+	Eltype(Blueprint)
+	Length(Int32,Naked)
+	Storage(Int32,Naked)
+}
+
+Blueprint Boxed Array
+{
+	Length(Int32,Naked)
+	Storage(Int32,Naked)
+}
+
+Blueprint Empty Array
+{
+}
+
+Foreign C:runtime
+{
+	_internal_array_copyout[array(Array), index(Int32,Naked), dest(Any Type,Boxed,Mutable):dest]
+	_internal_array_copyin[array(Array,Boxed,Mutable), index(Int32,Naked), val:array]
+	_internal_array_getboxed[array(Boxed Array), index(Int32,Naked):out]
+	_internal_array_setboxed[array(Boxed Array,Boxed,Mutable), index(Int32,Naked), val:array]
+	_internal_array_allocboxed[size(Int32,Naked):out(Boxed Array)]
+	_internal_array_allocboxedcopy[source(Boxed Array),size(Int32,Naked):out(Boxed Array)]
+	_internal_array_allocnaked[size(Int32,Naked),type(Blueprint):out(Array)]
+	_internal_array_allocnakedcopy[source(Array),size(Int32,Naked):out(Array)]
+}
+
+Array[:out(Empty Array)]
+{
+	out <- Build[Empty Array()]
+}
+
+First@Empty Array[array:out,empty]
+{
+	empty <- array
+}
+
+First@Array[array:out(Int32),empty]
+{
+	,empty <- If[[array]Length >>]
+	{ out <- 0 }
+}
+
+First@Boxed Array[array:out(Int32),empty]
+{
+	,empty <- If[[array]Length >>]
+	{ out <- 0 }
+}
+
+Next@Empty Array[array:out,empty]
+{
+	empty <- array
+}
+
+Next@Array[array,current:out(Int32),empty]
+{
+	next <- [current]+[1]
+	,empty <- If[[next] < [[array]Length >>]]
+	{
+		out <- Val[next]
+	}
+}
+
+Next@Boxed Array[array,current:out(Int32),empty]
+{
+	next <- [current]+[1]
+	,empty <- If[[next] < [[array]Length >>]]
+	{
+		out <- Val[next]
+	}
+}
+
+Last@Empty Array[array:out,empty]
+{
+	empty <- array
+}
+
+Last@Array[array:out(Int32),empty]
+{
+	,empty <- If[[array]Length >>]
+	{ out <-  [[array]Length >>] - [1] }
+}
+
+Last@Boxed Array[array:out(Int32),empty]
+{
+	,empty <- If[[array]Length >>]
+	{ out <-  [[array]Length >>] - [1] }
+}
+
+Append@Empty Array[array,newval:out(Array)]
+{
+	out <- [array]Set[0, newval]
+}
+
+Append@Array[array,newval:out]
+{
+	out <- [array]Set[[array]Length >>, newval]
+}
+
+Append@Boxed Array[array,newval:out(Boxed Array)]
+{
+	out <- [array]Set[[array]Length >>, newval]
+}
+
+Index@Empty Array[array:out,notfound]
+{
+	notfound <- array
+}
+
+Index@Array[array,index(Int32):out,notfound]
+{
+	,notfound <- If[[index] >= [0]]
+	{
+		,notfound <- If[[index] < [[array]Length >>]]
+		{
+			out <- _internal_array_copyout[array, index, Build[[array]Eltype >>]]
+		}
+	}	
+}
+
+Index@Boxed Array[array,index(Int32):out,notfound]
+{
+	,notfound <- If[[index] >= [0]]
+	{
+		,notfound <- If[[index] < [[array]Length >>]]
+		{
+			out <- _internal_array_getboxed[array, index]
+		}
+	}	
+}
+
+_Copy to Boxed[source,dest,current:out]
+{
+	ndest <- _internal_array_setboxed[dest, current, [source]Index[current]]
+	
+	[source]Next[current]
+	{
+		out <- _Copy to Boxed[source, ndest, ~]
+	}{
+		out <- Val[ndest]
+	}
+}
+
+_Copy Naked[source,dest,current:out]
+{
+	ndest <- _internal_array_copyin[dest, current, [source]Index[current]]
+	
+	[source]Next[current]
+	{
+		out <- _Copy Naked[source, ndest, ~]
+	}{
+		out <- Val[ndest]
+	}
+}
+
+Set@Array[array,index(Int32),val:out,invalid]
+{
+	invalid <- If[[index]<[0]] {}
+	{
+		len <- [array]Length >>
+		If[[index]>[len]]
+		{
+			out <- [[array]Set[[index]-[1],val]]Set[index, val]
+		}{
+			If[[Blueprint Of[val]]=[[array]Eltype >>]]
+			{
+				If[[index]<[[array]Storage >>]]
+				{
+					out <- [_internal_array_copyin[array, index, val]]Length <<[Max[len, [index]+[1]]]
+				}{
+					//Does this make sense given the copies we may have to make?
+					If[[index] < [4]]
+					{
+						new storage <- [index]+[index]
+					}{
+						new storage <- [index]+[[index]RShift[1]]
+					}
+					out <- [_internal_array_copyin[_internal_array_allocnakedcopy[array, new storage], index, val]]Length <<[[index]+[1]]
+				}
+			}{
+				out <-[[_Copy to Boxed[array, _internal_array_allocboxed[[array]Storage >>], [array]First]]Length <<[[array]Length >>]]Set[index, val]
+			}
+		}
+	}
+}
+
+Set@Boxed Array[array,index(Int32),val:out(Boxed Array),invalid]
+{
+	invalid <- If[[index]<[0]] {}
+	{
+		len <- [array]Length >>
+		If[[index]>[len]]
+		{
+			out <- [[array]Set[[index]-[1],val]]Set[index, val]
+		}{
+			If[[index]<[[array]Storage >>]]
+			{
+				out <- [_internal_array_setboxed[array, index, val]]Length <<[Max[len, [index]+[1]]]
+			}{
+				//Does this make sense given the copies we may have to make?
+				If[[index] < [4]]
+				{
+					new storage <- [index]+[index]
+				}{
+					new storage <- [index]+[[index]RShift[1]]
+				}
+				out <- [_internal_array_setboxed[_internal_array_allocboxedcopy[array, new storage], index, val]]Length <<[[index]+[1]]
+			}
+		}
+	}
+}
+
+Set@Empty Array[array,index(Int32),val:out(Array),invalid]
+{
+	invalid <- If[[index]<[0]] {}
+	{
+		out <- [_internal_array_allocnaked[1, Blueprint Of[val]]]Set[index, val]
+	}
+}
+
+Length@Empty Array[arr:out]
+{
+	out <- 0
+}
+
+Length@Array[arr:out]
+{
+	out <- [arr]Length >>
+}
+
+Length@Boxed Array[arr:out]
+{
+	out <- [arr]Length >>
+}
+
+Call@Array[arr,index(Int32):out,not found]
+{
+	out,not found <- [arr]Index[index]
+}
+
+Call@Boxed Array[arr,index(Int32):out,not found]
+{
+	out,not found <- [arr]Index[index]
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nworker_c.rhope	Tue Aug 10 20:55:52 2010 -0400
@@ -0,0 +1,1589 @@
+Import cbackend_c.rhope
+Import number_c.rhope
+Import boolean.rhope
+
+Blueprint Condition Set
+{
+	Variables
+	Subsets
+	Condition Type
+}
+
+AndSet[:out]
+{
+	out <- [[[Build[Condition Set()]]Variables <<[Dictionary[]]]Subsets <<[Dictionary[]]]Condition Type <<["And"]
+}
+
+OrSet[:out]
+{
+	out <- [[[Build[Condition Set()]]Variables <<[Dictionary[]]]Subsets <<[Dictionary[]]]Condition Type <<["Or"]
+}
+
+To String@Condition Set[set:out]
+{
+	out <- [[[[[set]Condition Type >>
+	]Append["Set:\n\tVariables:\n\t\t"]
+	]Append[ Join[Keys[[set]Variables >>], "\n\t\t"] ]
+	]Append["\n\tSubsets:\n\t\t"]
+	]Append[ Join[Keys[[set]Subsets >>], "\n\t\t"] ]
+}
+
+Add Condition@Condition Set[set,cond:out]
+{
+	If[[Blueprint Of[cond]] = [Condition Set()]]
+	{
+		out <- [set]Subsets <<[ [[set]Subsets>>]Set[[cond]To String, cond] ]
+	}{
+		out <- [set]Variables <<[ [[set]Variables >>]Set[cond, Yes] ]
+	}
+}
+
+=@Condition Set[set1,set2:out]
+{
+	,out <- If[[[set1]Condition Type >>] = [[set2]Condition Type >>]]
+	{
+		,out <- If[[[set1]Variables >>] = [[set2]Variables >>]]
+		{
+			out,out <- If[[[set1]Subsets >>] = [[set2]Subsets >>]]
+		}
+	}
+}
+
+_For Backend Var[current,junk,variable,type:out]
+{
+	If[[type]=["And"]]
+	{ cond <- Val[AndCond[?]] }
+	{ cond <- Val[OrCond[?]] }
+	out <- [cond]Call[current, variable]
+}
+
+_For Backend Subset[current,subset,type:out]
+{
+	[subset]For Backend
+	{
+		If[[type]=["And"]]
+		{ cond <- Val[AndCond[?]] }
+		{ cond <- Val[OrCond[?]] }
+		out <- out <- [cond]Call[current, ~]
+	}{
+		out <- current
+	}
+}
+
+Empty?@Condition Set[set:not empty,empty]
+{
+	Print["Empty?@Condition Set"]
+	[[set]Variables >>]First
+	{
+		not empty <- Yes
+	}{
+		,empty <- [[set]Subsets >>]First Non-empty Set
+		{
+			not empty <- Yes
+		}
+	}
+}
+
+_First Non-empty Set[setlist,index:out,none]
+{
+	current <- [setlist]Index[index]
+	[[current]Variables >>]First
+	{
+		out <- index
+	}{
+		,trynext <- [[current]Subsets >>]First Non-empty Set
+		{
+			out <- index
+		}
+	}
+	Val[trynext]
+	{
+		,none <- [setlist]Next[index]
+		{
+			out,none <- _First Non-empty Set[setlist, ~]
+		}
+	}
+}
+
+First Non-empty Set[setlist:index,none]
+{
+	,none <- [setlist]First
+	{
+		index,none <- _First Non-empty Set[setlist,~]
+	}
+}
+
+For Backend@Condition Set[set:out,none]
+{
+	firstvar <- [[set]Variables >>]First
+	{
+		[[set]Variables >>]Next[~]
+		{
+			vars <- _Fold[[set]Variables >>, ~, firstvar, _For Backend Var[?, ?, ?, [set]Condition Type >>]]
+		}{
+			vars <- Val[firstvar]
+		}
+		out <- Fold[_For Backend Subset[?, ?, [set]Condition Type >>], vars, [set]Subsets >>]
+	}{
+		[[set]Subsets >>]First Non-empty Set
+		{
+			firstsub <- [[[set]Subsets >>]Index[~]]For Backend
+			[[set]Subsets >>]Next[~]
+			{
+				out <- _Fold[[set]Subsets >>, ~, firstsub, _For Backend Subset[?, ?, [set]Condition Type >>]]
+			}{
+				out <- Val[firstsub]
+			}
+		}{
+			none <- Yes
+		}
+	}
+}
+
+List of Lists[num:out]
+{
+	out <- Fold[Append[?, ()],(), Range[0,num]]
+}
+
+Blueprint Worker Ref
+{
+	Name
+	Convention
+	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?]]Min Inputs <<[inputs]]Min Outputs <<[outputs]
+}
+
+String@Worker Ref[ref:out]
+{
+	out <- [[[[[[[["Worker Ref["
+		]Append[[ref]Name >>]
+		]Append[", "]
+		]Append[[ref]Convention >>]
+		]Append[", "]
+		]Append[String[[ref]Inputs >>]]
+		]Append[", "]
+		]Append[String[[ref]Outputs >>]]
+		]Append["]"]
+}
+
+Blueprint Node Ref
+{
+	Index
+	IO Num
+}
+
+Node Ref[index,ionum:out]
+{
+	out <- [[Build[Node Ref()]]Index <<[index]]IO Num <<[ionum]
+}
+
+=@Node Ref[left,right:out]
+{
+	,out <- If[[[left]Index >>] = [[right]Index >>]]
+	{
+		out <- [[left]IO Num>>] = [[right]IO Num >>]
+	}
+}
+
+Blueprint NWorker Node
+{
+	Type
+	Data
+	Inputs
+	Min Inputs
+	Input Types
+	Outputs
+	Min Outputs
+	Output Types
+	Wires From
+	Wires To
+	Conditions
+}
+
+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,
+			[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,
+			[existing cons]Append[Node Ref[to,input]]
+		]
+	]
+}
+
+_Has Input Types@NWorker Node[node,input num:does,does not]
+{
+	does <- If[[input num] > [[node]Inputs >>]] {}
+	{
+		,does not <- [[node]Input Types >>]Index[input num]
+		{
+			count <- [~]Index[1]
+			,does not <- If[[count] = [[[[node]Wires To >>]Index[input num]]Length]]
+			{
+				does,does not <- [node]_Has Input Types[[input num]+[1]]
+			}
+		}
+	}
+}
+
+Has Input Types?@NWorker Node[node:does,does not]
+{
+	If[[[node]Inputs >>] > [0]]
+	{
+		does,does not <- _Has Input Types[node,0]
+	}{
+		does <- Yes
+	}
+}
+
+_Dependency[dlist,ref:out]
+{
+	[dlist]Find[=[ref, ?]]
+	{
+		out <- dlist
+	}{
+		out <- [dlist]Append[ref]
+	}
+}
+
+Dependencies@NWorker Node[node:out]
+{
+	out <- Fold[Fold[_Dependency[?], ?], (), [node]Wires To >>]
+}
+
+
+NWorker Node[type,data,inputs,outputs:out]
+{
+	out <- [[[[[[[[[[[Build[NWorker Node()]
+		]Type <<[type]
+		]Data <<[data]
+		]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[]]
+		]Input Types <<[()]
+		]Output Types <<[()]
+}
+
+Blueprint NWorker
+{
+	Convention
+	Nodes
+	Inputs
+	Input Types
+	Outputs
+	Output Types
+	Uses
+	NodeResults
+	Free Temps
+	Name
+	Builtin?
+	Library
+}
+
+NWorker[convention:out]
+{
+	out <- [[[[[[[[[Build[NWorker()]]Convention <<[convention]]Nodes <<[()]]Inputs <<[()]]Outputs <<[()]]Input Types <<[()]]Output Types <<[()]]Name <<["Anonymous"]]Builtin? <<[No]]Library << [""]
+}
+
+String@NWorker[worker:out]
+{
+	out <- ["NWorker"]Append[[worker]Name >>]
+}
+
+Add Node@NWorker[worker,type,data,inputs,outputs:out,node index]
+{
+	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]
+		]Wires To <<[List of Lists[[min inputs]+[1]]]
+	]]
+	node index <- [[worker]Nodes >>]Length
+}
+
+Propagate Type[nodelist,dest,prog,worker,type:out]
+{
+	node <- [nodelist]Index[[dest]Index >>]
+	
+	[[node]Input Types >>]Index[[dest]IO Num >>]
+	{
+		existing type <- [~]Index[0]
+		new count <- [[~]Index[1]]+[1]
+		If[[[existing type]Name >>] = [[type]Name >>]]
+		{
+			If[[[existing type]Variant >>] = [[type]Variant >>]]
+			{
+				If[[[existing type]Params >>] = [[type]Params >>]]
+				{
+					new type <- Val[existing type]
+				}{
+					new variant <- [existing type]Variant >>
+					new params <- ()
+				}
+			}{
+				new variant <- "Boxed"
+				If[[[existing type]Params >>] = [[type]Params >>]]
+				{
+					new params <- [existing type]Params >>
+				}{
+					new params <- ()
+				}
+			}
+			new type <- [[existing type]Set Variant[new variant]]Params <<[new params]
+		}{
+			new type <- Type Instance["Any Type"]
+		}
+	}{
+		new type <- Val[type]
+		new count <- 1
+	}
+	new node <- [node]Input Types <<[  		
+		[ [node]Input Types >> ]Set[ [dest]IO Num >>, [[()]Append[new type]]Append[new count] ]
+	]
+	out <- Infer Types Node[[nodelist]Set[[dest]Index >>, new node], new node, [dest]Index >>, prog, worker]
+}
+
+Propagate Types[nodelist,dests,output num,prog,worker,source node:out]
+{
+	out <- Fold[Propagate Type[?, ?, prog, worker, [[source node]Output Types >>]Index[output num]], nodelist, dests]
+}
+
+Infer Types Node[nodelist,node,index,prog,worker:out]
+{
+	If[[[node]Type >>] = ["const"]]
+	{
+		const type <- Blueprint Of[[node]Data >>]
+		[(Int8(),UInt8(),Int16(),UInt16(),Int32(),UInt32(),Int64(),UInt64(),	
+			Type Instance(),Worker Literal(),List(),List Leaf(),String(),String Slice(),String Cat())]Find[=[const type, ?]]
+		{
+			outtype <- [("Int8","UInt8","Int16","UInt16","Int32","UInt32","Int64","UInt64",
+			"Blueprint","Worker","List","List","String","String","String")]Index[~]
+		}{
+			outtype <- "Any Type"
+		}
+		nextnode <- [node]Output Types <<[ [()]Append[Type Instance[outtype]] ]
+		
+	}{
+		If[[[node]Type >>] = ["input"]]
+		{
+			nextnode <- [node]Output Types <<[ [()]Append[ [[worker]Input Types >>]Index[[node]Data >>] ] ]
+		}{
+			If[[[node]Type >>] = ["output"]]
+			{
+				out <- nodelist
+
+			}{
+				[node]Has Input Types?
+				{
+					If[[[node]Type >>] = ["setfield"]]
+					{
+						nextnode <- [node]Output Types <<[ [()]Append[ [[[node]Input Types >>]Index[0]]Index[0] ] ]
+					}{
+						If[[[node]Type >>] = ["getfield"]]
+						{
+							type <- [[[node]Input Types >>]Index[0]]Index[0]
+							If[[[type]Name >>] = ["Any Type"]]
+							{
+								outtype <- Val[type]
+							}{
+								outtype <- [prog]Find Field[[node]Data >>, type] {}
+								{
+									//TODO: Return errors rather than printing them
+									Print[
+										[[[[["Type "
+										]Append[[type]Name >>]
+										]Append[" does not have a field named "]
+										]Append[[node]Data >>]
+										]Append[" in worker "]
+										]Append[worker name]]
+								}
+							}
+							nextnode <- [node]Output Types <<[ [()]Append[outtype] ]
+						}{
+							worker name <- [[node]Data >>]Name >>
+							[prog]Is Method?[worker name]
+							{
+								first arg type <- [[[node]Input Types >>]Index[0]]Index[0]
+								If[[[first arg type]Name >>] = ["Any Type"]]
+								{
+									outtypes <- Fold[Append[?, Type Instance["Any Type"]], (), Range[0, [node]Inputs >>]]
+								}{
+									worker def <- [prog]Find Method[worker name, first arg type] {}
+									{
+										//TODO: Return errors instead of printing them
+										Print[
+											[[[[["Type "
+											]Append[[first arg type]Name >>]
+											]Append[" does not support method "]
+											]Append[worker name]
+											]Append[" in worker "]
+											]Append[ [worker]Name >> ]]
+									}
+								}
+							}{
+								worker def <- [prog]Find Worker Def[worker name]
+							}
+							outtypes <- [worker def]Output Types >>
+							nextnode <- [node]Output Types <<[ outtypes ]
+						}
+					}
+				}{
+					out <- nodelist
+				}
+			}
+		}
+	}
+	
+	Val[nextnode]
+	{
+		nextlist <- [nodelist]Set[index, nextnode]
+		out <- Fold[Propagate Types[?, ?, ?, prog, worker, nextnode], nodelist, [nextnode]Wires From >>]
+	}
+}
+
+Infer Types@NWorker[worker,prog:out]
+{
+	out <- [worker]Nodes <<[Fold[Infer Types Node[?, ?, ?, prog, worker], [worker]Nodes >>, [worker]Nodes >>]]
+}
+
+Add Worker Call@NWorker[worker,tocall:out,node index]
+{
+	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]
+{
+	out, node index <- [worker]Add Node["const",constant,0,1]
+}
+
+Add Input@NWorker[worker,name,number:out,node index]
+{
+	out,node index <- [worker]Add Typed Input[name,number,Type Instance["Any Type"]]
+}
+
+Add Typed Input@NWorker[worker,name,number,type:out,node index]
+{
+	,node index <- [worker]Add Node["input",number,0,1]
+	{ 
+		out <- [[~]Inputs <<[[[~]Inputs >>]Set[number,name]]
+		]Input Types <<[[[~]Input Types >>]Set[number,type]]
+	}
+}
+
+Add Output@NWorker[worker,name,number:out,node index]
+{
+	out,node index <- [worker]Add Typed Output[name,number,Type Instance["Any Type"]]
+}
+
+Add Typed Output@NWorker[worker,name,number,type:out,node index]
+{
+	,node index <- [worker]Add Node["output",number,1,0]
+	{ 
+		out <- [[~]Outputs <<[[[~]Outputs >>]Set[number,name]]
+		]Output Types <<[[[~]Output Types >>]Set[number,type]]
+	}
+}
+
+Add Object Get@NWorker[worker,fieldname:out,node index]
+{
+	out, node index <- [worker]Add Node["getfield",fieldname,1,1]
+}
+
+Add Object Set@NWorker[worker,fieldname:out,node index]
+{
+	out, node index <- [worker]Add Node["setfield",fieldname,2,1]
+}
+
+Add Global Get@NWorker[worker,store,var:out,node index]
+{
+	out, node index <- [worker]Add Node["getglobal",[[()]Append[store]]Append[var],0,1]
+}
+
+Add Global Set@NWorker[worker,store,var:out,node index]
+{
+	out, node index <- [worker]Add Node["setglobal",[[()]Append[store]]Append[var],1,1]
+}
+
+Add Wire@NWorker[worker,from,output,to,input:out]
+{
+	fromw <- [[[worker]Nodes >>]Index[from]]Wire From[to,input,output]
+	tow <- [[[worker]Nodes >>]Index[to]]Wire To[from,output,input]
+	nodes <- [[[worker]Nodes >>]Set[from, fromw]]Set[to, tow]
+	out <- [worker]Nodes <<[nodes]
+}
+
+Uses@NWorker[worker,uses:out]
+{
+	out <- [worker]Uses <<[uses]
+}
+
+_No Dependencies[list,node,index:out]
+{
+	[[node]Wires To>>]Index[1]
+	{
+		out <- Val[list]
+	}{
+		[[[node]Wires To>>]Index[0]]First
+		{
+			out <- Val[list]
+		}{
+			out <- [list]Append[index]
+		}
+	}
+}
+
+No Dependencies@NWorker[worker:out]
+{
+	out <- Fold[_No Dependencies[?], (), [worker]Nodes >>]
+}
+
+_Collect Dests[candidates,wire:out]
+{
+	out <- [candidates]Set[[wire]Index >>, Yes]
+}
+
+Collect Dests@NWorker[worker,candidates,node index:out]
+{
+	out <- Fold[Fold[_Collect Dests[?], ?], candidates, [[[worker]Nodes >>]Index[node index]]Wires From >>]
+}
+
+Check Dependency@NWorker[worker,nodes,wires,wire index:met?]
+{
+	ref <- [wires]Index[wire index]
+	[nodes]Find[=[[ref]Index >>, ?]]
+	{
+		[wires]Next[wire index]
+		{
+			met? <- [worker]Check Dependency[nodes,wires,~]
+		}{
+			met? <- Yes
+		}
+	}{
+		met? <- No
+	}
+}
+_Check Dependencies@NWorker[worker,nodes,inputs,input index:met?]
+{
+	wires <- [inputs]Index[input index]
+	[wires]First
+	{
+		current met? <- [worker]Check Dependency[nodes, wires, ~]
+	}{
+		current met? <- Yes
+	}
+	If[current met?]
+	{
+		[inputs]Next[input index]
+		{
+			met? <- [worker]_Check Dependencies[nodes,inputs,~]
+		}{
+			met? <- Yes
+		}
+	}{
+		met? <- No
+	}
+}
+
+Check Dependencies@NWorker[worker,nodes,candidate:met?]
+{
+	inputs <- [[[worker]Nodes >>]Index[candidate]]Wires To >>
+	[inputs]First
+	{
+		met? <- [worker]_Check Dependencies[nodes, inputs, ~]
+	}{
+		met? <- Yes
+	}
+}
+
+Dependants@NWorker[worker,direct nodes,nodes:out]
+{
+	candidates <- Keys[Fold[Collect Dests[worker, ?], (), direct nodes]]
+	out <- Filter[candidates, Check Dependencies[worker, nodes, ?]]
+}
+
+_Dependency Groups@NWorker[worker,last,all,grouped:out]
+{
+	current <- [worker]Dependants[last,all]
+	[current]First
+	{
+		out <- [worker]_Dependency Groups[current, [all]Concatenate[current], [grouped]Append[current]]
+	}{
+		out <- grouped
+	}
+}
+Dependency Groups@NWorker[worker:out]
+{
+	no deps <- [worker]No Dependencies
+	out <- [worker]_Dependency Groups[no deps, no deps, [()]Append[no deps]]
+}
+
+Const Name[val,node index,worker name:out]
+{
+	valtype <- Blueprint Of[val]
+	If[[valtype] = [Type Instance()]]
+	{
+		//TODO: Support parametric types
+		datstring <- [val]Name >>
+		typename <- "Blueprint"
+	}{
+		[(Int8(),UInt8(),Int16(),UInt16(),Int32(),UInt32(),Int64(),UInt64())]Find[=[valtype,?]]
+		{
+			size <- [("8","16","32","64")]Index[[~]/[2]]
+			typename <- [("Int8","UInt8","Int16","UInt16","Int32","UInt32","Int64","UInt64")]Index[~]
+			If[[~]Mod[2]]
+			{ s <- "UI" }
+			{ s <- "I" }
+			datstring <- [[String[val]]Append[s]]Append[size]
+		}{
+			If[[valtype] = [Worker Literal()]]
+			{
+				typename <- "Worker"
+				If[[[[val]Args >>]Length] > [0]]
+				{
+					datstring <- [[["Arg "]Append[String[node index]]]Append[" "]]Append[worker name]
+				}{
+					datstring <- [val]Name >>
+				}
+			}{
+				[(List(),List Leaf())]Find[=[valtype,?]]
+				{
+					typename <- "List"
+					If[[[val]Length] > [0]]
+					{
+						datstring <- [[["Arg "]Append[String[node index]]]Append[" "]]Append[worker name]
+					}{
+						datstring <- "Empty"
+					}
+				}{
+					[(String(),String Cat(),String Slice())]Find[=[valtype, ?]]
+					{
+						typename <- "String"
+						datstring <- val
+					}{
+						typename <- "Unknown"
+						datstring <- String[val]
+					}
+					
+				}
+			}
+		}
+	}
+	out <- [[typename]Append["_"]]Append[datstring]
+}
+
+Format Input@NWorker[worker,noderef:out]
+{
+	node <- [[worker]Nodes >>]Index[[noderef]Index >>]
+	
+	[("call","getfield","setfield")]Find[=[[node]Type >>, ?]]
+	{
+		maybe addref <- Result Var Name[[noderef]IO Num >>, [noderef]Index >>]
+	}{
+		conditions <- [node]Conditions >>
+		
+		If[[[node]Type >>] = ["input"]]
+		{
+			input name <- [[worker]Inputs >>]Index[ [node]Data >> ]
+			[conditions]For Backend
+			{
+				out <- AddRef[Result Var Name[[noderef]IO Num >>, [noderef]Index >>]]
+			}{
+				out <- AddRef[input name] 
+			}
+		}{
+			If[[[node]Type >>] = ["const"]]
+			{
+				[conditions]For Backend
+				{
+					out <- AddRef[Result Var Name[[noderef]IO Num >>, [noderef]Index >>]]
+				}{
+					out <- Constant[Const Name[[node]Data >>, [noderef]Index >>, [worker]Name >>]]
+				}
+			}
+		}
+	}
+
+	Val[maybe addref]
+	{
+		If[[Length[[[node]Wires From >>]Index[[noderef]IO Num >>]]] > [1]]
+		{
+			out <- AddRef[maybe addref]
+		}{
+			out <- Val[maybe addref]
+		}
+	}
+}
+
+Collect Input@NWorker[worker,nodeinput:out]
+{
+	inputchoices <- Map[nodeinput, Format Input[worker, ?]]
+
+	[inputchoices]First
+	{
+		first <- [inputchoices]Index[~]
+		[inputchoices]Next[~]
+		{
+			out <- _Fold[inputchoices, ~, first, OrValue[?]]
+		}{
+			out <- Val[first]
+		}
+	}{
+		out <- "Missing"
+	}
+}
+
+Collect Inputs@NWorker[worker,node:out]
+{
+	out <- Map[Tail[[node]Wires To>>, 1], Collect Input[worker, ?]]
+}
+
+Collect Input Condition@NWorker[worker,set,noderef:out]
+{
+	node <- [[worker]Nodes >>]Index[ [noderef]Index >> ]
+	If[[[node]Outputs >>] > [1]]
+	{
+		out <- [set]Add Condition[ Result Var Name[[noderef]IO Num >>, [noderef]Index >>] ]
+	}{
+		out <- [set]Add Condition[[node]Conditions >>]
+	}
+}
+
+Collect Condition@NWorker[worker,set,nodeinput:out]
+{
+	out <- [set]Add Condition[Fold[Collect Input Condition[worker, ?], OrSet[], nodeinput]]
+}
+
+Collect Conditions@NWorker[worker,node:out]
+{
+	out <- Fold[Collect Condition[worker, ?], AndSet[], [node]Wires To>>]
+}
+
+Save Result[func,num,node index:out]
+{
+	out <- [func]Move[Result[num], Result Var Name[num, node index]]	
+}
+
+Save Maybe Result[func,num,node index:out]
+{
+	out <- [func]Move[Check Result[num], Result Var Name[num, node index]]
+}
+
+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]]
+		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]]
+			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[?, ?, 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]
+			}
+		}
+	}
+	after save <- Fold[Save Result[?, ?, node index], with call, Range[0, save outs]]
+}
+
+Compile Node@NWorker[worker,program,func,nodes,current:out,out worker]
+{
+	node index <- [nodes]Index[current]
+	node <- [[worker]Nodes >>]Index[node index]
+	conditions <- [node]Conditions >>
+	[("call","getfield","setfield")]Find[=[[node]Type >>, ?]]
+	{
+		inputs <- [worker]Collect Inputs[node]
+		[conditions]For Backend
+		{
+			stream <- [func]Instruction Stream
+			nfunc <- [func]Do If[~, nstream]
+		}{
+			stream <- Val[func]
+			nfunc <- Val[nstream]
+		}
+		nstream <- Compile Call Node[node, program, stream, inputs, node index]
+	}{
+		If[[[node]Type >>] = ["output"]]
+		{
+			inputs <- [worker]Collect Inputs[node]
+			[conditions]For Backend
+			{
+				stream <- [func]Instruction Stream
+				nfunc <- [func]Do If[~, nstream]
+			}{
+				stream <- Val[func]
+				nfunc <- Val[nstream]
+			}
+			nstream <- [stream]Move[[inputs]Index[0], [[worker]Outputs >>]Index[ [node]Data >> ] ]
+		}{
+			If[[[node]Type >>] = ["const"]]
+			{
+				constname <- Const Name[[node]Data >>, node index, [worker]Name >>]
+				withconst <- [func]Register Constant[constname, [node]Data >>]
+				[conditions]For Backend
+				{
+					stream <- [[withconst]Instruction Stream
+						]Move[Constant[constname], Result Var Name[0, node index]]
+					nfunc <- [withconst]Do If[~, stream]
+				}{
+					nfunc <- Val[withconst]
+				}
+			}{
+				[conditions]For Backend
+				{
+					input name <- [[worker]Inputs >>]Index[ [node]Data >> ]
+					stream <- [[func]Instruction Stream
+						]Move[input name, Result Var Name[0, node index]]
+					nfunc <- [func]Do If[~, stream]
+				}{
+					nfunc <- Val[func]
+				}
+			}
+			
+		}
+	}
+	[nodes]Next[current]
+	{
+		out,out worker <- [worker]Compile Node[program,nfunc,nodes,~]
+	}{
+		out <- Val[nfunc]
+		out worker <- Val[worker]
+	}
+}
+
+Save Node Conditions@NWorker[worker,node index:out]
+{
+	node <- [[worker]Nodes >>]Index[node index]
+	conditions <- [worker]Collect Conditions[node]
+	out <- [worker]Nodes <<[ [[worker]Nodes >>]Set[node index, [node]Conditions <<[conditions]] ]
+	
+}
+
+Save Group Conditions@NWorker[worker, groups,current:out]
+{
+	nodes <- [groups]Index[current]
+	nworker <- Fold[Save Node Conditions[?], worker, nodes]
+
+	[groups]Next[current]
+	{
+		out <- [nworker]Save Group Conditions[groups,~]
+	}{
+		out <- Val[nworker]
+	}
+}
+
+Compile Group@NWorker[worker,program,func,groups,current:out,out worker]
+{
+	nodes <- [groups]Index[current]
+	[nodes]First
+	{
+		nfunc,nworker <- [worker]Compile Node[program,func,nodes,~]
+	}{
+		nfunc <- Val[func]
+		nworker <- Val[worker]
+	}
+	[groups]Next[current]
+	{
+		out,out worker <- [nworker]Compile Group[program,nfunc,groups,~]
+	}{
+		out <- Val[nfunc]
+		out worker <- Val[nworker]
+	}
+}
+
+Release Var@NWorker[worker,func,name:out]
+{
+	//__result_index_ionum
+	parts <- [name]Split["_"]
+	index <- Int32[ [parts]Index[3] ]
+	io num <- Int32[ [parts]Index[4] ]
+	node <- [[worker]Nodes >>]Index[index]
+	dests <- [[node]Wires From >>]Index[io num] {}
+
+	If[[[dests]Length] = [1]]
+	{
+		dest index <- [[dests]Index[0]]Index >>
+		dest node <- [[worker]Nodes >>]Index[dest index]
+		
+		[[dest node]Conditions >>]For Backend
+		{
+			out <- [func]Do If[AndCond[NotCond[~], name],  [[func]Instruction Stream]Release[name]]
+		}{
+			out <- func
+		}
+	}{
+		do if <- If[[[node]Outputs >>] > [1]] {}
+		{
+			do if <- [[node]Conditions >>]Empty? {}
+			{
+				out <- [func]Release[name]
+			}
+		}
+	
+		Val[do if]
+		{
+			stream <- [[func]Instruction Stream]Release[name]
+			out <- [func]Do If[name, stream]
+		}
+	}
+}
+
+Result Var Name[io num, index:out]
+{
+	out <- [[["__result_"]Append[String[index]]]Append["_"]]Append[String[io num]]
+}
+
+Result Var[vars,io num,index:out]
+{
+	out <- [vars]Append[Result Var Name[io num, index]]
+}
+
+Node Result Vars[vars,node,index:out]
+{
+	[("call","getfield","setfield")]Find[=[[node]Type >>, ?]]
+	{
+		If[[[node]Type >>]=["call"]]
+		{
+			save outs <- [Max Used Output[node, [[node]Outputs >>]-[1]]]+[1]
+		}{
+			save outs <- [node]Outputs >>
+		}
+		out <- Fold[Result Var[?, ?, index], vars, Range[0, save outs]]
+	}{
+		out <- vars
+	}
+}
+
+Result Vars@NWorker[worker:out]
+{
+	out <- Fold[Node Result Vars[?], (), [worker]Nodes >>]
+}
+
+_No Release[vars,node,index,worker:out]
+{
+	[("const","input")]Find[=[[node]Type >>, ?]]
+	{
+		[[node]Conditions >>]For Backend
+		{
+			out <- Result Var[vars, 0, index]
+		}{	
+			out <- vars
+		}
+	}{
+		out <- vars
+	}
+}
+
+No Release Results@NWorker[worker:out]
+{
+	out <- Fold[_No Release[?, ?, ?, worker], (), [worker]Nodes >>]
+}
+
+Make Basic Type[type:out]
+{
+	out <- [Type Instance[[type]Name >>]]Params <<[ [type]Params >> ]
+}
+
+FInputs[ifunc, input type, index, inputs:out]
+{	
+	func <- [ifunc]Set Input Type[Make Basic Type[input type], index]
+	name <- [inputs]Index[index]
+	If[[[input type]Variant >>] = ["Naked"]]
+	{
+		
+		naked <- [" naked"]Append[name]
+		
+		out <- [[[func]Allocate Var[naked, input type]
+		]Unbox[name, naked]
+		]Release[name]
+	}{
+		If[[input type]Mutable? >>]
+		{
+			name <- [inputs]Index[index]
+			copied <- [func]Copy[name, name]
+			
+		}{
+			copied <- Val[func]
+		}
+		If[[[input type]Variant >>] = ["Raw Pointer"]]
+		{
+			raw <- [" raw"]Append[name]
+			If[[[input type]Name >>]=["Array"]]
+			{
+				
+				out <- [[copied]Allocate Var[raw, input type]
+				]Array Raw Pointer[name, raw]
+			}{
+				out <- [[copied]Allocate Var[raw, input type]
+				]Get Raw Pointer[name, raw]
+			}
+		}{
+			out <- Val[copied]
+		}
+	}
+}
+
+FParams[input:out]
+{
+	iname <- [input]Index[0]
+	type <- [input]Index[1]
+	If[[[type]Variant >>] = ["Naked"]]
+	{ out <- [" naked"]Append[iname] }
+	{ 
+		If[[[type]Variant >>] = ["Raw Pointer"]]
+		{ out <- [" raw"]Append[iname] }
+		{ out <- Val[iname] }
+	}
+}
+_Return Param[outputs, inputs, input types, index:out,none]
+{
+	output <- [outputs]Index[index]
+	[inputs]Find[=[output, ?]]
+	{
+		If[[[input types]Index[~]]Mutable? >>]	
+		{
+			,none <- [outputs]Next[index]
+			{
+				out,none <- _Return Param[outputs, inputs, input types, ~]
+			}
+		} { 
+			out <- index
+		}
+	}{
+		out <- index
+	}
+}
+
+Return Param[outputs, inputs, input types:out,none]
+{
+	,none <- [outputs]First
+	{ out,none <- _Return Param[outputs, inputs, input types, ~] }
+	
+}
+
+Save Foreign Result[func, output, index, output types, inputs, input types:out]
+{
+	type <- [output types]Index[index]
+	If[[[type]Variant >>] = ["Naked"]]
+	{
+		out <- [func]Box[[" naked"]Append[output], output, type]
+	}{
+		[inputs]Find[=[output, ?]]
+		{
+			If[[[input types]Index[~]]Mutable? >>]
+			{ 
+				out <- [func]Move[output, Output[output]]
+			}{
+				out <- func
+			}
+		}{	
+			out <- func
+		}
+	}
+}
+
+Compile Foreign Stub[worker,program,name:out]
+{
+	ifunc <- [[program]Create Function[name, [worker]Inputs >>, [worker]Outputs >>, "rhope"]
+	]Output Types <<[Map[[worker]Output Types >>, Make Basic Type[?]]]
+	
+	rp num <- Return Param[[worker]Outputs >>, [worker]Inputs >>, [worker]Input Types >>]
+	{
+		rbase <- [[worker]Outputs >>]Index[rp num]
+		If[[[[[worker]Output Types >>]Index[rp num]]Variant >>] = ["Naked"]]
+		{
+			rparam <- [" naked"]Append[rbase]
+			rfunc <- [ifunc]Allocate Var[rparam, [[worker]Output Types >>]Index[rp num]]
+		}{
+			rparam <- Val[rbase]
+			rfunc <- Val[ifunc]
+		}
+	}{
+		rparam <- ""
+		rfunc <- Val[ifunc]
+	}
+	
+	Fold[FInputs[?, ?, ?, [worker]Inputs >>], rfunc, [worker]Input Types >>]
+	{ [~]Call Foreign[name, [worker]Convention >>, Map[Zip[[worker]Inputs >>, [worker]Input Types >>], FParams[?]], rparam]
+	{ Fold[Save Foreign Result[?, ?, ?, [worker]Output Types >>, [worker]Inputs >>, [worker]Input Types >>], ~, [worker]Outputs >>]
+	{ out <- [program]Store Function[~] }}}
+}		
+
+Compile Worker@NWorker[worker,program,name:out]
+{
+	If[[worker]Builtin? >>]
+	{
+		out <- program
+	}{
+		If[[[worker]Library >>] = [""]]
+		{	
+			ifunc <- Fold[Set Output Type[?], Fold[Set Input Type[?], [program]Create Function[name,[worker]Inputs >>, [worker]Outputs >>, [worker]Convention >>], [worker]Input Types >>], [worker]Output Types >>]
+			
+			
+			
+			groups <- [worker]Dependency Groups
+			[groups]First
+			{
+				with conds <- [worker]Save Group Conditions[groups, ~]
+				final func <- [with conds]Compile Group[program,func,groups, ~]
+			}{
+				final func <- Val[func]
+			}
+			res vars <- [worker]Result Vars
+			init vars <- Concatenate[res vars, [with conds]No Release Results]
+			
+			func <- Fold[Set Null[?], Fold[Set Null[?], Fold[Allocate Var[?, ?, "Any Type"], ifunc, init vars], init vars], [worker]Outputs >>]
+			out <- [program]Store Function[Fold[Release[?], Fold[Release Var[with conds, ?], final func, res vars], [worker]Inputs >>]]
+		}{
+			out <- Compile Foreign Stub[worker,[program]Link[[worker]Convention >>, [worker]Library >> ],name]
+		}
+	}
+}
+
+Blueprint NBlueprint
+{
+	Fields
+	Methods
+}
+
+String@NBlueprint[nbp:out]
+{
+	out <- [[[["NBlueprint: Fields("
+		]Append[Join[Map[[nbp]Fields >>, [?]Index[0]], ", "]]
+		]Append["), Methods("]
+		]Append[Join[Keys[[nbp]Methods >>], ", "]]
+		]Append[")"]
+}
+
+NBlueprint[:out]
+{
+	out <- [[Build[NBlueprint()]]Fields <<[()]]Methods <<[Dictionary[]]
+}
+
+Add Field@NBlueprint[bp,name,type:out]
+{
+	out <- [bp]Fields <<[ [[bp]Fields >>]Append[ [[()]Append[name]]Append[type] ] ]
+}
+
+Add Method@NBlueprint[bp,name:out]
+{
+	out <- [bp]Methods <<[ [[bp]Methods >>]Set[name, Yes] ]
+}
+
+Understands Method@NBlueprint[bp,name:out]
+{
+	out <- [[bp]Methods >>]Index[name] {}
+	{ out <- No }
+}
+
+Get Field Type@NBlueprint[bp,name:out,notfound]
+{
+	,notfound <- [[bp]Fields >>]Index[name]
+	{ out <- [~]Index[1] }
+}
+
+_Compile Blueprint Fields[type,field:out]
+{
+	name <- [field]Index[0]
+	ftype <- [field]Index[1]
+	out <- [type]Add Field[name,ftype]
+}
+
+_Compile Blueprint Methods[type,junk,name:out]
+{
+	If[[[name]=["Call"]] And [[[type]Name >>] = ["Worker"]]]
+	{
+		out <- type
+	}{
+		out <- [type]Add Method[name]
+	}
+}
+
+Make Init[func,field:out]
+{
+	name <- [field]Index[0]
+	variant <- [[field]Index[1]]Variant >>
+	If[[variant] = ["Boxed"]]
+	{
+		out <- [func]Set Field Null["obj", name]
+	}{
+		out <- func
+	}
+}
+
+Make Copy[func,field:out]
+{
+	name <- [field]Index[0]
+	variant <- [[field]Index[1]]Variant >>
+	If[[variant] = ["Boxed"]]
+	{
+		got <- [func]Read Field["obj", name] {}
+		{ 
+			stream <- [[got]Instruction Stream
+				]AddRef No Dest[~] 
+			out <- [got]Do If[~, stream]
+		}
+	}{
+		out <- func
+	}
+}
+
+Make Cleanup[func,field:out]
+{
+	name <- [field]Index[0]
+	variant <- [[field]Index[1]]Variant >>
+	If[[variant] = ["Boxed"]]
+	{
+		got <- [func]Read Field["obj", name] {}
+		{ 
+			stream <- [[got]Instruction Stream
+				]Release[~] 
+			out <- [got]Do If[~, stream]
+		}
+	}{
+		out <- func
+	}
+}
+
+Make Special@NBlueprint[bp,backend,func name,bp name,pop worker:out]
+{
+	func <- [[backend]Create Function[func name,("obj"),(),"cdecl"]
+		]Set Input Type[Type Instance[bp name], 0]
+	out <- [backend]Store Function[Fold[pop worker, func, [bp]Fields >>]]
+}
+
+Getters Setters[backend,field,type name:out]
+{
+	//TODO: Throw an exception or something if we read a field that is empty
+	name <- [field]Index[0]
+	type <- [field]Index[1]
+	mytype <- Type Instance[type name]
+	start getter,getref <- [[[[backend]Create Function[ [[[name]Append[" >>"]]Append["@"]]Append[type name], ("obj"), ("out"), "rhope"]
+		]Set Input Type[mytype, 0]
+		]Set Output Type[[type]Set Variant["Boxed"], 0]
+		]Read Field["obj", name]
+	If[[[type]Variant >>] = ["Boxed"]]
+	{
+		getter <- [[start getter]Do AddRef[getref, "out"]]Release["obj"]
+	}{
+		getter <- [[start getter]Box[getref, "out", type]]Release["obj"]
+	}
+		
+	begin setter <- [[[[[backend]Create Function[ [[[name]Append[" <<"]]Append["@"]]Append[type name], ("obj","newval"), ("out"), "rhope"]
+		]Set Input Type[mytype, 0]
+		]Set Input Type[[type]Set Variant["Boxed"], 1]
+		]Set Output Type[mytype, 0]
+		]Copy["obj"]
+		
+	If[[[type]Variant >>] = ["Boxed"]]
+	{
+		,origref <- [begin setter]Read Field["obj", name]
+		{ 
+			stream <- [[~]Instruction Stream
+			]Release[origref]
+			,setref <- [[~]Do If[origref, stream]
+			]Write Field["obj", name]
+			{
+				setter <- [[~]Move["newval", setref]
+				]Move["obj", "out"]
+			}
+		}
+	}{
+		,setref <- [begin setter]Write Field["obj", name]
+		{ 
+			setter <- [[[~]Unbox["newval", setref]
+			]Release["newval"]
+			]Move["obj", "out"]
+		}
+	}
+	
+	out <- [[backend]Store Function[getter]]Store Function[setter]
+	
+}
+
+Compile Blueprint@NBlueprint[bp,backend,name:out]
+{
+	//Rhope identifiers can't start with spaces, so we can use identifiers that start with spaces for special functions
+	init name <- [" init "]Append[name]
+	copy name <- [" copy "]Append[name]
+	cleanup name <- [" cleanup "]Append[name]
+	type <- [[[Fold[_Compile Blueprint Methods[?], Fold[_Compile Blueprint Fields[?], [backend]Create Type[name], [bp]Fields >>], [bp]Methods >>]
+	]Init <<[init name]
+	]Copy <<[copy name]
+	]Cleanup <<[cleanup name]
+	
+	out <- [backend]Register Type[type]
+}
+
+Compile Special@NBlueprint[bp,backend,name:out]
+{
+	init name <- [" init "]Append[name]
+	copy name <- [" copy "]Append[name]
+	cleanup name <- [" cleanup "]Append[name]
+	got specials <- [bp]Make Special[
+				[bp]Make Special[
+					[bp]Make Special[backend, init name, name, Make Init[?]], 
+					copy name, name, Make Copy[?]], 
+			cleanup name, name, Make Cleanup[?]]
+	out <- Fold[Getters Setters[?, ?, name], got specials, [bp]Fields >>]
+}
+
+Blueprint NProgram
+{
+	Blueprints
+	Workers
+	Worker Refs
+}
+
+NProgram[:out]
+{
+	out <- [[[Build[NProgram()]]Blueprints <<[Dictionary[]]]Workers <<[Dictionary[]]]Worker Refs <<[Dictionary[]]
+}
+
+Bind Worker@NProgram[prog,name,worker:out]
+{	
+	after bind <- [prog]Workers << [ [[prog]Workers >>]Set[name, [worker]Name <<[name]] ]
+	parts <- [name]Split["@"]
+	[parts]Index[1]
+	{
+		orig bp <- [[after bind]Blueprints >>]Index[~] {}
+		{ orig bp <- NBlueprint[] }
+		out <- [after bind]Blueprints <<[ [[after bind]Blueprints >>]Set[~, [orig bp]Add Method[[parts]Index[0]] ] ]
+	}{
+		out <- Val[after bind]
+	}
+}
+
+Bind Blueprint@NProgram[prog,name,blueprint:out]
+{
+	out <- [prog]Blueprints << [ [[prog]Blueprints >>]Set[name, blueprint] ]
+}
+
+_Compile Program BP[backend, blueprint, name:out]
+{
+	out <- [blueprint]Compile Blueprint[backend, name]
+}
+
+_Compile Program BP Special[backend, blueprint, name:out]
+{
+	out <- [blueprint]Compile Special[backend, name]
+}
+
+_Compile Program[backend, worker, name:out]
+{
+	out <- [worker]Compile Worker[backend, name]
+}
+
+Compile Program@NProgram[prog, backend:out]
+{
+	backend with bps <- Generate Boolean Methods[Generate Number Methods[Fold[_Compile Program BP Special[?], Fold[_Compile Program BP[?], backend, [prog]Blueprints >>], [prog]Blueprints >>]]]
+	workers with infer <- Map[[prog]Workers >>, Infer Types[?, prog]]
+	out <- Fold[_Compile Program[?], backend with bps,  workers with infer]
+}
+
+Register Method@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, Yes]
+	}
+	out <- [prog]Worker Refs <<[ [[prog]Worker Refs >>]Set[name, ref]]
+}
+
+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, 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]
+{
+	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["Call@Worker", "rhope", 1, 2] //We're using 2 because we need to assume that the outputs are conditional
+	]Register Worker["ID", "rhope", 1, 1]
+	]Register Worker["Blueprint From ID", "rhope", 1, 2]
+	]Register Number Methods
+	
+	out <- [[[[[[[registered]Bind Worker["If@Boolean",
+		[[[[[NWorker["rhope"]
+		]Inputs <<[("condition")]
+		]Input Types <<[ [()]Append[Type Instance["Boolean"]] ]
+		]Outputs <<[("isyes","isno")]
+		]Output Types <<[ [[()]Append[Type Instance["Boolean"]]]Append[Type Instance["Boolean"]] ]
+		]Builtin? <<[Yes]]
+	]Bind Worker["Print",
+		[[[[[NWorker["rhope"]
+		]Inputs <<[("value")]
+		]Input Types <<[ [()]Append[Type Instance["Any Type"]] ]
+		]Outputs <<[("out")]
+		]Output Types <<[ [()]Append[Type Instance["Int32"]] ]
+		]Builtin? <<[Yes]] 
+	]Bind Worker["Build",
+		[[[[[NWorker["rhope"]
+		]Inputs <<[("type")]
+		]Input Types <<[ [()]Append[Type Instance["Blueprint"]] ]
+		]Outputs <<[("out")]
+		]Output Types <<[ [()]Append[Type Instance["Any Type"]] ]
+		]Builtin? <<[Yes]] 
+	]Bind Worker["Blueprint Of",
+		[[[[[NWorker["rhope"]
+		]Inputs <<[("object")]
+		]Input Types <<[ [()]Append[Type Instance["Any Type"]]]
+		]Outputs <<[("type")]
+		]Output Types <<[ [()]Append[Type Instance["Blueprint"]]]
+		]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]]
+	]Bind Worker["ID",
+		[[[[[NWorker["rhope"]
+		]Inputs <<[("bp")]
+		]Input Types <<[ [()]Append[Type Instance["Blueprint"]]]
+		]Outputs <<[("id")]
+		]Output Types <<[ [()]Append[Type Instance["UInt32"]]]
+		]Builtin? << [Yes]]
+	]Bind Worker["Blueprint From ID",
+		[[[[[NWorker["rhope"]
+		]Inputs <<[("id")]
+		]Input Types <<[ [()]Append[Type Instance["UInt32"]]]
+		]Outputs <<[("bp","none")]
+		]Output Types <<[ [[()]Append[Type Instance["Blueprint"]]]Append[Type Instance["Any Type"]]]
+		]Builtin? << [Yes]]
+}
+
+Find Worker@NProgram[prog, name:out,notfound]
+{
+	out,notfound <- [[prog]Worker Refs >>]Index[name]
+}
+
+Find Worker Def@NProgram[prog,name:out,notfound]
+{
+	out,notfound <- [[prog]Workers >>]Index[name]
+}
+
+Find Method@NProgram[prog, name, type:out,notfound]
+{
+	bp,notfound <- [[prog]Blueprints >>]Index[[type]Name >>]
+	,notfound <- If[[bp]Understands Method[name]]
+	{
+		out <- [[prog]Workers >>]Index[[[name]Append["@"]]Append[[type]Name >>]]
+	}
+}
+
+Find Field@NProgram[prog, name, type:fieldtype,notfound]
+{
+	bp,notfound <- [[prog]Blueprints >>]Index[[type]Name >>]
+	fieldtype,notfound <- [bp]Get Field Type[name]
+}
+
+Implicit Conversion@NProgram[prog, fromtype, totype:func,notfound]
+{
+	notfound <- No
+}
+
+Is Method?@NProgram[prog,name:is,is not]
+{
+	,is not <- [[prog]Worker Refs>>]Index[name]
+	{
+		is,is not <- If[[~]Is Method? >>]
+	}
+}
+