comparison parser_old.rhope @ 22:812673a8b1ea

Converted old parser to new syntax (needs work, currently crashes interpreter
author Mike Pavone <pavone@retrodev.com>
date Wed, 24 Jun 2009 02:07:12 -0400
parents
children 8b2b3f4a2a58
comparison
equal deleted inserted replaced
21:e9272f7ebd26 22:812673a8b1ea
1 Import extendlib.rhope
2
3
4
5 Blueprint Parser
6 {
7 Arg Begin
8 Arg End
9 Line Comment
10 Comment Begin
11 Comment End
12 Assign
13 Block Begin
14 Block End
15 Blueprint Type Delim
16 Empty Block
17 Binary Operator
18 String Begin
19 String End
20 String Escape
21 List Begin
22 List End
23 List Delim
24 In Out Delim
25 Do Worker
26 Index Begin
27 Index End
28 Previous
29 Block Val
30 Set Field
31 Get Field
32 Import
33 Blueprint
34 Global Separator
35 Uses
36 Hex Escape
37 Escape Map
38 }
39
40 New@Parser[:out]
41 {
42 out <- [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[Build["Parser"]
43 ]Arg Begin << ["["]
44 ]Arg End <<["]"]
45 ]Line Comment <<["//"]
46 ]Comment Begin <<["/*"]
47 ]Comment End <<["*/"]
48 ]Assign <<["<-"]
49 ]Block Begin <<["{"]
50 ]Block End <<["}"]
51 ]Blueprint Type Delim <<[":"]
52 ]Empty Block <<[";"]
53 ]Binary Operator <<["`"]
54 ]String Begin <<["\""]
55 ]String End <<["\""]
56 ]String Escape <<["\\"]
57 ]List Begin <<["("]
58 ]List End <<[")"]
59 ]List Delim <<[","]
60 ]In Out Delim <<[":"]
61 ]Do Worker <<["$"]
62 ]Index Begin <<["("]
63 ]Index End <<[")"]
64 ]Previous <<["@"]
65 ]Set Field <<["<<"]
66 ]Get Field <<[">>"]
67 ]Import <<["Import"]
68 ]Blueprint <<["Blueprint"]
69 ]Global Separator <<["::"]
70 ]Hex Escape <<["x"]
71 ]Uses <<["uses"]
72 ]Escape Map <<[[[[New@Dictionary[]]Set["n","\n"]]Set["r","\r"]]Set["t","\t"]]
73 }
74
75 Blueprint Output Reference
76 {
77 Index
78 Output Number
79 }
80
81 New@Output Reference[index,num:out]
82 {
83 out <- [[Build["Output Reference"]]Index <<[index]]Output Number <<[num]
84 }
85
86 Add Pipe Reference[refs,name,reference:out]
87 {
88 reflist <- [refs]Index[name] {}
89 {
90 reflist <- New@List[]
91 }
92 out <- [refs]Set[name, [reflist]Append[reference]]
93 }
94
95 Assignment Save Reference[refs,assignment,output num,parse worker,index:out]
96 {
97 [[parse worker]Outputs >>]Find[assignment]
98 {
99 out <- refs
100 }{
101 out <- Add Pipe Reference[refs, assignment, New@Output Reference[index, output num]]
102 }
103 }
104
105 Blueprint Parse Program
106 {
107 Workers
108 Imports
109 Blueprints
110 Errors
111 }
112
113 New@Parse Program[:out]
114 {
115 out <- [[[Build["Parse Program"]
116 ]Workers <<[New@Dictionary[]]
117 ]Imports <<[New@Dictionary[]]
118 ]Blueprints <<[New@Dictionary[]]
119 }
120
121 Blueprint Blueprint Definition
122 {
123 Name
124 Fields
125 }
126
127 New@Blueprint Definition[name,fields:out]
128 {
129 out <- [[Build["Blueprint Definition"]]Name << [name]]Fields <<[fields]
130 }
131
132 Blueprint Parse Worker
133 {
134 Name
135 Inputs
136 Outputs
137 Line Number
138 Trees
139 Uses Stores
140 }
141
142 New@Parse Worker[name,inputs,outputs,line:out]
143 {
144 out <- [[[[[[Build["Parse Worker"]]Name <<[name]]Inputs <<[inputs]]Outputs <<[outputs]]Line Number <<[line]]Trees <<[New@List[]]]Uses Stores <<[New@List[]]
145 }
146
147 Blueprint Worker Node
148 {
149 Name
150 Params
151 Assignments
152 Blocks
153 Index
154 }
155
156 New@Worker Node[name,params:out]
157 {
158 out <- [[[[Build["Worker Node"]]Name <<[name]]Params <<[params]]Assignments <<[New@List[]]]Blocks <<[New@List[]]
159 }
160
161 Add List Helper[list,worker,program,key,parse worker,refs:out,worker,refs]
162 {
163 ,nextworker,nextrefs <- [[list]Index[key]]Add to Worker[worker, program, parse worker, refs]
164 { nextlist <- [list]Set[key, ~] }
165 [list]Next[key]
166 {
167 list,worker,refs <- Add List Helper[nextlist, nextworker, program, ~, parse worker, nextrefs]
168 }{
169 list <- Val[nextlist]
170 worker <- Val[nextworker]
171 refs <- Val[nextrefs]
172 }
173 }
174
175 Add List to Worker[list,worker,program,parse worker,refs:list,worker,refs]
176 {
177 [list]First
178 {
179 list,worker,refs <- Add List Helper[list, worker, program, ~, parse worker, refs]
180 }{
181 list <- list
182 worker <- worker
183 refs <- refs
184 }
185 }
186
187 _Add Blocks to Worker[blocks,worker,program,parse worker,key,refs:blocks,worker,refs]
188 {
189 block, next worker, nextrefs <- Add List to Worker[[blocks]Index[key], worker, program, parse worker, refs]
190 next blocks <- [blocks]Set[key, block]
191 [blocks]Next[key]
192 {
193 blocks,worker,refs <- _Add Blocks to Worker[next blocks, next worker, program, parseworker, ~, nextrefs]
194 }{
195 blocks <- Val[next blocks]
196 worker <- Val[next worker]
197 refs <- Val[nextrefs]
198 }
199 }
200
201 Add Blocks to Worker[blocks,worker,program,parse worker,refs:blocks,worker,refs]
202 {
203 [blocks]First
204 {
205 blocks, worker, refs <- _Add Blocks to Worker[blocks, worker, program, parse worker, ~, refs]
206 }{
207 blocks <- blocks
208 worker <- worker
209 refs <- refs
210 }
211 }
212
213 Add to Worker@Worker Node[node,worker,program,parse worker,refs:node,worker,refs]
214 {
215 [program]Find Worker[[node]Name >>]
216 {
217 after worker <- [worker]Add Worker Call[~] {}
218 {
219 assignment refs <- Fold[[["Assignment Save Reference"]Set Input[3, parse worker]]Set Input[4, ~], refs, [node]Assignments >>]
220 [node]Index <<[~]
221 {
222 params list, params worker, params refs <- Add List to Worker[[~]Params >>, after worker, program, parse worker, assignment refs]
223 block list, worker, refs <- Add Blocks to Worker[[~]Blocks >>, params worker, program, parse worker, params refs]
224 node <- [[~]Params <<[params list]]Blocks <<[block list]
225 }
226 }
227 }{
228 Print[["Error: Could not find a worker named "]Append[[node]Name >>]]
229 }
230 }
231
232 Add Multi Wire[worker,ref,junk,end index,input num:out]
233 {
234 out <- [worker]Add Wire[[ref]Index >>, [ref]Output Number >>, end index, input num]
235 }
236
237 Add Param Wire[worker,param,input num,end index,blocks,parse worker,assignments:out]
238 {
239 param worker, start index, output num <- [param]Add Wires[worker, blocks, parse worker, assignments] {}
240 {
241 out <- [param worker]Add Wire[start index, output num, end index, input num]
242 }{}{
243 out <- Fold[[["Add Multi Wire"]Set Input[3, end index]]Set Input[4, input num], param worker, ~]
244 }
245 }
246
247 _Add Block Wire[worker,node,junk,blocks,parse worker,assignments:out]
248 {
249 out <- [node]Add Wires[worker, blocks, parse worker, assignments]
250 }
251
252 Add Block Wire[worker,block nodes,output num,parent index,existing blocks,parse worker,assignments:out]
253 {
254 blocks <- [existing blocks]Append[New@Output Reference[parent index, output num]]
255 out <- Fold[[[["_Add Block Wire"]Set Input[3, blocks]]Set Input[4, parse worker]]Set Input[5, assignments], worker, block nodes]
256 }
257
258 Assignments Add Wires[worker,assignement,output num,parse worker,start index:worker]
259 {
260 [[parse worker]Outputs >>]Find[assignment]
261 {
262 ,output index <- [worker]Add Output[assignment, ~]
263 {
264 worker <- [~]Add Wire[start index, output num, output index, 0]
265 }
266 }{
267 //Ugly hack alert!
268 If[[asignment]Contains["::"]]
269 {
270 parts <- [assignment]Split["::"]
271 ,global index <- [worker]Add Global Set[[parts]Index[0], [parts]Index[1]]
272 {
273 worker <- [~]Add Wire[start index, output num, global index, 0]
274 }
275 }{
276 worker <- worker
277 }
278 }
279 }
280
281 Has Block@Worker Node[junk:out,unused]
282 {
283 out <- Yes
284 }
285
286 _Has Block Params[list,key:out]
287 {
288 param <- [param list]Index[key]
289 out <- [param]Has Block {}
290 {
291 [param list]Next[key]
292 {
293 out <- _Has Block Params[param list, ~]
294 }{
295 out <- No
296 }
297 }
298
299 }
300
301 Has Block Params[param list:out]
302 {
303 [param list]First
304 {
305 out <- _Has Block Params[param list, ~]
306 }{
307 out <- No
308 }
309 }
310
311 Add Wires@Worker Node[node,worker,blocks,parse worker,assignments:worker,index,num,unused]
312 {
313 worker,index,num <- Add Wires Worker or Field[node, worker, blocks, parse worker, assignments]
314 }
315
316 Add Wires Worker or Field[node,worker,blocks,parse worker,assignments:worker,index,num,unused]
317 {
318 Fold[[["Assignments Add Wires"]Set Input[3, parse worker]]Set Input[4, [node]Index >>], worker, [node]Assignments >>]
319 { Fold[[[[["Add Block Wire"]Set Input[3, [node]Index >>]]Set Input[4, blocks]]Set Input[5, parse worker]]Set Input[6, assignments], ~, [node]Blocks >>]
320 { params worker <- Fold[[[[["Add Param Wire"]Set Input[3, [node]Index >>]]Set Input[4, blocks]]Set Input[5, parse worker]]Set Input[6, assignments], ~, [node]Params >>] :{|
321 If[Has Block Params[[node]Params >>]]
322 {
323 worker <- Val[params worker]
324 }{
325 [blocks]Peek
326 {
327 worker <- [params worker]Add Wire[[~]Index >>, [~]Output Number >>, [node]Index >>, [0]-[1]]
328 }{
329 worker <- Val[params worker]
330 }
331 }
332 index <- [node]Index >>
333 num <- 0
334 }
335
336 Blueprint Field Node
337 {
338 Name
339 Params
340 Assignments
341 Blocks
342 Index
343 Set?
344 }
345
346 Has Block@Field Node[junk:has block,unused]
347 {
348 has block <- Yes
349 }
350
351 New@Field Node[name,params,set:out]
352 {
353 out <- [[[[[Build["Field Node"]]Name <<[name]]Assignments <<[New@List[]]]Blocks <<[New@List[]]]Set? <<[set]]Params <<[params]
354 }
355
356 Add to Worker@Field Node[node,worker,program,parse worker,refs:node,worker,refs,unused]
357 {
358 If[[node]Set? >>]
359 {
360 after worker,index <- [worker]Add Object Set[[node]Name >>]
361 }{
362 after worker,index <- [worker]Add Object Get[[node]Name >>]
363 }
364 index
365 {
366 assignment refs <- Fold[[["Assignment Save Reference"]Set Input[3, parse worker]]Set Input[4, ~], refs, [node]Assignments >>]
367 [node]Index <<[~]
368 {
369 params list, params worker, params refs <- Add List to Worker[[~]Params >>, after worker, program, parse worker, assignment refs]
370 block list, worker, refs <- Add Blocks to Worker[[~]Blocks >>, params worker, program, parse worker, params refs]
371 node <- [[~]Params <<[params list]]Blocks <<[block list]
372 }
373 }
374 }
375
376 Add Wires@Field Node[node,worker,blocks,parse worker,assignments:worker,index,num]
377 {
378 worker,index,num <- Add Wires Worker or Field[node, worker, blocks, parse worker, assignments]
379 }
380
381 Blueprint Named Pipe Node
382 {
383 Name
384 Assignments
385 Blocks
386 Index
387 }
388
389 Has Block@Named Pipe Node[node:has block,no block]
390 {
391 If[[[node]Index >>] < [0]]
392 {
393 //~ should really be a parser parameter
394 If[[[node]Name >>] = ["~"]]
395 {
396 has block <- Yes
397 }{
398 no block <- No
399 }
400 }{
401 has block <- Yes
402 }
403 }
404
405 New@Named Pipe Node[name:out]
406 {
407 out <- [[[Build["Named Pipe Node"]]Name <<[name]]Assignments <<[New@List[]]]Blocks <<[New@List[]]
408 }
409
410 Add to Worker@Named Pipe Node[node,worker,program,parse worker,refs:node,worker,refs]
411 {
412 [[parse worker]Inputs >>]Find[[node]Name >>]
413 {
414 after add <- [worker]Add Input[[node]Name >>, ~] {}
415 {
416 assign refs <- Fold[[["Assignment Save Reference"]Set Input[3, parse worker]]Set Input[4, ~], refs, [node]Assignments >>]
417 index node <- [node]Index <<[~]
418 }
419 }{
420 after add <- worker
421 index node <- [node]Index <<[[0]-[1]]
422 //TODO: Handle assignments from a named pipe that isn't an input
423 assign refs <- refs
424 }
425 block list, worker, refs <- Add Blocks to Worker[[node]Blocks >>, after add, program, parse worker, assign refs]
426 node <- [index node]Blocks <<[block list]
427 }
428
429 Add Wires@Named Pipe Node[node,worker,blocks,parse worker,assignments:worker,index,num,unused]
430 {
431 reflist <- [assignments]Index[[node]Name >>]
432 {
433 //TODO: Fix support for a named pipe with a block
434 worker <- worker
435 }{
436 If[[[node]Name >>] = ["~"]]
437 {
438 wires worker <- worker
439 [blocks]Peek
440 {
441 my index <- [~]Index >>
442 num <- [~]Output Number >>
443 }{
444 //TODO: Propagate an error rather than printing it out
445 Print["Error, block reference symbol located outside of a block"]
446 }
447 }{
448 If[[[node]Index >>] < [0]]
449 {
450 Print[[[["Error, reference to named pipe "]Append[[node]Name >>]]Append[" that was never assigned to in worker "]]Append[[parse worker]Name >>]]
451 }{
452 my index <- [node]Index >>
453 num <- 0
454 assignments worker <- Fold[[["Assignments Add Wires"]Set Input[3, parse worker]]Set Input[4, [node]Index >>], worker, [node]Assignments >>]
455 [blocks]Peek
456 {
457 wires worker <- [assignments worker]Add Wire[[~]Index >>, [~]Output Number >>, [node]Index >>, [0]-[1]]
458 }{
459 wires worker <- Val[assignments worker]
460 }
461 }
462 }
463 }
464 index <- my index
465
466 worker <- Fold[[[[["Add Block Wire"]Set Input[3, my index]]Set Input[4, blocks]]Set Input[5, parse worker]]Set Input[6, assignments], wires worker, [node]Blocks >>]
467 }
468
469 Blueprint Global Node
470 {
471 Store
472 Name
473 Assignments
474 Blocks
475 Index
476 }
477
478 New@Global Node[store,name:out]
479 {
480 out <- [[[[Build["Global Node"]]Store <<[store]]Name <<[name]]Assignments <<[New@List[]]]Blocks <<[New@List[]]
481 }
482
483 Add to Worker@Global Node[node,worker,unused,parse worker,refs:out node,out worker,refs]
484 {
485 out worker <- [worker]Add Global Get[[node]Store >>, [node]Name >>] {}
486 {
487 refs <- Fold[[["Assignment Save Reference"]Set Input[3, parse worker]]Set Input[4, ~], refs, [node]Assignments >>]
488 out node <- [node]Index <<[~]
489 }
490 refs <- refs
491 }
492
493 Add Wires@Global Node[node,worker,blocks,parse worker,assignments:worker,index,num,unused]
494 {
495 worker,index,num <- Add Wires Literal or Global[node, worker, blocks, parse worker, assignments]
496 }
497
498 Has Block@Global Node[junk:out,unused]
499 {
500 out <- Yes
501 }
502
503 Blueprint Literal Node
504 {
505 Value
506 Assignments
507 Blocks
508 Index
509 }
510
511 Has Block@Literal Node[junk:out,unused]
512 {
513 out <- Yes
514 }
515
516 New@Literal Node[value:out]
517 {
518 out <- [[[Build["Literal Node"]]Value <<[value]]Assignments <<[New@List[]]]Blocks <<[New@List[]]
519 }
520
521 Add to Worker@Literal Node[node,worker,unused,parse worker,refs:out node,out worker,refs,unused]
522 {
523 out worker <- [worker]Add Constant[[node]Value >>] {}
524 {
525 refs <- Fold[[["Assignment Save Reference"]Set Input[3, parse worker]]Set Input[4, ~], refs, [node]Assignments >>]
526 out node <- [node]Index <<[~]
527 }
528 }
529
530 Add Wires@Literal Node[node,worker,blocks,parse worker,assignments:worker,index,num,unused]
531 {
532 worker,index,num <- Add Wires Literal or Global[node, worker, blocks, parse worker, assignments]
533 }
534
535 Add Wires Literal or Global[node,worker,blocks,parse worker,junk:worker,index,num,unused]
536 {
537 assignments worker <- Fold[[["Assignments Add Wires"]Set Input[3, parse worker]]Set Input[4, [node]Index >>], worker, [node]Assignments >>]
538 [blocks]Peek
539 {
540 worker <- [assignments worker]Add Wire[[~]Index >>, [~]Output Number>>, [node]Index >>, [0]-[1]]
541 }{
542 worker <- Val[assignments worker]
543 }
544 index <- [node]Index >>
545 num <- 0
546 }
547
548 Blueprint Block Node
549 {
550 Number
551 }
552
553 Blueprint Parse Error
554 {
555 Type
556 Text
557 Line Number
558 }
559
560 New@Parse Error[type,text,number:out]
561 {
562 out <- [[[Build["Parse Error"]]Type <<[type]]Text <<[text]]Line Number <<[number]
563 }
564
565 Filter Empty[string:out]
566 {
567 If[[[string]Length] > [0]]
568 {
569 out <- Yes
570 }{
571 out <- No
572 }
573 }
574
575 Blueprint Blueprint Field
576 {
577 Name
578 Type
579 }
580
581 New@Blueprint Field[name,type:out]
582 {
583 out <- [[Build["Blueprint Field"]]Name <<[name]]Type <<[type]
584 }
585
586 Process Blueprint Field[list,field,delim:out]
587 {
588 parts <- [field]Split[delim]
589 If[[[parts]Length] > [1]]
590 {
591 out <- [list]Append[New@Blueprint Field[[parts]Index[1], [parts]Index[0]]]
592 }{
593 out <- [list]Append[New@Blueprint Field[[parts]Index[0], "Any Type"]]
594 }
595 }
596
597 Block Comment[string,begin comment,end comment,block count:out]
598 {
599 If[[block count] > [0]]
600 {
601 after, before <- [string]Get DString[[[New@List[]]Append[begin comment]]Append[end comment]] {} {}
602 {
603 If[[~] = [begin comment]]
604 {
605 out <- Block Comment[after, begin comment, end comment, [block count]+[1]]
606 }{
607 out <- Block Comment[after, begin comment, end comment, [block count]-[1]]
608 }
609 }{
610 //No match
611 out <- ""
612 }
613 }{
614 out <- string
615 }
616 }
617
618 Line Comment[string:out]
619 {
620 [string]Get DString["\n"]
621 {
622 out <- ["\n"]Append[~]
623 } {} {} {
624 out <- ""
625 }
626 }
627
628 _Get Comment DString[string,delims,line comment,begin comment,end comment,prev before:rest,before,delim,nomatch]
629 {
630 after,before,delim,nomatch <- [string]Get DString[delims]
631 {
632 If[[delim] = [line comment]]
633 {
634 after comment <- Line Comment[after]
635 }{
636 If[[delim] = [begin comment]]
637 {
638 after comment <- Block Comment[after, begin comment, end comment, 1]
639 }{
640 rest <- Val[after]
641 before <- [prev before]Append[before]
642 delim <- Val[delim]
643 }
644 }
645 } {} {} {
646 before <- [prev before]Append[before]
647 }
648
649 after comment
650 {
651 rest,more before,delim,nomatch <- _Get Comment DString[~, delims, line comment, begin comment, end comment, prev before]
652 before <- [before]Append[more before]
653 }
654
655 }
656
657 Get Comment DString[string,delims,params:rest,before,delim,not found]
658 {
659 line comment <- [params]Line Comment >>
660 begin comment <- [params]Comment Begin >>
661 end comment <- [params]Comment End >>
662 all delims <- [[[delims]As List]Append[begin comment]]Append[line comment]
663 rest, before, delim, not found <- _Get Comment DString[string, delims, line comment, begin comment, end comment, ""]
664 }
665
666 Comment Left Trim[string,trim chars,params:out]
667 {
668 line comment <- [params]Line Comment >>
669
670 end comment <- [params]Comment End >>
671 trimmed <- Left Trim[string, trim chars]
672 If[[trimmed]Starts With[line comment]]
673 {
674 ,after delim <- [trimmed]Slice[[line comment]Length]
675 out <- Comment Left Trim[Line Comment[after delim], trim chars, params]
676 }{
677 begin comment <- [params]Comment Begin >>
678 If[[trimmed]Starts With[begin comment]]
679 {
680 ,after delim <- [trimmed]Slice[[line comment]Length]
681 out <- Comment Left Trim[Block Comment[after delim, begin comment, end comment, 1], trim chars, params]
682 }{
683 out <- Val[trimmed]
684 }
685 }
686 }
687
688 Blueprint[string,params,tree,lines:out]
689 {
690 ,whitespace name <- [string]Get Comment DString[[params]Block Begin >>, params]
691 {
692 ,no blueprint <- [whitespace name]Slice[ [[params]Blueprint >>]Length ]
693 name <- Trim[no blueprint, "\r\n\t "]
694 name lines <- 0//[Count Substring[left, "\n"]] + [Count Substring[right, "\n"]]
695 ,body <- [~]Get Comment DString[ [params]Block End >>, params]
696 {
697 body lines <- [body]Split["\n"]
698 more lines <- [[[body lines]Length] - [1]] + [name lines]
699 fields <- Fold[["Process Blueprint Field"]Set Input[2, [params]Blueprint Type Delim >>], New@List[], Filter[Map[body lines, ["Trim"]Set Input[1,"\n\r\t "]], "Filter Empty"]]
700 new tree <- [tree]Blueprints << [ [[tree]Blueprints >>]Set[name, New@Blueprint Definition[name, fields]] ]
701 out <- Null[~, params, new tree, [lines] + [more lines]]
702 } {} {
703 out <- [tree]Errors <<[ [[tree]Errors >>]Append[New@Parse Error["Error",[["Blueprint is missing an block close symbol \""]Append[[params]Block End >>]]Append["\""], lines]] ]
704 }
705
706 } {} {
707 out <- [tree]Errors <<[ [[tree]Errors >>]Append[New@Parse Error["Error",[["Blueprint is missing an block open symbol \""]Append[[params]Block Begin >>]]Append["\""], lines]] ]
708 }
709 }
710
711 Parse Import[string,params,tree,lines:out]
712 {
713 [line]Slice[ [[params]Import >>]Length ] {}
714 {
715 filename <- Trim[~, " \n\r\t"]
716 }
717 new tree <- [tree]Imports <<[ [[tree]Imports >>]Set[filename, Yes] ]
718 ,line <- [string]Get Comment DString["\n", params]
719 {
720 out <- Null[~, params, new tree, [lines] + [1]]
721 } {} {
722 out <- Val[new tree]
723 }
724 }
725
726 Get Expression Blocks[string,params,blocks:blocks,after]
727 {
728 check block <- Comment Left Trim[string, "\n\r\t ", params]
729 If[[check block]Starts With[[params]Block Begin >>]]
730 {
731 ,begin block <- [check block]Slice[[[params]Block Begin >>]Length]
732 trees, after block <- Worker Body[begin block, params, New@List[]]
733 blocks, after <- Get Expression Blocks[after block, params, [blocks]Append[trees]]
734 }{
735 If[[check block]Starts With[[params]Empty Block >>]]
736 {
737 blocks <- blocks
738 ,after <- [check block]Slice[[[params]Empty Block >>]Length]
739 }{
740 blocks <- blocks
741 after <- Val[check block]
742 }
743 }
744 }
745
746 Parse Escape[string,params:char,after]
747 {
748 code,rest <- [string]Slice[1]
749 If[[code] = [[params]Hex Escape >>]]
750 {
751 hex,after <- [rest]Slice[2]
752 char <- [""]Put Byte[From Hex@Whole Number[hex]]
753 }{
754 after <- Val[rest]
755 char <- [[params]Escape Map >>]Index[code] {}
756 {
757 char <- Val[code]
758 }
759 }
760 }
761
762 Parse String[string,params,current:value,after]
763 {
764 delims <- [[New@List[]]Append[[params]String End >>]]Append[[params]String Escape >>]
765 after, before, delim <- [string]Get Comment DString[delims, params]
766 {
767 If[[delim] = [[params]String End >>]]
768 {
769 value <- [current]Append[before]
770 after <- Val[after]
771 }{
772 char,after escape <- Parse Escape[after, params]
773 value,after <- Parse String[after escape, params, [[current]Append[before]]Append[char]]
774 }
775 }
776 }
777
778 Parse List[string,params,list:value,after]
779 {
780 trimmed <- Comment Left Trim[string, "\r\n\t ", params]
781 If[[trimmed]Starts With[[params]List End >>]]
782 {
783 value <- list
784 ,after <- [trimmed]Slice[[[params]List End >>]Length]
785 }{
786 If[[trimmed]Starts With[[params]List Delim >>]]
787 {
788 ,el string <- [trimmed]Slice[[[params]List Delim >>]Length]
789 }{
790 el string <- Val[trimmed]
791 }
792 element,after el <- Named Pipe or Literal[el string, params]
793 value,after <- Parse List[after el, params, [list]Append[[element]Get Value]]
794 }
795 }
796
797 Get Value@Literal Node[node:out]
798 {
799 out <- [node]Value >>
800 }
801
802 Get Value@Named Pipe Node[node:out]
803 {
804 out <- node
805 }
806
807 Parse Number[string,params:value,after]
808 {
809 delims <- [[[[(" ","\t","\n","\r")]Append[[params]List Delim >>]]Append[[params]Block Begin >>]]Append[[params]Arg End >>]]Append[[params]List End >>]
810 after delim,valstring <- [string]Get Comment DString[delims, params] {} {}
811 {
812 after <- [~]Append[after delim]
813 }{
814 after <- ""
815 }
816 first two,rest <- [valstring]Slice[2]
817 If[[first two] = ["0x"]]
818 {
819 value <- From Hex@Whole Number[rest]
820 }{
821 If[[valstring]Contains["."]]
822 {
823 value <- <String@Real Number[valstring]
824 }{
825 value <- <String@Whole Number[valstring]
826 }
827 }
828 }
829
830 Named Pipe or Literal[string,params:out,after]
831 {
832 name <- Comment Left Trim[string, "\n\r\t ", params]
833 If[[name]Starts With[[params]String Begin >>]]
834 {
835 ,string begin <- [name]Slice[[[params]String Begin >>]Length]
836 value,after <- Parse String[string begin, params, ""]
837 }{
838 If[[name]Starts With[[params]List Begin >>]]
839 {
840 ,list start <- [name]Slice[[[params]List Begin >>]Length]
841 value,after <- Parse List[list start, params, New@List[]]
842 }{
843 If[[[name]Slice[1]]In["-0123456789"]]
844 {
845 value,after <- Parse Number[name, params]
846 }{
847 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 >>]
848 afterdelim,raw before,delim <- [name]Get Comment DString[delims, params]
849 {
850 after <- [delim]Append[~]
851 } {} {} {
852 after <- ""
853 }
854 before <- Trim[raw before, "\r\n\t "]
855 If[[before] = ["Yes"]]
856 {
857 yesno <- Yes
858 }{
859 If[[before] = ["No"]]
860 {
861 yesno <- No
862 }{
863 If[[before] = [""]]
864 {
865 Print[[["Found "]Append[delim]]Append[" where a named pipe or literal was expected"]]
866 { Print[["Near: "]Append[ [afterdelim]Slice[40]]] }
867 }{
868 If[[before]Contains[[params]Global Separator >>]]
869 {
870 parts <- [before]Split[[params]Global Separator >>]
871 out <- New@Global Node[Right Trim[[parts]Index[0],"\r\n\t "], Trim[[parts]Index[1], "\r\n\t "]]
872 }{
873 out <- New@Named Pipe Node[Right Trim[before,"\r\n\t "]]
874 }
875 }
876 }
877 }
878 out <- New@Literal Node[yesno]
879 }
880 }
881 }
882 out <- New@Literal Node[value]
883 }
884
885 Parse Arguments[string,params,arglist:args,after]
886 {
887 args <- Comment Left Trim[string, "\r\n\t ", params]
888 If[[args]Starts With[[params]List Delim >>]]
889 {
890 [args]Slice[[[params]List Delim >>]Length] {}
891 {
892 final args <- Comment Left Trim[~, "\r\n\t ", params]
893 }
894 }{
895 If[[args]Starts With[[params]Arg End >>]]
896 {
897 args <- arglist
898 ,after <- [args]Slice[[[params]Arg End >>]Length]
899 }{
900 final args <- Val[args]
901 }
902 }
903 arg, after arg <- Parse Expression[final args, params]
904 args, after <- Parse Arguments[after arg, params, [arglist]Append[arg]]
905 }
906
907 Worker or Field[name,args,params:out]
908 {
909 get field <- [params]Get Field >>
910 If[[name]Ends With[get field]]
911 {
912 field <- Right Trim[[name]Slice[[[name]Length] - [[get field]Length]], "\n\r\t "]
913 out <- New@Field Node[field, args, No]
914 }{
915 set field <- [params]Set Field >>
916 If[[name]Ends With[set field]]
917 {
918 field <- Right Trim[[name]Slice[[[name]Length] - [[set field]Length]], "\n\r\t "]
919 out <- New@Field Node[field, args, Yes]
920 }{
921 out <- New@Worker Node[name, args]
922 }
923 }
924 }
925
926 Prefix[string,params,name,existing args:expression,after]
927 {
928 //Parse argument list
929 more args,after <- Parse Arguments[string, params, existing args]
930 expression <- Worker or Field[name, more args, params]
931 }
932
933 Postfix or Infix[string,params:expression,after]
934 {
935 args, after args <- Parse Arguments[string, params, New@List[]]
936 delims <- [[[[[("\n")]Append[[params]Arg Begin >>]]Append[[params]Empty Block >>]]Append[[params]Block Begin >>]]Append[[params]Arg End >>]]Append[[params]List Delim >>]
937 after,before,delim <- [after args]Get Comment DString[delims, params]
938 {
939 If[[delim] = [[params]Arg Begin >>]]
940 {
941 expression, after <- Prefix[after, params, Trim[before,"\r\n\t "], args]
942 }{
943 If[[delim] = [[params]Empty Block >>]]
944 {
945 after expression <- Val[after]
946 }{
947 ,after expression <- [after args]Slice[[before]Length]
948 }
949 expression <- Worker or Field[Trim[before,"\r\n\t "], args, params]
950 }
951 }
952 }
953
954 Parse Expression[trimmed,params:final expression,after blocks]
955 {
956 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 >>]
957 after, before, delim <- [trimmed]Get Comment DString[delims, params]
958 {
959 //If we find an arg begin token, we have a worker expression
960 If[[delim] = [[params]Arg Begin >>]]
961 {
962 maybe name <- Right Trim[before, "\r\t "]
963 //Prefix expressions will have the worker name before the first arg begin token
964 If[[maybe name] = [""]]
965 {
966 expression, after expression <- Postfix or Infix[after, params]
967 }{
968 If[[maybe name]Contains[[params]List Delim >>]]
969 {
970 after expression <- [after literal]Append[[delim]Append[after]]
971 expression, after literal <- Named Pipe or Literal[Right Trim[before, "\r\n\t "], params]
972 }{
973 expression, after expression <- Prefix[after, params, maybe name, New@List[]]
974 }
975 }
976 }{
977 If[[delim] = [[params]Assign >>]]
978 {
979 //Expressions starting with an assignment can be prefix, postfix or infix
980 //or they can be a simple literal or named pipe
981 assignments <- Map[[before]Split[[params]List Delim >>], ["Trim"]Set Input[1,"\n\r\t "]]
982 ,after blocks <- Parse Expression[Comment Left Trim[after, " \n\r\t", params], params]
983 {
984 final expression <- [~]Assignments <<[assignments]
985 }
986 }{
987 //If[[delim] = [[params]String Begin >>]]
988 //{
989 // If[[Trim[before, "\r\n\t "]] = [""]]
990 // {
991 // expression, after expression <- Named Pipe or Literal[[delim]Append[after], params]
992 // }{
993 // after expression <- [after literal]Append[[delim]Append[after]]
994 // expression, after literal <- Named Pipe or Literal[Right Trim[before, "\r\n\t "], params]
995 // }
996 //}{
997 // after expression <- [after literal]Append[[delim]Append[after]]
998 // expression, after literal <- Named Pipe or Literal[Right Trim[before, "\r\n\t "], params]
999 //}
1000 expression, after expression <- Named Pipe or Literal[trimmed, params]
1001 }
1002 }
1003 //Any expression can be followed by one or more blocks mapping the inputs of other expressions
1004 //to the outputs of the current one
1005 blocks,after blocks <- Get Expression Blocks[after expression, params, New@List[]]
1006 final expression <- [expression]Blocks <<[blocks]
1007 }
1008 }
1009
1010 Worker Body[string,params,trees:trees,after end]
1011 {
1012 trimmed <- Comment Left Trim[string, "\n\r\t ", params]
1013 If[[trimmed]Starts With[[params]Block End >>]]
1014 {
1015 //We're done with this block, return
1016 ,after end <- [trimmed]Slice[[[params]Block End >>]Length]
1017 trees <- trees
1018 }{
1019 expression, after expression <- Parse Expression[trimmed, params]
1020 trees,after end <- Worker Body[after expression, params, [trees]Append[expression]]
1021 }
1022 }
1023
1024 Process Modifiers[worker,params,modifiers:out]
1025 {
1026 //Eventually this will need to be more sophisticated to handle more modifiers
1027 trimmed <- Comment Left Trim[modifiers, "\n\r\t ", params]
1028 If[[trimmed]Starts With[[params]Uses >>]]
1029 {
1030 ,after uses <- [trimmed]Slice[[[params]Uses >>]Length]
1031 ,stores string <- [after uses]Get Comment DString["\n", params]
1032 out <- [worker]Uses Stores <<[Map[[stores string]Split[[params]List Delim >>], ["Trim"]Set Input[1, "\r\n\t "]]]
1033 }{
1034 out <- worker
1035 }
1036 }
1037
1038 Worker Name[string,params,tree,lines:out]
1039 {
1040 ,whitespace name <- [string]Get Comment DString[[params]Arg Begin >>, params]
1041 {
1042 worker name <- Trim[whitespace name, "\n\r\t "]
1043 in out <- [params]In Out Delim >>
1044 arg end <- [params]Arg End >>
1045 delims <- [[New@List[]]Append[in out]]Append[arg end]
1046 after <- [~]Get Comment DString[delims, params] {}
1047 {
1048 arglist <- Trim[~,"\r\n\t "]
1049 }{
1050 //check if there is an in/out separator
1051 //if it isn't present, everything in the arglist is an input
1052 If[[~] = [in out]]
1053 {
1054 after arglist <- [after]Get Comment DString[arg end, params] {}
1055 {
1056 output string <- Trim[~,"\n\r\t "]
1057 }
1058 }{
1059 after arglist <- Val[after]
1060 output string <- ""
1061 }
1062 inputs <- Map[[arglist]Split[[params]List Delim >>], ["Trim"]Set Input[1,"\n\r\t "]]
1063 outputs <- Map[[output string]Split[[params]List Delim >>], ["Trim"]Set Input[1,"\n\r\t "]]
1064
1065 New@Parse Worker[worker name, inputs, outputs, 0]
1066 {
1067 body text, modifiers <- [after arglist]Get Comment DString[[params]Block Begin >>, params]
1068 modified <- Process Modifiers[~, params, modifiers]
1069 expression trees, after body <- Worker Body[body text, params, New@List[]]
1070 worker <- [modified]Trees <<[expression trees]
1071 new worker dict <- [[tree]Workers >>]Set[worker name, worker]
1072 out <- Null[after body, params, [tree]Workers <<[new worker dict], 0]
1073 }
1074 }
1075 }{}{}{
1076 out <- tree
1077 }
1078 }
1079
1080 Null[string,params,tree,lines:out]
1081 {
1082 trimmed <- Comment Left Trim[string, " \n\r\t", params]
1083 current line <- 0//[lines] + [Count Substring[whitespace, "\n"]]
1084 If[[trimmed]Starts With[ [params]Blueprint >> ]]
1085 {
1086 out <- Blueprint[trimmed, params, tree, current line]
1087 }{
1088 If[[trimmed]Starts With[ [params]Import >> ]]
1089 {
1090 out <- Parse Import[trimmed, params, tree, current line]
1091 }{
1092 out <- Worker Name[trimmed, params, tree, current line]
1093 }
1094 }
1095 }
1096
1097 Add Workers[worker,name,program:out]
1098 {
1099 prog,worker <- [program]New Worker[name]
1100 [worker]Set IO Counts[ [[[worker]Index[name]]Inputs >>]Length, [[[worker]Index[name]]Outputs >>]Length]
1101 [workers]Next[name]
1102 {
1103 out <- Add Workers[workers, ~, prog]
1104 }{
1105 out <- Val[prog]
1106 }
1107 }
1108
1109 Add Wires Helper[worker,node,unused,parse worker,assignments:out]
1110 {
1111 out <- [node]Add Wires[worker, New@List[], parse worker, assignments]
1112 }
1113
1114 Add Contents[parse worker,name,program:out,key]
1115 {
1116 worker <- [[program]Find Worker[name]]Uses[[parse worker]Uses Stores >>]
1117 trees, contents worker, refs <- Add List to Worker[[parse worker]Trees >>, worker, program, parse worker, New@Dictionary[]]
1118 Fold[[["Add Wires Helper"]Set Input[3, parse worker]]Set Input[4, refs], contents worker, trees]
1119 out <- [parse worker]Trees <<[trees]
1120 key <- name
1121 }
1122
1123 Add Blueprint Field[blueprint,field,unused:out]
1124 {
1125 out <- [blueprint]Add Field[[field]Name >>, [field]Type >>]
1126 }
1127
1128 Add Blueprint[prog,def:out]
1129 {
1130 out <- [prog]New Blueprint[[def]Name >>] {}
1131 {
1132 Fold["Add Blueprint Field", ~, [def]Fields >>]
1133 }
1134 }
1135
1136 _Tree to Program[parse tree,program:out]
1137 {
1138 after blueprint <- Fold["Add Blueprint", program, [parse tree]Blueprints >>]
1139 [[parse tree]Workers >>]First
1140 {
1141 prog <- Add Workers[[parse tree]Workers >>, ~, after blueprint]
1142 }
1143 Key Value Map[[parse tree]Workers >>, ["Add Contents"]Set Input[2, prog]]
1144 out <- prog
1145 }
1146
1147 Tree to Program[parse tree:out]
1148 {
1149 out <- _Tree to Program[parse tree, [New@Program[]]Add Builtins]
1150 }
1151
1152 Needs Imports[needs import,not imported?,name:out]
1153 {
1154 If[not imported?]
1155 {
1156 out <- [needs import]Append[name]
1157 }{
1158 out <- needs import
1159 }
1160 }
1161
1162 Do Import[tree,file name,unused,params:out]
1163 {
1164 file <- <String@File[file name]
1165 ,text <- [file]Get FString[[file]Length]
1166 after import <- Null[text, params, tree, 0]
1167 out <- [after import]Imports <<[ [[after import]Imports >>]Set[file name, No] ]
1168 }
1169
1170 Process Imports[parse tree,params:out]
1171 {
1172 needs import <- Fold["Needs Imports", New@List[], [parse tree]Imports >>]
1173 If[[[needs import]Length] > [0]]
1174 {
1175 import tree <- Fold[["Do Import"]Set Input[3, params], parse tree, needs import]
1176 out <- Process Imports[import tree, params]
1177 }{
1178 out <- parse tree
1179 }
1180 }
1181
1182 _Init Used Store[dict,store name:out]
1183 {
1184 [dict]Index[store name]
1185 {
1186 out <- dict
1187 }{
1188 Init Store[store name]
1189 out <- [dict]Set[store name, Yes]
1190 }
1191 }
1192
1193 _Init Used Stores[dict,worker:out]
1194 {
1195 out <- Fold["_Init Used Store", dict, [worker]Uses Stores >>]
1196 }
1197
1198 Init Used Stores[parse tree,existing stores:out]
1199 {
1200 out <- Fold["_Init Used Stores", existing stores, [parse tree]Workers >>]
1201 }
1202
1203 Until End[text:out]
1204 {
1205 line <- Get Input[]
1206 If[[line] = ["End"]]
1207 {
1208 out <- [text]Append["\n"]
1209 }{
1210 out <- Until End[[[text]Append["\n"]]Append[line]]
1211 }
1212 }
1213
1214 _REPL[params,prog,stores]
1215 {
1216 line <- Get Input[]
1217 If[[line] = ["Begin"]]
1218 {
1219 text <- Until End[""]
1220 Null[text, params, New@Parse Program[], 0]
1221 {
1222 define tree <- Process Imports[~, params]
1223 Init Used Stores[define tree, stores]
1224 { _REPL[params, _Tree to Program[define tree, prog], ~] }
1225 }
1226 }{
1227 If[[line]Starts With[[params]Import >>]]
1228 {
1229 Parse Import[[line]Append["\n"], params, New@Parse Program[], 0]
1230 {
1231 import tree <- Process Imports[~, params]
1232 Init Used Stores[import tree, stores]
1233 { _REPL[params, _Tree to Program[import tree, prog], ~] }
1234 }
1235 }{
1236 trees <- Worker Body[[line]Append["}"], params, New@List[]]
1237 tree <- [New@Worker Node["Val", [New@List[]]Append[[trees]Index[0]]]]Assignments <<[("__out")]
1238 this stores <- [[tree]Gather Stores[params, New@Dictionary[]]]Keys
1239 next stores <- Fold["_Init Used Store", stores, this stores]
1240 {
1241 pworker <- [[New@Parse Worker["__Eval", New@List[], ("__out"), 0]]Trees <<[[New@List[]]Append[tree]]]Uses Stores <<[this stores]
1242 }
1243 [[prog]Find Worker["__Eval"]]Clear
1244 { Add Contents[pworker, "__Eval", prog]
1245 { Pretty Print[[[[prog]Find Worker["__Eval"]]Do[New@List[]]]Index[0], ""]
1246 { _REPL[params, prog, next stores] } } }
1247 }
1248 }
1249 }
1250
1251 REPL[params]
1252 {
1253 Print["Rhope Alpha 2\nCopyright 2008 by Michael Pavone\nEntering interactive mode\n"]
1254 prog <- Tree to Program[Null["Val[in:out]\n{\n out <- in\n}\n__Eval[:__out]\n{\n}\n", params, New@Parse Program[], 0]]
1255 _REPL[params, prog, New@Dictionary[]]
1256 }
1257
1258 Add If Store[stores,name,params:out]
1259 {
1260 If[[name]Contains[[params]Global Separator >>]]
1261 {
1262 parts <- [name]Split[[params]Global Separator >>]
1263 out <- [stores]Set[[parts]Index[0], Yes]
1264 }{
1265 out <- stores
1266 }
1267 }
1268
1269 Param Gather Stores[stores,node,params:out]
1270 {
1271 out <- [node]Gather Stores[params, stores]
1272 }
1273
1274 Gather Stores@Named Pipe Node[node,params,stores:out]
1275 {
1276 out <- Fold[["Add If Store"]Set Input[2, params], stores, [node]Assignments >>]
1277 }
1278
1279 Gather Stores@Global Node[node,params,stores:out]
1280 {
1281 out <- [stores]Set[[node]Store >>, Yes]
1282 }
1283
1284 Gather Stores@Worker Node[node,params,stores:out]
1285 {
1286 //TODO: Handle blocks
1287 store list <- Fold[["Param Gather Stores"]Set Input[2, params], stores, [node]Params >>]
1288 out <- Fold[["Add If Store"]Set Input[2, params], store list, [node]Assignments >>]
1289 }
1290
1291 Gather Stores@Field Node[node,params,stores:out]
1292 {
1293 //TODO: Handle blocks
1294 store list <- Fold[["Param Gather Stores"]Set Input[2, params], stores, [node]Params >>]
1295 out <- Fold[["Add If Store"]Set Input[2, params], store list, [node]Assignments >>]
1296 }
1297
1298 Gather Stores@Literal Node[node,params,stores:out]
1299 {
1300 out <- Fold[["Add If Store"]Set Input[2, params], stores, [node]Assignments >>]
1301 }
1302
1303
1304 Main[args]
1305 {
1306 [args]Index[1]
1307 {
1308 file <- <String@File[~]
1309 ,text <- [file]Get FString[[file]Length]
1310 params <- New@Parser[]
1311 Null[text, params, New@Parse Program[], 0]
1312 {
1313 tree <- Process Imports[~, params]
1314 Init Used Stores[tree, New@Dictionary[]]
1315 { [Tree to Program[tree]]Run[[args]Tail[1]] }
1316 }
1317 }{
1318 REPL[New@Parser[]]
1319 }
1320 }