1 package edu.berkeley.fleet.api;
3 public abstract class Instruction {
5 public final Pump pump;
6 public Instruction(Pump pump) { this.pump = pump; }
7 public String toString() { return pump+": "; }
9 public static abstract class CountingInstruction extends Instruction {
10 public final int count;
11 public CountingInstruction(Pump pump, int count) {
15 protected abstract boolean isRequeueing();
16 public String toString() { return super.toString()+(count==1?"":(isRequeueing()?("("+(count==0?"*":(count+""))+")"):("["+(count==0?"*":(count+""))+"]")))+" "; }
19 public static class UnClog extends Instruction {
20 public UnClog(Pump pump) { super(pump); }
21 public String toString() { return super.toString() + "unclog;"; }
24 public static class Clog extends Instruction {
25 public Clog(Pump pump) { super(pump); }
26 public String toString() { return super.toString() + "clog;"; }
29 public static class Kill extends CountingInstruction {
30 public Kill(Pump pump, int count) { super(pump, count); }
31 protected boolean isRequeueing() { return false; }
32 public String toString() { return super.toString() + "kill;"; }
35 public static class Executable extends Instruction {
37 public final Destination dest;
38 public final int count;
40 public final boolean tokenIn;
41 public final boolean dataIn;
42 public final boolean latch;
43 public final boolean dataOutDest;
44 public final boolean dataOut;
45 public final boolean tokenOut;
46 public final boolean requeue;
47 public final boolean ignoreUntilLast;
49 protected boolean isRequeueing() { return requeue; }
51 /** count=0 denotes a standing move */
52 public Executable(Pump pump,
62 boolean ignoreUntilLast) {
66 this.tokenIn = tokenIn;
69 this.dataOutDest = dataOutDest;
70 this.dataOut = dataOut;
71 this.tokenOut = tokenOut;
72 this.requeue = requeue;
73 this.ignoreUntilLast = ignoreUntilLast;
75 throw new RuntimeException("count field of an instruction must be >=0");
76 if (pump.isInbox() && tokenIn && dataIn)
77 throw new RuntimeException("cannot have both \"wait\" and \"take\"/\"recieve\" on an inbox: " + this);
78 if (pump.isOutbox() && tokenOut && dataOut)
79 throw new RuntimeException("cannot have both \"sendto\" and \"notify\" on an outbox: " + this);
81 throw new RuntimeException("cannot have latch bit set without dataIn bit: " + this);
84 public boolean isStanding() {
88 public Instruction.Executable decrementCount() {
89 if (count==1) return null;
90 return new Executable(pump, dest, count==0 ? 0 : count-1,
91 tokenIn, dataIn, latch, dataOutDest, dataOut, tokenOut, requeue, ignoreUntilLast);
94 public String toString() {
96 String ret = super.toString();
97 boolean needcomma = false;
98 if (tokenIn) { ret += (needcomma ? ", " : "") + "wait"; needcomma = true; }
99 if (dataIn && latch) {
101 ret += (needcomma ? ", " : "") + "receive";
103 ret += (needcomma ? ", " : "") + "take";
106 if (dataIn && !latch) { ret += (needcomma ? ", " : "") + "dismiss"; needcomma = true; }
108 if (pump.isInbox() || dest==null)
109 ret += (needcomma ? ", " : "") + "deliver";
111 ret += (needcomma ? ", " : "") + "sendto "+dest;
114 if (tokenOut) { ret += (needcomma ? ", " : "") + "notify "+dest; needcomma = true; }
120 public static class LocalLiteral extends CountingInstruction {
121 public final long literal;
122 public boolean isRequeueing() { return true; }
123 public LocalLiteral(Pump pump, long literal, int count) {
125 this.literal = literal;
129 public static class CodeBagDescriptor extends Instruction {
130 /** address of CBD, relative to address that this instruction was loaded from */
131 public final long offset;
132 public final long size;
133 public CodeBagDescriptor(Pump pump, long offset, long size) {
135 this.offset = offset;
138 public String toString() {
139 String off = ""+offset;
140 if (offset > 0) off = "+"+off;
141 return "(CBD @"+off+"+"+size+"): sendto " + pump;