comparison parser_old_c.rhope @ 100:f51c4c17457c

Broken port of parser to compiler
author Mike Pavone <pavone@retrodev.com>
date Mon, 09 Aug 2010 02:03:57 -0400
parents
children f4fc0a98088a
comparison
equal deleted inserted replaced
99:e09c2d1d6d5b 100:f51c4c17457c
1 Import nworker_c.rhope
2
3 //Rather than rewrite the code that uses this
4 //let's implement Get DString using Partition
5 Get DString[str,delims:after,before,delim,not found]
6 {
7 before,delim,after,not found <- [str]Partition[delims] {} {} {}
8 {
9 before <- str
10 }
11 }
12
13
14 Blueprint Parser
15 {
16 Arg Begin
17 Arg End
18 Line Comment
19 Comment Begin
20 Comment End
21 Assign
22 Block Begin
23 Block End
24 Blueprint Type Delim
25 Empty Block
26 Binary Operator
27 String Begin
28 String End
29 String Escape
30 List Begin
31 List End
32 List Delim
33 In Out Delim
34 Do Worker
35 Index Begin
36 Index End
37 Previous
38 Block Val
39 Set Field
40 Get Field
41 Import
42 Blueprint
43 Global Separator
44 Uses
45 Hex Escape
46 Escape Map
47 Foreign
48 }
49
50 Parser[:out]
51 {
52 out <- [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[Build[Parser()]
53 ]Arg Begin << ["["]
54 ]Arg End <<["]"]
55 ]Line Comment <<["//"]
56 ]Comment Begin <<["/*"]
57 ]Comment End <<["*/"]
58 ]Assign <<["<-"]
59 ]Block Begin <<["{"]
60 ]Block End <<["}"]
61 ]Blueprint Type Delim <<[":"]
62 ]Empty Block <<[";"]
63 ]Binary Operator <<["`"]
64 ]String Begin <<["\""]
65 ]String End <<["\""]
66 ]String Escape <<["\\"]
67 ]List Begin <<["("]
68 ]List End <<[")"]
69 ]List Delim <<[","]
70 ]In Out Delim <<[":"]
71 ]Do Worker <<["$"]
72 ]Index Begin <<["("]
73 ]Index End <<[")"]
74 ]Previous <<["@"]
75 ]Set Field <<["<<"]
76 ]Get Field <<[">>"]
77 ]Import <<["Import"]
78 ]Blueprint <<["Blueprint"]
79 ]Global Separator <<["::"]
80 ]Hex Escape <<["x"]
81 ]Uses <<["uses"]
82 ]Escape Map <<[[[[Dictionary[]]Set["n","\n"]]Set["r","\r"]]Set["t","\t"]]
83 ]Foreign <<["Foreign"]
84 }
85
86 Blueprint Output Reference
87 {
88 Index
89 Output Number
90 }
91
92 Output Reference[index,num:out]
93 {
94 out <- [[Build[Output Reference()]]Index <<[index]]Output Number <<[num]
95 }
96
97 Add Pipe Reference[refs,name,reference:out]
98 {
99 reflist <- [refs]Index[name] {}
100 {
101 reflist <- ()
102 }
103 out <- [refs]Set[name, [reflist]Append[reference]]
104 }
105
106 Assignment Save Reference[refs,assignment,output num,parse worker,index:out]
107 {
108 [[parse worker]Outputs >>]Find[=[assignment,?]]
109 {
110 out <- refs
111 }{
112 out <- Add Pipe Reference[refs, assignment, Output Reference[index, output num]]
113 }
114 }
115
116 Blueprint Foreign Lib
117 {
118 Language
119 Name
120 }
121
122 New Foreign Lib[language, library:out]
123 {
124 out <- [[Build[Foreign Lib()]
125 ]Language <<[language]
126 ]Name <<[library]
127 }
128
129 Blueprint Parse Program
130 {
131 Workers
132 Imports
133 Blueprints
134 Errors
135 }
136
137 Parse Program[:out]
138 {
139 out <- [[[[Build[Parse Program()]
140 ]Workers <<[Dictionary[]]
141 ]Imports <<[[Dictionary[]]Set["kernel.rhope", Yes]]
142 ]Blueprints <<[Dictionary[]]
143 ]Errors <<[()]
144 }
145
146 Blueprint Blueprint Definition
147 {
148 Name
149 Fields
150 }
151
152 New Blueprint Definition[name,fields:out]
153 {
154 out <- [[Build[Blueprint Definition()]]Name << [name]]Fields <<[fields]
155 }
156
157 Blueprint Parse Worker
158 {
159 Name
160 Inputs
161 Outputs
162 Line Number
163 Trees
164 Uses Stores
165 Input Types
166 Output Types
167 }
168
169 Parse Worker[name,inputs,outputs,intypes,outtypes,line:out]
170 {
171 out <- [[[[[[[[Build[Parse Worker()]]Name <<[name]]Inputs <<[inputs]]Outputs <<[outputs]]Line Number <<[line]]Trees <<[()]]Uses Stores <<[()]]Input Types <<[intypes]]Output Types <<[outtypes]
172 }
173
174 Blueprint Worker Node
175 {
176 Name
177 Params
178 Assignments
179 Blocks
180 Index
181 }
182
183 Worker Node[name,params:out]
184 {
185 out <- [[[[Build[Worker Node()]]Name <<[name]]Params <<[params]]Assignments <<[()]]Blocks <<[()]
186 }
187
188 Add List Helper[inlist,worker,program,key,parse worker,refs:out list,out worker,out refs]
189 {
190 ,nextworker,nextrefs <- [[inlist]Index[key]]Add to Worker[worker, program, parse worker, refs]
191 { nextlist <- [inlist]Set[key, ~] }
192 [inlist]Next[key]
193 {
194 out list,out worker,out refs <- Add List Helper[nextlist, nextworker, program, ~, parse worker, nextrefs]
195 }{
196 out list <- Val[nextlist]
197 out worker <- Val[nextworker]
198 out refs <- Val[nextrefs]
199 }
200 }
201
202 Add List to Worker[list,worker,program,parse worker,refs:out list,out worker,out refs]
203 {
204 [list]First
205 {
206 out list,out worker,out refs <- Add List Helper[list, worker, program, ~, parse worker, refs]
207 }{
208 out list <- list
209 out worker <- worker
210 out refs <- refs
211 }
212 }
213
214 _Add Blocks to Worker[blocks,worker,program,parse worker,key,refs:out blocks,out worker,out refs]
215 {
216 block, next worker, nextrefs <- Add List to Worker[[blocks]Index[key], worker, program, parse worker, refs]
217 next blocks <- [blocks]Set[key, block]
218 [blocks]Next[key]
219 {
220 out blocks,out worker,out refs <- _Add Blocks to Worker[next blocks, next worker, program, parse worker, ~, nextrefs]
221 }{
222 out blocks <- Val[next blocks]
223 out worker <- Val[next worker]
224 out refs <- Val[nextrefs]
225 }
226 }
227
228 Add Blocks to Worker[blocks,worker,program,parse worker,refs:out blocks,out worker,out refs]
229 {
230 [blocks]First
231 {
232 out blocks, out worker, out refs <- _Add Blocks to Worker[blocks, worker, program, parse worker, ~, refs]
233 }{
234 out blocks <- blocks
235 out worker <- worker
236 out refs <- refs
237 }
238 }
239
240 Add to Worker@Worker Node[node,worker,program,parse worker,refs:out node,out worker,out refs]
241 {
242 [program]Find Worker[[node]Name >>]
243 {
244 after worker <- [worker]Add Worker Call[~] {}
245 {
246 //Print[[[[node]Name >>]Append[" has index "]]Append[~]]
247 assignment refs <- Fold[Assignment Save Reference[?, ?, ?, parse worker, ~], refs, [node]Assignments >>]
248 [node]Index <<[~]
249 {
250 params list, params worker, params refs <- Add List to Worker[[~]Params >>, after worker, program, parse worker, assignment refs]
251 block list, out worker, out refs <- Add Blocks to Worker[[~]Blocks >>, params worker, program, parse worker, params refs]
252 out node <- [[~]Params <<[params list]]Blocks <<[block list]
253 }
254 }
255 }{
256 Print[["Error: Could not find a worker named "]Append[[node]Name >>]]
257 }
258 }
259
260 Check Question Mark[params, index:has mark,no mark]
261 {
262 param,no mark <-[params]Index[index]
263 {
264 If[[Blueprint Of[param]]=[Named Pipe Node()]]
265 {
266 has mark <-If[[[param]Name >>] = ["?"]] {}
267 {
268 has mark,no mark <- Check Question Mark[params, [index]+[1]]
269 }
270 }{
271 has mark,no mark <- Check Question Mark[params, [index]+[1]]
272 }
273 }
274 }
275
276 Collect Literal Inputs[literal, params, index, complex inputs:literal out,complex out]
277 {
278 param <- [params]Index[index]
279 {
280 If[[Blueprint Of[param]]=[Literal Node()]]
281 {
282 next literal <- [literal]Set Input[index, [param]Value >>]
283 next complex <- Val[complex inputs]
284 }{
285 ,doset <- If[[Blueprint Of[param]]=[Named Pipe Node()]]
286 {
287 ,doset <- If[[[param]Name >>] = ["?"]]
288 {
289 //Question mark indicates unpopulated input
290 next complex <- Val[complex inputs]
291 next literal <- Val[literal]
292 }
293 }
294
295 Val[doset]
296 {
297 next complex <- [complex inputs]Set[index, param]
298 next literal <- Val[literal]
299 }
300 }
301 literal out, complex out <- Collect Literal Inputs[next literal, params, [index]+[1], next complex]
302 }{
303 literal out <- literal
304 complex out <- complex inputs
305 }
306 }
307
308 Do Set Input[literal,param,index:out]
309 {
310 out <- Worker Node["Set Input", [[[()]Append[literal]]Append[Literal Node[index]]]Append[param]]
311 }
312
313 Check Worker Literals@Worker Node[node,program:out]
314 {
315 new params <- Map[[node]Params >>, Check Worker Literals[?, program]]
316 Check Question Mark[new params, 0]
317 {
318 base literal, complex inputs <- Collect Literal Inputs[Worker Literal[[node]Name >>], new params, 0, ()]
319 new node <- Fold[Do Set Input[?], Literal Node[base literal], complex inputs]
320 }{
321 new node <- [node]Params <<[new params]
322 }
323 out <- [new node]Blocks <<[ Map[[node]Blocks >>, Map[?, Check Worker Literals[?, program]]] ]
324 }
325
326 Add Multi Wire[worker,ref,junk,end index,input num:out]
327 {
328 out <- [worker]Add Wire[[ref]Index >>, [ref]Output Number >>, end index, input num]
329 }
330
331 Add Param Wire[worker,param,input num,end index,blocks,parse worker,assignments:out]
332 {
333 param worker, start index, output num <- [param]Add Wires[worker, blocks, parse worker, assignments] {}
334 {
335 out <- [param worker]Add Wire[start index, output num, end index, input num]
336 }{}{
337 out <- Fold[Add Multi Wire[?, ?, ?, end index, input num], param worker, ~]
338 }
339 }
340
341 _Add Block Wire[worker,node,junk,blocks,parse worker,assignments:out]
342 {
343 out <- [node]Add Wires[worker, blocks, parse worker, assignments]
344 }
345
346 Add Block Wire[worker,block nodes,output num,parent index,existing blocks,parse worker,assignments:out]
347 {
348 blocks <- [existing blocks]Append[Output Reference[parent index, output num]]
349 out <- Fold[_Add Block Wire[?, ?, ?, blocks, parse worker, assignments], worker, block nodes]
350 }
351
352 Assignments Add Wires[worker,assignment,output num,parse worker,start index:out worker]
353 {
354 [[parse worker]Outputs >>]Find[=[assignment,?]]
355 {
356 ,output index <- [worker]Add Typed Output[assignment, ~, [[parse worker]Output Types >>]Index[~]]
357 {
358 out worker <- [~]Add Wire[start index, output num, output index, 0]
359 }
360 }{
361 //Ugly hack alert!
362 If[[assignment]Contains["::"]]
363 {
364 parts <- [assignment]Split["::"]
365 ,global index <- [worker]Add Global Set[[parts]Index[0], [parts]Index[1]]
366 {
367 out worker <- [~]Add Wire[start index, output num, global index, 0]
368 }
369 }{
370 out worker <- worker
371 }
372 }
373 }
374
375 Has Block@Worker Node[junk:out,unused]
376 {
377 out <- Yes
378 }
379
380 _Has Block Params[param list,key:out]
381 {
382 param <- [param list]Index[key]
383 out <- [param]Has Block {}
384 {
385 [param list]Next[key]
386 {
387 out <- _Has Block Params[param list, ~]
388 }{
389 out <- No
390 }
391 }
392
393 }
394
395 Has Block Params[param list:out]
396 {
397 [param list]First
398 {
399 out <- _Has Block Params[param list, ~]
400 }{
401 out <- No
402 }
403 }
404
405 Add Wires@Worker Node[node,worker,blocks,parse worker,assignments:outworker,index,num,unused]
406 {
407 outworker,index,num <- Add Wires Worker or Field[node, worker, blocks, parse worker, assignments]
408 }
409
410 Add Wires Worker or Field[node,worker,blocks,parse worker,assignments:outworker,index,num,unused]
411 {
412 Fold[Assignments Add Wires[?, ?, ?, parse worker, [node]Index >>], worker, [node]Assignments >>]
413 {
414 Fold[Add Block Wire[?, ?, ?, [node]Index >>, blocks, parse worker, assignments], ~, [node]Blocks >>]
415 {
416 params worker <- Fold[Add Param Wire[?, ?, ?, [node]Index >>, blocks, parse worker, assignments], ~, [node]Params >>]
417 {
418 index <- [node]Index >>
419 num <- 0
420 }
421 }
422 }
423 If[Has Block Params[[node]Params >>]]
424 {
425 outworker <- Val[params worker]
426 }{
427 [blocks]Peek
428 {
429 outworker <- [params worker]Add Wire[[~]Index >>, [~]Output Number >>, [node]Index >>, [0]-[1]]
430 }{
431 outworker <- Val[params worker]
432 }
433 }
434 }
435
436 Blueprint Field Node
437 {
438 Name
439 Params
440 Assignments
441 Blocks
442 Index
443 Set?
444 }
445
446 Has Block@Field Node[junk:has block,unused]
447 {
448 has block <- Yes
449 }
450
451 Field Node[name,params,set:out]
452 {
453 out <- [[[[[Build[Field Node()]]Name <<[name]]Assignments <<[()]]Blocks <<[()]]Set? <<[set]]Params <<[params]
454 }
455
456 Add to Worker@Field Node[node,worker,program,parse worker,refs:out node,out worker,out refs]
457 {
458 If[[node]Set? >>]
459 {
460 after worker,index <- [worker]Add Object Set[[node]Name >>]
461 }{
462 after worker,index <- [worker]Add Object Get[[node]Name >>]
463 }
464 Val[index]
465 {
466 assignment refs <- Fold[Assignment Save Reference[?, ?, ?, parse worker, ~], refs, [node]Assignments >>]
467 [node]Index <<[~]
468 {
469 params list, params worker, params refs <- Add List to Worker[[~]Params >>, after worker, program, parse worker, assignment refs]
470 block list, out worker, out refs <- Add Blocks to Worker[[~]Blocks >>, params worker, program, parse worker, params refs]
471 out node <- [[~]Params <<[params list]]Blocks <<[block list]
472 }
473 }
474 }
475
476 Add Wires@Field Node[node,worker,blocks,parse worker,assignments:outworker,index,num]
477 {
478 outworker,index,num <- Add Wires Worker or Field[node, worker, blocks, parse worker, assignments]
479 }
480
481 Check Worker Literals@Field Node[node,program:out]
482 {
483 new params <- Map[[node]Params >>, Check Worker Literals[?, program]]
484 out <- [[node]Blocks <<[ Map[[node]Blocks >>, Map[?, Check Worker Literals[?, program]]] ]
485 ]Params <<[new params]
486 }
487
488 Blueprint Named Pipe Node
489 {
490 Name
491 Assignments
492 Blocks
493 Index
494 }
495
496 Has Block@Named Pipe Node[node:has block,no block]
497 {
498 If[[[node]Index >>] < [0]]
499 {
500 //~ should really be a parser parameter
501 If[[[node]Name >>] = ["~"]]
502 {
503 has block <- Yes
504 }{
505 no block <- No
506 }
507 }{
508 has block <- Yes
509 }
510 }
511
512 Named Pipe Node[name:out]
513 {
514 out <- [[[Build[Named Pipe Node()]]Name <<[name]]Assignments <<[()]]Blocks <<[()]
515 }
516
517 Add to Worker@Named Pipe Node[node,worker,program,parse worker,refs:out node,out worker,out refs]
518 {
519 [[parse worker]Inputs >>]Find[=[[node]Name >>, ?]]
520 {
521 after add <- [worker]Add Typed Input[[node]Name >>, ~, [[parse worker]Input Types>>]Index[~]] {}
522 {
523 assign refs <- Fold[Assignment Save Reference[?, ?, ?, parse worker, ~], refs, [node]Assignments >>]
524 index node <- [node]Index <<[~]
525 }
526 }{
527 after add <- worker
528 index node <- [node]Index <<[[0]-[1]]
529 //TODO: Handle assignments from a named pipe that isn't an input
530 assign refs <- refs
531 }
532 block list, out worker, out refs <- Add Blocks to Worker[[node]Blocks >>, after add, program, parse worker, assign refs]
533 out node <- [index node]Blocks <<[block list]
534 }
535
536 Add Wires@Named Pipe Node[node,worker,blocks,parse worker,assignments:outworker,index,num,reflist]
537 {
538 reflist <- [assignments]Index[[node]Name >>]
539 {
540 //TODO: Fix support for a named pipe with a block
541 outworker <- worker
542 }{
543 If[[[node]Name >>] = ["~"]]
544 {
545 wires worker <- worker
546 [blocks]Peek
547 {
548 my index <- [~]Index >>
549 num <- [~]Output Number >>
550 }{
551 //TODO: Propagate an error rather than printing it out
552 Print["Error, block reference symbol located outside of a block"]
553 }
554 }{
555 If[[[node]Index >>] < [0]]
556 {
557 Print[[[["Error, reference to named pipe "]Append[[node]Name >>]]Append[" that was never assigned to in worker "]]Append[[parse worker]Name >>]]
558 }{
559 my index <- [node]Index >>
560 num <- 0
561 assignments worker <- Fold[Assignments Add Wires[?, ?, ?, parse worker, [node]Index >>], worker, [node]Assignments >>]
562 [blocks]Peek
563 {
564 wires worker <- [assignments worker]Add Wire[[~]Index >>, [~]Output Number >>, [node]Index >>, [0]-[1]]
565 }{
566 wires worker <- Val[assignments worker]
567 }
568 }
569 }
570 }
571 index <- Val[my index]
572
573 outworker <- Fold[Add Block Wire[?, ?, ?, my index, blocks, parse worker, assignments], wires worker, [node]Blocks >>]
574 }
575
576 Check Worker Literals@Named Pipe Node[node,program:out]
577 {
578 out <- [node]Blocks <<[ Map[[node]Blocks >>, Map[?, Check Worker Literals[?, program]]] ]
579 }
580
581 Blueprint Global Node
582 {
583 Store
584 Name
585 Assignments
586 Blocks
587 Index
588 }
589
590 Global Node[store,name:out]
591 {
592 out <- [[[[Build[Global Node()]]Store <<[store]]Name <<[name]]Assignments <<[()]]Blocks <<[()]
593 }
594
595 Add to Worker@Global Node[node,worker,unused,parse worker,refs:out node,out worker,outrefs]
596 {
597 out worker <- [worker]Add Global Get[[node]Store >>, [node]Name >>] {}
598 {
599 outrefs <- Fold[Assignment Save Reference[?, ?, ?, parse worker, ~], refs, [node]Assignments >>]
600 out node <- [node]Index <<[~]
601 }
602 outrefs <- refs
603 }
604
605 Add Wires@Global Node[node,worker,blocks,parse worker,assignments:outworker,index,num,unused]
606 {
607 outworker,index,num <- Add Wires Literal or Global[node, worker, blocks, parse worker, assignments]
608 }
609
610 Has Block@Global Node[junk:out,unused]
611 {
612 out <- Yes
613 }
614
615 Check Worker Literals@Global Node[node,program:out]
616 {
617 out <- [node]Blocks <<[ Map[[node]Blocks >>, Map[?, Check Worker Literals[?, program]]] ]
618 }
619
620 Blueprint Literal Node
621 {
622 Value
623 Assignments
624 Blocks
625 Index
626 }
627
628 Has Block@Literal Node[junk:out,unused]
629 {
630 out <- Yes
631 }
632
633 Literal Node[value:out]
634 {
635 out <- [[[Build[Literal Node()]]Value <<[value]]Assignments <<[()]]Blocks <<[()]
636 }
637
638 Add to Worker@Literal Node[node,worker,unused,parse worker,refs:out node,out worker,out refs]
639 {
640 out worker <- [worker]Add Constant[[node]Value >>] {}
641 {
642 out refs <- Fold[Assignment Save Reference[?, ?, ?, parse worker, ~], refs, [node]Assignments >>]
643 out node <- [node]Index <<[~]
644 }
645 }
646
647 Add Wires@Literal Node[node,worker,blocks,parse worker,assignments:outworker,index,num,unused]
648 {
649 outworker,index,num <- Add Wires Literal or Global[node, worker, blocks, parse worker, assignments]
650 }
651
652 Check Worker Literals@Literal Node[node,program:out]
653 {
654 out <- [node]Blocks <<[ Map[[node]Blocks >>, Map[?, Check Worker Literals[?, program]]] ]
655 }
656
657 Add Wires Literal or Global[node,worker,blocks,parse worker,junk:outworker,index,num,unused]
658 {
659 assignments worker <- Fold[Assignments Add Wires[?, ?, ?, parse worker, [node]Index >>], worker, [node]Assignments >>]
660 [blocks]Peek
661 {
662 outworker <- [assignments worker]Add Wire[[~]Index >>, [~]Output Number>>, [node]Index >>, [0]-[1]]
663 }{
664 outworker <- Val[assignments worker]
665 }
666 index <- [node]Index >>
667 num <- 0
668 }
669
670 Blueprint Block Node
671 {
672 Number
673 }
674
675 Blueprint Parse Error
676 {
677 Type
678 Text
679 Line Number
680 }
681
682 Parse Error[type,text,number:out]
683 {
684 out <- [[[Build[Parse Error()]]Type <<[type]]Text <<[text]]Line Number <<[number]
685 }
686
687 Not Empty[string:out]
688 {
689 If[[[string]Length] > [0]]
690 {
691 out <- Yes
692 }{
693 out <- No
694 }
695 }
696
697 Blueprint Blueprint Field
698 {
699 Name
700 Type
701 }
702
703 New Blueprint Field[name,type:out]
704 {
705 out <- [[Build[Blueprint Field()]]Name <<[name]]Type <<[type]
706 }
707
708 Process Blueprint Field[list,field,params:out]
709 {
710 ,name <- [field]Get DString[[params]List Begin >>]
711 {
712 type info <- Parse List[~,params,()]
713 type <- [type info]Index[0]
714 {
715 If[[Blueprint Of[~]] = [Named Pipe Node()]]
716 {
717 before variant <- Type Instance[[type]Name >>]
718 }{
719 before variant <- [type]Params <<[ Map[[type]Params >>, Remove Named Pipe Node[?]] ]
720 }
721 variant <- [type info]Index[1]
722 {
723 ,warn <- If[[Blueprint Of[~]] = [Named Pipe Node()]]
724 {
725 fieldtype,warn <- [before variant]Set Variant[[variant]Name >>]
726 }
727 Val[warn]
728 {
729 Print[[[["Warning: Invalid variant for type "]Append[[before variant]Name >>]]Append[" on field "]]Append[name]]
730 fieldtype <- Val[before variant]
731 }
732 }{
733 fieldtype <- Val[before variant]
734 }
735 }{
736 fieldtype <- Type Instance["Any Type"]
737 }
738 out <- [list]Append[New Blueprint Field[name, fieldtype]]
739 } {} {} {
740 out <- [list]Append[New Blueprint Field[name, Type Instance["Any Type"]]]
741 }
742 }
743
744 Block Comment[string,begin comment,end comment,block count:out]
745 {
746 If[[block count] > [0]]
747 {
748 after, before <- [string]Get DString[[[()]Append[begin comment]]Append[end comment]] {} {}
749 {
750 If[[~] = [begin comment]]
751 {
752 out <- Block Comment[after, begin comment, end comment, [block count]+[1]]
753 }{
754 out <- Block Comment[after, begin comment, end comment, [block count]-[1]]
755 }
756 }{
757 //No match
758 out <- ""
759 }
760 }{
761 out <- string
762 }
763 }
764
765 Line Comment[string:out]
766 {
767 [string]Get DString["\n"]
768 {
769 out <- ["\n"]Append[~]
770 } {} {} {
771 out <- ""
772 }
773 }
774
775 _Get Comment DString[string,delims,line comment,begin comment,end comment,prev before:rest,before,delim,nomatch]
776 {
777 after,befored,used delim,nomatch <- [string]Get DString[delims]
778 {
779 If[[used delim] = [line comment]]
780 {
781 after comment <- Line Comment[after]
782 }{
783 If[[used delim] = [begin comment]]
784 {
785 after comment <- Block Comment[after, begin comment, end comment, 1]
786 }{
787 rest <- Val[after]
788 before <- [prev before]Append[befored]
789 delim <- Val[used delim]
790 }
791 }
792 } {} {} {
793 before <- [prev before]Append[befored]
794 }
795
796 after comment
797 {
798 rest,more before,delim,nomatch <- _Get Comment DString[~, delims, line comment, begin comment, end comment, prev before]
799 before <- [before]Append[more before]
800 }
801
802 }
803
804 As List[val:out]
805 {
806 [(List(),List Leaf())]Find[=[Blueprint Of[val], ?]]
807 {
808 out <- val
809 }{
810 out <- [()]Append[val]
811 }
812 }
813
814 Get Comment DString[string,delims,params:rest,before,delim,not found]
815 {
816 line comment <- [params]Line Comment >>
817 begin comment <- [params]Comment Begin >>
818 end comment <- [params]Comment End >>
819 all delims <- [[[delims]As List]Append[begin comment]]Append[line comment]
820 rest, before, delim, not found <- _Get Comment DString[string, delims, line comment, begin comment, end comment, ""]
821 }
822
823 Comment Left Trim[string,trim chars,params:out]
824 {
825 line comment <- [params]Line Comment >>
826
827 end comment <- [params]Comment End >>
828 trimmed <- Left Trim[string, trim chars]
829 If[[trimmed]Starts With[line comment]]
830 {
831 ,after delim <- [trimmed]Slice[[line comment]Length]
832 out <- Comment Left Trim[Line Comment[after delim], trim chars, params]
833 }{
834 begin comment <- [params]Comment Begin >>
835 If[[trimmed]Starts With[begin comment]]
836 {
837 ,after delim <- [trimmed]Slice[[line comment]Length]
838 out <- Comment Left Trim[Block Comment[after delim, begin comment, end comment, 1], trim chars, params]
839 }{
840 out <- Val[trimmed]
841 }
842 }
843 }
844
845 PBlueprint[string,params,tree,lines:out]
846 {
847 ,whitespace name <- [string]Get Comment DString[[params]Block Begin >>, params]
848 {
849 ,no blueprint <- [whitespace name]Slice[ [[params]Blueprint >>]Length ]
850 name <- Trim[no blueprint, "\r\n\t "]
851 name lines <- 0
852 ,body <- [~]Get Comment DString[ [params]Block End >>, params]
853 {
854 body lines <- [body]Split["\n"]
855 more lines <- [[[body lines]Length] - [1]] + [name lines]
856 fields <- Fold[Process Blueprint Field[?, ?, params], (), Filter[Map[body lines, Trim[?,"\n\r\t "]], Not Empty[?]]]
857 new tree <- [tree]Blueprints << [ [[tree]Blueprints >>]Set[name, New Blueprint Definition[name, fields]] ]
858 out <- Null[~, params, new tree, [lines] + [more lines]]
859 } {} {
860 out <- [tree]Errors <<[ [[tree]Errors >>]Append[Parse Error["Error",[["Blueprint is missing an block close symbol \""]Append[[params]Block End >>]]Append["\""], lines]] ]
861 }
862
863 } {} {
864 out <- [tree]Errors <<[ [[tree]Errors >>]Append[Parse Error["Error",[["Blueprint is missing an block open symbol \""]Append[[params]Block Begin >>]]Append["\""], lines]] ]
865 }
866 }
867
868 Parse Import[string,params,tree,lines:out]
869 {
870 [line]Slice[ [[params]Import >>]Length ] {}
871 {
872 filename <- Trim[~, " \n\r\t"]
873 }
874
875 new tree <- [tree]Imports <<[[[tree]Imports >>]Set[filename, Yes]]
876
877 ,line <- [string]Get Comment DString["\n", params]
878 {
879 out <- Null[~, params, new tree, [lines] + [1]]
880 } {} {} {
881 out <- Val[new tree]
882 }
883 }
884
885 Get Expression Blocks[string,params,blocks:outblocks,after]
886 {
887 check block <- Comment Left Trim[string, "\n\r\t ", params]
888 If[[check block]Starts With[[params]Block Begin >>]]
889 {
890 ,begin block <- [check block]Slice[[[params]Block Begin >>]Length]
891 trees, after block <- Worker Body[begin block, params, ()]
892 outblocks, after <- Get Expression Blocks[after block, params, [blocks]Append[trees]]
893 }{
894 If[[check block]Starts With[[params]Empty Block >>]]
895 {
896 outblocks <- blocks
897 ,after <- [check block]Slice[[[params]Empty Block >>]Length]
898 }{
899 outblocks <- blocks
900 after <- Val[check block]
901 }
902 }
903 }
904
905 Parse Escape[string,params:char,after]
906 {
907 code,rest <- [string]Slice[1]
908 If[[code] = [[params]Hex Escape >>]]
909 {
910 hex,after <- [rest]Slice[2]
911 char <- String[[Array[]]Append[Trunc UInt8[Abs UInt[Hex Int32[hex]]]]]
912 }{
913 after <- Val[rest]
914 char <- [[params]Escape Map >>]Index[code] {}
915 {
916 char <- Val[code]
917 }
918 }
919 }
920
921 Parse String[string,params,current:value,after]
922 {
923 delims <- [[()]Append[[params]String End >>]]Append[[params]String Escape >>]
924 afters, before, delim <- [string]Get Comment DString[delims, params]
925 {
926 If[[delim] = [[params]String End >>]]
927 {
928 value <- [current]Append[before]
929 after <- Val[afters]
930 }{
931 char,after escape <- Parse Escape[afters, params]
932 value,after <- Parse String[after escape, params, [[current]Append[before]]Append[char]]
933 }
934 }
935 }
936
937 Parse List[string,params,list:value,after]
938 {
939 trimmed <- Comment Left Trim[string, "\r\n\t ", params]
940 If[[trimmed]Starts With[[params]List End >>]]
941 {
942 value <- list
943 ,after <- [trimmed]Slice[[[params]List End >>]Length]
944 }{
945 If[[trimmed]Starts With[[params]List Delim >>]]
946 {
947 ,el string <- [trimmed]Slice[[[params]List Delim >>]Length]
948 }{
949 el string <- Val[trimmed]
950 }
951 element,after el <- Named Pipe or Literal[el string, params]
952 value,after <- Parse List[after el, params, [list]Append[[element]Get Value]]
953 }
954 }
955
956 Get Value@Literal Node[node:out]
957 {
958 out <- [node]Value >>
959 }
960
961 Get Value@Named Pipe Node[node:out]
962 {
963 out <- node
964 }
965
966 Machine Integer[val, size, signed?:out]
967 {
968 conv <- [[[[[[[[()
969 ]Append[UInt8[?]]
970 ]Append[Int8[?]]
971 ]Append[UInt16[?]]
972 ]Append[Int16[?]]
973 ]Append[UInt32[?]]
974 ]Append[Int32[?]]
975 ]Append[UInt64[?]]
976 ]Append[Int64[?]]
977
978 base idx <- [[(8,16,32,64)]Find[=[size,?]]]*[2]
979
980 If[signed?]
981 {
982 idx <- [base idx]+[1]
983 }{
984 idx <- Val[base idx]
985 }
986 out <- [[conv]Index[idx]]Call[val]
987 }
988
989 Parse Number[string,params:value,after]
990 {
991 delims <- [[[[(" ","\t","\n","\r")]Append[[params]List Delim >>]]Append[[params]Block Begin >>]]Append[[params]Arg End >>]]Append[[params]List End >>]
992 after delim,valstring <- [string]Get Comment DString[delims, params] {} {}
993 {
994 after <- [~]Append[after delim]
995 }{
996 after <- ""
997 }
998 first two,rest <- [valstring]Slice[2]
999 If[[first two] = ["0x"]]
1000 {
1001 value <- Hex Int32[rest]
1002 }{
1003 If[[valstring]Contains["."]]
1004 {
1005 value <- Real64[valstring]
1006 }{
1007 size, val, type <- [valstring]Get DString[("i","u")]
1008 {
1009 value <- Machine Integer[val, Int32[size], [type]=["i"]]
1010 } {} {} {
1011 value <- Int32[valstring]
1012 }
1013 }
1014 }
1015 }
1016
1017 Parse Params@Type Instance[literal,params,string:out,after]
1018 {
1019 plist,after <- Parse List[string,params,()]
1020 out <- [literal]Params <<[plist]
1021 }
1022
1023 Named Pipe or Literal[string,params:out,after]
1024 {
1025 name <- Comment Left Trim[string, "\n\r\t ", params]
1026 If[[name]Starts With[[params]String Begin >>]]
1027 {
1028 ,string begin <- [name]Slice[[[params]String Begin >>]Length]
1029 value,after <- Parse String[string begin, params, ""]
1030 }{
1031 If[[name]Starts With[[params]List Begin >>]]
1032 {
1033 ,list start <- [name]Slice[[[params]List Begin >>]Length]
1034 value,after <- Parse List[list start, params, ()]
1035 }{
1036 If[[[name]Slice[1]]In["-0123456789"]]
1037 {
1038 value,after <- Parse Number[name, params]
1039 }{
1040 delims <- [[[[[[[("\n")]Append[[params]Block Begin >>]]Append[[params]Block End >>]]Append[[params]Empty Block >>]]Append[[params]Arg End >>]]Append[[params]List Delim >>]]Append[[params]List End >>]]Append[[params]List Begin >>]
1041 afterdelim,raw before,delim,nodelim <- [name]Get Comment DString[delims, params]
1042
1043 before <- Trim[raw before, "\r\n\t "]
1044 If[[delim] = [[params]List Begin >>]]
1045 {
1046 value,after <- [Type Instance[before]]Parse Params[params,afterdelim]
1047 }{
1048 Val[afterdelim]
1049 {
1050 after <- [delim]Append[~]
1051 }
1052 Val[nodelim]
1053 {
1054 after <- ""
1055 }
1056 If[[before] = ["Yes"]]
1057 {
1058 yesno <- Yes
1059 }{
1060 If[[before] = ["No"]]
1061 {
1062 yesno <- No
1063 }{
1064 If[[before] = [""]]
1065 {
1066 Print[[["Found "]Append[delim]]Append[" where a named pipe or literal was expected"]]
1067 { Print[["Near: "]Append[ [afterdelim]Slice[80]]] }
1068 }{
1069 If[[before]Contains[[params]Global Separator >>]]
1070 {
1071 parts <- [before]Split[[params]Global Separator >>]
1072 out <- Global Node[Right Trim[[parts]Index[0],"\r\n\t "], Trim[[parts]Index[1], "\r\n\t "]]
1073 }{
1074 out <- Named Pipe Node[Right Trim[before,"\r\n\t "]]
1075 }
1076 }
1077 }
1078 }
1079 out <- Literal Node[yesno]
1080 }
1081 }
1082 }
1083 }
1084 out <- Literal Node[value]
1085 }
1086
1087 Parse Arguments[string,params,arglist:args,after]
1088 {
1089 targs <- Comment Left Trim[string, "\r\n\t ", params]
1090 If[[targs]Starts With[[params]List Delim >>]]
1091 {
1092 [targs]Slice[[[params]List Delim >>]Length] {}
1093 {
1094 final args <- Comment Left Trim[~, "\r\n\t ", params]
1095 }
1096 }{
1097 If[[targs]Starts With[[params]Arg End >>]]
1098 {
1099 args <- arglist
1100 ,after <- [targs]Slice[[[params]Arg End >>]Length]
1101 }{
1102 final args <- Val[targs]
1103 }
1104 }
1105 arg, after arg <- Parse Expression[final args, params]
1106 args, after <- Parse Arguments[after arg, params, [arglist]Append[arg]]
1107 }
1108
1109 Worker or Field[name,args,params:out]
1110 {
1111 get field <- [params]Get Field >>
1112 If[[name]Ends With[get field]]
1113 {
1114 field <- Right Trim[[name]Slice[[[name]Length] - [[get field]Length]], "\n\r\t "]
1115 out <- Field Node[field, args, No]
1116 }{
1117 set field <- [params]Set Field >>
1118 If[[name]Ends With[set field]]
1119 {
1120 field <- Right Trim[[name]Slice[[[name]Length] - [[set field]Length]], "\n\r\t "]
1121 out <- Field Node[field, args, Yes]
1122 }{
1123 out <- Worker Node[name, args]
1124 }
1125 }
1126 }
1127
1128 Prefix[string,params,name,existing args:expression,after]
1129 {
1130 //Parse argument list
1131 more args,after <- Parse Arguments[string, params, existing args]
1132 expression <- Worker or Field[name, more args, params]
1133 }
1134
1135 Postfix or Infix[string,params:expression,after]
1136 {
1137 args, after args <- Parse Arguments[string, params, ()]
1138 delims <- [[[[[("\n")]Append[[params]Arg Begin >>]]Append[[params]Empty Block >>]]Append[[params]Block Begin >>]]Append[[params]Arg End >>]]Append[[params]List Delim >>]
1139 aftere,before,delim <- [after args]Get Comment DString[delims, params]
1140 {
1141 If[[delim] = [[params]Arg Begin >>]]
1142 {
1143 expression, after <- Prefix[aftere, params, Trim[before,"\r\n\t "], args]
1144 }{
1145 If[[delim] = [[params]Empty Block >>]]
1146 {
1147 after <- Val[aftere]
1148 }{
1149 ,after <- [after args]Slice[[before]Length]
1150 }
1151 expression <- Worker or Field[Trim[before,"\r\n\t "], args, params]
1152 }
1153 }
1154 }
1155
1156 Parse Expression[trimmed,params:final expression,after blocks]
1157 {
1158 delims <- [[[[[[[("\n")]Append[[params]Arg Begin >>]]Append[[params]Arg End >>]]Append[[params]Assign >>]]Append["\n"]]Append[[params]Empty Block >>]]Append[[params]Block End >>]]Append[[params]String Begin >>]
1159 after, before, delim <- [trimmed]Get Comment DString[delims, params]
1160 {
1161 //If we find an arg begin token, we have a worker expression
1162 If[[delim] = [[params]Arg Begin >>]]
1163 {
1164 maybe name <- Right Trim[before, "\r\t "]
1165 //Prefix expressions will have the worker name before the first arg begin token
1166 If[[maybe name] = [""]]
1167 {
1168 expression, after expression <- Postfix or Infix[after, params]
1169 }{
1170 If[[maybe name]Contains[[params]List Delim >>]]
1171 {
1172 after expression <- [after literal]Append[[delim]Append[after]]
1173 expression, after literal <- Named Pipe or Literal[Right Trim[before, "\r\n\t "], params]
1174 }{
1175 expression, after expression <- Prefix[after, params, maybe name, ()]
1176 }
1177 }
1178 }{
1179 If[[delim] = [[params]Assign >>]]
1180 {
1181 //Expressions starting with an assignment can be prefix, postfix or infix
1182 //or they can be a simple literal or named pipe
1183 assignments <- Map[[before]Split[[params]List Delim >>], Trim[?,"\n\r\t "]]
1184 ,after blocks <- Parse Expression[Comment Left Trim[after, " \n\r\t", params], params]
1185 {
1186 final expression <- [~]Assignments <<[assignments]
1187 }
1188 }{
1189 //If[[delim] = [[params]String Begin >>]]
1190 //{
1191 // If[[Trim[before, "\r\n\t "]] = [""]]
1192 // {
1193 // expression, after expression <- Named Pipe or Literal[[delim]Append[after], params]
1194 // }{
1195 // after expression <- [after literal]Append[[delim]Append[after]]
1196 // expression, after literal <- Named Pipe or Literal[Right Trim[before, "\r\n\t "], params]
1197 // }
1198 //}{
1199 // after expression <- [after literal]Append[[delim]Append[after]]
1200 // expression, after literal <- Named Pipe or Literal[Right Trim[before, "\r\n\t "], params]
1201 //}
1202 expression, after expression <- Named Pipe or Literal[trimmed, params]
1203 }
1204 }
1205 //Any expression can be followed by one or more blocks mapping the inputs of other expressions
1206 //to the outputs of the current one
1207 blocks,after blocks <- Get Expression Blocks[after expression, params, ()]
1208 final expression <- [expression]Blocks <<[blocks]
1209 }
1210 }
1211
1212 Worker Body[string,params,trees:outtrees,after end]
1213 {
1214 trimmed <- Comment Left Trim[string, "\n\r\t ", params]
1215 If[[trimmed]Starts With[[params]Block End >>]]
1216 {
1217 //We're done with this block, return
1218 ,after end <- [trimmed]Slice[[[params]Block End >>]Length]
1219 outtrees <- trees
1220 }{
1221 expression, after expression <- Parse Expression[trimmed, params]
1222 outtrees,after end <- Worker Body[after expression, params, [trees]Append[expression]]
1223 }
1224 }
1225
1226 Process Modifiers[worker,params,modifiers:out]
1227 {
1228 //Eventually this will need to be more sophisticated to handle more modifiers
1229 trimmed <- Comment Left Trim[modifiers, "\n\r\t ", params]
1230 If[[trimmed]Starts With[[params]Uses >>]]
1231 {
1232 ,after uses <- [trimmed]Slice[[[params]Uses >>]Length]
1233 ,stores string <- [after uses]Get Comment DString["\n", params]
1234 out <- [worker]Uses Stores <<[Map[[stores string]Split[[params]List Delim >>], Trim[?, "\r\n\t "]]]
1235 }{
1236 out <- worker
1237 }
1238 }
1239
1240 Remove Named Pipe Node[element:out]
1241 {
1242 If[[Blueprint Of[element]] = [Named Pipe Node()]]
1243 {
1244 out <- [element]Name >>
1245 }{
1246 If[[Blueprint Of[element]] = [Type Instance()]]
1247 {
1248 out <- [element]Params <<[ Map[[element]Params >>, Remove Named Pipe Node[?]] ]
1249 }{
1250 out <- element
1251 }
1252 }
1253 }
1254
1255 Parse Param List[text,paramlist,typelist,params:out params,out types]
1256 {
1257 delims <- [[()]Append[[params]List Begin >>]]Append[[params]List Delim >>]
1258 after,param name <-[text]Get DString[delims] {}
1259 {
1260 tname <- Trim[~, "\r\n\t "]
1261 If[[tname] = [""]]
1262 {
1263 nextlist <- Val[paramlist]
1264 next types <- Val[typelist]
1265 }{
1266 nextlist <- [paramlist]Append[tname]
1267 next types <- [typelist]Append[paramtype]
1268 }
1269 }{
1270 If[[~] = [[params]List Begin >>]]
1271 {
1272 type info,after type <- Parse List[after,params,()]
1273 type <- [type info]Index[0]
1274 {
1275 If[[Blueprint Of[~]] = [Named Pipe Node()]]
1276 {
1277 before variant <- Type Instance[[type]Name >>]
1278 }{
1279 before variant <- <- [type]Params <<[ Map[[type]Params >>, Remove Named Pipe Node[?]] ]
1280 }
1281 variant <- [type info]Index[1]
1282 {
1283 ,warn <- If[[Blueprint Of[~]] = [Named Pipe Node()]]
1284 {
1285 before mutable,warn <- [before variant]Set Variant[[variant]Name >>]
1286 }
1287 Val[warn]
1288 {
1289 Print[[[["Warning: Invalid variant for type "]Append[[before variant]Name >>]]Append[" on input "]]Append[param name]]
1290 before mutable <- Val[before variant]
1291 }
1292 }{
1293 before mutable <- Val[before variant]
1294 }
1295 [type info]Index[2]
1296 {
1297 paramtype <- [before mutable]Mutable? <<[ [[~]Name >>] = ["Mutable"] ]
1298 }{
1299 paramtype <- Val[before mutable]
1300 }
1301 }{
1302 paramtype <- Type Instance["Any Type"]
1303 }
1304 [after type]Get DString[","]
1305 {
1306 out params,out types <- Parse Param List[~,nextlist,next types,params]
1307 } {} {} {
1308 out params <- Val[nextlist]
1309 out types <- Val[next types]
1310 }
1311 }{
1312 paramtype <- Type Instance["Any Type"]
1313 out params,out types <- Parse Param List[after,nextlist,next types,params]
1314 }
1315
1316 }{
1317 paramtype <- Type Instance["Any Type"]
1318 out params <- Val[nextlist]
1319 out types <- Val[next types]
1320 }
1321 }
1322
1323 Worker Declaration[string,params:worker,rest,no match]
1324 {
1325 ,whitespace name <- [string]Get Comment DString[[params]Arg Begin >>, params]
1326 {
1327 worker name <- Trim[whitespace name, "\n\r\t "]
1328 in out <- [params]In Out Delim >>
1329 arg end <- [params]Arg End >>
1330 delims <- [[()]Append[in out]]Append[arg end]
1331 after <- [~]Get Comment DString[delims, params] {}
1332 {
1333 arglist <- Trim[~,"\r\n\t "]
1334 }{
1335 //check if there is an in/out separator
1336 //if it isn't present, everything in the arglist is an input
1337 If[[~] = [in out]]
1338 {
1339 rest <- [after]Get Comment DString[arg end, params] {}
1340 {
1341 outputs,output types <- Parse Param List[~, (), (), params]
1342 }
1343 }{
1344 rest <- Val[after]
1345 outputs <- ()
1346 output types <- ()
1347 }
1348 inputs,input types <- Parse Param List[arglist, (), (), params]
1349 worker <- Parse Worker[worker name, inputs, outputs, input types, output types, 0]
1350 }
1351 }{}{}{
1352 no match <- string
1353 }
1354 }
1355
1356 Worker Name[string,params,tree,lines:out]
1357 {
1358 ,after arglist <- Worker Declaration[string, params]
1359 {
1360 worker name <- [~]Name >>
1361 body text, modifiers <- [after arglist]Get Comment DString[[params]Block Begin >>, params]
1362 modified <- Process Modifiers[~, params, modifiers]
1363 expression trees, after body <- Worker Body[body text, params, ()]
1364 worker <- [modified]Trees <<[expression trees]
1365 new worker dict <- [[tree]Workers >>]Set[worker name, worker]
1366 out <- Null[after body, params, [tree]Workers <<[new worker dict], 0]
1367 } {} {
1368 out <- tree
1369 }
1370 }
1371
1372 Parse Foreign Worker[tree, string, lib, params:out]
1373 {
1374 ,rest <- Worker Declaration[string, params]
1375 {
1376 foreign <- [~]Trees << [lib]
1377 next <- [tree]Workers << [[[tree]Workers >>]Set[[foreign]Name >>, foreign]]
1378 out <- Parse Foreign Worker[next, rest, lib, params]
1379 } {} {
1380 out <- tree
1381 }
1382 }
1383
1384 Parse Foreign[string,params,tree,lines:out]
1385 {
1386 ,after foreign <- [string]Slice[[[params]Foreign >>]Length]
1387 [after foreign]Get Comment DString[[params]Blueprint Type Delim >>, params]
1388 {
1389 [~]Get Comment DString[[params]Block Begin >>, params]
1390 {
1391 rest, body <- [~]Get Comment DString[[params]Block End >>, params]
1392 }
1393 { lib <- Trim[~, "\r\n\t "] }
1394 }
1395 { language <- Trim[~, "\r\n\t "] }
1396 Parse Foreign Worker[tree, body, New Foreign Lib[language, lib], params]
1397 {
1398 out <- Null[rest, params, ~, 0]
1399 }
1400 }
1401
1402 Null[string,params,tree,lines:out]
1403 {
1404 trimmed <- Comment Left Trim[string, " \n\r\t", params]
1405 current line <- 0
1406 If[[trimmed]Starts With[ [params]Blueprint >> ]]
1407 {
1408 out <- PBlueprint[trimmed, params, tree, current line]
1409 }{
1410 If[[trimmed]Starts With[ [params]Import >> ]]
1411 {
1412 out <- Parse Import[trimmed, params, tree, current line]
1413 }{
1414 If[[trimmed]Starts With[ [params]Foreign >> ]]
1415 {
1416 out <- Parse Foreign[trimmed, params, tree, current line]
1417 }{
1418 If[trimmed]
1419 {
1420 out <- Worker Name[trimmed, params, tree, current line]
1421 }{
1422 out <- tree
1423 }
1424 }
1425 }
1426 }
1427 }
1428
1429 Check Worker Literals@Parse Worker[worker,program:out]
1430 {
1431 [(List(),List Leaf())]Find[=[Blueprint Of[[worker]Trees >>], ?]]
1432 {
1433 out <- [worker]Trees <<[ Map[[worker]Trees >>, Check Worker Literals[?, program]] ]
1434 }{
1435 out <- worker
1436 }
1437 }
1438
1439 Register Workers Compile[prog, worker, name:out]
1440 {
1441 //Print[["Registering "]Append[name]]
1442 If[[ Blueprint Of[[worker]Trees >>] ] = [Foreign Lib()]]
1443 { convention <- Val[[[worker]Trees >>]Language >>] }
1444 { convention <- "rhope" }
1445 out <- [prog]Register Worker[name, convention, [[worker]Inputs >>]Length, [[worker]Outputs >>]Length]
1446 }
1447
1448 Add Workers Compile[prog, worker, name:out]
1449 {
1450 Print[["Transforming "]Append[name]]
1451 If[[Blueprint Of[[worker]Trees >>]] = [Foreign Lib()]]
1452 {
1453 //TODO: Handle foreign func
1454 final nworker <- [[[[[NWorker[[[worker]Trees >>]Language >>]
1455 ]Inputs <<[ [worker]Inputs >> ]
1456 ]Input Types <<[ [worker]Input Types >> ]
1457 ]Outputs <<[ [worker]Outputs >> ]
1458 ]Output Types <<[ [worker]Output Types >> ]
1459 ]Library <<[ [[worker]Trees >>]Name >> ]
1460
1461 }{
1462 trees, nworker, refs <- Add List to Worker[[worker]Trees >>, [[NWorker["rhope"]]Uses[[worker]Uses Stores >>]]Outputs <<[ [worker]Outputs >> ], prog, worker, Dictionary[]]
1463 {
1464 final nworker <- Fold[Add Wires Helper[?, ?, ?, worker, refs], nworker, trees]
1465 }
1466
1467 }
1468 out <- [prog]Bind Worker[name, final nworker]
1469 }
1470
1471 Add Wires Helper[worker,node,unused,parse worker,assignments:out]
1472 {
1473 out <- [node]Add Wires[worker, (), parse worker, assignments]
1474 }
1475
1476 Add Blueprint Field[blueprint,field,unused:out]
1477 {
1478 out <- [blueprint]Add Field[[field]Name >>, [field]Type >>]
1479 }
1480
1481 Add Blueprint Compile[prog,def:out]
1482 {
1483 out <- [prog]Bind Blueprint[[def]Name >>, Fold[Add Blueprint Field[?], NBlueprint[], [def]Fields >>]]
1484 }
1485
1486 Tree to Program Native[parse tree:out]
1487 {
1488 registered <- Fold[Register Workers Compile[?], [Fold[Add Blueprint Compile[?], NProgram[], [parse tree]Blueprints >>]]Register Builtins, [parse tree]Workers >>]
1489 out <- Fold[Add Workers Compile[?], registered, [parse tree]Workers >>]
1490 { Print["Transformed AST to dataflow graph "] }
1491 }
1492
1493 Needs Imports[needs import,not imported?,name:out]
1494 {
1495 If[not imported?]
1496 {
1497 out <- [needs import]Append[name]
1498 }{
1499 out <- needs import
1500 }
1501 }
1502
1503 Do Import[tree,file name,unused,params:out]
1504 {
1505 Print[["Parsing: "]Append[file name]]
1506 file <- [File[file name]]Open["r"]
1507 text <- String[[file]Read[[file]Length]]
1508 after import <- Null[text, params, tree, 0]
1509
1510 out <- [after import]Imports <<[[[after import]Imports >>]Set[file name, No]]
1511 }
1512
1513 Process Imports[parse tree,params:out]
1514 {
1515 needs import <- Fold[Needs Imports[?], (), [parse tree]Imports >>]
1516 If[[[needs import]Length] > [0]]
1517 {
1518 import tree <- Fold[Do Import[?, ?, ?, params], parse tree, needs import]
1519 out <- Process Imports[import tree, params]
1520 }{
1521 out <- parse tree
1522 }
1523 }
1524
1525 Until End[text:out]
1526 {
1527 line <- Get Input[]
1528 If[[line] = ["End"]]
1529 {
1530 out <- [text]Append["\n"]
1531 }{
1532 out <- Until End[[[text]Append["\n"]]Append[line]]
1533 }
1534 }
1535
1536 Add If Store[stores,name,params:out]
1537 {
1538 If[[name]Contains[[params]Global Separator >>]]
1539 {
1540 parts <- [name]Split[[params]Global Separator >>]
1541 out <- [stores]Set[[parts]Index[0], Yes]
1542 }{
1543 out <- stores
1544 }
1545 }
1546
1547 Param Gather Stores[stores,node,params:out]
1548 {
1549 out <- [node]Gather Stores[params, stores]
1550 }
1551
1552 Gather Stores@Named Pipe Node[node,params,stores:out]
1553 {
1554 out <- Fold[Add If Store[?, ?, params], stores, [node]Assignments >>]
1555 }
1556
1557 Gather Stores@Global Node[node,params,stores:out]
1558 {
1559 out <- [stores]Set[[node]Store >>, Yes]
1560 }
1561
1562 Gather Stores@Worker Node[node,params,stores:out]
1563 {
1564 //TODO: Handle blocks
1565 store list <- Fold[Param Gather Stores[?, ?, params], stores, [node]Params >>]
1566 out <- Fold[Add If Store[?, ?, params], store list, [node]Assignments >>]
1567 }
1568
1569 Gather Stores@Field Node[node,params,stores:out]
1570 {
1571 //TODO: Handle blocks
1572 store list <- Fold[Param Gather Stores[?, ?, params], stores, [node]Params >>]
1573 out <- Fold[Add If Store[?, ?, params], store list, [node]Assignments >>]
1574 }
1575
1576 Gather Stores@Literal Node[node,params,stores:out]
1577 {
1578 out <- Fold[Add If Store[?, ?, params], stores, [node]Assignments >>]
1579 }
1580
1581
1582 Main[args]
1583 {
1584 fname <- [args]Index[1]
1585 {
1586 file <- [File[~]]Open["r"]
1587 text <- String[[file]Read[[file]Length]]
1588 params <- Parser[]
1589 Print[["Parsing "]Append[fname]]
1590 Null[text, params, Parse Program[], 0]
1591 {
1592 Print["Parsing imports"]
1593 Process Imports[~, params]
1594 {
1595 tree <- [~]Workers << [ Map[[~]Workers >>, Check Worker Literals[?, ~]] ]
1596 { Print["Compiling"] }
1597 }
1598 compiled <- [Tree to Program Native[tree]]Compile Program[C Program[]]
1599 { Print["Compiled program to backend"] }
1600 outfile <- [File[ [fname]Append[".c"] ]]Truncate
1601 [outfile]Write[ [Flatten[[compiled]Text]]Buffer >> ]
1602 { Print[["Wrote output to "]Append[ [fname]Append[".c"] ]] }
1603 }
1604 }{
1605 Print["You must provide a file name to compile"]
1606 }
1607 }