implement am26 support for constants
[fleet.git] / src / edu / berkeley / fleet / interpreter / Interpreter.java
index e4bde06..5996334 100644 (file)
@@ -8,81 +8,12 @@ import edu.berkeley.sbp.util.ANSI;
 import edu.berkeley.fleet.doc.*;
 import edu.berkeley.fleet.api.*;
 import edu.berkeley.fleet.ies44.*;
-import edu.berkeley.fleet.interpreter.ships.*;
 
-public class Interpreter extends Fleet {
+public class Interpreter extends Fleet implements Fleet.WithDynamicShips {
 
     /** some "halt ship" can turn this on to stop the interpreter */
-    public boolean       halt         = false;
-    public ArrayList<InterpreterShip> shiplist   = new ArrayList<InterpreterShip>();
-    public HashMap<String,InterpreterShip> ships = new HashMap<String,InterpreterShip>();
-    private BlockingQueue<Long> debugStream = new LinkedBlockingQueue<Long>();
-    public int[] mem = new int[0];
-
-
-    public void debug(long data) {
-        try {
-            if (debugStream != null) {
-                debugStream.put(data);
-            } else {
-                Log.println(ANSI.invert("   DEBUG: got a datum: " +  data+ANSI.clreol()));
-            }
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    public static class DynamicInterpreter extends Interpreter implements Fleet.WithDynamicShips {
-    }
-
-    public void expand(ShipDescription sd) {
-        try {
-            String filename = (sd.name.charAt(0)+"").toUpperCase() + sd.name.substring(1).toLowerCase();
-            File outf = new File("build/java/edu/berkeley/fleet/interpreter/ships/"+filename+".java");
-            new File(outf.getParent()).mkdirs();
-            System.err.println("writing to " + outf);
-            FileOutputStream out = new FileOutputStream(outf);
-            PrintWriter pw = new PrintWriter(out);
-
-            pw.println("package edu.berkeley.fleet.interpreter.ships;");
-            pw.println("import edu.berkeley.sbp.util.ANSI;");
-            pw.println("import edu.berkeley.fleet.interpreter.*;");
-            pw.println("import edu.berkeley.fleet.api.*;");
-            pw.println("import edu.berkeley.fleet.*;");
-            pw.println("import java.util.*;");
-            pw.println("import java.io.*;");
-            pw.println("");
-            pw.println("public class "+filename+" extends InterpreterShip {");
-            pw.println("");
-            for(ShipDescription.BenkoBox b : sd.benkoBoxes) {
-                if (b.ports.length != 1)
-                    throw new RuntimeException("multiple ports not supported");
-                String name = b.ports[0];
-                pw.print("    ");
-                if (!b.tokenOnly &&  b.inbox) pw.print("DataInbox");
-                if ( b.tokenOnly &&  b.inbox) pw.print("TokenInbox");
-                if (!b.tokenOnly && !b.inbox) pw.print("DataOutbox");
-                if ( b.tokenOnly && !b.inbox) pw.print("TokenOutbox");
-                pw.print(" box_");
-                pw.print(name);
-                pw.print(" = new ");
-                if (!b.tokenOnly &&  b.inbox) pw.print("DataInbox");
-                if ( b.tokenOnly &&  b.inbox) pw.print("TokenInbox");
-                if (!b.tokenOnly && !b.inbox) pw.print("DataOutbox");
-                if ( b.tokenOnly && !b.inbox) pw.print("TokenOutbox");
-                pw.println("(this, \""+name+"\");");
-            }
-            pw.println("");
-            pw.println("    public "+filename+"(Interpreter fleet, String name) { super(fleet, name); }");
-            pw.println("");
-            //pw.println("    public void service() {");
-            pw.println(sd.sections.get("fleeterpreter"));
-            //pw.println("}");
-            pw.println("}");
-            pw.flush();
-            pw.close();
-        } catch (Exception e) { throw new RuntimeException(e); }
-    }
+    private HashMap<String,InterpreterShip> ships       = new HashMap<String,InterpreterShip>();
+    private BlockingQueue<Long>             debugStream = new LinkedBlockingQueue<Long>();
 
     public FleetProcess run(final byte[] instructions) {
         try {
@@ -95,16 +26,47 @@ public class Interpreter extends Fleet {
                             throw new RuntimeException(e);
                         } }
                     protected void _terminate() {
-                        shiplist   = new ArrayList<InterpreterShip>();
+                        // FIXME: hack
                         ships = new HashMap<String,InterpreterShip>();
                         debugStream = new LinkedBlockingQueue<Long>();
-                        mem = new int[0];
                     }
                 };
             new Thread() {
                 public void run() {
                     try {
-                        go(fp, instructions);
+                        // find the first icache
+                        InterpreterShip iscratch = null;
+                        for(Ship ship : Interpreter.this)
+                            if (ship.getClass().getSimpleName().equals("Memory")) {
+                                iscratch = (InterpreterShip)ship;
+                                break;
+                            }
+                        if (iscratch==null)
+                            iscratch = (InterpreterShip)Class.forName("edu.berkeley.fleet.interpreter.Memory")
+                                .getConstructor(new Class[] { Interpreter.class, String.class })
+                                .newInstance(new Object[] { Interpreter.this, "memory" });
+                        iscratch
+                            .getClass()
+                            .getMethod("boot", new Class[] { byte[].class })
+                            .invoke(iscratch, new Object[] { instructions });
+                        
+                        while(!fp.isTerminated())
+                            for(InterpreterShip ship : ships.values())
+                                for(int j=0; j<10; j++)
+                                    ship._service();
+                        
+                        // run the ships a bit longer for good measure
+                        for(int i=0; i<100; i++)
+                            for(InterpreterShip ship : ships.values())
+                                for(int j=0; j<10; j++)
+                                    ship._service();
+                        
+                        // check the state of the ships
+                        for(InterpreterShip ship : ships.values())
+                            ship.shutdown();
+                        
+                        Log.println(ANSI.yellow("    DONE: ====== FLEET is halted.  Have a nice day.  ======"));
+                        
                     } catch (Exception e) {
                         if (fp.isTerminated()) return;
                         throw new RuntimeException(e);
@@ -117,65 +79,25 @@ public class Interpreter extends Fleet {
         }
     }
 
-    public void go(FleetProcess fp, byte[] instructions) {
-        try {
-            // find the first icache
-            InterpreterShip iscratch = null;
-            for(Ship ship : this)
-                if (ship.getClass().getSimpleName().equals("Iscratch")) {
-                    iscratch = (InterpreterShip)ship;
-                    break;
-                }
-            if (iscratch==null)
-                iscratch = (InterpreterShip)Class.forName("edu.berkeley.fleet.interpreter.ships.Iscratch")
-                    .getConstructor(new Class[] { Interpreter.class, String.class })
-                    .newInstance(new Object[] { this, "iscratch" });
-            iscratch
-                .getClass()
-                .getMethod("boot", new Class[] { byte[].class })
-                .invoke(iscratch, new Object[] { instructions });
-
-            while(!halt && !fp.isTerminated())
-                for(InterpreterShip ship : ships.values())
-                    for(int j=0; j<10; j++)
-                        ship._service();
-
-            // run the ships a bit longer for good measure
-            for(int i=0; i<100; i++)
-                for(InterpreterShip ship : ships.values())
-                    for(int j=0; j<10; j++)
-                        ship._service();
-
-            // check the state of the ships
-            for(InterpreterShip ship : ships.values())
-                ship.shutdown();
-
-            Log.println(ANSI.yellow("    DONE: ====== FLEET is halted.  Have a nice day.  ======"));
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-    }
-
     public void dispatch(Instruction i, long address) {
         Log.dispatch(i);
         if (i instanceof Instruction.Executable) {
             InterpreterBenkoBox sourceBenkoBox = (InterpreterBenkoBox)(((Instruction.Executable)i).benkoBox);
-            ((InstructionPort)sourceBenkoBox).addInstruction(((Instruction.Executable)i));
+            ((InstructionBenkoBox)sourceBenkoBox).addInstruction(((Instruction.Executable)i));
 
         } else if (i instanceof Instruction.Literal.CodeBagDescriptor) {
             Instruction.Literal.CodeBagDescriptor cbd = (Instruction.Literal.CodeBagDescriptor)i;
-            InterpreterBenkoBox destBenkoBox = (InterpreterBenkoBox)(cbd.dest);
             long absolute_cbd = ((cbd.offset+address) << 6) | cbd.size;
-            destBenkoBox.addDataFromFabric((int)absolute_cbd);
+            new Packet(this, null, (int)absolute_cbd, (InterpreterDestination)cbd.dest).send();
             
         } else if (i instanceof Instruction.Literal.Absolute) {
-            InterpreterBenkoBox destBenkoBox = (InterpreterBenkoBox)(((Instruction.Literal.Absolute)i).dest);
-            Log.data(((Instruction.Literal.Absolute)i).value+"", null, destBenkoBox);
-            destBenkoBox.addDataFromFabric((int)((Instruction.Literal.Absolute)i).value);
+            new Packet(this, null,
+                       (int)((Instruction.Literal.Absolute)i).value,
+                       (InterpreterDestination)(((Instruction.Literal.Absolute)i).dest)).send();
 
         } else if (i instanceof Instruction.Kill) {
             InterpreterBenkoBox benkoBox = (InterpreterBenkoBox)(((Instruction.Kill)i).benkoBox);
-            ((InstructionPort)benkoBox).kill(((Instruction.Kill)i).count,
+            ((InstructionBenkoBox)benkoBox).kill(((Instruction.Kill)i).count,
                                              ((Instruction.Kill)i).killOnlyStandingInstructions);
 
         } else {
@@ -183,62 +105,112 @@ public class Interpreter extends Fleet {
         }
     }
 
-    public void sendToken(InterpreterBenkoBox source, InterpreterBenkoBox dest) {
-        Log.token(source, dest);
-        dest.addTokenFromFabric();
-    }
+    public Iterator<Ship> iterator() { return (Iterator<Ship>)(Object)ships.values().iterator(); }
 
-    public void sendData(InterpreterBenkoBox source, int data, InterpreterBenkoBox dest) {
-        Log.data(data+"", source, dest);
-        dest.addDataFromFabric(data);
+    public Ship createShip(String shipType, String shipname) {
+        try {
+            Class c = Class.forName("edu.berkeley.fleet.interpreter."+shipType);
+            Constructor con = c.getConstructor(new Class[] { Interpreter.class, String.class });
+            InterpreterShip ret = (InterpreterShip)con.newInstance(new Object[] { this, shipname });
+            BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("ships/"+shipType+".ship")));
+            ShipDescription sd = new ShipDescription(shipname, br);
+            ret.setShipDescription(sd);
+            ships.put(shipname, ret);
+            return ret;
+        } catch (Exception e) {
+            return null;
+        }
     }
 
+    public void debug(long data) {
+        try {
+            if (debugStream != null) debugStream.put(data);
+            else Log.println(ANSI.invert("   DEBUG: got a datum: " +  data+ANSI.clreol()));
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
 
-    // Implementation of the Fleet class abstract methods /////////////////////////////////////////////////////////
-
-    public Iterator<Ship> iterator() { return (Iterator<Ship>)(Object)shiplist.iterator(); }
-
-    public int computeOffset(int origin, int target) { return (target - origin)/6; }
-    public int computeTarget(int origin, int offset) { return origin + (offset*6); }
+    // Instruction Encoding /////////////////////////////////////////////////////////////////////////
 
-    private InterpreterInstructionEncoder iie = new InterpreterInstructionEncoder();
+    public final InterpreterInstructionEncoder iie = new InterpreterInstructionEncoder();
     public Instruction readInstruction(DataInputStream is) throws IOException { return iie.readInstruction(is); }
     public Instruction readInstruction(long instr) { return iie.readInstruction(instr); }
     public long writeInstruction(Instruction d) { return writeInstruction(d); }
     public void writeInstruction(DataOutputStream os, Instruction d) throws IOException { iie.writeInstruction(os, d); }
-
-    private class InterpreterInstructionEncoder extends InstructionEncoder {
-        public long getBoxAddr(Destination box) { return ((InterpreterBenkoBox)box).addr; }
-        public long getBoxInstAddr(BenkoBox box) { return ((InterpreterBenkoBox)box).instr_addr; }
-        public BenkoBox getBoxByAddr(long dest) {
+    public class InterpreterInstructionEncoder extends InstructionEncoder {
+        public long getDestAddr(Destination box) { return ((InterpreterDestination)box).getDestAddr(); }
+        public long getBoxInstAddr(BenkoBox box) { return ((InterpreterBenkoBox)box).getDestAddr(); }
+        public Destination getDestByAddr(long dest) {
             for(Ship ship : Interpreter.this)
                 for(BenkoBox bb : ship.getBenkoBoxes())
-                    if (((InterpreterBenkoBox)bb).addr == dest)
-                        return bb;
+                    for(Destination d : bb.getDestinations())
+                        if (getDestAddr(d)==dest)
+                            return d;
             return null;
         }
         public BenkoBox getBoxByInstAddr(long dest) {
             for(Ship ship : Interpreter.this)
                 for(BenkoBox bb : ship.getBenkoBoxes())
-                    if (((InterpreterBenkoBox)bb).instr_addr == dest)
+                    if (getBoxInstAddr(bb) == dest)
                         return bb;
             return null;
         }
     }
 
-    public Ship createShip(String shipType, String shipname) {
+    // ShipDescription //////////////////////////////////////////////////////////////////////////////
+
+    public void expand(ShipDescription sd) {
         try {
-            Class c = Class.forName("edu.berkeley.fleet.interpreter.ships."+shipType);
-            Constructor con = c.getConstructor(new Class[] { Interpreter.class, String.class });
-            InterpreterShip ret = (InterpreterShip)con.newInstance(new Object[] { this, shipname });
-            ships.put(shipname, ret);
-            shiplist.add(ret);
-            return ret;
-        } catch (Exception e) {
-            return null;
-        }
-    }
+            String filename = sd.getName();
+            //String filename = (sd.getName().charAt(0)+"").toUpperCase() + sd.getName().substring(1).toLowerCase();
+            File outf = new File("build/java/edu/berkeley/fleet/interpreter/"+filename+".java");
+            new File(outf.getParent()).mkdirs();
+            System.err.println("writing to " + outf);
+            FileOutputStream out = new FileOutputStream(outf);
+            PrintWriter pw = new PrintWriter(out);
 
+            pw.println("package edu.berkeley.fleet.interpreter;");
+            pw.println("import edu.berkeley.sbp.util.ANSI;");
+            pw.println("import edu.berkeley.fleet.api.*;");
+            pw.println("import edu.berkeley.fleet.*;");
+            pw.println("import java.util.*;");
+            pw.println("import java.io.*;");
+            pw.println("");
+            pw.println("public class "+filename+" extends InterpreterShip {");
+            pw.println("");
+            for(BenkoBoxDescription b : sd) {
+                String name = b.getName();
+                pw.print("    ");
+                if ( b.isInbox()) pw.print("Inbox");
+                if (!b.isInbox()) pw.print("Outbox");
+                pw.print(" box_");
+                pw.print(name);
+                pw.print(" = new ");
+                if ( b.isInbox()) pw.print("Inbox");
+                if (!b.isInbox()) pw.print("Outbox");
+                pw.print("(this, \""+name+"\", new String[] { ");
+                boolean first = true;
+                for(String destination : b) {
+                    if (!first) pw.print(", ");
+                    first = false;
+                    pw.print("\""+destination+"\"");
+                }
+                pw.println("});");
+            }
+            pw.println("");
+            pw.println("    public "+filename+"(Interpreter fleet, String name) {");
+            pw.println("       super(fleet, name, \""+filename+"\");");
+            for(BenkoBoxDescription b : sd)
+                pw.println("       addBenkoBox(\""+b.getName()+"\", box_"+b.getName()+");");
+            pw.println("    }");
+            pw.println("");
+            pw.println(sd.getSection("fleeterpreter"));
+            pw.println("}");
+            pw.flush();
+            pw.close();
+        } catch (Exception e) { throw new RuntimeException(e); }
+    }
 
 }