more fixes to bring things up to date with the new test/doc apis
[fleet.git] / src / edu / berkeley / fleet / interpreter / Interpreter.java
index 2e934a3..77605ac 100644 (file)
 package edu.berkeley.fleet.interpreter;
 import java.io.*;
 import java.util.*;
+import java.util.concurrent.*;
 import java.lang.reflect.*;
 import edu.berkeley.fleet.*;
+import edu.berkeley.fleet.doc.*;
 import edu.berkeley.fleet.api.*;
 import edu.berkeley.fleet.ies44.*;
 import edu.berkeley.fleet.ships.*;
 
-public class Interpreter extends Fleet /*, Fleet.WithDynamicShips*/ {
+public class Interpreter extends Fleet {
 
     /** 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 go(byte[] instructions) {
 
-        // find the first icache
-        Icache icache = null;
-        for(Ship ship : this)
-            if (ship instanceof Icache) {
-                icache = (Icache)ship;
-                break;
+    public void debug(long data) {
+        try {
+            if (debugStream != null) {
+                debugStream.put(data);
+            } else {
+                Log.println(Log.invert("   DEBUG: got a datum: " +  data+Log.clreol()));
             }
-
-        // load the icache and take note of the 0-address CBD
-        long launch = 0;
-        for(int i=0; i<instructions.length; i+=6) {
-            long word = 0;
-            for(int j=0; j<6; j++)
-                word = (word << 8) | (instructions[i+j] & 0xff);
-            icache.writeMem(i/6, word);
-            if (i==0) launch = word;
+        } catch (Exception e) {
+            throw new RuntimeException(e);
         }
+    }
 
-        // dispatch the 0-address CBD
-        int base = (int)(launch >> 6);
-        base = base & ~(0xffffffff << 18);
-        int size = (int)launch;
-        size = size & ~(0xffffffff <<  6);
-        icache.dispatch(base, size);
+    public static class DynamicInterpreter extends Interpreter implements Fleet.WithDynamicShips {
+    }
 
-        while(!halt)
-            for(InterpreterShip ship : ships.values())
-                for(int j=0; j<10; j++)
-                    ship._service();
+    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/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.ships;");
+            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); }
+    }
 
-        // 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();
+    public FleetProcess run(final byte[] instructions) {
+        try {
+            final FleetProcess fp = new FleetProcess() {
+                    public void invokeInstruction(Instruction i) { throw new RuntimeException("not supported"); }
+                    public long readWord() {
+                        try {
+                            return debugStream.take();
+                        } catch (Exception e) {
+                            throw new RuntimeException(e);
+                        } }
+                    protected void _terminate() {
+                        shiplist   = new ArrayList<InterpreterShip>();
+                        ships = new HashMap<String,InterpreterShip>();
+                        debugStream = new LinkedBlockingQueue<Long>();
+                        mem = new int[0];
+                    }
+                };
+            new Thread() {
+                public void run() {
+                    try {
+                        go(fp, instructions);
+                    } catch (Exception e) {
+                        throw new RuntimeException(e);
+                    }
+                }
+            }.start();
+            return fp;
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
 
-        // check the state of the ships
-        for(InterpreterShip ship : ships.values())
-            ship.shutdown();
+    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.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(Log.yellow("    DONE: ====== FLEET is halted.  Have a nice day.  ======"));
+            Log.println(Log.yellow("    DONE: ====== FLEET is halted.  Have a nice day.  ======"));
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
     }
 
     public void dispatch(Instruction i, long address) {
@@ -145,8 +238,6 @@ public class Interpreter extends Fleet /*, Fleet.WithDynamicShips*/ {
 
     // Memory //////////////////////////////////////////////////////////////////////////////
 
-    public int[] mem = new int[0];
-
     public void dumpMem() {
         Log.print(Log.cyan("  MEMORY: "));
         for(int i=0; i<mem.length; i++) {