initial commit
[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
29     public static @bind.as("NamedCodeBag") CodeBag codeBag(String name, Object[] statements) {
30         return codeBag(statements);
31     }
32
33     public static @bind.as("CodeBag") CodeBag codeBag(Object[] statements) {
34         CodeBag ret = new CodeBag();
35         for(Object s : statements) ret.add((Statement)s);
36         return ret;
37     }
38
39     public static @bind.as("->")       Statement move(Port source, Port[] dest) {
40         return new Move(source, dest);
41     }
42
43     public static @bind.as("->*")      Statement smove(Port source, Port[] dest) {
44         //return new SMove(source, dest);
45         return null;
46     }
47
48     public static @bind.as(":=")       Statement gets(Port dest, Port source) {
49         return new Move(source, new Port[] { dest });
50     }
51
52     public static @bind.as("Port") Port port(String ship, String port) {
53         return new Port(ship, port);
54     }
55     public static @bind.as("Port") Port port(String ship) {
56         return new Port(ship, null);
57     }
58
59     public static @bind.as("ShipName") String    shipname(String name, String index) { return index==null?name:name+index; }
60     public static @bind.as("PortName") String    portname(String name, String index) { return index==null?name:name+index; }
61
62     public static interface Source { }
63     public static interface Destination { }
64     public static interface Statement {
65         public void dispatch(Fleet fleet);
66     }
67
68     public static @bind.as("Program") Program program(Directive[] directives, CodeBag rootCodeBag) {
69         return new Program(directives, rootCodeBag);
70     }
71
72     public static abstract class Directive {
73         public void configure(Fleet fleet) {
74         }
75     }
76
77     public static @bind.as("Memory") MemoryDirective memory(String[] values) {
78         return new MemoryDirective(values);
79     }
80
81     public static class MemoryDirective extends Directive{
82         private int[] mem;
83         public MemoryDirective(String[] values) {
84             this.mem = new int[values.length];
85             for(int i=0; i<mem.length; i++)
86                 mem[i] = Integer.parseInt(values[i]);
87         }
88         public void configure(Fleet fleet) {
89             fleet.mem = mem;
90         }
91     }
92
93     public static class ShipDirective extends Directive {
94         String shipname;
95         String classname;
96         public @bind.as("Ship") ShipDirective(String shipname, String classname) {
97             this.shipname = shipname;
98             this.classname = classname;
99         }
100         public void configure(Fleet fleet) {
101             for(String s : fleet.imports)
102                 if (tryCreate(fleet, s))
103                     return;
104             throw new RuntimeException("unable to instantiate class " + classname);
105         }
106         private boolean tryCreate(Fleet fleet, String packagename) {
107             try {
108                 Class c = Class.forName(packagename+"."+classname);
109                 Constructor con = c.getConstructor(new Class[] { Fleet.class, String.class });
110                 con.newInstance(new Object[] { fleet, shipname });
111                 return true;
112             } catch (Exception e) {
113                 return false;
114             }
115         }
116     }
117
118     public static class ImportDirective extends Directive {
119         String packagename;
120         public @bind.as("Import") ImportDirective(String packagename) {
121             this.packagename = packagename;
122         }
123         public void configure(Fleet fleet) {
124             fleet.imports.add(packagename);
125         }
126     }
127
128     public static class Move implements Statement {
129         Port source;
130         Port[] dest;
131         public Move(Port source, Port[] dest) { this.source = source; this.dest = dest; }
132         public void dispatch(Fleet fleet) {
133             Ship.Outbox ob = fleet.getOutbox(source.ship, source.port);
134             for(Port d : dest) {
135                 Ship.Inbox ib = fleet.getInbox(d.ship, d.port);
136                 ob.addDestination(ib);
137                 System.out.println("instr: " + ob + " -> " + ib);
138             }
139         }
140         public String toString() {
141             StringBuffer sb = new StringBuffer();
142             sb.append(source + " -> ");
143             sb.append(dest[0]);
144             for(int i=1; i<dest.length; i++) {
145                 sb.append(", " + dest[i]);
146             }
147             return sb.toString();
148         }
149     }
150
151     public static class Port implements Source, Destination {
152         String ship;
153         String port;
154         public Port(String ship, String port) {
155             this.ship = ship;
156             this.port = port;
157         }
158         public String toString() { return port==null?ship:ship+"."+port; }
159     }
160
161     public static class CodeBag extends ArrayList<Statement> implements Statement {
162         public void dispatch(Fleet fleet) {
163             for(Statement s : this)
164                 s.dispatch(fleet);
165         }
166         public String toString() {
167             StringBuffer s = new StringBuffer();
168             for(Statement stmt : this) s.append("\n"+stmt);
169             return "{"+indentify(s.toString())+"\n}";
170         }
171     }
172
173     private static String indentify(String s) {
174         StringBuffer s2 = new StringBuffer();
175         for(int i=0; i<s.length(); i++) {
176             char c = s.charAt(i);
177             s2.append(c);
178             if (c == '\n')
179                 s2.append("  ");
180         }
181         return s2.toString();
182     }
183
184 }