view cbackend_c.rhope @ 142:7bbdc034e347

Fix some bugs. Get basic network code working (epoll listener + accept connections). Start porting webserver.
author Mike Pavone <pavone@retrodev.com>
date Sun, 21 Nov 2010 16:33:17 -0500
parents f2cb85c53ced
children f3686f60985d
line wrap: on
line source

Import backendutils_c.rhope

Blueprint C Method Registry
{
	Lookup
	Next ID
}

C Method Registry[:out]
{
	builtins <- [[[[[[[[[[[[[Dictionary[]
		]Set["+", "METHOD_ADD"]
		]Set["-", "METHOD_SUB"]
		]Set["/", "METHOD_DIV"]
		]Set["*", "METHOD_MUL"]
		]Set["LShift", "METHOD_LSHIFT"]
		]Set["RShift", "METHOD_RSHIFT"]
		]Set["=", "METHOD_EQUALS"]
		]Set[">", "METHOD_GREATER"]
		]Set["<", "METHOD_LESS"]
		]Set["If", "METHOD_IF"]
		]Set["Set Missing Field", "METHOD_SETFIELDMISSING"]
		]Set["Get Missing Field", "METHOD_GETFIELDMISSING"]
		]Set["Missing Method", "METHOD_MISSING"]
	out <- [[Build[C Method Registry()]]Lookup <<[builtins]]Next ID<<[0]

}

Register Method@C Method Registry[reg,method:out]
{
	[[reg]Lookup >>]Index[method]
	{
		out <- reg
	}{
		method ID <- [reg]Next ID>>
		new lookup <- [[reg]Lookup >>]Set[method, ["METHOD_FIRST_USER+"]Append[String[method ID]]]
		out <- [[reg]Lookup <<[new lookup]]Next ID <<[[method ID]+[1]]
	}
}

Method ID@C Method Registry[reg,method:out,notfound]
{
	out,notfound <- [[reg]Lookup >>]Index[method]
}

Blueprint C Field Registry
{
	Lookup
	Next ID
}

C Field Registry[:out]
{
	out <- [[Build[C Field Registry()]]Lookup <<[Dictionary[]]]Next ID<<[1]

}

Register Field@C Field Registry[reg,field:out]
{
	[[reg]Lookup >>]Index[field]
	{
		out <- reg
	}{
		field ID <- [reg]Next ID>>
		new lookup <- [[reg]Lookup >>]Set[field, field ID]
		out <- [[reg]Lookup <<[new lookup]]Next ID <<[[field ID]+[1]]
	}
}

Field ID@C Field Registry[reg,field:out,notfound]
{
	out,notfound <- [[reg]Lookup >>]Index[field]
}

Blueprint C Type
{
	Name
	Fields
	Methods
	Init
	Copy
	Cleanup
	
}

C Type[name:out]
{
	out <- [[[[[[Build[C Type()]]Name <<[name]]Fields <<[()]]Methods <<[()]]Init <<["NULL"]]Copy <<["NULL"]]Cleanup <<["NULL"]
}

Add Field@C Type[ctype,name,type:out]
{
	out <- [ctype]Fields <<[ [[ctype]Fields >>]Append[ [[()]Append[name]]Append[type] ] ]
}

Add Method@C Type[ctype,name:out]
{
	out <- [ctype]Methods <<[ [[ctype]Methods >>]Append[name] ]
}

Register Methods@C Type[ctype,method reg:out]
{
	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 C[?], field reg, [ctype]Fields >>]
}

Rhope Type to C[type,p:out,array]
{
	If[[Blueprint Of[type]]=[Type Instance()]]
	{
		variant <- [type]Variant >>
		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]
				{ param,param <- [pre param]Set Variant[~] }
				{ param <- Val[pre param] }
				child type <- Rhope Type to C[param]
				If[[variant] = ["Naked"]]
				{
					out <- Val[child type]
					array <- "[1]"
				}{
					out <- [child type]Append[" *"]
					array <- ""
				} */
				out <- "void *"
				array <- ""
			}{
				typename <- "Array"
			}
			primitive <- No
		}{	
			,regulartype <- [("Naked","Raw Pointer")]Find[=[variant,?]]
			{
				[("Int64","Int32","Int16","Int8")]Find[=[[type]Name >>,?]]
				{
					primitive <- Yes
					[[type]Name >>]Slice[3] {}
					{ typename <- [["int"]Append[~]]Append["_t"] }
				}{
					[("UInt64","UInt32","UInt16","UInt8")]Find[=[[type]Name >>,?]]
					{
						primitive <- Yes
						[[type]Name >>]Slice[4] {}
						{ typename <- [["uint"]Append[~]]Append["_t"] }
					}{
						,regulartype <- If[[[type]Name >>]=["Context"]]
						{
							typename <- "context *"
							primitive <- Yes
						}
					}
				}
			}
			
			Val[regulartype]
			{
				typename <- [type]Name >>
				primitive <- No
			}
		}
	}{
		typename <- type
		param <- "Any Type"
		variant <- "boxed"
		primitive <- No
	}
	
	Val[typename]
	{ array <- "" }
	If[[typename] = ["Any Type"]]
	{
		out <- "struct object *"
	}{
		[("Naked","Raw Pointer")]Find[=[variant,?]]
		{
			If[primitive]
			{
				prefix <- ""
			}{
				prefix <- "nt_"
			}
		}{
			prefix <- "t_"
		}
		
		If[[variant]=["Naked"]]
		{
			postfix <- ""
		}{
			postfix <- " *"
		}
	}
	If[primitive]
	{
		escaped <- Val[typename]	
	}{
		escaped <- Escape Rhope Name[typename,p]
	}
	out <- [[prefix]Append[escaped]]Append[postfix]
}

_Type Def C Type[text,field,p:out]
{
	name <- [field]Index[0]
	,postfix <- Rhope Type to C[[field]Index[1],p]
	{ type <- ["\n\t"]Append[~] }
	
	out <- [[[[text]Append[type]]Append[" "]]Append[[Escape Rhope Name[name,p]]Append[postfix]]]Append[";"]
}

Type Def@C Type[ctype,p:out]
{
	If[[[[ctype]Fields >>]Length] = [1]]
	{
		out <- [[[[_Type Def C Type["typedef struct {\n\tobject _SP_header;\n\t", [[ctype]Fields >>]Index[0], p]]Append["\n} t_"]]Append[Escape Rhope Name[[ctype]Name >>,p]]]Append[";"]
					]Append[ 
						[[[["typedef "
							]Append[Rhope Type to C[ [[[ctype]Fields >>]Index[0]]Index[1],p ]]
							]Append[" nt_"]
							]Append[Escape Rhope Name[[ctype]Name >>,p]]
							]Append[";"] ]
	}{
		//HACK!!!
		If[[[ctype]Name >>]=["Blueprint"]]
		{
			out <- ""	
		}{
			[("Array","Boxed Array","Worker")]Find[=[[ctype]Name >>,?]]
			{ oend <- "\nMObject(" }
			{ oend <- "\nObject(" } 
			out <- [Fold[_Type Def C Type[?,?,p], "OBegin", [ctype]Fields >>]]Append[ [[oend]Append[Escape Rhope Name[[ctype]Name >>,p]]]Append[")"] ]
		}
	}
}

_Global Type Defs C[text,store,p:out]
{
	estore <- Escape Rhope Name[[store]Name >>, p]
	varnames <- Map[Keys[[store]Vars >>], Escape Rhope Name[?, p]]
	out <- [text]Append[ 
		[[[[[[[[["typedef struct {\n\tobject header;\n\t"
			]Append[ [[ Map[varnames, ["object * gs_"]Append[?]] ]Join[";\n\t"]
				]Append[";\n} mutt_"]]
			]Append[estore]
			]Append[[[";\nmutable_object * gs_"]Append[estore]]Append[";\n\n"]]
			]Append[[["void gscopy_"]Append[estore]]Append[[["(object * obj)\n{\n\tmutt_"]Append[estore]]Append[[[" *mutt_obj = (mutt_"]Append[estore]]Append[" *)obj;\n\t"]]]]
			]Append[ [Map[varnames, ["add_ref(mutt_obj->gs_"]Append[?]]]Join[");\n\t"] ]
			]Append[");\n}\n\n"]
			]Append[[["void gscleanup_"]Append[estore]]Append[[["(object * obj)\n{\n\tmutt_"]Append[estore]]Append[[[" *mutt_obj = (mutt_"]Append[estore]]Append[" *)obj;\n\t"]]]]
			]Append[ [Map[varnames, ["release_ref(mutt_obj->gs_"]Append[?]]]Join[");\n\t"] ]
			]Append[");\n}\n\n"] ]
}

_Global Type Inits C[text,store,p:out]
{
	estore <- Escape Rhope Name[[store]Name >>, p]
	out <- [text]Append[ [[[[[[[[["\tbp = register_type(sizeof(mutt_"]Append[estore]]Append[ [[[")-sizeof(object), NULL, gscopy_"]Append[estore]]Append[", gscleanup_"]]Append[estore] ]]Append[");\n\tgs_"]]Append[estore]]Append[" = (mutable_object *)new_object(TYPE_MUTABLEGLOBAL);\n\tgs_"]]Append[estore]]Append["->data = new_object_bp(bp);\n\tgs_"]]Append[estore]]Append["->version = 0;"] ]
}

_Type Init C[type name,method reg,text,method,p:out]
{
	out <- [[text]Append[[["\n\tadd_method(bp, "]Append[ [method reg]Method ID[method] ]]Append[  [[", MethodName("]Append[Escape Rhope Name[method,p]]]Append[[","]Append[Escape Rhope Name[type name,p]]]]]]Append["));"]
}

_Type Init C Field[type name,field reg,text,field,p:out]
{
	fname <- [field]Index[0]
	out <- [[[[text]Append[[["\n\tadd_getter(bp, "]Append[ String[[field reg]Field ID[fname]] ]]Append[  [[", MethodName("]Append[Escape Rhope Name[[fname]Append[" >>"],p]]]Append[[","]Append[Escape Rhope Name[type name,p]]]]]]Append["));"]
		]Append[[["\n\tadd_setter(bp, "]Append[ String[[field reg]Field ID[fname]] ]]Append[  [[", MethodName("]Append[Escape Rhope Name[[fname]Append[" <<"],p]]]Append[[","]Append[Escape Rhope Name[type name,p]]]]]]Append["));"]
}

Type Init@C Type[ctype,id,method reg,field reg,p:out]
{
	[("Array","Boxed Array", "Worker")]Find[=[[ctype]Name >>, ?]]
	{ 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 >>,p]] }
				}
			}
		}
		size <- [["sizeof("]Append[typename]]Append[")"] 
	}
	start <- [["\tbp = register_type_byid("
		]Append[id]
		]Append[
			[[", "]Append[size]
			]Append[
				[", (special_func)"]Append[
					[ 
						[[[[Escape Rhope Name[[ctype]Init >>,p]
						]Append[", (special_func)"]
						]Append[Escape Rhope Name[[ctype]Copy >> ,p]]
						]Append[", (special_func)"]
						]Append[Escape Rhope Name[[ctype]Cleanup >>,p]]         
					]Append[");"]]] ]
	out <- Val[start]//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
{
	Lookup
	Definitions
	Next ID
	Escape Pattern
}

C Type Registry[p:out]
{
	out <- [[[[Build[C Type Registry()]]Lookup << [
			[[[[[[[[[[[[[[[[[[[Dictionary[]
			]Set["UInt8", "TYPE_UINT8"]			//1
			]Set["UInt16", "TYPE_UINT16"]		//2
			]Set["UInt32", "TYPE_UINT32"]		//3
			]Set["UInt64", "TYPE_UINT64"]		//4
			]Set["Int8", "TYPE_INT8"]			//5
			]Set["Int16", "TYPE_INT16"]			//6
			]Set["Int32", "TYPE_INT32"]			//7
			]Set["Int64", "TYPE_INT64"]			//8
			]Set["Boolean", "TYPE_BOOLEAN"]		//9
			]Set["Float32", "TYPE_FLOAT32"]		//10
			]Set["Float64", "TYPE_FLOAT64"]		//11
			]Set["Real Number", "TYPE_FLOAT64"]
			]Set["Blueprint", "TYPE_BLUEPRINT"]	//12
			]Set["Array", "TYPE_ARRAY"]			//13
			]Set["Boxed Array", "TYPE_BOXEDARRAY"]//14
			]Set["Worker", "TYPE_WORKER"]			//15
			]Set["Method Missing Exception", "TYPE_METHODMISSINGEXCEPTION"]	//16
			]Set["Field Missing Exception", "TYPE_FIELDMISSINGEXCEPTION"]	//17
			]Set["Wrong Type Exception", "TYPE_WRONGTYPEEXCEPTION"]]		//18
		]Definitions << [Dictionary[]]
		]Next ID <<[0]
		]Escape Pattern <<[p]
}

_Type Defs C[text,def,p:out]
{
	out <- [[text]Append[[def]Type Def[p]]]Append["\n\n"]
}

Type Defs@C Type Registry[reg:out]
{
	out <- Fold[_Type Defs C[?,?,[reg]Escape Pattern >>], "", [reg]Definitions >>]
}

_Type Inits C[reg,method reg,field reg,text,def,name:out]
{
	out <- [[text]Append[ [def]Type Init[[reg]Type ID[name], method reg, field reg,[reg]Escape Pattern >>] ]]Append["\n\n"]
}

Type Inits@C Type Registry[reg,method reg,field reg:out]
{
	out <- Fold[_Type Inits C[reg, method reg, field reg, ?], "", [reg]Definitions >>]
}

Register Type@C Type Registry[reg,def:out]
{
	name <- [def]Name >>
	[[reg]Lookup >>]Index[name]
	{
		[[reg]Definitions >>]Index[name]
		{
			out <- reg
		}{
			out <- [reg]Definitions <<[[[reg]Definitions >>]Set[name, def]]
		}
	}{
		out <- [[[reg]Lookup <<[ [[reg]Lookup >>]Set[name, ["TYPE_FIRST_USER+"]Append[String[[reg]Next ID >>]]] ]
			]Definitions <<[ [[reg]Definitions >>]Set[name, def] ]
			]Next ID <<[ [[reg]Next ID >>]+[1] ]
	}
}

Type ID@C Type Registry[reg,name:out,notfound]
{
	out <- [[reg]Lookup >>]Index[name] {}
	{
		,notfound <- If[[name]=["Any Type"]]
		{ out <- "0" }
	}
}

Simple Type?@C Type Registry[reg,name:yep,nope,notfound]
{
	,notfound <- [[reg]Definitions >>]Index[name]
	{
		yep,nope <- If[[[[~]Fields >>]Length] = [1]]
	}
}

Defined?@C Type Registry[reg,name:yep,nope]
{
	yep,nope <- [[reg]Definitions >>]Index[name]
}

Blueprint C Function
{
	Name
	Inputs
	Outputs
	Convention
	Variables
	Statements
	Method Registry
	Field Registry
	Type Registry
	Constants
	Input Types
	Output Types
	Uses
	Resume Index
	Last NumParams
	Escape Pattern
}

C Function[name,inputs,outputs,convention,p:out]
{
	out <- C Function With Registry[name,inputs,outputs,convention, C Method Registry[], C Field Registry[], C Type Registry[p],p]
}

C Function With Registry[name,inputs,outputs,convention,registry,field reg,type reg,p:out]
{
	out <- [[[[[[[[[[[[[[[[Build[C Function()]
		]Name <<[name]
		]Inputs <<[inputs]
		]Outputs <<[outputs]
		]Convention <<[convention]
		]Variables <<[Dictionary[]]
		]Statements <<[()]
		]Method Registry <<[registry]
		]Field Registry <<[field reg]
		]Type Registry <<[type reg]
		]Constants <<[Dictionary[]]
		]Input Types <<[ Fold[Append[?, "Any Type"], (), inputs] ]
		]Output Types <<[ Fold[Append[?, "Any Type"], (), outputs] ]
		]Resume Index <<[1]
		]Last NumParams <<[-1]
		]Escape Pattern <<[p]
		]Uses <<[()]
}

Set Input Type@C Function[func,type,input num:out]
{
	out <- [func]Input Types <<[ [[func]Input Types >>]Set[input num, type] ]
}

Set Output Type@C Function[func,type,output num:out]
{
	out <- [func]Output Types <<[ [[func]Output Types >>]Set[output num, type] ]
}

Register Constant@C Function[func,name,constant:out]
{
	out <- [func]Constants <<[ [[func]Constants >>]Set[name, constant] ]
}

Allocate Var@C Function[func,name,type:out]
{
	out <- [func]Variables <<[ [[func]Variables >>]Set[name,type] ]
}

Add Statement@C Function[func,statement:out]
{
	out <- [func]Statements <<[ [[func]Statements >>]Append[["\t"]Append[[statement]Append[";\n"]]] ]
}

Add Raw Line@C Function[func,line:out]
{
	out <- [func]Statements <<[ [[func]Statements >>]Append[["\t"]Append[[line]Append["\n"]]] ]
}

Add Operator Statement@C Function[func,psource1,psource2,pdest,op:out]
{
	source1 <- [psource1]Make Op[func]
	source2 <- [psource2]Make Op[func]
	dest <- [pdest]Make Op[func]
	out <- [func]Add Statement[[[[[dest]Append[" = "]]Append[source1]]Append[op]]Append[source2]]
}

Make AddRef Op@C Function[func,val:out]
{
	out <- [["add_ref((object *)"]Append[ [val]Make Op[func] ]]Append[")"]
}

Add@C Function[func,source1,source2,dest:out]
{
	out <- [func]Add Operator Statement[source1,source2,dest," + "]
}

Sub@C Function[func,source1,source2,dest:out]
{
	out <- [func]Add Operator Statement[source1,source2,dest," - "]
}

Multiply@C Function[func,source1,source2,dest:out]
{
	out <- [func]Add Operator Statement[source1,source2,dest," * "]
}

Divide@C Function[func,source1,source2,dest:out]
{
	out <- [func]Add Operator Statement[source1,source2,dest," / "]
}

DoLShift@C Function[func,source1,source2,dest:out]
{
	out <- [func]Add Operator Statement[source1,source2,dest," << "]
}

DoRShift@C Function[func,source1,source2,dest:out]
{
	out <- [func]Add Operator Statement[source1,source2,dest," >> "]
}

BitAnd@C Function[func,source1,source2,dest:out]
{
	out <- [func]Add Operator Statement[source1,source2,dest," & "]
}

BitOr@C Function[func,source1,source2,dest:out]
{
	out <- [func]Add Operator Statement[source1,source2,dest," | "]
}

CompLess@C Function[func,source1,source2,dest:out]
{
	out <- [func]Add Operator Statement[source1,source2,dest," < "]
}

CompGreater@C Function[func,source1,source2,dest:out]
{
	out <- [func]Add Operator Statement[source1,source2,dest," > "]
}

CompEqual@C Function[func,source1,source2,dest:out]
{
	out <- [func]Add Operator Statement[source1,source2,dest," == "]
}

CompLessEqual@C Function[func,source1,source2,dest:out]
{
	out <- [func]Add Operator Statement[source1,source2,dest," <= "]
}

CompGreaterEqual@C Function[func,source1,source2,dest:out]
{
	out <- [func]Add Operator Statement[source1,source2,dest," >= "]
}

CompNotEqual@C Function[func,source1,source2,dest:out]
{
	out <- [func]Add Operator Statement[source1,source2,dest," != "]
}

Move@C Function[func,psource,pdest:out]
{
	source <- [psource]Make Op[func]
	dest <- [pdest]Make Op[func]
	out <- [func]Add Statement[[[dest]Append[" = "]]Append[source]]
}

Do AddRef@C Function[func,psource,pdest:out]
{
    source <- [psource]Make Op[func] 
    dest <- [pdest]Make Op[func]
    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((object *)"]Append[source]]Append[")"]]
}

Release@C Function[func,psource:out]
{
	source <- [psource]Make Op[func]
	out <- [func]Add Statement[[["release_ref((object *)"]Append[source]]Append[")"]]
}

Set Null@C Function[func,pdest:out]
{
	dest <- [pdest]Make Op[func]
	out <- [func]Add Statement[[dest]Append[" = NULL"]]
}

Lookup Constant@C Function[func,const,doaddref:out]
{
	var <- ["_const_"]Append[Escape Rhope Name[const,[func]Escape Pattern >>]]
	If[doaddref]
	{
		out <- [["add_ref("]Append[var]]Append[")"]
	}{
		out <- Val[var]
	}
}

Field Result@C Function[func,var,field:out]
{
	as op <- [var]Make Op[func]
	[(String(),String Cat(),String Slice())]Find[=[Blueprint Of[var],?]]
	{
		[[func]Inputs >>]Find[=[var,?]]
		{
			type <- [[func]Input Types >>]Index[~]
			
		}{
			type <- [[func]Variables >>]Index[var] { Print["op refers to a var"] }
			{
				[[func]Outputs >>]Find[=[var,?]]
				{
					type <- [[func]Output Types >>]Index[~]
				}{
					//Does it make sense for us to do this?
					type <- Type Instance["Any Type"] 
				}
			}
		}
	}{
		type <- Type Instance["Any Type"] 
	}
	If[[[func]Convention >>] = ["rhope"]]
	{
		If[[type] = ["Any Type"]]
		{
			rvar <- Val[as op]
		}{
			rvar <- [[[["(("]Append[ Rhope Type to C[type,[func]Escape Pattern >>] ]]Append[")("]]Append[as op]]Append["))"]
		}
	}{
		rvar <- Val[as op]
	}

	[[func]Type Registry >>]Simple Type?[[type]Name >>]
	{ access <- "->" }
	{ access <- "->payload." }
	{ 
		//TODO: Generate some kind of error/exception in this case
		access <- "->" 
	}
	out <- [[rvar]Append[access]]Append[Escape Rhope Name[field,[func]Escape Pattern >>]]
}

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]
}

Global Reference@C Function[func,store,var:out]
{
	
	estore <- Escape Rhope Name[store,[func]Escape Pattern >>]
	out <- [[[[[ [["((mutt_"]Append[estore]]Append["*)lv_"]]Append[Escape Rhope Name[[func]Name >>,[func]Escape Pattern >>]]]Append["->gs_"]]Append[estore]]Append["->local_data)->gs_"]]Append[Escape Rhope Name[var,[func]Escape Pattern >>]]
}

Set Global@C Function[func,store,var,src:out]
{
	estore <- Escape Rhope Name[store,[func]Escape Pattern >>]
	cell pointer <- [[["lv_"]Append[Escape Rhope Name[[func]Name >>,[func]Escape Pattern >>]]]Append["->gs_"]]Append[estore]
	out <- [[[[func]Add Statement[[["tmp = copy_object("]Append[[cell pointer]Append["->local_data"]]]Append[")"]]
		]Add Statement[ [[[["((mutt_"]Append[estore]]Append[" *)tmp)->gs_"]]Append[Escape Rhope Name[var, [func]Escape Pattern >>]]]Append[[" = "]Append[[src]Make Op[func]]] ]
		]Add Statement[[cell pointer]Append["->local_data = tmp"]]
		]Add Statement[[cell pointer]Append["->local_version++"]]
}

Set Field Null@C Function[func,var,field:out]
{
	out <- [func]Add Statement[ [[func]Field Result[var,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[")"]] ]
}

Box@C Function[func,psource,pdest,type:out]
{
	dest <- [pdest]Make Op[func]
	source <- [psource]Make Op[func]
	out <- [func]Add Statement[ 
		[[[[[dest
		]Append[" = naked_to_boxed("]
		]Append[ [[func]Type Registry >>]Type ID[[type]Name >>] ]
		]Append[", &"]
		]Append[source]
		]Append[")"] ]
}

Unbox@C Function[func,psource,pdest:out]
{
	dest <- [pdest]Make Op[func]
	source <- [psource]Make Op[func]
	out <- [func]Add Statement[ 
		[[[["boxed_to_naked("
		]Append[source]
		]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[" = (void*)("]]Append[source]]Append[" + 1)"] ]
}

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]
{
	out <- [func]Add Raw Line[
		[[[["SetParam("
		]Append[String[inputnum]]
		]Append[", "]
		]Append[val]
		]Append[")"]
	]
}

_Val Function Arg C[func,val,inputnum,worker:out]
{
	out <- [func]Add Raw Line[
		[[[[[["VCSetParam("
		]Append[worker]
		]Append[", "]
		]Append[String[inputnum]]
		]Append[", "]
		]Append[val]
		]Append[")"]
	]
}

Method Call@C Function[func,method,args:out]
{
	out <- [func]Call[method,args]
}

Val Call@C Function[func,to call,args:out]
{
	worker <- Make Op[Strip Addref[to call], func]
	rargs <- Map[args, Make Op[?, func]]
	
	If[[[[func]Variables >>]Length]+[[[func]Outputs >>]Length]]
	{
		valcall <- "ValCall("
		postlude <- "ValCallPostlude("
	}{
		valcall <- "ValCallNoLocals("
		postlude <- "ValCallNoLocalsPostlude("
	}

	If[[[func]Last NumParams >>] = [-1]]
	{
		prepped <- [[func]Add Raw Line[ 
			[[[["VCPrepCall("
				]Append[worker]
				]Append[", "]
				]Append[String[[rargs]Length]]
				]Append[")"] ]
		]Last NumParams <<[[rargs]Length]
	}{
		prepped <- [[func]Add Raw Line[ 
			[[[[[["VCRePrepCall("
				]Append[worker]
				]Append[", "]
				]Append[String[[rargs]Length]]
				]Append[", "]
				]Append[String[[func]Last NumParams >>]]
				]Append[")"] ]
		]Last NumParams <<[[rargs]Length]
	}
	
	
	out <- [[[[Fold[_Val Function Arg C[?, ?, ?, worker], prepped, rargs]
	]Add Raw Line[
		[[[[[[[[valcall
		]Append[worker]
		]Append[", "]
		]Append[String[[rargs]Length]]
		]Append[", "]
		]Append[String[[func]Resume Index >>]]
		]Append[", "]
		]Append[Escape Rhope Name[[func]Name >>,[func]Escape Pattern >>]]
		]Append[")"]]
	]Add Raw Line["DISPATCH"]
	]Add Raw Line[
		[[[[postlude
		]Append[String[[func]Resume Index >>]]
		]Append[", "]
		]Append[Escape Rhope Name[[func]Name >>,[func]Escape Pattern >>]]
		]Append[")"]]
	]Resume Index <<[ [[func]Resume Index >>]+[1] ]
}

Call@C Function[func,name,args:out]
{
	If[[name]=["Call@Worker"]]
	{
		//TODO: Handle case when user explicitly calls the fully qualified version, but the type of the first arg isn't Worker
		out <- [func]Val Call[[args]Index[0], Tail[args,1]]
	}{
		If[[name]=["Call"]]
		{
			to call <- [args]Index[0]
			last numparams <- [func]Last NumParams >>
			out <- [[[[[[func]Add Raw Line[[["if (get_blueprint("]Append[Make Op[Strip Addref[to call], func]]]Append[")->type_id == TYPE_WORKER) {"]]
			]Val Call[to call, Tail[args,1]]
			]Add Raw Line["} else {"]
			]Last NumParams <<[last numparams]
			]Func Base["Call",args, "Call"]
			]Add Raw Line["}"]
		}{
			out <- [func]Func Base[Escape Rhope Name[name,[func]Escape Pattern >>],args, "Call"]
		}
	}
}

Func Base@C Function[func,tocall,args,rtype:out]
{
	Print[ [[func]Name >>]Append[ [": Func Base("]Append[tocall] ] ]
	rargs <- Map[args, Make Op[?, func]]
	
	If[[[[func]Variables >>]Length]+[[[func]Outputs >>]Length]]
	{ type <- Val[rtype] }
	{ type <- [rtype]Append["NoLocals"] }

	If[[[rargs]Length] > [[func]Last NumParams >>]]
	{	
		If[[[func]Last NumParams >>] = [-1]]
		{
			freed <- Val[func]
		}{
			freed <- [func]Add Raw Line["FreeCall"]
		}
		prepped <- [[freed]Add Raw Line[ [["PrepCall("]Append[String[[rargs]Length]]]Append[")"] ]
		]Last NumParams <<[[rargs]Length]
	}{
		prepped <- Val[func]
	}
	
	
	out <- [[Fold[_Function Arg C[?], prepped, rargs]
	]Add Raw Line[
		[[[[[[[[[type]Append["("]
		]Append[tocall]
		]Append[", "]
		]Append[String[[rargs]Length]]
		]Append[", "]
		]Append[String[[func]Resume Index >>]]
		]Append[", "]
		]Append[Escape Rhope Name[[func]Name >>,[func]Escape Pattern >>]]
		]Append[")"]]
	]Resume Index <<[ [[func]Resume Index >>]+[1] ]
}

Call Foreign@C Function[func,name,language,args,store result:out]
{
	rargs <- Map[args, Make Op[?, func]]
	//Assume language = "C" for now
	base <- [[[name]Append["("]]Append[ Join[rargs, ", "] ]]Append[")"]
	,do store <- [(String(), String Slice(), String Cat())]Find[=[Blueprint Of[store result], ?]]
	{ 
		,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]
}

Get Field Call@C Function[func,field,source:out]
{
	out <- [func]Func Base[Escape Rhope Name[[field]Append[" >>"],[func]Escape Pattern >>], [()]Append[source], "Call"]
}

Set Field Call@C Function[func,field,object,value:out]
{
	out <- [func]Func Base[Escape Rhope Name[[field]Append[" <<"],[func]Escape Pattern >>], [[()]Append[object]]Append[value], "Call"]
}

Tail Method Call@C Function[func,method,args:out]
{
	out <- [func]Func Base[[[func]Method Registry >>]Method ID[method],args, "TMCall"]
}

Tail Call@C Function[func,name,args:out]
{
	out <- [func]Func Base[Escape Rhope Name[name,[func]Escape Pattern >>],args, "TCall"]
}

Resolve@C Function[func,op:out]
{
	If[[[func]Convention >>] = ["rhope"]]
	{
		[[func]Inputs >>]Find[=[op,?]]
		{
			out <- [["my_cdata->params["]Append[String[~]]]Append["	]"]
		}{
			out <- [[["lv_"]Append[Escape Rhope Name[[func]Name >>,[func]Escape Pattern >>]]]Append["->"]]Append[Escape Rhope Name[op,[func]Escape Pattern >>]]
		}
	}{
		out <- Escape Rhope Name[op,[func]Escape Pattern >>]
	}
}

Resolve Output@C Function[func,name:out]
{
	If[[[func]Convention >>] = ["rhope"]]
	{
		out <- [[["lv_"]Append[Escape Rhope Name[[func]Name >>,[func]Escape Pattern >>]]]Append["->"]]Append[Escape Rhope Name[name,[func]Escape Pattern >>]]
	}{
		out <- Escape Rhope Name[name,[func]Escape Pattern >>]
	} 
}

Instruction Stream@C Function[func:out]
{
	out <- [func]Statements <<[()]
}

_If C[func, statement:out]
{
	out <- [func]Statements <<[ [[func]Statements >>]Append[ ["\t"]Append[statement] ] ]
}

Do If@C Function[func,condition,stream:out]
{
	cond <- [condition]Make Op[func]
	out <- [[Fold[_If C[?], [[func
		]Add Raw Line[ [["if("]Append[cond]]Append[")"] ]
		]Add Raw Line["{"], [stream]Statements >>]
		]Add Raw Line["}"]
		]Resume Index <<[[stream]Resume Index >>]

}

Discard Outputs@C Function[func,first to discard:out]
{
	out <- [[[[[func
		]Add Raw Line[[["for(idx = "]Append[String[first to discard]]]Append["; idx < cdata->num_params; ++idx)"]]
		]Add Raw Line["{"]
		]Add Raw Line["	if (cdata->params[idx])"]
		]Add Raw Line["		release_ref(cdata->params[idx]);"]
		]Add Raw Line["}"]
}

Result Reference@C Function[func,output:out]
{
	out <- [["cdata->params["]Append[String[output]]]Append["]"]
}

Checked Result Reference@C Function[func,output:out]
{
	out <- [[[["("]Append[String[output]]]Append[" < cdata->num_params ? cdata->params["]]Append[String[output]]]Append["] : NULL)"]
}


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[check]
		]Append[" ? "]
		]Append[l]
		]Append[" : "]
		]Append[r]
		]Append[")"]
}

_Set Outputs C[string,inputname,inputnum,func:out]
{
	out <- [string]Append[[[ [ ["\tRet("]Append[String[inputnum]] ]Append[ [[", lv_"]Append[Escape Rhope Name[[func]Name >>,[func]Escape Pattern >>]]]Append["->"]]]Append[Escape Rhope Name[inputname,[func]Escape Pattern >>]]]Append[")\n"]]
}

Set Outputs@C Function[func:out]
{
	If[[[func]Convention >>] = ["rhope"]]
	{
		out <- [[[Fold[_Set Outputs C[?, ?, ?, func], "", [func]Outputs >>]]Append["\tNumRet("]]Append[String[[[func]Outputs >>]Length]]]Append[")\n"]
	}{
		[[func]Outputs >>]Index[0]
		{
			out <- [["\treturn "]Append[Escape Rhope Name[~,[func]Escape Pattern >>]]]Append[";\n"]
		}{
			out <- ""
		}
	}
}
_Output Defs C[string,varname,index,func:out]
{
	out <- [[[string]Append[ ["\t"]Append[Rhope Type to C[[[func]Output Types >>]Index[index],[func]Escape Pattern >>]] ]]Append[[" "]Append[Escape Rhope Name[varname,[func]Escape Pattern >>]]]]Append[";\n"]
}
_Var Defs C[string,type,varname,p:out]
{
	out <- [[[string]Append[ ["\t"]Append[Rhope Type to C[type,p]] ]]Append[[" "]Append[Escape Rhope Name[varname,p]]]]Append[";\n"]
}
_Global Cell Defs C[func,p,string,store:out]
{
	out <- [string]Append[ [["\ttrans_cell *gs_"]Append[Escape Rhope Name[store,p]]]Append[";\n"] ]
}


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[_Global Cell Defs C[func,[func]Escape Pattern >>,?], Fold[_Output Defs C[?, ?, ?, func], Fold[_Var Defs C[?,?,?,[func]Escape Pattern >>],"typedef struct {\n", [func]Variables >>], [func]Outputs >>], [func]Uses >>]]Append["} lt_"]]Append[Escape Rhope Name[[func]Name >>,[func]Escape Pattern >>]]]Append[";\n"]
	}{
		localtype <- ""
	}
	
	If[ [[func]Convention >>] = ["rhope"] ]
	{
		/* parts <- [[func]Name >>]Split["@"]
		[parts]Index[1]
		{
			proto <- [[[["MethodDef("
				]Append[Escape Rhope Name[[parts]Index[0],[func]Escape Pattern >>]]
				]Append[", "]
				]Append[Escape Rhope Name[~,[func]Escape Pattern >>]]
				]Append[")\n"]
		}{
			proto <- [["FuncDef("]Append[Escape Rhope Name[[func]Name >>,[func]Escape Pattern >>]]]Append[")\n"]
		} */
		out <- Val[localtype]
	}{
		out <- [[func]Naked Proto]Append[";\n"]
	}
	}
}

_Proto Input[list,input,index,types,p:out]
{
	out <- [list]Append[ [[Rhope Type to C[[types]Index[index],p]]Append[" "]]Append[Escape Rhope Name[input,p]] ]
}

Naked Proto@C Function[func:out]
{
	[[func]Output Types >>]Index[0]
	{
		outtype <- [Rhope Type to C[~,[func]Escape Pattern >>]]Append[" "]
	}{
		outtype <- "void "
	}
	out <- [[[[outtype
			]Append[ Escape Rhope Name[[func]Name >>,[func]Escape Pattern >>]]
			]Append["("]
			]Append[ [Fold[_Proto Input[?, ?, ?, [func]Input Types >>,[func]Escape Pattern >>], (), [func]Inputs >>]]Join[", "] ]
			]Append[")"]
}

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[")"] ] ]
	}
}

Check Param Type C[text,type,input num,func:out]
{
	[(String(),String Cat(),String Slice())]Find[=[Blueprint Of[type],?]]
	{
		typename <- type
	}{
		typename <- [type]Name >>
	}
	If[[typename] = ["Any Type"]]
	{
		out <- text
	}{
		out <- [text]Append[[[["\tParam("]Append[String[input num]]]Append[ [","]Append[ [[func]Type Registry >>]Type ID[typename] ] ]]Append[")\n"]]
	}
}

Find Trans Cell@C Function[func,text,store:out]
{
	estore <- Escape Rhope Name[store,[func]Escape Pattern >>]
	out <- [text]Append[  [[[["lv_"]Append[Escape Rhope Name[[func]Name >>,[func]Escape Pattern >>]]]Append["->gs_"]]Append[estore]]Append[[[" = find_obj_cell(ct->transaction, gs_"]Append[estore]]Append[");\n"]] ]
}

Text@C Function[func:out]
{	
	Print[["Text@C Function: "]Append[[func]Name >>]]
	If[ [[func]Convention >>] = ["rhope"] ]
	{
		before <- [[func]Name >>]Partition["@"] {} {}
		{
			type <- "MethodImpl"
			cname <- [[[[Escape Rhope Name[before,[func]Escape Pattern >>]
				]Append[", "]
				]Append[Escape Rhope Name[~,[func]Escape Pattern >>]]
				]Append[", "]
				]Append[ [[func]Type Registry >>]Type ID[~] ]
		}{
			type <- "Func"
			cname <- Val[fname]
		}
		fname <- Escape Rhope Name[[func]Name >>,[func]Escape Pattern >>]
		param check <- Fold[Check Param Type C[?, ?, ?, func], "", [func]Input Types >>]
		If[[[func]Last NumParams >>] = [-1]]
		{
			freecall <- ""
		}{
			freecall <- "\n\tFreeCall\n"
		}
		If[ [ [[[[func]Variables >>]Length]+[[[func]Outputs >>]Length]]+[[[func]Uses >>]Length] ] = [0] ]
		{
			out <- [[[[[[[[[ [type]Append["NoLocals("]
				]Append[cname]
				]Append[",\n\tNumParams "]
				]Append[ String[[[func]Inputs >>]Length] ]
				]Append[")\n\n"]
				]Append[param check]
				]Append[ [[func]Statements >>]Join[""] ]
				]Append[freecall]
				]Append["EndFuncNoLocals\n"]
				]Append["DISPATCH"]
		}{
			If[[[func]Uses >>]Length]
			{
				begin trans <- [[[["\tbegin_transaction(ct, "]Append[ String[[[func]Uses >>]Length] ]]Append[", "]]Append[ [Map[Map[[func]Uses >>, Escape Rhope Name[?, [func]Escape Pattern >>]], ["gs_"]Append[?]]]Join[", "] ]]Append[");\n"]
				init trans <- [[Fold[Find Trans Cell[func,?], begin trans, [func]Uses >>]
					]Append[[["transretry_"]Append[fname]]Append[":\n"]]
					]Append["\tfor(idx = 0; idx < cdata->num_params; ++idx) { add_ref(cdata->params[idx]); }\n"]
				//TODO: Figure out whether this is a readonly or write transaction
				commit trans <- [[["\tif(!commit_transaction(ct, 0)) { prep_retry(ct); goto transretry_"]Append[fname]]Append["; }\n"]
					]Append["\tfor(idx = 0; idx < cdata->num_params; ++idx) { release_ref(cdata->params[idx]); }\n"]
			}{
				init trans <- ""
				commit trans <- ""
			}
			out <- [[[[[[[[[[[[ [type]Append["("]
				]Append[cname]
				]Append[",\n\tNumParams "]
				]Append[ String[[[func]Inputs >>]Length] ]
				]Append[")\n\n"]
				]Append[param check]
				]Append[init trans]
				]Append[ [[func]Statements >>]Join[""] ]
				]Append[freecall]
				]Append[commit trans]
				]Append[[func]Set Outputs]
				]Append[[["EndFunc("]Append[fname]]Append[")\n"]]
				]Append["DISPATCH"]
		}
	}{
		
		out <- [[[
				Fold[_Output Defs C[?, ?, ?, func],
					Fold[_Var Defs C[?], [[func]Naked Proto]Append["\n{"], [func]Variables >>], [func]Outputs >>]
			]Append[[[func]Statements >>]Join[""]]
			]Append[[func]Set Outputs]
			]Append["}"]
	}
}

Blueprint C Program
{
	Functions
	Method Registry
	Field Registry
	Type Registry
	Libraries
	Global Stores
	Escape Pattern
}

C Program[:out]
{
	p <- Pattern[("_",  "@",  " ",  ":",  "?",  "+",  "-",  "*",  "/",  "<",  ">",  "(",  ")",  "!",  "=",  "'",  
			"\"", "\t", ",",  ".",  "\n", "{",  "}",   "[",   "]",   "#",   "\\",  "\r",  ";",   "&",   "|",   "%",   "^",   "`",   "~")]
	out <- [[[[[[[Build[C Program()]]Functions <<[Dictionary[]]]Method Registry <<[C Method Registry[]]]Type Registry <<[C Type Registry[p]]]Field Registry <<[C Field Registry[]]]Libraries <<[Dictionary[]]]Escape Pattern <<[p]]Global Stores <<[Dictionary[]]
}

Supported Number Types@C Program[program:out]
{
	out <- ("Int8","Int16","Int32","Int64","UInt8","UInt16","UInt32","UInt64")
}

Needed Specials@C Program[program,typename,makespecial:out]
{
	init name <- [" init "]Append[typename]
	with init <- [()]Append[ [[()]Append[init name]]Append[[makespecial]Index["init"]] ]
	[("Array","Boxed Array","Worker")]Find[=[?,typename]]
	{
		out <- Val[with init]
	}{
		copy name <- [" copy "]Append[typename]
		cleanup name <- [" cleanup "]Append[typename]
		out <- [[with init]Append[ [[()]Append[copy name]]Append[[makespecial]Index["copy"]] ]
			]Append[ [[()]Append[cleanup name]]Append[[makespecial]Index["cleanup"]] ]
	}
}

Set Stdlib Imports@C Program[program,parser:out]
{
	out <- [parser]Imports <<[ [[parser]Imports >>]Set["kernel.rhope", Yes] ]
}

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]
{
	out <- [[[program]Type Registry <<[ [[program]Type Registry >>]Register Type[def] ]
		]Method Registry <<[ [def]Register Methods[[program]Method Registry >>] ]
		]Field Registry <<[ [def]Register Fields[[program]Field Registry >>] ]
}

Create Type@C Program[program,name:out]
{
	out <- C Type[name]
}

Create Function@C Program[program,name,inputs,outputs,convention:out]
{
	out <- C Function With Registry[name,inputs,outputs,convention, [program]Method Registry >>, [program]Field Registry >>, [program]Type Registry >>, [program]Escape Pattern >>]
}

Store Function@C Program[program,func:out]
{
	out <- [program]Functions <<[ [[program]Functions >>]Set[ [func]Name >>, func] ]
}

Method?@C Program[program,funcname:is,isnot]
{
	is,isnot <- [[program]Method Registry >>]Method ID[funcname]
}

_Defs C Program[text,func:out]
{
	def <- [func]Definitions
	If[[def]=[""]]
	{
		out <- text
	}{
		out <- [text]Append[[def]Append["\n\n"]]
	}
}

_Text C Program[text,func,type reg:out]
{
	out <- [text]Append[[[ [func]Type Registry <<[type reg] ]Text]Append["\n\n"]]
}

Combine Consts[consts,func:out]
{
	out <- Combine[[func]Constants >>, consts]
}

_Consts C Program[text,value,name,p:out]
{
	out <- [text]Append[ [["object * _const_"]Append[Escape Rhope Name[name,p]]]Append[";\n"] ]
}

_Consts C Release[text,value,name,p:out]
{
	out <- [text]Append[ [["\trelease_ref(_const_"]Append[Escape Rhope Name[name,p]]]Append[");\n"] ]
}

_List Literal El[text,val,index,type reg:out]
{
	out <- [[[[text
		]Append[", "]
		]Append[index]
		]Append[", "]
		]Append[Const Construct C[val, type reg]]
}

Const Construct C[value,type reg:out]
{
	valtype <- Blueprint Of[value]
	[(Int8(),UInt8(),Int16(),UInt16(),Int32(),UInt32(),Int64(),UInt64())]Find[=[valtype,?]]
	{
		size <- [("8","16","32","64")]Index[[~]/[2]]
		If[[~]Mod[2]]
		{ s <- "UI" }
		{ s <- "I" }
		
		out <- [[[[[["make_"
			]Append[s]
			]Append["nt"]
			]Append[size]
			]Append["("]
			]Append[String[value]]
			]Append[")"]
	}{
		If[[valtype] = [Type Instance()]]
		{
			//TODO: Support parametric types
			typeid <- [type reg]Type ID[[value]Name >>]

			out <- [["make_Blueprint("]Append[typeid]]Append[")"]
		}{
			If[[valtype] = [Boolean()]]
			{
				If[value]
				{
					out <- "make_Bool(1)"
				}{
					out <- "make_Bool(0)"
				}
			}{

				[(String(),String Slice(),String Cat())]Find[=[valtype,?]]
				{
					out <- [["make_String(\""]Append[ [[[[value]Replace["\\", "\\\\"]]Replace["\n", "\\n"]]Replace["\"", "\\\""]]Replace["\r", "\\r"] ]]Append["\")"]
				}{
					If[[valtype]=[Worker Literal()]]
					{
						//TODO: Figure out how to fully support these in nested cases
						//or workaround the problem higher up in the food chain
						[[value]Args >>]Last
						{ size <- String[[~]+[1]] }
						{ size <- "0" }
						out <- [[[[[["make_Worker(FUNC_"
								]Append[Escape Rhope Name[[value]Name >>,[type reg]Escape Pattern >>]]
								]Append[", "]
								]Append[size]
								]Append[", "]
								]Append[String[Fold[+[1,?], 0, [value]Args >>]]]
								]Append[")"]
					}{
						[(List(), List Leaf())]Find[=[?,valtype]]
						{
							out <- [Fold[_List Literal El[?, ?, ?, type reg], ["make_List("]Append[String[[value]Length]], value]]Append[")"]
						}{
							out <- "UnhandledLiteralType"
						}
					}
				}
			}
		}
			
	}
}

_Set Worker Params C[text,param,num,type reg,name:out]
{
	out <- [text]Append[
		[[[[[["\t((object **)(((t_Worker *)_const_"
			]Append[name]
			]Append[")+1))["]
			]Append[String[num]]
			]Append["] = "]
			]Append[Const Construct C[param, type reg]]
			]Append[";\n"] ]
}

_Set Consts C Program[text,value,name,type reg:out]
{
	valtype <- Blueprint Of[value]
	[(String(),String Cat(),String Slice(),Worker Literal(),List(),List Leaf())]Find[=[valtype,?]]
	{
		Print[[name]Append[" is not of an early constant type"]]
		out <- text
	}{
		Const Construct C[value,type reg]
		{ out <- [text]Append[ [[[["\t_const_"]Append[Escape Rhope Name[name,[type reg]Escape Pattern >>]]]Append[" = "]]Append[~]]Append[";\n"] ] }
	}
}

_Set List Els[text,el,index,type reg:out]
{
	out <- [[text]Append[
		[["\tinout[1] = "
		]Append[Const Construct C[index,type reg]]
		]Append[
			[[";\n\tinout[2] = "
			]Append[Const Construct C[el, type reg]]
			]Append[";\n"]
		]]]Append["\trhope(FUNC_Set, inout, 3, 3);\n"]
}

_Set Late Consts C[text,value,name,type reg:out]
{
	valtype <- Blueprint Of[value]
	[(String(),String Cat(),String Slice(),Worker Literal(),List(),List Leaf())]Find[=[valtype,?]]
	{
		If[[~]>[3]]
		{
			out <- [Fold[_Set List Els[?, ?, ?, type reg], [text]Append["\trhope(FUNC_List, inout, 0, 1);\n"], value]
				]Append[[["\t_const_"]Append[Escape Rhope Name[name,[type reg]Escape Pattern >>]]]Append[" = inout[0];\n"]]
		}{
			Const Construct C[value,type reg]
			{ init <- [text]Append[ [[[["\t_const_"]Append[Escape Rhope Name[name,[type reg]Escape Pattern >>]]]Append[" = "]]Append[~]]Append[";\n"] ] }
		
			If[[valtype]=[Worker Literal()]]
			{
				out <- Fold[_Set Worker Params C[?, ?, ?, type reg, Escape Rhope Name[name,[type reg]Escape Pattern >>]], init, [value]Args >>]
			}{
				out <- Val[init]
			}
		}
	}{
		out <- text
	}
}

_Global Var Init C[text,value,name,storevar,type reg:out]
{
	out <- [[[[[text]Append[storevar]]Append[Escape Rhope Name[name, [type reg]Escape Pattern >>]]]Append[" = "]]Append[Const Construct C[value, type reg]]]Append[";\n"]
}

_Global Store Inits C[text,store,type reg:out]
{
	estore <- Escape Rhope Name[[store]Name >>, [type reg]Escape Pattern >>]
	out <- Fold[_Global Var Init C[?,?,?, [[[["\t((mutt_"]Append[estore]]Append[" *)(gs_"]]Append[estore]]Append["->data))->gs_"], type reg], text, [store]Vars >>]
}

_Dispatch Switch Sub[text, num, name:out]
{
	out <- [[[[[text
		]Append["\tResumeEntry("]
		]Append[String[num]]
		]Append[","]
		]Append[name]
		]Append[")\\\n"]
}

_Dispatch Switch[text,func,raw name:out]
{
	If[[[func]Convention >>] = ["rhope"]]
	{
		name <- Escape Rhope Name[raw name,[func]Escape Pattern >>]
		out <- [[text]Append[ [["\tDispatchEntry("]Append[name]]Append[")\\\n"] ]
			]Append[Fold[_Dispatch Switch Sub[?, ?, name], "", Range[1, [func]Resume Index >>]]]
	}{
		out <- text
	}
}

_Dispatch Switch Methods[p,text,id,raw name:out]
{
	name <- Escape Rhope Name[raw name,p]
	out <- [text]Append[ [["\tDispatchEntry("]Append[name]]Append[")\\\n"] ]
}

_Dispatch Enum Sub[text, num, name:out]
{
	out <- [[[[[text
		]Append["\tRES_"]
		]Append[String[num]]
		]Append["_"]
		]Append[name]
		]Append[",\n"]
}

_Dispatch Enum[text,func,raw name:out]
{
	If[[[func]Convention >>] = ["rhope"]]
	{
		name <- Escape Rhope Name[raw name,[func]Escape Pattern >>]
		out <- [[text]Append[ [["\tFUNC_"]Append[name]]Append[",\n"] ]
			]Append[Fold[_Dispatch Enum Sub[?, ?, name], "", Range[1, [func]Resume Index >>]]]
	}{
		out <- text
	}
}

_Dispatch Enum Methods[p,text,types,name:out]
{
	out <- [text]Append[ [["\tFUNC_"]Append[Escape Rhope Name[name,p]]]Append[",\n"] ]
}

Dispatch@C Program[program,all methods:out]
{
	out <- [[[[["typedef enum {\n"
		]Append[Fold[_Dispatch Enum[?], 
			[Fold[_Dispatch Enum Methods[[program]Escape Pattern >>,?], "", all methods]]Append["\tFUNC_Build,\n\tFUNC_BlueprintSP_Of,\n\tFUNC_ID,\n\tFUNC_BlueprintSP_FromSP_ID,\n\tFUNC_Pause,\n\tRES_1_Pause,\n\tFUNC_Resume,\n"], 
			[program]Functions >>]]
		]Append["\tEND,\n\tEND_THREAD\n} funcids;\n\n"]
		]Append["#define DispatchEntries \\\n"] 
		]Append[Fold[_Dispatch Switch[?], 
			[Fold[_Dispatch Switch Methods[[program]Escape Pattern >>,?], "", all methods]]Append["\tDispatchEntry(Build)\\\n\tDispatchEntry(BlueprintSP_Of)\\\n\tDispatchEntry(ID)\\\n\tDispatchEntry(BlueprintSP_FromSP_ID)\\\n\tDispatchEntry(Pause)\\\n\tResumeEntry(1,Pause)\\\n\tDispatchEntry(Resume)\\\n"], 
			[program]Functions >>]]
		]Append["\tEndEntry\\\n\tEndThreadEntry\n\n"]
}

Not Native[func:out]
{
	If[[[func]Convention >>] = ["rhope"]]
	{ out <- No }
	{ out <- Yes }
}

Native[func:out]
{
	out <- [[func]Convention >>] = ["rhope"]
}

Local Pointers[text,func:out]
{
	If[ [ [[[func]Variables >>]Length]+[[[func]Outputs >>]Length] ] = [0] ]
	{
		out <- text
	}{
		out <- [text]Append[[["\tFuncDef("]Append[Escape Rhope Name[[func]Name >>,[func]Escape Pattern >>]]]Append[")\n"]]
	}
}

_Method to Types[dict,name,type:out]
{
	typelist <- [dict]Index[name] {}
	{ typelist <- () }

	out <- [dict]Set[name, [typelist]Append[[type]Name >>]]

}

_Field to Types[dict,field,type:out]
{
	name <- [field]Index[0]
	out <- _Method to Types[_Method to Types[dict, [name]Append[" >>"], type], [name]Append[" <<"], type]

}

Method to Types[dict,type:out]
{
	out <- Fold[_Method to Types[?, ?, type], dict, [type]Methods >>]
}

Field to Types[dict,type:out]
{
	out <- Fold[_Field to Types[?, ?, type], dict, [type]Fields >>]
}

_Method Dispatch[text, type, method, reg: out]
{
	out <- [[[[[[[text]Append["\tMethodDispatch("]]Append[ [reg]Type ID[type] ]]Append[","]]Append[Escape Rhope Name[method,[reg]Escape Pattern >>]]]Append[","]]Append[Escape Rhope Name[type,[reg]Escape Pattern >>]]]Append[")\n"]
}

Method Dispatch[text, types, method, reg: out]
{
	out <- [[[Fold[_Method Dispatch[?, ?, method, reg], [[[text]Append["Method("]]Append[ Escape Rhope Name[method,[reg]Escape Pattern >>] ]]Append[")\n"], types]
		]Append["EndMethod("]
		]Append[Escape Rhope Name[method,[reg]Escape Pattern >>]]
		]Append[")\n\n"]
}

Init Type Names[text,typeid,name,reg:out]
{
	[reg]Defined?[name]
	{ out <- [text]Append[ [[[["\tregistered_types["]Append[typeid]]Append["]->name = "]]Append[Const Construct C[name, reg]]]Append[";\n"] ] }
	{ out <- text }
}

Text Filename@C Program[program,source name:out]
{
	out <- [source name]Append[".c"]
}

Text@C Program[program:out]
{
	p <- [program]Escape Pattern >>
	type defs <- [[program]Type Registry >>]Definitions >>
	constants <- Fold[Combine Consts[?], Dictionary[], [program]Functions >>]
	all methods <- Fold[Field to Types[?], Fold[Method to Types[?], Dictionary[], type defs], type defs]
	headers <- "#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include \"builtin.h\"
#include \"object.h\"
#include \"context.h\"
#include \"func.h\"
#include \"integer.h\"
#include \"blueprint.h\"
#include \"array.h\"
#include \"worker.h\"
#include \"bool.h\"
#include <sys/time.h>\n\n"
	out <- [[[[[[[[[[[[[[[[[[[[[headers
		]Append[[program]Dispatch[all methods]]
		]Append[[[program]Type Registry >>]Type Defs]
		]Append[Fold[_Global Type Defs C[?,?,p], "", [program]Global Stores >>]]
		]Append[Fold[_Consts C Program[?,?,?,p], 
					Fold[_Defs C Program[?], "", [program]Functions >>], 
					constants]]
		]Append[Fold[_Text C Program[?, ?, [program]Type Registry >>], "", Filter[[program]Functions >>, Not Native[?]]]]
		]Append["\n
#ifdef ENABLE_PROFILING
uint64_t profile_counts[END];
uint64_t profile_nestedcounts[END];
uint64_t profile_totals[END];
uint64_t profile_selftotals[END];
uint64_t profile_activationlevel[END];
#endif

int32_t rhope(uint32_t func, object ** params, uint16_t numparams, uint16_t callspace)
{
#ifdef ENABLE_PROFILING
	struct timeval time;
#endif
	uint16_t resume,idx, vcparam_offset, last_vcparam;
	context *ct,*temp_ct;
	void *tmp;
	calldata * cdata, *temp_cdata, *my_cdata;
	DispatchVar
	FuncDef(Build)
	FuncDef(BlueprintSP_Of)
	FuncDef(ID)
	FuncDef(BlueprintSP_FromSP_ID)\n"]
		]Append[Fold[Local Pointers[?], "", [program]Functions >>]]
		]Append["
	ct = new_context();
	cdata = alloc_cdata(ct, NULL, callspace);
	cdata->num_params = numparams;
	for(idx = 0; idx < numparams; ++idx)
		cdata->params[idx] = params[idx];
	cdata->func = END;
DISPATCH\n"]
		]Append[Fold[Method Dispatch[?, ?, ?, [program]Type Registry >>], "", all methods]]
		]Append["
Func(Build,
	NumParams 1)
	
	Param(0, TYPE_BLUEPRINT)
	
	lv_Build->bp = ((t_Blueprint *)(cdata->params[0]))->bp;
	release_ref(cdata->params[0]);
	
	Ret(0, new_object_bp(lv_Build->bp))
EndFunc(Build)
DISPATCH

Func(BlueprintSP_Of,
	NumParams 1)
	
	lv_BlueprintSP_Of->bp = get_blueprint(cdata->params[0]);
	release_ref(cdata->params[0]);
	
	Ret(0, new_object(TYPE_BLUEPRINT))
	((t_Blueprint *)cdata->params[0])->bp = lv_BlueprintSP_Of->bp;
EndFunc(BlueprintSP_Of)
DISPATCH

Func(ID, NumParams 1)

	Param(0, TYPE_BLUEPRINT)

	lv_ID->id = new_object(TYPE_UINT32);
	((t_UInt32 *)lv_ID->id)->Num = ((t_Blueprint *)cdata->params[0])->bp->type_id;
	release_ref(cdata->params[0]);
	Ret(0, lv_ID->id)
EndFunc(ID)
DISPATCH

Func(BlueprintSP_FromSP_ID, NumParams 1)

	Param(0, TYPE_UINT32)

	lv_BlueprintSP_FromSP_ID->type = ((t_UInt32 *)cdata->params[0])->Num;
	if (lv_BlueprintSP_FromSP_ID->type >= max_registered_type || !registered_types[lv_BlueprintSP_FromSP_ID->type]) {
		Ret(1, cdata->params[0])
		Ret(0, NULL)
	} else {
		release_ref(cdata->params[0]);	
		Ret(0, new_object(TYPE_BLUEPRINT))
		((t_Blueprint *)cdata->params[0])->bp = registered_types[lv_BlueprintSP_FromSP_ID->type];
		Ret(1, NULL)
	}
	
EndFunc(BlueprintSP_FromSP_ID)
DISPATCH

FuncNoLocals(Pause, NumParams 1)
	Param(0, TYPE_WORKER)

	ct->resume_cdata = my_cdata;
	ct->resumeable = 1;
	temp_ct = ct;
	ct = new_context();
	VCPrepCall(my_cdata->params[0], 1)
	VCSetParam(my_cdata->params[0], 0, make_Context(temp_ct))
	ValCallNoLocals(my_cdata->params[0], 1, 1, Pause)
	release_ref(my_cdata->params[0]);
	DISPATCH
	ValCallNoLocalsPostlude(1, Pause)
	for(idx = 0; idx < cdata->num_params; ++idx)
		if(cdata->params[idx])
		{ release_ref(cdata->params[idx]); }
	free_context(ct);
	ct = get_cqueue();
	if (!ct) goto NOTHING_TO_DO;
	cdata = ct->resume_cdata;
	ct->resume_cdata = NULL;
EndFuncNoLocals
DISPATCH

FuncNoLocals(Resume, NumParams 2)
	Param(0, TYPE_CONTEXT)

	temp_ct = ((t_Context *)my_cdata->params[0])->ct;
	release_ref(my_cdata->params[0]);
	if(temp_ct->resumeable && temp_ct->resume_cdata)
	{
		temp_ct->resumeable = 0;
		temp_ct->resume_cdata->params[0] = add_ref(my_cdata->params[1]);
		my_cdata->params[0] = my_cdata->params[1];
		my_cdata->params[1] = NULL;
		if(!put_cqueue(temp_ct))
		{
			ct->resume_cdata = my_cdata;
			temp_ct->runafter = ct;
			ct = temp_ct;
			cdata = ct->resume_cdata;
			ct->resume_cdata = NULL;
		}
	} else {
		my_cdata->params[0] = NULL;
	}
EndFuncNoLocals
DISPATCH\n"]
		]Append[Fold[_Text C Program[?, ?, [program]Type Registry >>], "", Filter[[program]Functions >>, Native[?]]]]
		]Append["
DO_END:
	for(idx = 0; idx < cdata->num_params; ++idx)	
		params[idx] = cdata->params[idx];
	free_context(ct);
	return cdata->num_params;

DO_END_THREAD:
	for(idx = 0; idx < cdata->num_params; ++idx)
	{ release_ref(cdata->params[idx]); }
	if(ct->runafter)
	{
		temp_ct = ct;
		ct = ct->runafter;
		free_context(temp_ct);
		cdata = ct->resume_cdata;
		func = cdata->func;
		DISPATCH
	}
	free_context(ct);
	if(ct = get_cqueue())
	{
		cdata = ct->resume_cdata;
		func = cdata->func;
		DISPATCH
	}
NOTHING_TO_DO:
	return 0;

_exception:
	puts(\"Exception! Trace follows:\");
	while(cdata && cdata->func < END)
	{
		printf(\"%d\\n\", cdata->func);
		cdata = cdata->lastframe;
	}
	return -1;
}

#include \"builtin.c\"
#include \"array.c\"
#include \"worker.c\"

int main(int argc, char **argv)
{
	blueprint * bp;
	int numret;
	int idx;
	object * inout[3];
	register_builtin_types();
	register_type_byid(TYPE_MUTABLEGLOBAL, sizeof(mutable_object)-sizeof(object), NULL, NULL, NULL);\n\n"]
		]Append[ [[program]Type Registry >>]Type Inits[[program]Method Registry >>, [program]Field Registry >>] ]
		]Append[Fold[_Global Type Inits C[?, ?, p], "", [program]Global Stores >>]]
		]Append[Fold[_Set Consts C Program[?, ?, ?, [program]Type Registry >>], "", constants]]
		]Append[Fold[_Set Late Consts C[?, ?, ?, [program]Type Registry >>], "", constants]]
		]Append[Fold[_Global Store Inits C[?, ?, [program]Type Registry >>], "", [program]Global Stores >>]]
		]Append[Fold[Init Type Names[?, ?, ?, [program]Type Registry >>], "", [[program]Type Registry >>]Lookup >>]]
		]Append["
	rhope(FUNC_List, inout, 0, 1);
	for (idx = 0; idx < argc; ++idx)
	{
		inout[1] = make_String(argv[idx]);
		rhope(FUNC_Append, inout, 2, 2);
	}
	numret = rhope(FUNC_Main, inout, 1, 1);"]
		]Append[Fold[_Consts C Release[?, ?, ?, p], "", constants]]
		]Append[
	"
	print_mem_info(manager);
	print_live_object_types(manager);
	
#ifdef ENABLE_PROFILING
	for (idx = 0; idx < END; ++idx)
	{
		if(profile_counts[idx])
			printf(\"Func: %d\tCount: %llu\tTime: %llu\tAvg: %f\tSelf: %llu\tAvg: %f\tNested Count: %llu\\n\", idx, profile_counts[idx], profile_totals[idx], ((double)profile_totals[idx])/((double)profile_counts[idx]), profile_selftotals[idx], ((double)profile_selftotals[idx])/((double)profile_counts[idx]), profile_nestedcounts[idx]);
	}
#endif
	if (!numret)
		return 0;
	if (numret < 0)
		return numret;
	if (get_blueprint(inout[0])->type_id == TYPE_INT32)
		return ((t_Int32 *)inout[0])->Num;

	rhope(FUNC_If, inout, 1, 2);
	if (inout[0])
		return 0;
	return 1;
}\n\n"]

}