c3ec5824a1a3929fdb9c05c34275437453731751
[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.fleet.*;
7 import edu.berkeley.sbp.util.ANSI;
8 import edu.berkeley.fleet.api.*;
9 import edu.berkeley.fleet.two.*;
10 import edu.berkeley.fleet.assembler.*;
11 import edu.berkeley.fleet.two.*;
12 import edu.berkeley.fleet.util.*;
13
14 public class Interpreter extends FleetTwoFleet implements Parser.FleetWithDynamicShips {
15
16     public Ship getShip(String type, int ordinal) {
17         for(Ship s : this)
18             if (s.getType().equals(type))
19                 if (ordinal-- < 0)
20                     return s;
21         return null;
22     }
23
24     public int getWordWidth() { return 37; }
25     /** some "halt ship" can turn this on to stop the interpreter */
26     private HashMap<String,InterpreterShip> ships       = new HashMap<String,InterpreterShip>();
27     private BlockingQueue<Long>             debugStream = new LinkedBlockingQueue<Long>();
28
29     public int getWordSize() { return 37; }
30
31     public FleetProcess run(final byte[] instructions) {
32         try {
33             final FleetProcess fp = new FleetProcess() {
34                     public void dispatchInstruction(Instruction i) { throw new RuntimeException(); }
35                     public void invokeInstruction(Instruction i) { throw new RuntimeException("not supported"); }
36                     public Dock getDebugInputDock() { return null; }
37                     public BitVector readWord() {
38                         /*
39                         try {
40                             return debugStream.take();
41                         } catch (Exception e) {
42                             throw new RuntimeException(e);
43                             }*/
44                         throw new RuntimeException();
45                         }
46                     protected void _terminate() {
47                         // FIXME: hack
48                         ships = new HashMap<String,InterpreterShip>();
49                         debugStream = new LinkedBlockingQueue<Long>();
50                     }
51                 };
52             new Thread() {
53                 public void run() {
54                     try {
55                         // find the first icache
56                         InterpreterShip iscratch = null;
57                         for(Ship ship : Interpreter.this)
58                             if (ship.getClass().getSimpleName().equals("Memory")) {
59                                 iscratch = (InterpreterShip)ship;
60                                 break;
61                             }
62                         if (iscratch==null) {
63                             BufferedReader br =
64                                 new BufferedReader(new InputStreamReader(new FileInputStream("ships/Memory.ship")));
65                             ShipDescription sd = new ShipDescription("Memory", br);
66                             iscratch = (InterpreterShip)Class.forName("edu.berkeley.fleet.interpreter.Memory")
67                                 .getConstructor(new Class[] { Interpreter.class, String.class, ShipDescription.class })
68                                 .newInstance(new Object[] { Interpreter.this, "memory", sd });
69                         }
70                         iscratch
71                             .getClass()
72                             .getMethod("boot", new Class[] { byte[].class })
73                             .invoke(iscratch, new Object[] { instructions });
74                         
75                         while(!fp.isTerminated())
76                             for(InterpreterShip ship : ships.values())
77                                 for(int j=0; j<10; j++)
78                                     ship._service();
79                         
80                         // run the ships a bit longer for good measure
81                         for(int i=0; i<100; i++)
82                             for(InterpreterShip ship : ships.values())
83                                 for(int j=0; j<10; j++)
84                                     ship._service();
85                         
86                         // check the state of the ships
87                         for(InterpreterShip ship : ships.values())
88                             ship.shutdown();
89                         
90                         Log.println(ANSI.yellow("    DONE: ====== FLEET is halted.  Have a nice day.  ======"));
91                         
92                     } catch (Exception e) {
93                         if (fp.isTerminated()) return;
94                         throw new RuntimeException(e);
95                     }
96                 }
97             }.start();
98             return fp;
99         } catch (Exception e) {
100             throw new RuntimeException(e);
101         }
102     }
103
104     public void dispatch(Instruction i, long address) {
105         Log.dispatch(i);
106            
107         if (i instanceof Instruction.Tail) {
108             Instruction.Tail ic = (Instruction.Tail)i;
109             ((InstructionDock)(ic.dock)).tailged--;
110
111         } else {
112             InterpreterDock sourceDock = (InterpreterDock)(((Instruction)i).dock);
113             ((InstructionDock)sourceDock).addInstruction(((Instruction)i));
114         }
115     }
116
117     public Iterator<Ship> iterator() { return (Iterator<Ship>)(Object)ships.values().iterator(); }
118
119     public Ship createShip(String shipType, String shipname) {
120         try {
121             Class c = Class.forName("edu.berkeley.fleet.interpreter."+shipType);
122             Constructor con = c.getConstructor(new Class[] { Interpreter.class, String.class, ShipDescription.class });
123             BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("ships/"+shipType+".ship")));
124             ShipDescription sd = new ShipDescription(shipType, br);
125             InterpreterShip ret = (InterpreterShip)con.newInstance(new Object[] { this, shipname, sd });
126             ships.put(shipname, ret);
127             return ret;
128         } catch (Exception e) {
129             e.printStackTrace();
130             return null;
131         }
132     }
133
134     public void debug(long data) {
135         try {
136             if (debugStream != null) debugStream.put(data);
137             else Log.println(ANSI.invert("   DEBUG: got a datum: " +  data+ANSI.clreol()));
138         } catch (Exception e) {
139             throw new RuntimeException(e);
140         }
141     }
142
143     // Instruction Encoding /////////////////////////////////////////////////////////////////////////
144
145     public Dock getUniversalSource() { return null; }
146
147         public long getDestAddr(Path path) { throw new RuntimeException(); }
148         public long getBoxInstAddr(Dock box) { return ((InterpreterDock)box).getDestAddr(); }
149         public Path getPathByAddr(Dock source, long dest) { throw new RuntimeException(); }
150         public Destination getDestByAddr(long dest) {
151             /*
152             for(Ship ship : Interpreter.this)
153                 for(Dock bb : ship)
154                     if (getDestAddr(bb.getDataDestination())==dest)
155                         return bb.getDataDestination();
156             */
157             return null;
158         }
159         public Dock getBoxByInstAddr(long dest) {
160             for(Ship ship : Interpreter.this)
161                 for(Dock bb : ship)
162                     if (getBoxInstAddr(bb) == dest)
163                         return bb;
164             return null;
165         }
166
167
168     // ShipDescription //////////////////////////////////////////////////////////////////////////////
169
170     public void expand(ShipDescription sd) {
171         try {
172             String filename = sd.getName();
173             //String filename = (sd.getName().charAt(0)+"").toUpperCase() + sd.getName().substring(1).toLowerCase();
174             File outf = new File("build/java/edu/berkeley/fleet/interpreter/"+filename+".java");
175             new File(outf.getParent()).mkdirs();
176             System.err.println("writing to " + outf);
177             FileOutputStream out = new FileOutputStream(outf);
178             PrintWriter pw = new PrintWriter(out);
179
180             pw.println("package edu.berkeley.fleet.interpreter;");
181             pw.println("import edu.berkeley.sbp.util.ANSI;");
182             pw.println("import edu.berkeley.fleet.api.*;");
183             pw.println("import edu.berkeley.fleet.two.*;");
184             pw.println("import edu.berkeley.fleet.*;");
185             pw.println("import java.util.*;");
186             pw.println("import java.io.*;");
187             pw.println("");
188             pw.println("public class "+filename+" extends InterpreterShip {");
189             pw.println("");
190             for(DockDescription b : sd) {
191                 String name = b.getName();
192                 pw.print("    ");
193                 if ( b.isInputDock()) pw.print("Inbox");
194                 if (!b.isInputDock()) pw.print("Outbox");
195                 pw.print(" box_");
196                 pw.print(name);
197                 pw.print(" = new ");
198                 if ( b.isInputDock()) pw.print("Inbox");
199                 if (!b.isInputDock()) pw.print("Outbox");
200                 pw.print("(this, new String[] { ");
201                 boolean first = true;
202                 pw.print("\"\"");
203                 pw.println("}, shipDescription.getDockDescription(\""+name+"\"));");
204             }
205             pw.println("");
206             pw.println("    public "+filename+"(Interpreter fleet, String name, ShipDescription sd) {");
207             pw.println("       super(fleet, name, sd);");
208             for(DockDescription b : sd)
209                 pw.println("       addDock(\""+b.getName()+"\", box_"+b.getName()+");");
210             pw.println("    }");
211             pw.println("");
212             pw.println(sd.getSection("fleeterpreter"));
213             pw.println("}");
214             pw.flush();
215             pw.close();
216         } catch (Exception e) { throw new RuntimeException(e); }
217     }
218
219 }
220