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