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) {
// Memory //////////////////////////////////////////////////////////////////////////////
- public int[] mem = new int[0];
-
public void dumpMem() {
Log.print(Log.cyan(" MEMORY: "));
for(int i=0; i<mem.length; i++) {