comparison nworker_c.rhope @ 102:2f6f0867fd68

Added files I forgot to add in a previous commit
author Mike Pavone <pavone@retrodev.com>
date Tue, 10 Aug 2010 20:55:52 -0400
parents
children fd23ab2c1a73 25a205094f9b
comparison
equal deleted inserted replaced
101:f4fc0a98088a 102:2f6f0867fd68
1 Import cbackend_c.rhope
2 Import number_c.rhope
3 Import boolean.rhope
4
5 Blueprint Condition Set
6 {
7 Variables
8 Subsets
9 Condition Type
10 }
11
12 AndSet[:out]
13 {
14 out <- [[[Build[Condition Set()]]Variables <<[Dictionary[]]]Subsets <<[Dictionary[]]]Condition Type <<["And"]
15 }
16
17 OrSet[:out]
18 {
19 out <- [[[Build[Condition Set()]]Variables <<[Dictionary[]]]Subsets <<[Dictionary[]]]Condition Type <<["Or"]
20 }
21
22 To String@Condition Set[set:out]
23 {
24 out <- [[[[[set]Condition Type >>
25 ]Append["Set:\n\tVariables:\n\t\t"]
26 ]Append[ Join[Keys[[set]Variables >>], "\n\t\t"] ]
27 ]Append["\n\tSubsets:\n\t\t"]
28 ]Append[ Join[Keys[[set]Subsets >>], "\n\t\t"] ]
29 }
30
31 Add Condition@Condition Set[set,cond:out]
32 {
33 If[[Blueprint Of[cond]] = [Condition Set()]]
34 {
35 out <- [set]Subsets <<[ [[set]Subsets>>]Set[[cond]To String, cond] ]
36 }{
37 out <- [set]Variables <<[ [[set]Variables >>]Set[cond, Yes] ]
38 }
39 }
40
41 =@Condition Set[set1,set2:out]
42 {
43 ,out <- If[[[set1]Condition Type >>] = [[set2]Condition Type >>]]
44 {
45 ,out <- If[[[set1]Variables >>] = [[set2]Variables >>]]
46 {
47 out,out <- If[[[set1]Subsets >>] = [[set2]Subsets >>]]
48 }
49 }
50 }
51
52 _For Backend Var[current,junk,variable,type:out]
53 {
54 If[[type]=["And"]]
55 { cond <- Val[AndCond[?]] }
56 { cond <- Val[OrCond[?]] }
57 out <- [cond]Call[current, variable]
58 }
59
60 _For Backend Subset[current,subset,type:out]
61 {
62 [subset]For Backend
63 {
64 If[[type]=["And"]]
65 { cond <- Val[AndCond[?]] }
66 { cond <- Val[OrCond[?]] }
67 out <- out <- [cond]Call[current, ~]
68 }{
69 out <- current
70 }
71 }
72
73 Empty?@Condition Set[set:not empty,empty]
74 {
75 Print["Empty?@Condition Set"]
76 [[set]Variables >>]First
77 {
78 not empty <- Yes
79 }{
80 ,empty <- [[set]Subsets >>]First Non-empty Set
81 {
82 not empty <- Yes
83 }
84 }
85 }
86
87 _First Non-empty Set[setlist,index:out,none]
88 {
89 current <- [setlist]Index[index]
90 [[current]Variables >>]First
91 {
92 out <- index
93 }{
94 ,trynext <- [[current]Subsets >>]First Non-empty Set
95 {
96 out <- index
97 }
98 }
99 Val[trynext]
100 {
101 ,none <- [setlist]Next[index]
102 {
103 out,none <- _First Non-empty Set[setlist, ~]
104 }
105 }
106 }
107
108 First Non-empty Set[setlist:index,none]
109 {
110 ,none <- [setlist]First
111 {
112 index,none <- _First Non-empty Set[setlist,~]
113 }
114 }
115
116 For Backend@Condition Set[set:out,none]
117 {
118 firstvar <- [[set]Variables >>]First
119 {
120 [[set]Variables >>]Next[~]
121 {
122 vars <- _Fold[[set]Variables >>, ~, firstvar, _For Backend Var[?, ?, ?, [set]Condition Type >>]]
123 }{
124 vars <- Val[firstvar]
125 }
126 out <- Fold[_For Backend Subset[?, ?, [set]Condition Type >>], vars, [set]Subsets >>]
127 }{
128 [[set]Subsets >>]First Non-empty Set
129 {
130 firstsub <- [[[set]Subsets >>]Index[~]]For Backend
131 [[set]Subsets >>]Next[~]
132 {
133 out <- _Fold[[set]Subsets >>, ~, firstsub, _For Backend Subset[?, ?, [set]Condition Type >>]]
134 }{
135 out <- Val[firstsub]
136 }
137 }{
138 none <- Yes
139 }
140 }
141 }
142
143 List of Lists[num:out]
144 {
145 out <- Fold[Append[?, ()],(), Range[0,num]]
146 }
147
148 Blueprint Worker Ref
149 {
150 Name
151 Convention
152 Inputs
153 Min Inputs
154 Outputs
155 Min Outputs
156 Is Method?
157 }
158
159 Worker Ref[name,convention,inputs,outputs,ismethod?:out]
160 {
161 out <- [[[[[[[Build[Worker Ref()]]Name <<[name]]Convention <<[convention]]Inputs <<[inputs]]Outputs <<[outputs]]Is Method? <<[ismethod?]]Min Inputs <<[inputs]]Min Outputs <<[outputs]
162 }
163
164 String@Worker Ref[ref:out]
165 {
166 out <- [[[[[[[["Worker Ref["
167 ]Append[[ref]Name >>]
168 ]Append[", "]
169 ]Append[[ref]Convention >>]
170 ]Append[", "]
171 ]Append[String[[ref]Inputs >>]]
172 ]Append[", "]
173 ]Append[String[[ref]Outputs >>]]
174 ]Append["]"]
175 }
176
177 Blueprint Node Ref
178 {
179 Index
180 IO Num
181 }
182
183 Node Ref[index,ionum:out]
184 {
185 out <- [[Build[Node Ref()]]Index <<[index]]IO Num <<[ionum]
186 }
187
188 =@Node Ref[left,right:out]
189 {
190 ,out <- If[[[left]Index >>] = [[right]Index >>]]
191 {
192 out <- [[left]IO Num>>] = [[right]IO Num >>]
193 }
194 }
195
196 Blueprint NWorker Node
197 {
198 Type
199 Data
200 Inputs
201 Min Inputs
202 Input Types
203 Outputs
204 Min Outputs
205 Output Types
206 Wires From
207 Wires To
208 Conditions
209 }
210
211 Wire To@NWorker Node[node,from,output,pre input:out]
212 {
213 existing cons <- [[node]Wires To >>]Index[input] {}
214 { existing cons <- () }
215 input <- [pre input]+[1]
216 out <- [node]Wires To <<[
217 [[node]Wires To >>]Set[input,
218 [existing cons]Append[Node Ref[from,output]]
219 ]
220 ]
221 }
222
223 Wire From@NWorker Node[node,to,input,output:out]
224 {
225 existing cons <- [[node]Wires From >>]Index[output] {}
226 { exist cons <- () }
227 out <- [node]Wires From <<[
228 [[node]Wires From >>]Set[output,
229 [existing cons]Append[Node Ref[to,input]]
230 ]
231 ]
232 }
233
234 _Has Input Types@NWorker Node[node,input num:does,does not]
235 {
236 does <- If[[input num] > [[node]Inputs >>]] {}
237 {
238 ,does not <- [[node]Input Types >>]Index[input num]
239 {
240 count <- [~]Index[1]
241 ,does not <- If[[count] = [[[[node]Wires To >>]Index[input num]]Length]]
242 {
243 does,does not <- [node]_Has Input Types[[input num]+[1]]
244 }
245 }
246 }
247 }
248
249 Has Input Types?@NWorker Node[node:does,does not]
250 {
251 If[[[node]Inputs >>] > [0]]
252 {
253 does,does not <- _Has Input Types[node,0]
254 }{
255 does <- Yes
256 }
257 }
258
259 _Dependency[dlist,ref:out]
260 {
261 [dlist]Find[=[ref, ?]]
262 {
263 out <- dlist
264 }{
265 out <- [dlist]Append[ref]
266 }
267 }
268
269 Dependencies@NWorker Node[node:out]
270 {
271 out <- Fold[Fold[_Dependency[?], ?], (), [node]Wires To >>]
272 }
273
274
275 NWorker Node[type,data,inputs,outputs:out]
276 {
277 out <- [[[[[[[[[[[Build[NWorker Node()]
278 ]Type <<[type]
279 ]Data <<[data]
280 ]Inputs <<[inputs]
281 ]Min Inputs <<[inputs]
282 ]Outputs <<[outputs]
283 ]Min Outputs <<[outputs]
284 ]Wires From <<[List of Lists[outputs]]
285 ]Wires To <<[List of Lists[[inputs]+[1]]]
286 ]Conditions <<[AndSet[]]
287 ]Input Types <<[()]
288 ]Output Types <<[()]
289 }
290
291 Blueprint NWorker
292 {
293 Convention
294 Nodes
295 Inputs
296 Input Types
297 Outputs
298 Output Types
299 Uses
300 NodeResults
301 Free Temps
302 Name
303 Builtin?
304 Library
305 }
306
307 NWorker[convention:out]
308 {
309 out <- [[[[[[[[[Build[NWorker()]]Convention <<[convention]]Nodes <<[()]]Inputs <<[()]]Outputs <<[()]]Input Types <<[()]]Output Types <<[()]]Name <<["Anonymous"]]Builtin? <<[No]]Library << [""]
310 }
311
312 String@NWorker[worker:out]
313 {
314 out <- ["NWorker"]Append[[worker]Name >>]
315 }
316
317 Add Node@NWorker[worker,type,data,inputs,outputs:out,node index]
318 {
319 out <- [worker]Nodes <<[[[worker]Nodes >>]Append[NWorker Node[type,data,inputs,outputs]]]
320 node index <- [[worker]Nodes >>]Length
321 }
322
323 Add Full Node@NWorker[worker,type,data,inputs,min inputs,outputs,min outputs:out,node index]
324 {
325 out <- [worker]Nodes <<[[[worker]Nodes >>]Append[
326 [[[NWorker Node[type,data,inputs,outputs]
327 ]Min Inputs <<[min inputs]
328 ]Min Outputs <<[min outputs]
329 ]Wires To <<[List of Lists[[min inputs]+[1]]]
330 ]]
331 node index <- [[worker]Nodes >>]Length
332 }
333
334 Propagate Type[nodelist,dest,prog,worker,type:out]
335 {
336 node <- [nodelist]Index[[dest]Index >>]
337
338 [[node]Input Types >>]Index[[dest]IO Num >>]
339 {
340 existing type <- [~]Index[0]
341 new count <- [[~]Index[1]]+[1]
342 If[[[existing type]Name >>] = [[type]Name >>]]
343 {
344 If[[[existing type]Variant >>] = [[type]Variant >>]]
345 {
346 If[[[existing type]Params >>] = [[type]Params >>]]
347 {
348 new type <- Val[existing type]
349 }{
350 new variant <- [existing type]Variant >>
351 new params <- ()
352 }
353 }{
354 new variant <- "Boxed"
355 If[[[existing type]Params >>] = [[type]Params >>]]
356 {
357 new params <- [existing type]Params >>
358 }{
359 new params <- ()
360 }
361 }
362 new type <- [[existing type]Set Variant[new variant]]Params <<[new params]
363 }{
364 new type <- Type Instance["Any Type"]
365 }
366 }{
367 new type <- Val[type]
368 new count <- 1
369 }
370 new node <- [node]Input Types <<[
371 [ [node]Input Types >> ]Set[ [dest]IO Num >>, [[()]Append[new type]]Append[new count] ]
372 ]
373 out <- Infer Types Node[[nodelist]Set[[dest]Index >>, new node], new node, [dest]Index >>, prog, worker]
374 }
375
376 Propagate Types[nodelist,dests,output num,prog,worker,source node:out]
377 {
378 out <- Fold[Propagate Type[?, ?, prog, worker, [[source node]Output Types >>]Index[output num]], nodelist, dests]
379 }
380
381 Infer Types Node[nodelist,node,index,prog,worker:out]
382 {
383 If[[[node]Type >>] = ["const"]]
384 {
385 const type <- Blueprint Of[[node]Data >>]
386 [(Int8(),UInt8(),Int16(),UInt16(),Int32(),UInt32(),Int64(),UInt64(),
387 Type Instance(),Worker Literal(),List(),List Leaf(),String(),String Slice(),String Cat())]Find[=[const type, ?]]
388 {
389 outtype <- [("Int8","UInt8","Int16","UInt16","Int32","UInt32","Int64","UInt64",
390 "Blueprint","Worker","List","List","String","String","String")]Index[~]
391 }{
392 outtype <- "Any Type"
393 }
394 nextnode <- [node]Output Types <<[ [()]Append[Type Instance[outtype]] ]
395
396 }{
397 If[[[node]Type >>] = ["input"]]
398 {
399 nextnode <- [node]Output Types <<[ [()]Append[ [[worker]Input Types >>]Index[[node]Data >>] ] ]
400 }{
401 If[[[node]Type >>] = ["output"]]
402 {
403 out <- nodelist
404
405 }{
406 [node]Has Input Types?
407 {
408 If[[[node]Type >>] = ["setfield"]]
409 {
410 nextnode <- [node]Output Types <<[ [()]Append[ [[[node]Input Types >>]Index[0]]Index[0] ] ]
411 }{
412 If[[[node]Type >>] = ["getfield"]]
413 {
414 type <- [[[node]Input Types >>]Index[0]]Index[0]
415 If[[[type]Name >>] = ["Any Type"]]
416 {
417 outtype <- Val[type]
418 }{
419 outtype <- [prog]Find Field[[node]Data >>, type] {}
420 {
421 //TODO: Return errors rather than printing them
422 Print[
423 [[[[["Type "
424 ]Append[[type]Name >>]
425 ]Append[" does not have a field named "]
426 ]Append[[node]Data >>]
427 ]Append[" in worker "]
428 ]Append[worker name]]
429 }
430 }
431 nextnode <- [node]Output Types <<[ [()]Append[outtype] ]
432 }{
433 worker name <- [[node]Data >>]Name >>
434 [prog]Is Method?[worker name]
435 {
436 first arg type <- [[[node]Input Types >>]Index[0]]Index[0]
437 If[[[first arg type]Name >>] = ["Any Type"]]
438 {
439 outtypes <- Fold[Append[?, Type Instance["Any Type"]], (), Range[0, [node]Inputs >>]]
440 }{
441 worker def <- [prog]Find Method[worker name, first arg type] {}
442 {
443 //TODO: Return errors instead of printing them
444 Print[
445 [[[[["Type "
446 ]Append[[first arg type]Name >>]
447 ]Append[" does not support method "]
448 ]Append[worker name]
449 ]Append[" in worker "]
450 ]Append[ [worker]Name >> ]]
451 }
452 }
453 }{
454 worker def <- [prog]Find Worker Def[worker name]
455 }
456 outtypes <- [worker def]Output Types >>
457 nextnode <- [node]Output Types <<[ outtypes ]
458 }
459 }
460 }{
461 out <- nodelist
462 }
463 }
464 }
465 }
466
467 Val[nextnode]
468 {
469 nextlist <- [nodelist]Set[index, nextnode]
470 out <- Fold[Propagate Types[?, ?, ?, prog, worker, nextnode], nodelist, [nextnode]Wires From >>]
471 }
472 }
473
474 Infer Types@NWorker[worker,prog:out]
475 {
476 out <- [worker]Nodes <<[Fold[Infer Types Node[?, ?, ?, prog, worker], [worker]Nodes >>, [worker]Nodes >>]]
477 }
478
479 Add Worker Call@NWorker[worker,tocall:out,node index]
480 {
481 out, node index <- [worker]Add Full Node["call",tocall,[tocall]Inputs >>, [tocall]Min Inputs >>,[tocall]Outputs >>, [tocall]Min Outputs >>]
482 }
483
484 Add Constant@NWorker[worker,constant:out,node index]
485 {
486 out, node index <- [worker]Add Node["const",constant,0,1]
487 }
488
489 Add Input@NWorker[worker,name,number:out,node index]
490 {
491 out,node index <- [worker]Add Typed Input[name,number,Type Instance["Any Type"]]
492 }
493
494 Add Typed Input@NWorker[worker,name,number,type:out,node index]
495 {
496 ,node index <- [worker]Add Node["input",number,0,1]
497 {
498 out <- [[~]Inputs <<[[[~]Inputs >>]Set[number,name]]
499 ]Input Types <<[[[~]Input Types >>]Set[number,type]]
500 }
501 }
502
503 Add Output@NWorker[worker,name,number:out,node index]
504 {
505 out,node index <- [worker]Add Typed Output[name,number,Type Instance["Any Type"]]
506 }
507
508 Add Typed Output@NWorker[worker,name,number,type:out,node index]
509 {
510 ,node index <- [worker]Add Node["output",number,1,0]
511 {
512 out <- [[~]Outputs <<[[[~]Outputs >>]Set[number,name]]
513 ]Output Types <<[[[~]Output Types >>]Set[number,type]]
514 }
515 }
516
517 Add Object Get@NWorker[worker,fieldname:out,node index]
518 {
519 out, node index <- [worker]Add Node["getfield",fieldname,1,1]
520 }
521
522 Add Object Set@NWorker[worker,fieldname:out,node index]
523 {
524 out, node index <- [worker]Add Node["setfield",fieldname,2,1]
525 }
526
527 Add Global Get@NWorker[worker,store,var:out,node index]
528 {
529 out, node index <- [worker]Add Node["getglobal",[[()]Append[store]]Append[var],0,1]
530 }
531
532 Add Global Set@NWorker[worker,store,var:out,node index]
533 {
534 out, node index <- [worker]Add Node["setglobal",[[()]Append[store]]Append[var],1,1]
535 }
536
537 Add Wire@NWorker[worker,from,output,to,input:out]
538 {
539 fromw <- [[[worker]Nodes >>]Index[from]]Wire From[to,input,output]
540 tow <- [[[worker]Nodes >>]Index[to]]Wire To[from,output,input]
541 nodes <- [[[worker]Nodes >>]Set[from, fromw]]Set[to, tow]
542 out <- [worker]Nodes <<[nodes]
543 }
544
545 Uses@NWorker[worker,uses:out]
546 {
547 out <- [worker]Uses <<[uses]
548 }
549
550 _No Dependencies[list,node,index:out]
551 {
552 [[node]Wires To>>]Index[1]
553 {
554 out <- Val[list]
555 }{
556 [[[node]Wires To>>]Index[0]]First
557 {
558 out <- Val[list]
559 }{
560 out <- [list]Append[index]
561 }
562 }
563 }
564
565 No Dependencies@NWorker[worker:out]
566 {
567 out <- Fold[_No Dependencies[?], (), [worker]Nodes >>]
568 }
569
570 _Collect Dests[candidates,wire:out]
571 {
572 out <- [candidates]Set[[wire]Index >>, Yes]
573 }
574
575 Collect Dests@NWorker[worker,candidates,node index:out]
576 {
577 out <- Fold[Fold[_Collect Dests[?], ?], candidates, [[[worker]Nodes >>]Index[node index]]Wires From >>]
578 }
579
580 Check Dependency@NWorker[worker,nodes,wires,wire index:met?]
581 {
582 ref <- [wires]Index[wire index]
583 [nodes]Find[=[[ref]Index >>, ?]]
584 {
585 [wires]Next[wire index]
586 {
587 met? <- [worker]Check Dependency[nodes,wires,~]
588 }{
589 met? <- Yes
590 }
591 }{
592 met? <- No
593 }
594 }
595 _Check Dependencies@NWorker[worker,nodes,inputs,input index:met?]
596 {
597 wires <- [inputs]Index[input index]
598 [wires]First
599 {
600 current met? <- [worker]Check Dependency[nodes, wires, ~]
601 }{
602 current met? <- Yes
603 }
604 If[current met?]
605 {
606 [inputs]Next[input index]
607 {
608 met? <- [worker]_Check Dependencies[nodes,inputs,~]
609 }{
610 met? <- Yes
611 }
612 }{
613 met? <- No
614 }
615 }
616
617 Check Dependencies@NWorker[worker,nodes,candidate:met?]
618 {
619 inputs <- [[[worker]Nodes >>]Index[candidate]]Wires To >>
620 [inputs]First
621 {
622 met? <- [worker]_Check Dependencies[nodes, inputs, ~]
623 }{
624 met? <- Yes
625 }
626 }
627
628 Dependants@NWorker[worker,direct nodes,nodes:out]
629 {
630 candidates <- Keys[Fold[Collect Dests[worker, ?], (), direct nodes]]
631 out <- Filter[candidates, Check Dependencies[worker, nodes, ?]]
632 }
633
634 _Dependency Groups@NWorker[worker,last,all,grouped:out]
635 {
636 current <- [worker]Dependants[last,all]
637 [current]First
638 {
639 out <- [worker]_Dependency Groups[current, [all]Concatenate[current], [grouped]Append[current]]
640 }{
641 out <- grouped
642 }
643 }
644 Dependency Groups@NWorker[worker:out]
645 {
646 no deps <- [worker]No Dependencies
647 out <- [worker]_Dependency Groups[no deps, no deps, [()]Append[no deps]]
648 }
649
650 Const Name[val,node index,worker name:out]
651 {
652 valtype <- Blueprint Of[val]
653 If[[valtype] = [Type Instance()]]
654 {
655 //TODO: Support parametric types
656 datstring <- [val]Name >>
657 typename <- "Blueprint"
658 }{
659 [(Int8(),UInt8(),Int16(),UInt16(),Int32(),UInt32(),Int64(),UInt64())]Find[=[valtype,?]]
660 {
661 size <- [("8","16","32","64")]Index[[~]/[2]]
662 typename <- [("Int8","UInt8","Int16","UInt16","Int32","UInt32","Int64","UInt64")]Index[~]
663 If[[~]Mod[2]]
664 { s <- "UI" }
665 { s <- "I" }
666 datstring <- [[String[val]]Append[s]]Append[size]
667 }{
668 If[[valtype] = [Worker Literal()]]
669 {
670 typename <- "Worker"
671 If[[[[val]Args >>]Length] > [0]]
672 {
673 datstring <- [[["Arg "]Append[String[node index]]]Append[" "]]Append[worker name]
674 }{
675 datstring <- [val]Name >>
676 }
677 }{
678 [(List(),List Leaf())]Find[=[valtype,?]]
679 {
680 typename <- "List"
681 If[[[val]Length] > [0]]
682 {
683 datstring <- [[["Arg "]Append[String[node index]]]Append[" "]]Append[worker name]
684 }{
685 datstring <- "Empty"
686 }
687 }{
688 [(String(),String Cat(),String Slice())]Find[=[valtype, ?]]
689 {
690 typename <- "String"
691 datstring <- val
692 }{
693 typename <- "Unknown"
694 datstring <- String[val]
695 }
696
697 }
698 }
699 }
700 }
701 out <- [[typename]Append["_"]]Append[datstring]
702 }
703
704 Format Input@NWorker[worker,noderef:out]
705 {
706 node <- [[worker]Nodes >>]Index[[noderef]Index >>]
707
708 [("call","getfield","setfield")]Find[=[[node]Type >>, ?]]
709 {
710 maybe addref <- Result Var Name[[noderef]IO Num >>, [noderef]Index >>]
711 }{
712 conditions <- [node]Conditions >>
713
714 If[[[node]Type >>] = ["input"]]
715 {
716 input name <- [[worker]Inputs >>]Index[ [node]Data >> ]
717 [conditions]For Backend
718 {
719 out <- AddRef[Result Var Name[[noderef]IO Num >>, [noderef]Index >>]]
720 }{
721 out <- AddRef[input name]
722 }
723 }{
724 If[[[node]Type >>] = ["const"]]
725 {
726 [conditions]For Backend
727 {
728 out <- AddRef[Result Var Name[[noderef]IO Num >>, [noderef]Index >>]]
729 }{
730 out <- Constant[Const Name[[node]Data >>, [noderef]Index >>, [worker]Name >>]]
731 }
732 }
733 }
734 }
735
736 Val[maybe addref]
737 {
738 If[[Length[[[node]Wires From >>]Index[[noderef]IO Num >>]]] > [1]]
739 {
740 out <- AddRef[maybe addref]
741 }{
742 out <- Val[maybe addref]
743 }
744 }
745 }
746
747 Collect Input@NWorker[worker,nodeinput:out]
748 {
749 inputchoices <- Map[nodeinput, Format Input[worker, ?]]
750
751 [inputchoices]First
752 {
753 first <- [inputchoices]Index[~]
754 [inputchoices]Next[~]
755 {
756 out <- _Fold[inputchoices, ~, first, OrValue[?]]
757 }{
758 out <- Val[first]
759 }
760 }{
761 out <- "Missing"
762 }
763 }
764
765 Collect Inputs@NWorker[worker,node:out]
766 {
767 out <- Map[Tail[[node]Wires To>>, 1], Collect Input[worker, ?]]
768 }
769
770 Collect Input Condition@NWorker[worker,set,noderef:out]
771 {
772 node <- [[worker]Nodes >>]Index[ [noderef]Index >> ]
773 If[[[node]Outputs >>] > [1]]
774 {
775 out <- [set]Add Condition[ Result Var Name[[noderef]IO Num >>, [noderef]Index >>] ]
776 }{
777 out <- [set]Add Condition[[node]Conditions >>]
778 }
779 }
780
781 Collect Condition@NWorker[worker,set,nodeinput:out]
782 {
783 out <- [set]Add Condition[Fold[Collect Input Condition[worker, ?], OrSet[], nodeinput]]
784 }
785
786 Collect Conditions@NWorker[worker,node:out]
787 {
788 out <- Fold[Collect Condition[worker, ?], AndSet[], [node]Wires To>>]
789 }
790
791 Save Result[func,num,node index:out]
792 {
793 out <- [func]Move[Result[num], Result Var Name[num, node index]]
794 }
795
796 Save Maybe Result[func,num,node index:out]
797 {
798 out <- [func]Move[Check Result[num], Result Var Name[num, node index]]
799 }
800
801 Max Used Output[node,cur:out]
802 {
803 If[[cur] < [0]]
804 {
805 out <- cur
806 }{
807 [[[node]Wires From >>]Index[cur]]Index[0]
808 {
809 out <- cur
810 }{
811 out <- Max Used Output[node, [cur]-[1]]
812 }
813 }
814 }
815
816 Compile Call Node[node,program,func,inputs,node index:out]
817 {
818 If[[[node]Type >>] = ["getfield"]]
819 {
820 with call <- [func]Get Field Call[[node]Data >>, [inputs]Index[0]]
821 save outs <- [node]Outputs >>
822 out <- Val[after save]
823 }{
824 If[[[node]Type >>] = ["setfield"]]
825 {
826 with call <- [func]Set Field Call[[node]Data >>, [inputs]Index[0], [inputs]Index[1]]
827 save outs <- [node]Outputs >>
828 out <- Val[after save]
829 }{
830 [program]Method?[[[node]Data >>]Name >>]
831 {
832 with call <- [func]Method Call[[[node]Data >>]Name >>, inputs]
833 }{
834 with call <- [func]Call[[[node]Data >>]Name >>, inputs]
835 }
836 first unused <- [Max Used Output[node, [[node]Outputs >>]-[1]]]+[1]
837 If[[first unused] > [[node]Min Outputs >>]]
838 {
839 save outs <- [node]Min Outputs >>
840 after maybe <- Fold[Save Maybe Result[?, ?, node index], after save, Range[save outs, first unused]]
841 }{
842 save outs <- Val[first unused]
843 after maybe <- Val[after save]
844 }
845 If[[first unused] < [[node]Outputs >>]]
846 {
847 out <- [after maybe]Discard Outputs[first unused]
848 }{
849 out <- Val[after maybe]
850 }
851 }
852 }
853 after save <- Fold[Save Result[?, ?, node index], with call, Range[0, save outs]]
854 }
855
856 Compile Node@NWorker[worker,program,func,nodes,current:out,out worker]
857 {
858 node index <- [nodes]Index[current]
859 node <- [[worker]Nodes >>]Index[node index]
860 conditions <- [node]Conditions >>
861 [("call","getfield","setfield")]Find[=[[node]Type >>, ?]]
862 {
863 inputs <- [worker]Collect Inputs[node]
864 [conditions]For Backend
865 {
866 stream <- [func]Instruction Stream
867 nfunc <- [func]Do If[~, nstream]
868 }{
869 stream <- Val[func]
870 nfunc <- Val[nstream]
871 }
872 nstream <- Compile Call Node[node, program, stream, inputs, node index]
873 }{
874 If[[[node]Type >>] = ["output"]]
875 {
876 inputs <- [worker]Collect Inputs[node]
877 [conditions]For Backend
878 {
879 stream <- [func]Instruction Stream
880 nfunc <- [func]Do If[~, nstream]
881 }{
882 stream <- Val[func]
883 nfunc <- Val[nstream]
884 }
885 nstream <- [stream]Move[[inputs]Index[0], [[worker]Outputs >>]Index[ [node]Data >> ] ]
886 }{
887 If[[[node]Type >>] = ["const"]]
888 {
889 constname <- Const Name[[node]Data >>, node index, [worker]Name >>]
890 withconst <- [func]Register Constant[constname, [node]Data >>]
891 [conditions]For Backend
892 {
893 stream <- [[withconst]Instruction Stream
894 ]Move[Constant[constname], Result Var Name[0, node index]]
895 nfunc <- [withconst]Do If[~, stream]
896 }{
897 nfunc <- Val[withconst]
898 }
899 }{
900 [conditions]For Backend
901 {
902 input name <- [[worker]Inputs >>]Index[ [node]Data >> ]
903 stream <- [[func]Instruction Stream
904 ]Move[input name, Result Var Name[0, node index]]
905 nfunc <- [func]Do If[~, stream]
906 }{
907 nfunc <- Val[func]
908 }
909 }
910
911 }
912 }
913 [nodes]Next[current]
914 {
915 out,out worker <- [worker]Compile Node[program,nfunc,nodes,~]
916 }{
917 out <- Val[nfunc]
918 out worker <- Val[worker]
919 }
920 }
921
922 Save Node Conditions@NWorker[worker,node index:out]
923 {
924 node <- [[worker]Nodes >>]Index[node index]
925 conditions <- [worker]Collect Conditions[node]
926 out <- [worker]Nodes <<[ [[worker]Nodes >>]Set[node index, [node]Conditions <<[conditions]] ]
927
928 }
929
930 Save Group Conditions@NWorker[worker, groups,current:out]
931 {
932 nodes <- [groups]Index[current]
933 nworker <- Fold[Save Node Conditions[?], worker, nodes]
934
935 [groups]Next[current]
936 {
937 out <- [nworker]Save Group Conditions[groups,~]
938 }{
939 out <- Val[nworker]
940 }
941 }
942
943 Compile Group@NWorker[worker,program,func,groups,current:out,out worker]
944 {
945 nodes <- [groups]Index[current]
946 [nodes]First
947 {
948 nfunc,nworker <- [worker]Compile Node[program,func,nodes,~]
949 }{
950 nfunc <- Val[func]
951 nworker <- Val[worker]
952 }
953 [groups]Next[current]
954 {
955 out,out worker <- [nworker]Compile Group[program,nfunc,groups,~]
956 }{
957 out <- Val[nfunc]
958 out worker <- Val[nworker]
959 }
960 }
961
962 Release Var@NWorker[worker,func,name:out]
963 {
964 //__result_index_ionum
965 parts <- [name]Split["_"]
966 index <- Int32[ [parts]Index[3] ]
967 io num <- Int32[ [parts]Index[4] ]
968 node <- [[worker]Nodes >>]Index[index]
969 dests <- [[node]Wires From >>]Index[io num] {}
970
971 If[[[dests]Length] = [1]]
972 {
973 dest index <- [[dests]Index[0]]Index >>
974 dest node <- [[worker]Nodes >>]Index[dest index]
975
976 [[dest node]Conditions >>]For Backend
977 {
978 out <- [func]Do If[AndCond[NotCond[~], name], [[func]Instruction Stream]Release[name]]
979 }{
980 out <- func
981 }
982 }{
983 do if <- If[[[node]Outputs >>] > [1]] {}
984 {
985 do if <- [[node]Conditions >>]Empty? {}
986 {
987 out <- [func]Release[name]
988 }
989 }
990
991 Val[do if]
992 {
993 stream <- [[func]Instruction Stream]Release[name]
994 out <- [func]Do If[name, stream]
995 }
996 }
997 }
998
999 Result Var Name[io num, index:out]
1000 {
1001 out <- [[["__result_"]Append[String[index]]]Append["_"]]Append[String[io num]]
1002 }
1003
1004 Result Var[vars,io num,index:out]
1005 {
1006 out <- [vars]Append[Result Var Name[io num, index]]
1007 }
1008
1009 Node Result Vars[vars,node,index:out]
1010 {
1011 [("call","getfield","setfield")]Find[=[[node]Type >>, ?]]
1012 {
1013 If[[[node]Type >>]=["call"]]
1014 {
1015 save outs <- [Max Used Output[node, [[node]Outputs >>]-[1]]]+[1]
1016 }{
1017 save outs <- [node]Outputs >>
1018 }
1019 out <- Fold[Result Var[?, ?, index], vars, Range[0, save outs]]
1020 }{
1021 out <- vars
1022 }
1023 }
1024
1025 Result Vars@NWorker[worker:out]
1026 {
1027 out <- Fold[Node Result Vars[?], (), [worker]Nodes >>]
1028 }
1029
1030 _No Release[vars,node,index,worker:out]
1031 {
1032 [("const","input")]Find[=[[node]Type >>, ?]]
1033 {
1034 [[node]Conditions >>]For Backend
1035 {
1036 out <- Result Var[vars, 0, index]
1037 }{
1038 out <- vars
1039 }
1040 }{
1041 out <- vars
1042 }
1043 }
1044
1045 No Release Results@NWorker[worker:out]
1046 {
1047 out <- Fold[_No Release[?, ?, ?, worker], (), [worker]Nodes >>]
1048 }
1049
1050 Make Basic Type[type:out]
1051 {
1052 out <- [Type Instance[[type]Name >>]]Params <<[ [type]Params >> ]
1053 }
1054
1055 FInputs[ifunc, input type, index, inputs:out]
1056 {
1057 func <- [ifunc]Set Input Type[Make Basic Type[input type], index]
1058 name <- [inputs]Index[index]
1059 If[[[input type]Variant >>] = ["Naked"]]
1060 {
1061
1062 naked <- [" naked"]Append[name]
1063
1064 out <- [[[func]Allocate Var[naked, input type]
1065 ]Unbox[name, naked]
1066 ]Release[name]
1067 }{
1068 If[[input type]Mutable? >>]
1069 {
1070 name <- [inputs]Index[index]
1071 copied <- [func]Copy[name, name]
1072
1073 }{
1074 copied <- Val[func]
1075 }
1076 If[[[input type]Variant >>] = ["Raw Pointer"]]
1077 {
1078 raw <- [" raw"]Append[name]
1079 If[[[input type]Name >>]=["Array"]]
1080 {
1081
1082 out <- [[copied]Allocate Var[raw, input type]
1083 ]Array Raw Pointer[name, raw]
1084 }{
1085 out <- [[copied]Allocate Var[raw, input type]
1086 ]Get Raw Pointer[name, raw]
1087 }
1088 }{
1089 out <- Val[copied]
1090 }
1091 }
1092 }
1093
1094 FParams[input:out]
1095 {
1096 iname <- [input]Index[0]
1097 type <- [input]Index[1]
1098 If[[[type]Variant >>] = ["Naked"]]
1099 { out <- [" naked"]Append[iname] }
1100 {
1101 If[[[type]Variant >>] = ["Raw Pointer"]]
1102 { out <- [" raw"]Append[iname] }
1103 { out <- Val[iname] }
1104 }
1105 }
1106 _Return Param[outputs, inputs, input types, index:out,none]
1107 {
1108 output <- [outputs]Index[index]
1109 [inputs]Find[=[output, ?]]
1110 {
1111 If[[[input types]Index[~]]Mutable? >>]
1112 {
1113 ,none <- [outputs]Next[index]
1114 {
1115 out,none <- _Return Param[outputs, inputs, input types, ~]
1116 }
1117 } {
1118 out <- index
1119 }
1120 }{
1121 out <- index
1122 }
1123 }
1124
1125 Return Param[outputs, inputs, input types:out,none]
1126 {
1127 ,none <- [outputs]First
1128 { out,none <- _Return Param[outputs, inputs, input types, ~] }
1129
1130 }
1131
1132 Save Foreign Result[func, output, index, output types, inputs, input types:out]
1133 {
1134 type <- [output types]Index[index]
1135 If[[[type]Variant >>] = ["Naked"]]
1136 {
1137 out <- [func]Box[[" naked"]Append[output], output, type]
1138 }{
1139 [inputs]Find[=[output, ?]]
1140 {
1141 If[[[input types]Index[~]]Mutable? >>]
1142 {
1143 out <- [func]Move[output, Output[output]]
1144 }{
1145 out <- func
1146 }
1147 }{
1148 out <- func
1149 }
1150 }
1151 }
1152
1153 Compile Foreign Stub[worker,program,name:out]
1154 {
1155 ifunc <- [[program]Create Function[name, [worker]Inputs >>, [worker]Outputs >>, "rhope"]
1156 ]Output Types <<[Map[[worker]Output Types >>, Make Basic Type[?]]]
1157
1158 rp num <- Return Param[[worker]Outputs >>, [worker]Inputs >>, [worker]Input Types >>]
1159 {
1160 rbase <- [[worker]Outputs >>]Index[rp num]
1161 If[[[[[worker]Output Types >>]Index[rp num]]Variant >>] = ["Naked"]]
1162 {
1163 rparam <- [" naked"]Append[rbase]
1164 rfunc <- [ifunc]Allocate Var[rparam, [[worker]Output Types >>]Index[rp num]]
1165 }{
1166 rparam <- Val[rbase]
1167 rfunc <- Val[ifunc]
1168 }
1169 }{
1170 rparam <- ""
1171 rfunc <- Val[ifunc]
1172 }
1173
1174 Fold[FInputs[?, ?, ?, [worker]Inputs >>], rfunc, [worker]Input Types >>]
1175 { [~]Call Foreign[name, [worker]Convention >>, Map[Zip[[worker]Inputs >>, [worker]Input Types >>], FParams[?]], rparam]
1176 { Fold[Save Foreign Result[?, ?, ?, [worker]Output Types >>, [worker]Inputs >>, [worker]Input Types >>], ~, [worker]Outputs >>]
1177 { out <- [program]Store Function[~] }}}
1178 }
1179
1180 Compile Worker@NWorker[worker,program,name:out]
1181 {
1182 If[[worker]Builtin? >>]
1183 {
1184 out <- program
1185 }{
1186 If[[[worker]Library >>] = [""]]
1187 {
1188 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 >>]
1189
1190
1191
1192 groups <- [worker]Dependency Groups
1193 [groups]First
1194 {
1195 with conds <- [worker]Save Group Conditions[groups, ~]
1196 final func <- [with conds]Compile Group[program,func,groups, ~]
1197 }{
1198 final func <- Val[func]
1199 }
1200 res vars <- [worker]Result Vars
1201 init vars <- Concatenate[res vars, [with conds]No Release Results]
1202
1203 func <- Fold[Set Null[?], Fold[Set Null[?], Fold[Allocate Var[?, ?, "Any Type"], ifunc, init vars], init vars], [worker]Outputs >>]
1204 out <- [program]Store Function[Fold[Release[?], Fold[Release Var[with conds, ?], final func, res vars], [worker]Inputs >>]]
1205 }{
1206 out <- Compile Foreign Stub[worker,[program]Link[[worker]Convention >>, [worker]Library >> ],name]
1207 }
1208 }
1209 }
1210
1211 Blueprint NBlueprint
1212 {
1213 Fields
1214 Methods
1215 }
1216
1217 String@NBlueprint[nbp:out]
1218 {
1219 out <- [[[["NBlueprint: Fields("
1220 ]Append[Join[Map[[nbp]Fields >>, [?]Index[0]], ", "]]
1221 ]Append["), Methods("]
1222 ]Append[Join[Keys[[nbp]Methods >>], ", "]]
1223 ]Append[")"]
1224 }
1225
1226 NBlueprint[:out]
1227 {
1228 out <- [[Build[NBlueprint()]]Fields <<[()]]Methods <<[Dictionary[]]
1229 }
1230
1231 Add Field@NBlueprint[bp,name,type:out]
1232 {
1233 out <- [bp]Fields <<[ [[bp]Fields >>]Append[ [[()]Append[name]]Append[type] ] ]
1234 }
1235
1236 Add Method@NBlueprint[bp,name:out]
1237 {
1238 out <- [bp]Methods <<[ [[bp]Methods >>]Set[name, Yes] ]
1239 }
1240
1241 Understands Method@NBlueprint[bp,name:out]
1242 {
1243 out <- [[bp]Methods >>]Index[name] {}
1244 { out <- No }
1245 }
1246
1247 Get Field Type@NBlueprint[bp,name:out,notfound]
1248 {
1249 ,notfound <- [[bp]Fields >>]Index[name]
1250 { out <- [~]Index[1] }
1251 }
1252
1253 _Compile Blueprint Fields[type,field:out]
1254 {
1255 name <- [field]Index[0]
1256 ftype <- [field]Index[1]
1257 out <- [type]Add Field[name,ftype]
1258 }
1259
1260 _Compile Blueprint Methods[type,junk,name:out]
1261 {
1262 If[[[name]=["Call"]] And [[[type]Name >>] = ["Worker"]]]
1263 {
1264 out <- type
1265 }{
1266 out <- [type]Add Method[name]
1267 }
1268 }
1269
1270 Make Init[func,field:out]
1271 {
1272 name <- [field]Index[0]
1273 variant <- [[field]Index[1]]Variant >>
1274 If[[variant] = ["Boxed"]]
1275 {
1276 out <- [func]Set Field Null["obj", name]
1277 }{
1278 out <- func
1279 }
1280 }
1281
1282 Make Copy[func,field:out]
1283 {
1284 name <- [field]Index[0]
1285 variant <- [[field]Index[1]]Variant >>
1286 If[[variant] = ["Boxed"]]
1287 {
1288 got <- [func]Read Field["obj", name] {}
1289 {
1290 stream <- [[got]Instruction Stream
1291 ]AddRef No Dest[~]
1292 out <- [got]Do If[~, stream]
1293 }
1294 }{
1295 out <- func
1296 }
1297 }
1298
1299 Make Cleanup[func,field:out]
1300 {
1301 name <- [field]Index[0]
1302 variant <- [[field]Index[1]]Variant >>
1303 If[[variant] = ["Boxed"]]
1304 {
1305 got <- [func]Read Field["obj", name] {}
1306 {
1307 stream <- [[got]Instruction Stream
1308 ]Release[~]
1309 out <- [got]Do If[~, stream]
1310 }
1311 }{
1312 out <- func
1313 }
1314 }
1315
1316 Make Special@NBlueprint[bp,backend,func name,bp name,pop worker:out]
1317 {
1318 func <- [[backend]Create Function[func name,("obj"),(),"cdecl"]
1319 ]Set Input Type[Type Instance[bp name], 0]
1320 out <- [backend]Store Function[Fold[pop worker, func, [bp]Fields >>]]
1321 }
1322
1323 Getters Setters[backend,field,type name:out]
1324 {
1325 //TODO: Throw an exception or something if we read a field that is empty
1326 name <- [field]Index[0]
1327 type <- [field]Index[1]
1328 mytype <- Type Instance[type name]
1329 start getter,getref <- [[[[backend]Create Function[ [[[name]Append[" >>"]]Append["@"]]Append[type name], ("obj"), ("out"), "rhope"]
1330 ]Set Input Type[mytype, 0]
1331 ]Set Output Type[[type]Set Variant["Boxed"], 0]
1332 ]Read Field["obj", name]
1333 If[[[type]Variant >>] = ["Boxed"]]
1334 {
1335 getter <- [[start getter]Do AddRef[getref, "out"]]Release["obj"]
1336 }{
1337 getter <- [[start getter]Box[getref, "out", type]]Release["obj"]
1338 }
1339
1340 begin setter <- [[[[[backend]Create Function[ [[[name]Append[" <<"]]Append["@"]]Append[type name], ("obj","newval"), ("out"), "rhope"]
1341 ]Set Input Type[mytype, 0]
1342 ]Set Input Type[[type]Set Variant["Boxed"], 1]
1343 ]Set Output Type[mytype, 0]
1344 ]Copy["obj"]
1345
1346 If[[[type]Variant >>] = ["Boxed"]]
1347 {
1348 ,origref <- [begin setter]Read Field["obj", name]
1349 {
1350 stream <- [[~]Instruction Stream
1351 ]Release[origref]
1352 ,setref <- [[~]Do If[origref, stream]
1353 ]Write Field["obj", name]
1354 {
1355 setter <- [[~]Move["newval", setref]
1356 ]Move["obj", "out"]
1357 }
1358 }
1359 }{
1360 ,setref <- [begin setter]Write Field["obj", name]
1361 {
1362 setter <- [[[~]Unbox["newval", setref]
1363 ]Release["newval"]
1364 ]Move["obj", "out"]
1365 }
1366 }
1367
1368 out <- [[backend]Store Function[getter]]Store Function[setter]
1369
1370 }
1371
1372 Compile Blueprint@NBlueprint[bp,backend,name:out]
1373 {
1374 //Rhope identifiers can't start with spaces, so we can use identifiers that start with spaces for special functions
1375 init name <- [" init "]Append[name]
1376 copy name <- [" copy "]Append[name]
1377 cleanup name <- [" cleanup "]Append[name]
1378 type <- [[[Fold[_Compile Blueprint Methods[?], Fold[_Compile Blueprint Fields[?], [backend]Create Type[name], [bp]Fields >>], [bp]Methods >>]
1379 ]Init <<[init name]
1380 ]Copy <<[copy name]
1381 ]Cleanup <<[cleanup name]
1382
1383 out <- [backend]Register Type[type]
1384 }
1385
1386 Compile Special@NBlueprint[bp,backend,name:out]
1387 {
1388 init name <- [" init "]Append[name]
1389 copy name <- [" copy "]Append[name]
1390 cleanup name <- [" cleanup "]Append[name]
1391 got specials <- [bp]Make Special[
1392 [bp]Make Special[
1393 [bp]Make Special[backend, init name, name, Make Init[?]],
1394 copy name, name, Make Copy[?]],
1395 cleanup name, name, Make Cleanup[?]]
1396 out <- Fold[Getters Setters[?, ?, name], got specials, [bp]Fields >>]
1397 }
1398
1399 Blueprint NProgram
1400 {
1401 Blueprints
1402 Workers
1403 Worker Refs
1404 }
1405
1406 NProgram[:out]
1407 {
1408 out <- [[[Build[NProgram()]]Blueprints <<[Dictionary[]]]Workers <<[Dictionary[]]]Worker Refs <<[Dictionary[]]
1409 }
1410
1411 Bind Worker@NProgram[prog,name,worker:out]
1412 {
1413 after bind <- [prog]Workers << [ [[prog]Workers >>]Set[name, [worker]Name <<[name]] ]
1414 parts <- [name]Split["@"]
1415 [parts]Index[1]
1416 {
1417 orig bp <- [[after bind]Blueprints >>]Index[~] {}
1418 { orig bp <- NBlueprint[] }
1419 out <- [after bind]Blueprints <<[ [[after bind]Blueprints >>]Set[~, [orig bp]Add Method[[parts]Index[0]] ] ]
1420 }{
1421 out <- Val[after bind]
1422 }
1423 }
1424
1425 Bind Blueprint@NProgram[prog,name,blueprint:out]
1426 {
1427 out <- [prog]Blueprints << [ [[prog]Blueprints >>]Set[name, blueprint] ]
1428 }
1429
1430 _Compile Program BP[backend, blueprint, name:out]
1431 {
1432 out <- [blueprint]Compile Blueprint[backend, name]
1433 }
1434
1435 _Compile Program BP Special[backend, blueprint, name:out]
1436 {
1437 out <- [blueprint]Compile Special[backend, name]
1438 }
1439
1440 _Compile Program[backend, worker, name:out]
1441 {
1442 out <- [worker]Compile Worker[backend, name]
1443 }
1444
1445 Compile Program@NProgram[prog, backend:out]
1446 {
1447 backend with bps <- Generate Boolean Methods[Generate Number Methods[Fold[_Compile Program BP Special[?], Fold[_Compile Program BP[?], backend, [prog]Blueprints >>], [prog]Blueprints >>]]]
1448 workers with infer <- Map[[prog]Workers >>, Infer Types[?, prog]]
1449 out <- Fold[_Compile Program[?], backend with bps, workers with infer]
1450 }
1451
1452 Register Method@NProgram[prog, name, convention, inputs, outputs: out]
1453 {
1454 [[prog]Worker Refs >>]Index[name]
1455 {
1456 ref <- [[[[~]Inputs <<[ Max[[~]Inputs >>, inputs] ]
1457 ]Min Inputs <<[ Min[[~]Min Inputs >>, inputs] ]
1458 ]Outputs <<[ Max[[~]Outputs >>, outputs] ]
1459 ]Min Outputs <<[ Min[[~]Min Outputs >>, outputs] ]
1460 }{
1461 ref <- Worker Ref[name, convention, inputs, outputs, Yes]
1462 }
1463 out <- [prog]Worker Refs <<[ [[prog]Worker Refs >>]Set[name, ref]]
1464 }
1465
1466 Register Worker@NProgram[prog, name, convention, inputs, outputs: out]
1467 {
1468 [[prog]Worker Refs >>]Index[name]
1469 {
1470 ref <- [[[[~]Inputs <<[ Max[[~]Inputs >>, inputs] ]
1471 ]Min Inputs <<[ Min[[~]Min Inputs >>, inputs] ]
1472 ]Outputs <<[ Max[[~]Outputs >>, outputs] ]
1473 ]Min Outputs <<[ Min[[~]Min Outputs >>, outputs] ]
1474 }{
1475 ref <- Worker Ref[name, convention, inputs, outputs, No]
1476 }
1477 after reg <- [prog]Worker Refs <<[
1478 [ [prog]Worker Refs >> ]Set[name, ref]
1479 ]
1480
1481 parts <- [name]Split["@"]
1482 [parts]Index[1]
1483 {
1484 out <- [after reg]Register Method@NProgram[[parts]Index[0], convention, inputs, outputs]
1485 }{
1486 out <- Val[after reg]
1487 }
1488 }
1489
1490 Register Builtins@NProgram[prog:out]
1491 {
1492 registered <- [[[[[[[[prog]Register Worker["Print", "rhope", 1, 1]
1493 ]Register Worker["If@Boolean", "rhope", 1, 2]
1494 ]Register Worker["Build", "rhope", 1, 1]
1495 ]Register Worker["Blueprint Of", "rhope", 1, 1]
1496 ]Register Worker["Call@Worker", "rhope", 1, 2] //We're using 2 because we need to assume that the outputs are conditional
1497 ]Register Worker["ID", "rhope", 1, 1]
1498 ]Register Worker["Blueprint From ID", "rhope", 1, 2]
1499 ]Register Number Methods
1500
1501 out <- [[[[[[[registered]Bind Worker["If@Boolean",
1502 [[[[[NWorker["rhope"]
1503 ]Inputs <<[("condition")]
1504 ]Input Types <<[ [()]Append[Type Instance["Boolean"]] ]
1505 ]Outputs <<[("isyes","isno")]
1506 ]Output Types <<[ [[()]Append[Type Instance["Boolean"]]]Append[Type Instance["Boolean"]] ]
1507 ]Builtin? <<[Yes]]
1508 ]Bind Worker["Print",
1509 [[[[[NWorker["rhope"]
1510 ]Inputs <<[("value")]
1511 ]Input Types <<[ [()]Append[Type Instance["Any Type"]] ]
1512 ]Outputs <<[("out")]
1513 ]Output Types <<[ [()]Append[Type Instance["Int32"]] ]
1514 ]Builtin? <<[Yes]]
1515 ]Bind Worker["Build",
1516 [[[[[NWorker["rhope"]
1517 ]Inputs <<[("type")]
1518 ]Input Types <<[ [()]Append[Type Instance["Blueprint"]] ]
1519 ]Outputs <<[("out")]
1520 ]Output Types <<[ [()]Append[Type Instance["Any Type"]] ]
1521 ]Builtin? <<[Yes]]
1522 ]Bind Worker["Blueprint Of",
1523 [[[[[NWorker["rhope"]
1524 ]Inputs <<[("object")]
1525 ]Input Types <<[ [()]Append[Type Instance["Any Type"]]]
1526 ]Outputs <<[("type")]
1527 ]Output Types <<[ [()]Append[Type Instance["Blueprint"]]]
1528 ]Builtin? <<[Yes]]
1529 ]Bind Worker["Call@Worker",
1530 [[[[[NWorker["rhope"]
1531 ]Inputs <<[("worker")]
1532 ]Input Types <<[ [()]Append[Type Instance["Worker"]] ]
1533 ]Outputs <<[("ret1","ret2")]
1534 ]Output Types <<[ [[()]Append[Type Instance["Any Type"]]]Append[Type Instance["Any Type"]] ]
1535 ]Builtin? << [Yes]]
1536 ]Bind Worker["ID",
1537 [[[[[NWorker["rhope"]
1538 ]Inputs <<[("bp")]
1539 ]Input Types <<[ [()]Append[Type Instance["Blueprint"]]]
1540 ]Outputs <<[("id")]
1541 ]Output Types <<[ [()]Append[Type Instance["UInt32"]]]
1542 ]Builtin? << [Yes]]
1543 ]Bind Worker["Blueprint From ID",
1544 [[[[[NWorker["rhope"]
1545 ]Inputs <<[("id")]
1546 ]Input Types <<[ [()]Append[Type Instance["UInt32"]]]
1547 ]Outputs <<[("bp","none")]
1548 ]Output Types <<[ [[()]Append[Type Instance["Blueprint"]]]Append[Type Instance["Any Type"]]]
1549 ]Builtin? << [Yes]]
1550 }
1551
1552 Find Worker@NProgram[prog, name:out,notfound]
1553 {
1554 out,notfound <- [[prog]Worker Refs >>]Index[name]
1555 }
1556
1557 Find Worker Def@NProgram[prog,name:out,notfound]
1558 {
1559 out,notfound <- [[prog]Workers >>]Index[name]
1560 }
1561
1562 Find Method@NProgram[prog, name, type:out,notfound]
1563 {
1564 bp,notfound <- [[prog]Blueprints >>]Index[[type]Name >>]
1565 ,notfound <- If[[bp]Understands Method[name]]
1566 {
1567 out <- [[prog]Workers >>]Index[[[name]Append["@"]]Append[[type]Name >>]]
1568 }
1569 }
1570
1571 Find Field@NProgram[prog, name, type:fieldtype,notfound]
1572 {
1573 bp,notfound <- [[prog]Blueprints >>]Index[[type]Name >>]
1574 fieldtype,notfound <- [bp]Get Field Type[name]
1575 }
1576
1577 Implicit Conversion@NProgram[prog, fromtype, totype:func,notfound]
1578 {
1579 notfound <- No
1580 }
1581
1582 Is Method?@NProgram[prog,name:is,is not]
1583 {
1584 ,is not <- [[prog]Worker Refs>>]Index[name]
1585 {
1586 is,is not <- If[[~]Is Method? >>]
1587 }
1588 }
1589