import edu.berkeley.sbp.util.*;
import java.util.*;
import java.io.*;
+import static edu.berkeley.fleet.Instruction.IgnoreCopyTake.*;
+/**
+ * @author Adam Megacz <megacz@cs.berkeley.edu>
+ * @author Thomas Kho <tkho@eecs.berkeley.edu>
+ */
public class FleetParser {
public static void main(String[] s) throws Exception {
+ for(int i=0; i<s.length; i++) {
+ if (s[i].startsWith("--color=")) {
+ String val = s[i].substring(s[i].indexOf('=')+1);
+ if (val.equals("on")) {
+ Log.ansi_color = true;
+ continue;
+ } else if (val.equals("off")) {
+ Log.ansi_color = false;
+ continue;
+ }
+ } else if (s[i].startsWith("--inboxes=")) {
+ String val = s[i].substring(s[i].indexOf('=')+1);
+ if (val.equals("configured")) {
+ DataInbox.defaultInstruction =
+ new Instruction(null, null, Integer.MAX_VALUE, TAKE, false, false, true);
+ continue;
+ } else if (val.equals("unconfigured")) {
+ DataInbox.defaultInstruction = null;
+ continue;
+ }
+ } else if (s[i].startsWith("--memory=")) {
+ String val = s[i].substring(s[i].indexOf('=')+1);
+ if (val.equals("hide")) {
+ debugMemory = false;
+ continue;
+ } else if (val.equals("show")) {
+ debugMemory = true;
+ continue;
+ }
+ }
+ System.out.println("Fleeterpreter usage:");
+ System.out.println("");
+ System.out.println(" --color={on|off}");
+ System.out.println(" --inboxes={configured|unconfigured}");
+ System.out.println(" --memory={hide|show}");
+ System.exit(-1);
+ }
go(new InputStreamReader(System.in));
}
public static void go(Reader r) throws Exception {
+ Fleet fleet = new Fleet();
+ FleetParser fp = new FleetParser(fleet);
+ fp.walk((Tree<String>)parse(r));
+ fp.done();
+ }
+
+ public static Tree<String> parse(Reader r) throws Exception {
InputStream grammarStream =
FleetParser.class.getClassLoader().getResourceAsStream("fleet.g");
-
Parser metaGrammarParser = new CharParser(MetaGrammar.newInstance());
Tree<String> parsedGrammar = metaGrammarParser.parse(new CharInput(grammarStream)).expand1();
- Grammar.Bindings gbr = new AnnotationGrammarBindings(Program.class);
- Union mathGrammar = Grammar.create(parsedGrammar, "s", gbr);
- Parser mathParser = new CharParser(mathGrammar);
+ Union grammar = Grammar.create(parsedGrammar, "s", new Grammar.Bindings() { });
+ Parser parser = new CharParser(grammar);
+ Tree tree = parser.parse(new CharInput(r)).expand1();
+ return tree;
+ }
- Log.println("about to parse: tests/test.fleet");
- Tree tree = mathParser.parse(new CharInput(r)).expand1();
+ private Fleet fleet;
+ private ArrayList<String> imports = new ArrayList<String>();
+ private CodeBag rootCodeBag;
+ private static boolean debugMemory = true;
- // below is ugly voodoo which will go away very soon. ignore it.
- TreeFunctor tf = (TreeFunctor)tree.head();
- Program program = (Program)tf.invoke(tree);
- // above is ugly voodoo which will go away very soon. ignore it.
+ public FleetParser(Fleet fleet) {
+ this.fleet = fleet;
+ }
- Log.println();
- Log.println("dispatching root codebag:");
- Log.println(program.root);
+ public void done() {
+ if (rootCodeBag != null) {
+ if (debugMemory) { fleet.dumpMem(); }
+ System.out.println(rootCodeBag);
+ rootCodeBag.dispatch(fleet);
+ fleet.go();
+ if (debugMemory) { fleet.dumpMem(); }
+ }
+ }
- Fleet fleet = new Fleet();
- program.configure(fleet);
-
- Log.println("memory before execution:");
- Log.print(" ");
- for(int i=0; i<fleet.mem.length; i++)
- Log.print(fleet.mem[i] + " ");
- Log.println();
-
- Log.println();
- Log.println("enabling execution...");
- fleet.go();
- Log.println("execution halted.");
-
- Log.println();
- Log.println("memory after execution:");
- Log.print(" ");
- for(int i=0; i<fleet.mem.length; i++)
- Log.print(fleet.mem[i] + " ");
- Log.println();
+ public void walk(Tree<String> t) {
+ String head = t.head();
+ if (head==null) {
+ } else if (head.equals("Program")) {
+ for(Tree<String> tc : t.child(0))
+ walk(tc);
+ CodeBag cb = new CodeBag(null, null);
+ if (t.size()>1)
+ for(Tree<String> statement : t.child(1))
+ fillCodeBag(statement, cb);
+ rootCodeBag = cb;
+
+ } else if (head.equals("Import")) {
+ imports.add(string(t.child(0)));
+
+ } else if (head.equals("Ship")) {
+ String name = name(t.child(0));
+ String classname = string(t.child(1));
+ boolean good = false;
+ for(String s : imports)
+ if (fleet.tryCreate(s+"."+classname, name)) {
+ good = true;
+ break;
+ }
+ if (!good)
+ throw new RuntimeException("couldn't find a ship called \""+classname+"\"");
+
+ } else if (head.equals("Include")) {
+ try {
+ walk(parse(new InputStreamReader(new FileInputStream(string(t.child(0))))));
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ } else if (head.equals("Memory")) {
+ if (fleet.mem.length != 0)
+ throw new RuntimeException("multiple memory directives found");
+ Tree<String> m = t.child(0);
+ int[] mem = new int[m.size()];
+ for(int i=0; i<mem.length; i++)
+ mem[i] = Integer.parseInt(string(m.child(i)));
+ fleet.mem = mem;
+ }
+ }
+
+ public String string(Tree<String> t) {
+ String ret = "";
+ if (t.head() != null) ret += t.head();
+ for(Tree<String> c : t)
+ ret += string(c);
+ return ret;
+ }
+
+ public String name(Tree<String> t) {
+ return string(t.child(0))+string(t.child(1));
+ }
+
+ public PortReference portReference(Tree<String> t) {
+ if (!"Port".equals(t.head())) return null;
+ return new PortReference(name(t.child(0)), name(t.child(1)));
+ }
+
+ public void fillCodeBag(Tree<String> t, CodeBag cb) {
+ if (t.head()==null) return;
+ else if (t.head().equals("NamedCodeBag")) {
+ CodeBag cb2 = new CodeBag(cb, name(t.child(0)));
+ for(Tree<String> statement : t.child(1))
+ fillCodeBag(statement, cb2);
+
+ } else if (t.head().equals("Instruction")) {
+ Tree<String> opcode = t.child(0);
+ boolean trigger = opcode != null && opcode.size()>0 && "Triggered".equals(opcode.child(0).head());
+
+ int count = 0;
+ Tree arrow = t.child(2);
+ if (arrow.head().equals("->")) count = 1;
+ else if (arrow.head().equals("-[*]->")) count = Integer.MAX_VALUE;
+ else if (arrow.head().equals("-[")) count = Integer.parseInt(string(arrow.child(0)));
+
+ Tree opcodebody = opcode.size()==0 ? null : opcode.child(0).child(opcode.size()-1);
+
+ PortReference d = portReference(t.child(3));
+ if (t.child(1).head() == null) {
+ int literal = Integer.parseInt(string(t.child(1)));
+ cb.add(new Literal.LiteralDatum(literal, d, false, count));
+
+ } else if ("AnonymousCodeBag".equals(t.child(1).head())) {
+ CodeBag cb3 = new CodeBag(cb, null);
+ for(Tree<String> tc : t.child(1).child(0))
+ fillCodeBag(tc, cb3);
+ cb.add(new Literal.LiteralDatum(cb3.getDescriptor(), d, true));
+
+ } else if ("CodeBagRef".equals(t.child(1).head())) {
+ cb.add(new Literal.CodeBagRef(name(t.child(1).child(0)), cb, d));
+
+ } else if ("ShipSpecific".equals(t.child(1).head())) {
+ cb.add(new Literal.ShipSpecific(string(t.child(1).child(0)), d, count));
+
+ } else {
+ PortReference s = portReference(t.child(1));
+ Instruction inst = null;
+ if (opcodebody==null) inst = new Instruction(s, d, count, TAKE, false, trigger, true);
+ else if (opcodebody.head().equals("nop")) inst = new Instruction(s, d, count, IGNORE, false, trigger, false);
+ else if (opcodebody.head().equals("synthesize")) inst = new Instruction(s, d, count, IGNORE, false, trigger, true);
+ else if (opcodebody.head().equals("synthesize+ack")) inst = new Instruction(s, d, count, IGNORE, true, trigger, true);
+ else if (opcodebody.head().equals("wait")) inst = new Instruction(s, d, count, COPY, false, trigger, false);
+ else if (opcodebody.head().equals("discard")) inst = new Instruction(s, d, count, TAKE, false, trigger, false);
+ else if (opcodebody.head().equals("nop+ack")) inst = new Instruction(s, d, count, IGNORE, true, trigger, false);
+ else if (opcodebody.head().equals("wait+ack")) inst = new Instruction(s, d, count, COPY, true, trigger, false);
+ else if (opcodebody.head().equals("discard+ack")) inst = new Instruction(s, d, count, TAKE, true, trigger, false);
+ else if (opcodebody.head().equals("copy")) inst = new Instruction(s, d, count, COPY, false, trigger, true);
+ else if (opcodebody.head().equals("copy+ack")) inst = new Instruction(s, d, count, COPY, true, trigger, true);
+ else if (opcodebody.head().equals("move")) inst = new Instruction(s, d, count, TAKE, false, trigger, true);
+ else if (opcodebody.head().equals("move+ack")) inst = new Instruction(s, d, count, TAKE, true, trigger, true);
+ else if (opcodebody.head().equals("accept")) inst = new Instruction(s, d, count, TAKE, false, trigger, true);
+ else if (opcodebody.head().equals("accept+ack")) inst = new Instruction(s, d, count, TAKE, true, trigger, true);
+ cb.add(inst);
+ }
+ }
}
}