changeset 22:812673a8b1ea

Converted old parser to new syntax (needs work, currently crashes interpreter
author Mike Pavone <pavone@retrodev.com>
date Wed, 24 Jun 2009 02:07:12 -0400
parents e9272f7ebd26
children 0534bb8ee7ad
files parser_old.rhope
diffstat 1 files changed, 1320 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/parser_old.rhope	Wed Jun 24 02:07:12 2009 -0400
@@ -0,0 +1,1320 @@
+Import extendlib.rhope
+
+
+
+Blueprint Parser
+{
+	Arg Begin
+	Arg End
+	Line Comment
+	Comment Begin
+	Comment End
+	Assign
+	Block Begin
+	Block End
+	Blueprint Type Delim
+	Empty Block
+	Binary Operator
+	String Begin
+	String End
+	String Escape 
+	List Begin
+	List End
+	List Delim
+	In Out Delim
+	Do Worker
+	Index Begin
+	Index End
+	Previous
+	Block Val
+	Set Field
+	Get Field
+	Import
+	Blueprint
+	Global Separator
+	Uses
+	Hex Escape
+	Escape Map
+}
+
+New@Parser[:out]
+{
+	out <- [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[Build["Parser"]
+	]Arg Begin << ["["]
+	]Arg End <<["]"]
+	]Line Comment <<["//"]
+	]Comment Begin <<["/*"]
+	]Comment End <<["*/"]
+	]Assign <<["<-"]
+	]Block Begin <<["{"]
+	]Block End <<["}"]
+	]Blueprint Type Delim <<[":"]
+	]Empty Block <<[";"]
+	]Binary Operator <<["`"]
+	]String Begin <<["\""]
+	]String End <<["\""]
+	]String Escape <<["\\"]
+	]List Begin <<["("]
+	]List End <<[")"]
+	]List Delim <<[","]
+	]In Out Delim <<[":"]
+	]Do Worker <<["$"]
+	]Index Begin <<["("]
+	]Index End <<[")"]
+	]Previous <<["@"]
+	]Set Field <<["<<"]
+	]Get Field <<[">>"]
+	]Import <<["Import"]
+	]Blueprint <<["Blueprint"]
+	]Global Separator <<["::"]
+	]Hex Escape <<["x"]
+	]Uses <<["uses"]
+	]Escape Map <<[[[[New@Dictionary[]]Set["n","\n"]]Set["r","\r"]]Set["t","\t"]]
+}
+
+Blueprint Output Reference
+{
+	Index
+	Output Number
+}
+
+New@Output Reference[index,num:out]
+{
+	out <- [[Build["Output Reference"]]Index <<[index]]Output Number <<[num]
+}
+
+Add Pipe Reference[refs,name,reference:out]
+{
+	reflist <- [refs]Index[name] {}
+	{
+		reflist <- New@List[]
+	}
+	out <- [refs]Set[name, [reflist]Append[reference]]
+}
+
+Assignment Save Reference[refs,assignment,output num,parse worker,index:out]
+{
+	[[parse worker]Outputs >>]Find[assignment]
+	{
+		out <- refs
+	}{
+		out <- Add Pipe Reference[refs, assignment, New@Output Reference[index, output num]]
+	}
+}
+
+Blueprint Parse Program
+{
+	Workers
+	Imports
+	Blueprints
+	Errors
+}
+
+New@Parse Program[:out]
+{
+	out <- [[[Build["Parse Program"]
+	]Workers <<[New@Dictionary[]]
+	]Imports <<[New@Dictionary[]]
+	]Blueprints <<[New@Dictionary[]]
+}
+
+Blueprint Blueprint Definition
+{
+	Name
+	Fields
+}
+
+New@Blueprint Definition[name,fields:out]
+{
+	out <- [[Build["Blueprint Definition"]]Name << [name]]Fields <<[fields]
+}
+
+Blueprint Parse Worker
+{
+	Name
+	Inputs
+	Outputs
+	Line Number
+	Trees
+	Uses Stores
+}
+
+New@Parse Worker[name,inputs,outputs,line:out]
+{
+	out <- [[[[[[Build["Parse Worker"]]Name <<[name]]Inputs <<[inputs]]Outputs <<[outputs]]Line Number <<[line]]Trees <<[New@List[]]]Uses Stores <<[New@List[]]
+}
+
+Blueprint Worker Node
+{
+	Name
+	Params
+	Assignments
+	Blocks
+	Index
+}
+
+New@Worker Node[name,params:out]
+{
+	out <- [[[[Build["Worker Node"]]Name <<[name]]Params <<[params]]Assignments <<[New@List[]]]Blocks <<[New@List[]]
+}
+
+Add List Helper[list,worker,program,key,parse worker,refs:out,worker,refs]
+{
+	,nextworker,nextrefs <- [[list]Index[key]]Add to Worker[worker, program, parse worker, refs]
+	{ nextlist <- [list]Set[key, ~] }
+	[list]Next[key]
+	{
+		list,worker,refs <- Add List Helper[nextlist, nextworker, program, ~, parse worker, nextrefs]
+	}{
+		list <- Val[nextlist]
+		worker <- Val[nextworker]
+		refs <- Val[nextrefs]
+	}
+}
+
+Add List to Worker[list,worker,program,parse worker,refs:list,worker,refs]
+{
+	[list]First
+	{
+		list,worker,refs <- Add List Helper[list, worker, program, ~, parse worker, refs]
+	}{
+		list <- list
+		worker <- worker
+		refs <- refs
+	}
+}
+
+_Add Blocks to Worker[blocks,worker,program,parse worker,key,refs:blocks,worker,refs]
+{
+	block, next worker, nextrefs <- Add List to Worker[[blocks]Index[key], worker, program, parse worker, refs]
+	next blocks <- [blocks]Set[key, block]
+	[blocks]Next[key]
+	{
+		blocks,worker,refs <- _Add Blocks to Worker[next blocks, next worker, program, parseworker, ~, nextrefs]
+	}{
+		blocks <- Val[next blocks]
+		worker <- Val[next worker]
+		refs <- Val[nextrefs]
+	}
+}
+
+Add Blocks to Worker[blocks,worker,program,parse worker,refs:blocks,worker,refs]
+{
+	[blocks]First
+	{
+		blocks, worker, refs <- _Add Blocks to Worker[blocks, worker, program, parse worker, ~, refs]
+	}{
+		blocks <- blocks
+		worker <- worker
+		refs <- refs
+	}
+}
+
+Add to Worker@Worker Node[node,worker,program,parse worker,refs:node,worker,refs]
+{
+	[program]Find Worker[[node]Name >>]
+	{
+		after worker <- [worker]Add Worker Call[~] {}
+		{
+			assignment refs <- Fold[[["Assignment Save Reference"]Set Input[3, parse worker]]Set Input[4, ~], refs, [node]Assignments >>]
+			[node]Index <<[~]
+			{ 
+				params list, params worker, params refs <- Add List to Worker[[~]Params >>, after worker, program, parse worker, assignment refs]
+				block list, worker, refs <- Add Blocks to Worker[[~]Blocks >>, params worker, program, parse worker, params refs]
+				node <- [[~]Params <<[params list]]Blocks <<[block list]
+			}
+		}
+	}{
+		Print[["Error: Could not find a worker named "]Append[[node]Name >>]]
+	}
+}
+
+Add Multi Wire[worker,ref,junk,end index,input num:out]
+{
+	out <- [worker]Add Wire[[ref]Index >>, [ref]Output Number >>, end index, input num]
+}
+
+Add Param Wire[worker,param,input num,end index,blocks,parse worker,assignments:out]
+{
+	param worker, start index, output num <- [param]Add Wires[worker, blocks, parse worker, assignments] {}
+	{
+		out <- [param worker]Add Wire[start index, output num, end index, input num]
+	}{}{
+		out <- Fold[[["Add Multi Wire"]Set Input[3, end index]]Set Input[4, input num], param worker, ~]
+	}
+}
+
+_Add Block Wire[worker,node,junk,blocks,parse worker,assignments:out]
+{
+	out <- [node]Add Wires[worker, blocks, parse worker, assignments]
+}
+
+Add Block Wire[worker,block nodes,output num,parent index,existing blocks,parse worker,assignments:out]
+{
+	blocks <- [existing blocks]Append[New@Output Reference[parent index, output num]]
+	out <- Fold[[[["_Add Block Wire"]Set Input[3, blocks]]Set Input[4, parse worker]]Set Input[5, assignments], worker, block nodes]
+}
+
+Assignments Add Wires[worker,assignement,output num,parse worker,start index:worker]
+{
+	[[parse worker]Outputs >>]Find[assignment]
+	{
+		,output index <- [worker]Add Output[assignment, ~]
+		{
+			worker <- [~]Add Wire[start index, output num, output index, 0]
+		}
+	}{
+		//Ugly hack alert!
+		If[[asignment]Contains["::"]]
+		{
+			parts <- [assignment]Split["::"]
+			,global index <- [worker]Add Global Set[[parts]Index[0], [parts]Index[1]]
+			{
+				worker <- [~]Add Wire[start index, output num, global index, 0]
+			}
+		}{
+			worker <- worker
+		}
+	}
+}
+
+Has Block@Worker Node[junk:out,unused]
+{
+	out <- Yes
+}
+
+_Has Block Params[list,key:out]
+{
+	param <- [param list]Index[key]
+	out <- [param]Has Block {}
+	{
+		[param list]Next[key]
+		{
+			out <- _Has Block Params[param list, ~]
+		}{
+			out <- No
+		}
+	}
+	
+}
+
+Has Block Params[param list:out]
+{
+	[param list]First
+	{
+		out <- _Has Block Params[param list, ~]
+	}{
+		out <- No
+	}
+}
+
+Add Wires@Worker Node[node,worker,blocks,parse worker,assignments:worker,index,num,unused]
+{
+	worker,index,num <- Add Wires Worker or Field[node, worker, blocks, parse worker, assignments]
+}
+
+Add Wires Worker or Field[node,worker,blocks,parse worker,assignments:worker,index,num,unused]
+{
+	Fold[[["Assignments Add Wires"]Set Input[3, parse worker]]Set Input[4, [node]Index >>], worker, [node]Assignments >>]
+	{ Fold[[[[["Add Block Wire"]Set Input[3, [node]Index >>]]Set Input[4, blocks]]Set Input[5, parse worker]]Set Input[6, assignments], ~, [node]Blocks >>]
+	{ params worker <- Fold[[[[["Add Param Wire"]Set Input[3, [node]Index >>]]Set Input[4, blocks]]Set Input[5, parse worker]]Set Input[6, assignments], ~, [node]Params >>] :{|
+	If[Has Block Params[[node]Params >>]]
+	{
+		worker <- Val[params worker]
+	}{
+		[blocks]Peek
+		{
+			worker <- [params worker]Add Wire[[~]Index >>, [~]Output Number >>, [node]Index >>, [0]-[1]]
+		}{
+			worker <- Val[params worker]
+		}
+	}
+	index <- [node]Index >>
+	num <- 0
+}
+
+Blueprint Field Node
+{
+	Name
+	Params
+	Assignments
+	Blocks
+	Index
+	Set?
+}
+
+Has Block@Field Node[junk:has block,unused]
+{
+	has block <- Yes
+}
+
+New@Field Node[name,params,set:out]
+{
+	out <- [[[[[Build["Field Node"]]Name <<[name]]Assignments <<[New@List[]]]Blocks <<[New@List[]]]Set? <<[set]]Params <<[params]
+}
+
+Add to Worker@Field Node[node,worker,program,parse worker,refs:node,worker,refs,unused]
+{
+	If[[node]Set? >>]
+	{
+		after worker,index <- [worker]Add Object Set[[node]Name >>]
+	}{
+		after worker,index <- [worker]Add Object Get[[node]Name >>]
+	}
+	index
+	{
+		assignment refs <- Fold[[["Assignment Save Reference"]Set Input[3, parse worker]]Set Input[4, ~], refs, [node]Assignments >>]
+		[node]Index <<[~]
+		{ 
+			params list, params worker, params refs <- Add List to Worker[[~]Params >>, after worker, program, parse worker, assignment refs]
+			block list, worker, refs <- Add Blocks to Worker[[~]Blocks >>, params worker, program, parse worker, params refs]
+			node <- [[~]Params <<[params list]]Blocks <<[block list]
+		}
+	}
+}
+
+Add Wires@Field Node[node,worker,blocks,parse worker,assignments:worker,index,num]
+{
+	worker,index,num <- Add Wires Worker or Field[node, worker, blocks, parse worker, assignments]
+}
+
+Blueprint Named Pipe Node
+{
+	Name
+	Assignments
+	Blocks
+	Index
+}
+
+Has Block@Named Pipe Node[node:has block,no block]
+{
+	If[[[node]Index >>] < [0]]
+	{
+		//~ should really be a parser parameter
+		If[[[node]Name >>] = ["~"]]
+		{
+			has block <- Yes
+		}{
+			no block <- No
+		}
+	}{
+		has block <- Yes
+	}
+}
+
+New@Named Pipe Node[name:out]
+{
+	out <- [[[Build["Named Pipe Node"]]Name <<[name]]Assignments <<[New@List[]]]Blocks <<[New@List[]]
+}
+
+Add to Worker@Named Pipe Node[node,worker,program,parse worker,refs:node,worker,refs]
+{
+	[[parse worker]Inputs >>]Find[[node]Name >>]
+	{
+		after add <- [worker]Add Input[[node]Name >>, ~] {}
+		{
+			assign refs <- Fold[[["Assignment Save Reference"]Set Input[3, parse worker]]Set Input[4, ~], refs, [node]Assignments >>]
+			index node <- [node]Index <<[~]
+		}
+	}{
+		after add <- worker
+		index node <- [node]Index <<[[0]-[1]]
+		//TODO: Handle assignments from a named pipe that isn't an input
+		assign refs <- refs
+	}
+	block list, worker, refs <- Add Blocks to Worker[[node]Blocks >>, after add, program, parse worker, assign refs]
+	node <- [index node]Blocks <<[block list]
+}
+
+Add Wires@Named Pipe Node[node,worker,blocks,parse worker,assignments:worker,index,num,unused]
+{
+	reflist <- [assignments]Index[[node]Name >>]
+	{ 
+		//TODO: Fix support for a named pipe with a block
+		worker <- worker 
+	}{
+		If[[[node]Name >>] = ["~"]]
+		{
+			wires worker <- worker
+			[blocks]Peek
+			{
+				my index <- [~]Index >>
+				num <- [~]Output Number >>
+			}{
+				//TODO: Propagate an error rather than printing it out
+				Print["Error, block reference symbol  located outside of a block"]
+			}
+		}{
+			If[[[node]Index >>] < [0]]
+			{
+				Print[[[["Error, reference to named pipe "]Append[[node]Name >>]]Append[" that was never assigned to in worker "]]Append[[parse worker]Name >>]]
+			}{
+				my index <- [node]Index >>
+				num <- 0
+				assignments worker <- Fold[[["Assignments Add Wires"]Set Input[3, parse worker]]Set Input[4, [node]Index >>], worker, [node]Assignments >>]
+				[blocks]Peek
+				{
+					wires worker <- [assignments worker]Add Wire[[~]Index >>, [~]Output Number >>, [node]Index >>, [0]-[1]]
+				}{
+					wires worker <- Val[assignments worker]
+				}
+			}
+		}
+	}
+	index <- my index
+	
+	worker <- Fold[[[[["Add Block Wire"]Set Input[3, my index]]Set Input[4, blocks]]Set Input[5, parse worker]]Set Input[6, assignments], wires worker, [node]Blocks >>]
+}
+
+Blueprint Global Node
+{
+	Store
+	Name
+	Assignments
+	Blocks
+	Index
+}
+
+New@Global Node[store,name:out]
+{
+	out <- [[[[Build["Global Node"]]Store <<[store]]Name <<[name]]Assignments <<[New@List[]]]Blocks <<[New@List[]]
+}
+
+Add to Worker@Global Node[node,worker,unused,parse worker,refs:out node,out worker,refs]
+{
+	out worker <- [worker]Add Global Get[[node]Store >>, [node]Name >>] {}
+	{
+		refs <- Fold[[["Assignment Save Reference"]Set Input[3, parse worker]]Set Input[4, ~], refs, [node]Assignments >>]
+		out node <- [node]Index <<[~]
+	}
+	refs <- refs
+}
+
+Add Wires@Global Node[node,worker,blocks,parse worker,assignments:worker,index,num,unused]
+{
+	worker,index,num <- Add Wires Literal or Global[node, worker, blocks, parse worker, assignments]
+}
+
+Has Block@Global Node[junk:out,unused]
+{
+	out <- Yes
+}
+
+Blueprint Literal Node
+{
+	Value
+	Assignments
+	Blocks
+	Index
+}
+
+Has Block@Literal Node[junk:out,unused]
+{
+	out <- Yes
+}
+
+New@Literal Node[value:out]
+{
+	out <- [[[Build["Literal Node"]]Value <<[value]]Assignments <<[New@List[]]]Blocks <<[New@List[]]
+}
+
+Add to Worker@Literal Node[node,worker,unused,parse worker,refs:out node,out worker,refs,unused]
+{
+	out worker <- [worker]Add Constant[[node]Value >>] {}
+	{
+		refs <- Fold[[["Assignment Save Reference"]Set Input[3, parse worker]]Set Input[4, ~], refs, [node]Assignments >>]
+		out node <- [node]Index <<[~]
+	}
+}
+
+Add Wires@Literal Node[node,worker,blocks,parse worker,assignments:worker,index,num,unused]
+{
+	worker,index,num <- Add Wires Literal or Global[node, worker, blocks, parse worker, assignments]
+}
+
+Add Wires Literal or Global[node,worker,blocks,parse worker,junk:worker,index,num,unused]
+{
+	assignments worker <- Fold[[["Assignments Add Wires"]Set Input[3, parse worker]]Set Input[4, [node]Index >>], worker, [node]Assignments >>]
+	[blocks]Peek
+	{
+		worker <- [assignments worker]Add Wire[[~]Index >>, [~]Output Number>>, [node]Index >>, [0]-[1]]
+	}{
+		worker <- Val[assignments worker]
+	}
+	index <- [node]Index >>
+	num <- 0
+}
+
+Blueprint Block Node
+{
+	Number
+}
+
+Blueprint Parse Error
+{
+	Type
+	Text
+	Line Number
+}
+
+New@Parse Error[type,text,number:out]
+{
+	out <- [[[Build["Parse Error"]]Type <<[type]]Text <<[text]]Line Number <<[number]
+}
+
+Filter Empty[string:out]
+{
+	If[[[string]Length] > [0]]
+	{
+		out <- Yes
+	}{
+		out <- No
+	}
+}
+
+Blueprint Blueprint Field
+{
+	Name
+	Type
+}
+
+New@Blueprint Field[name,type:out]
+{
+	out <- [[Build["Blueprint Field"]]Name <<[name]]Type <<[type]
+}
+
+Process Blueprint Field[list,field,delim:out]
+{
+	parts <- [field]Split[delim]
+	If[[[parts]Length] > [1]]
+	{
+		out <- [list]Append[New@Blueprint Field[[parts]Index[1], [parts]Index[0]]]
+	}{
+		out <- [list]Append[New@Blueprint Field[[parts]Index[0], "Any Type"]]
+	}
+}
+
+Block Comment[string,begin comment,end comment,block count:out]
+{
+	If[[block count] > [0]]
+	{
+		after, before <- [string]Get DString[[[New@List[]]Append[begin comment]]Append[end comment]] {} {}
+		{
+			If[[~] = [begin comment]]
+			{
+				out <- Block Comment[after, begin comment, end comment, [block count]+[1]]
+			}{
+				out <- Block Comment[after, begin comment, end comment, [block count]-[1]]
+			}
+		}{
+			//No match
+			out <- ""
+		}
+	}{
+		out <- string
+	}
+}
+
+Line Comment[string:out]
+{
+	[string]Get DString["\n"]
+	{
+		out <- ["\n"]Append[~]
+	} {} {} {
+		out <- ""
+	}
+}
+
+_Get Comment DString[string,delims,line comment,begin comment,end comment,prev before:rest,before,delim,nomatch]
+{
+	after,before,delim,nomatch <- [string]Get DString[delims]
+	{
+		If[[delim] = [line comment]]
+		{
+			after comment <- Line Comment[after]
+		}{
+			If[[delim] = [begin comment]]
+			{
+				after comment <- Block Comment[after, begin comment, end comment, 1]	
+			}{
+				rest <- Val[after]
+				before <- [prev before]Append[before]
+				delim <- Val[delim]
+			}
+		}
+	} {} {} {
+		before <- [prev before]Append[before]
+	}
+	
+	after comment
+	{
+		rest,more before,delim,nomatch <- _Get Comment DString[~, delims, line comment, begin comment, end comment, prev before]
+		before <- [before]Append[more before]
+	}
+		
+}
+
+Get Comment DString[string,delims,params:rest,before,delim,not found]
+{
+	line comment <- [params]Line Comment >>
+	begin comment <- [params]Comment Begin >>
+	end comment <- [params]Comment End >>
+	all delims <- [[[delims]As List]Append[begin comment]]Append[line comment]
+	rest, before, delim, not found <- _Get Comment DString[string, delims, line comment, begin comment, end comment, ""]
+}
+
+Comment Left Trim[string,trim chars,params:out]
+{
+	line comment <- [params]Line Comment >>
+	
+	end comment <- [params]Comment End >>
+	trimmed <- Left Trim[string, trim chars]
+	If[[trimmed]Starts With[line comment]]
+	{
+		,after delim <- [trimmed]Slice[[line comment]Length]
+		out <- Comment Left Trim[Line Comment[after delim], trim chars, params]
+	}{
+		begin comment <- [params]Comment Begin >>
+		If[[trimmed]Starts With[begin comment]]
+		{
+			,after delim <- [trimmed]Slice[[line comment]Length]
+			out <- Comment Left Trim[Block Comment[after delim, begin comment, end comment, 1], trim chars, params]
+		}{
+			out <- Val[trimmed]
+		}
+	}
+}
+
+Blueprint[string,params,tree,lines:out]
+{
+	,whitespace name <- [string]Get Comment DString[[params]Block Begin >>, params]
+	{	
+		,no blueprint <- [whitespace name]Slice[ [[params]Blueprint >>]Length ]
+		name <- Trim[no blueprint, "\r\n\t "]
+		name lines <- 0//[Count Substring[left, "\n"]] + [Count Substring[right, "\n"]]
+		,body <- [~]Get Comment DString[ [params]Block End >>, params]
+		{
+			body lines <- [body]Split["\n"]
+			more lines <- [[[body lines]Length] - [1]] + [name lines]
+			fields <- Fold[["Process Blueprint Field"]Set Input[2, [params]Blueprint Type Delim >>], New@List[], Filter[Map[body lines, ["Trim"]Set Input[1,"\n\r\t "]], "Filter Empty"]]
+			new tree <- [tree]Blueprints << [ [[tree]Blueprints >>]Set[name, New@Blueprint Definition[name, fields]] ]
+			out <- Null[~, params, new tree, [lines] + [more lines]]
+		} {} {
+			out <- [tree]Errors <<[ [[tree]Errors >>]Append[New@Parse Error["Error",[["Blueprint is missing an block close symbol \""]Append[[params]Block End >>]]Append["\""], lines]] ]
+		}
+		
+	} {} {
+		out <- [tree]Errors <<[ [[tree]Errors >>]Append[New@Parse Error["Error",[["Blueprint is missing an block open symbol \""]Append[[params]Block Begin >>]]Append["\""], lines]] ]
+	}
+}
+
+Parse Import[string,params,tree,lines:out]
+{
+	[line]Slice[ [[params]Import >>]Length ] {}
+	{
+		filename <- Trim[~, " \n\r\t"]
+	}
+	new tree <- [tree]Imports <<[ [[tree]Imports >>]Set[filename, Yes] ]
+	,line <- [string]Get Comment DString["\n", params]
+	{
+		out <- Null[~, params, new tree, [lines] + [1]]
+	} {} {
+		out <- Val[new tree]
+	}
+}
+
+Get Expression Blocks[string,params,blocks:blocks,after]
+{
+	check block <- Comment Left Trim[string, "\n\r\t ", params]
+	If[[check block]Starts With[[params]Block Begin >>]]
+	{
+		,begin block <- [check block]Slice[[[params]Block Begin >>]Length]
+		trees, after block <- Worker Body[begin block, params, New@List[]]
+		blocks, after <- Get Expression Blocks[after block, params, [blocks]Append[trees]]
+	}{
+		If[[check block]Starts With[[params]Empty Block >>]]
+		{
+			blocks <- blocks
+			,after <- [check block]Slice[[[params]Empty Block >>]Length]
+		}{
+			blocks <- blocks
+			after <- Val[check block]
+		}
+	}
+}
+
+Parse Escape[string,params:char,after]
+{
+	code,rest <- [string]Slice[1]
+	If[[code] = [[params]Hex Escape >>]]
+	{
+		hex,after <- [rest]Slice[2]
+		char <- [""]Put Byte[From Hex@Whole Number[hex]]
+	}{
+		after <- Val[rest]
+		char <- [[params]Escape Map >>]Index[code] {}
+		{
+			char <- Val[code]
+		}
+	}
+}
+
+Parse String[string,params,current:value,after]
+{
+	delims <- [[New@List[]]Append[[params]String End >>]]Append[[params]String Escape >>]
+	after, before, delim <- [string]Get Comment DString[delims, params]
+	{
+		If[[delim] = [[params]String End >>]]
+		{
+			value <- [current]Append[before]
+			after <- Val[after]
+		}{
+			char,after escape <- Parse Escape[after, params]
+			value,after <- Parse String[after escape, params, [[current]Append[before]]Append[char]]
+		}
+	}
+}
+
+Parse List[string,params,list:value,after]
+{
+	trimmed <- Comment Left Trim[string, "\r\n\t ", params]
+	If[[trimmed]Starts With[[params]List End >>]]
+	{
+		value <- list
+		,after <- [trimmed]Slice[[[params]List End >>]Length]
+	}{
+		If[[trimmed]Starts With[[params]List Delim >>]]
+		{
+			,el string <- [trimmed]Slice[[[params]List Delim >>]Length]
+		}{
+			el string <- Val[trimmed]
+		}
+		element,after el <- Named Pipe or Literal[el string, params]
+		value,after <- Parse List[after el, params, [list]Append[[element]Get Value]]
+	}
+}
+
+Get Value@Literal Node[node:out]
+{
+	out <- [node]Value >>
+}
+
+Get Value@Named Pipe Node[node:out]
+{
+	out <- node
+}
+
+Parse Number[string,params:value,after]
+{
+	delims <- [[[[(" ","\t","\n","\r")]Append[[params]List Delim >>]]Append[[params]Block Begin >>]]Append[[params]Arg End >>]]Append[[params]List End >>]
+	after delim,valstring <- [string]Get Comment DString[delims, params] {} {}
+	{
+		after <- [~]Append[after delim]
+	}{
+		after <- ""
+	}
+	first two,rest <- [valstring]Slice[2]
+	If[[first two] = ["0x"]]
+	{
+		value <- From Hex@Whole Number[rest]
+	}{
+		If[[valstring]Contains["."]]
+		{
+			value <- <String@Real Number[valstring]
+		}{
+			value <- <String@Whole Number[valstring]
+		}
+	}
+}
+
+Named Pipe or Literal[string,params:out,after]
+{
+	name <- Comment Left Trim[string, "\n\r\t ", params]
+	If[[name]Starts With[[params]String Begin >>]]
+	{
+		,string begin <- [name]Slice[[[params]String Begin >>]Length]
+		value,after <- Parse String[string begin, params, ""]
+	}{
+		If[[name]Starts With[[params]List Begin >>]]
+		{
+			,list start <- [name]Slice[[[params]List Begin >>]Length]
+			value,after <- Parse List[list start, params, New@List[]]
+		}{
+			If[[[name]Slice[1]]In["-0123456789"]]
+			{
+				value,after <- Parse Number[name, params]
+			}{
+				delims <- [[[[[[("\n")]Append[[params]Block Begin >>]]Append[[params]Block End >>]]Append[[params]Empty Block >>]]Append[[params]Arg End >>]]Append[[params]List Delim >>]]Append[[params]List End >>]
+				afterdelim,raw before,delim <- [name]Get Comment DString[delims, params]
+				{
+					after <- [delim]Append[~]
+				} {} {} { 
+					after <- ""
+				}
+				before <- Trim[raw before, "\r\n\t "]
+				If[[before] = ["Yes"]]
+				{
+					yesno <- Yes
+				}{
+					If[[before] = ["No"]]
+					{
+						yesno <- No
+					}{
+						If[[before] = [""]]
+						{
+							Print[[["Found "]Append[delim]]Append[" where a named pipe or literal was expected"]]
+							{ Print[["Near: "]Append[ [afterdelim]Slice[40]]] }
+						}{
+							If[[before]Contains[[params]Global Separator >>]]
+							{
+								parts <- [before]Split[[params]Global Separator >>]
+								out <- New@Global Node[Right Trim[[parts]Index[0],"\r\n\t "], Trim[[parts]Index[1], "\r\n\t "]]
+							}{
+								out <- New@Named Pipe Node[Right Trim[before,"\r\n\t "]]
+							}
+						}
+					}
+				}
+				out <- New@Literal Node[yesno]
+			}
+		}
+	}
+	out <- New@Literal Node[value]
+}
+
+Parse Arguments[string,params,arglist:args,after]
+{
+	args <- Comment Left Trim[string, "\r\n\t ", params]
+	If[[args]Starts With[[params]List Delim >>]]
+	{
+		[args]Slice[[[params]List Delim >>]Length] {} 
+		{
+			final args <- Comment Left Trim[~, "\r\n\t ", params]
+		}
+	}{
+		If[[args]Starts With[[params]Arg End >>]]
+		{
+			args <- arglist
+			,after <- [args]Slice[[[params]Arg End >>]Length]
+		}{
+			final args <- Val[args]
+		}
+	}
+	arg, after arg <- Parse Expression[final args, params]
+	args, after <- Parse Arguments[after arg, params, [arglist]Append[arg]]
+}
+
+Worker or Field[name,args,params:out]
+{
+	get field <- [params]Get Field >>
+	If[[name]Ends With[get field]]
+	{
+		field <- Right Trim[[name]Slice[[[name]Length] - [[get field]Length]], "\n\r\t "]
+		out <- New@Field Node[field, args, No]
+	}{
+		set field <- [params]Set Field >>
+		If[[name]Ends With[set field]]
+		{
+			field <- Right Trim[[name]Slice[[[name]Length] - [[set field]Length]], "\n\r\t "]
+			out <- New@Field Node[field, args, Yes]
+		}{
+			out <- New@Worker Node[name, args]
+		}
+	}
+}
+
+Prefix[string,params,name,existing args:expression,after]
+{	
+	//Parse argument list
+	more args,after <- Parse Arguments[string, params, existing args]
+	expression <- Worker or Field[name, more args, params]
+}
+
+Postfix or Infix[string,params:expression,after]
+{
+	args, after args <- Parse Arguments[string, params, New@List[]]
+	delims <- [[[[[("\n")]Append[[params]Arg Begin >>]]Append[[params]Empty Block >>]]Append[[params]Block Begin >>]]Append[[params]Arg End >>]]Append[[params]List Delim >>]
+	after,before,delim <- [after args]Get Comment DString[delims, params]
+	{
+		If[[delim] = [[params]Arg Begin >>]]
+		{
+			expression, after <- Prefix[after, params, Trim[before,"\r\n\t "], args]
+		}{
+			If[[delim] = [[params]Empty Block >>]]
+			{
+				after expression <- Val[after]
+			}{
+				,after expression <- [after args]Slice[[before]Length]
+			}
+			expression <- Worker or Field[Trim[before,"\r\n\t "], args, params]
+		}
+	}
+}
+
+Parse Expression[trimmed,params:final expression,after blocks]
+{
+	delims <- [[[[[[[("\n")]Append[[params]Arg Begin >>]]Append[[params]Arg End >>]]Append[[params]Assign >>]]Append["\n"]]Append[[params]Empty Block >>]]Append[[params]Block End >>]]Append[[params]String Begin >>]
+	after, before, delim <- [trimmed]Get Comment DString[delims, params]
+	{
+		//If we find an arg begin token, we have a worker expression
+		If[[delim] = [[params]Arg Begin >>]]
+		{
+			maybe name <- Right Trim[before, "\r\t "]
+			//Prefix expressions will have the worker name before the first arg begin token
+			If[[maybe name] = [""]]
+			{
+				expression, after expression <- Postfix or Infix[after, params]
+			}{
+				If[[maybe name]Contains[[params]List Delim >>]]
+				{
+					after expression <- [after literal]Append[[delim]Append[after]]
+					expression, after literal <- Named Pipe or Literal[Right Trim[before, "\r\n\t "], params]
+				}{
+					expression, after expression <- Prefix[after, params, maybe name, New@List[]]
+				}
+			}
+		}{
+			If[[delim] = [[params]Assign >>]]
+			{
+				//Expressions starting with an assignment can be prefix, postfix or infix
+				//or they can be a simple literal or named pipe
+				assignments <- Map[[before]Split[[params]List Delim >>], ["Trim"]Set Input[1,"\n\r\t "]]
+				,after blocks <- Parse Expression[Comment Left Trim[after, " \n\r\t", params], params]
+				{
+					final expression <- [~]Assignments <<[assignments]
+				}
+			}{
+				//If[[delim] = [[params]String Begin >>]]
+				//{
+				//	If[[Trim[before, "\r\n\t "]] = [""]]
+				//	{
+				//		expression, after expression <- Named Pipe or Literal[[delim]Append[after], params]
+				//	}{
+				//		after expression <- [after literal]Append[[delim]Append[after]]
+				//		expression, after literal <- Named Pipe or Literal[Right Trim[before, "\r\n\t "], params]
+				//	}
+				//}{
+				//	after expression <- [after literal]Append[[delim]Append[after]]
+				//	expression, after literal <- Named Pipe or Literal[Right Trim[before, "\r\n\t "], params]
+				//}
+				expression, after expression <- Named Pipe or Literal[trimmed, params]
+			}
+		}
+		//Any expression can be followed by one or more blocks mapping the inputs of other expressions
+		//to the outputs of the current one
+		blocks,after blocks <- Get Expression Blocks[after expression, params, New@List[]]
+		final expression <- [expression]Blocks <<[blocks]
+	}
+}
+
+Worker Body[string,params,trees:trees,after end]
+{
+	trimmed <- Comment Left Trim[string, "\n\r\t ", params]
+	If[[trimmed]Starts With[[params]Block End >>]]
+	{
+		//We're done with this block, return
+		,after end <- [trimmed]Slice[[[params]Block End >>]Length]
+		trees <- trees
+	}{
+		expression, after expression <- Parse Expression[trimmed, params]
+		trees,after end <- Worker Body[after expression, params, [trees]Append[expression]]
+	}
+}
+
+Process Modifiers[worker,params,modifiers:out]
+{
+	//Eventually this will need to be more sophisticated to handle more modifiers
+	trimmed <- Comment Left Trim[modifiers, "\n\r\t ", params]
+	If[[trimmed]Starts With[[params]Uses >>]]
+	{
+		,after uses <- [trimmed]Slice[[[params]Uses >>]Length]
+		,stores string <- [after uses]Get Comment DString["\n", params]
+		out <- [worker]Uses Stores <<[Map[[stores string]Split[[params]List Delim >>], ["Trim"]Set Input[1, "\r\n\t "]]]
+	}{
+		out <- worker
+	}
+}
+
+Worker Name[string,params,tree,lines:out]
+{
+	,whitespace name <- [string]Get Comment DString[[params]Arg Begin >>, params]
+	{
+		worker name <- Trim[whitespace name, "\n\r\t "]
+		in out <- [params]In Out Delim >>
+		arg end <- [params]Arg End >>
+		delims <- [[New@List[]]Append[in out]]Append[arg end]
+		after <- [~]Get Comment DString[delims, params] {} 
+		{
+			arglist <- Trim[~,"\r\n\t "]
+		}{
+			//check if there is an in/out separator
+			//if it isn't present, everything in the arglist is an input
+			If[[~] = [in out]]
+			{
+				after arglist <- [after]Get Comment DString[arg end, params] {}
+				{
+					output string <- Trim[~,"\n\r\t "]
+				}
+			}{
+				after arglist <- Val[after]
+				output string <- ""
+			}
+			inputs <- Map[[arglist]Split[[params]List Delim >>], ["Trim"]Set Input[1,"\n\r\t "]]
+			outputs <- Map[[output string]Split[[params]List Delim >>], ["Trim"]Set Input[1,"\n\r\t "]]
+
+			New@Parse Worker[worker name, inputs, outputs, 0]
+			{
+				body text, modifiers <- [after arglist]Get Comment DString[[params]Block Begin >>, params]
+				modified <- Process Modifiers[~, params, modifiers]
+				expression trees, after body <- Worker Body[body text, params, New@List[]]
+				worker <- [modified]Trees <<[expression trees]
+				new worker dict <- [[tree]Workers >>]Set[worker name, worker]
+				out <- Null[after body, params, [tree]Workers <<[new worker dict], 0]
+			}
+		}
+	}{}{}{
+		out <- tree
+	}
+}
+
+Null[string,params,tree,lines:out]
+{
+	trimmed <- Comment Left Trim[string, " \n\r\t", params]
+	current line <- 0//[lines] + [Count Substring[whitespace, "\n"]]
+	If[[trimmed]Starts With[ [params]Blueprint >> ]]
+	{
+		out <- Blueprint[trimmed, params, tree, current line]
+	}{
+		If[[trimmed]Starts With[ [params]Import >> ]]
+		{
+			out <- Parse Import[trimmed, params, tree, current line]
+		}{
+			out <- Worker Name[trimmed, params, tree, current line]
+		}
+	}
+}
+
+Add Workers[worker,name,program:out]
+{
+	prog,worker <- [program]New Worker[name]
+	[worker]Set IO Counts[ [[[worker]Index[name]]Inputs >>]Length, [[[worker]Index[name]]Outputs >>]Length]
+	[workers]Next[name]
+	{
+		out <- Add Workers[workers, ~, prog]
+	}{
+		out <- Val[prog]
+	}
+}
+
+Add Wires Helper[worker,node,unused,parse worker,assignments:out]
+{
+	out <- [node]Add Wires[worker, New@List[], parse worker, assignments]
+}
+
+Add Contents[parse worker,name,program:out,key]
+{
+	worker <- [[program]Find Worker[name]]Uses[[parse worker]Uses Stores >>]
+	trees, contents worker, refs <- Add List to Worker[[parse worker]Trees >>, worker, program, parse worker, New@Dictionary[]]
+	Fold[[["Add Wires Helper"]Set Input[3, parse worker]]Set Input[4, refs], contents worker, trees]
+	out <- [parse worker]Trees <<[trees]
+	key <- name
+}
+
+Add Blueprint Field[blueprint,field,unused:out]
+{
+	out <- [blueprint]Add Field[[field]Name >>, [field]Type >>]
+}
+
+Add Blueprint[prog,def:out]
+{
+	out <- [prog]New Blueprint[[def]Name >>] {}
+	{	
+		Fold["Add Blueprint Field", ~, [def]Fields >>]
+	}
+}
+
+_Tree to Program[parse tree,program:out]
+{
+	after blueprint <- Fold["Add Blueprint", program, [parse tree]Blueprints >>]
+	[[parse tree]Workers >>]First
+	{
+		prog <- Add Workers[[parse tree]Workers >>, ~, after blueprint]
+	}
+	Key Value Map[[parse tree]Workers >>, ["Add Contents"]Set Input[2, prog]]
+	out <- prog
+}
+
+Tree to Program[parse tree:out]
+{
+	out <- _Tree to Program[parse tree, [New@Program[]]Add Builtins]
+}
+
+Needs Imports[needs import,not imported?,name:out]
+{
+	If[not imported?]
+	{
+		out <- [needs import]Append[name]
+	}{
+		out <- needs import
+	}
+}
+
+Do Import[tree,file name,unused,params:out]
+{
+	file <- <String@File[file name]
+	,text <- [file]Get FString[[file]Length]
+	after import <- Null[text, params, tree, 0]
+	out <- [after import]Imports <<[ [[after import]Imports >>]Set[file name, No] ]
+}
+
+Process Imports[parse tree,params:out]
+{
+	needs import <- Fold["Needs Imports", New@List[], [parse tree]Imports >>]
+	If[[[needs import]Length] > [0]]
+	{
+		import tree <- Fold[["Do Import"]Set Input[3, params], parse tree, needs import]
+		out <- Process Imports[import tree, params]
+	}{
+		out <- parse tree
+	}
+}
+
+_Init Used Store[dict,store name:out]
+{
+	[dict]Index[store name]
+	{
+		out <- dict
+	}{
+		Init Store[store name]
+		out <- [dict]Set[store name, Yes]
+	}
+}
+
+_Init Used Stores[dict,worker:out]
+{
+	out <- Fold["_Init Used Store", dict, [worker]Uses Stores >>]
+}
+
+Init Used Stores[parse tree,existing stores:out]
+{
+	out <- Fold["_Init Used Stores", existing stores, [parse tree]Workers >>]
+}
+
+Until End[text:out]
+{
+	line <- Get Input[]
+	If[[line] = ["End"]]
+	{
+		out <- [text]Append["\n"]
+	}{
+		out <- Until End[[[text]Append["\n"]]Append[line]]
+	}
+}
+
+_REPL[params,prog,stores]
+{
+	line <- Get Input[]
+	If[[line] = ["Begin"]]
+	{
+		text <- Until End[""]
+		Null[text, params, New@Parse Program[], 0]
+		{
+			define tree <- Process Imports[~, params]
+			Init Used Stores[define tree, stores]
+			{ _REPL[params, _Tree to Program[define tree, prog], ~] }
+		}
+	}{
+		If[[line]Starts With[[params]Import >>]]
+		{
+			Parse Import[[line]Append["\n"], params, New@Parse Program[], 0]
+			{
+				import tree <- Process Imports[~, params]
+				Init Used Stores[import tree, stores]
+				{ _REPL[params, _Tree to Program[import tree, prog], ~] }
+			}
+		}{
+			trees <- Worker Body[[line]Append["}"], params, New@List[]]
+			tree <- [New@Worker Node["Val", [New@List[]]Append[[trees]Index[0]]]]Assignments <<[("__out")]
+			this stores <- [[tree]Gather Stores[params, New@Dictionary[]]]Keys
+			next stores <- Fold["_Init Used Store", stores, this stores]
+			{
+			pworker <- [[New@Parse Worker["__Eval", New@List[], ("__out"), 0]]Trees <<[[New@List[]]Append[tree]]]Uses Stores <<[this stores]
+			}
+			[[prog]Find Worker["__Eval"]]Clear
+			{ Add Contents[pworker, "__Eval", prog]
+			{ Pretty Print[[[[prog]Find Worker["__Eval"]]Do[New@List[]]]Index[0], ""]
+			{ _REPL[params, prog, next stores] } } }
+		}
+	}
+}
+
+REPL[params]
+{
+	Print["Rhope Alpha 2\nCopyright 2008 by Michael Pavone\nEntering interactive mode\n"]
+	prog <- Tree to Program[Null["Val[in:out]\n{\n out <- in\n}\n__Eval[:__out]\n{\n}\n", params, New@Parse Program[], 0]]
+	_REPL[params, prog, New@Dictionary[]]
+}
+
+Add If Store[stores,name,params:out]
+{
+	If[[name]Contains[[params]Global Separator >>]]
+	{
+		parts <- [name]Split[[params]Global Separator >>]
+		out <- [stores]Set[[parts]Index[0], Yes]
+	}{
+		out <- stores
+	}
+}
+
+Param Gather Stores[stores,node,params:out]
+{
+	out <- [node]Gather Stores[params, stores]
+}
+
+Gather Stores@Named Pipe Node[node,params,stores:out]
+{
+	out <- Fold[["Add If Store"]Set Input[2, params], stores, [node]Assignments >>]
+}
+
+Gather Stores@Global Node[node,params,stores:out]
+{
+	out <- [stores]Set[[node]Store >>, Yes]
+}
+
+Gather Stores@Worker Node[node,params,stores:out]
+{
+	//TODO: Handle blocks
+	store list <- Fold[["Param Gather Stores"]Set Input[2, params], stores, [node]Params >>]
+	out <- Fold[["Add If Store"]Set Input[2, params], store list, [node]Assignments >>]
+}
+
+Gather Stores@Field Node[node,params,stores:out]
+{
+	//TODO: Handle blocks
+	store list <- Fold[["Param Gather Stores"]Set Input[2, params], stores, [node]Params >>]
+	out <- Fold[["Add If Store"]Set Input[2, params], store list, [node]Assignments >>]
+}
+
+Gather Stores@Literal Node[node,params,stores:out]
+{
+	out <- Fold[["Add If Store"]Set Input[2, params], stores, [node]Assignments >>]
+}
+
+
+Main[args]
+{
+	[args]Index[1]
+	{
+		file <- <String@File[~]
+		,text <- [file]Get FString[[file]Length]
+		params <- New@Parser[]
+		Null[text, params, New@Parse Program[], 0]
+		{
+			tree <- Process Imports[~, params]
+			Init Used Stores[tree, New@Dictionary[]]
+			{ [Tree to Program[tree]]Run[[args]Tail[1]] }
+		}
+	}{
+		REPL[New@Parser[]]
+	}
+}