diff nworker.rhope @ 36:495dddadd058

User defined types work in the compiler now
author Mike Pavone <pavone@retrodev.com>
date Sat, 03 Oct 2009 03:18:15 -0400
parents df038cef648b
children 640f541e9116
line wrap: on
line diff
--- a/nworker.rhope	Wed Sep 30 23:55:04 2009 -0400
+++ b/nworker.rhope	Sat Oct 03 03:18:15 2009 -0400
@@ -297,6 +297,16 @@
 	{ out <- [~]Outputs <<[[[~]Outputs >>]Set[number,name]] }
 }
 
+Add Object Get@NWorker[worker,fieldname:out,node index]
+{
+	out, node index <- [worker]Add Node["getfield",fieldname,1,1]
+}
+
+Add Object Set@NWorker[worker,fieldname:out,node index]
+{
+	out, node index <- [worker]Add Node["setfield",fieldname,2,1]
+}
+
 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["]"]]
@@ -420,7 +430,7 @@
 Format Input@NWorker[worker,noderef:out]
 {
 	node <- [[worker]Nodes >>]Index[[noderef]Index >>]
-	If[[[node]Type >>] = ["call"]]
+	[("call","getfield","setfield")]Find[[node]Type >>]
 	{
 		out <- AddRef[ [[["__result_"]Append[[noderef]Index >>]]Append["_"]]Append[[noderef]IO Num >>] ]
 	}{
@@ -431,7 +441,15 @@
 		}{
 			If[[[node]Type >>] = ["const"]]
 			{
-				out <- Constant[[[Type Of[[node]Data >>]]Append["_"]]Append[[node]Data >>]]
+				If[[Type Of[[node]Data >>]] = ["Type Literal"]]
+				{
+					//TODO: Support parametric types
+					datstring <- [[node]Data >>]Name >>
+				}{
+					datstring <- [node]Data >>
+				}
+				out <- Constant[[[Type Of[[node]Data >>]]Append["_"]]Append[datstring]]
+					
 			}
 		}
 	}
@@ -498,14 +516,27 @@
 
 Compile Call Node[node,program,func,inputs,node index:out]
 {
-	[program]Method?[[[node]Data >>]Name >>]
+	If[[[node]Type >>] = ["getfield"]]
 	{
-		Print["Method!"]
-		with call <- [func]Method Call[[[node]Data >>]Name >>, inputs]
-		{ Print["Method Call done"] }
+		with call <- [func]Get Field Call[[node]Data >>, [inputs]Index[0]]
 	}{
-		Print["Function!"]
-		with call <- [func]Call[[[node]Data >>]Name >>, inputs]
+		If[[[node]Type >>] = ["setfield"]]
+		{
+			with call <- [func]Set Field Call[[node]Data >>, [inputs]Index[0], [inputs]Index[1]]
+		}{
+			Print[["Call: "]Append[[[node]Data >>]Name >>]]
+			{
+			[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 >>]]
 }
@@ -516,10 +547,8 @@
 	node index <- [nodes]Index[current]
 	node <- [[worker]Nodes >>]Index[node index]
 	conditions <- [worker]Collect Conditions[node]
-	If[[[node]Type >>] = ["call"]]
+	[("call","getfield","setfield")]Find[[node]Type >>]
 	{
-		Print[["Call: "]Append[[[node]Data >>]Name >>]]
-		
 		inputs <- [worker]Collect Inputs[node]
 		[conditions]For Backend
 		{
@@ -549,7 +578,14 @@
 			If[[[node]Type >>] = ["const"]]
 			{
 				//TODO: Handle list constants
-				nfunc <- [func]Register Constant[[[Type Of[[node]Data >>]]Append["_"]]Append[[node]Data >>], [node]Data >>]
+				If[[Type Of[[node]Data >>]] = ["Type Literal"]]
+				{
+					//TODO: Support parametric types
+					datstring <- [[node]Data >>]Name >>
+				}{
+					datstring <- [node]Data >>
+				}
+				nfunc <- [func]Register Constant[[[Type Of[[node]Data >>]]Append["_"]]Append[datstring], [node]Data >>]
 			}{
 				nfunc <- Val[func]
 			}
@@ -619,7 +655,7 @@
 
 Node Result Vars[vars,node,index:out]
 {
-	If[[[node]Type >>] = ["call"]]
+	[("call","getfield","setfield")]Find[[node]Type >>]
 	{
 		out <- Fold[["Result Var"]Set Input[2, index], vars, Range[0, [node]Outputs >>]]
 	}{
@@ -676,6 +712,129 @@
 	out <- [Test[]]Compile Worker[C Program[], "Test"]
 }
 
+Blueprint NBlueprint
+{
+	Fields
+	Methods
+}
+
+NBlueprint[:out]
+{
+	out <- [[Build["NBlueprint"]]Fields <<[()]]Methods <<[New@Dictionary[]]
+}
+
+Add Field@NBlueprint[bp,name,type:out]
+{
+	out <- [bp]Fields <<[ [[bp]Fields >>]Append[ [[()]Append[name]]Append[type] ] ]
+}
+
+Add Method@NBlueprint[bp,name:out]
+{
+	out <- [bp]Methods <<[ [[bp]Methods >>]Set[name, Yes] ]
+}
+
+_Compile Blueprint Fields[type,field:out]
+{
+	name <- [field]Index[0]
+	ftype <- [field]Index[1]
+	out <- [type]Add Field[name,ftype]
+}
+
+_Compile Blueprint Methods[type,junk,name:out]
+{
+	out <- [type]Add Method[name]
+}
+
+Make Init[func,field:out]
+{
+	name <- [field]Index[0]
+	out <- [func]Set Field Null["obj", name]
+}
+
+Make Copy[func,field:out]
+{
+	name <- [field]Index[0]
+	got <- [func]Read Field["obj", name] {}
+	{ 
+		stream <- [[got]Instruction Stream
+			]AddRef No Dest[~] 
+		out <- [got]Do If[~, stream]
+	}
+}
+
+Make Cleanup[func,field:out]
+{
+	name <- [field]Index[0]
+	got <- [func]Read Field["obj", name] {}
+	{ 
+		stream <- [[got]Instruction Stream
+			]Release[~] 
+		out <- [got]Do If[~, stream]
+	}
+}
+
+Make Special@NBlueprint[bp,backend,func name,bp name,pop worker:out]
+{
+	func <- [[backend]Create Function[func name,("obj"),(),"cdecl"]
+		]Set Input Type[0, bp name]
+	out <- [backend]Store Function[Fold[pop worker, func, [bp]Fields >>]]
+}
+
+Getters Setters[backend,field,type name:out]
+{
+	//TODO: Throw an exception or something if we read a field that is empty
+	Print[["Getters Setters: "]Append[name]]
+	name <- [field]Index[0]
+	type <- [field]Index[1]
+	,getref <- [[[[backend]Create Function[ [[[name]Append[" >>"]]Append["@"]]Append[type name], ("obj"), ("out"), "rhope"]
+		]Set Input Type[0, type name]
+		]Set Output Type[0, type]
+		]Read Field["obj", name]
+	{ getter <- [~]Do AddRef[getref, "out"]
+	{ Print["Got getter"] } }
+		
+	,origref <- [[[[[[backend]Create Function[ [[[name]Append[" <<"]]Append["@"]]Append[type name], ("obj","newval"), ("out"), "rhope"]
+		]Set Input Type[0, type name]
+		]Set Input Type[1, type]
+		]Set Output Type[0, type name]
+		]Copy["obj"]
+		]Read Field["obj", name]
+	{ 
+		stream <- [[~]Instruction Stream
+		]Release[origref]
+		,setref <- [[~]Do If[origref, stream]
+		]Write Field["obj", name]
+		{
+			setter <- [[~]Move["newval", setref]
+			]Move["obj", "out"]
+			{ Print["got setter"] }
+		}
+	}
+	
+	out <- [[backend]Store Function[getter]]Store Function[setter]
+	
+}
+
+Compile Blueprint@NBlueprint[bp,backend,name:out]
+{
+	
+	//Rhope identifiers can't start with spaces, so we can use identifiers that start with spaces for special functions
+	init name <- [" init "]Append[name]
+	copy name <- [" copy "]Append[name]
+	cleanup name <- [" cleanup "]Append[name]
+	type <- [[[Fold["_Compile Blueprint Methods", Fold["_Compile Blueprint Fields", [backend]Create Type[name], [bp]Fields >>], [bp]Methods >>]
+	]Init <<[init name]
+	]Copy <<[copy name]
+	]Cleanup <<[cleanup name]
+	
+	got specials <- [bp]Make Special[
+				[bp]Make Special[
+					[bp]Make Special[[backend]Register Type[type], init name, name, "Make Init"], 
+					copy name, name, "Make Copy"], 
+			cleanup name, name, "Make Cleanup"]
+	out <- Fold[["Getters Setters"]Set Input[2, name], got specials, [bp]Fields >>]
+}
+
 Blueprint NProgram
 {
 	Blueprints
@@ -689,15 +848,28 @@
 }
 
 Bind Worker@NProgram[prog,name,worker:out]
-{
-	out <- [prog]Workers << [ [[prog]Workers >>]Set[name, worker] ]
+{	
+	after bind <- [prog]Workers << [ [[prog]Workers >>]Set[name, worker] ]
+	parts <- [name]Split["@"]
+	[parts]Index[1]
+	{
+		out <- [after bind]Blueprints <<[ [[after bind]Blueprints >>]Set[~, [[[after bind]Blueprints >>]Index[~]]Add Method[[parts]Index[0]] ] ]
+	}{
+		out <- Val[after bind]
+	}
 }
 
 Bind Blueprint@NProgram[prog,name,blueprint:out]
 {
+	Print[["Bind blueprint: "]Append[name]]
 	out <- [prog]Blueprints << [ [[prog]Blueprints >>]Set[name, blueprint] ]
 }
 
+_Compile Program BP[backend, blueprint, name:out]
+{
+	out <- [blueprint]Compile Blueprint[backend, name]
+}
+
 _Compile Program[backend, worker, name:out]
 {
 	out <- [worker]Compile Worker[backend, name]
@@ -705,26 +877,33 @@
 
 Compile Program@NProgram[prog, backend:out]
 {
-	out <- Fold["_Compile Program", backend, [prog]Workers >>]
+	out <- Fold["_Compile Program", Fold["_Compile Program BP", backend, [prog]Blueprints >>], [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]]]
+	after reg <- [prog]Worker Refs <<[ [[prog]Worker Refs >>]Set[name, Worker Ref[name, convention, inputs, outputs]]]
+	parts <- [name]Split["@"]
+	[parts]Index[1]
+	{
+		out <- [prog]Register Worker[[parts]Index[0], convention, inputs, outputs]
+	}{
+		out <- Val[after reg]
+	}
 }
 
 Register Builtins@NProgram[prog:out]
 {
-	out <- [[[[[[[[[prog]Register Worker["+", "rhope", 2, 1]
-	]Register Worker["-", "rhope", 2, 1]
-	]Register Worker["*", "rhope", 2, 1]
-	]Register Worker["/", "rhope", 2, 1]
+	out <- [[[[[[[[[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["Print", "rhope", 1, 1]
-	]Register Worker["Index", "rhope", 2, 1]
-	]Register Worker["If", "rhope", 1, 2]
-	]Register Worker["<", "rhope", 2, 1]
-	]Register Worker[">", "rhope", 1, 1]
+	]Register Worker["If@Yes No", "rhope", 1, 2]
+	]Register Worker["<@Int32", "rhope", 2, 1]
+	]Register Worker[">@Int32", "rhope", 1, 1]
+	]Register Worker["Build", "rhope", 1, 1]
 }
 
 Find Worker@NProgram[prog, name:out,notfound]
@@ -732,3 +911,4 @@
 	Print[ ["Find Worker@NProgram: "]Append[name] ]
 	out,notfound <- [[prog]Worker Refs >>]Index[name]
 }
+