move InterpreterDestination serial number into the Interpreter class
[fleet.git] / src / edu / berkeley / fleet / interpreter / Interpreter.java
1 package edu.berkeley.fleet.interpreter;
2 import java.io.*;
3 import java.util.*;
4 import java.util.concurrent.*;
5 import java.lang.reflect.*;
6 import edu.berkeley.sbp.util.ANSI;
7 import edu.berkeley.fleet.api.*;
8 import edu.berkeley.fleet.two.*;
9 import edu.berkeley.fleet.assembler.*;
10 import edu.berkeley.fleet.util.*;
11
12 public class Interpreter extends FleetTwoFleet implements Parser.FleetWithDynamicShips {
13
14     /** used to allocate serial numbers; see InterpreterDestination for further detail */
15     int maxAllocatedDestinationSerialNumber = 0;
16
17     private InterpreterShip debugShip = null;
18     private BlockingQueue<BitVector> debugStream = new LinkedBlockingQueue<BitVector>();
19     private HashMap<String,InterpreterShip> ships = new HashMap<String,InterpreterShip>();
20     public Iterator<Ship> iterator() { return (Iterator<Ship>)(Object)ships.values().iterator(); }
21     public Ship getShip(String type, int ordinal) {
22         for(Ship s : this)
23             if (s.getType().equals(type))
24                 if (ordinal-- <= 0)
25                     return s;
26         return null;
27     }
28
29     /** do not use this; it is going to go away */
30     public Interpreter() {
31     }
32
33     public Interpreter(String[] ships, boolean logging) {
34         int i=0;
35         Log.quiet = !logging;
36         for(String s : ships) {
37             createShip(ships[i], ships[i]+"_"+i);
38             i++;
39         }
40     }
41
42     void dispatch(Instruction i) {
43         Log.dispatch(i);
44         long il = writeInstruction(i, debugShip.getDock("in"));
45         Path path = debugShip.getDock("in").getPath(i.dock.getInstructionDestination(), null);
46         new Packet((InterpreterPath)path, new BitVector(getWordWidth()).set(il), false).send();
47     }
48
49     /** do not use this; it is going to go away */
50     public Ship createShip(String shipType, String shipname) {
51         try {
52             if (ships.get(shipname)!=null) return ships.get(shipname);
53             Class c = Class.forName("edu.berkeley.fleet.interpreter."+shipType);
54             Constructor con = c.getConstructor(new Class[] { Interpreter.class, String.class, ShipDescription.class });
55             String src = "/ships/" + shipType + ".ship";
56             InputStream is = getClass().getResourceAsStream(src);
57             BufferedReader br = new BufferedReader(new InputStreamReader(is));
58             ShipDescription sd = new ShipDescription(shipType, br);
59             InterpreterShip ret = (InterpreterShip)con.newInstance(new Object[] { this, shipname, sd });
60             ships.put(shipname, ret);
61             if (shipType.equals("Debug") && debugShip == null)
62                 debugShip = ret;
63             return ret;
64         } catch (Exception e) {
65             e.printStackTrace();
66             return null;
67         }
68     }
69
70     void debug(long d) { debug(new BitVector(getWordWidth()).set(d)); }
71     void debug(BitVector data) {
72         try {
73             if (debugStream != null) debugStream.put(data);
74             else Log.println(ANSI.invert("   DEBUG: got a datum: " +  data+ANSI.clreol()));
75         } catch (Exception e) {
76             throw new RuntimeException(e);
77         }
78     }
79
80     // Instruction Encoding /////////////////////////////////////////////////////////////////////////
81
82     public BitVector getDestAddr(Path path) {
83         long ret = ((InterpreterDestination)path.getDestination()).getSerialNumber();
84         BitVector sig = path.getSignal();
85         BitVector bv = new BitVector(DISPATCH_PATH.valmaskwidth+1);
86         bv.set(ret);
87         if (sig != null) {
88             if (sig.length() > 1) throw new RuntimeException("signal was " + sig.length() + " bits long!");
89             if (sig.length() > 0 && sig.get(0)) bv.set(bv.length()-1,true);
90         }
91         return bv;
92     }
93
94
95     // ShipDescription //////////////////////////////////////////////////////////////////////////////
96
97     public void expand(ShipDescription sd) {
98         try {
99             String filename = sd.getName();
100             //String filename = (sd.getName().charAt(0)+"").toUpperCase() + sd.getName().substring(1).toLowerCase();
101             File outf = new File("build/java/edu/berkeley/fleet/interpreter/"+filename+".java");
102             new File(outf.getParent()).mkdirs();
103             System.err.println("writing to " + outf);
104             FileOutputStream out = new FileOutputStream(outf);
105             PrintWriter pw = new PrintWriter(out);
106
107             pw.println("package edu.berkeley.fleet.interpreter;");
108             pw.println("import edu.berkeley.sbp.util.ANSI;");
109             pw.println("import edu.berkeley.fleet.api.*;");
110             pw.println("import edu.berkeley.fleet.two.*;");
111             pw.println("import edu.berkeley.fleet.*;");
112             pw.println("import java.util.*;");
113             pw.println("import java.io.*;");
114             pw.println("");
115             pw.println("public class "+filename+" extends InterpreterShip {");
116             pw.println("");
117             pw.println("    public "+filename+"(Interpreter fleet, String name, ShipDescription sd) {");
118             pw.println("       super(fleet, sd);");
119             pw.println("    }");
120             pw.println("");
121             for(DockDescription b : sd) {
122                 String name = b.getName();
123                 pw.print("    InterpreterDock box_");
124                 pw.print(name);
125                 pw.print(" = new InterpreterDock(this, shipDescription.getDockDescription(\""+name+"\"));");
126             }
127             pw.println("");
128             pw.println(sd.getSection("fleeterpreter"));
129             pw.println("}");
130             pw.flush();
131             pw.close();
132         } catch (Exception e) { throw new RuntimeException(e); }
133     }
134
135     // Run //////////////////////////////////////////////////////////////////////////////
136
137     public FleetProcess run(final Instruction[] instructions) {
138         InterpreterProcess ip = initialize(instructions);
139         new Thread(ip).start();
140         return ip;
141     }
142
143     public InterpreterProcess initialize(Instruction[] instr) {
144         return new InterpreterProcess(instr);
145     }
146
147     public class InterpreterProcess extends FleetProcess implements Runnable {
148         private Instruction[] instructions;
149         public void flush() { }
150         public void sendWord(Destination d, BitVector word) {
151             throw new RuntimeException("not implemented");
152         }
153         public void sendToken(Destination d) { throw new RuntimeException("not implemented"); }
154         public InterpreterProcess(Instruction[] instructions) {
155             this.instructions = instructions;
156             for(Instruction i : instructions)
157                 sendInstruction(i);
158         }
159         public Fleet getFleet() { return Interpreter.this; }
160         public void sendInstruction(Instruction i) { dispatch(i); }
161         public Dock getDebugInputDock() { return debugShip.getDock("in"); }
162         public BitVector recvWord() {
163             try {
164                 return debugStream.take();
165             } catch (Exception e) { throw new RuntimeException(e); }
166         }
167         protected void _terminate() { }
168         public void run() {
169             try {
170                 while(!isTerminated())
171                     for(InterpreterShip ship : ships.values())
172                         for(int j=0; j<10; j++)
173                             ship._service();
174                 for(InterpreterShip ship : ships.values())
175                     ship.reset();
176                 debugStream.clear();
177             } catch (Exception e) {
178                 if (isTerminated()) return;
179                 throw new RuntimeException(e);
180             }
181         }
182
183         public void step(Dock d) {
184             ((InterpreterDock)d).service();
185         }
186         
187         public void step(Ship s) {
188             ((InterpreterShip)s).service();
189         }
190
191     }
192 }