update to new AM37 syntax
[fleet.git] / src / edu / berkeley / fleet / assembler / Parser.java
index 91368ea..6eebcc2 100644 (file)
@@ -195,9 +195,6 @@ public class Parser {
                 for(Tree<String> statement : t.child(1))
                     fillCodeBag(statement, cb);
    
-        } else if (head.equals("#import")) {
-            // ignored
-
         } else if (head.equals("#ship")) {
             String name = name(t.child(0));
             String type = string(t.child(1));
@@ -213,13 +210,6 @@ public class Parser {
             }
             shipMap.put(name, ship);
 
-        } else if (head.equals("#include")) {
-            try {
-                walk(parseIt(new InputStreamReader(new FileInputStream(string(t.child(0))))), cb);
-            } catch (Exception e) {
-                throw new RuntimeException(e);
-            }
-            
         } else if (head.equals("#expect")) {
             expect.add(number(t.child(0)));
         } else if (head.equals("#skip")) {
@@ -249,10 +239,8 @@ public class Parser {
 
     Path path(Dock dock, Tree<String> t) {
         if (!"Dock".equals(t.head()) && !"Destination".equals(t.head()) && !"ShipSpecificLiteral".equals(t.head())) return null;
-        t = t.child(0);
         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;
@@ -263,10 +251,11 @@ public class Parser {
             }
         if (bb==null)
             throw new RuntimeException("no such pump \""+portName+"\"");
-        if (subPort==null) subPort="";
-        if (":i".equals(t.head())) return dock.getPath(bb.getInstructionDestination(),SIGNAL_ZERO);
-        if (":1".equals(t.head())) return dock.getPath(bb.getDataDestination(),SIGNAL_ONE);
-        if (":0".equals(t.head())) return dock.getPath(bb.getDataDestination(),SIGNAL_ZERO);
+        if (t.size() >= 3) {
+            if (":i".equals(t.child(2).head())) return dock.getPath(bb.getInstructionDestination(),SIGNAL_ZERO);
+            if (":1".equals(t.child(2).head())) return dock.getPath(bb.getDataDestination(),SIGNAL_ONE);
+            if (":0".equals(t.child(2).head())) return dock.getPath(bb.getDataDestination(),SIGNAL_ZERO);
+        }
         return dock.getPath(bb.getDataDestination(),SIGNAL_ZERO);
     }
 
@@ -370,6 +359,12 @@ public class Parser {
             Dock dock = (Dock)dock(t.child(0));
             
             OUTER: for(Tree tt : t.child(1)) {
+
+                if ("tail".equals(tt.head()))    {
+                    cb.add(new Tail(dock));
+                    continue;
+                }
+
                 int count = 1;
                 Predicate predicate = Default;
                 boolean looping = false;
@@ -382,36 +377,45 @@ public class Parser {
                     if ("[!a]".equals(ttt.head())) predicate = NotFlagA;
                     if ("[!b]".equals(ttt.head())) predicate = NotFlagB;
                     if ("[!c]".equals(ttt.head())) predicate = NotFlagC;
-                    if ("[+]".equals(ttt.head()))  predicate = IgnoreOLC;
-                    if ("[I]".equals(ttt.head()))  interruptible = true;
-                    if ("[L]".equals(ttt.head()))  looping = true;
+                    // FIXME: test case for this
+                    if ("[*]".equals(ttt.head()))  predicate = IgnoreOLC;
+                    // FIXME: test case for this
+                    if ("[olc=0]".equals(ttt.head()))  predicate = OLCZero;
+                    if ("[Rq]".equals(ttt.head()))  looping = true;
                 }
                 tt = tt.child(1);
                 if ("tail".equals(tt.head()))    {
                     cb.add(new Tail(dock));
                     continue;
-                } else if ("setflags".equals(tt.head()))    {
+                } else if ("flags".equals(tt.head()))    {
                     cb.add(new Set(dock, looping, predicate, parseFlags(tt.child(0)), parseFlags(tt.child(1))));
                     continue;
-                } else if ("load".equals(tt.head()) && "loop".equals(tt.child(0).head()))    {
+                } else if ("olc=word".equals(tt.head()))    {
                     cb.add(new Set(dock, looping, predicate, SetDest.OuterLoopCounter, SetSource.DataLatch));
                     continue;
-                } else if ("load".equals(tt.head()) && "repeat".equals(tt.child(0).head()))    {
+                } else if ("ilc=word".equals(tt.head()))    {
                     cb.add(new Set(dock, looping, predicate, SetDest.InnerLoopCounter, SetSource.DataLatch));
                     continue;
                 } else if ("*".equals(tt.head()))    {
                     cb.add(new Set(dock, looping, predicate, SetDest.InnerLoopCounter, SetSource.Infinity));
                     continue;
-                } else if ("with".equals(tt.head()) && "loop".equals(tt.child(0).head()))    {
-                    cb.add(new Set(dock, looping, predicate, SetDest.OuterLoopCounter, (number(tt.child(1)))));
+                } else if ("olc=int".equals(tt.head()))    {
+                    cb.add(new Set(dock, looping, predicate, SetDest.OuterLoopCounter, (number(tt.child(0)))));
                     continue;
-                } else if ("with".equals(tt.head()) && "repeat".equals(tt.child(0).head()))    {
-                    cb.add(new Set(dock, looping, predicate, SetDest.InnerLoopCounter, (number(tt.child(1)))));
+                } else if ("ilc=int".equals(tt.head()))    {
+                    cb.add(new Set(dock, looping, predicate, SetDest.InnerLoopCounter, (number(tt.child(0)))));
                     continue;
-                } else if ("decrement".equals(tt.head())) {
+                } else if ("--".equals(tt.head())) {
                     cb.add(new Set(dock, looping, predicate, SetDest.OuterLoopCounter, SetSource.Decrement));
                     continue;
-                } else if ("literal".equals(tt.head())) {
+                } else if ("nop".equals(tt.head())) {
+                    // FIXME: test case for "torpedoable nop"
+                    if (tt.child(0).size() > 0 && "[T]".equals(tt.child(0).head()))  interruptible = true;
+                    cb.add(new Move(dock, looping, predicate, interruptible, null, false, false, false, false, false, false));
+                } else if ("shift".equals(tt.head())) {
+                    cb.add(new Shift(dock, looping, predicate,
+                                     new BitVector(dock.getShip().getFleet().getWordWidth()).set(number(tt.child(0)))));
+                } else if ("word".equals(tt.head())) {
                     long literal = 0;
                     if (tt.child(0).head().equals("CodeBagBody")) {
                         Tree<String> tq = tt;
@@ -431,11 +435,13 @@ public class Parser {
                         literal = number(tt.child(0));
                     }
                     count = 1;
+                    /*
                     if ("int".equals(tt.child(1).head())) {
                         count = (int)number(tt.child(1));
                     } else if ("forever".equals(tt.child(1).head())) {
                         count = 0;
                     }
+                    */
 
 
                     if (FleetTwoFleet.isSmallEnoughToFit(literal)) {
@@ -455,23 +461,8 @@ public class Parser {
                 }
                 Tree ttx = null;
                 boolean requeue = false;
-                ttx = tt.child(1).head().equals("Commands") ? tt.child(1) : tt;
-                if ("int".equals(tt.child(2).head())) {
-                    count = (int)number(tt.child(2));
-                    requeue = true;
-                } else if ("forever".equals(tt.child(2).head())) {
-                    count = 0;
-                    requeue = true;
-                }
-                tt = tt.child(0);
-                if (tt.head().equals("[*]")) {
-                    cb.add(new Set(dock, looping, predicate, SetDest.InnerLoopCounter, SetSource.Infinity));
-                    //count = 0;
-                    requeue = false;
-                } else if (tt.head().equals("int")) {
-                    count = (int)number(tt);
-                    requeue = false;
-                }
+                if ("[T]".equals(tt.child(0).head()))  interruptible = true;
+                ttx = tt.child(tt.size()-1);
                 boolean tokenIn = false;
                 boolean dataIn = false;
                 boolean latch = false;
@@ -484,18 +475,66 @@ public class Parser {
                 Path path = 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()))     { }
+                    if      ("recv token".equals(ttt.head()))    { tokenIn = true; }
                     else if ("discard".equals(ttt.head())) { dataIn = true; latch = false; }
                     else if ("take".equals(ttt.head()))    { dataIn = true; latch = true; }
-                    else if ("recv".equals(ttt.head()))    { dataIn = true; latch = true; }
-                    else if ("collect".equals(ttt.head()))    { dataIn = true; latch = true; }
-                    else if ("recieve".equals(ttt.head()))    { dataIn = true; latch = true; }
-                    else if ("send".equals(ttt.head()))  { dispatch = true; dataOut = true; }
-                    else if ("sendto".equals(ttt.head()))  { dataOut = true; path = path(dock, ttt.child(0)); }
+                    else if ("collect".equals(ttt.head()))    {
+                        if (dock.isInputDock())
+                            throw new RuntimeException("you can't use \"collect\" at input docks; try \"recv\" instead");
+                        dataIn = true;
+                        latch = true;
+                    }
+                    else if ("collect path".equals(ttt.head()))    {
+                        if (dock.isInputDock())
+                            throw new RuntimeException("you can't use \"collect\" at input docks; try \"recv\" instead");
+                        dataIn = true;
+                        latch = false;
+                        dispatch = true;
+                    }
+                    else if ("collect packet".equals(ttt.head()))    {
+                        if (dock.isInputDock())
+                            throw new RuntimeException("you can't use \"collect\" at input docks; try \"recv\" instead");
+                        dataIn = true;
+                        latch = true;
+                        dispatch = true;
+                    }
+                    else if ("collect nothing".equals(ttt.head()))    {
+                        if (dock.isInputDock())
+                            throw new RuntimeException("you can't use \"collect\" at input docks; try \"recv\" instead");
+                        dataIn = true;
+                    }
+                    else if ("recv".equals(ttt.head()))    {
+                        if (dock.isOutputDock())
+                            throw new RuntimeException("you can't use \"recv\" at input docks; try \"collect\" instead");
+                        dataIn = true;
+                        latch = true;
+                    }
+                    else if ("recv path".equals(ttt.head()))    {
+                        if (dock.isOutputDock())
+                            throw new RuntimeException("you can't use \"recv\" at input docks; try \"collect\" instead");
+                        dataIn = true;
+                        latch = false;
+                        dispatch = true;
+                    }
+                    else if ("recv packet".equals(ttt.head()))    {
+                        if (dock.isOutputDock())
+                            throw new RuntimeException("you can't use \"recv\" at input docks; try \"collect\" instead");
+                        dataIn = true;
+                        latch = true;
+                        dispatch = true;
+                    }
+                    else if ("recv nothing".equals(ttt.head()))    {
+                        if (dock.isOutputDock())
+                            throw new RuntimeException("you can't use \"recv\" at input docks; try \"collect\" instead");
+                        dataIn = true;
+                    }
+                    else if ("send".equals(ttt.head()))  {
+                        dataOut = true;
+                    }
+                    else if ("send to".equals(ttt.head()))  { dataOut = true; path = path(dock, ttt.child(0)); }
                     else if ("deliver".equals(ttt.head())) { dataOut = true;  }
-                    else if ("notify".equals(ttt.head()))     { tokenOut = true; path = path(dock, ttt.child(0)); }
-                    else if ("notifyLast".equals(ttt.head()))     { tokenOut = true; ignoreUntilLast = true; path = path(dock, ttt.child(0)); }
+                    else if ("send token".equals(ttt.head()))     { tokenOut = true; }
+                    else if ("send token to".equals(ttt.head()))     { tokenOut = true; path = path(dock, ttt.child(0)); }
                 }
                 cb.add(new Move(dock, looping, predicate,
                                             interruptible, path, tokenIn, dataIn,