changeset 44:a7c79ac22efc

Beginning of basic type inference
author Mike Pavone <pavone@retrodev.com>
date Sat, 31 Oct 2009 21:28:28 -0400
parents 709df3e82bb4
children 6420c35edb43
files nworker.rhope
diffstat 1 files changed, 302 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/nworker.rhope	Thu Oct 15 21:32:43 2009 -0400
+++ b/nworker.rhope	Sat Oct 31 21:28:28 2009 -0400
@@ -167,11 +167,12 @@
 	Convention
 	Inputs
 	Outputs
+	Is Method?
 }
 
-Worker Ref[name,convention,inputs,outputs:out]
+Worker Ref[name,convention,inputs,outputs,ismethod?:out]
 {
-	out <- [[[[Build["Worker Ref"]]Name <<[name]]Convention <<[convention]]Inputs <<[inputs]]Outputs <<[outputs]
+	out <- [[[[[Build["Worker Ref"]]Name <<[name]]Convention <<[convention]]Inputs <<[inputs]]Outputs <<[outputs]]Is Method ? <<[ismethod?]
 }
 
 Blueprint Node Ref
@@ -198,7 +199,9 @@
 	Type
 	Data
 	Inputs
+	Input Types
 	Outputs
+	Output Types
 	Wires From
 	Wires To
 	Conditions
@@ -225,6 +228,31 @@
 	]
 }
 
+_Has Input Types@NWorker Node[node,input num:does,does not]
+{
+	does <- If[[input num] > [[node]Inputs >>]] {}
+	{
+		,does not <- [[node]Input Types >>]Index[input num]
+		{
+			count <- [~]Index[1]
+			,does not <- If[[count] = [[[[node]Wires To >>]Index[input num]]Length]]
+			{
+				does,does not <- [node]_Has Input Types[[input num]+[1]]
+			}
+		}
+	}
+}
+
+Has Input Types?@NWorker Node[node:does,does not]
+{
+	If[[[[node]Inputs >>]Length] > [0]]
+	{
+		does,does not <- _Has Input Types[node,0]
+	}{
+		does <- Yes
+	}
+}
+
 _Dependency[dlist,ref:out]
 {
 	[dlist]Find[ref]
@@ -243,7 +271,7 @@
 
 NWorker Node[type,data,inputs,outputs:out]
 {
-	out <- [[[[[[[Build["NWorker Node"]
+	out <- [[[[[[[[[Build["NWorker Node"]
 		]Type <<[type]
 		]Data <<[data]
 		]Inputs <<[inputs]
@@ -251,6 +279,8 @@
 		]Wires From <<[List of Lists[outputs]]
 		]Wires To <<[List of Lists[[inputs]+[1]]]
 		]Conditions <<[AndSet[]]
+		]Input Types <<[()]
+		]Output Types <<[()]
 }
 
 Blueprint NWorker
@@ -264,11 +294,13 @@
 	Uses
 	NodeResults
 	Free Temps
+	Name
+	Builtin?
 }
 
 NWorker[convention:out]
 {
-	out <- [[[[[[Build["NWorker"]]Convention <<[convention]]Nodes <<[()]]Inputs <<[()]]Outputs <<[()]]Input Types <<[()]]Output Types <<[()]
+	out <- [[[[[[[[Build["NWorker"]]Convention <<[convention]]Nodes <<[()]]Inputs <<[()]]Outputs <<[()]]Input Types <<[()]]Output Types <<[()]]Name <<["Anonymous"]]Builtin <<[No]
 }
 
 Add Node@NWorker[worker,type,data,inputs,outputs:out,node index]
@@ -277,6 +309,146 @@
 	node index <- [[worker]Nodes >>]Length
 }
 
+Propagate Type[nodelist,dest,prog,worker,type:out]
+{
+	node <- [nodelist]Index[[dest]Index >>]
+	
+	[[node]Input Types >>]Index[[dest]IO Num >>]
+	{
+		existing type <- [~]Index[0]
+		new count <- [[~]Index[1]]+[1]
+		If[[[existing type]Name >>] = [[type]Name >>]]
+		{
+			If[[[existing type]Variant >>] = [[type]Variant >>]]
+			{
+				If[[[existing type]Params >>] = [[type]Params >>]]
+				{
+					new type <- Val[existing type]
+				}{
+					new variant <- [existing type]Variant >>
+					new params <- ()
+				}
+			}{
+				new variant <- "Boxed"
+				If[[[existing type]Params >>] = [[type]Params >>]]
+				{
+					new params <- [existing type]Params >>
+				}{
+					new params <- ()
+				}
+			}
+			new type <- [[existing type]Set Variant[new variant]]Params <<[new params]
+		}{
+			new type <- Type Instance["Any Type"]
+		}
+	}{
+		new type <- Val[type]
+		new count <- 1
+	}
+	new node <- [node]Input Types <<[  [[node]Input Types >>]Set[[dest]IO Num >>, new type] ]
+	out <- Infer Types Node[[nodelist]Set[[dest]Index >>, new node], new node, [dest]Index >>, prog, worker]
+}
+
+Propagate Types[nodelist,dests,output num,prog,worker,source node:out]
+{
+	out <- Fold[[[["Propagate Type"]Set Input[2, prog]]Set Input[3, worker]]Set Input[4, [[source node]Output Types >>]Index[output num]], nodelist, dests]
+}
+
+Infer Types Node[nodelist,node,index,prog,worker:out]
+{
+	If[[[node]Type >>] = ["const"]]
+	{
+		//Temporary hack
+		If[[Type Of[[node]Data >>]] = ["Whole Number"]]
+		{
+			outtype <- Type Instance["Whole Number"]
+		}{
+			outtype <- Type Instance[Type Of[[node]Data >>]]
+		}
+		nextnode <- [node]Output Types <<[ [()]Append[outtype] ]
+		
+	}{
+		If[[[node]Type >>] = ["input"]]
+		{
+			nextnode <- [node]Output Types <<[ [()]Append[ [[worker]Input Types >>]Index[[node]Data >>] ] ]
+		}{
+			If[[[node]Type >>] = ["output"]]
+			{
+				out <- nodelist
+			}{
+				[node]Has Input Types?
+				{
+					If[[[node]Type >>] = ["setfield"]]
+					{
+						nextnode <- [node]Output Types <<[ [()]Append[ [[[node]Input Types >>]Index[0]]Index[0] ] ]
+					}{
+						If[[[node]Type >>] = ["getfield"]]
+						{
+							type <- [[[node]Input Types >>]Index[0]]Index[0]
+							If[[[type]Name >>] = ["Any Type"]]
+							{
+								outtype <- Val[type]
+							}{
+								outtype <- [prog]Find Field[[node]Data >>, type] {}
+								{
+									//TODO: Return errors rather than printing them
+									Print[
+										[[[[["Type "
+										]Append[[type]Name >>]
+										]Append[" does not have a field named "]
+										]Append[[node]Data >>]
+										]Append[" in worker "]
+										]Append[worker name]]
+								}
+							}
+							nextnode <- [node]Output Types <<[ [()]Append[outtype] ]
+						}{
+							worker name <- [[node]Data >>]Name >>
+							[prog]Is Method?[worker name]
+							{
+								first arg type <- [[[node]Input Types >>]Index[0]]Index[0]
+								If[[[first arg type]Name >>] = ["Any Type"]]
+								{
+									outtypes <- Fold[["Append"]Set Input[1, Type Instance["Any Type"]], (), Range[0, [node]Inputs >>]]
+								}{
+									worker def <- [prog]Find Method[worker name, first arg type] {}
+									{
+										//TODO: Return errors instead of printing them
+										Print[
+											[[[[["Type "
+											]Append[[first arg type]Name >>]
+											]Append[" does not support method "]
+											]Append[worker name]
+											]Append[" in worker "]
+											]Append[ [worker]Name >> ]]
+									}
+								}
+							}{
+								worker def <- [prog]Find Worker Def[worker name]
+							}
+							outtypes <- [worker def]Output Types >>
+							nextnode <- [node]Output Types <<[ outtypes ]
+						}
+					}
+				}{
+					out <- nodelist
+				}
+			}
+		}
+	}
+	
+	Val[nextnode]
+	{
+		nextlist <- [nodelist]Set[index, nextnode]
+		out <- Fold[[[["Propagate Types"]Set Input[3, prog]]Set Input[4, worker]]Set Input[5, nextnode], nodelist, [nextnode]Wires From >>]
+	}
+}
+
+Infer Types@NWorker[worker,prog:out]
+{
+	out <- [worker]Nodes <<[Fold[[["Infer Types Node"]Set Input[3, prog]]Set Input[4, worker], [worker]Nodes >>, [worker]Nodes >>]]
+}
+
 Add Worker Call@NWorker[worker,tocall:out,node index]
 {
 	out, node index <- [worker]Add Node["call",tocall,[tocall]Inputs >>,[tocall]Outputs >>]
@@ -688,21 +860,26 @@
 
 Compile Worker@NWorker[worker,program,name:out]
 {
-	Print[["Compiling: "]Append[name]]
+	If[[worker]Builtin? >>]
 	{
-	ifunc <- Fold["Set Output Type", Fold["Set Input Type", [program]Create Function[name,[worker]Inputs >>, [worker]Outputs >>, [worker]Convention >>], [worker]Input Types >>], [worker]Output Types >>]
-	
-	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
-	{
-		final func <- [worker]Compile Group[program,func,groups, ~]
+		out <- program
 	}{
-		final func <- Val[func]
-	}
-	out <- [program]Store Function[Fold["Release", Fold[["Release Var"]Set Input[0, worker], final func, res vars], [worker]Inputs >>]]
+		Print[["Compiling: "]Append[name]]
+		{
+		ifunc <- Fold["Set Output Type", Fold["Set Input Type", [program]Create Function[name,[worker]Inputs >>, [worker]Outputs >>, [worker]Convention >>], [worker]Input Types >>], [worker]Output Types >>]
+		
+		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
+		{
+			final func <- [worker]Compile Group[program,func,groups, ~]
+		}{
+			final func <- Val[func]
+		}
+		out <- [program]Store Function[Fold["Release", Fold[["Release Var"]Set Input[0, worker], final func, res vars], [worker]Inputs >>]]
+		}
 	}
 }
 
@@ -925,7 +1102,7 @@
 
 Bind Worker@NProgram[prog,name,worker:out]
 {	
-	after bind <- [prog]Workers << [ [[prog]Workers >>]Set[name, worker] ]
+	after bind <- [prog]Workers << [ [[prog]Workers >>]Set[name, [worker]Name <<[name]] ]
 	parts <- [name]Split["@"]
 	[parts]Index[1]
 	{
@@ -961,14 +1138,19 @@
 	out <- Fold["_Compile Program", Fold["_Compile Program BP Special", Fold["_Compile Program BP", backend, [prog]Blueprints >>], [prog]Blueprints >>], [prog]Workers >>]
 }
 
+Register Method@NProgram[prog, name, convention, inputs, outputs: out]
+{
+	out <- [prog]Worker Refs <<[ [[prog]Worker Refs >>]Set[name, Worker Ref[name, convention, inputs, outputs, Yes]]]
+}
+
 Register Worker@NProgram[prog, name, convention, inputs, outputs: out]
 {
 	Print[["Register Worker "]Append[name]]
-	after reg <- [prog]Worker Refs <<[ [[prog]Worker Refs >>]Set[name, Worker Ref[name, convention, inputs, outputs]]]
+	after reg <- [prog]Worker Refs <<[ [[prog]Worker Refs >>]Set[name, Worker Ref[name, convention, inputs, outputs, No]]]
 	parts <- [name]Split["@"]
 	[parts]Index[1]
 	{
-		out <- [prog]Register Worker[[parts]Index[0], convention, inputs, outputs]
+		out <- [after reg]Register Method[[parts]Index[0], convention, inputs, outputs]
 	}{
 		out <- Val[after reg]
 	}
@@ -976,17 +1158,97 @@
 
 Register Builtins@NProgram[prog:out]
 {
-	out <- [[[[[[[[[[[prog]Register Worker["+@Int32", "rhope", 2, 1]
+	registered <- [[[[[[[[[[[prog]Register Worker["+@Int32", "rhope", 2, 1]
 	]Register Worker["-@Int32", "rhope", 2, 1]
 	]Register Worker["*@Int32", "rhope", 2, 1]
 	]Register Worker["/@Int32", "rhope", 2, 1]
 	]Register Worker["LShift@Int32", "rhope", 2, 1]
 	]Register Worker["RShift@Int32", "rhope", 2, 1]
 	]Register Worker["Print", "rhope", 1, 1]
-	]Register Worker["If@Yes No", "rhope", 1, 2]
+	]Register Worker["If@Boolean", "rhope", 1, 2]
 	]Register Worker["<@Int32", "rhope", 2, 1]
 	]Register Worker[">@Int32", "rhope", 2, 1]
 	]Register Worker["Build", "rhope", 1, 1]
+	
+	out <- [[[[[[[[[[[[[registered]Bind Blueprint["Int32", NBlueprint[]]
+	]Bind Worker["+@Int32", 
+		[[[[[NWorker["rhope"]
+		]Inputs <<[("left","right")]
+		]Input Types <<[ [[()]Append[Type Instance["Int32"]]]Type Instance["Int32"] ]
+		]Outputs <<[("out")]
+		]Output types <<[ [()]Append[Type Instance["Int32"]] ]
+		]Builin? <<[Yes]]
+	]Bind Worker["-@Int32", 
+		[[[[[NWorker["rhope"]
+		]Inputs <<[("left","right")]
+		]Input Types <<[ [[()]Append[Type Instance["Int32"]]]Type Instance["Int32"] ]
+		]Outputs <<[("out")]
+		]Output types <<[ [()]Append[Type Instance["Int32"]] ]
+		]Builin? <<[Yes]]
+	]Bind Worker["*@Int32", 
+		[[[[[NWorker["rhope"]
+		]Inputs <<[("left","right")]
+		]Input Types <<[ [[()]Append[Type Instance["Int32"]]]Type Instance["Int32"] ]
+		]Outputs <<[("out")]
+		]Output types <<[ [()]Append[Type Instance["Int32"]] ]
+		]Builin? <<[Yes]]
+	]Bind Worker["/@Int32", 
+		[[[[[NWorker["rhope"]
+		]Inputs <<[("left","right")]
+		]Input Types <<[ [[()]Append[Type Instance["Int32"]]]Type Instance["Int32"] ]
+		]Outputs <<[("out")]
+		]Output types <<[ [()]Append[Type Instance["Int32"]] ]
+		]Builin? <<[Yes]]
+	]Bind Worker["LShift@Int32", 
+		[[[[[NWorker["rhope"]
+		]Inputs <<[("left","right")]
+		]Input Types <<[ [[()]Append[Type Instance["Int32"]]]Type Instance["Int32"] ]
+		]Outputs <<[("out")]
+		]Output types <<[ [()]Append[Type Instance["Int32"]] ]
+		]Builin? <<[Yes]]
+	]Bind Worker["RShift@Int32", 
+		[[[[[NWorker["rhope"]
+		]Inputs <<[("left","right")]
+		]Input Types <<[ [[()]Append[Type Instance["Int32"]]]Type Instance["Int32"] ]
+		]Outputs <<[("out")]
+		]Output types <<[ [()]Append[Type Instance["Int32"]] ]
+		]Builin? <<[Yes]]
+	]Bind Worker["<@Int32", 
+		[[[[[NWorker["rhope"]
+		]Inputs <<[("left","right")]
+		]Input Types <<[ [[()]Append[Type Instance["Int32"]]]Type Instance["Int32"] ]
+		]Outputs <<[("out")]
+		]Output types <<[ [()]Append[Type Instance["Int32"]] ]
+		]Builin? <<[Yes]]
+	]Bind Worker[">@Int32", 
+		[[[[[NWorker["rhope"]
+		]Inputs <<[("left","right")]
+		]Input Types <<[ [[()]Append[Type Instance["Int32"]]]Type Instance["Int32"] ]
+		]Outputs <<[("out")]
+		]Output types <<[ [()]Append[Type Instance["Int32"]] ]
+		]Builin? <<[Yes]]
+	]Bind Blueprint["Boolean", NBlueprint[]]
+	]Bind Worker["If@Boolean",
+		[[[[[NWorker["rhope"]
+		]Inputs <<[("condition")]
+		]Input Types <<[ [()]Append[Type Instance["Boolean"]] ]
+		]Outputs <<[("isyes","isno")]
+		]Output types <<[ [[()]Append[Type Instance["Boolean"]]]Append[Type Instance["Boolean"]] ]
+		]Builin? <<[Yes]]
+	]Bind Worker["Print",
+		[[[[[NWorker["rhope"]
+		]Inputs <<[("value")]
+		]Input Types <<[ [()]Append[Type Instance["Any Type"]] ]
+		]Outputs <<[("out")]
+		]Output types <<[ [()]Append[Type Instance["Int32"]] ]
+		]Builin? <<[Yes]] 
+	]Bind Worker["Build",
+		[[[[[NWorker["rhope"]
+		]Inputs <<[("type")]
+		]Input Types <<[ [()]Append[Type Instance["Blueprint"]] ]
+		]Outputs <<[("out")]
+		]Output types <<[ [()]Append[Type Instance["Any Type"]] ]
+		]Builin? <<[Yes]] 
 }
 
 Find Worker@NProgram[prog, name:out,notfound]
@@ -995,6 +1257,11 @@
 	out,notfound <- [[prog]Worker Refs >>]Index[name]
 }
 
+Find Worker Def@NProgram[prog,name:out,notfound]
+{
+	out,notfound <- [[prog]Workers >>]Index[name]
+}
+
 Find Method@NProgram[prog, name, type:out,notfound]
 {
 	bp,notfound <- [[prog]Blueprints >>]Index[[type]Name >>]
@@ -1009,3 +1276,16 @@
 	bp,notfound <- [[prog]Blueprints >>]Index[[type]Name >>]
 	fieldtype,notfound <- [bp]Get Field Type[name]
 }
+
+Implicit Conversion@NProgram[prog, fromtype, totype:func,notfound]
+{
+	notfound <- No
+}
+
+Is Method?@NProgram[prog,name:is,is not]
+{
+	,is not <- [[prog]Worker Refs>>]Index[name]
+	{
+		is,is not <- If[[~]Is Method? >>]
+	}
+}