comparison nworker.rhope @ 184:c6ba9fe45910

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