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