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