177a0ff1c89ed7a188f91108b42b28b182e88893
[fleet.git] / src / edu / berkeley / fleet / api / Instruction.java
1 package edu.berkeley.fleet.api;
2
3 public abstract class Instruction {
4
5     public final Pump pump;
6     public Instruction(Pump pump) { this.pump = pump; }
7     public String toString() { return pump+": "; }
8
9     public static abstract class CountingInstruction extends Instruction {
10         public final int count;
11         public CountingInstruction(Pump pump, int count) {
12             super(pump);
13             this.count = count;
14         }
15         public boolean isStanding() { return count==0; }
16         public abstract boolean isRequeueing();
17         public String toString() { return super.toString()+(count==1?"":(isRequeueing()?("("+(count==0?"*":(count+""))+")"):("["+(count==0?"*":(count+""))+"]")))+" "; }
18     }
19
20     public static class UnClog extends Instruction {
21         public UnClog(Pump pump) { super(pump); }
22         public String toString() { return super.toString() + "unclog;"; }
23     }
24
25     public static class Clog extends Executable {
26         public Clog(Pump pump) { super(pump, 1); }
27         public String toString() { return super.toString() + "clog;"; }
28         public Instruction.Executable decrementCount() { return null; }
29         public boolean isRequeueing() { return false; }
30     }
31
32     public static class Kill extends CountingInstruction {
33         public Kill(Pump pump, int count) { super(pump, count); }
34         public boolean isRequeueing() { return false; }
35         public String toString() { return super.toString() + "kill;"; }
36     }
37
38     public static abstract class Executable extends CountingInstruction {
39         public Executable(Pump pump, int count) { super(pump, count); }
40         public abstract Instruction.Executable decrementCount();
41     }
42
43     public static class Move extends Executable {
44         public final Destination dest;
45
46         public final boolean     tokenIn;
47         public final boolean     dataIn;
48         public final boolean     latch;
49         public final boolean     dataOutDest;
50         public final boolean     dataOut;
51         public final boolean     tokenOut;
52         public final boolean     requeue;
53         public final boolean     ignoreUntilLast;
54
55         public boolean isRequeueing() { return requeue; }
56
57         /** count=0 denotes a standing move */
58         public Move(Pump        pump,
59                           Destination dest,
60                           int         count,
61                           boolean     tokenIn,
62                           boolean     dataIn,
63                           boolean     latch,
64                           boolean     dataOutDest,
65                           boolean     dataOut,
66                           boolean     tokenOut,
67                           boolean     requeue,
68                           boolean     ignoreUntilLast) {
69             super(pump, count);
70             this.dest = dest;
71             this.tokenIn = tokenIn;
72             this.dataIn = dataIn;
73             this.latch = latch;
74             this.dataOutDest = dataOutDest;
75             this.dataOut = dataOut;
76             this.tokenOut = tokenOut;
77             this.requeue = requeue;
78             this.ignoreUntilLast = ignoreUntilLast;
79             if (count < 0)
80                 throw new RuntimeException("count field of an instruction must be >=0");
81             if (pump.isInbox() && tokenIn && dataIn)
82                 throw new RuntimeException("cannot have both \"wait\" and \"take\"/\"recieve\" on an inbox: " + this);
83             if (pump.isOutbox() && tokenOut && dataOut)
84                 throw new RuntimeException("cannot have both \"sendto\" and \"notify\" on an outbox: " + this);
85             if (latch && !dataIn)
86                 throw new RuntimeException("cannot have latch bit set without dataIn bit: " + this);
87         }
88
89         public Instruction.Executable decrementCount() {
90             if (count==1) return null;
91             return new Move(pump, dest, count==0 ? 0 : count-1,
92                             tokenIn, dataIn, latch, dataOutDest, dataOut, tokenOut, requeue, ignoreUntilLast);
93         }
94
95         public String toString() {
96             // FIXME
97             String ret = super.toString();
98             boolean needcomma = false;
99             if (tokenIn)           { ret += (needcomma ? ", " : "") + "wait";    needcomma = true; }
100             if (dataIn && latch)  {
101                 if (pump.isInbox())
102                     ret += (needcomma ? ", " : "") + "receive";
103                 else
104                     ret += (needcomma ? ", " : "") + "take";
105                 needcomma = true;
106             }
107             if (dataIn && !latch)  { ret += (needcomma ? ", " : "") + "dismiss"; needcomma = true; }
108             if (dataOut)  {
109                 if (pump.isInbox() || dest==null)
110                     ret += (needcomma ? ", " : "") + "deliver";
111                 else
112                     ret += (needcomma ? ", " : "") + "sendto "+dest;
113                 needcomma = true;
114             }
115             if (tokenOut) { ret += (needcomma ? ", " : "") + "notify "+dest; needcomma = true; }
116             return ret;
117         }
118
119     }
120
121     public static class LocalLiteral extends Executable {
122         public final long literal;
123         public boolean isRequeueing() { return true; }
124         public LocalLiteral(Pump pump, long literal, int count) {
125             super(pump, count);
126             this.literal = literal;
127         }
128         public Instruction.Executable decrementCount() {
129             if (count==1) return null;
130             return new LocalLiteral(pump, literal, count-1);
131         }
132     }
133
134     public static class CodeBagDescriptor extends Instruction {
135         /** address of CBD, relative to address that this instruction was loaded from */
136         public final long offset;
137         public final long size;
138         public CodeBagDescriptor(Pump pump, long offset, long size) {
139             super(pump);
140             this.offset = offset;
141             this.size = size;
142         }
143         public String toString() {
144             String off = ""+offset;
145             if (offset > 0) off = "+"+off;
146             return "(CBD @"+off+"+"+size+"): sendto " + pump;
147         }
148     }
149
150 }