added am10 inbox/outbox support
[fleet.git] / src / edu / berkeley / fleet / FleetParser.java
1 package edu.berkeley.fleet;
2
3 import edu.berkeley.sbp.*;
4 import edu.berkeley.sbp.chr.*;
5 import edu.berkeley.sbp.misc.*;
6 import edu.berkeley.sbp.meta.*;
7 import edu.berkeley.sbp.bind.*;
8 import edu.berkeley.sbp.util.*;
9 import java.util.*;
10 import java.io.*;
11 import static edu.berkeley.fleet.Instruction.IgnoreCopyTake.*;
12
13 public class FleetParser {
14
15     public static void main(String[] s) throws Exception {
16         go(new InputStreamReader(System.in));
17     }
18
19     public static void go(Reader r) throws Exception {
20         InputStream grammarStream =
21             FleetParser.class.getClassLoader().getResourceAsStream("fleet.g");
22
23         Parser metaGrammarParser   = new CharParser(MetaGrammar.newInstance());
24         Tree<String> parsedGrammar = metaGrammarParser.parse(new CharInput(grammarStream)).expand1();
25         Union   grammar            = Grammar.create(parsedGrammar, "s",
26                                                     new Grammar.Bindings() { });
27         Parser  parser             = new CharParser(grammar);
28         Tree tree = parser.parse(new CharInput(r)).expand1();
29         //System.out.println(tree);
30         Fleet fleet = new Fleet();
31         FleetParser fp = new FleetParser(fleet);
32         fp.walk((Tree<String>)tree);
33         fp.done();
34     }
35
36     private Fleet fleet;
37     private ArrayList<String> imports = new ArrayList<String>();
38     private CodeBag rootCodeBag;
39
40     public FleetParser(Fleet fleet) {
41         this.fleet = fleet;
42     }
43
44     public void done() {
45         if (rootCodeBag != null) {
46             rootCodeBag.dispatch(fleet);
47             fleet.go();
48         }
49     }
50
51     public void walk(Tree<String> t) {
52         String head = t.head();
53         if (head==null) {
54         } else if (head.equals("Program")) {
55             for(Tree<String> tc : t.child(0))
56                 walk(tc);
57             CodeBag cb = new CodeBag(null, null);
58             for(Tree<String> statement : t.child(1))
59                 fillCodeBag(statement, cb);
60             System.out.println(cb);
61             rootCodeBag = cb;
62    
63         } else if (head.equals("Import")) {
64             imports.add(string(t.child(0)));
65
66         } else if (head.equals("Ship")) {
67             String name = name(t.child(0));
68             String classname = string(t.child(1));
69             boolean good = false;
70             for(String s : imports)
71                 if (fleet.tryCreate(s+"."+classname, name)) {
72                     good = true;
73                     break;
74                 }
75             if (!good)
76                 throw new RuntimeException("couldn't find a ship called \""+classname+"\"");
77         }
78     }
79
80     public String string(Tree<String> t) {
81         String ret = "";
82         if (t.head() != null) ret += t.head();
83         for(Tree<String> c : t)
84             ret += string(c);
85         return ret;
86     }
87
88     public String name(Tree<String> t) {
89         return string(t.child(0))+string(t.child(1));
90     }
91
92     public PortReference portReference(Tree<String> t) {
93         if (!"Port".equals(t.head())) return null;
94         return new PortReference(name(t.child(0)), name(t.child(1)));
95     }
96
97     public void fillCodeBag(Tree<String> t, CodeBag cb) {
98         if (t.head()==null) return;
99         else if (t.head().equals("NamedCodeBag")) {
100             CodeBag cb2 = new CodeBag(cb, name(t.child(0)));
101             for(Tree<String> statement : t.child(1))
102                 fillCodeBag(statement, cb2);
103
104         } else if (t.head().equals("Instruction")) {
105             Tree<String> opcode = t.child(0);
106             boolean trigger = opcode != null && opcode.size()>0 && "Triggered".equals(opcode.child(0).head());
107
108             int count = 0;
109             Tree arrow = t.child(2);
110             if      (arrow.head().equals("->"))     count = 1;
111             else if (arrow.head().equals("-[*]->")) count = Integer.MAX_VALUE;
112             else if (arrow.head().equals("-["))     count = Integer.parseInt(string(arrow.child(0)));
113
114             Tree opcodebody = opcode.size()==0 ? null : opcode.child(0).child(opcode.size()-1);
115             
116             PortReference d = portReference(t.child(3));
117             if (t.child(1).head() == null) {
118                 int literal = Integer.parseInt(string(t.child(1)));
119                 cb.add(new Literal.LiteralDatum(literal, d, false));
120
121             } else if ("AnonymousCodeBag".equals(t.child(1).head())) {
122                 CodeBag cb3 = new CodeBag(cb, null);
123                 for(Tree<String> tc : t.child(1).child(0))
124                     fillCodeBag(tc, cb3);
125                 cb.add(new Literal.LiteralDatum(cb3.getDescriptor(), d, true));
126
127             } else if ("CodeBagRef".equals(t.child(1).head())) {
128                 cb.add(new Literal.CodeBagRef(name(t.child(1).child(0)), cb, d));
129
130             } else {
131                 PortReference s = portReference(t.child(1));
132                 Instruction inst = null;
133                 if (opcodebody==null)         inst = new Instruction(s, d, count, TAKE,   false,  trigger, true);
134                 else if (opcodebody.head().equals("nop"))          inst = new Instruction(s, d, count, IGNORE, false,  trigger, false);
135                 else if (opcodebody.head().equals("wait"))         inst = new Instruction(s, d, count, COPY,   false,  trigger, false);
136                 else if (opcodebody.head().equals("discard"))      inst = new Instruction(s, d, count, TAKE,   false,  trigger, false);
137                 else if (opcodebody.head().equals("nop+ack"))      inst = new Instruction(s, d, count, IGNORE, true,   trigger, false);
138                 else if (opcodebody.head().equals("wait+ack"))     inst = new Instruction(s, d, count, COPY,   true,   trigger, false);
139                 else if (opcodebody.head().equals("discard+ack"))  inst = new Instruction(s, d, count, TAKE,   true,   trigger, false);
140                 else if (opcodebody.head().equals("copy"))         inst = new Instruction(s, d, count, COPY,   false,  trigger, true);
141                 else if (opcodebody.head().equals("copy+ack"))     inst = new Instruction(s, d, count, COPY,   true,   trigger, true);
142                 else if (opcodebody.head().equals("move"))         inst = new Instruction(s, d, count, TAKE,   false,  trigger, true);
143                 else if (opcodebody.head().equals("move+ack"))     inst = new Instruction(s, d, count, TAKE,   true,   trigger, true);
144                 else if (opcodebody.head().equals("accept"))         inst = new Instruction(s, d, count, TAKE,   false,  trigger, true);
145                 else if (opcodebody.head().equals("accept+ack"))     inst = new Instruction(s, d, count, TAKE,   true,   trigger, true);
146                 cb.add(inst);
147             }
148         }
149     }
150
151 }