diff nworker.rhope @ 30:914ad38f9b59

Compiler now works for some simple programs
author Mike Pavone <pavone@retrodev.com>
date Mon, 28 Sep 2009 19:42:33 -0400
parents e9272f7ebd26
children df038cef648b
line wrap: on
line diff
--- a/nworker.rhope	Sat Jun 27 01:50:33 2009 -0400
+++ b/nworker.rhope	Mon Sep 28 19:42:33 2009 -0400
@@ -1,6 +1,155 @@
 Import extendlib.rhope
 Import cbackend.rhope
 
+
+Blueprint Condition Set
+{
+	Variables
+	Subsets
+	Condition Type
+}
+
+AndSet[:out]
+{
+	out <- [[[Build["Condition Set"]]Variables <<[New@Dictionary[]]]Subsets <<[New@Dictionary[]]]Condition Type <<["And"]
+}
+
+OrSet[:out]
+{
+	out <- [[[Build["Condition Set"]]Variables <<[New@Dictionary[]]]Subsets <<[New@Dictionary[]]]Condition Type <<["Or"]
+}
+
+To String@Condition Set[set:out]
+{
+	out <- [[[[[set]Condition Type >>
+	]Append["Set:\n\tVariables:\n\t\t"]
+	]Append[ Join[Keys[[set]Variables >>], "\n\t\t"] ]
+	]Append["\n\tSubsets:\n\t\t"]
+	]Append[ Join[Keys[[set]Subsets >>], "\n\t\t"] ]
+}
+
+Add Condition@Condition Set[set,cond:out]
+{
+	If[[Type Of[cond]] = ["Condition Set"]]
+	{
+		out <- [set]Subsets <<[ [[set]Subsets>>]Set[[cond]To String, cond] ]
+	}{
+		out <- [set]Variables <<[ [[set]Variables >>]Set[cond, Yes] ]
+	}
+}
+
+=@Condition Set[set1,set2:out]
+{
+	,out <- If[[[set1]Condition Type >>] = [[set2]Condition Type >>]]
+	{
+		,out <- If[[[set1]Variables >>] = [[set2]Variables >>]]
+		{
+			out,out <- If[[[set1]Subsets >>] = [[set2]Subsets >>]]
+		}
+	}
+}
+
+_For Backend Var[current,junk,variable,type:out]
+{
+	out <- [[<String@Worker[[type]Append["Cond"]]]Do[ [[()]Append[current]]Append[variable] ]]Index[0]
+}
+
+_For Backend Subset[current,subset,type:out]
+{
+	Print["Calling For Backend on subset"]
+	{
+	[subset]For Backend
+	{
+		Print["Got output from for backend"]
+		out <- [[<String@Worker[[type]Append["Cond"]]]Do[ [[()]Append[current]]Append[~] ]]Index[0]
+		{ Print["done _For Backend Subset with condition"] }
+	}{
+		Print["none output from for backend"]
+		out <- current
+	}
+	}
+}
+
+Empty?@Condition Set[set:not empty,empty]
+{
+	[[set]Variables >>]First
+	{
+		not empty <- Yes
+	}{
+		,empty <- [[set]Subsets >>]First Non-empty Set
+		{
+			not empty <- Yes
+		}
+	}
+}
+
+_First Non-empty Set[setlist,index:out,none]
+{
+	current <- [setlist]Index[index]
+	[[current]Variables >>]First
+	{
+		out <- index
+	}{
+		,trynext <- [[current]Subsets >>]First Non-empty Set
+		{
+			out <- index
+		}
+	}
+	Val[trynext]
+	{
+		,none <- [setlist]Next[index]
+		{
+			out,none <- _First Non-empty Set[setlist, ~]
+		}
+	}
+}
+
+First Non-empty Set[setlist:index,none]
+{
+	,none <- [setlist]First
+	{
+		index,none <- _First Non-empty Set[setlist,~]
+	}
+}
+
+For Backend@Condition Set[set:out,none]
+{
+	Print["For Backend"]
+	firstvar <- [[set]Variables >>]First
+	{
+		Print["At least one var"]
+		[[set]Variables >>]Next[~]
+		{
+			Print["at least two vars"]
+			vars <- _Fold[[set]Variables >>, ~, firstvar, ["_For Backend Var"]Set Input[3, [set]Condition Type >>]]
+		}{
+			Print["just one var"]
+			vars <- Val[firstvar]
+		}
+		out <- Fold[["_For Backend Subset"]Set Input[2, [set]Condition Type >>], vars, [set]Subsets >>]
+		{ Print["done For Backend, with vars"] }
+	}{
+		Print["no vars"]
+		[[set]Subsets >>]First Non-empty Set
+		{
+			Print[["At least one non-empty subset: "]Append[~]]
+			firstsub <- [[[set]Subsets >>]Index[~]]For Backend
+			[[set]Subsets >>]Next[~]
+			{
+				Print["at least two subsets"]
+				out <- _Fold[[set]Subsets >>, ~, firstsub, ["_For Backend Subset"]Set Input[2, [set]Condition Type >>]]
+				{ Print["done with subsets, but no vars"] }
+			}{
+				out <- Val[firstsub]
+				{ Pretty Print[~, "1s:\t"] }
+			}
+		}{
+			Print["done with none"]
+			none <- Yes
+		}
+	}
+}
+
 Set@Range[range,index,val:out]
 {
 	out <- [[()]Concatenate[range]
@@ -52,10 +201,12 @@
 	Outputs
 	Wires From
 	Wires To
+	Conditions
 }
 
-Wire To@NWorker Node[node,from,output,input:out]
+Wire To@NWorker Node[node,from,output,pre input:out]
 {
+	input <- [pre input]+[1]
 	out <- [node]Wires To <<[
 		[[node]Wires To >>]Set[input,
 			[[[node]Wires To >>]Index[input]
@@ -92,13 +243,14 @@
 
 NWorker Node[type,data,inputs,outputs:out]
 {
-	out <- [[[[[[Build["NWorker Node"]
+	out <- [[[[[[[Build["NWorker Node"]
 		]Type <<[type]
 		]Data <<[data]
 		]Inputs <<[inputs]
 		]Outputs <<[outputs]
 		]Wires From <<[List of Lists[outputs]]
-		]Wires To <<[List of Lists[inputs]]
+		]Wires To <<[List of Lists[[inputs]+[1]]]
+		]Conditions <<[AndSet[]]
 }
 
 Blueprint NWorker
@@ -107,6 +259,7 @@
 	Nodes
 	Inputs
 	Outputs
+	Uses
 	NodeResults
 	Free Temps
 }
@@ -146,19 +299,36 @@
 
 Add Wire@NWorker[worker,from,output,to,input:out]
 {
+	Print[[[[[[[[["Add Wire@NWorker["]Append[from]]Append[","]]Append[output]]Append[","]]Append[to]]Append[","]]Append[input]]Append["]"]]
+	{
 	fromw <- [[[worker]Nodes >>]Index[from]]Wire From[to,input,output]
+	{ Print["fromw"] }
 	tow <- [[[worker]Nodes >>]Index[to]]Wire To[from,output,input]
+	{ Print["tow"] }
 	nodes <- [[[worker]Nodes >>]Set[from, fromw]]Set[to, tow]
+	{ Print["nodes"] }
 	out <- [worker]Nodes <<[nodes]
+	{ Print["Add Wire@NWorker done"] }
+	}
+}
+
+Uses@NWorker[worker,uses:out]
+{
+	out <- [worker]Uses <<[uses]
 }
 
 _No Dependencies[list,node,index:out]
 {
-	[[node]Wires To>>]First
+	[[node]Wires To>>]Index[1]
 	{
 		out <- Val[list]
 	}{
-		out <- [list]Append[index]
+		[[[node]Wires To>>]Index[0]]First
+		{
+			out <- Val[list]
+		}{
+			out <- [list]Append[index]
+		}
 	}
 }
 
@@ -258,6 +428,11 @@
 		{
 			input name <- [[worker]Inputs >>]Index[ [node]Data >> ]
 			out <- AddRef[input name] 
+		}{
+			If[[[node]Type >>] = ["const"]]
+			{
+				out <- Constant[[[Type Of[[node]Data >>]]Append["_"]]Append[[node]Data >>]]
+			}
 		}
 	}
 }
@@ -265,6 +440,7 @@
 Collect Input@NWorker[worker,nodeinput:out]
 {
 	inputchoices <- Map[nodeinput, ["Format Input"]Set Input[0, worker]]
+
 	[inputchoices]First
 	{
 		first <- [inputchoices]Index[~]
@@ -281,73 +457,190 @@
 
 Collect Inputs@NWorker[worker,node:out]
 {
-	out <- Map[[node]Wires To>>, ["Collect Input"]Set Input[0, worker]]
+	out <- Map[Tail[[node]Wires To>>, 1], ["Collect Input"]Set Input[0, worker]]
+}
+
+Collect Input Condition@NWorker[worker,set,noderef:out]
+{
+	node <- [[worker]Nodes >>]Index[ [noderef]Index >> ]
+	If[[[node]Outputs >>] > [1]]
+	{
+		out <- [set]Add Condition[ [["__result_"]Append[[noderef]Index >>]]Append[["_"]Append[[noderef]IO Num >>]] ]
+	}{
+		out <- [set]Add Condition[[node]Conditions >>]
+	}
+}
+
+Collect Condition@NWorker[worker,set,nodeinput:out]
+{
+	out <- [set]Add Condition[Fold[["Collect Input Condition"]Set Input[0, worker], OrSet[], nodeinput]]
+}
+
+Collect Conditions@NWorker[worker,node:out]
+{
+	Print["Collect Conditions"]
+	{
+	out <- Fold[["Collect Condition"]Set Input[0, worker], AndSet[], [node]Wires To>>]
+	{ Print["done Collect Conditions"] }
+	}
 }
 
 Save Result[func,num,node index:out]
 {
+	Print["Save Result"]
 	out var <- [[["__result_"]Append[node index]]Append["_"]]Append[num]
-	out <- [[func]Allocate Var[out var, "Any Type"]
+	Print[out var]
+	/*out <- [[func]Allocate Var[out var, "Any Type"]
 		]Move[Result[num], out var]
+	*/
+	out <- [func]Move[Result[num], out var]	
 }
 
-Compile Node@NWorker[worker,program,func,nodes,current:out]
+Compile Call Node[node,program,func,inputs,node index:out]
 {
-	Print[[node]Type >>]
+	[program]Method?[[[node]Data >>]Name >>]
+	{
+		Print["Method!"]
+		with call <- [func]Method Call[[[node]Data >>]Name >>, inputs]
+		{ Print["Method Call done"] }
+	}{
+		Print["Function!"]
+		with call <- [func]Call[[[node]Data >>]Name >>, inputs]
+	}
+	out <- Fold[["Save Result"]Set Input[2, node index], with call, Range[0, [node]Outputs >>]]
+}
+
+Compile Node@NWorker[worker,program,func,nodes,current:out,out worker]
+{
+	Print[["Compile Node: "]Append[[node]Type >>]]
 	node index <- [nodes]Index[current]
 	node <- [[worker]Nodes >>]Index[node index]
+	conditions <- [worker]Collect Conditions[node]
 	If[[[node]Type >>] = ["call"]]
 	{
+		Print[["Call: "]Append[[[node]Data >>]Name >>]]
+		
 		inputs <- [worker]Collect Inputs[node]
-		[program]Method?[[[node]Data >>]Name >>]
+		[conditions]For Backend
 		{
-			with call <- [func]Method Call[[[node]Data >>]Name >>, inputs]
+			Print["Conditional execution, do if"]
+			stream <- [func]Instruction Stream
+			nfunc <- [func]Do If[~, nstream]
 		}{
-			with call <- [func]Call[[[node]Data >>]Name >>, inputs]
+			Print["No conditions, full steam ahead"]
+			stream <- Val[func]
+			nfunc <- Val[nstream]
 		}
-		nfunc <- Fold[["Save Result"]Set Input[2, node index], with call, Range[0, [node]Outputs >>]]
+		nstream <- Compile Call Node[node, program, stream, inputs, node index]
 	}{
 		If[[[node]Type >>] = ["output"]]
 		{
 			inputs <- [worker]Collect Inputs[node]
-			nfunc <- [func]Move[[inputs]Index[0], [[worker]Outputs >>]Index[ [node]Data >> ] ]
+			[conditions]For Backend
+			{
+				stream <- [func]Instruction Stream
+				nfunc <- [func]Do If[~, nstream]
+			}{
+				stream <- Val[func]
+				nfunc <- Val[nstream]
+			}
+			nstream <- [stream]Move[[inputs]Index[0], [[worker]Outputs >>]Index[ [node]Data >> ] ]
 		}{
-			nfunc <- Val[func]
+			If[[[node]Type >>] = ["const"]]
+			{
+				//TODO: Handle list constants
+				nfunc <- [func]Register Constant[[[Type Of[[node]Data >>]]Append["_"]]Append[[node]Data >>], [node]Data >>]
+			}{
+				nfunc <- Val[func]
+			}
+			
 		}
 	}
+	If[[[node]Outputs >>] = [0]]
+	{
+		nworker <- Val[worker]
+	}{
+		nworker <- [worker]Nodes <<[ [[worker]Nodes >>]Set[node index, [node]Conditions <<[conditions]] ]
+	}
 	[nodes]Next[current]
 	{
-		out <- [worker]Compile Node[program,nfunc,nodes,~]
+		out,out worker <- [nworker]Compile Node[program,nfunc,nodes,~]
 	}{
 		out <- Val[nfunc]
+		out worker <- Val[nworker]
 	}
 }
 
-Compile Group@NWorker[worker,program,func,groups,current:out]
+Compile Group@NWorker[worker,program,func,groups,current:out,out worker]
 {
 	nodes <- [groups]Index[current]
 	[nodes]First
 	{
-		nfunc <- [worker]Compile Node[program,func,nodes,~]
+		nfunc,nworker <- [worker]Compile Node[program,func,nodes,~]
 	}{
 		nfunc <- Val[func]
+		nworker <- Val[worker]
 	}
 	[groups]Next[current]
 	{
-		out <- [worker]Compile Group[program,nfunc,groups,~]
+		out,out worker <- [nworker]Compile Group[program,nfunc,groups,~]
 	}{
 		out <- Val[nfunc]
+		out worker <- Val[nworker]
 	}
 }
 
-Release Var[func,type,name:out]
+Release Var@NWorker[worker,func,name:out]
 {
-	out <- [func]Release[name]
+	//_result_index_ionum
+	parts <- [name]Split["_"]
+	index <- <String@Whole Number[ [parts]Index[2] ]
+	io num <- <String@Whole Number[ [parts]Index[3] ]
+	node <- [[worker]Nodes >>]Index[index]
+	do if <- If[[[node]Outputs >>] > [1]] {}
+	{
+		,do if <- [[node]Conditions >>]Empty?
+		{
+			out <- [func]Release[name]
+		}
+	}
+	
+	Val[do if]
+	{
+		stream <- [[func]Instruction Stream]Release[name]
+		out <- [func]Do If[name, stream]
+	}
+}
+
+Result Var[vars,io num,index:out]
+{
+	out <- [vars]Append[[[["__result_"]Append[index]]Append["_"]]Append[io num]]
+}
+
+Node Result Vars[vars,node,index:out]
+{
+	If[[[node]Type >>] = ["call"]]
+	{
+		out <- Fold[["Result Var"]Set Input[2, index], vars, Range[0, [node]Outputs >>]]
+	}{
+		out <- vars
+	}
+}
+
+Result Vars@NWorker[worker:out]
+{
+	out <- Fold["Node Result Vars", (), [worker]Nodes >>]
 }
 
 Compile Worker@NWorker[worker,program,name:out]
 {
-	func <- Fold["Null", [program]Create Function[name,[worker]Inputs >>, [worker]Outputs >>, [worker]Convention >>], [worker]Outputs >>]
+	Print[["Compiling: "]Append[name]]
+	{
+	ifunc <- [program]Create Function[name,[worker]Inputs >>, [worker]Outputs >>, [worker]Convention >>]
+	
+	res vars <- [worker]Result Vars
+	func <- Fold["Set Null", Fold["Set Null", Fold[["Allocate Var"]Set Input[2, "Any Type"], ifunc, res vars], res vars], [worker]Outputs >>]
+	
 	groups <- [worker]Dependency Groups
 	[groups]First
 	{
@@ -355,7 +648,8 @@
 	}{
 		final func <- Val[func]
 	}
-	out <- [program]Store Function[Fold["Release Var", final func, [final func]Variables >>]]
+	out <- [program]Store Function[Fold[["Release Var"]Set Input[0, worker], final func, res vars]]
+	}
 }
 
 Test[:out]
@@ -382,7 +676,59 @@
 	out <- [Test[]]Compile Worker[C Program[], "Test"]
 }
 
-Main[]
+Blueprint NProgram
+{
+	Blueprints
+	Workers
+	Worker Refs
+}
+
+NProgram[:out]
+{
+	out <- [[[Build["NProgram"]]Blueprints <<[New@Dictionary[]]]Workers <<[New@Dictionary[]]]Worker Refs <<[New@Dictionary[]]
+}
+
+Bind Worker@NProgram[prog,name,worker:out]
+{
+	out <- [prog]Workers << [ [[prog]Workers >>]Set[name, worker] ]
+}
+
+Bind Blueprint@NProgram[prog,name,blueprint:out]
+{
+	out <- [prog]Blueprints << [ [[prog]Blueprints >>]Set[name, blueprint] ]
+}
+
+_Compile Program[backend, worker, name:out]
 {
-	Pretty Print[Test Graph to Backend[], ""]
+	out <- [worker]Compile Worker[backend, name]
+}
+
+Compile Program@NProgram[prog, backend:out]
+{
+	out <- Fold["_Compile Program", backend, [prog]Workers >>]
+}
+
+Register Worker@NProgram[prog, name, convention, inputs, outputs: out]
+{
+	Print[["Register Worker "]Append[name]]
+	out <- [prog]Worker Refs <<[ [[prog]Worker Refs >>]Set[name, Worker Ref[name, convention, inputs, outputs]]]
 }
+
+Register Builtins@NProgram[prog:out]
+{
+	out <- [[[[[[[[[prog]Register Worker["+", "cdecl", 2, 1]
+	]Register Worker["-", "cdecl", 2, 1]
+	]Register Worker["*", "cdecl", 2, 1]
+	]Register Worker["/", "cdecl", 2, 1]
+	]Register Worker["Print", "cdecl", 1, 1]
+	]Register Worker["Index", "cdecl", 2, 1]
+	]Register Worker["If", "cdecl", 1, 2]
+	]Register Worker["<", "cdecl", 2, 1]
+	]Register Worker["<String@Whole Number", "cdecl", 1, 1]
+}
+
+Find Worker@NProgram[prog, name:out,notfound]
+{
+	Print[ ["Find Worker@NProgram: "]Append[name] ]
+	out,notfound <- [[prog]Worker Refs >>]Index[name]
+}