# HG changeset patch # User Mike Pavone # Date 1257038908 14400 # Node ID a7c79ac22efc11cd36a3ca6a739d627540c4f50c # Parent 709df3e82bb4672af79618eb1f937c325c699845 Beginning of basic type inference diff -r 709df3e82bb4 -r a7c79ac22efc nworker.rhope --- 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? >>] + } +}