Mercurial > repos > rhope
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 |