fix splitpane positioning
[fleet.git] / src / edu / berkeley / fleet / Program.java
1 package edu.berkeley.fleet;
2
3 import edu.berkeley.sbp.*;
4 import edu.berkeley.sbp.chr.*;
5 import edu.berkeley.sbp.misc.*;
6 import edu.berkeley.sbp.meta.*;
7 import edu.berkeley.sbp.bind.*;
8 import edu.berkeley.sbp.util.*;
9 import java.util.*;
10 import java.io.*;
11 import java.lang.reflect.*;
12
13 public class Program {
14
15         Directive[] directives;
16         CodeBag root;
17         public Program(Directive[] directives, CodeBag root) {
18             this.root = root;
19             this.directives = directives;
20         }
21         public void configure(Fleet fleet) {
22             for(Directive directive : directives)
23                 directive.configure(fleet);
24             root.dispatch(fleet);
25         }
26
27     // inner classes //////////////////////////////////////////////////////////////////////////////
28     public static HashMap<String,CodeBag> namedCodeBags = new HashMap<String,CodeBag>();
29
30     public static @bind.as("NamedCodeBag") Statement codeBag(String name, CodeBag body) {
31         namedCodeBags.put(name, body);
32         return new NullStatement();
33     }
34
35     public static @bind.as("CodeBag") CodeBag codeBag(Object[] statements) {
36         CodeBagReal ret = new CodeBagReal();
37         for(Object s : statements) ret.add((Statement)s);
38         return ret;
39     }
40
41     public static @bind.as("CodeBagRef") CodeBag codeBagRef(String name) {
42         return new CodeBagRef(name);
43     }
44
45     public static @bind.as("->")       Statement move(Port source, Port[] dest) {
46         return new Move(source, dest);
47     }
48
49     public static @bind.as("CodeBagMove") Statement cbmove(CodeBag cb, Port dest) {
50         return new CodeBagMove(cb, new Port[] { dest });
51     }
52
53     public static @bind.as("CodeBagMoveX") Statement cbmovex(Port dest, CodeBag cb) {
54         return new CodeBagMove(cb, new Port[] { dest });
55     }
56
57     public static @bind.as("LiteralMove")    Statement move(String value, Port[] dest) {
58         return new LiteralMove(Integer.parseInt(value), dest);
59     }
60
61     public static @bind.as("->*")      Statement smove(Port source, Port[] dest) {
62         //return new SMove(source, dest);
63         return null;
64     }
65
66     public static @bind.as("<-")       Statement gets(Port dest, Port source) {
67         return new Move(source, new Port[] { dest });
68     }
69
70     public static @bind.as("Port") Port port(String ship, String port) {
71         return new Port(ship, port);
72     }
73     public static @bind.as("Port") Port port(String ship) {
74         return new Port(ship, null);
75     }
76
77
78     public static @bind.as("ShipName") String    shipname(String name, String index) { return index==null?name:name+index; }
79     public static @bind.as("PortName") String    portname(String name, String index) { return index==null?name:name+index; }
80
81     public static interface Source { }
82     public static interface Destination { }
83     public static interface Statement {
84         public void dispatch(Fleet fleet);
85     }
86     public static class NullStatement implements Statement {
87         public void dispatch(Fleet fleet) { }
88     }
89
90     public static @bind.as("Program") Program program(Directive[] directives, CodeBag rootCodeBag) {
91         return new Program(directives, rootCodeBag);
92     }
93
94     public static abstract class Directive {
95         public void configure(Fleet fleet) {
96         }
97     }
98
99     public static @bind.as("Memory") MemoryDirective memory(String[] values) {
100         return new MemoryDirective(values);
101     }
102
103     public static class MemoryDirective extends Directive{
104         private int[] mem;
105         public MemoryDirective(String[] values) {
106             this.mem = new int[values.length];
107             for(int i=0; i<mem.length; i++)
108                 mem[i] = Integer.parseInt(values[i]);
109         }
110         public void configure(Fleet fleet) {
111             fleet.mem = mem;
112         }
113     }
114
115     public static class ShipDirective extends Directive {
116         String shipname;
117         String classname;
118         public @bind.as("Ship") ShipDirective(String shipname, String classname) {
119             this.shipname = shipname;
120             this.classname = classname;
121         }
122         public void configure(Fleet fleet) {
123             for(String s : fleet.imports)
124                 if (tryCreate(fleet, s))
125                     return;
126             throw new RuntimeException("unable to instantiate class " + classname);
127         }
128         private boolean tryCreate(Fleet fleet, String packagename) {
129             try {
130                 Class c = Class.forName(packagename+"."+classname);
131                 Constructor con = c.getConstructor(new Class[] { Fleet.class, String.class });
132                 con.newInstance(new Object[] { fleet, shipname });
133                 return true;
134             } catch (Exception e) {
135                 return false;
136             }
137         }
138     }
139
140     public static class ImportDirective extends Directive {
141         String packagename;
142         public @bind.as("Import") ImportDirective(String packagename) {
143             this.packagename = packagename;
144         }
145         public void configure(Fleet fleet) {
146             fleet.imports.add(packagename);
147         }
148     }
149
150     public static class Move implements Statement {
151         Port source;
152         Port[] dest;
153         public Move(Port source, Port[] dest) { this.source = source; this.dest = dest; }
154         public void dispatch(Fleet fleet) {
155             Ship.Outbox ob = fleet.getOutbox(source.ship, source.port);
156             for(Port d : dest) {
157                 Ship.Inbox ib = fleet.getInbox(d.ship, d.port);
158                 ob.addDestination(ib);
159                 Log.println("instr: " + ob + " -> " + ib);
160             }
161         }
162         public String toString() {
163             StringBuffer sb = new StringBuffer();
164             sb.append(source + " -> ");
165             sb.append(dest[0]);
166             for(int i=1; i<dest.length; i++) {
167                 sb.append(", " + dest[i]);
168             }
169             return sb.toString();
170         }
171     }
172
173     public static class LiteralMove implements Statement {
174         int val;
175         Port[] dest;
176         public LiteralMove(int val, Port[] dest) { this.val = val; this.dest = dest; }
177         public void dispatch(Fleet fleet) {
178             for(Port d : dest) {
179                 Ship.Inbox ib = fleet.getInbox(d.ship, d.port);
180                 ib.add(val);
181                 Log.println("instr: " + val + " -> " + ib);
182             }
183         }
184         public String toString() {
185             StringBuffer sb = new StringBuffer();
186             sb.append(val + " -> ");
187             sb.append(dest[0]);
188             for(int i=1; i<dest.length; i++) {
189                 sb.append(", " + dest[i]);
190             }
191             return sb.toString();
192         }
193     }
194
195     public static class CodeBagMove implements Statement {
196         CodeBag cb;
197         Port[] dest;
198         public CodeBagMove(CodeBag cb, Port[] dest) { this.cb = cb; this.dest = dest; }
199         public void dispatch(Fleet fleet) {
200             for(Port d : dest) {
201                 Ship.Inbox ib = fleet.getInbox(d.ship, d.port);
202                 ib.add(cb.getIdentifier());
203                 Log.println("instr: codebag #" + cb.getIdentifier() + " -> " + ib);
204             }
205         }
206         public String toString() {
207             StringBuffer sb = new StringBuffer();
208             sb.append(cb + " -> ");
209             sb.append(dest[0]);
210             for(int i=1; i<dest.length; i++) {
211                 sb.append(", " + dest[i]);
212             }
213             return sb.toString();
214         }
215     }
216
217     public static class Port implements Source, Destination {
218         String ship;
219         String port;
220         public Port(String ship, String port) {
221             this.ship = ship;
222             this.port = port;
223         }
224         public String toString() { return port==null?ship:ship+"."+port; }
225     }
226
227     public static int master_identifier = 1;
228     public static HashMap<Integer,CodeBagReal> allCodeBags = new HashMap<Integer,CodeBagReal>();
229
230     public interface CodeBag extends Statement {
231         public int getIdentifier();
232     }
233
234     public static class CodeBagRef implements CodeBag {
235         String name;
236         public CodeBagRef(String name) { this.name = name; }
237         public void dispatch(Fleet fleet) {
238             namedCodeBags.get(name).dispatch(fleet);
239         }
240         public int getIdentifier() {
241             return namedCodeBags.get(name).getIdentifier();
242         }
243     }
244
245     public static class CodeBagReal extends ArrayList<Statement> implements Statement, CodeBag {
246         int identifier;
247         public CodeBagReal() {
248             this.identifier = master_identifier++;
249             allCodeBags.put(identifier, this);
250         }
251         public int getIdentifier() {
252             return identifier;
253         }
254         public void dispatch(Fleet fleet) {
255             for(Statement s : this)
256                 s.dispatch(fleet);
257         }
258         public String toString() {
259             StringBuffer s = new StringBuffer();
260             for(Statement stmt : this) s.append("\n"+stmt);
261             return "{"+indentify(s.toString())+"\n}";
262         }
263     }
264
265     private static String indentify(String s) {
266         StringBuffer s2 = new StringBuffer();
267         for(int i=0; i<s.length(); i++) {
268             char c = s.charAt(i);
269             s2.append(c);
270             if (c == '\n')
271                 s2.append("  ");
272         }
273         return s2.toString();
274     }
275
276 }