changeset 2:73e978d590c7

Adding WIP compiler code
author Mike Pavone <pavone@retrodev.com>
date Wed, 29 Apr 2009 02:58:03 -0400
parents b3f71490858c
children 94c885692eb5 0c5f24b4f69d
files cbackend.rhope compile.rhope countstring.rhope genasm.rhope lex.rhope nworker.rhope parse.rhope
diffstat 7 files changed, 1963 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cbackend.rhope	Wed Apr 29 02:58:03 2009 -0400
@@ -0,0 +1,84 @@
+
+Blueprint Blueprint Def
+{
+	Name
+	Fixed Size
+	Fields
+	Methods
+}
+
+Blueprint Def[name]
+{
+	out <- [[[[Build["Blueprint Def"]]Name <<[name]]Fixed Size <<[0]]Fields <<[()]]Methods <<[New@Dictionary[]]
+}
+
+Blueprint C Function
+{
+	Name
+	Inputs
+	Outputs
+	Convention
+	Variables
+	Statements
+}
+
+C Function[name,inputs,outputs,convention:out]
+{
+	out <- [[[[[[Build["C Function"]
+		]Name <<[name]
+		]Inputs <<[inputs]
+		]Outputs <<[outputs]
+		]Convention <<[convention]
+		]Variables <<[New@Dictionary[]]
+		]Statements <<[()]
+}
+
+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[[statement]Append[";"]] ]
+}
+
+Add Operator Statement@C Function[func,source1,source2,dest,op:out]
+{
+	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," / "]
+}
+
+Move@C Function[func,source,dest:out]
+{
+	out <- [func]Add Statement[[[dest]Append[" = "]]Append[source]]
+}
+
+Definitions@C Function[func:out]
+{
+	
+}
+
+Text@C Function[func:out]
+{
+	
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/compile.rhope	Wed Apr 29 02:58:03 2009 -0400
@@ -0,0 +1,17 @@
+Import lex.rhope
+Import countstring.rhope
+Import parse.rhope
+
+Main[args]
+{
+	[args]Index[1]
+	{
+		Print[["Parsing "]Append[~]]
+		file <- <String@File[~]
+		,data <- [file]Get FString[[file]Length]
+		tokens <- Lex[Count String[data]]
+		Pretty Print[Parse[tokens], ""]
+	}{
+		Print["Usage: rhope compile.rhope <filename>"]
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/countstring.rhope	Wed Apr 29 02:58:03 2009 -0400
@@ -0,0 +1,106 @@
+
+Blueprint Count String
+{
+	Text
+	Line
+	Column
+}
+
+Count String[text:out]
+{
+	out <- Count String At Pos[text, 0, 0]
+}
+
+Count String At Pos[text,line,col:out]
+{
+	out <- [[[Build["Count String"]]Text <<[text]]Line <<[line]]Column <<[col]
+}
+
+Slice@Count String[string,index:left,right]
+{
+	
+	If[[index] = [0]]
+	{
+		left <- [string]Text <<[""]
+		right <- Val[string]
+	}{
+		ltext,rtext <- [[string]Text >>]Slice[index]
+		left <- [string]Text <<[ltext]
+		parts <- [ltext]Split["\n"]
+		last line <- [[parts]Length] - [1]
+		rline <- [[string]Line >>] + [last line]
+		prercol <- [[parts]Index[last line]]Length
+		If[[last line] > [0]]
+		{
+			rcol <- Val[prercol]
+		}{
+			rcol <- [prercol] + [[string]Column >>]
+		}
+		right <- Count String At Pos[rtext, rline, rcol]
+	}
+}
+
+Length@Count String[string:out]
+{
+	out <- Length[[string]Text >>]
+}
+
+Append@Count String[left,right:out]
+{
+	If[[[left]Length] > [0]]
+	{
+		out <- [left]Text << [ [To String[left]]Append[To String[right]] ]
+	}{
+		out <- right
+	}
+}
+
+=@Count String[left,right:out]
+{
+	out <- [To String[left]] = [To String[right]]
+}
+
+Get DString@Count String[string, delims:after,before,delim,nomatch]
+{
+	,,delim,nomatch <- [[string]Text >>]Get DString[delims]
+	{
+		If[[dlines] > [0]]
+		{
+			cols <- Val[dcols]
+		}{
+			If[[blines] > [0]]
+			{
+				cols <- [bcols] + [dcols]
+			}{
+				cols <- [[bcols] + [dcols]] + [[string]Column >>]
+			}
+		}
+		after <- Count String At Pos[~, [[blines]+[dlines]] + [[string]Line >>], cols]
+	}{
+		before <- [string]Text <<[~]
+		bparts <- [~]Split["\n"]
+		preblines <- [[bparts]Length] - [1]
+		If[[preblines] > [-1]]
+		{
+			blines <- Val[preblines]
+			bcols <- Length[[bparts]Index[blines]]
+		}{
+			bcols <- 0
+			blines <- 0
+		}
+	}{
+		dparts <- [~]Split["\n"]
+		dlines <- [[dparts]Length] - [1]
+		dcols <- Length[[dparts]Index[dlines]]
+	}
+}
+
+To String@Count String[string:out]
+{
+	out <- [string]Text >>
+}
+
+Empty@Count String[string:out]
+{
+	out <- Count String[""]
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/genasm.rhope	Wed Apr 29 02:58:03 2009 -0400
@@ -0,0 +1,940 @@
+//Import extendlib.rhope
+Escape Rhope Name[name:escaped]
+{
+	escaped <- [[[[[[[[[name]Replace["_","__"]
+		]Replace["@","_AT_"]
+		]Replace[" ","_SP_"]
+		]Replace[":","_CN_"]
+		]Replace["?","_QN_"]
+		]Replace["+","_PL_"]
+		]Replace["-","_MN_"]
+		]Replace["*","_TM_"]
+		]Replace["/","_DV_"]
+}
+
+Blueprint Registers
+{
+	Names
+	Can Data
+	Can Pointer
+	Available?
+	Need Save
+	Max Size
+}
+
+Set Yes[in:out]
+{
+	out <- Yes
+}
+
+_Flip[dest,val,index:out]
+{
+	out <- [dest]Set[val,index]
+}
+Flip[list,dest:out]
+{
+	out <- Fold["_Flip", dest, list]
+}
+
+Registers[names, data, pointer, need save, max size:out]
+{
+	out <- [[[[[[Build["Registers"]
+	]Names << [names]
+	]Can Data << [data]
+	]Can Pointer << [pointer]
+	]Available? << [ Map[names, "Set Yes"] ]
+	]Need Save << [ Flip[need save, ()] ]
+	]Max Size <<[max size]
+}
+
+Name@Registers[regs,num:out]
+{
+	out <- [[regs]Names >>]Index[num]
+}
+
+Allocate Helper@Registers[regs, try, current:found, not found]
+{
+	reg <- [try]Index[current]
+	If[[[regs]Available? >>]Index[reg]]
+	{
+		found <- Val[reg]
+	}{
+		[try]Next[current]
+		{
+			found, not found <- [regs]Allocate Helper[try, ~]
+		}{
+			not found <- Yes
+		}
+	}
+}
+
+Allocate Reg@Registers[regs,try:next regs,found,need save?,not found]
+{
+	[try]First
+	{
+		found, not found <- [regs]Allocate Helper[try, ~]
+		{
+			next regs <- [regs]Available? << [ [[regs]Available? >>]Set[~, No] ]
+			[[regs]Need Save >>]Index[~]
+			{
+				need save? <- Yes
+			}{
+				need save? <- No
+			}
+		}
+	}{
+		not found <- Yes
+	}
+}
+
+Free Reg@Registers[regs,num:out]
+{
+	out <- [regs]Available? <<[ [[regs]Available? >>]Set[num, Yes] ]
+}
+
+Processor Reg[func,type:next func,num,not found]
+{
+	regs <- [func]Registers >>
+	If[[type] = ["pointer"]]
+	{
+		source <- [regs]Can Pointer >>
+	}{
+		source <- [regs]Can Data >>
+	}
+	next regs, reg num, need save?, not found <- [regs]Allocate Reg[source] {}
+	{
+		If[need save?]
+		{
+			next func <- [[func]Need Save << [ [[func]Need Save >>]Set[reg num, Yes] ]
+			]Registers << [next regs]
+		}{
+			next func <- [func]Registers << [next regs]
+		}
+		num <- Val[reg num]
+	}
+}
+
+Processor Free Reg[func,num:out func]
+{
+	out func <- [func]Registers <<[  [[func]Registers >>]Free Reg[num] ]
+}
+
+Processor Allocate[func,name,size,type:out func,out]
+{
+	regs <- [func]Registers >>
+	If[[type] = ["pointer"]]
+	{
+		alloc size <- [func]Pointer Size
+	}{
+		alloc size <- size
+	}
+	If[[alloc size] > [[regs]Max Size >>]] {
+			stack alloc <- Val[alloc size]
+	}{
+		next func <- [func]Processor Reg[type] {}
+		{
+			location <- Register[~, alloc size]
+		}{
+			stack alloc <- Val[alloc size]
+		}
+	}
+	Val[stack alloc]
+	{
+		next func, location <- [func]Allocate Stack[alloc size]
+	}
+	out func <- [next func]Variables <<[ [[next func]Variables >>]Set[name, location] ]
+	out <- Val[location]
+}
+
+Blueprint Register
+{
+	Number
+	Value Size
+}
+Register[num,size:out]
+{
+	If[[size] = [3]]
+	{
+		value size <- 4
+	}{
+		value size <- size
+	}
+	out <- [[Build["Register"]]Number <<[num]]Value Size <<[value size]
+}
+
+In Memory?@Register[reg:out]
+{
+	out <- No
+}
+
+=@Register[reg,other:out]
+{
+	,out <- If[[Type Of[reg]] = [Type Of[other]]]
+	{
+		out <- [[reg]Number >>] = [[other]Number >>]
+	}
+}
+
+Op ASM@Register[reg,func,regs,extra offset:out]
+{
+	out <- [regs]Index[ [reg]Number >> ]
+}
+
+Size@Register[reg:out]
+{
+	out <- [reg]Value Size >>
+}
+
+Blueprint Immediate
+{
+	Value
+}
+
+Immediate[val:out]
+{
+	out <- [Build["Immediate"]]Value <<[val]
+}
+
+In Memory?@Immediate[val:out]
+{
+	out <- No
+}
+
+=@Immediate[val,other:out]
+{
+	,out <- If[[Type Of[val]] = [Type Of[other]]]
+	{
+		out <- [[val]Value >>] = [[other]Value >>]
+	}
+}
+
+Op ASM@Immediate[val,func,regs,extra offset:out]
+{
+	out <- [val]Value >>
+}
+
+Size@Immediate[val:out]
+{
+	out <- 4
+}
+
+Blueprint None
+{
+	Dummy
+}
+
+None[:out]
+{
+	out <- Build["None"]
+}
+
+In Memory?@None[none:out]
+{
+	out <- No
+}
+
+Op ASM@None[none,func,regs,extra offset:out]
+{
+	out <- ""
+}
+
+Size@None[none:out]
+{
+	out <- 0
+}
+
+Blueprint Stack Location
+{
+	Offset
+	Size
+}
+
+Stack Location[offset,size:out]
+{
+	out <- [[Build["Stack Location"]]Offset <<[offset]]Size <<[size]
+}
+
+In Memory?@Stack Location[location:out]
+{
+	out <- Yes
+}
+
+=@Stack Location[loc,other:out]
+{
+	,out <- If[[Type Of[loc]] = [Type Of[other]]]
+	{
+		out <- [[loc]Offset >>] = [[other]Offset >>]
+	}
+}
+
+Op ASM@Stack Location[loc,func,regs,extra offset:out]
+{
+	offset <- [[[func]Stack Size >>] - [[loc]Offset >>]] - [[loc]Size >>]
+	If[[offset] > [0]]
+	{
+		toffset <- ["+"]Append[offset]
+	}{
+		toffset <- ""
+	}
+	out <- [["[esp"]Append[toffset]]Append["]"]
+}
+
+Size@Stack Location[loc:out]
+{
+	out <- [loc]Size >>
+}
+
+Blueprint Pointer
+{
+	Base
+	Offset
+	Target Size
+}
+
+Pointer[base,offset,size:out]
+{
+	out <- [[[Build["Pointer"]]Base <<[base]]Offset <<[offset]]Target Size <<[size]
+}
+
+In Memory?@Pointer[location:out]
+{
+	out <- Yes
+}
+
+=@Pointer[pointer,other:out]
+{
+	,out <- If[[Type Of[loc]] = [Type Of[other]]]
+	{
+		out <- [[loc]Storage >>] = [[other]Storage >>]
+	}
+}
+
+Op ASM@Pointer[pointer,func,regs,extra offset:out]
+{
+	If[[Type Of[ [pointer]Offset >> ]] = ["None"]]
+	{
+		out <- [["["]Append[ [[pointer]Base >>]Op ASM[func,regs,extra offset] ]]Append["]"]
+	}{
+		out <- [[[["["
+			]Append[ [[pointer]Base >>]Op ASM[func,regs,extra offset] ]
+			]Append["+"]
+			]Append[ [[pointer]Offset >>]Op ASM[func,regs,extra offset] ]
+			]Append["]"]
+	}
+}
+
+Size@Pointer[pointer:out]
+{
+	out <- [pointer]Target Size >>
+}
+
+Blueprint X86 Instruction
+{
+	Name
+	Op1
+	Op2
+	Width
+	Extra Offset
+}
+
+X86 Instruction[name, op1, op2, width:out]
+{
+	out <- [[[[[Build["X86 Instruction"]]Name << [name]]Op1 << [op1]]Op2 <<[op2]]Width <<[width]]Extra Offset <<[0]
+}
+
+CAppend[left,right:out]
+{
+	If[[right] = [""]]
+	{
+		out <- ""
+	}{
+		out <- [left]Append[right]
+	}
+}
+
+Inst ASM@X86 Instruction[inst,func:out]
+{
+	If[[[inst]Width >>] = [4]]
+	{
+		regs <- ("eax","ecx","edx","ebx","esi","edi","esp")
+	}{
+		If[[[inst]Width >>] = [2]]
+		{
+			regs <- ("ax","cx","dx","bx","si","di")
+		}{
+			regs <- ("al","cl","dl","bl","si","di")
+		}
+	}
+	out <- [[[inst]Name >>
+	]Append[ [" "]CAppend[[[inst]Op1>>]Op ASM[func, regs, [inst]Extra Offset >>]] ]
+	]Append[ [", "]CAppend[[[inst]Op2>>]Op ASM[func, regs, [inst]Extra Offset >>]] ]
+}
+
+Blueprint X86 Function
+{
+	Name
+	Registers
+	Variables
+	Scratch
+	Need Save
+	Free Stack Locations
+	Stack Size
+	Param Size
+	Temp Stack
+	Convention
+	Instructions
+}
+
+X86 Function[name,params,convention:out]
+{
+	[[[[[[[[[Build["X86 Function"]
+	]Name << [name]
+	]Registers << [Registers[("eax","ecx","edx","ebx","esi","edi"), (0,1,2,3,4,5), (0,1,2,3,4,5), (3,4,5), 4]]
+	]Variables  <<[New@Dictionary[]]
+	]Need Save <<[()]
+	]Free Stack Locations <<[()]
+	]Stack Size <<[0]
+	]Instructions <<[()]
+	]Convention <<[convention]
+	]Alloc Params[params, convention]
+	{
+		out <- [~]Param Size <<[ [~]Stack Size >> ]
+	}
+}
+
+Pointer Size@X86 Function[func:out]
+{
+	out <- 4
+}
+
+Param Helper@X86 Function[func, param:out]
+{
+	,loc <- [func]Allocate Stack[4]
+	{
+		out <- [~]Variables << [ [[~]Variables >>]Set[param, loc] ]
+	}
+}
+
+Alloc Params@X86 Function[func,params,convention:out]
+{
+	If[[convention] = ["fastcall"]]
+	{
+		[params]Index[0]
+		{
+				next func <- [[func]Registers <<[ [[func]Registers >>]Available? <<[ [[[func]Registers >>]Available? >>]Set[1, No] ]]
+				]Variables <<[ [[func]Variables >>]Set[~, Register[1,4]] ]
+				[params]Index[1]
+				{
+					next func2 <- [[next func]Registers <<[ [[next func]Registers >>]Available? <<[ [[[next func]Registers >>]Available? >>]Set[2, No] ]]
+					]Variables <<[ [[next func]Variables >>]Set[~, Register[2,4]] ]
+					[params]Index[2]
+					{
+						out <- _Fold[params, 2, next func2, "Param Helper"]
+					}{
+						out <- Val[next func2]
+					}
+				}{
+					out <- Val[next func]
+				}
+		}{
+			out <- func
+		}
+	}{
+		out <- Fold["Param Helper", func, params]
+	}
+}
+
+Add Instruction@X86 Function[func, inst:out]
+{
+	out <- [func]Instructions << [ [[func]Instructions >>]Append[ [inst]Extra Offset <<[[func]Temp Stack >>] ] ]
+}
+
+Allocate Stack@X86 Function[func,size:func out,out]
+{
+	out <- Stack Location[[func]Stack Size >>, size]
+	func out <- [func]Stack Size <<[ [[func]Stack Size >>]+[size] ]
+}
+
+Allocate Var@X86 Function[func,name,size,type:out func,out]
+{
+	out func, out <- Processor Allocate[func,name,size,type]
+}
+
+Resolve@X86 Function[func,op:out,out func]
+{
+	If[[Type Of[op]] = ["String"]]
+	{
+		out <- [[func]Variables >>]Index[op]
+	}{
+		out <- op
+	}
+}
+
+Allocate Scratch@X86 Function[func,size:out func,scratch]
+{
+	out func,scratch <- Processor Reg[func,"data"] {} {}
+	{
+		//FIXME: need to use a reg that's not involved in the current op
+		//FIXME: Also, might need two scratch regs and both might be in use
+		,stack inc <- [func]Save Reg[0]
+		{
+			out func <- [~]Scratch << [ [[~]Scratch >>]Set[0, Yes] ]
+		}
+	}
+}
+
+Free Scratch@X86 Function[func,scratch:out func]
+{
+	[[func]Scratch >>]Index[scratch]
+	{
+		[func]Restore Reg[scratch]
+		{
+			out func <- [~]Scratch << [ [[~]Scratch >>]Remove[scratch] ]
+		}
+	}{
+		out func <- Processor Free Reg[func, scratch]
+	}
+	If[[scratch]Index[1]]
+	{
+		
+	}{
+		
+	}
+}
+
+Classify Op@X86 Function[func,op:class]
+{
+	If[[op]In Memory?]
+	{
+		If[[Type Of[op]] = ["Pointer"]]
+		{
+			If[[[[op]Base >>]In Memory?] Or [[[op]Offset >>]In Memory?]]
+			{
+				class <- "u"
+			}{
+				class <- "m"
+			}
+		}{
+			class <- "m"
+		}
+	}{
+		class <- "r"
+	}
+}
+
+RegMem2Op@X86 Function[func,dest,notdest,op,size:out]
+{
+	out <- [func]Add Instruction[X86 Instruction[op, dest, notdest, size]]
+}
+
+MemPointer2Op@X86 Function[func,dest,notdest,op,size:out]
+{
+	,scratch <- [func]Allocate Scratch[size]
+	{
+		out <- [[[~]Fetch[notdest,scratch]
+			]Add Instruction[X86 Instruction[op, dest, scratch, size]]
+			]Free Scratch[scratch]
+	}
+}
+
+//Make sure to map this to both r, (m or r) -> m and r, (m or r) -> r
+RegMemToNotPointer@X86 Function[func,source1,source2,dest,op,size:out]
+{
+	out <- [[func]Move[source2,dest]
+		]Add Instruction[X86 Instruction[op, dest, source1, size]]
+}
+
+RegMemToPointer@X86 Function[func,source1,source2,dest,op,size:out]
+{
+	,scratch <- [func]Allocate Scratch[size]
+	{
+		spointer <- Pointer[scratch, None[], size]
+		out <- [[[[~]Calculate Address[dest, scratch]
+			]Move[source2, spointer]
+			]Add Instruction[X86 Instruction[op, spointer, source1, size]]
+			]Free Scratch[scratch]
+	}
+}
+
+RegPointerToMem@X86 Function[func,source1,source2,dest,op,size:out]
+{
+	,scratch <- [func]Allocate Scratch[size]
+	{
+		spointer <- Pointer[scratch, None[], size]
+		out <- [[[[~]Calculate Address[source2, scratch]
+			]Move[spointer, dest]
+			]Add Instruction[X86 Instruction[op, dest, source1, size]]
+			]Free Scratch[scratch]
+	}
+}
+
+RegPointerReg2Op@X86 Function[func,dest,notdest,op,size:out]
+{
+	,scratch <- [func]Allocate Scratch[size]
+	{
+		spointer <- Pointer[scratch, None[], size]
+		out <- [[[~]Calculate Address[notdest, scratch]
+			]Add Instruction[X86 Instruction[op, dest, spointer, size]]
+			]Free Scratch[scratch]
+	}
+}
+
+RegPointerPointer2Op@X86 Function[func,dest,notdest,op,size:out]
+{
+	,scratch <- [func]Allocate Scratch[size]
+	{
+		spointer <- Pointer[scratch, None[], size]
+		out <- [[[~]Calculate Address[dest, scratch]
+			]Add Instruction[X86 Instruction[op, spointer, notdest, size]]
+			]Free Scratch[scratch]
+	}
+}
+
+RegPointerToPointer@X86 Function[func,source1,source2,dest,op,size:out]
+{
+	,scratch <- [func]Allocate Scratch[size]
+	{
+		spointer <- Pointer[scratch, None[], size]
+		,scratch2 <- [~]Allocate Scratch[size]
+		{
+			spointer2 <- Pointer[scratch2, None[], size]
+			out <- [[[[[[~]Calculate Address[source2, scratch]
+				]Calculate Address[dest, scratch2]
+				]Move[spointer2, spointer]
+				]Add Instruction[X86 Instruction[op, spointer2, source1, size]]
+				]Free Scratch[scratch2]
+				]Free Scratch[scratch]
+		}
+	}
+}
+
+//If source1, source2 and dest are all pointers with register offsets, allocating a scratch register could
+//become a problem unless I let ebp be used as a scratch register. Should be doable as long as thread local
+//variables properly report ebp as a used register. Alternatively, one register could be reserved for scratch
+//usage
+MemPointerToMem@X86 Function[func,source1,source2,dest,op,size:out]
+{
+	,scratch <- [func]Allocate Scratch[size]
+	{
+		out <- [[[[~]Fetch[source2, scratch]
+			]Add Instruction[X86 Instruction[op, scratch, source1, size]]
+			]Move[scratch, dest]
+			]Free Scratch[scratch]
+	}
+}
+
+MemPointerToPointer@X86 Function[func,source1,source2,dest,op,size:out]
+{
+	,scratch <- [func]Allocate Scratch[size]
+	{
+		,scratch2 <- [~]Allocate Scratch[size]
+		{
+			spointer2 <- Pointer[scratch2, None[], size]
+			out <- [[[[[[~]Fetch[source2, scratch]
+				]Add Instruction[X86 Instruction[op, scratch, source1, size]]
+				]Calculate Address[dest, scratch2]
+				]Move[scratch, spointer2]
+				]Free Scratch[scratch2]
+				]Free Scratch[scratch]
+		}
+	}
+}
+
+//This does almost the same thing as RegMemToNotPointer, depending on how I do the pattern matching I could maybe combine them
+PointerMemToReg@X86 Function[func,source1,source2,dest,op,size:out]
+{
+	out <- [[func]Fetch[source1,dest]
+		]Add Instruction[X86 Instruction[op, dest, source2, size]]
+}
+
+PointerPointer2Op@X86 Function[func,dest,notdest,op,size:out]
+{
+	,scratch <- [func]Allocate Scratch[size]
+	{
+		spointer <- Pointer[scratch, None[], size]
+		,scratch2 <- [~]Allocate Scratch[size]
+		{
+			out <- [[[[[[[~]Calculate Address[dest, scratch]
+				]Fetch[notdest, scratch2]
+				]Add Instruction[X86 Instruction[op, scratch, scratch2, size]]
+				]Calculate Address[dest, scratch2]
+				]Move[scratch, spointer2]
+				]Free Scratch[scratch2]
+				]Free Scratch[scratch]
+		}
+	}
+}
+
+PointerPointerToPointer@X86 Function[func,source1,source2,dest,op,size:out]
+{
+	,scratch <- [func]Allocate Scratch[size]
+	{
+		,scratch2 <- [~]Allocate Scratch[size]
+		{
+			spointer2 <- Pointer[scratch2, None[], size]
+			out <- [[[[[[[~]Fetch[source1, scratch]
+				]Calculate Address[source2, scratch2]
+				]Add Instruction[X86 Instruction[op, scratch, spointer2, size]]
+				]Calculate Address[dest, scratch2]
+				]Move[scratch, spointer2]
+				]Free Scratch[scratch2]
+				]Free Scratch[scratch]
+		}
+	}
+}
+
+PointerPointerToMem@X86 Function[func,source1,souce2,dest,op,size:out]
+{
+	,scratch <- [func]Allocate Scratch[size]
+	{
+		spointer <- Pointer[scratch, None[], size]
+		out <- [[[[[~]Calculate Address[source1, scratch]
+			]Move[dest, spointer]
+			]Fetch[source2, scratch]
+			]Add Instruction[X86 Instruction[op, dest, scratch, size]]
+			]Free Scratch[scratch]
+	}
+}
+
+PointerPointerToReg@X86 Function[func,source1,souce2,dest,op,size:out]
+{
+	,scratch <- [func]Allocate Scratch[size]
+	{
+		spointer <- Pointer[scratch, None[], size]
+		out <- [[[[~]Fetch[source1, dest]
+			]Calculate Address[source2, scratch]
+			]Add Instruction[X86 Instruction[op, dest, scratch, size]]
+			]Free Scratch[scratch]
+	}
+}
+
+2Op Associative@X86 Function[func,psource1,psource2,pdest,name:out func]
+{
+	source1 <- [func]Resolve[psource1]
+	source2 <- [func]Resolve[psource2]
+	dest <- [func]Resolve[pdest]
+	dest class <- [func]Classify Op[dest]
+	width <- Min[Min[Min[[source1]Size,[source2]Size], [dest]Size], 4]
+	swapper <- (1,0)
+	sources <- [[()]Append[source1]Append[source2]
+	[sources]Find[dest]
+	{
+		source <- [swapper]Index[~]
+		source class <- [func]Classify Op[source]
+		If[[dest class] = ["u"]]
+		{
+			If[[source class] = ["r"]]
+			{
+				out func <- [func]RegPointerPointer2Op[dest,source,name,width]
+			}{
+				out func <- [func]PointerPointer2Op[dest,source,name,width]
+			}
+		}{
+			If[[dest class] = ["r"]]
+			{
+				If[[source class] = ["u"]]
+				{
+					out func <- [func]RegPointerReg2Op[dest,source,name,width]
+				}{
+					out func <- [func]RegMem2Op[dest,source,name,width]
+				}
+			}{
+				If[[source class] = ["r"]]
+				{
+					out func <- [func]RegMem2Op[dest,source,name,width]
+				}{
+					out func <- [func]MemPointer2Op[dest,source,name,width]
+				}
+			}
+		}
+	}{
+		sclasses <- Map[sources, ["Classify Op"]Set Input[0, func]]
+		first <- [sources]Index[found index]
+		other index <- [swapper]Index[found index]
+		other <- [sources]Index[other index]
+		other class <- [sclasses]Index[other index]
+		found index <- [sclasses]Find["r"]
+		{
+			If[[other class] = ["u"]]
+			{
+				If[[dest class] = ["m"]]
+				{
+					out func <- [func]RegPointerToMem[first,other,dest,name,width]
+				}{
+					If[[dest class] = ["u"]]
+					{
+						out func <- [func]RegPointerToPointer[first,other,dest,name,width]
+					}{
+						out func <- [func]PointerMemToReg[other,first,dest,name,width]
+					}
+				}
+			}{
+				If[[dest class] = ["u"]]
+				{
+					out func <- [func]RegMemToPointer[first,other,dest,name,width]
+				}{
+					out func <- [func]RegMemToNotPointer[first,other,dest,name,width]
+				}
+			}
+		}{
+			found index <- [sclasses]Find["m"]
+			{
+				If[[dest class] = ["r"]]
+				{
+					out func <- [func]PointerMemToReg[other,first,dest,name,width]
+				}{
+					If[[dest class] = ["m"]]
+					{
+						out func <- [func]MemPointerToMem[first,other,dest,name,width]	
+					}{
+						out func <- [func]MemPointerToPointer[first,other,dest,name,width]
+					}
+				}
+			}{
+				If[[dest class] = ["r"]]
+				{
+					out func <- [func]PointerPointerToReg[first,other,dest,name,width]
+				}{
+					If[[dest class] = ["m"]]
+					{
+						out func <- [func]PointerPointerToMem[first,other,dest,name,width]
+					}{
+						out func <- [func]PointerPointerToPointer[first,other,dest,name,width]
+					}
+				}
+			}
+		}
+	}
+}
+
+2Op@X86 Function[func,psource1,psource2,pdest,name:out func]
+{
+	source1 <- [func]Resolve[psource1]
+	source2 <- [func]Resolve[psource2]
+	dest <- [func]Resolve[pdest]
+	width <- Min[Min[Min[[source1]Size,[source2]Size], [dest]Size], 4]
+	If[[source1] = [dest]]
+	{
+		If[[[source1]In Memory?] And [[source2]In Memory?]]
+		{
+			,scratch, stack inc <- [func]Allocate Scratch[width]
+			{
+				out func <- [[[~]Add Instruction[X86 Instruction["mov", [scratch]Index[0], source2, width, stack inc]]
+				]Add Instruction[X86 Instruction[name, source1, [scratch]Index[0], width, stack inc]]
+				]Free Scratch[scratch]
+			}
+		}{
+			out func <- [func]Add Instruction[X86 Instruction[name, dest, source2, width, 0]]
+		}
+	}{
+		If[[dest]In Memory?]
+		{
+			If[[source2]In Memory?]
+			{
+				,scratch, stack inc <- [func]Allocate Scratch[width]
+				{
+					out func <- [[[[~]Add Instruction[X86 Instruction["mov", [scratch]Index[0], source1, width, stack inc]]
+					]Add Instruction[X86 Instruction[name, [scratch]Index[0], source2, width, stack inc]]
+					]Add Instruction[X86 Instruction["mov", dest, [scratch]Index[0], width, stack inc]]
+					]Free Scratch[scratch]
+				}
+			}{
+				out func <- [[func]Move[source1,dest]
+				]Add Instruction[X86 Instruction[name, dest, source2, width, 0]]
+			}
+		}{
+			out func <- [[func]Move[source1,dest]
+			]Add Instruction[X86 Instruction[name, dest, source2, width, 0]]
+		}
+	}
+}
+
+Add@X86 Function[func,source1,source2,dest:out func]
+{
+	out func <- [func]2Op Associative[source1,source2,dest,"add"]
+}
+
+Sub@X86 Function[func,source1,source2,dest:out func]
+{
+	out func <- [func]2Op[source1,source2,dest,"sub"]
+}
+
+Move@X86 Function[func,psource,pdest:out func]
+{
+	source <- [func]Resolve[psource]
+	dest <- [func]Resolve[pdest]
+	out func <- [func]Add Instruction[X86 Instruction["mov", dest, source, 4]]
+}
+
+Instruction ASM[current,instruction,func:out]
+{
+	out <- [[[current]Append["\t"]]Append[ [instruction]Inst ASM[func] ]]Append["\n"]
+}
+
+Save Reg@X86 Function[func,reg:out]
+{
+	out <- [[func]Add Instruction[X86 Instruction["push", Register[reg, 4], None[], 4]]
+	]Temp Stack << [ [[func]Temp Stack >>]+[4] ]
+}
+
+Prolog Save@X86 Function[func,junk,reg:out]
+{
+	out <- [[func]Add Instruction[X86 Instruction["push", Register[reg, 4], None[], 4]]
+	]Stack Size << [ [[func]Stack Size >>]+[4] ]
+}
+
+Restore Reg@X86 Function[func,reg:out]
+{
+	out <- [[func]Add Instruction[X86 Instruction["pop", Register[reg, 4], None[], 4]]
+	]Temp Stack << [ [[func]Temp Stack >>]-[4] ]
+}
+
+Epilogue Restore@X86 Function[func,junk,reg:out]
+{
+	out <- [func]Add Instruction[X86 Instruction["pop", Register[reg, 4], None[], 4]]
+}
+
+Finalize@X86 Function[func:out]
+{
+	alloc stack <- [[func]Stack Size >>] - [[func]Param Size >>]
+	
+	oldstream <- [func]Instructions >>
+	
+	If[[alloc stack] > [0]]
+	{
+		start <- [()]Append[X86 Instruction["sub", Register[6, 4],Immediate[alloc stack], Register[6, 4], 4], func]
+	}{
+		start <- ()
+	}
+	
+	If[[[func]Convention >>] = ["cdecl"]]
+	{
+		If[ [alloc stack] > [0] ]
+		{
+			retparam <- Immediate[alloc stack]
+		}{
+			retparam <- None[]
+		}
+	}{
+		retparam <- Immediate[[func]Stack Size >>]
+	}
+	
+	[[func]Need Save >>]First
+	{
+		prolog <- Fold["Prolog Save", [func]Instructions << [start], [func]Need Save >>]
+		out <- [Reverse Fold["Epilogue Restore", body, [func]Need Save >>]]Add Instruction[X86 Instruction["ret", retparam, None[], 4]]
+	}{
+		prolog <- [func]Instructions <<[start]
+		out <- [body]Add Instruction[X86 Instruction["ret", retparam, None[], 4]]
+	}
+	
+	body <- Fold["Add Instruction", prolog, oldstream]
+}
+
+Text@X86 Function[func:out]
+{
+	name line <- [Escape Rhope Name[[func]Name >>]
+	]Append[":\n"]
+	
+	out <- Fold[["Instruction ASM"]Set Input[2, func], name line, [func]Instructions >>]
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lex.rhope	Wed Apr 29 02:58:03 2009 -0400
@@ -0,0 +1,188 @@
+Import extendlib.rhope
+
+Blueprint Token
+{
+	Type
+	Raw Text
+	Text
+}
+
+Token[type,raw,text:out]
+{
+	out <- [[[Build["Token"]]Type <<[type]]Raw Text <<[raw]]Text <<[text]
+}
+
+_Type Match[val, test type, type:out]
+{
+	If[[test type]=[type]]
+	{
+		out <- Yes
+	}{
+		out <- Val[val]
+	}
+}
+
+Type Match@Token[token,type:match,nomatch]
+{
+	match,nomatch <- If[Fold[["_Type Match"]Set Input[2, [token]Type >>], No, As List[type]]]
+}
+
+String Literal[string, raw string, escapes, text, simple tokens, token list:out]
+{
+	first,rest <- [text]Slice[1]
+	If[[first] = ["\""]]
+	{
+		out <- _Lex[rest, [first]Slice[0], simple tokens, [token list]Append[Token["String Literal", raw string, string]]]
+	}{
+		next raw <- [raw string]Append[first]
+		If[[first] = ["\\"]]
+		{
+			second,next text <- [rest]Slice[1]
+			char <- [escapes]Index[To String[second]] {} 
+			{
+				char <- Val[second]
+			}
+			next string <- [string]Append[char]
+		}{
+			next string <- [string]Append[first]
+			next text <- Val[rest]
+		}
+		out <- String Literal[next string, next raw, escapes, next text, simple tokens, token list]
+	}
+}
+
+Line Comment[start comment, text, simple tokens, token list:out]
+{
+	next text, comment <- [text]Get DString["\n"] {} {} {}
+	{
+		next text <- ""
+	}
+	out <- _Lex[next text, [next text]Slice[0], simple tokens, [token list]Append[Token["Line Comment", [start comment]Append[comment], comment]]]
+	
+}
+
+Block Comment[comment,raw comment, depth, text, simple tokens, token list:out]
+{
+	Print[["Block Comment: Depth="]Append[depth]]
+	If[[depth] > [0]]
+	{
+		next text, chunk, delim <- [text]Get DString[("/*","*/")] {} {} {}
+		{
+			next text <- ""
+			delim <- ""
+		}
+		If[[delim] = ["/*"]]
+		{
+			next depth <- [depth] + [1]
+		}{
+			next depth <- [depth] - [1]
+		}
+		If[[next depth] = [0]]
+		{
+			next comment <- [comment]Append[chunk]
+		}{
+			next comment <- [[comment]Append[chunk]]Append[delim]
+		}
+		out <- Block Comment[next comment, [[raw comment]Append[chunk]]Append[delim], next depth, next text, simple tokens, token list]
+	}{
+		out <- _Lex[text, [raw comment]Slice[0], simple tokens, [token list]Append[Token["Block Comment", raw comment, comment]]]
+	}
+}
+
+Numeric Literal[literal, text, simple tokens, token list:out]
+{
+	first,rest <- [text]Slice[1]
+	If[[first] In ["01234567890.x"]]
+	{
+		out <- Numeric Literal[[literal]Append[first], rest, simple tokens, token list]
+	}{
+		out <- _Lex[text, [first]Slice[0], simple tokens, [token list]Append[Token["Numeric Literal", literal, literal]]]
+	}
+}
+
+Add Token[token, text, simple tokens, token list:out]
+{
+	out <- _Lex[text, [text]Slice[0], simple tokens, [token list]Append[token]]
+}
+
+_Lex[text, symbol, simple tokens,token list:out]
+{
+	If[[[text]Length] > [0]]
+	{
+		first,rest <- [text]Slice[1]
+		[simple tokens]Index[To String[first]]
+		{
+			token worker <- [["Add Token"]Set Input[0, Token[~, first, ""]]]Set Input[1, rest]
+		}{
+			If[[first] = ["\""]]
+			{
+				escapes <- [[[New@Dictionary[]]Set["n","\n"]]Set["r","\r"]]Set["t","\t"]
+				token worker <- [[[["String Literal"]Set Input[0, [first]Slice[0]]]Set Input[1, first]]Set Input[2, escapes]]Set Input[3, rest]
+				//out <- String Literal["", first, rest, simple tokens, token list, escapes]
+			}{
+				second,second rest <- [rest]Slice[1]
+				If[[[first] = ["<"]] And [[second]=["-"]]]
+				{
+					[first]Append[second]
+					{
+						token worker <- [["Add Token"]Set Input[0, Token["Assignment", ~, ~]]]Set Input[1, second rest]
+					}
+				}{
+					
+					If[[[first] = ["/"]] And [[second] = ["*"]]]
+					{
+						token worker <- [[[["Block Comment"]Set Input[0, [first]Slice[0]]]Set Input[1, [first]Append[second]]]Set Input[2, 1]]Set Input[3, second rest]
+						//out <- Block Comment[next text, simple tokens, token list, 1]
+					}{
+						If[[[first] = ["/"]] And [[second] = ["/"]]]
+						{
+							token worker <- [["Line Comment"]Set Input[0, [first]Append[second]]]Set Input[1, second rest]
+							//out <- Line Comment["", [first]Append[second], next text, simple tokens, token list]
+						}{
+							If[[[first]In["0123456789"]] Or [[[first] = ["-"]] And [[second]In["0123456789"]]]]
+							{
+								token worker <- [["Numeric Literal"]Set Input[0, first]]Set Input[1, rest]
+								//out <- Numeric Literal[text, simple tokens, token list]
+							}{
+								out <- _Lex[rest, [symbol]Append[first], simple tokens, token list]
+							}
+						}
+					}
+				}
+				
+			}
+		}
+		Val[token worker]
+		{
+			trimmed <- Trim[symbol, " \t\r\n"]
+			If[[trimmed] = [""]]
+			{
+				next list <- Val[token list]
+			}{
+				next list <- [token list]Append[Token["Symbol", trimmed, trimmed]]
+			}
+			out <- [[token worker]Do[
+				[[()]Append[simple tokens]]Append[next list]]
+			]Index[0]
+		}
+	}{
+		out <- token list
+	}
+}
+
+Lex[text:out]
+{
+	simple tokens <- [[[[[[[[[[[New@Dictionary[]
+		]Set["{", "Block Begin"]
+		]Set["}", "Block End"]
+		]Set["(", "List Begin"]
+		]Set[")", "List End"]
+		]Set["[", "Args Begin"]
+		]Set["]", "Args End"]
+		]Set[",", "List Separator"]
+		]Set[":", "Name Separator"]
+		]Set["@", "Method Separator"]
+		]Set["`", "Binary Operation"]
+		]Set["\n", "Newline"]
+	out <- _Lex[text, [text]Slice[0], simple tokens, ()]
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nworker.rhope	Wed Apr 29 02:58:03 2009 -0400
@@ -0,0 +1,302 @@
+Import extendlib.rhope
+
+Blueprint Range
+{
+	Start
+	Stop
+}
+
+Range[start,stop:out]
+{
+	out <- [[Build["Range"]]Start <<[start]]Stop <<[stop]
+}
+
+First@Range[range:first,none]
+{
+	If[[[range]Start >>] < [[range]Stop >>]]
+	{
+		first <- [range]Start >>
+	}{
+		none <- range
+	}
+}
+
+Next@Range[range,current:next,none]
+{
+	pnext <- [current]+[1]
+	If[[pnext] < [[range]Stop >>]]
+	{
+		next <- Val[pnext]
+	}{
+		none <- range
+	}
+}
+
+Index@Range[range,index:val,none]
+{
+	val <- index
+}
+
+Set@Range[range,index,val:out]
+{
+	out <- [[()]Concatenate[range]
+	]Set[index,val]
+}
+
+List of Lists[num:out]
+{
+	out <- Fold[["Append"]Set Input[1, ()],(), Range[0,num]]
+}
+
+Blueprint Worker Ref
+{
+	Name
+	Convention
+	Inputs
+	Outputs
+}
+
+Worker Ref[name,convention,inputs,outputs:out]
+{
+	out <- [[[[Build["Worker Ref"]]Name <<[name]]Convention <<[convention]]Inputs <<[inputs]]Outputs <<[outputs]
+}
+
+Blueprint Node Ref
+{
+	Index
+	IO Num
+}
+
+Node Ref[index,ionum:out]
+{
+	out <- [[Build["Node Ref"]]Index <<[index]]IO Num <<[ionum]
+}
+
+=@Node Ref[left,right:out]
+{
+	,out <- If[[[left]Index >>] = [[right]Index >>]]
+	{
+		out <- [[left]IO Num>>] = [[right]IO Num >>]
+	}
+}
+
+Blueprint NWorker Node
+{
+	Type
+	Data
+	Inputs
+	Outputs
+	Wires From
+	Wires To
+}
+
+Wire To@NWorker Node[node,from,output,input:out]
+{
+	out <- [node]Wires To <<[
+		[[node]Wires To >>]Set[input,
+			[[[node]Wires To >>]Index[input]
+			]Append[Node Ref[from,output]]
+		]
+	]
+}
+
+Wire From@NWorker Node[node,to,input,output:out]
+{
+	out <- [node]Wires From <<[
+		[[node]Wires From >>]Set[output,
+			[[[node]Wires From >>]Index[output]
+			]Append[Node Ref[to,input]]
+		]
+	]
+}
+
+_Dependency[dlist,ref:out]
+{
+	[dlist]Find[ref]
+	{
+		out <- dlist
+	}{
+		out <- [dlist]Append[ref]
+	}
+}
+
+Dependencies@NWorker Node[node:out]
+{
+	out <- Fold[["Fold"]Set Input[0, "_Dependency"], (), [node]Wires To >>]
+}
+
+
+NWorker Node[type,data,inputs,outputs:out]
+{
+	out <- [[[[[[Build["NWorker Node"]
+		]Type <<[type]
+		]Data <<[data]
+		]Inputs <<[inputs]
+		]Outputs <<[outputs]
+		]Wires From <<[List of Lists[outputs]]
+		]Wires To <<[List of Lists[inputs]]
+}
+
+Blueprint NWorker
+{
+	Convention
+	Nodes
+	Inputs
+	Outputs
+}
+
+NWorker[convention:out]
+{
+	out <- [[[[Build["NWorker"]]Convention <<[convention]]Nodes <<[()]]Inputs <<[()]]Outputs <<[()]
+}
+
+Add Node@NWorker[worker,type,data,inputs,outputs:out,node index]
+{
+	out <- [worker]Nodes <<[[[worker]Nodes >>]Append[NWorker Node[type,data,inputs,outputs]]]
+	node index <- [[worker]Nodes >>]Length
+}
+
+Add Worker Call@NWorker[worker,tocall:out,node index]
+{
+	out, node index <- [worker]Add Node["call",tocall,[tocall]Inputs >>,[tocall]Outputs >>]
+}
+
+Add Constant@NWorker[worker,constant:out,node index]
+{
+	out, node index <- [worker]Add Node["const",constant,0,1]
+}
+
+Add Input@NWorker[worker,name,number:out,node index]
+{
+	,node index <- [worker]Add Node["input",number,0,1]
+	{ out <- [~]Inputs <<[[[~]Inputs >>]Set[number,name]] }
+}
+
+Add Output@NWorker[worker,name,number:out,node index]
+{
+	,node index <- [worker]Add Node["output",number,1,0]
+	{ out <- [~]Outputs <<[[[~]Outputs >>]Set[number,name]] }
+}
+
+Add Wire@NWorker[worker,from,output,to,input:out]
+{
+	fromw <- [[[worker]Nodes >>]Index[from]]Wire From[to,input,output]
+	tow <- [[[worker]Nodes >>]Index[to]]Wire To[from,output,input]
+	nodes <- [[[worker]Nodes >>]Set[from, fromw]]Set[to, tow]
+	out <- [worker]Nodes <<[nodes]
+}
+
+_No Dependencies[list,node,index:out]
+{
+	[[node]Wires To>>]First
+	{
+		out <- Val[list]
+	}{
+		out <- [list]Append[index]
+	}
+}
+
+No Dependencies@NWorker[worker:out]
+{
+	out <- Fold["_No Dependencies", (), [worker]Nodes >>]
+}
+
+_Collect Dests[candidates,wire:out]
+{
+	out <- [candidates]Set[[wire]Index >>, Yes]
+}
+
+Collect Dests@NWorker[worker,candidates,node index:out]
+{
+	out <- Fold[["Fold"]Set Input[0, "_Collect Dests"], candidates, [[[worker]Nodes >>]Index[node index]]Wires From >>]
+}
+
+Check Dependency@NWorker[worker,nodes,wires,wire index:met?]
+{
+	ref <- [wires]Index[wire index]
+	[nodes]Find[[ref]Index >>]
+	{
+		[wires]Next[wire index]
+		{
+			met? <- [worker]Check Dependency[nodes,wires,~]
+		}{
+			met? <- Yes
+		}
+	}{
+		Print[[ref]Index >>]
+		met? <- No
+	}
+}
+_Check Dependencies@NWorker[worker,nodes,inputs,input index:met?]
+{
+	wires <- [inputs]Index[input index]
+	[wires]First
+	{
+		current met? <- [worker]Check Dependency[nodes, wires, ~]
+	}{
+		current met? <- Yes
+	}
+	If[current met?]
+	{
+		[inputs]Next[input index]
+		{
+			met? <- [worker]_Check Dependencies[nodes,inputs,~]
+		}{
+			met? <- Yes
+		}
+	}{
+		met? <- No
+	}
+}
+
+Check Dependencies@NWorker[worker,nodes,candidate:met?]
+{
+	inputs <- [[[worker]Nodes >>]Index[candidate]]Wires To >>
+	[inputs]First
+	{
+		met? <- [worker]_Check Dependencies[nodes, inputs, ~]
+	}{
+		met? <- Yes
+	}
+}
+
+Dependants@NWorker[worker,direct nodes,nodes:out]
+{
+	candidates <- Keys[Fold[["Collect Dests"]Set Input[0,worker], (), direct nodes]]
+	out <- Filter[candidates, [["Check Dependencies"]Set Input[0, worker]]Set Input[1, nodes]]
+}
+
+_Dependency Groups@NWorker[worker,last,all,grouped:out]
+{
+	current <- [worker]Dependants[last,all]
+	[current]First
+	{
+		out <- [worker]_Dependency Groups[current, [all]Concatenate[current], [grouped]Append[current]]
+	}{
+		out <- grouped
+	}
+}
+Dependency Groups@NWorker[worker:out]
+{
+	no deps <- [worker]No Dependencies
+	out <- [worker]_Dependency Groups[no deps, no deps, [()]Append[no deps]]
+}
+
+Test[:out]
+{
+	ref+ <- Worker Ref["+","cdecl",2,1]
+	ref* <- Worker Ref["*","cdecl",2,1]
+	,a <- [NWorker["cdecl"]
+	]Add Input["a", 0] {
+		,b <- [~]Add Input["b", 1] {
+		,c <- [~]Add Input["c", 2] {
+		,outref <- [~]Add Output["out", 0] {
+		,call+ <- [~]Add Worker Call[ref+] {
+		,call* <- [~]Add Worker Call[ref*] {
+		out <- [[[[[~]Add Wire[a,0,call+,0]
+		]Add Wire[b,0,call+,1]
+		]Add Wire[call+,0,call*,0]
+		]Add Wire[c,0,call*,1]
+		]Add Wire[call*,0,outref,0]
+	}}}}}}
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/parse.rhope	Wed Apr 29 02:58:03 2009 -0400
@@ -0,0 +1,326 @@
+
+Blueprint Error
+{
+	Message
+	Line
+	Column
+}
+
+Error[msg,text:out]
+{
+	out <- [[[Build["Error"]]Message <<[msg]]Line << [ [[text]Line >>]+[1] ]]Column << [ [[text]Column >>]+[1] ]
+}
+
+To String@Error[error:out]
+{
+	out <- [[[[[error]Message >>]Append[" on line "]]Append[[error]Line >>]]Append[" at column "]]Append[[error]Column >>]
+}
+
+Blueprint PImport Node
+{
+	File
+}
+
+PImport Node[file:out]
+{
+	out <- [Build["PImport Node"]]File <<[file]
+}
+
+Blueprint Worker Node
+{
+	Name
+	Blueprint
+	Inputs
+	Outputs
+	Tree
+}
+
+Add Node Input@Worker Node[node,input:out]
+{
+	Print["Add Node Input"]
+	Print[["Input: "]Append[To String[input]]]
+	out <- [node]Inputs <<[[[node]Inputs >>]Append[input]]
+}
+
+Add Node Output@Worker Node[node,output:out]
+{
+	out <- [node]Outputs <<[[[node]Outputs >>]Append[output]]
+}
+
+Body[node,tokens,current,depth:out,out index, done]
+{
+	Print[["Body: Depth="]Append[depth]]
+	If[[depth] > [0]]
+	{
+		token <- [tokens]Index[current]
+		[token]Type Match["Block Begin"]
+		{
+			,end stream <- [tokens]Next[current]
+			{
+				out,out index, done <- Body[node,tokens,~,[depth]+[1]]
+			}
+		}{
+			[token]Type Match["Block End"]
+			{
+				[tokens]Next[current]
+				{
+					out,out index, done <- Body[node,tokens,~,[depth]-[1]]
+				}{
+					,end stream <- If[[depth] = [1]]
+					{
+						Print["done"]
+						out <- Val[node]
+						done <- Yes
+					}
+				}
+			}{
+				,end stream <- [tokens]Next[current]
+				{
+					out,out index, done <- Body[node,tokens,~,depth]
+				}
+			}
+		}
+	}{
+		out <- node
+		out index <- current
+	}
+	Val[end stream]
+	{
+		Print[To String[Error[["Unexpected end of stream after token of type "]Append[[token]Type >>], [token]Raw Text >>]]]
+	}
+}
+
+Before Body[node,tokens,current:out,out index, done]
+{
+	Print["Before body"]
+	token <- [tokens]Index[current]
+	next,end stream <- [tokens]Next[current]
+	{
+		[token]Type Match["Block Begin"]
+		{
+			out,out index, done <- Body[node,tokens,next,1]
+		}{
+			out,out index, done <- Before Body[node,tokens,next]
+		}
+	}
+	Val[end stream]
+	{
+		Print[To String[Error[["Unexpected end of stream after token of type "]Append[[token]Type >>], [token]Raw Text >>]]]
+	}
+}
+
+Outputs[node,tokens,current:out,out index, done]
+{
+	Print["outputs"]
+	token <- [tokens]Index[current]
+	next,end stream <- [tokens]Next[current]
+	{
+		[token]Type Match["Symbol"]
+		{
+			out,out index, done <- Outputs[[node]Add Node Output[[token]Text >>], tokens, next]
+		}{
+			[token]Type Match["Args End"]
+			{
+				out,out index, done <- Before Body[node, tokens, next]
+			}{
+				[token]Type Match[("List Separator","Block Comment","Line Comment","Newline")]
+				{
+					out,out index, done <- Outputs[node, tokens, next]
+				}{
+					Print[To String[Error[["Unexpected token of type "]Append[[token]Type >>], [token]Raw Text >>]]]
+				}
+			}
+		}
+	}
+	Val[end stream]
+	{
+		Print[To String[Error[["Unexpected end of stream after token of type "]Append[[token]Type >>], [token]Raw Text >>]]]
+	}
+}
+
+Inputs[node,tokens,current:out,out index, done]
+{
+	Print["Inputs"]
+	token <- [tokens]Index[current]
+	next,end stream <- [tokens]Next[current]
+	{
+		[token]Type Match["Symbol"]
+		{
+
+			out,out index, done <- Inputs[[node]Add Node Input[[token]Text >>], tokens, next]
+		}{
+			[token]Type Match["Name Separator"]
+			{
+				Print["in out sep"]
+				out,out index, done <- Outputs[node, tokens, next]
+			}{
+				[token]Type Match["Args End"]
+				{
+					out,out index, done <- Before Body[node, tokens, next]
+				}{
+					[token]Type Match[("List Separator","Block Comment","Line Comment","Newline")]
+					{
+						out,out index,done <- Inputs[node, tokens, next]
+					}{
+						Print[To String[Error[["Unexpected token of type "]Append[[token]Type >>], [token]Raw Text >>]]]
+					}
+				}
+			}
+		}
+	}
+	Val[end stream]
+	{
+		Print[To String[Error[["Unexpected end of stream after token of type "]Append[[token]Type >>], [token]Raw Text >>]]]
+	}
+}
+
+Method[node,tokens,current:out,out index,done]
+{
+	token <- [tokens]Index[current]
+	next <- [tokens]Next[current]
+	{
+		[token]Type Match["Symbol"]
+		{
+			out,out index,done <- Before Inputs[[node]Blueprint <<[[token]Text >>], tokens, next]
+		}{
+			[token]Type Match[("List Separator","Block Comment","Line Comment","Newline")]
+			{
+				out,out index,done <- Method[node, tokens, next]
+			}{
+				Print[To String[Error[["Unexpected token of type "]Append[[token]Type >>], [token]Raw Text >>]]]
+			}
+		}
+	}{
+		Print[To String[Error[["Unexpected end of stream after token of type "]Append[[token]Type >>], [token]Raw Text >>]]]
+	}
+}
+
+//TODO: support method declarations
+Before Inputs[node, tokens, current:out, out index, done]
+{
+	Print["Before Inputs"]
+	token <- [tokens]Index[current]
+	[token]Type Match["Args Begin"]
+	{
+		[tokens]Next[current]
+		{
+			out,out index, done <- Inputs[node, tokens, ~]
+		}{
+			Print[To String[Error[["Unexpected end of stream after token of type "]Append[[token]Type >>], [token]Raw Text >>]]]
+		}
+	}{
+		[token]Type Match["Method Separator"]
+		{
+			[tokens]Next[current]
+			{
+				out,out index,done <- Method[node, tokens, ~]
+			}{
+				Print[To String[Error[["Unexpected end of stream after token of type "]Append[[token]Type >>], [token]Raw Text >>]]]
+			}
+		}{
+			[token]Type Match[("Line Comment","Block Comment","Newline")]
+			{
+				continue <- Yes
+			}{
+				Print[To String[Error[["Unexpected token of type "]Append[[token]Type >>], [token]Raw Text >>]]]
+			}
+			Val[continue]
+			{
+				[tokens]Next[current]
+				{
+					out,out index, done <- Before Inputs[node, tokens, ~]
+				}{
+					Print[To String[Error[["Unexpected end of stream after token of type "]Append[[token]Type >>], [token]Raw Text >>]]]
+				}
+			}
+		}
+	}
+}
+
+Worker Node[name, tokens, current:out,out index, done]
+{
+	Print[["Worker: "]Append[To String[name]]]
+	out,out index, done <- Before Inputs[[[[[Build["Worker Node"]]Name <<[name]]Inputs <<[()]]Outputs <<[()]]Tree <<[()], tokens, current]
+}
+
+Blueprint PBlueprint Node
+{
+	Name
+	Fields
+}
+
+PBlueprint Node[name, tokens, current:out,out index,done]
+{
+	out <- [[Build["PBlueprint Node"]]Name <<[name]]Fields <<[()]
+	out index <- current
+	//TODO: Parse rest of blueprint definition
+}
+
+
+Top Level[tokens, current, nodes:out]
+{
+	token <- [tokens]Index[current]
+	Print[[token]Type >>]
+	[token]Type Match["Symbol"]
+	{
+		[[token]Text >>]After["Import "]
+		{
+			next nodes <- [nodes]Append[PImport Node[~]]
+			next index <- Val[current]
+		}{
+			blueprint name,worker name <- [~]After["Blueprint "]
+			{
+				[tokens]Next[current]
+				{
+					, next index <- PBlueprint Node[blueprint name, tokens, ~]
+					{
+						next nodes <- [nodes]Append[~]
+					} {} {
+						Print["done!"]
+						out <- Val[next nodes]
+					}
+				}{
+					Print[To String[Error[["Unexpected end of stream after symbol "]Append[[token]Text >>], [token]Raw Text >>]]]
+				}
+			}{
+				[tokens]Next[current]
+				{
+					, next index <- Worker Node[worker name, tokens, ~]
+					{
+						next nodes <- [nodes]Append[~]
+					} {} {
+						Print["done!"]
+						out <- Val[next nodes]
+					}
+				}{
+					Print[To String[Error[["Unexpected end of stream after symbol "]Append[[token]Text >>], [token]Raw Text >>]]]
+				}
+			}
+		}
+		
+	}{
+		[token]Type Match[("Newline","Block Comment","Line Comment")]
+		{
+			next nodes <- Val[nodes]
+			next index <- Val[current]
+		}{
+			Print[To String[Error[["Unexpected token of type "]Append[[token]Type >>], [token]Raw Text >>]]]
+		}
+	}
+	[tokens]Next[next index]
+	{
+		out <- Top Level[tokens, ~, next nodes]
+	}{
+		out <- Val[next nodes]
+	}
+}
+
+Parse[tokens:out]
+{
+	[tokens]First
+	{
+		out <- Top Level[tokens, ~, ()]
+	}{
+		out <- ()
+	}
+}