changeset 49:3e20ed8959c4

Added initial FFI implementation, Array type and 64-bit integers
author Mike Pavone <pavone@retrodev.com>
date Thu, 08 Apr 2010 01:02:18 -0400
parents a24eb366195c
children 689fb73e7612
files backendutils.rhope cbackend.rhope kernel.rhope number.rhope nworker.rhope parser_old.rhope putchar.rhope runtime/array.c runtime/array.h runtime/block_alloc.h runtime/blueprint.c runtime/blueprint.h runtime/fixed_alloc.c runtime/object.c runtime/object.h
diffstat 15 files changed, 870 insertions(+), 162 deletions(-) [+]
line wrap: on
line diff
--- a/backendutils.rhope	Tue Mar 02 00:18:49 2010 -0500
+++ b/backendutils.rhope	Thu Apr 08 01:02:18 2010 -0400
@@ -36,22 +36,62 @@
 Make Op@AddRef[addref,func:out]
 {
 	//TODO: Make me work with other backends
-	out <- [["add_ref("]Append[ [[addref]Value >>]Make Op[func] ]]Append[")"]
+	out <- [["add_ref((object *)"]Append[ [[addref]Value >>]Make Op[func] ]]Append[")"]
+}
+
+Strip Addref@AddRef[op:out]
+{
+	out <- [[op]Value >>]Strip Addref
 }
 
 Make Op@String[string,func:out]
 {
 	out <- [func]Resolve[string]
+}
+
+Strip Addref@String[op:out]
+{
+	out <- op
 }
 
 Make Op@Whole Number[num,func:out]
 {
 	out <- num
+}
+
+Strip Addref@Whole Number[op:out]
+{
+	out <- op
 }
 
 Make Op@Real Number[num,func:out]
 {
 	out <- num
+}
+
+Strip Addref@Real Number[op:out]
+{
+	out <- op
+}
+
+Blueprint Output
+{
+	Name
+}
+
+Output[name:out]
+{
+	out <- [Build["Output"]]Name <<[name]
+}
+
+Make Op@Output[op,func:out]
+{
+	out <- [func]Resolve Output[[op]Name >>]
+}
+
+Strip Addref@Output[op:out]
+{
+	out <- op
 }
 
 Blueprint Constant
@@ -67,6 +107,11 @@
 Make Op@Constant[const,func:out]
 {
 	out <- [func]Lookup Constant[[const]Value >>]
+}
+
+Strip Addref@Constant[op:out]
+{
+	out <- op
 }
 
 Blueprint Result
@@ -82,6 +127,21 @@
 Make Op@Result[result,func:out]
 {
 	out <- [func]Result Reference[[result]Output Num>>]
+}
+
+Strip Addref@Result[op:out]
+{
+	out <- op
+}
+
+Make Condition[op:out]
+{
+	If[[Type Of[op]]=["OrValue"]]
+	{
+		out <- OrCond[Make Condition[[op]Left >>], Make Condition[[op]Right >>]]
+	}{
+		out <- op
+	}
 }
 
 Blueprint OrValue
@@ -97,7 +157,12 @@
 
 Make Op@OrValue[orval,func:out]
 {
-	out <- [func]If Null Else[[[func]Left >>]Make Op[func], [[func]Right >>]Make Op[func]]
+	out <- [func]If Null Else[[orval]Left >>, [orval]Right >>]
+}
+
+Strip Addref@OrValue[op:out]
+{
+	out <- [[op]Left <<[ [[op]Left >>]Strip Addref ]]Right <<[ [[op]Right >>]Strip Addref ]
 }
 
 Blueprint NotCond
@@ -107,12 +172,17 @@
 
 NotCond[cond:out]
 {
-	out <- [Build["NotCond"]]Condition <<[cond]
+	out <- [Build["NotCond"]]Condition <<[[cond]Strip Addref]
 }
 
 Make Op@NotCond[cond,func:out]
 {
 	out <- ["!"]Append[[[cond]Condition >>]Make Op[func]]
+}
+
+Strip Addref@NotCond[op:out]
+{
+	out <- op
 }
 
 Blueprint OrCond
@@ -123,12 +193,17 @@
 
 OrCond[cond1,cond2:out]
 {
-	out <- [[Build["OrCond"]]Condition1 <<[cond1]]Condition2 <<[cond2]
+	out <- [[Build["OrCond"]]Condition1 <<[[cond1]Strip Addref]]Condition2 <<[[cond2]Strip Addref]
 }
 
 Make Op@OrCond[cond,func:out]
 {
 	out <- ["("]Append[[[ [[cond]Condition1 >>]Make Op[func] ]Append[" || "]]Append[[ [[cond]Condition2 >>]Make Op[func] ]Append[")"]]]
+}
+
+Strip Addref@OrCond[op:out]
+{
+	out <- op
 }
 
 Blueprint AndCond
@@ -139,12 +214,17 @@
 
 AndCond[cond1,cond2:out]
 {
-	out <- [[Build["AndCond"]]Condition1 <<[cond1]]Condition2 <<[cond2]
+	out <- [[Build["AndCond"]]Condition1 <<[[cond1]Strip Addref]]Condition2 <<[[cond2]Strip Addref]
 }
 
 Make Op@AndCond[cond,func:out]
 {
 	out <- ["("]Append[[[ [[cond]Condition1 >>]Make Op[func] ]Append[" && "]]Append[[ [[cond]Condition2 >>]Make Op[func] ]Append[")"]]]
+}
+
+Strip Addref@AndCond[op:out]
+{
+	out <- op
 }
 
 Blueprint Field Ref
@@ -161,13 +241,19 @@
 Make Op@Field Ref[ref,func:out]
 {
 	out <- [func]Field Result[[ref]Variable >>,[ref]Field >>]
+}
+
+Strip Addref@Field Ref[op:out]
+{
+	out <- op
 }
 
 Blueprint Type Instance
 {
 	Name
 	Params
-	Variant
+	Variant
+	Mutable?
 }
 
 Type Instance[raw name:out]
@@ -178,7 +264,7 @@
 	}{
 		name <- raw name
 	}
-	out <- [[[Build["Type Instance"]]Name <<[name]]Params <<[()]]Variant <<["Boxed"]
+	out <- [[[[Build["Type Instance"]]Name <<[name]]Params <<[()]]Variant <<["Boxed"]]Mutable? <<[No]
 }
 
 Set Variant@Type Instance[type,variant:out,invalid]
--- a/cbackend.rhope	Tue Mar 02 00:18:49 2010 -0500
+++ b/cbackend.rhope	Thu Apr 08 01:02:18 2010 -0400
@@ -137,7 +137,9 @@
 		If[[[type]Name >>] = ["Array"]]
 		{
 			[("Naked","Raw Pointer")]Find[variant]
-			{
+			{
+				/*
+				//Below code assumes that paramaterized types are implemented
 				pre param <- [[type]Params >>]Index[0] {}
 				{ pre param <- Type Instance["Any Type"] }
 				[[type]Params >>]Index[1]
@@ -151,7 +153,9 @@
 				}{
 					out <- [child type]Append[" *"]
 					array <- ""
-				}
+				} */
+				out <- "void *"
+				array <- ""
 			}{
 				typename <- "Array"
 			}
@@ -159,13 +163,13 @@
 		}{
 			,regulartype <- [("Naked","Raw Pointer")]Find[variant]
 			{
-				[("Int32","Int16","Int8")]Find[[type]Name >>]
+				[("Int64","Int32","Int16","Int8")]Find[[type]Name >>]
 				{
 					primitive <- Yes
 					[[type]Name >>]Slice[3] {}
 					{ typename <- [["int"]Append[~]]Append["_t"] }
 				}{
-					,regulartype <- [("UInt32","UInt16","UInt8")]Find[[type]Name >>]
+					,regulartype <- [("UInt64","UInt32","UInt16","UInt8")]Find[[type]Name >>]
 					{
 						primitive <- Yes
 						[[type]Name >>]Slice[4] {}
@@ -234,8 +238,17 @@
 	If[[[[ctype]Fields >>]Length] = [1]]
 	{
 		out <- [[[_Type Def C Type["typedef struct {\n\tobject _SP_header;\n\t", [[ctype]Fields >>]Index[0]]]Append["\n} t_"]]Append[[ctype]Name >>]]Append[";"]
-	}{
-		out <- [Fold["_Type Def C Type", "OBegin", [ctype]Fields >>]]Append[ [["\nObject("]Append[Escape Rhope Name[[ctype]Name >>]]]Append[")"] ]
+	}{
+		//HACK!!!
+		If[[[ctype]Name >>]=["Blueprint"]]
+		{
+			out <- ""	
+		}{
+			If[[[ctype]Name >>]=["Array"]]
+			{ oend <- "\nMObject(" }
+			{ oend <- "\nObject(" } 
+			out <- [Fold["_Type Def C Type", "OBegin", [ctype]Fields >>]]Append[ [[oend]Append[Escape Rhope Name[[ctype]Name >>]]]Append[")"] ]
+		}
 	}
 }
 
@@ -252,15 +265,37 @@
 }
 
 Type Init@C Type[ctype,id,method reg,field reg:out]
-{
+{
+	If[[[ctype]Name >>]=["Array"]]
+	{ size <- "-1" }
+	{ 
+		[("Int64","Int32","Int16","Int8")]Find[[ctype]Name >>]
+		{
+			[[ctype]Name >>]Slice[3] {}
+			{ typename <- [["int"]Append[~]]Append["_t"] }
+		}{
+			[("UInt64","UInt32","UInt16","UInt8")]Find[[ctype]Name >>]
+			{
+				[[ctype]Name >>]Slice[4] {}
+				{ typename <- [["uint"]Append[~]]Append["_t"] }
+			}{
+				If[[[ctype]Name >>]=["Blueprint"]]
+				{ typename <- "blueprint *" }
+				{ 
+					If[[[ctype]Name >>]=["Boolean"]]
+					{ typename <- "int32_t" }
+					{ typename <- ["nt_"]Append[Escape Rhope Name[[ctype]Name >>]] }
+				}
+			}
+		}
+		size <- [["sizeof("]Append[typename]]Append[")"] 
+	}
 	start <- [["\tbp = register_type_byid("
 		]Append[id]
-		]Append[ 
-			[[", sizeof("
+		]Append[
+			[[", "]Append[size]
 			]Append[
-				["t_"]Append[Escape Rhope Name[ [ctype]Name >> ]]]
-			]Append[
-				["), (special_func)"]Append[
+				[", (special_func)"]Append[
 					[ 
 						[[[[Escape Rhope Name NU[[ctype]Init >>]
 						]Append[", (special_func)"]
@@ -281,7 +316,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"]
@@ -293,7 +328,8 @@
 			]Set["Boolean", "TYPE_BOOLEAN"]
 			]Set["Float32", "TYPE_FLOAT32"]
 			]Set["Float64", "TYPE_FLOAT64"]
-			]Set["Real Number", "TYPE_FLOAT64"]
+			]Set["Real Number", "TYPE_FLOAT64"]
+			]Set["Blueprint", "TYPE_BLUEPRINT"]
 			]Set["Array", "TYPE_ARRAY"]
 			]Set["Method Missing Exception", "TYPE_METHODMISSINGEXCEPTION"]
 			]Set["Field Missing Exception", "TYPE_FIELDMISSINGEXCEPTION"]
@@ -319,7 +355,8 @@
 
 Type Inits@C Type Registry[reg,method reg,field reg:out]
 {
-	out <- Fold[[[["_Type Inits C"]Set Input[0, reg]]Set Input[1, method reg]]Set Input[2, field reg], "", [reg]Definitions >>]
+	out <- Fold[[[["_Type Inits C"]Set Input[0, reg]]Set Input[1, method reg]]Set Input[2, field reg], "", [reg]Definitions >>]
+	{ Print["Type inits got output"] }
 }
 
 Register Type@C Type Registry[reg,def:out]
@@ -343,7 +380,11 @@
 
 Type ID@C Type Registry[reg,name:out,notfound]
 {
-	out,notfound <- [[reg]Lookup >>]Index[name]
+	out <- [[reg]Lookup >>]Index[name] {}
+	{
+		,notfound <- If[[name]=["Any Type"]]
+		{ out <- "0" }
+	}
 }
 
 Simple Type?@C Type Registry[reg,name:yep,nope,notfound]
@@ -509,18 +550,19 @@
 {
     source <- [psource]Make Op[func] 
     dest <- [pdest]Make Op[func]
-    out <- [func]Add Statement[[[[dest]Append[" = add_ref("]]Append[source]]Append[")"]]
+    out <- [func]Add Statement[[[[dest]Append[" = add_ref((object *)"]]Append[source]]Append[")"]]
 }
 
 AddRef No Dest@C Function[func,psource:out]
 {
     source <- [psource]Make Op[func] 
-    out <- [func]Add Statement[[["add_ref("]Append[source]]Append[")"]]
+    out <- [func]Add Statement[[["add_ref((object *)"]Append[source]]Append[")"]]
 }
 
 Release@C Function[func,psource:out]
 {
-	source <- [psource]Make Op[func]
+	source <- [psource]Make Op[func]
+	Print[["Release: "]Append[source]]
 	out <- [func]Add Statement[[["release_ref("]Append[source]]Append[")"]]
 }
 
@@ -624,7 +666,21 @@
 		]Append[", &"]
 		]Append[dest]
 		]Append[")"] ]
-}
+}
+
+Get Raw Pointer@C Function[func,psource,pdest:out]
+{
+	dest <- [pdest]Make Op[func]
+	source <- [psource]Make Op[func]
+	out <- [func]Add Statement[ [[[dest]Append[" = &("]]Append[source]]Append["->payload)"] ]
+}
+
+Array Raw Pointer@C Function[func,psource,pdest:out]
+{
+	dest <- [pdest]Make Op[func]
+	source <- [psource]Make Op[func]
+	out <- [func]Add Statement[ [[[dest]Append[" = ((char *)"]]Append[source]]Append[")+ sizeof(t_Array)"] ]
+}
 
 _Function Arg C[func,val,inputnum:out]
 {
@@ -647,10 +703,29 @@
 }
 
 Func Base@C Function[func,tocall,args,type:out]
-{
+{
+	Pretty Print[args, ""]
+	{
 	rargs <- Map[args, ["Make Op"]Set Input[1, func]]
 	out <- [Fold["_Function Arg C", func, rargs]
-	]Add Raw Line[[[[[ [type]Append["("] ]Append[tocall]]Append[", "]]Append[ [rargs]Length ]]Append[")"]]
+	]Add Raw Line[[[[[ [type]Append["("] ]Append[tocall]]Append[", "]]Append[ [rargs]Length ]]Append[")"]]
+	}
+}
+
+Call Foreign@C Function[func,name,language,args,store result:out]
+{
+	rargs <- Map[args, ["Make Op"]Set Input[1, func]]
+	//Assume language = "C" for now
+	base <- [[[name]Append["("]]Append[ Join[rargs, ", "] ]]Append[")"]
+	,do store <- If[[Type Of[store result]]=["String"]]
+	{ 
+		,do store <- If[[store result]=[""]]
+		{ stmt <- Val[base] }
+	}
+	
+	Val[do store]
+	{ stmt <- [[Make Op[store result, func]]Append[" = "]]Append[base] }
+	out <- [func]Add Statement[stmt]
 }
 
 Field Base@C Function[func,field,args,type:out]
@@ -693,6 +768,16 @@
 	}{
 		out <- Escape Rhope Name[op]
 	}
+}
+
+Resolve Output@C Function[func,name:out]
+{
+	If[[[func]Convention >>] = ["rhope"]]
+	{
+		out <- ["locals->"]Append[Escape Rhope Name[name]]
+	}{
+		out <- Escape Rhope Name[name]
+	} 
 }
 
 Instruction Stream@C Function[func:out]
@@ -721,13 +806,16 @@
 }
 
 If Null Else@C Function[func,left,right:out]
-{
+{
+	check <- [[Make Condition[left]]Strip Addref]Make Op[func]
+	l <- [left]Make Op[func]
+	r <- [right]Make Op[func]
 	out <- [[[[[["("
-		]Append[left]
+		]Append[check]
 		]Append[" ? "]
-		]Append[left]
+		]Append[l]
 		]Append[" : "]
-		]Append[right]
+		]Append[r]
 		]Append[")"]
 }
 
@@ -761,7 +849,9 @@
 
 
 Definitions@C Function[func:out]
-{
+{
+	Print[["Definitions@C Function: "]Append[[func]Name >>]]
+	{
 	If[ [[[func]Convention >>] = ["rhope"]] And [[ [[[func]Variables >>]Length]+[[[func]Outputs >>]Length] ] > [0]] ]
 	{
 		localtype <- [[[Fold[["_Output Defs C"]Set Input[3, func], Fold["_Var Defs C","typedef struct {\n", [func]Variables >>], [func]Outputs >>]]Append["} l_"]]Append[Escape Rhope Name[[func]Name >>]]]Append[";\n"]
@@ -785,7 +875,8 @@
 	}{
 		proto <- [[func]Naked Proto]Append[";\n"]
 	}
-	out <- [localtype]Append[proto]
+	out <- [localtype]Append[proto]
+	}
 }
 
 _Proto Input[list,input,index,types:out]
@@ -837,7 +928,8 @@
 }
 
 Text@C Function[func:out]
-{	
+{	
+	Print[["Text@C Function: "]Append[[func]Name >>]]
 	If[ [[func]Convention >>] = ["rhope"] ]
 	{
 		cname <- Escape Rhope Name[[func]Name >>]
@@ -881,12 +973,25 @@
 	Functions
 	Method Registry
 	Field Registry
-	Type Registry
+	Type Registry
+	Libraries
 }
 
 C Program[:out]
 {
-	out <- [[[[Build["C Program"]]Functions <<[Dictionary[]]]Method Registry <<[C Method Registry[]]]Type Registry <<[C Type Registry[]]]Field Registry <<[C Field Registry[]]
+	out <- [[[[[Build["C Program"]]Functions <<[Dictionary[]]]Method Registry <<[C Method Registry[]]]Type Registry <<[C Type Registry[]]]Field Registry <<[C Field Registry[]]]Libraries <<[Dictionary[]]
+}
+
+Link@C Program[program,language,library:out]
+{
+	If[[library] = ["runtime"]]
+	{
+		out <- program
+	}{
+		langlibs <- [[program]Libraries >>]Index[language] {}
+		{ langlibs <- Dictionary[] }
+		out <- [program]Libraries <<[ [[program]Libraries >>]Set[language, [langlibs]Set[library, Yes]] ]
+	}
 }
 
 Register Type@C Program[program,def:out]
@@ -943,26 +1048,32 @@
 }
 
 _Set Consts C Program[text,value,name,type reg:out]
-{
+{
+	Print[["_Set Consts: "]Append[valtype]]
+	Pretty Print[value, "_Set Consts: "]
 	//TODO: Support more constant types
 	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 <- [text]Append[[[[["\t_const_"]Append[Escape Rhope Name[name]]]Append[" = make_Int32("]]Append[value]]Append[");\n"]]
+		{ Print["_Set Consts got output integer"] }
 	}{
 		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"]]
+			out <- [text]Append[[[[["\t_const_"]Append[Escape Rhope Name[name]]]Append[" = make_Blueprint("]]Append[typeid]]Append[");\n"]]
+			{ Print["_Set Consts got output blueprint"] }
 		}{
 			If[[valtype] = ["Yes No"]]
 			{
 				If[value]
 				{
-					out <- [text]Append[[["\t_const_"]Append[Escape Rhope Name[name]]]Append[" = (object *)val_yes;\n"]]
+					out <- [text]Append[[["\t_const_"]Append[Escape Rhope Name[name]]]Append[" = (object *)val_yes;\n"]]
+					{ Print["_Set Consts got output yes"] }
 				}{
-					out <- [text]Append[[["\t_const_"]Append[Escape Rhope Name[name]]]Append[" = (object *)val_no;\n"]]
+					out <- [text]Append[[["\t_const_"]Append[Escape Rhope Name[name]]]Append[" = (object *)val_no;\n"]]
+					{ Print["_Set Consts got output no"] }
 				}
 			}
 		}
@@ -979,7 +1090,8 @@
 #include \"context.h\"
 #include \"func.h\"
 #include \"integer.h\"
-#include \"blueprint.h\"
+#include \"blueprint.h\"
+#include \"array.h\"
 #include \"bool.h\"\n\n"
 	out <- [[[[[[headers
 		]Append[[[program]Type Registry >>]Type Defs]
@@ -988,7 +1100,7 @@
 					Fold["_Defs C Program", "", [program]Functions >>], 
 					constants
 				], [program]Functions >>]]
-		]Append["#include \"builtin.c\"\n\nint main(int argc, char **argv)
+		]Append["#include \"builtin.c\"\n#include \"array.c\"\n\nint main(int argc, char **argv)
 {
 	returntype ret;
 	calldata *cdata;
--- a/kernel.rhope	Tue Mar 02 00:18:49 2010 -0500
+++ b/kernel.rhope	Thu Apr 08 01:02:18 2010 -0400
@@ -1,9 +1,30 @@
+
+Val[in:out]
+{
+	out <- in
+}
 
 Blueprint Boolean
 {
 	Val(Int32,Naked)
 }
 
+/*
+Blueprint Blueprint
+{
+	Val(Blueprint,Naked)
+}*/
+
+Blueprint Int64
+{
+	Num(Int64,Naked)
+}
+
+If@Int64[num:yes,no]
+{
+	yes,no <- If[[num]!=[0]]
+}
+
 Blueprint Int32
 {
 	Num(Int32,Naked)
@@ -11,7 +32,7 @@
 
 If@Int32[num:yes,no]
 {
-	yes,no <- If[[num]=[0]]
+	yes,no <- If[[num]!=[0]]
 }
 
 Blueprint Int16
@@ -21,7 +42,7 @@
 
 If@Int16[num:yes,no]
 {
-	yes,no <- If[[num]=[0]]
+	yes,no <- If[[num]!=[0]]
 }
 
 Blueprint Int8
@@ -31,7 +52,17 @@
 
 If@Int8[num:yes,no]
 {
-	yes,no <- If[[num]=[0]]
+	yes,no <- If[[num]!=[0]]
+}
+
+Blueprint UInt64
+{
+	Num(UInt64,Naked)
+}
+
+If@UInt64[num:yes,no]
+{
+	yes,no <- If[[num]!=[0]]
 }
 
 Blueprint UInt32
@@ -41,7 +72,7 @@
 
 If@UInt32[num:yes,no]
 {
-	yes,no <- If[[num]=[0]]
+	yes,no <- If[[num]!=[0]]
 }
 
 Blueprint UInt16
@@ -51,7 +82,7 @@
 
 If@UInt16[num:yes,no]
 {
-	yes,no <- If[[num]=[0]]
+	yes,no <- If[[num]!=[0]]
 }
 
 Blueprint UInt8
@@ -61,7 +92,171 @@
 
 If@UInt8[num:yes,no]
 {
-	yes,no <- If[[num]=[0]]
+	yes,no <- If[[num]!=[0]]
 }
 
 
+Blueprint Array
+{
+	Eltype(Blueprint)
+	Length(Int32,Naked)
+	Storage(Int32,Naked)
+}
+
+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(Array), index(Int32,Naked):out]
+	_internal_array_setboxed[array(Array,Boxed,Mutable), index(Int32,Naked), val:array]
+	_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)]
+}
+
+=@Blueprint[left,right:out]
+{
+	out <- [_internal_blueprint_eq[left,right]]!=[0]
+}
+
+Array[n:out(Array)]
+{
+	out <- [[_internal_array_allocboxed[0]
+	]Length <<[0]
+	]Storage <<[0]
+}
+
+First@Array[array:out(Int32),empty]
+{
+	,empty <- If[[array]Length >>]
+	{ out <- 0 }
+}
+
+Next@Array[array,current:out(Int32),empty]
+{
+	next <- [current]+[1]
+	,empty <- If[[next] < [[array]Length >>]]
+	{
+		out <- Val[next]
+	}
+}
+
+Last@Array[array:out(Int32),empty]
+{
+	,empty <- If[[array]Length >>]
+	{ out <-  [[array]Length >>] - [1] }
+}
+
+Append@Array[array,newval:out(Array)]
+{
+	out <- [array]Set[[array]Length >>, newval]
+}
+
+Index@Array[array,index(Int32):out,notfound]
+{
+	,notfound <- If[[index] >= [0]]
+	{
+		,notfound <- If[[index] < [[array]Length >>]]
+		{
+			eltype <- [array]Eltype >>
+			If[[eltype] = [Any Type()]]
+			{
+				out <- _internal_array_getboxed[array, index]
+			}{
+				out <- _internal_array_copyout[array, index, Build[eltype]]
+			}
+		}
+	}	
+}
+
+_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(Array)]
+{
+	If[[index] < [[array]Storage >>]]
+	{
+		If[[index] > [[array]Length >>]]
+		{
+			farray <- [[array]Set[[index]-[1], val]]Length <<[ [index]+[1] ]
+		}{
+			If[[index] = [[array]Length >>]]
+			{
+				farray <- [array]Length <<[ [index]+[1] ]
+			}{
+				farray <- Val[array]
+			}
+		}
+		eltype <- [array]Eltype >>
+		If[[eltype] = [Any Type()]]
+		{
+			out <- _internal_array_setboxed[farray, index, val]
+		}{
+			If[[Blueprint Of[val]] = [eltype]]
+			{
+				out <- _internal_array_copyin[farray, index, val]
+			}{
+				boxed <- _internal_array_allocboxed[[farray]Storage >>]
+				[array]First
+				{
+					copied <- _Copy to Boxed[farray, boxed, ~]
+				}{
+					//I don't think this case should happen normally
+					copied <- Val[boxed]
+				}
+				out <- _internal_array_setboxed[copied, index, val]
+			}
+		}
+	}{
+		If[[array]Length >>]
+		{
+			If[[index] < [4]]
+			{
+				new storage <- [index]+[index]
+			}{
+				new storage <- [index]+[[index]RShift[1]]
+			}
+			 
+			do boxed <- If[[[array]Eltype >>] = [Any Type()]]
+			{
+				copied <- _Copy to Boxed[array, _internal_array_allocboxed[new storage], 0]
+			}{	
+				bp <- Blueprint Of[val]
+				If[[[array]Eltype >>] = [bp]]
+				{
+					copied <- _Copy Naked[array, _internal_array_allocnaked[new storage, bp], 0]
+				}{
+					copied <- _Copy to Boxed[array, _internal_array_allocboxed[new storage], 0]
+				}
+			}
+			out <- [[copied]Length <<[[array]Length >>]]Set[index,val]
+		}{
+			len <- [index]+[1]
+			out <- [_internal_array_allocnaked[len, Blueprint Of[val]]
+			]Set[index,val]
+		}
+	}
+}
+
+
--- a/number.rhope	Tue Mar 02 00:18:49 2010 -0500
+++ b/number.rhope	Thu Apr 08 01:02:18 2010 -0400
@@ -71,7 +71,7 @@
 		
 Generate Number Methods[backend:out]
 {	
-	numtypes <- ("Int8","Int16","Int32","UInt8","UInt16","UInt32")
+	numtypes <- ("Int8","Int16","Int32","Int64","UInt8","UInt16","UInt32","UInt64")
 	
 	out <- Fold["_Generate Number Methods", backend, numtypes]
 }
@@ -103,7 +103,7 @@
 
 Register Number Methods[program:out]
 {
-	numtypes <- ("Int8","Int16","Int32","UInt8","UInt16","UInt32")
+	numtypes <- ("Int8","Int16","Int32","Int64","UInt8","UInt16","UInt32","UInt64")
 	out <- Fold["_Register Number Methods", program, numtypes]
 }
 
--- a/nworker.rhope	Tue Mar 02 00:18:49 2010 -0500
+++ b/nworker.rhope	Thu Apr 08 01:02:18 2010 -0400
@@ -295,12 +295,13 @@
 	NodeResults
 	Free Temps
 	Name
-	Builtin?
+	Builtin?
+	Library
 }
 
 NWorker[convention:out]
 {
-	out <- [[[[[[[[Build["NWorker"]]Convention <<[convention]]Nodes <<[()]]Inputs <<[()]]Outputs <<[()]]Input Types <<[()]]Output Types <<[()]]Name <<["Anonymous"]]Builtin? <<[No]
+	out <- [[[[[[[[[Build["NWorker"]]Convention <<[convention]]Nodes <<[()]]Inputs <<[()]]Outputs <<[()]]Input Types <<[()]]Output Types <<[()]]Name <<["Anonymous"]]Builtin? <<[No]]Library << [""]
 }
 
 Add Node@NWorker[worker,type,data,inputs,outputs:out,node index]
@@ -731,8 +732,12 @@
 				with call <- [func]Method Call[[[node]Data >>]Name >>, inputs]
 				{ Print["Method Call done"] }
 			}{
-				Print["Function!"]
-				with call <- [func]Call[[[node]Data >>]Name >>, inputs]
+				Print["Function!"]
+				{
+					Pretty Print[inputs, ""]
+					{ with call <- [func]Call[[[node]Data >>]Name >>, inputs]}
+				}
+				
 			}
 			}
 		}
@@ -762,13 +767,16 @@
 		nstream <- Compile Call Node[node, program, stream, inputs, node index]
 	}{
 		If[[[node]Type >>] = ["output"]]
-		{
+		{
+			Print["Compiling output node"]
 			inputs <- [worker]Collect Inputs[node]
 			[conditions]For Backend
-			{
+			{
+				Print["has conditions"]
 				stream <- [func]Instruction Stream
 				nfunc <- [func]Do If[~, nstream]
-			}{
+			}{
+				Print["no conditions"]
 				stream <- Val[func]
 				nfunc <- Val[nstream]
 			}
@@ -865,29 +873,171 @@
 Result Vars@NWorker[worker:out]
 {
 	out <- Fold["Node Result Vars", (), [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]
+	Print[["FInputs: "]Append[index]]
+	Pretty Print[input type, ""]
+	{
+	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]
+{
+	Print[["_Return Param: "]Append[output]]
+	output <- [outputs]Index[index]
+	[inputs]Find[output]
+	{
+		If[[[input types]Index[~]]Mutable? >>]	
+		{
+			,none <- [outputs]Next[index]
+			{
+				out,none <- _Return Param[outputs, index, input types, ~]
+			}
+		} { 
+			out <- index
+		}
+	}{
+		out <- index
+	}
+}
+
+Return Param[outputs, inputs, input types:out,none]
+{
+	Print["Return Param"]
+	,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]
+{
+	Print[["Compiling FFI stub for "]Append[name]]
+	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"]Set Input[3, [worker]Inputs >>], rfunc, [worker]Input Types >>]
+	{ [~]Call Foreign[name, [worker]Convention >>, Map[Zip[[worker]Inputs >>, [worker]Input Types >>], "FParams"], rparam]
+	{ Fold[[[["Save Foreign Result"]Set Input[3, [worker]Output Types >>]]Set Input[4, [worker]Inputs >>]]Set Input[5, [worker]Input Types >>], ~, [worker]Outputs >>]
+	{ out <- [program]Store Function[~] }}}
+}		
 
 Compile Worker@NWorker[worker,program,name:out]
 {
 	If[[worker]Builtin? >>]
 	{
 		out <- program
-	}{
-		Print[["Compiling: "]Append[name]]
-		{
-		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 >>]
-		
-		res vars <- [worker]Result Vars
-		func <- Fold["Set Null", Fold["Set Null", Fold[["Allocate Var"]Set Input[2, "Any Type"], ifunc, res vars], res vars], [worker]Outputs >>]
-		
-		groups <- [worker]Dependency Groups
-		[groups]First
-		{
-			final func <- [worker]Compile Group[program,func,groups, ~]
-		}{
-			final func <- Val[func]
-		}
-		out <- [program]Store Function[Fold["Release", Fold[["Release Var"]Set Input[0, worker], final func, res vars], [worker]Inputs >>]]
+	}{
+		If[[[worker]Library >>] = [""]]
+		{	
+			Print[["Compiling: "]Append[name]]
+			{
+			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 >>]
+			
+			res vars <- [worker]Result Vars
+			func <- Fold["Set Null", Fold["Set Null", Fold[["Allocate Var"]Set Input[2, "Any Type"], ifunc, res vars], res vars], [worker]Outputs >>]
+			
+			groups <- [worker]Dependency Groups
+			[groups]First
+			{
+				final func <- [worker]Compile Group[program,func,groups, ~]
+			}{
+				final func <- Val[func]
+			}
+			out <- [program]Store Function[Fold["Release", Fold[["Release Var"]Set Input[0, worker], final func, res vars], [worker]Inputs >>]]
+			}
+		}{
+			out <- Compile Foreign Stub[worker,[program]Link[[worker]Convention >>, [worker]Library >> ],name]
 		}
 	}
 }
@@ -1116,8 +1266,10 @@
 	after bind <- [prog]Workers << [ [[prog]Workers >>]Set[name, [worker]Name <<[name]] ]
 	parts <- [name]Split["@"]
 	[parts]Index[1]
-	{
-		out <- [after bind]Blueprints <<[ [[after bind]Blueprints >>]Set[~, [[[after bind]Blueprints >>]Index[~]]Add Method[[parts]Index[0]] ] ]
+	{
+		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]
 	}
@@ -1178,12 +1330,13 @@
 
 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 Number Methods
 	
-	out <- [[[registered]Bind Worker["If@Boolean",
+	out <- [[[[registered]Bind Worker["If@Boolean",
 		[[[[[NWorker["rhope"]
 		]Inputs <<[("condition")]
 		]Input Types <<[ [()]Append[Type Instance["Boolean"]] ]
@@ -1203,7 +1356,14 @@
 		]Input Types <<[ [()]Append[Type Instance["Blueprint"]] ]
 		]Outputs <<[("out")]
 		]Output Types <<[ [()]Append[Type Instance["Any Type"]] ]
-		]Builtin? <<[Yes]] 
+		]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]]
 }
 
 Find Worker@NProgram[prog, name:out,notfound]
--- a/parser_old.rhope	Tue Mar 02 00:18:49 2010 -0500
+++ b/parser_old.rhope	Thu Apr 08 01:02:18 2010 -0400
@@ -33,11 +33,12 @@
 	Uses
 	Hex Escape
 	Escape Map
+	Foreign
 }
 
 New@Parser[:out]
 {
-	out <- [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[Build["Parser"]
+	out <- [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[Build["Parser"]
 	]Arg Begin << ["["]
 	]Arg End <<["]"]
 	]Line Comment <<["//"]
@@ -68,6 +69,7 @@
 	]Hex Escape <<["x"]
 	]Uses <<["uses"]
 	]Escape Map <<[[[[Dictionary[]]Set["n","\n"]]Set["r","\r"]]Set["t","\t"]]
+	]Foreign <<["Foreign"]
 }
 
 Blueprint Output Reference
@@ -100,6 +102,19 @@
 	}
 }
 
+Blueprint Foreign Lib
+{
+	Language
+	Name
+}
+
+New Foreign Lib[language, library:out]
+{
+	out <- [[Build["Foreign Lib"]
+	]Language <<[language]
+	]Name <<[library]
+}
+
 Blueprint Parse Program
 {
 	Workers
@@ -645,7 +660,7 @@
 	out <- [[[Build["Parse Error"]]Type <<[type]]Text <<[text]]Line Number <<[number]
 }
 
-Filter Empty[string:out]
+Not Empty[string:out]
 {
 	If[[[string]Length] > [0]]
 	{
@@ -804,7 +819,7 @@
 		{
 			body lines <- [body]Split["\n"]
 			more lines <- [[[body lines]Length] - [1]] + [name lines]
-			fields <- Fold[["Process Blueprint Field"]Set Input[2, params], (), Filter[Map[body lines, ["Trim"]Set Input[1,"\n\r\t "]], "Filter Empty"]]
+			fields <- Fold[["Process Blueprint Field"]Set Input[2, params], (), Filter[Map[body lines, ["Trim"]Set Input[1,"\n\r\t "]], "Not Empty"]]
 			new tree <- [tree]Blueprints << [ [[tree]Blueprints >>]Set[name, New@Blueprint Definition[name, fields]] ]
 			out <- Null[~, params, new tree, [lines] + [more lines]]
 		} {} {
@@ -1196,15 +1211,21 @@
 				{
 					,warn <- If[[Type Of[~]] = ["Named Pipe Node"]]
 					{
-						paramtype,warn <- [before variant]Set Variant[[variant]Name >>]
+						before mutable,warn <- [before variant]Set Variant[[variant]Name >>]
 					}
 					Val[warn]
 					{
 						Print[[[["Warning: Invalid variant for type "]Append[[before variant]Name >>]]Append[" on input "]]Append[param name]]
-						paramtype <- Val[before variant]
+						before mutable <- Val[before variant]
 					}
 				}{
-					paramtype <- Val[before variant]
+					before mutable <- Val[before variant]
+				}
+				[type info]Index[2]
+				{
+					paramtype <- [before mutable]Mutable? <<[ [[~]Name >>] = ["Mutable"] ]
+				}{
+					paramtype <- Val[before mutable]
 				}
 			}{
 				paramtype <- Type Instance["Any Type"]
@@ -1228,7 +1249,7 @@
 	}
 }
 
-Worker Name[string,params,tree,lines:out]
+Worker Declaration[string,params:worker,rest,no match]
 {
 	,whitespace name <- [string]Get Comment DString[[params]Arg Begin >>, params]
 	{
@@ -1245,40 +1266,79 @@
 			//if it isn't present, everything in the arglist is an input
 			If[[~] = [in out]]
 			{
-				after arglist <- [after]Get Comment DString[arg end, params] {}
+				rest <- [after]Get Comment DString[arg end, params] {}
 				{
 					outputs,output types <- Parse Param List[~, (), (), params]
 					{ Print["got outputs"] }
 					{ Print["got output types"] }
 				}
 			}{
-				after arglist <- Val[after]
+				rest <- Val[after]
 				outputs <- ()
 				output types <- ()
 			}
 			inputs,input types <- Parse Param List[arglist, (), (), params]
 			{ Print["got inputs"] }
 			{ Print["got input types"] }
-			
-			//inputs <- Map[[arglist]Split[[params]List Delim >>], ["Trim"]Set Input[1,"\n\r\t "]]
-			//outputs <- Map[[output string]Split[[params]List Delim >>], ["Trim"]Set Input[1,"\n\r\t "]]
-
-			New@Parse Worker[worker name, inputs, outputs, input types, output types, 0]
-			{
-				Print["Got parse worker"]
-				body text, modifiers <- [after arglist]Get Comment DString[[params]Block Begin >>, params]
-				modified <- Process Modifiers[~, params, modifiers]
-				expression trees, after body <- Worker Body[body text, params, ()]
-				worker <- [modified]Trees <<[expression trees]
-				new worker dict <- [[tree]Workers >>]Set[worker name, worker]
-				out <- Null[after body, params, [tree]Workers <<[new worker dict], 0]
-			}
+			worker <- New@Parse Worker[worker name, inputs, outputs, input types, output types, 0]
 		}
 	}{}{}{
+		no match <- string
+	}
+}
+
+Worker Name[string,params,tree,lines:out]
+{
+	,after arglist <- Worker Declaration[string, params]
+	{
+		Print["Got parse worker"]
+		worker name <- [~]Name >>
+		body text, modifiers <- [after arglist]Get Comment DString[[params]Block Begin >>, params]
+		modified <- Process Modifiers[~, params, modifiers]
+		expression trees, after body <- Worker Body[body text, params, ()]
+		worker <- [modified]Trees <<[expression trees]
+		new worker dict <- [[tree]Workers >>]Set[worker name, worker]
+		out <- Null[after body, params, [tree]Workers <<[new worker dict], 0]
+	} {} {
 		out <- tree
 	}
 }
 
+Parse Foreign Worker[tree, string, lib, params:out]
+{
+	,rest <- Worker Declaration[string, params]
+	{
+		foreign <- [~]Trees << [lib]
+		next <- [tree]Workers << [[[tree]Workers >>]Set[[foreign]Name >>, foreign]]
+		out <- Parse Foreign Worker[next, rest, lib, params]
+	} {} {
+		out <- tree
+	}
+}
+
+Parse Foreign[string,params,tree,lines:out]
+{	
+	Print["Foreign block"]
+	,after foreign <- [string]Slice[[[params]Foreign >>]Length]
+	Print[[after foreign]Slice[20]]
+	[after foreign]Get Comment DString[[params]Blueprint Type Delim >>, params]
+	{
+		[~]Get Comment DString[[params]Block Begin >>, params]
+		{
+			rest, body <- [~]Get Comment DString[[params]Block End >>, params]
+		}
+		{ lib <- Trim[~, "\r\n\t "] }
+	}
+	{ language <- Trim[~, "\r\n\t "] }
+	Print[[[["Language: "]Append[language]]Append[" Library: "]]Append[lib]]
+	{
+	Parse Foreign Worker[tree, body, New Foreign Lib[language, lib], params]
+	{ 
+		out <- Null[rest, params, ~, 0]
+	}
+	}
+}
+
 Null[string,params,tree,lines:out]
 {
 	trimmed <- Comment Left Trim[string, " \n\r\t", params]
@@ -1291,7 +1351,12 @@
 		{
 			out <- Parse Import[trimmed, params, tree, current line]
 		}{
-			out <- Worker Name[trimmed, params, tree, current line]
+			If[[trimmed]Starts With[ [params]Foreign >> ]]
+			{
+				out <- Parse Foreign[trimmed, params, tree, current line]
+			}{
+				out <- Worker Name[trimmed, params, tree, current line]
+			}
 		}
 	}
 }
@@ -1311,16 +1376,31 @@
 Register Workers Compile[prog, worker, name:out]
 {
 	Print[["Registering "]Append[name]]
-	out <- [prog]Register Worker[name, "rhope", [[worker]Inputs >>]Length, [[worker]Outputs >>]Length]
+	If[[ Type Of[[worker]Trees >>] ] = ["Foreign Lib"]]
+	{ convention <- Val[[[worker]Trees >>]Language >>] }
+	{ convention <- "rhope" }
+	out <- [prog]Register Worker[name, convention, [[worker]Inputs >>]Length, [[worker]Outputs >>]Length]
 }
 
 Add Workers Compile[prog, worker, name:out]
 {
 	Print[["Add Workers Compile: "]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]
-	out <- [prog]Bind Worker[name, final nworker]
+		If[[Type Of[[worker]Trees >>]] = ["Foreign Lib"]]
+		{
+			//TODO: Handle foreign func
+			final nworker <- [[[[[NWorker[[[worker]Trees >>]Language >>]
+			]Inputs <<[ [worker]Inputs >> ]
+			]Input Types <<[ [worker]Input Types >> ]
+			]Outputs <<[ [worker]Outputs >> ]
+			]Output Types <<[ [worker]Output Types >> ]
+			]Library <<[ [[worker]Trees >>]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]
+		}
+		out <- [prog]Bind Worker[name, final nworker]
 	}
 }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/putchar.rhope	Thu Apr 08 01:02:18 2010 -0400
@@ -0,0 +1,17 @@
+
+
+Foreign C:libc
+{
+	putchar[char(Int32,Naked):out(Int32,Naked)]
+}
+
+Main[]
+{
+	putchar[72]
+	{ putchar[101]
+	{ putchar[108]
+	{ putchar[108]
+	{ putchar[111]
+	{ putchar[10] }}}}}
+}
+
--- a/runtime/array.c	Tue Mar 02 00:18:49 2010 -0500
+++ b/runtime/array.c	Thu Apr 08 01:02:18 2010 -0400
@@ -1,26 +1,55 @@
-#include "array.h"
-#include "integer.h"
-
-Func(Array,0,
-	;)
-	Ret(0, new_object(TYPE_ARRAY))
-	Return
-EndFunc
+#include "integer.h"
+#include "object.h"
 
-Method(Index,Array,2,
-	_t_Int32 * idx;)
-	Param(1,idx,Int32)
-	if (idx->num < 0 || idx->num >= me->numels) {
-		Ret(0, NULL)
-		Ret(1, me)
-	} else {
-		Ret(1, NULL)
-		if (me->contents_type) {
-			Ret(0, copy_from_raw(me->conents_type, (char *)me + sizeof(*me) + (idx->num * sizeof(object *))))
-		} else {
-			Ret(0, add_ref((object *)((char *)me + sizeof(*me) + (idx->num * sizeof(object *)))))
-		}
-		release_ref(me);
-	}
-EndFunc
+void _internal_array_copyout(object * array, int32_t index, object * dest)
+{
+	t_Array * arr = (t_Array *)array;
+	memcpy(((char *)dest) + sizeof(object), ((char *)array) + sizeof(t_Array) + arr->payload.Eltype->bp->size * index, get_blueprint(dest)->size);
+}
+
+void _internal_array_copyin(object * array, int32_t index, object * val)
+{
+	t_Array * arr = (t_Array *)array;
+	memcpy(((char *)array) + sizeof(t_Array) + arr->payload.Eltype->bp->size * index, ((char *)val) + sizeof(object), arr->payload.Eltype->bp->size);
+}
+
+object * _internal_array_getboxed(object * array, int32_t index)
+{
+	object * ret;
+	object ** intarr = (object *)(((char *) array) + sizeof(t_Array));
+	ret = add_ref(intarr[index]);
+	release_ref(array);
+	return ret;
+}
+
+void _internal_array_setboxed(object *array, int32_t index, object * val)
+{
+	object ** intarr = (object *)(((char *) array) + sizeof(t_Array));
+	intarr[index] = val;
+}
+
+object *_internal_array_allocboxed(int32_t size)
+{
+	t_Array * ret = (t_Array *)new_multisize(TYPE_ARRAY, sizeof(nt_Array)+sizeof(object *)*size);
+	ret->payload.Length = 0;
+	ret->payload.Storage = size;
+	ret->payload.Eltype = (t_Blueprint *)make_Blueprint(0);
+	
+	return ret;
+}
+
+object * _internal_array_allocnaked(int32_t size , object * type)
+{
+	t_Array * ret;
+	t_Blueprint * bp = (t_Blueprint *)type;
+	if (bp->bp->size < 0) {
+		return _internal_array_allocboxed(size);
+	}	
+	ret = (t_Array *)new_multisize(TYPE_ARRAY, sizeof(nt_Array)+bp->bp->size*size);
+	ret->payload.Length = 0;
+	ret->payload.Storage = size;
+	ret->payload.Eltype = bp;
+	
+	return ret;
+}
 
--- a/runtime/array.h	Tue Mar 02 00:18:49 2010 -0500
+++ b/runtime/array.h	Thu Apr 08 01:02:18 2010 -0400
@@ -3,12 +3,14 @@
 
 #include "object.h"
 #include "func.h"
-#include "builtin.h"
+#include "builtin.h"	
 
-MOBegin
-	blueprint *contents_type;
-	int32     numels;
-Object(Array)
+void _internal_array_copyout(object * array, int32_t index, object * dest);
+void _internal_array_copyin(object * array, int32_t index, object * val);
+object * _internal_array_getboxed(object * array, int32_t index);
+void _internal_array_setboxed(object *, int32_t index, object * val);
+object *_internal_array_allocboxed(int32_t size);
+object * _internal_array_allocnaked(int32_t size , object * type);
 
 
-#endif //_ARRAY_H_
\ No newline at end of file
+#endif //_ARRAY_H_
--- a/runtime/block_alloc.h	Tue Mar 02 00:18:49 2010 -0500
+++ b/runtime/block_alloc.h	Thu Apr 08 01:02:18 2010 -0400
@@ -9,7 +9,7 @@
 #define block_free(block,size) VirtualFree(block, size, MEM_RELEASE)
 
 #else
-#define BLOCK_SIZE 1024*8
+#define BLOCK_SIZE 1024*4
 #include <sys/mman.h>
 
 #define block_alloc(size)      mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)
--- a/runtime/blueprint.c	Tue Mar 02 00:18:49 2010 -0500
+++ b/runtime/blueprint.c	Thu Apr 08 01:02:18 2010 -0400
@@ -1,6 +1,7 @@
 #include "blueprint.h"
 #include "builtin.h"
-#include "context.h"
+#include "context.h"
+#include <stddef.h>
 
 typedef struct
 {
@@ -18,6 +19,18 @@
 	release_ref(cdata->params[0]);
 	
 	Ret(0, new_object_bp(locals->bp))
+EndFunc
+
+Func(BlueprintSP_Of,
+	NumParams 1,
+	CallSpace 1,
+	l_Build)
+	
+	locals->bp = get_blueprint(cdata->params[0]);
+	release_ref(cdata->params[0]);
+	
+	Ret(0, new_object(TYPE_BLUEPRINT))
+	((t_Blueprint *)cdata->params[0])->bp = locals->bp;
 EndFunc
 
 object * make_Blueprint(int32_t type_id)
@@ -25,6 +38,15 @@
 	t_Blueprint * obj;
 	object * ret = new_object(TYPE_BLUEPRINT);
 	obj = (t_Blueprint *)ret;
-	obj->bp = get_blueprint_byid(type_id);
+	obj->bp = type_id ? get_blueprint_byid(type_id) : NULL;
 	return ret;
-}
+}
+
+int32_t _internal_blueprint_eq(object * left, object * right)
+{
+	t_Blueprint * l = (t_Blueprint *)left;
+	t_Blueprint * r = (t_Blueprint *)right;
+	return l->bp == r->bp;
+}
+
+
--- a/runtime/blueprint.h	Tue Mar 02 00:18:49 2010 -0500
+++ b/runtime/blueprint.h	Thu Apr 08 01:02:18 2010 -0400
@@ -7,6 +7,8 @@
 Box(blueprint *,bp,Blueprint)
 
 object * make_Blueprint(int32_t type_id);
-FuncDef(Build)
+FuncDef(Build)
+FuncDef(BlueprintSP_Of)
+int32_t _internal_blueprint_eq(object * left, object * right);
 
 #endif //BLUEPRINT_H_
--- a/runtime/fixed_alloc.c	Tue Mar 02 00:18:49 2010 -0500
+++ b/runtime/fixed_alloc.c	Thu Apr 08 01:02:18 2010 -0400
@@ -36,11 +36,13 @@
 		if(block)
 		{
 			--manager->freecount;
-			manager->freelist = block->next;
+			manager->freelist = block->next;
+			memset(block, 0xCD, BLOCK_SIZE);
 		}
 		else
 		{
-			block = block_alloc(BLOCK_SIZE);
+			block = block_alloc(BLOCK_SIZE);
+			memset(block, 0xAB, BLOCK_SIZE);
 		}
 		manager->inuse[bucket] = block;
 		block->next = NULL;
@@ -79,7 +81,6 @@
 			block->next->last = block->last;
 	}
 	i = i*8+bit;
-	//printf("%X\n", ((char *)block)+BLOCK_SIZE-((i+1)*size));
 	return (void *)(((char *)block)+BLOCK_SIZE-((i+1)*size));
 }
 
@@ -93,7 +94,8 @@
 		return;
 	}
 	//puts("ffree");
-	size = ADJUST_SIZE(size);
+	size = ADJUST_SIZE(size);
+	memset(ptr, 0xEF, size);
 	block = GET_BLOCK(ptr);
 	i = (((((char *)block) + BLOCK_SIZE) - ((char *)ptr))/size)-1;
 	bit = i & 0x7;
@@ -119,8 +121,10 @@
 			manager->inuse[bucket] = block->next;
 		if(block->next)
 			block->next->last = block->last;
-		if(manager->freecount == MAX_FREE)
-			block_free(block, BLOCK_SIZE);
+		if(manager->freecount == MAX_FREE)
+		{
+			block_free(block, BLOCK_SIZE);
+		}
 		else
 		{
 			block->next = manager->freelist;
--- a/runtime/object.c	Tue Mar 02 00:18:49 2010 -0500
+++ b/runtime/object.c	Thu Apr 08 01:02:18 2010 -0400
@@ -293,10 +293,10 @@
 	blueprint * bp = get_blueprint(obj);
 	if(bp->cleanup)
 		bp->cleanup(obj);
-	ffree(multi, sizeof(multi) + multi->size, manager);
+	ffree(multi, sizeof(multisize) + multi->size, manager);
 }
 
-blueprint * new_blueprint(uint32_t type, uint32_t size, special_func init, special_func copy, special_func cleanup)
+blueprint * new_blueprint(uint32_t type, int32_t size, special_func init, special_func copy, special_func cleanup)
 {
 	blueprint * bp = malloc(sizeof(blueprint));
 	//dirty hack!, move elsewhere
@@ -320,7 +320,7 @@
 	return bp;
 }
 
-blueprint * register_type_byid(uint32_t type, uint32_t size, special_func init, special_func copy, special_func cleanup)
+blueprint * register_type_byid(uint32_t type, int32_t size, special_func init, special_func copy, special_func cleanup)
 {
 	check_type_storage(type);
 	if(registered_types[type])
--- a/runtime/object.h	Tue Mar 02 00:18:49 2010 -0500
+++ b/runtime/object.h	Thu Apr 08 01:02:18 2010 -0400
@@ -26,8 +26,8 @@
 	uint32_t       last_convertto;
 	uint32_t       first_convertfrom;
 	uint32_t       last_convertfrom;
-	uint32_t       size;
-	uint32_t       boxed_size;
+	int32_t       size;
+	int32_t       boxed_size;
 } blueprint;
 
 typedef struct object {
@@ -53,10 +53,9 @@
 } calldata;
 
 #define OBegin typedef struct {
-#define Object(name) } nt_ ## name; typedef struct { object _SP_header; nt_ ## name payload; } t_ ## name;
-#define Box(nakedtype,fieldname,objectname) typedef struct{ object _SP_header; nakedtype fieldname; } t_ ## objectname;
-
-#define MOBegin typedef struct { multisize header;
+#define Object(name) } nt_ ## name; typedef struct { object SP_header; nt_ ## name payload; } t_ ## name;
+#define MObject(name) } nt_ ## name; typedef struct { multisize SP_header; nt_ ## name payload; } t_ ## name; 
+#define Box(nakedtype,fieldname,objectname) typedef struct{ object SP_header; nakedtype fieldname; } t_ ## objectname;
 
 #define get_blueprint(object) (object)->bprint
 
@@ -71,8 +70,8 @@
 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);
-blueprint * new_blueprint(uint32_t type, uint32_t size, special_func init, special_func copy, special_func cleanup);
+blueprint * register_type_byid(uint32_t type, int32_t size, special_func init, special_func copy, special_func cleanup);
+blueprint * new_blueprint(uint32_t type, int32_t size, special_func init, special_func copy, special_func cleanup);
 void add_method(blueprint * bp, uint32_t methodid, rhope_func impl);
 void add_getter(blueprint * bp, uint32_t fieldid, rhope_func impl);
 void add_setter(blueprint * bp, uint32_t fieldid, rhope_func impl);