view cbackend.rhope @ 75:0083b2f7b3c7

Partially working implementation of List. Modified build scripts to allow use of other compilers. Fixed some bugs involving method implementations on different types returning different numbers of outputs. Added Fold to the 'builtins' in the comipler.
author Mike Pavone <pavone@retrodev.com>
date Tue, 06 Jul 2010 07:52:59 -0400
parents a844c623c7df
children dbe95bfec970
line wrap: on
line source

Import extendlib.rhope
Import backendutils.rhope

Blueprint Blueprint Def
{
	Name
	Fixed Size
	Fields
	Methods
}

Blueprint Def[name]
{
	out <- [[[[Build["Blueprint Def"]]Name <<[name]]Fixed Size <<[0]]Fields <<[()]]Methods <<[Dictionary[]]
}

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[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:out,array]
{
	If[[Type 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"] }
				}{
					,regulartype <- [("UInt64","UInt32","UInt16","UInt8")]Find[[type]Name >>]
					{
						primitive <- Yes
						[[type]Name >>]Slice[4] {}
						{ typename <- [["uint"]Append[~]]Append["_t"] }
					}
				}
			}
			
			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]
	}
	out <- [[prefix]Append[escaped]]Append[postfix]
}

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

Type Def@C Type[ctype:out]
{
	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[Escape Rhope Name[[ctype]Name >>]]]Append[";"]
					]Append[ 
						[[[["typedef "
							]Append[Rhope Type to C[ [[[ctype]Fields >>]Index[0]]Index[1] ]]
							]Append[" nt_"]
							]Append[Escape Rhope Name[[ctype]Name >>]]
							]Append[";"] ]
	}{
		//HACK!!!
		If[[[ctype]Name >>]=["Blueprint"]]
		{
			out <- ""	
		}{
			[("Array","Worker")]Find[[ctype]Name >>]
			{ oend <- "\nMObject(" }
			{ oend <- "\nObject(" } 
			out <- [Fold["_Type Def C Type", "OBegin", [ctype]Fields >>]]Append[ [[oend]Append[Escape Rhope Name[[ctype]Name >>]]]Append[")"] ]
		}
	}
}

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

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

Type Init@C Type[ctype,id,method reg,field reg:out]
{
	[("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 >>]] }
				}
			}
		}
		size <- [["sizeof("]Append[typename]]Append[")"] 
	}
	start <- [["\tbp = register_type_byid("
		]Append[id]
		]Append[
			[[", "]Append[size]
			]Append[
				[", (special_func)"]Append[
					[ 
						[[[[Escape Rhope Name NU[[ctype]Init >>]
						]Append[", (special_func)"]
						]Append[Escape Rhope Name NU[[ctype]Copy >> ]]
						]Append[", (special_func)"]
						]Append[Escape Rhope Name NU[[ctype]Cleanup >>]]         
					]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
}

C Type Registry[: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"]	//12
			]Set["Blueprint", "TYPE_BLUEPRINT"]	//13
			]Set["Array", "TYPE_ARRAY"]			//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]
}

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

Type Defs@C Type Registry[reg:out]
{
	out <- Fold["_Type Defs C", "", [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] ]]Append["\n\n"]
}

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

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

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

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

C Function With Registry[name,inputs,outputs,convention,registry,field reg,type reg: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"]Set Input[1, "Any Type"], (), inputs] ]
		]Output Types <<[ Fold[["Append"]Set Input[1, "Any Type"], (), outputs] ]
		]Resume Index <<[1]
		]Last NumParams <<[-1]
}

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

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

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]]
	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]
	If[[Type Of[var]] = ["String"]]
	{
		[[func]Inputs >>]Find[var]
		{
			type <- [[func]Input Types >>]Index[~]
		}{
			type <- [[func]Variables >>]Index[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] ]]Append[")("]]Append[as op]]Append["))"]
		}
	}{
		rvar <- Val[as op]
	}

	[[func]Type Registry >>]Simple Type?[[type]Name >>]
	{ access <- "->" }
	{ access <- "->payload." }
	out <- [[rvar]Append[access]]Append[Escape Rhope Name[field]]
}

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

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

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

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

Val Call@C Function[func,to call,args:out]
{
	worker <- Make Op[Strip Addref[to call], func]
	rargs <- Map[args, ["Make Op"]Set Input[1, func]]

	If[[[func]Last NumParams >>] = [-1]]
	{
		freed <- Val[func]
	}{
		freed <- [func]Add Raw Line["FreeCall"]
	}
	prepped <- [[freed]Add Raw Line[ 
			[[[["VCPrepCall("
				]Append[worker]
				]Append[", "]
				]Append[[rargs]Length]
				]Append[")"] ]
		]Last NumParams <<[[rargs]Length]
	
	
	out <- [[[[Fold[["_Val Function Arg C"]Set Input[3, worker], prepped, rargs]
	]Add Raw Line[
		[[[[[[[["ValCall("
		]Append[worker]
		]Append[", "]
		]Append[[rargs]Length]
		]Append[", "]
		]Append[[func]Resume Index >>]
		]Append[", "]
		]Append[Escape Rhope Name[[func]Name >>]]
		]Append[")"]]
	]Add Raw Line["DISPATCH"]
	]Add Raw Line[
		[[[["ValCallPostlude("
		]Append[[func]Resume Index >>]
		]Append[", "]
		]Append[Escape Rhope Name[[func]Name >>]]
		]Append[")"]]
	]Resume Index <<[ [[func]Resume Index >>]+[1] ]
}

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

Func Base@C Function[func,tocall,args,type:out]
{
	rargs <- Map[args, ["Make Op"]Set Input[1, func]]

	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[[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[[rargs]Length]
		]Append[", "]
		]Append[[func]Resume Index >>]
		]Append[", "]
		]Append[Escape Rhope Name[[func]Name >>]]
		]Append[")"]]
	]Resume Index <<[ [[func]Resume Index >>]+[1] ]
}

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

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

Set Field Call@C Function[func,field,object,value:out]
{
	out <- [func]Func Base[Escape Rhope Name[[field]Append[" <<"]], [[()]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],args, "TCall"]
}

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

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

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

Checked Result Reference@C Function[func,output:out]
{
	out <- [[[["("]Append[output]]Append[" < cdata->num_params ? cdata->params["]]Append[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[inputnum] ]Append[ [[", lv_"]Append[Escape Rhope Name[[func]Name >>]]]Append["->"]]]Append[Escape Rhope Name[inputname]]]Append[")\n"]]
}

Set Outputs@C Function[func:out]
{
	If[[[func]Convention >>] = ["rhope"]]
	{
		out <- [[[Fold[["_Set Outputs C"]Set Input[3, func], "", [func]Outputs >>]]Append["\tNumRet("]]Append[[[func]Outputs >>]Length]]Append[")\n"]
	}{
		[[func]Outputs >>]Index[0]
		{
			out <- [["\treturn "]Append[Escape Rhope Name[~]]]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]]] ]]Append[[" "]Append[Escape Rhope Name[varname]]]]Append[";\n"]
}
_Var Defs C[string,type,varname:out]
{
	out <- [[[string]Append[ ["\t"]Append[Rhope Type to C[type]] ]]Append[[" "]Append[Escape Rhope Name[varname]]]]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[["_Output Defs C"]Set Input[3, func], Fold["_Var Defs C","typedef struct {\n", [func]Variables >>], [func]Outputs >>]]Append["} lt_"]]Append[Escape Rhope Name[[func]Name >>]]]Append[";\n"]
	}{
		localtype <- ""
	}
	
	If[ [[func]Convention >>] = ["rhope"] ]
	{
		/* parts <- [[func]Name >>]Split["@"]
		[parts]Index[1]
		{
			proto <- [[[["MethodDef("
				]Append[Escape Rhope Name[[parts]Index[0]]]
				]Append[", "]
				]Append[Escape Rhope Name[~]]
				]Append[")\n"]
		}{
			proto <- [["FuncDef("]Append[Escape Rhope Name[[func]Name >>]]]Append[")\n"]
		} */
		out <- Val[localtype]
	}{
		out <- [[func]Naked Proto]Append[";\n"]
	}
	}
}

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

Naked Proto@C Function[func:out]
{
	[[func]Output Types >>]Index[0]
	{
		outtype <- [Rhope Type to C[~]]Append[" "]
	}{
		outtype <- "void "
	}
	out <- [[[[outtype
			]Append[ Escape Rhope Name NU[[func]Name >>]]
			]Append["("]
			]Append[ [Fold[["_Proto Input"]Set Input[3, [func]Input Types >>], (), [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]
{
	If[[Type Of[type]] = ["String"]]
	{
		typename <- type
	}{
		typename <- [type]Name >>
	}
	If[[typename] = ["Any Type"]]
	{
		out <- text
	}{
		out <- [text]Append[[[["\tParam("]Append[input num]]Append[ [","]Append[ [[func]Type Registry >>]Type ID[typename] ] ]]Append[")\n"]]
	}
}

Text@C Function[func:out]
{	
	Print[["Text@C Function: "]Append[[func]Name >>]]
	If[ [[func]Convention >>] = ["rhope"] ]
	{
		,before <- [[func]Name >>]Get DString["@"]
		{
			type <- "MethodImpl"
			cname <- [[[[Escape Rhope Name[before]
				]Append[", "]
				]Append[Escape Rhope Name[~]]
				]Append[", "]
				]Append[ [[func]Type Registry >>]Type ID[~] ]
		}{}{}{
			type <- "Func"
			cname <- Val[fname]
		}
		fname <- Escape Rhope Name[[func]Name >>]
		param check <- Fold[["Check Param Type C"]Set Input[3, func], "", [func]Input Types >>]
		If[ [ [[[func]Variables >>]Length]+[[[func]Outputs >>]Length] ] = [0] ]
		{
			out <- [[[[[[[[ [type]Append["NoLocals("]
				]Append[cname]
				]Append[",\n\tNumParams "]
				]Append[ [[func]Inputs >>]Length ]
				]Append[")\n\n"]
				]Append[param check]
				]Append[ [[func]Statements >>]Join[""] ]
				]Append["EndFuncNoLocals\n"]
				]Append["DISPATCH"]
		}{
			If[[[func]Last NumParams >>] = [-1]]
			{
				freecall <- ""
			}{
				freecall <- "\n\tFreeCall\n"
			}
			out <- [[[[[[[[[[ [type]Append["("]
				]Append[cname]
				]Append[",\n\tNumParams "]
				]Append[ [[func]Inputs >>]Length ]
				]Append[")\n\n"]
				]Append[param check]
				]Append[ [[func]Statements >>]Join[""] ]
				]Append[freecall]
				]Append[[func]Set Outputs]
				]Append[[["EndFunc("]Append[fname]]Append[")\n"]]
				]Append["DISPATCH"]
		}
	}{
		
		out <- [[[
				Fold[["_Output Defs C"]Set Input[3, 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
}

C Program[:out]
{
	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]
{
	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 >>]
}

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:out]
{
	out <- [text]Append[ [["object * _const_"]Append[Escape Rhope Name[name]]]Append[";\n"] ]
}

Const Construct C[value,type reg:out]
{
	valtype <- Type Of[value]
	[("Int32","Whole Number")]Find[valtype]
	{
		out <- [["make_Int32("]Append[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] = ["Yes No"]]
			{
				If[value]
				{
					out <- "make_Bool(1)"
				}{
					out <- "make_Bool(0)"
				}
			}{
				If[[valtype] = ["Machine Integer"]]
				{
					If[[value]Signed? >>]
					{ s <- "I" }
					{ s <- "UI" }
					
					out <- [[[[[["make_"
						]Append[s]
						]Append["nt"]
						]Append[[value]Size >>]
						]Append["("]
						]Append[[value]Value >>]
						]Append[")"]
				}{
					If[[valtype] = ["String"]]
					{
						out <- [["make_String(\""]Append[ [[[value]Replace["\\", "\\\\"]]Replace["\n", "\\n"]]Replace["\"", "\\\""] ]]Append["\")"]
					}{
						If[[valtype]=["Worker Literal"]]
						{
							//TODO: Figure out how to fully support these in nested cases
							//or workaround the problem higher up in the food chain
							[[value]Args >>]Last
							{ size <- [~]+[1] }
							{ size <- "0" }
							out <- [[[[[["make_Worker(FUNC_"
									]Append[Escape Rhope Name[[value]Name >>]]
									]Append[", "]
									]Append[size]
									]Append[", "]
									]Append[[[value]Args >>]Length]
									]Append[")"]
						}{
							out <- "UnhandledLiteralType"
						}
					}
				}
			}
		}
			
	}
}

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

_Set Consts C Program[text,value,name,type reg:out]
{
	valtype <- Type Of[value]
	[("String","Worker Literal")]Find[valtype]
	{
		out <- text
	}{
		Const Construct C[value,type reg]
		{ out <- [text]Append[ [[[["\t_const_"]Append[Escape Rhope Name[name]]]Append[" = "]]Append[~]]Append[";\n"] ] }
	}
}

_Set Late Consts C[text,value,name,type reg:out]
{
	valtype <- Type Of[value]
	[("String","Worker Literal")]Find[valtype]
	{
		Const Construct C[value,type reg]
		{ init <- [text]Append[ [[[["\t_const_"]Append[Escape Rhope Name[name]]]Append[" = "]]Append[~]]Append[";\n"] ] }
		
		If[[valtype]=["Worker Literal"]]
		{
			out <- Fold[[["_Set Worker Params C"]Set Input[3, type reg]]Set Input[4, Escape Rhope Name[name]], init, [value]Args >>]
		}{
			out <- Val[init]
		}
	}{
		out <- text
	}
}

_Dispatch Switch Sub[text, num, name:out]
{
	out <- [[[[[[[[[text
		]Append["\tcase RES_"]
		]Append[num]
		]Append["_"]
		]Append[name]
		]Append[": goto r"]
		]Append[num]
		]Append["_"]
		]Append[name]
		]Append[";\\\n"]
}

_Dispatch Switch[text,func,raw name:out]
{
	If[[[func]Convention >>] = ["rhope"]]
	{
		name <- Escape Rhope Name[raw name]
		out <- [[text]Append[ [[[["\tcase FUNC_"]Append[name]]Append[": goto f_"]]Append[name]]Append[";\\\n"] ]
			]Append[Fold[["_Dispatch Switch Sub"]Set Input[2, name], "", Range[1, [func]Resume Index >>]]]
	}{
		out <- text
	}
}

_Dispatch Switch Methods[text,id,raw name:out]
{
	name <- Escape Rhope Name[raw name]
	out <- [text]Append[ [[[["\tcase FUNC_"]Append[name]]Append[": goto f_"]]Append[name]]Append[";\\\n"] ]
}

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

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

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

Dispatch@C Program[program,all methods:out]
{
	out <- [[[[["typedef enum {\n"
		]Append[Fold["_Dispatch Enum", 
			[Fold["_Dispatch Enum Methods", "", all methods]]Append["\tFUNC_Build,\n\tFUNC_BlueprintSP_Of,\n"], 
			[program]Functions >>]]
		]Append["\tEND\n} funcids;\n\n"]
		]Append["#define DISPATCH switch(func) { \\\n"]
		]Append[Fold["_Dispatch Switch", 
			[Fold["_Dispatch Switch Methods", "", all methods]]Append["\tcase FUNC_Build: goto f_Build;\\\n\tcase FUNC_BlueprintSP_Of: goto f_BlueprintSP_Of;\\\n"], 
			[program]Functions >>]]
		]Append["\tcase END: goto DO_END;\\\n}\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 >>]]]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"]Set Input[2, type], dict, [type]Methods >>]
}

Field to Types[dict,type:out]
{
	out <- Fold[["_Field to Types"]Set Input[2, 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]]]Append[","]]Append[Escape Rhope Name[type]]]Append[")\n"]
}

Method Dispatch[text, types, method, reg: out]
{
	out <- [[[Fold[[["_Method Dispatch"]Set Input[2, method]]Set Input[3, reg], [[[text]Append["Method("]]Append[ Escape Rhope Name[method] ]]Append[")\n"], types]
		]Append["EndMethod("]
		]Append[Escape Rhope Name[method]]
		]Append[")\n\n"]
}

Text@C Program[program:out]
{
	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 \"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\"\n\n"
	out <- [[[[[[[[[[[[[[[headers
		]Append[[program]Dispatch[all methods]]
		]Append[[[program]Type Registry >>]Type Defs]
		]Append[Fold["_Consts C Program", 
					Fold["_Defs C Program", "", [program]Functions >>], 
					constants]]
		]Append[Fold[["_Text C Program"]Set Input[2, [program]Type Registry >>], "", Filter[[program]Functions >>, "Not Native"]]]
		]Append["\n
int32_t rhope(uint32_t func, object ** params, uint16_t numparams, uint16_t callspace)
{
	uint16_t resume,idx, vcparam_offset, last_vcparam;
	context * ct;
	calldata * cdata, *temp_cdata, *my_cdata;\n\nFuncDef(Build)\nFuncDef(BlueprintSP_Of)\n"]
		]Append[Fold["Local Pointers", "", [program]Functions >>]]
		]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"]Set Input[3, [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\n"]
		]Append[Fold[["_Text C Program"]Set Input[2, [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;

_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[2];
	register_builtin_types();\n\n"]
		]Append[ [[program]Type Registry >>]Type Inits[[program]Method Registry >>, [program]Field Registry >>] ]
		]Append[Fold[["_Set Consts C Program"]Set Input[3, [program]Type Registry >>], "", constants]]
		]Append[Fold[["_Set Late Consts C"]Set Input[3, [program]Type Registry >>], "", constants]]
		]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);
	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"]

}