changeset 36:495dddadd058

User defined types work in the compiler now
author Mike Pavone <pavone@retrodev.com>
date Sat, 03 Oct 2009 03:18:15 -0400
parents 3498713c3dc9
children 640f541e9116
files backendutils.rhope cbackend.rhope nworker.rhope parser_old.rhope runtime/builtin.c runtime/builtin.h runtime/object.c runtime/object.h
diffstat 8 files changed, 379 insertions(+), 84 deletions(-) [+]
line wrap: on
line diff
--- a/backendutils.rhope	Wed Sep 30 23:55:04 2009 -0400
+++ b/backendutils.rhope	Sat Oct 03 03:18:15 2009 -0400
@@ -10,7 +10,7 @@
 		]Replace["*","_TM_"]
 		]Replace["/","_DV_"]
 		]Replace["<","_LT_"]
-		]Replace["<","_GT_"]
+		]Replace[">","_GT_"]
 }
 
 Escape Rhope Name[name:escaped]
--- a/cbackend.rhope	Wed Sep 30 23:55:04 2009 -0400
+++ b/cbackend.rhope	Sat Oct 03 03:18:15 2009 -0400
@@ -65,7 +65,7 @@
 
 C Field Registry[:out]
 {
-	out <- [[Build["C Field Registry"]]Lookup <<[New@Dictionary[]]]Next ID<<[0]
+	out <- [[Build["C Field Registry"]]Lookup <<[New@Dictionary[]]]Next ID<<[1]
 
 }
 
@@ -117,31 +117,31 @@
 	out <- Fold["Register Method", method reg, [ctype]Methods >>]
 }
 
+_Register Field C[reg,field:out]
+{
+	name <- [field]Index[0]
+	out <- [reg]Register Field[name]
+}
+
 Register Fields@C Type[ctype,field reg:out]
 {
-	out <- Fold["Register Field", field reg, [ctype]Fields >>]
+	out <- Fold["_Register Field C", field reg, [ctype]Fields >>]
 }
 
-Rhope Type to C[typename,naked:out]
+Rhope Type to C[typename:out]
 {
 	If[[typename] = ["Any Type"]]
 	{
 		out <- "struct object *"
 	}{
-		ctype <- ["t_"]Append[Escape Rhope Name[typename]]
-		If[naked]
-		{
-			out <- Val[ctype]
-		}{
-			out <- [ctype]Append[" *"]
-		}
+		out <- [["t_"]Append[Escape Rhope Name[typename]]]Append[" *"]
 	}
 }
 
 _Type Def C Type[text,field:out]
 {
 	name <- [field]Index[0]
-	type <- ["\n\t"]Append[Rhope Type to C[[field]Index[1], No]]
+	type <- ["\n\t"]Append[Rhope Type to C[[field]Index[1]]]
 	out <- [[[[text]Append[type]]Append[" "]]Append[Escape Rhope Name[name]]]Append[";"]
 }
 
@@ -155,9 +155,15 @@
 	out <- [[text]Append[[["\n\tadd_method(bp, "]Append[ [method reg]Method ID[method] ]]Append[  [[", MethodName("]Append[Escape Rhope Name[method]]]Append[[","]Append[Escape Rhope Name[type name]]]]]]Append["));"]
 }
 
+_Type Init C Field[type name,field reg,text,field:out]
+{
+	fname <- [field]Index[0]
+	out <- [[[[text]Append[[["\n\tadd_getter(bp, "]Append[ [field reg]Field ID[fname] ]]Append[  [[", MethodName("]Append[Escape Rhope Name[[fname]Append[" >>"]]]]Append[[","]Append[Escape Rhope Name[type name]]]]]]Append["));"]
+		]Append[[["\n\tadd_setter(bp, "]Append[ [field reg]Field ID[fname] ]]Append[  [[", MethodName("]Append[Escape Rhope Name[[fname]Append[" <<"]]]]Append[[","]Append[Escape Rhope Name[type name]]]]]]Append["));"]
+}
+
 Type Init@C Type[ctype,id,method reg,field reg:out]
 {
-	//TODO: Handle function pointers for build/copy/destroy funcs
 	start <- [["\tbp = register_type_byid("
 		]Append[id]
 		]Append[ 
@@ -165,15 +171,15 @@
 			]Append[
 				["t_"]Append[Escape Rhope Name[ [ctype]Name >> ]]]
 			]Append[
-				["), "]Append[
+				["), (special_func)"]Append[
 					[ 
 						[[[[Escape Rhope Name NU[[ctype]Init >>]
-						]Append[", "]
+						]Append[", (special_func)"]
 						]Append[Escape Rhope Name NU[[ctype]Copy >> ]]
-						]Append[", "]
+						]Append[", (special_func)"]
 						]Append[Escape Rhope Name NU[[ctype]Cleanup >>]]         
 					]Append[");"]]] ]
-	out <- Fold[[["_Type Init C"]Set Input[0, [ctype]Name >>]]Set Input[1, method reg], start, [ctype]Methods >>]
+	out <- Fold[[["_Type Init C Field"]Set Input[0, [ctype]Name >>]]Set Input[1, field reg], Fold[[["_Type Init C"]Set Input[0, [ctype]Name >>]]Set Input[1, method reg], start, [ctype]Methods >>], [ctype]Fields >>]
 }
 
 Blueprint C Type Registry
@@ -209,7 +215,7 @@
 
 _Type Defs C[text,def:out]
 {
-	out <- [[text]Append["\n\n"]]Append[[def]Type Def]
+	out <- [[text]Append[[def]Type Def]]Append["\n\n"]
 }
 
 Type Defs@C Type Registry[reg:out]
@@ -219,7 +225,7 @@
 
 _Type Inits C[reg,method reg,field reg,text,def,name:out]
 {
-	out <- [[text]Append["\n\n"]]Append[ [def]Type Init[[reg]Type ID[name], method reg, field reg] ]
+	out <- [[text]Append[ [def]Type Init[[reg]Type ID[name], method reg, field reg] ]]Append["\n\n"]
 }
 
 Type Inits@C Type Registry[reg,method reg,field reg:out]
@@ -255,6 +261,7 @@
 	Statements
 	Method Registry
 	Field Registry
+	Type Registry
 	Constants
 	Input Types
 	Output Types
@@ -267,7 +274,7 @@
 
 C Function With Registry[name,inputs,outputs,convention,registry,field reg:out]
 {
-	out <- [[[[[[[[[[[Build["C Function"]
+	out <- [[[[[[[[[[[[Build["C Function"]
 		]Name <<[name]
 		]Inputs <<[inputs]
 		]Outputs <<[outputs]
@@ -276,6 +283,7 @@
 		]Statements <<[()]
 		]Method Registry <<[registry]
 		]Field Registry <<[field reg]
+		]Type Registry <<[C Type Registry[]]
 		]Constants <<[New@Dictionary[]]
 		]Input Types <<[ Fold[["Append"]Set Input[1, "Any Type"], (), inputs] ]
 		]Output Types <<[ Fold[["Append"]Set Input[1, "Any Type"], (), outputs] ]
@@ -295,7 +303,6 @@
 {
 	Print["Register Constant"]
 	Print[name]
-	Print[constant]
 	out <- [func]Constants <<[ [[func]Constants >>]Set[name, constant] ]
 	{ Print["Got register constant output"] }
 }
@@ -351,7 +358,7 @@
 	out <- [func]Add Statement[[[dest]Append[" = "]]Append[source]]
 }
 
-AddRef@C Function[func,psource,pdest:out]
+Do AddRef@C Function[func,psource,pdest:out]
 {
     source <- [psource]Make Op[func] 
     dest <- [pdest]Make Op[func]
@@ -384,10 +391,34 @@
 
 Field Result@C Function[func,var,field:out]
 {
-	out <- [[var]Append["->"]]Append[field]
+	as op <- [var]Make Op[func]
+	If[[[Type Of[var]] = ["String"]] And[ [[func]Convention >>] = ["rhope"]] ]
+	{
+		[[func]Inputs >>]Find[var]
+		{
+			type <- [[func]Input Types >>]Index[~]
+			If[[type] = ["Any Type"]]
+			{
+				rvar <- Val[as op]
+			}{
+				rvar <- [[[["(("]Append[ Rhope Type to C[type] ]]Append[")("]]Append[as op]]Append["))"]
+			}
+		}{
+			rvar <- Val[as op]
+		}
+	}{
+		rvar <- Val[as op]
+	}
+	out <- [[rvar]Append["->"]]Append[Escape Rhope Name[field]]
 }
 
-Get Field@C Function[func,var,field:out,result op]
+Read Field@C Function[func,var,field:out,result op]
+{
+	out <- func
+	result op <- Field Ref[var,field]
+}
+
+Write Field@C Function[func,var,field:out,result op]
 {
 	out <- func
 	result op <- Field Ref[var,field]
@@ -398,6 +429,12 @@
 	out <- [func]Add Statement[ [[[var]Append["->"]]Append[field]]Append[" = NULL"] ]
 }
 
+Copy@C Function[func,pdest:out]
+{
+	dest <- [pdest]Make Op[func]
+	out <- [func]Add Statement[ [dest]Append[[[" = copy_object("]Append[dest]]Append[")"]] ]
+}
+
 _Function Arg C[func,val,inputnum:out]
 {
 	out <- [func]Add Statement[
@@ -524,11 +561,11 @@
 }
 _Output Defs C[string,varname,index,func:out]
 {
-	out <- [[[string]Append[ ["\t"]Append[Rhope Type to C[[[func]Output Types >>]Index[index], No]] ]]Append[Escape Rhope Name[varname]]]Append[";\n"]
+	out <- [[[string]Append[ ["\t"]Append[Rhope Type to C[[[func]Output Types >>]Index[index]]] ]]Append[Escape Rhope Name[varname]]]Append[";\n"]
 }
 _Var Defs C[string,type,varname:out]
 {
-	out <- [[[string]Append[ ["\t"]Append[Rhope Type to C[type, No]] ]]Append[Escape Rhope Name[varname]]]Append[";\n"]
+	out <- [[[string]Append[ ["\t"]Append[Rhope Type to C[type]] ]]Append[Escape Rhope Name[varname]]]Append[";\n"]
 }
 
 
@@ -560,19 +597,39 @@
 	out <- [localtype]Append[proto]
 }
 
+_Proto Input[list,input,index,types:out]
+{
+	Print[["_Proto Input: "]Append[input]]
+	{ Print[[types]Index[index]] }
+	out <- [list]Append[ [[Rhope Type to C[[types]Index[index]]]Append[" "]]Append[Escape Rhope Name[input]] ]
+	{ Pretty Print[~, ""] }
+}
+
 Naked Proto@C Function[func:out]
 {
+	Print[["Naked Proto: "]Append[ [func]Name >>] ]
 	[[func]Output Types >>]Index[0]
 	{
-		outtype <- [Rhope Type to C[~, Yes]]Append[" "]
+		outtype <- [Rhope Type to C[~]]Append[" "]
 	}{
 		outtype <- "void "
 	}
 	out <- [[[[outtype
 			]Append[ Escape Rhope Name NU[[func]Name >>]]
 			]Append["("]
-			]Append[ [[func]Input Types >>]Join[", "] ]
+			]Append[ [Fold[["_Proto Input"]Set Input[3, [func]Input Types >>], (), [func]Inputs >>]]Join[", "] ]
 			]Append[")"]
+	{ Print[~] }
+}
+
+Type Check@C Function[func,text,type,input num:out]
+{
+	If[[type] = ["Any Type"]]
+	{
+		out <- text
+	}{
+		out <- [text]Append[ [["\tParam("]Append[input num]]Append[ [[", "]Append[ [[func]Type Registry >>]Type ID[type] ]]Append[")"] ] ]
+	}
 }
 
 Text@C Function[func:out]
@@ -580,7 +637,7 @@
 	If[ [[func]Convention >>] = ["rhope"] ]
 	{
 		cname <- Escape Rhope Name[[func]Name >>]
-		If[ [[[func]Variables >>]Length] = [0] ]
+		If[ [ [[[func]Variables >>]Length]+[[[func]Outputs >>]Length] ] = [0] ]
 		{
 			out <- [[[[[["FuncNoLocals("
 				]Append[cname]
@@ -663,9 +720,9 @@
 	}
 }
 
-_Text C Program[text,func:out]
+_Text C Program[text,func,type reg:out]
 {
-	out <- [text]Append[[[func]Text]Append["\n\n"]]
+	out <- [text]Append[[[ [func]Type Registry <<[type reg] ]Text]Append["\n\n"]]
 }
 
 Combine Consts[consts,func:out]
@@ -678,24 +735,37 @@
 	out <- [text]Append[ [["object * _const_"]Append[Escape Rhope Name[name]]]Append[";\n"] ]
 }
 
-_Set Consts C Program[text,value,name:out]
+_Set Consts C Program[text,value,name,type reg:out]
 {
 	//TODO: Support more constant types
-	out <- [text]Append[[[[["\t_const_"]Append[Escape Rhope Name[name]]]Append[" = make_Int32("]]Append[value]]Append[");\n"]]
+	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"]]
+	}{
+		If[[valtype] = ["Type Literal"]]
+		{
+			//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"]]
+		}
+	}
 }
 
 Text@C Program[program:out]
 {
+	Print["Text@C Program"]
 	constants <- Fold["Combine Consts", New@Dictionary[], [program]Functions >>]
 	headers <- "#include <stdio.h>
 #include \"builtin.h\"
 #include \"object.h\"
 #include \"context.h\"
 #include \"func.h\"
-#include \"integer.h\"\n\n"
+#include \"integer.h\"
+#include \"blueprint.h\"\n\n"
 	out <- [[[[[[headers
 		]Append[[[program]Type Registry >>]Type Defs]
-		]Append[Fold["_Text C Program", 
+		]Append[Fold[["_Text C Program"]Set Input[2, [program]Type Registry >>], 
 				Fold["_Consts C Program", 
 					Fold["_Defs C Program", "", [program]Functions >>], 
 					constants
@@ -705,9 +775,10 @@
 	returntype ret;
 	calldata *cdata;
 	context * ct;
+	blueprint * bp;
 	register_builtin_types();\n\n"]
 		]Append[ [[program]Type Registry >>]Type Inits[[program]Method Registry >>, [program]Field Registry >>] ]
-		]Append[Fold["_Set Consts C Program", "", constants]]
+		]Append[Fold[["_Set Consts C Program"]Set Input[3, [program]Type Registry >>], "", constants]]
 		]Append["
 	ct = new_context();
 	cdata = alloc_cdata(ct, 0);
--- a/nworker.rhope	Wed Sep 30 23:55:04 2009 -0400
+++ b/nworker.rhope	Sat Oct 03 03:18:15 2009 -0400
@@ -297,6 +297,16 @@
 	{ out <- [~]Outputs <<[[[~]Outputs >>]Set[number,name]] }
 }
 
+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 Wire@NWorker[worker,from,output,to,input:out]
 {
 	Print[[[[[[[[["Add Wire@NWorker["]Append[from]]Append[","]]Append[output]]Append[","]]Append[to]]Append[","]]Append[input]]Append["]"]]
@@ -420,7 +430,7 @@
 Format Input@NWorker[worker,noderef:out]
 {
 	node <- [[worker]Nodes >>]Index[[noderef]Index >>]
-	If[[[node]Type >>] = ["call"]]
+	[("call","getfield","setfield")]Find[[node]Type >>]
 	{
 		out <- AddRef[ [[["__result_"]Append[[noderef]Index >>]]Append["_"]]Append[[noderef]IO Num >>] ]
 	}{
@@ -431,7 +441,15 @@
 		}{
 			If[[[node]Type >>] = ["const"]]
 			{
-				out <- Constant[[[Type Of[[node]Data >>]]Append["_"]]Append[[node]Data >>]]
+				If[[Type Of[[node]Data >>]] = ["Type Literal"]]
+				{
+					//TODO: Support parametric types
+					datstring <- [[node]Data >>]Name >>
+				}{
+					datstring <- [node]Data >>
+				}
+				out <- Constant[[[Type Of[[node]Data >>]]Append["_"]]Append[datstring]]
+					
 			}
 		}
 	}
@@ -498,14 +516,27 @@
 
 Compile Call Node[node,program,func,inputs,node index:out]
 {
-	[program]Method?[[[node]Data >>]Name >>]
+	If[[[node]Type >>] = ["getfield"]]
 	{
-		Print["Method!"]
-		with call <- [func]Method Call[[[node]Data >>]Name >>, inputs]
-		{ Print["Method Call done"] }
+		with call <- [func]Get Field Call[[node]Data >>, [inputs]Index[0]]
 	}{
-		Print["Function!"]
-		with call <- [func]Call[[[node]Data >>]Name >>, inputs]
+		If[[[node]Type >>] = ["setfield"]]
+		{
+			with call <- [func]Set Field Call[[node]Data >>, [inputs]Index[0], [inputs]Index[1]]
+		}{
+			Print[["Call: "]Append[[[node]Data >>]Name >>]]
+			{
+			[program]Method?[[[node]Data >>]Name >>]
+			{
+				Print["Method!"]
+				with call <- [func]Method Call[[[node]Data >>]Name >>, inputs]
+				{ Print["Method Call done"] }
+			}{
+				Print["Function!"]
+				with call <- [func]Call[[[node]Data >>]Name >>, inputs]
+			}
+			}
+		}
 	}
 	out <- Fold[["Save Result"]Set Input[2, node index], with call, Range[0, [node]Outputs >>]]
 }
@@ -516,10 +547,8 @@
 	node index <- [nodes]Index[current]
 	node <- [[worker]Nodes >>]Index[node index]
 	conditions <- [worker]Collect Conditions[node]
-	If[[[node]Type >>] = ["call"]]
+	[("call","getfield","setfield")]Find[[node]Type >>]
 	{
-		Print[["Call: "]Append[[[node]Data >>]Name >>]]
-		
 		inputs <- [worker]Collect Inputs[node]
 		[conditions]For Backend
 		{
@@ -549,7 +578,14 @@
 			If[[[node]Type >>] = ["const"]]
 			{
 				//TODO: Handle list constants
-				nfunc <- [func]Register Constant[[[Type Of[[node]Data >>]]Append["_"]]Append[[node]Data >>], [node]Data >>]
+				If[[Type Of[[node]Data >>]] = ["Type Literal"]]
+				{
+					//TODO: Support parametric types
+					datstring <- [[node]Data >>]Name >>
+				}{
+					datstring <- [node]Data >>
+				}
+				nfunc <- [func]Register Constant[[[Type Of[[node]Data >>]]Append["_"]]Append[datstring], [node]Data >>]
 			}{
 				nfunc <- Val[func]
 			}
@@ -619,7 +655,7 @@
 
 Node Result Vars[vars,node,index:out]
 {
-	If[[[node]Type >>] = ["call"]]
+	[("call","getfield","setfield")]Find[[node]Type >>]
 	{
 		out <- Fold[["Result Var"]Set Input[2, index], vars, Range[0, [node]Outputs >>]]
 	}{
@@ -676,6 +712,129 @@
 	out <- [Test[]]Compile Worker[C Program[], "Test"]
 }
 
+Blueprint NBlueprint
+{
+	Fields
+	Methods
+}
+
+NBlueprint[:out]
+{
+	out <- [[Build["NBlueprint"]]Fields <<[()]]Methods <<[New@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] ]
+}
+
+_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]
+{
+	out <- [type]Add Method[name]
+}
+
+Make Init[func,field:out]
+{
+	name <- [field]Index[0]
+	out <- [func]Set Field Null["obj", name]
+}
+
+Make Copy[func,field:out]
+{
+	name <- [field]Index[0]
+	got <- [func]Read Field["obj", name] {}
+	{ 
+		stream <- [[got]Instruction Stream
+			]AddRef No Dest[~] 
+		out <- [got]Do If[~, stream]
+	}
+}
+
+Make Cleanup[func,field:out]
+{
+	name <- [field]Index[0]
+	got <- [func]Read Field["obj", name] {}
+	{ 
+		stream <- [[got]Instruction Stream
+			]Release[~] 
+		out <- [got]Do If[~, stream]
+	}
+}
+
+Make Special@NBlueprint[bp,backend,func name,bp name,pop worker:out]
+{
+	func <- [[backend]Create Function[func name,("obj"),(),"cdecl"]
+		]Set Input Type[0, bp name]
+	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
+	Print[["Getters Setters: "]Append[name]]
+	name <- [field]Index[0]
+	type <- [field]Index[1]
+	,getref <- [[[[backend]Create Function[ [[[name]Append[" >>"]]Append["@"]]Append[type name], ("obj"), ("out"), "rhope"]
+		]Set Input Type[0, type name]
+		]Set Output Type[0, type]
+		]Read Field["obj", name]
+	{ getter <- [~]Do AddRef[getref, "out"]
+	{ Print["Got getter"] } }
+		
+	,origref <- [[[[[[backend]Create Function[ [[[name]Append[" <<"]]Append["@"]]Append[type name], ("obj","newval"), ("out"), "rhope"]
+		]Set Input Type[0, type name]
+		]Set Input Type[1, type]
+		]Set Output Type[0, type name]
+		]Copy["obj"]
+		]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"]
+			{ Print["got setter"] }
+		}
+	}
+	
+	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]
+	
+	got specials <- [bp]Make Special[
+				[bp]Make Special[
+					[bp]Make Special[[backend]Register Type[type], init name, name, "Make Init"], 
+					copy name, name, "Make Copy"], 
+			cleanup name, name, "Make Cleanup"]
+	out <- Fold[["Getters Setters"]Set Input[2, name], got specials, [bp]Fields >>]
+}
+
 Blueprint NProgram
 {
 	Blueprints
@@ -689,15 +848,28 @@
 }
 
 Bind Worker@NProgram[prog,name,worker:out]
-{
-	out <- [prog]Workers << [ [[prog]Workers >>]Set[name, worker] ]
+{	
+	after bind <- [prog]Workers << [ [[prog]Workers >>]Set[name, worker] ]
+	parts <- [name]Split["@"]
+	[parts]Index[1]
+	{
+		out <- [after bind]Blueprints <<[ [[after bind]Blueprints >>]Set[~, [[[after bind]Blueprints >>]Index[~]]Add Method[[parts]Index[0]] ] ]
+	}{
+		out <- Val[after bind]
+	}
 }
 
 Bind Blueprint@NProgram[prog,name,blueprint:out]
 {
+	Print[["Bind blueprint: "]Append[name]]
 	out <- [prog]Blueprints << [ [[prog]Blueprints >>]Set[name, blueprint] ]
 }
 
+_Compile Program BP[backend, blueprint, name:out]
+{
+	out <- [blueprint]Compile Blueprint[backend, name]
+}
+
 _Compile Program[backend, worker, name:out]
 {
 	out <- [worker]Compile Worker[backend, name]
@@ -705,26 +877,33 @@
 
 Compile Program@NProgram[prog, backend:out]
 {
-	out <- Fold["_Compile Program", backend, [prog]Workers >>]
+	out <- Fold["_Compile Program", Fold["_Compile Program BP", backend, [prog]Blueprints >>], [prog]Workers >>]
 }
 
 Register Worker@NProgram[prog, name, convention, inputs, outputs: out]
 {
 	Print[["Register Worker "]Append[name]]
-	out <- [prog]Worker Refs <<[ [[prog]Worker Refs >>]Set[name, Worker Ref[name, convention, inputs, outputs]]]
+	after reg <- [prog]Worker Refs <<[ [[prog]Worker Refs >>]Set[name, Worker Ref[name, convention, inputs, outputs]]]
+	parts <- [name]Split["@"]
+	[parts]Index[1]
+	{
+		out <- [prog]Register Worker[[parts]Index[0], convention, inputs, outputs]
+	}{
+		out <- Val[after reg]
+	}
 }
 
 Register Builtins@NProgram[prog:out]
 {
-	out <- [[[[[[[[[prog]Register Worker["+", "rhope", 2, 1]
-	]Register Worker["-", "rhope", 2, 1]
-	]Register Worker["*", "rhope", 2, 1]
-	]Register Worker["/", "rhope", 2, 1]
+	out <- [[[[[[[[[prog]Register Worker["+@Int32", "rhope", 2, 1]
+	]Register Worker["-@Int32", "rhope", 2, 1]
+	]Register Worker["*@Int32", "rhope", 2, 1]
+	]Register Worker["/@Int32", "rhope", 2, 1]
 	]Register Worker["Print", "rhope", 1, 1]
-	]Register Worker["Index", "rhope", 2, 1]
-	]Register Worker["If", "rhope", 1, 2]
-	]Register Worker["<", "rhope", 2, 1]
-	]Register Worker[">", "rhope", 1, 1]
+	]Register Worker["If@Yes No", "rhope", 1, 2]
+	]Register Worker["<@Int32", "rhope", 2, 1]
+	]Register Worker[">@Int32", "rhope", 1, 1]
+	]Register Worker["Build", "rhope", 1, 1]
 }
 
 Find Worker@NProgram[prog, name:out,notfound]
@@ -732,3 +911,4 @@
 	Print[ ["Find Worker@NProgram: "]Append[name] ]
 	out,notfound <- [[prog]Worker Refs >>]Index[name]
 }
+
--- a/parser_old.rhope	Wed Sep 30 23:55:04 2009 -0400
+++ b/parser_old.rhope	Sat Oct 03 03:18:15 2009 -0400
@@ -908,6 +908,25 @@
 	}
 }
 
+Blueprint Type Literal
+{
+	Name
+	Params
+}
+
+Type Literal[name:out]
+{
+	Print["Type Literal"]
+	out <- [[Build["Type Literal"]]Name <<[name]]Params <<[()]
+}
+
+Parse Params@Type Literal[literal,params,string:out,after]
+{
+	Print[["Parse Params: "]Append[ [string]Slice[10] ]]
+	plist,after <- Parse List[string,params,()]
+	out <- [literal]Params <<[plist]
+}
+
 Named Pipe or Literal[string,params:out,after]
 {
 	name <- Comment Left Trim[string, "\n\r\t ", params]
@@ -925,38 +944,47 @@
 			{
 				value,after <- Parse Number[name, params]
 			}{
-				delims <- [[[[[[("\n")]Append[[params]Block Begin >>]]Append[[params]Block End >>]]Append[[params]Empty Block >>]]Append[[params]Arg End >>]]Append[[params]List Delim >>]]Append[[params]List End >>]
-				afterdelim,raw before,delim <- [name]Get Comment DString[delims, params]
+				delims <- [[[[[[[("\n")]Append[[params]Block Begin >>]]Append[[params]Block End >>]]Append[[params]Empty Block >>]]Append[[params]Arg End >>]]Append[[params]List Delim >>]]Append[[params]List End >>]]Append[[params]List Begin >>]
+				afterdelim,raw before,delim,nodelim <- [name]Get Comment DString[delims, params]
+
+				before <- Trim[raw before, "\r\n\t "]
+				If[[delim] = [[params]List Begin >>]]
 				{
-					after <- [delim]Append[~]
-				} {} {} { 
-					after <- ""
-				}
-				before <- Trim[raw before, "\r\n\t "]
-				If[[before] = ["Yes"]]
-				{
-					yesno <- Yes
+					value,after <- [Type Literal[before]]Parse Params[params,afterdelim]
 				}{
-					If[[before] = ["No"]]
+					Val[afterdelim]
+					{
+						after <- [delim]Append[~]
+					}
+					Val[nodelim]
+					{
+						after <- ""
+					}
+					If[[before] = ["Yes"]]
 					{
-						yesno <- No
+						yesno <- Yes
 					}{
-						If[[before] = [""]]
+						If[[before] = ["No"]]
 						{
-							Print[[["Found "]Append[delim]]Append[" where a named pipe or literal was expected"]]
-							{ Print[["Near: "]Append[ [afterdelim]Slice[40]]] }
+							yesno <- No
 						}{
-							If[[before]Contains[[params]Global Separator >>]]
+							If[[before] = [""]]
 							{
-								parts <- [before]Split[[params]Global Separator >>]
-								out <- New@Global Node[Right Trim[[parts]Index[0],"\r\n\t "], Trim[[parts]Index[1], "\r\n\t "]]
+								Print[[["Found "]Append[delim]]Append[" where a named pipe or literal was expected"]]
+								{ Print[["Near: "]Append[ [afterdelim]Slice[40]]] }
 							}{
-								out <- New@Named Pipe Node[Right Trim[before,"\r\n\t "]]
+								If[[before]Contains[[params]Global Separator >>]]
+								{
+									parts <- [before]Split[[params]Global Separator >>]
+									out <- New@Global Node[Right Trim[[parts]Index[0],"\r\n\t "], Trim[[parts]Index[1], "\r\n\t "]]
+								}{
+									out <- New@Named Pipe Node[Right Trim[before,"\r\n\t "]]
+								}
 							}
 						}
 					}
+					out <- New@Literal Node[yesno]
 				}
-				out <- New@Literal Node[yesno]
 			}
 		}
 	}
@@ -1023,9 +1051,9 @@
 		}{
 			If[[delim] = [[params]Empty Block >>]]
 			{
-				after expression <- Val[aftere]
+				after <- Val[aftere]
 			}{
-				,after expression <- [after args]Slice[[before]Length]
+				,after <- [after args]Slice[[before]Length]
 			}
 			expression <- Worker or Field[Trim[before,"\r\n\t "], args, params]
 		}
@@ -1235,6 +1263,11 @@
 	}
 }
 
+Add Blueprint Compile[prog,def:out]
+{
+	out <- [prog]Bind Blueprint[[def]Name >>, Fold["Add Blueprint Field", NBlueprint[], [def]Fields >>]]
+}
+
 _Tree to Program[parse tree,program:out]
 {
 	after blueprint <- Fold["Add Blueprint", program, [parse tree]Blueprints >>]
@@ -1260,7 +1293,7 @@
 
 Tree to Program Native[parse tree:out]
 {
-	registered <- Fold["Register Workers Compile", [NProgram[]]Register Builtins, [parse tree]Workers >>]
+	registered <- Fold["Register Workers Compile", Fold["Add Blueprint Compile", [NProgram[]]Register Builtins, [parse tree]Blueprints >>], [parse tree]Workers >>]
 	out <- Fold["Add Workers Compile", registered, [parse tree]Workers >>]
 }
 
--- a/runtime/builtin.c	Wed Sep 30 23:55:04 2009 -0400
+++ b/runtime/builtin.c	Sat Oct 03 03:18:15 2009 -0400
@@ -25,6 +25,9 @@
 		val_no = (t_Boolean *)new_object(TYPE_BOOLEAN);
 		val_no->val = 0;
 		break;
+	case TYPE_BLUEPRINT:
+		bp = register_type_byid(TYPE_BLUEPRINT, sizeof(blueprint *), NULL, NULL, NULL);
+		break;
 	}
 }
 
--- a/runtime/builtin.h	Wed Sep 30 23:55:04 2009 -0400
+++ b/runtime/builtin.h	Sat Oct 03 03:18:15 2009 -0400
@@ -18,6 +18,7 @@
 	TYPE_BOOLEAN,
 	TYPE_FLOAT32,
 	TYPE_FLOAT64,
+	TYPE_BLUEPRINT,
 	TYPE_ARRAY,
 	TYPE_METHODMISSINGEXCEPTION,
 	TYPE_FIELDMISSINGEXCEPTION,
--- a/runtime/object.c	Wed Sep 30 23:55:04 2009 -0400
+++ b/runtime/object.c	Sat Oct 03 03:18:15 2009 -0400
@@ -147,6 +147,12 @@
 	if(type >= max_registered_type || !registered_types[type])
 		return NULL;
 	bp = registered_types[type];
+	return new_object_bp(bp);
+}
+
+object * new_object_bp(blueprint * bp)
+{
+	object * ret;
 	ret = alloc_object(bp);
 	if(ret)
 	{
--- a/runtime/object.h	Wed Sep 30 23:55:04 2009 -0400
+++ b/runtime/object.h	Sat Oct 03 03:18:15 2009 -0400
@@ -66,6 +66,7 @@
 object * alloc_object(blueprint * bp);
 void * alloc_variable(uint32_t size);
 object * new_object(uint32_t type);
+object * new_object_bp(blueprint * bp);
 multisize * new_multisize(uint32_t type, uint32_t size);
 void release_ref(object * obj);
 blueprint * register_type_byid(uint32_t type, uint32_t size, special_func init, special_func copy, special_func cleanup);