checkpoint
[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 /**
14  *  @author Adam Megacz <megacz@cs.berkeley.edu>
15  *  @author Thomas Kho <tkho@eecs.berkeley.edu>
16  */
17 public class FleetParser {
18
19     public static boolean dump_fabric = false;
20     public static boolean dump_code = false;
21
22     public static void main(String[] s) throws Exception {
23         for(int i=0; i<s.length; i++) {
24             if (s[i].startsWith("--color=")) {
25                 String val = s[i].substring(s[i].indexOf('=')+1);
26                 if (val.equals("on")) {
27                     Log.ansi_color = true;
28                     continue;
29                 } else if (val.equals("off")) {
30                     Log.ansi_color = false;
31                     continue;
32                 }
33             } else if (s[i].startsWith("--dump-fabric")) {
34                 dump_fabric = true;
35                 continue;
36             } else if (s[i].startsWith("--dump-code")) {
37                 dump_code = true;
38                 continue;
39
40             } else if (s[i].startsWith("--inboxes=")) {
41                 String val = s[i].substring(s[i].indexOf('=')+1);
42                 if (val.equals("configured")) {
43                     DataInbox.defaultInstruction =
44                         new Instruction(null, null, Integer.MAX_VALUE, TAKE, false, false, true);
45                     continue;
46                 } else if (val.equals("unconfigured")) {
47                     DataInbox.defaultInstruction = null;
48                     continue;
49                 }
50             } else if (s[i].startsWith("--memory=")) {
51                 String val = s[i].substring(s[i].indexOf('=')+1);
52                 if (val.equals("hide")) {
53                     debugMemory = false;
54                     continue;
55                 } else if (val.equals("show")) {
56                     debugMemory = true;
57                     continue;
58                 }
59             }
60             System.out.println("Fleeterpreter usage:");
61             System.out.println("");
62             System.out.println("  --dump-fabric");
63             System.out.println("  --dump-code");
64             System.out.println("  --color={on|off}");
65             System.out.println("  --inboxes={configured|unconfigured}");
66             System.out.println("  --memory={hide|show}");
67             System.exit(-1);
68         }
69         go(new InputStreamReader(System.in));
70     }
71
72     public static void go(Reader r) throws Exception {
73         Fleet fleet = new Fleet();
74         FleetParser fp = new FleetParser(fleet);
75         fp.walk((Tree<String>)parse(r));
76         fp.done();
77     }
78
79     public static Tree<String> parse(Reader r) throws Exception {
80         InputStream grammarStream =
81             FleetParser.class.getClassLoader().getResourceAsStream("fleet.g");
82         Parser metaGrammarParser   = new CharParser(MetaGrammar.newInstance());
83         Tree<String> parsedGrammar = metaGrammarParser.parse(new CharInput(grammarStream)).expand1();
84         Union   grammar            = Grammar.create(parsedGrammar, "s", new Grammar.Bindings() { });
85         Parser  parser             = new CharParser(grammar);
86         Tree tree = parser.parse(new CharInput(r)).expand1();
87         return tree;
88     }
89
90     private Fleet fleet;
91     private ArrayList<String> imports = new ArrayList<String>();
92     private CodeBag rootCodeBag;
93     private static boolean debugMemory = true;
94
95     public FleetParser(Fleet fleet) {
96         this.fleet = fleet;
97     }
98
99     public void done() {
100         if (dump_fabric) {
101             fleet.dumpFabric(false);
102
103         } else if (dump_code) {
104             fleet.dumpFabric(true);
105             try {
106                 rootCodeBag.dump(fleet);
107             } catch (Exception e) { throw new RuntimeException(e); }
108
109         } else if (rootCodeBag != null) {
110             if (debugMemory) { fleet.dumpMem(); }
111             System.out.println(rootCodeBag);
112             rootCodeBag.dispatch(fleet);
113             fleet.go();
114             if (debugMemory) { fleet.dumpMem(); }
115         }
116     }
117
118     public void walk(Tree<String> t) {
119         String head = t.head();
120         if (head==null) {
121         } else if (head.equals("Program")) {
122             for(Tree<String> tc : t.child(0))
123                 walk(tc);
124             CodeBag cb = new CodeBag(null, null);
125             if (t.size()>1)
126                 for(Tree<String> statement : t.child(1))
127                     fillCodeBag(statement, cb);
128             rootCodeBag = cb;
129    
130         } else if (head.equals("Import")) {
131             imports.add(string(t.child(0)));
132
133         } else if (head.equals("Ship")) {
134             String name = name(t.child(0));
135             String classname = string(t.child(1));
136             boolean good = false;
137             for(String s : imports)
138                 if (fleet.tryCreate(s+"."+classname, name)) {
139                     good = true;
140                     break;
141                 }
142             if (!good)
143                 throw new RuntimeException("couldn't find a ship called \""+classname+"\"");
144
145         } else if (head.equals("Include")) {
146             try {
147                 walk(parse(new InputStreamReader(new FileInputStream(string(t.child(0))))));
148             } catch (Exception e) {
149                 throw new RuntimeException(e);
150             }
151             
152         } else if (head.equals("Memory")) {
153             if (fleet.mem.length != 0)
154                 throw new RuntimeException("multiple memory directives found");
155             Tree<String> m = t.child(0);
156             int[] mem = new int[m.size()];
157             for(int i=0; i<mem.length; i++)
158                 mem[i] = Integer.parseInt(string(m.child(i)));
159             fleet.mem = mem;
160         }
161     }
162
163     public String string(Tree<String> t) {
164         String ret = "";
165         if (t.head() != null) ret += t.head();
166         for(Tree<String> c : t)
167             ret += string(c);
168         return ret;
169     }
170
171     public String name(Tree<String> t) {
172         return string(t.child(0))+string(t.child(1));
173     }
174
175     public PortReference portReference(Tree<String> t) {
176         if (!"Port".equals(t.head())) return null;
177         return new PortReference(name(t.child(0)), name(t.child(1)));
178     }
179
180     public void fillCodeBag(Tree<String> t, CodeBag cb) {
181         if (t.head()==null) return;
182         else if (t.head().equals("NamedCodeBag")) {
183             CodeBag cb2 = new CodeBag(cb, name(t.child(0)));
184             for(Tree<String> statement : t.child(1))
185                 fillCodeBag(statement, cb2);
186
187         } else if (t.head().equals("Instruction")) {
188             Tree<String> opcode = t.child(0);
189             boolean trigger = opcode != null && opcode.size()>0 && "Triggered".equals(opcode.child(0).head());
190
191             int count = 0;
192             Tree arrow = t.child(2);
193             if      (arrow.head().equals("->"))     count = 1;
194             else if (arrow.head().equals("-[*]->")) count = Integer.MAX_VALUE;
195             else if (arrow.head().equals("-["))     count = Integer.parseInt(string(arrow.child(0)));
196
197             Tree opcodebody = opcode.size()==0 ? null : opcode.child(0).child(opcode.size()-1);
198             
199             PortReference d = portReference(t.child(3));
200             if (t.child(1).head() == null) {
201                 int literal = Integer.parseInt(string(t.child(1)));
202                 cb.add(new Literal.LiteralDatum(literal, d, false, count));
203
204             } else if ("AnonymousCodeBag".equals(t.child(1).head())) {
205                 CodeBag cb3 = new CodeBag(cb, null);
206                 for(Tree<String> tc : t.child(1).child(0))
207                     fillCodeBag(tc, cb3);
208                 cb.add(new Literal.LiteralDatum(cb3.getDescriptor(), d, true));
209
210             } else if ("CodeBagRef".equals(t.child(1).head())) {
211                 cb.add(new Literal.CodeBagRef(name(t.child(1).child(0)), cb, d));
212
213             } else if ("ShipSpecific".equals(t.child(1).head())) {
214                 cb.add(new Literal.ShipSpecific(string(t.child(1).child(0)), d, count));
215
216             } else {
217                 PortReference s = portReference(t.child(1));
218                 Instruction inst = null;
219                 if (opcodebody==null)         inst = new Instruction(s, d, count, TAKE,   false,  trigger, true);
220                 else if (opcodebody.head().equals("nop"))            inst = new Instruction(s, d, count, IGNORE, false,  trigger, false);
221                 else if (opcodebody.head().equals("synthesize"))     inst = new Instruction(s, d, count, IGNORE, false,  trigger, true);
222                 else if (opcodebody.head().equals("synthesize+ack")) inst = new Instruction(s, d, count, IGNORE, true,   trigger, true);
223                 else if (opcodebody.head().equals("wait"))           inst = new Instruction(s, d, count, COPY,   false,  trigger, false);
224                 else if (opcodebody.head().equals("discard"))        inst = new Instruction(s, d, count, TAKE,   false,  trigger, false);
225                 else if (opcodebody.head().equals("nop+ack"))        inst = new Instruction(s, d, count, IGNORE, true,   trigger, false);
226                 else if (opcodebody.head().equals("wait+ack"))       inst = new Instruction(s, d, count, COPY,   true,   trigger, false);
227                 else if (opcodebody.head().equals("discard+ack"))    inst = new Instruction(s, d, count, TAKE,   true,   trigger, false);
228                 else if (opcodebody.head().equals("copy"))           inst = new Instruction(s, d, count, COPY,   false,  trigger, true);
229                 else if (opcodebody.head().equals("copy+ack"))       inst = new Instruction(s, d, count, COPY,   true,   trigger, true);
230                 else if (opcodebody.head().equals("move"))           inst = new Instruction(s, d, count, TAKE,   false,  trigger, true);
231                 else if (opcodebody.head().equals("move+ack"))       inst = new Instruction(s, d, count, TAKE,   true,   trigger, true);
232                 else if (opcodebody.head().equals("accept"))         inst = new Instruction(s, d, count, TAKE,   false,  trigger, true);
233                 else if (opcodebody.head().equals("accept+ack"))     inst = new Instruction(s, d, count, TAKE,   true,   trigger, true);
234                 cb.add(inst);
235             }
236         }
237     }
238
239 }