remove last vestiges of old literal system
[fleet.git] / src / edu / berkeley / fleet / assembler / Parser.java
index f39f869..a6a55a9 100644 (file)
@@ -1,12 +1,9 @@
 package edu.berkeley.fleet.assembler;
-
 import edu.berkeley.fleet.api.*;
-
 import edu.berkeley.sbp.*;
 import edu.berkeley.sbp.chr.*;
 import edu.berkeley.sbp.misc.*;
 import edu.berkeley.sbp.meta.*;
-import edu.berkeley.sbp.bind.*;
 import edu.berkeley.sbp.util.*;
 import java.util.*;
 import java.io.*;
@@ -38,61 +35,67 @@ public class Parser {
         return new CodeBag(name);
     }
 
-    Tree<String> parse(Reader r) throws Exception {
+    private static Union grammar;
+    private static synchronized Union getGrammar() throws Exception {
+        if (grammar != null) return grammar;
         InputStream grammarStream =
             Parser.class.getClassLoader().getResourceAsStream("edu/berkeley/fleet/assembler/fleet.g");
         CharParser metaGrammarParser   = new CharParser(MetaGrammar.newInstance());
         Tree<String> parsedGrammar     = metaGrammarParser.parse(new CharInput(grammarStream)).expand1();
-        Union   grammar                = Grammar.create(parsedGrammar, "s", new Grammar.Bindings() { });
-        CharParser  parser             = new CharParser(grammar);
-        Tree tree = parser.parse(new CharInput(r)).expand1();
-        return tree;
+        grammar                        = GrammarAST.buildFromAST(parsedGrammar, "s", new File[0]);
+        return grammar;
     }
 
-    public void parse(Reader r, OutputStream out) throws Exception {
+    Tree<String> parse(Reader r) throws Exception {
+        return new CharParser(getGrammar()).parse(new CharInput(r)).expand1();
+    }
 
+    public void parse(Reader r, OutputStream out) throws Exception {
         // this needs to be "code bag zero"
         CodeBag baseCodeBag = new CodeBag();
         CodeBag rootCodeBag = new CodeBag();
+        skip = false;
         baseCodeBag.add(new Instruction.Literal.CodeBagDescriptor(null, rootCodeBag.getFakeAddress(), 1));
         walk((Tree<String>)parse(r), rootCodeBag);
-        if (fleet instanceof edu.berkeley.fleet.slipway.Slipway)
-            ((edu.berkeley.fleet.slipway.Slipway)fleet).dumpFabric(true);
+        if (fleet instanceof edu.berkeley.fleet.fpga.Fpga)
+            ((edu.berkeley.fleet.fpga.Fpga)fleet).dumpFabric(true);
 
         // map from arbitrary identifiers to actual addresses
         int[] codeBagMap = new int[codeBags.size()];
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        CountingOutputStream cos   = new CountingOutputStream(baos);
-        DataOutputStream dos       = new DataOutputStream(cos);
+        DataOutputStream dos       = new DataOutputStream(baos);
+        int count = 0;
         for(int i=0; i<codeBags.size(); i++) {
             CodeBag c = codeBags.get(i);
             dos.flush();
-            codeBagMap[i] = cos.getCount();
-            for(Instruction inst : c)
+            codeBagMap[i] = count;
+            for(Instruction inst : c) {
                 fleet.writeInstruction(dos, inst);
+                count++;
+            }
         }
 
         // now write for real
-        cos = new CountingOutputStream(out);
-        dos = new DataOutputStream(cos);
+        dos = new DataOutputStream(out);
+        count = 0;
         for(int i=0; i<codeBags.size(); i++) {
             CodeBag c = codeBags.get(i);
             dos.flush();
             for(Instruction inst : c) {
                 if (inst instanceof Instruction.Literal.CodeBagDescriptor) {
                     dos.flush();
-                    cos.getCount();
                     Instruction.Literal.CodeBagDescriptor old = (Instruction.Literal.CodeBagDescriptor)inst;
-                    int offset = fleet.computeOffset(cos.getCount(), codeBagMap[(int)old.offset]);
-                    inst = new Instruction.Literal.CodeBagDescriptor(old.dest,
+                    int offset = codeBagMap[(int)old.offset];// - count;
+                    inst = new Instruction.Literal.CodeBagDescriptor(old.pump,
                                                                      offset,
                                                                      codeBags.get((int)old.offset).size());
+                    //System.out.println("cbd: " + offset + " " + codeBags.get((int)old.offset).size() + " " + codeBags.get((int)old.offset).name + " " + codeBags.get((int)old.offset));
                 }
                 fleet.writeInstruction(dos, inst);
+                count++;
             }
         }
         dos.flush();
-        cos.flush();
         out.flush();
         out.close();
     }
@@ -136,15 +139,9 @@ public class Parser {
             
         } else if (head.equals("Expect")) {
             expect.add(Long.parseLong(string(t.child(0))));
+        } else if (head.equals("Skip")) {
+            skip = true;
 
-        } else if (head.equals("Memory")) {
-            if (((edu.berkeley.fleet.interpreter.Interpreter)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)));
-            ((edu.berkeley.fleet.interpreter.Interpreter)fleet).mem = mem;
         }
     }
 
@@ -160,16 +157,42 @@ public class Parser {
         return string(t.child(0))+string(t.child(1));
     }
 
-    BenkoBox portReference(Tree<String> t) {
-        if (!"Port".equals(t.head())) return null;
+    Destination portReference(Tree<String> t) {
+        if (!"Port".equals(t.head()) && !"SubPort".equals(t.head()) && !"ShipSpecificLiteral".equals(t.head())) return null;
+        String shipName = name(t.child(0));
+        String portName = name(t.child(1));
+        String subPort = t.size()<3 ? null : name(t.child(2));
+        Ship ship = shipMap.get(shipName);
+        if (ship==null) throw new RuntimeException("no such ship \""+shipName+"\"");
+        Destination ret = null;
+        Pump bb = null;
+        for(Pump b : ship.getPumps())
+            if (b.getName().equals(portName)) {
+                bb = b;
+            }
+        if (bb==null)
+            throw new RuntimeException("no such pump \""+portName+"\"");
+        if (subPort==null) subPort="";
+        for(Destination d : bb.getDestinations())
+            if (d.getDestinationName().equals(subPort))
+                return d;
+        if (ret==null)
+            throw new RuntimeException("no such pump \""+portName+"\" on ships of type \""+ship.getType()+"\"");
+        return ret;
+    }
+
+    Pump pump(Tree<String> t) {
+        if (!"Port".equals(t.head()) && !"SubPort".equals(t.head()) && !"ShipSpecificLiteral".equals(t.head()))
+            throw new RuntimeException(t+"");
         String shipName = name(t.child(0));
         String portName = name(t.child(1));
         Ship ship = shipMap.get(shipName);
         if (ship==null) throw new RuntimeException("no such ship \""+shipName+"\"");
-        for(BenkoBox b : ship.getBenkoBoxes())
+        Pump bb = null;
+        for(Pump b : ship.getPumps())
             if (b.getName().equals(portName))
                 return b;
-        throw new RuntimeException("no such benkobox \""+portName+"\" on ships of type \""+ship.getType()+"\"");
+        throw new RuntimeException("no such pump \""+portName+"\"");
     }
 
     private HashMap<String,Integer> numAllocated = new HashMap<String,Integer>();
@@ -191,6 +214,26 @@ public class Parser {
         throw new RuntimeException("no more ships of type \""+shipType+"\"");
     }
 
+    private long parseSSL(Tree t) {
+        String shipType = name(t.child(0));
+        String portName = name(t.child(1));
+        Ship chosenship = null;
+        for(Ship ship : fleet) {
+            if (ship.getType().equals(shipType)) {
+                chosenship = ship;
+                break;
+            }
+        }
+        Pump chosenport = chosenship.getPump(portName);
+        Tree specs = t.child(2);
+        long literal = 0;
+        for(int i=0; i<specs.size(); i++) {
+            Tree tt = specs.child(i);
+            literal |= chosenport.resolveLiteral(string(tt));
+        }
+        return literal;
+    }
+
     void fillCodeBag(Tree<String> t, CodeBag cb) {
         if (t.head()==null) return;
         else if (t.head().equals("NamedCodeBag")) {
@@ -198,34 +241,28 @@ public class Parser {
             for(Tree<String> statement : t.child(1))
                 fillCodeBag(statement, cb2);
 
-        } else if (t.head().equals("Literal")) {
-            int literal = Integer.parseInt(string(t.child(0)));
-            BenkoBox benkobox = portReference(t.child(1));
-            cb.add(new Instruction.Literal.Absolute(benkobox, literal));
-
-        } else if (t.head().equals("CodeBagDescriptor")) {
-            String refname = name(t.child(0).child(0));
-            CodeBag cb2 = getCodeBag(refname);
-            BenkoBox benkobox = portReference(t.child(1));
-            cb.add(new Instruction.Literal.CodeBagDescriptor(benkobox, cb2.getFakeAddress(), 0));
-
         } else if (t.head().equals("Fiber")) {
-            BenkoBox benkobox = portReference(t.child(0));
+            Pump pump = (Pump)pump(t.child(0));
             
             OUTER: for(Tree tt : t.child(1)) {
                 int count = 1;
                 Tree ttx = null;
-                boolean recycle = false;
+                boolean requeue = false;
                 ttx = tt.child(1);
-                if (tt.size() > 1) {
-                    tt = tt.child(0);
-                    if (tt.size() > 0 && tt.child(0).size()>0) {
-                        tt = tt.child(0);
-                        if (tt.child(0).size() == 0) count=1;
-                        else if (tt.child(0).size() > 0 && "Star".equals(tt.child(0).child(0).head())) count=0;
-                        else count = Integer.parseInt(string(tt.child(0)));
-                        if (tt.size() > 1 && tt.child(1).size() > 0)
-                            recycle = true;
+                if (tt.size() > 1 && tt.child(0).size()>0) {
+                    tt = tt.child(0).child(0);
+                    if (tt.head().equals("BrackStar")) {
+                        count = 0;
+                        requeue = false;
+                    } else if (tt.head().equals("ParenStar")) {
+                        count = 0;
+                        requeue = true;
+                    } else if (tt.head().equals("Brack")) {
+                        count = Integer.parseInt(string(tt.child(0)));
+                        requeue = false;
+                    } else if (tt.head().equals("Paren")) {
+                        count = Integer.parseInt(string(tt.child(0)));
+                        requeue = true;
                     }
                 }
                 boolean tokenIn = false;
@@ -233,51 +270,59 @@ public class Parser {
                 boolean latch = false;
                 boolean dataOut = false;
                 boolean tokenOut = false;
-                BenkoBox dest = null;
+                boolean dataOutDest = false;
+                boolean localLiteral = false;
+                long literal = 0;
+                Destination dest = null;
                 for(int i=0; i<ttx.size(); i++) {
                     Tree ttt = ttx.child(i);
                     if      ("Wait".equals(ttt.head()))    { tokenIn = true; }
                     else if ("Nop".equals(ttt.head()))     { }
-                    else if ("Kill".equals(ttt.head()))    {
-                        cb.add(new Instruction.Kill(benkobox, count));
+                    else if ("KillStar".equals(ttt.head()))    {
+                        cb.add(new Instruction.Kill(pump, count, true));
+                        continue OUTER;
+                    } else if ("Kill".equals(ttt.head()))    {
+                        cb.add(new Instruction.Kill(pump, count, false));
                         continue OUTER;
                     }
                     else if ("Discard".equals(ttt.head())) { dataIn = true; latch = false; }
                     else if ("Take".equals(ttt.head()))    { dataIn = true; latch = true; }
                     else if ("SendTo".equals(ttt.head()))  { dataOut = true; dest = portReference(ttt.child(0)); }
+                    else if ("LocalLiteral".equals(ttt.head()))  { localLiteral = true; literal = Long.parseLong(string(ttt.child(0))); }
+                    else if ("LocalLiteralCodeBag".equals(ttt.head()))  {
+                        String refname = name(ttt.child(0).child(0));
+                        CodeBag cb2 = getCodeBag(refname);
+                        cb.add(new Instruction.Literal.CodeBagDescriptor(pump, cb2.getFakeAddress(), 0));
+                        continue OUTER;
+                    } else if ("LocalLiteralConst".equals(ttt.head()))  {
+                        localLiteral = true;
+                        literal = parseSSL(ttt.child(0));
+                    }
+                    else if ("DataOutDest".equals(ttt.head()))  { dataOutDest = true; }
                     else if ("Deliver".equals(ttt.head())) { dataOut = true;  }
                     else if ("Ack".equals(ttt.head()))     { tokenOut = true; dest = portReference(ttt.child(0)); }
                 }
-                cb.add(new Instruction.Executable(benkobox,
-                                                  dest, count, tokenIn, dataIn,
-                                                  latch, dataOut, tokenOut, recycle));
+                if (localLiteral)
+                    cb.add(new Instruction.LocalLiteral(pump, literal));
+                else
+                    cb.add(new Instruction.Executable(pump,
+                                                      dest, count, tokenIn, dataIn,
+                                                      latch, dataOutDest, dataOut, tokenOut, requeue));
             }
         }
     }
 
-    private static class CountingOutputStream extends FilterOutputStream {
-        public CountingOutputStream(OutputStream os) { super(os); }
-        int count = 0;
-        public int getCount() { return count; }
-        public void write(int b) throws IOException {
-            super.write(b);
-            count++;
-        }
-        public void write(byte[] b, int off, int len) throws IOException {
-            super.write(b, off, len);
-            count += len;
-        }
-    }
-
     private class CodeBag extends ArrayList<Instruction> {
-        public int address = -1;
-        public CodeBag() { codeBags.add(this); }
-        public CodeBag(String name) { this(); codeBagsByName.put(name, this); }
+        public long address = -1;
+        public final String name;
+        public CodeBag() { codeBags.add(this); this.name = "root"; }
+        public CodeBag(String name) { codeBags.add(this); codeBagsByName.put(name, this); this.name = name; }
         public long getFakeAddress() { return codeBags.indexOf(this); }
         public boolean equals(Object o) { return this==o; }
     }
 
     // hideous hack
     public static ArrayList<Long> expect;
+    public static boolean         skip;
 
 }