view cbackend.rhope @ 54:243d013a49cb

Defer processing of string literals until after simpler ones to avoid a segfault
author Mike Pavone <pavone@retrodev.com>
date Thu, 29 Apr 2010 01:12:43 -0400
parents 079200bc3e75
children e1fd6d244f14
line wrap: on
line source

Import extendlib.rhope
Import backendutils.rhope
Import number.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[[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[")"] ]
		}
	}
}

_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]
{
	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[
			[[", "]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 <- 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"]
			]Set["UInt16", "TYPE_UINT16"]
			]Set["UInt32", "TYPE_UINT32"]
			]Set["UInt64", "TYPE_UINT64"]
			]Set["Int8", "TYPE_INT8"]
			]Set["Int16", "TYPE_INT16"]
			]Set["Int32", "TYPE_INT32"]
			]Set["Int64", "TYPE_INT64"]
			]Set["Boolean", "TYPE_BOOLEAN"]
			]Set["Float32", "TYPE_FLOAT32"]
			]Set["Float64", "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"]
			]Set["Wrong Type Exception", "TYPE_WRONGTYPEEXCEPTION"]]
		]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 >>]
	{ Print["Type inits got output"] }
}

Register Type@C Type Registry[reg,def:out]
{
	name <- [def]Name >>
	[[reg]Lookup >>]Index[name]
	{
		[[reg]Definitions >>]Index[name]
		{
			out <- reg
		}{
			Print[["Registered def for "]Append[name]]
			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]
{
	Print[["Symple Type?: "]Append[name]]
	,notfound <- [[reg]Definitions >>]Index[name]
	{
		Print["found type"]
		yep,nope <- If[[[[~]Fields >>]Length] = [1]]
	}{
		Pretty Print[reg, ""]
	}
}

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

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

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]
{
	Print["Register Constant"]
	Print[name]
	out <- [func]Constants <<[ [[func]Constants >>]Set[name, constant] ]
	{ Print["Got register constant output"] }
}

Allocate Var@C Function[func,name,type:out]
{
	Print[["Allocate Var: "]Append[name]]
	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]
	Print[["Release: "]Append[source]]
	out <- [func]Add Statement[[["release_ref("]Append[source]]Append[")"]]
}

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

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

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]
{
	Print["Set Field Null"]
	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 Statement[
		[[["call->params["
		]Append[inputnum]
		]Append["] = "]
		]Append[val]
	]
}

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

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

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

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]
{
	rargs <- Map[args, ["Make Op"]Set Input[1, func]]
	out <- [Fold["_Function Arg C", func, rargs]
	]Add Raw Line[[[ [type]Append["("] ]Append[ [[func]Field Registry >>]Field ID[field] ]]Append[")"]]
}

Get Field Call@C Function[func,field,source:out]
{
	out <- [func]Field Base[field, [()]Append[source], "GFieldCall"]
}

Set Field Call@C Function[func,field,object,value:out]
{
	out <- [func]Field Base[field, [[()]Append[object]]Append[value], "SFieldCall"]
}

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 <- [["cdata->params["]Append[~]]Append["]"]
		}{
			out <- ["locals->"]Append[Escape Rhope Name[op]]
		}
	}{
		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]
{
	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["}"]

}

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

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:out]
{
	out <- [string]Append[[[ [ ["\tRet("]Append[inputnum] ]Append[", locals->"]]Append[inputname]]Append[")\n"]]
}

Set Outputs@C Function[func:out]
{
	If[[[func]Convention >>] = ["rhope"]]
	{
		out <- Fold["_Set Outputs C", "", [func]Outputs >>]
	}{
		[[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["} l_"]]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"]
		}
	}{
		proto <- [[func]Naked Proto]Append[";\n"]
	}
	out <- [localtype]Append[proto]
	}
}

_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]
{
	Print[["Naked Proto: "]Append[ [func]Name >>] ]
	[[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[")"]
	{ Print[~] }
}

Type Check@C Function[func,text,type,input num:out]
{
	If[[type] = ["Any Type"]]
	{
		out <- text
	}{
		out <- [text]Append[ [["\tParam("]Append[input num]]Append[ [[", "]Append[ [[func]Type Registry >>]Type ID[type] ]]Append[")"] ] ]
	}
}

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"] ]
	{
		cname <- 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 <- [[[[[[["FuncNoLocals("
				]Append[cname]
				]Append[",\n\tNumParams "]
				]Append[ [[func]Inputs >>]Length ]
				]Append[",\n\tCallSpace 32)\n\n"]//TODO: Fill in with calculated callspace value
				]Append[param check]
				]Append[ [[func]Statements >>]Join[""] ]
				]Append["EndFunc"]
		}{
			out <- [[[[[[[[[["Func("
				]Append[cname]
				]Append[",\n\tNumParams "]
				]Append[ [[func]Inputs >>]Length ]
				]Append[",\n\tCallSpace 32,\n\t"]//TODO: Fill in with calculated callspace value
				]Append[["l_"]Append[cname]]
				]Append[")\n\n"]
				]Append[param check]
				]Append[ [[func]Statements >>]Join[""] ]
				]Append[[func]Set Outputs]
				]Append["EndFunc"]
		}
	}{
		
		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"] ]
}

_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"]]
		{ 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"]]
			{ 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"]]
					{ Print["_Set Consts got output yes"] }
				}{
					out <- [text]Append[[["\t_const_"]Append[Escape Rhope Name[name]]]Append[" = (object *)val_no;\n"]]
					{ Print["_Set Consts got output no"] }
				}
			}{
				If[[valtype] = ["Machine Integer"]]
				{
					If[[value]Signed? >>]
					{ s <- "I" }
					{ s <- "UI" }
					
					make <- [[[" = make_"]Append[s]]Append["nt"]]Append[[value]Size >>]
					out <- [text]Append[ [[[[["\t_const_"]Append[Escape Rhope Name[name]]]Append[make]]Append["("]]Append[[value]Value >>]]Append[");\n"] ]
				}{
					out <- text
				}
			}
		}
	}
}

_Set Late Consts C[text,value,name,type reg:out]
{
	valtype <- Type Of[value]
	If[[valtype] = ["String"]]
	{
		out <- [text]Append[ [[[["\t_const_"]Append[Escape Rhope Name[name]]]Append[" = make_String(\""]]Append[ [[value]Replace["\n", "\\n"]]Replace["\\", "\\\\"]]]Append["\");\n"] ]
	}{
		out <- text
	}
}

Text@C Program[program:out]
{
	Print["Text@C Program"]
	constants <- Fold["Combine Consts", Dictionary[], [program]Functions >>]
	headers <- "#include <stdio.h>
#include \"builtin.h\"
#include \"object.h\"
#include \"context.h\"
#include \"func.h\"
#include \"integer.h\"
#include \"blueprint.h\"
#include \"array.h\"
#include \"bool.h\"\n\n"
	out <- [[[[[[[headers
		]Append[[[program]Type Registry >>]Type Defs]
		]Append[Fold[["_Text C Program"]Set Input[2, [program]Type Registry >>], 
				Fold["_Consts C Program", 
					Fold["_Defs C Program", "", [program]Functions >>], 
					constants
				], [program]Functions >>]]
		]Append["#include \"builtin.c\"\n#include \"array.c\"\n\nint main(int argc, char **argv)
{
	returntype ret;
	calldata *cdata;
	context * ct;
	blueprint * bp;
	register_builtin_types();\n\n"]
		]Append[ [[program]Type Registry >>]Type Inits[[program]Method Registry >>, [program]Field Registry >>] ]
		]Append[Fold[["_Set Consts C Program"]Set Input[3, [program]Type Registry >>], "", constants]]
		]Append[Fold[["_Set Late Consts C"]Set Input[3, [program]Type Registry >>], "", constants]]
		]Append["
	ct = new_context();
	cdata = alloc_cdata(ct, 0);
	cdata->num_params = 0;
	cdata->resume = 0;
	ret = f_Main(cdata);
	while(ret == TAIL_RETURN)
		ret = cdata->tail_func(cdata);
	if(ret == EXCEPTION_RETURN) {
		puts(\"Exception!\");
		return -1;
	}
	return 0;
}\n\n"]

}