import edu.berkeley.sbp.misc.*;
import edu.berkeley.sbp.meta.*;
import edu.berkeley.sbp.util.*;
+import static edu.berkeley.fleet.util.BitManipulations.*;
+import edu.berkeley.fleet.two.*;
+import edu.berkeley.fleet.api.Instruction.Set;
+import static edu.berkeley.fleet.api.Instruction.*;
+import static edu.berkeley.fleet.api.Instruction.Set.*;
+import static edu.berkeley.fleet.api.Predicate.*;
+import edu.berkeley.fleet.two.*;
+import edu.berkeley.fleet.fpga.*;
+import edu.berkeley.fleet.interpreter.*;
import java.util.*;
import java.io.*;
+
/**
* @author Adam Megacz <megacz@cs.berkeley.edu>
*/
public class Parser {
- Parser(Fleet fleet) {
+ private static final BitVector SIGNAL_ZERO = new BitVector(1);
+ private static final BitVector SIGNAL_ONE = new BitVector(1);
+ static {
+ SIGNAL_ONE.set(0,true);
+ }
+
+ /** WARNING: this class may change in the future; it is not a stable interface */
+ public Parser(Fleet fleet) {
expect = new ArrayList<Long>();
this.fleet = fleet;
}
if (grammar != null) return grammar;
InputStream grammarStream =
Parser.class.getClassLoader().getResourceAsStream("edu/berkeley/fleet/assembler/fleet.g");
- CharParser metaGrammarParser = new CharParser(MetaGrammar.newInstance());
+ CharParser metaGrammarParser = new CharParser(GrammarAST.getMetaGrammar());
Tree<String> parsedGrammar = metaGrammarParser.parse(new CharInput(grammarStream)).expand1();
- grammar = GrammarAST.buildFromAST(parsedGrammar, "s", new File[0]);
+ grammar = GrammarAST.buildFromAST(parsedGrammar, "s", new GrammarAST.ImportResolver() {
+ public InputStream getImportStream(String importname) { return null; }
+ });
return grammar;
}
- Tree<String> parse(Reader r) throws Exception {
- return new CharParser(getGrammar()).parse(new CharInput(r)).expand1();
+ // FIXME: this ought to be cached via serialization, I think
+ private static CharParser cp = null;
+ Tree<String> parseIt(Reader r) throws Exception {
+ if (cp==null)
+ cp = new CharParser(getGrammar());
+ CharInput ci = new CharInput(r);
+ Forest f = cp.parse(ci);
+ return f.expand1();
}
- public void parse(Reader r, OutputStream out) throws Exception {
+ public Instruction[] parse(Reader r) throws Exception {
// this needs to be "code bag zero"
CodeBag baseCodeBag = new CodeBag();
CodeBag rootCodeBag = new CodeBag();
skip = false;
- baseCodeBag.add(new Instruction.Literal.CodeBagDescriptor(null, rootCodeBag.getFakeAddress(), 1));
- walk((Tree<String>)parse(r), rootCodeBag);
- if (fleet instanceof edu.berkeley.fleet.fpga.Fpga)
- ((edu.berkeley.fleet.fpga.Fpga)fleet).dumpFabric(true);
+ Tree<String> parsed = (Tree<String>)parseIt(r);
+ walk(parsed, rootCodeBag);
// map from arbitrary identifiers to actual addresses
int[] codeBagMap = new int[codeBags.size()];
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- DataOutputStream dos = new DataOutputStream(baos);
int count = 0;
for(int i=0; i<codeBags.size(); i++) {
CodeBag c = codeBags.get(i);
- dos.flush();
codeBagMap[i] = count;
for(Instruction inst : c) {
- fleet.writeInstruction(dos, inst);
count++;
}
}
// now write for real
- dos = new DataOutputStream(out);
count = 0;
+ ArrayList<Instruction> ret = new ArrayList<Instruction>();
for(int i=0; i<codeBags.size(); i++) {
CodeBag c = codeBags.get(i);
- dos.flush();
- for(Instruction inst : c) {
- if (inst instanceof Instruction.Literal.CodeBagDescriptor) {
- dos.flush();
- Instruction.Literal.CodeBagDescriptor old = (Instruction.Literal.CodeBagDescriptor)inst;
- int offset = codeBagMap[(int)old.offset];// - count;
- inst = new Instruction.Literal.CodeBagDescriptor(old.pump,
- offset,
- codeBags.get((int)old.offset).size());
- //System.out.println("cbd: " + offset + " " + codeBags.get((int)old.offset).size() + " " + codeBags.get((int)old.offset).name + " " + codeBags.get((int)old.offset));
+ for(int j=0; j<c.size(); j++) {
+ Instruction inst = c.get(j);
+ if (c.isCBD.contains(j)) {
+ Set old = (Set)inst;
+ long lit = 0;
+ lit = ((FleetTwoFleet)fleet).CBD_SIZE.setval(lit, codeBags.get((int)old.immediate).size());
+ lit = ((FleetTwoFleet)fleet).CBD_OFFSET.setval(lit, codeBagMap[(int)old.immediate]);
+ inst = new Set(old.dock, IgnoreFlagD, SetDest.DataLatch, lit);
}
- fleet.writeInstruction(dos, inst);
+ ret.add(inst);
count++;
}
}
- dos.flush();
- out.flush();
- out.close();
+ long startcbd = 0;
+ for(int i=0; i<codeBags.size(); i++) {
+ if (codeBags.get(i)==rootCodeBag) {
+ long lit = 0;
+ lit = ((FleetTwoFleet)fleet).CBD_SIZE.setval(lit, codeBags.get(i).size());
+ lit = ((FleetTwoFleet)fleet).CBD_OFFSET.setval(lit, codeBagMap[i]);
+ startcbd = lit;
+ }
+ }
+ if (codeBags.size()<=2)
+ return (Instruction[])ret.toArray(new Instruction[0]);
+ return fixup((Instruction[])ret.toArray(new Instruction[0]), startcbd);
+ }
+
+ private Instruction[] fixup(Instruction[] instructions, long startcbd) {
+ ArrayList<Instruction> ret = new ArrayList<Instruction>();
+ Fleet fpga = fleet;
+
+ Dock inAddrWrite = null;
+ Dock inDataWrite = null;
+ Dock inCBD = null;
+ Dock out = null;
+ Dock debugIn = null;
+ Dock ihorn = null;
+
+ for(Ship ship : fpga) {
+ if ("Memory".equals(ship.getType()) && ship.getOrdinal()==0) {
+ inAddrWrite = ship.getDock("inAddrWrite");
+ inDataWrite = ship.getDock("inDataWrite");
+ inCBD = ship.getDock("inCBD");
+ out = ship.getDock("out");
+ ihorn = out;
+ //ihorn = ship.getDock("outIhorn");
+ }
+ if ("Debug".equals(ship.getType()) && ship.getOrdinal()==0) {
+ debugIn = ship.getDock("in");
+ }
+ }
+
+ for(int i=0; i<instructions.length; i++) {
+ long lit = ((FleetTwoFleet)fpga).writeInstruction(instructions[i], out);
+ ret.add(discard(out));
+ ret.add(new Instruction.Shift(inDataWrite, IgnoreFlagD, new BitVector(fpga.getShiftWidth()).set(getField(36, 19, lit))));
+ ret.add(new Instruction.Shift(inDataWrite, IgnoreFlagD, new BitVector(fpga.getShiftWidth()).set(getField(18, 0, lit))));
+ ret.add(deliver(inDataWrite));
+ ret.add(new Instruction.Shift(inAddrWrite, IgnoreFlagD, new BitVector(fpga.getShiftWidth()).set(getField(36, 19, i))));
+ ret.add(new Instruction.Shift(inAddrWrite, IgnoreFlagD, new BitVector(fpga.getShiftWidth()).set(getField(18, 0, i))));
+ ret.add(deliver(inAddrWrite));
+ }
+ ret.add(new Instruction.Shift(inCBD, IgnoreFlagD, new BitVector(fpga.getShiftWidth()).set(getField(36, 19, startcbd))));
+ ret.add(new Instruction.Shift(inCBD, IgnoreFlagD, new BitVector(fpga.getShiftWidth()).set(getField(18, 0, startcbd))));
+ ret.add(wait(inCBD));
+ ret.add(deliver(inCBD));
+ ret.add(sendto(out, out.getPath(inCBD.getDataDestination(),null)));
+
+ int count = (int)((FleetTwoFleet)fleet).CBD_SIZE.getval(startcbd);
+ // FIXME FIXME FIXME!
+ int MAX_ILC = 31;
+ int num_instrs = 0;
+ while(count > 0) {
+ int num = Math.min(count, MAX_ILC);
+ num_instrs+=2;
+ count -= num;
+ ret.add(new Instruction.Set(ihorn, IgnoreFlagD, SetDest.InnerLoopCounter, num));
+ ret.add(new Instruction.Move(ihorn, IgnoreFlagD, false, null,false,true,true,true,true,false));
+ }
+ if (num_instrs > ihorn.getInstructionFifoSize()) throw new RuntimeException();
+
+ return (Instruction[])ret.toArray(new Instruction[0]);
}
/** in the first pass, codebags are assigned "addresses" in arbitrary order */
for(Tree<String> statement : t.child(1))
fillCodeBag(statement, cb);
- } else if (head.equals("Import")) {
- // ignored
-
- } else if (head.equals("Ship")) {
+ } else if (head.equals("#ship")) {
String name = name(t.child(0));
String type = string(t.child(1));
- Ship ship = null;
-
- if (fleet instanceof Fleet.WithDynamicShips) {
- Fleet.WithDynamicShips dyn = ((Fleet.WithDynamicShips)fleet);
- ship = dyn.createShip(type, name);
- if (ship==null)
- throw new RuntimeException("couldn't find a ship called \""+type+"\"");
- } else {
- ship = allocateShip(type);
- }
+ Ship ship = allocateShip(type);
shipMap.put(name, ship);
- } else if (head.equals("Include")) {
- try {
- walk(parse(new InputStreamReader(new FileInputStream(string(t.child(0))))), cb);
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
-
- } else if (head.equals("Expect")) {
- expect.add(Long.parseLong(string(t.child(0))));
- } else if (head.equals("Skip")) {
+ } else if (head.equals("#expect")) {
+ expect.add(number(t.child(0)));
+ } else if (head.equals("#skip")) {
skip = true;
}
}
- String string(Tree<String> t) {
+ private static String string(Tree<String> t) {
String ret = "";
if (t.head() != null) ret += t.head();
for(Tree<String> c : t)
return ret;
}
- String name(Tree<String> t) {
+ private static String stringBody(Tree<String> t) {
+ String ret = "";
+ for(Tree<String> c : t)
+ ret += string(c);
+ return ret;
+ }
+
+ private static String name(Tree<String> t) {
return string(t.child(0))+string(t.child(1));
}
- Destination portReference(Tree<String> t) {
- if (!"Port".equals(t.head()) && !"SubPort".equals(t.head()) && !"ShipSpecificLiteral".equals(t.head())) return null;
+ Path path(Dock dock, Tree<String> t) {
+ if (!"Dock".equals(t.head()) && !"Destination".equals(t.head()) && !"ShipSpecificLiteral".equals(t.head())) return null;
String shipName = name(t.child(0));
String portName = name(t.child(1));
- String subPort = t.size()<3 ? null : name(t.child(2));
Ship ship = shipMap.get(shipName);
if (ship==null) throw new RuntimeException("no such ship \""+shipName+"\"");
Destination ret = null;
- Pump bb = null;
- for(Pump b : ship.getPumps())
+ Dock bb = null;
+ for(Dock b : ship)
if (b.getName().equals(portName)) {
bb = b;
}
if (bb==null)
- throw new RuntimeException("no such pump \""+portName+"\"");
- if (subPort==null) subPort="";
- for(Destination d : bb.getDestinations())
- if (d.getDestinationName().equals(subPort))
- return d;
- if (ret==null)
- throw new RuntimeException("no such pump \""+portName+"\" on ships of type \""+ship.getType()+"\"");
- return ret;
+ throw new RuntimeException("no such dock \""+portName+"\"");
+ if (t.size() >= 3) {
+ if (":i".equals(t.child(2).head())) return dock.getPath(bb.getInstructionDestination(),SIGNAL_ZERO);
+ if (":1".equals(t.child(2).head())) return dock.getPath(bb.getDataDestination(),SIGNAL_ONE);
+ if (":0".equals(t.child(2).head())) return dock.getPath(bb.getDataDestination(),SIGNAL_ZERO);
+ }
+ return dock.getPath(bb.getDataDestination(),SIGNAL_ZERO);
}
- Pump pump(Tree<String> t) {
- if (!"Port".equals(t.head()) && !"SubPort".equals(t.head()) && !"ShipSpecificLiteral".equals(t.head()))
+ Dock dock(Tree<String> t) {
+ if (!"Dock".equals(t.head()) && !"Destination".equals(t.head()) && !"ShipSpecificLiteral".equals(t.head()))
throw new RuntimeException(t+"");
String shipName = name(t.child(0));
String portName = name(t.child(1));
Ship ship = shipMap.get(shipName);
if (ship==null) throw new RuntimeException("no such ship \""+shipName+"\"");
- Pump bb = null;
- for(Pump b : ship.getPumps())
+ Dock bb = null;
+ for(Dock b : ship)
if (b.getName().equals(portName))
return b;
- throw new RuntimeException("no such pump \""+portName+"\"");
+ throw new RuntimeException("no such dock \""+portName+"\"");
}
private HashMap<String,Integer> numAllocated = new HashMap<String,Integer>();
allocated--;
}
}
- throw new RuntimeException("no more ships of type \""+shipType+"\"");
+ if (fleet instanceof FleetWithDynamicShips) {
+ FleetWithDynamicShips dyn = ((FleetWithDynamicShips)fleet);
+ Ship ship = dyn.createShip(shipType, shipType+allocated);
+ if (ship==null)
+ throw new RuntimeException("couldn't find a ship called \""+shipType+"\"");
+ return ship;
+ } else {
+ throw new RuntimeException("no more ships of type \""+shipType+"\"");
+ }
}
private long parseSSL(Tree t) {
break;
}
}
- Pump chosenport = chosenship.getPump(portName);
+ if (chosenship==null) throw new RuntimeException("no ships of type " + shipType);
+ Dock chosenport = chosenship.getDock(portName);
Tree specs = t.child(2);
long literal = 0;
for(int i=0; i<specs.size(); i++) {
Tree tt = specs.child(i);
- literal |= chosenport.resolveLiteral(string(tt));
+ literal |= resolveLiteral(chosenport, stringBody(tt));
}
return literal;
}
+ private static long resolveLiteral(Dock dd, String s) {
+ long val = 0;
+ long ret = 0;
+ boolean hasval = false;
+ if (s.indexOf('=') != -1) {
+ val = Long.parseLong(s.substring(s.indexOf('=')+1));
+ s = s.substring(0, s.indexOf('='));
+ hasval = true;
+ }
+ ShipDescription.Constant c = ((FleetTwoDock)dd).getDockConstant(s);
+ if (c==null) throw new RuntimeException("no constant " + s + " on dock " + dd);
+ ret |= c.setbits;
+ ret &= ~c.clearbits;
+ if (hasval)
+ ret |= ((~(0xffffffffffffffffL << c.numberWidth)) & val) << c.numberOffset;
+ return ret;
+ }
+
+ private static FlagFunction parseFlags(Tree<String> t) {
+ FlagFunction ret = FlagFunction.ZERO;
+ for(int i=0; i<t.size(); i++) {
+ String s = t.child(i).head();
+ if (s.equals("0")) ret = ret.add(FlagFunction.ZERO);
+ if (s.equals("1")) ret = ret.add(FlagFunction.ONE);
+ if (s.equals("a")) ret = ret.add(FlagA);
+ if (s.equals("!a")) ret = ret.add(NotFlagA);
+ if (s.equals("b")) ret = ret.add(FlagB);
+ if (s.equals("!b")) ret = ret.add(NotFlagB);
+ if (s.equals("c")) ret = ret.add(FlagC);
+ if (s.equals("!c")) ret = ret.add(NotFlagC);
+ }
+ return ret;
+ }
+
+ private int anoncount = 1;
void fillCodeBag(Tree<String> t, CodeBag cb) {
if (t.head()==null) return;
- else if (t.head().equals("NamedCodeBag")) {
+ else if (t.head().equals("CodeBagDef")) {
CodeBag cb2 = getCodeBag(name(t.child(0)));
for(Tree<String> statement : t.child(1))
fillCodeBag(statement, cb2);
} else if (t.head().equals("Fiber")) {
- Pump pump = (Pump)pump(t.child(0));
+ Dock dock = (Dock)dock(t.child(0));
OUTER: for(Tree tt : t.child(1)) {
+
+ if ("tail".equals(tt.head())) {
+ cb.add(new Tail(dock));
+ continue;
+ } else if ("head".equals(tt.head())) {
+ cb.add(new Head(dock));
+ continue;
+ }
+
int count = 1;
- Tree ttx = null;
- boolean requeue = false;
- ttx = tt.child(1);
- if (tt.size() > 1 && tt.child(0).size()>0) {
- tt = tt.child(0).child(0);
- if (tt.head().equals("BrackStar")) {
- count = 0;
- requeue = false;
- } else if (tt.head().equals("ParenStar")) {
+ Predicate predicate = Default;
+ boolean interruptible = false;
+ for(int i=0; i<tt.child(0).size(); i++) {
+ Tree ttt = tt.child(0).child(i);
+ if ("[a]".equals(ttt.head())) predicate = FlagA;
+ if ("[b]".equals(ttt.head())) predicate = FlagB;
+ if ("[c]".equals(ttt.head())) predicate = FlagC;
+ if ("[!a]".equals(ttt.head())) predicate = NotFlagA;
+ if ("[!b]".equals(ttt.head())) predicate = NotFlagB;
+ if ("[!c]".equals(ttt.head())) predicate = NotFlagC;
+ if ("[*]".equals(ttt.head())) predicate = IgnoreFlagD;
+ if ("[d]".equals(ttt.head())) predicate = FlagD;
+ }
+ tt = tt.child(1);
+ if ("flags".equals(tt.head())) {
+ cb.add(new Set(dock, predicate, parseFlags(tt.child(0)), parseFlags(tt.child(1))));
+ continue;
+ } else if ("olc=word".equals(tt.head())) {
+ cb.add(new Set(dock, predicate, SetDest.OuterLoopCounter, SetSource.DataLatch));
+ continue;
+ } else if ("ilc=word".equals(tt.head())) {
+ cb.add(new Set(dock, predicate, SetDest.InnerLoopCounter, SetSource.DataLatch));
+ continue;
+ } else if ("*".equals(tt.head())) {
+ cb.add(new Set(dock, predicate, SetDest.InnerLoopCounter, SetSource.Infinity));
+ continue;
+ } else if ("olc=int".equals(tt.head())) {
+ cb.add(new Set(dock, predicate, SetDest.OuterLoopCounter, (number(tt.child(0)))));
+ continue;
+ } else if ("ilc=int".equals(tt.head())) {
+ cb.add(new Set(dock, predicate, SetDest.InnerLoopCounter, (number(tt.child(0)))));
+ continue;
+ } else if ("--".equals(tt.head())) {
+ cb.add(new Set(dock, predicate, SetDest.OuterLoopCounter, SetSource.Decrement));
+ continue;
+ } else if ("nop".equals(tt.head())) {
+ if (tt.size() > 0 && "[T]".equals(tt.child(0).head())) interruptible = true;
+ cb.add(new Move(dock, predicate, interruptible, null, false, false, false, false, false, false));
+ } else if ("shift".equals(tt.head())) {
+ cb.add(new Shift(dock, predicate,
+ new BitVector(dock.getShip().getFleet().getShiftWidth()).set(number(tt.child(0)))));
+ continue;
+ } else if ("flush".equals(tt.head())) {
+ cb.add(new Flush(dock, predicate));
+ continue;
+ } else if ("abort".equals(tt.head())) {
+ cb.add(new Abort(dock, predicate));
+ continue;
+ } else if ("word".equals(tt.head())) {
+ long literal = 0;
+ if (tt.child(0).head().equals("CodeBagBody")) {
+ Tree<String> tq = tt;
+ CodeBag cb2 = getCodeBag("anon"+(anoncount++));
+ for(Tree<String> statement : tq.child(0))
+ fillCodeBag(statement, cb2);
+ cb.add(new Set(dock, predicate, SetDest.DataLatch, (cb2.getFakeAddress())), true);
+ continue OUTER;
+ } else if (tt.child(0).head().equals("Name")) {
+ String refname = name(tt.child(0));
+ CodeBag cb2 = getCodeBag(refname);
+ cb.add(new Set(dock, predicate, SetDest.DataLatch, (cb2.getFakeAddress())), true);
+ continue OUTER;
+ } else if (tt.child(0).head().equals("[")) {
+ literal = parseSSL(tt.child(0));
+ } else {
+ literal = number(tt.child(0));
+ }
+ count = 1;
+ /*
+ if ("int".equals(tt.child(1).head())) {
+ count = (int)number(tt.child(1));
+ } else if ("forever".equals(tt.child(1).head())) {
count = 0;
- requeue = true;
- } else if (tt.head().equals("Brack")) {
- count = Integer.parseInt(string(tt.child(0)));
- requeue = false;
- } else if (tt.head().equals("Paren")) {
- count = Integer.parseInt(string(tt.child(0)));
- requeue = true;
}
+ */
+
+
+ if (((FleetTwoFleet)fleet).isSmallEnoughToFit(literal)) {
+ cb.add(new Set(dock, predicate, SetDest.DataLatch, (literal)));
+ } else {
+ int counter = 0;
+ while(counter < dock.getShip().getFleet().getWordWidth()) counter += fleet.getShiftWidth();
+ while(counter > 0) {
+ cb.add(new Shift(dock, predicate,
+ new BitVector(dock.getShip().getFleet().getShiftWidth())
+ .set(getField(counter-1, counter-fleet.getShiftWidth(), literal))));
+ counter -= fleet.getShiftWidth();
+ }
+ }
+
+ continue;
}
+ Tree ttx = null;
+ boolean requeue = false;
+ if ("[T]".equals(tt.child(0).head())) interruptible = true;
+ ttx = tt.child(tt.size()-1);
boolean tokenIn = false;
boolean dataIn = false;
boolean latch = false;
boolean dataOut = false;
boolean tokenOut = false;
- boolean dataOutDest = false;
+ boolean dispatch = false;
boolean localLiteral = false;
+ boolean ignoreUntilLast = false;
long literal = 0;
- Destination dest = null;
+ Path path = null;
for(int i=0; i<ttx.size(); i++) {
Tree ttt = ttx.child(i);
- if ("Wait".equals(ttt.head())) { tokenIn = true; }
- else if ("Nop".equals(ttt.head())) { }
- else if ("KillStar".equals(ttt.head())) {
- cb.add(new Instruction.Kill(pump, count, true));
- continue OUTER;
- } else if ("Kill".equals(ttt.head())) {
- cb.add(new Instruction.Kill(pump, count, false));
- continue OUTER;
+ if ("recv token".equals(ttt.head())) { tokenIn = true; }
+ else if ("discard".equals(ttt.head())) { dataIn = true; latch = false; }
+ else if ("take".equals(ttt.head())) { dataIn = true; latch = true; }
+ else if ("collect".equals(ttt.head())) {
+ if (dock.isInputDock())
+ throw new RuntimeException("you can't use \"collect\" at input docks; try \"recv\" instead");
+ dataIn = true;
+ latch = true;
}
- else if ("Discard".equals(ttt.head())) { dataIn = true; latch = false; }
- else if ("Take".equals(ttt.head())) { dataIn = true; latch = true; }
- else if ("SendTo".equals(ttt.head())) { dataOut = true; dest = portReference(ttt.child(0)); }
- else if ("LocalLiteral".equals(ttt.head())) { localLiteral = true; literal = Long.parseLong(string(ttt.child(0))); }
- else if ("LocalLiteralCodeBag".equals(ttt.head())) {
- String refname = name(ttt.child(0).child(0));
- CodeBag cb2 = getCodeBag(refname);
- cb.add(new Instruction.Literal.CodeBagDescriptor(pump, cb2.getFakeAddress(), 0));
- continue OUTER;
- } else if ("LocalLiteralConst".equals(ttt.head())) {
- localLiteral = true;
- literal = parseSSL(ttt.child(0));
+ else if ("collect path".equals(ttt.head())) {
+ if (dock.isInputDock())
+ throw new RuntimeException("you can't use \"collect\" at input docks; try \"recv\" instead");
+ dataIn = true;
+ latch = false;
+ dispatch = true;
+ }
+ else if ("collect packet".equals(ttt.head())) {
+ if (dock.isInputDock())
+ throw new RuntimeException("you can't use \"collect\" at input docks; try \"recv\" instead");
+ dataIn = true;
+ latch = true;
+ dispatch = true;
+ }
+ else if ("collect nothing".equals(ttt.head())) {
+ if (dock.isInputDock())
+ throw new RuntimeException("you can't use \"collect\" at input docks; try \"recv\" instead");
+ dataIn = true;
+ }
+ else if ("recv".equals(ttt.head())) {
+ if (dock.isOutputDock())
+ throw new RuntimeException("you can't use \"recv\" at input docks; try \"collect\" instead");
+ dataIn = true;
+ latch = true;
}
- else if ("DataOutDest".equals(ttt.head())) { dataOutDest = true; }
- else if ("Deliver".equals(ttt.head())) { dataOut = true; }
- else if ("Ack".equals(ttt.head())) { tokenOut = true; dest = portReference(ttt.child(0)); }
+ else if ("recv path".equals(ttt.head())) {
+ if (dock.isOutputDock())
+ throw new RuntimeException("you can't use \"recv\" at input docks; try \"collect\" instead");
+ dataIn = true;
+ latch = false;
+ dispatch = true;
+ }
+ else if ("recv packet".equals(ttt.head())) {
+ if (dock.isOutputDock())
+ throw new RuntimeException("you can't use \"recv\" at input docks; try \"collect\" instead");
+ dataIn = true;
+ latch = true;
+ dispatch = true;
+ }
+ else if ("recv nothing".equals(ttt.head())) {
+ if (dock.isOutputDock())
+ throw new RuntimeException("you can't use \"recv\" at input docks; try \"collect\" instead");
+ dataIn = true;
+ }
+ else if ("send".equals(ttt.head())) {
+ dataOut = true;
+ }
+ else if ("send to".equals(ttt.head())) { dataOut = true; path = path(dock, ttt.child(0)); }
+ else if ("deliver".equals(ttt.head())) { dataOut = true; }
+ else if ("send token".equals(ttt.head())) { tokenOut = true; }
+ else if ("send token to".equals(ttt.head())) { tokenOut = true; path = path(dock, ttt.child(0)); }
}
- if (localLiteral)
- cb.add(new Instruction.LocalLiteral(pump, literal));
- else
- cb.add(new Instruction.Executable(pump,
- dest, count, tokenIn, dataIn,
- latch, dataOutDest, dataOut, tokenOut, requeue));
+ cb.add(new Move(dock, predicate,
+ interruptible, path, tokenIn, dataIn,
+ latch, dispatch, dataOut, tokenOut));
}
}
}
private class CodeBag extends ArrayList<Instruction> {
public long address = -1;
public final String name;
+ private HashSet<Integer> isCBD = new HashSet<Integer>();
public CodeBag() { codeBags.add(this); this.name = "root"; }
public CodeBag(String name) { codeBags.add(this); codeBagsByName.put(name, this); this.name = name; }
public long getFakeAddress() { return codeBags.indexOf(this); }
public boolean equals(Object o) { return this==o; }
+ public void add(Instruction i, boolean isCBD) {
+ if (isCBD) this.isCBD.add(size());
+ add(i);
+ }
}
// hideous hack
public static ArrayList<Long> expect;
public static boolean skip;
+ private static long number(Tree t) {
+ String ret = "";
+ for(Object c : t.child(2)) ret += ((Tree)c).head();
+ boolean negative = "-".equals(t.child(0).head());
+ ret = ret.trim();
+ long val = 0;
+ if ("0x".equals(t.child(1).head())) val = Long.parseLong(ret, 16);
+ else if ("0b".equals(t.child(1).head())) val = Long.parseLong(ret, 2);
+ else val = Long.parseLong(ret);
+ if (negative) val = -1L * val;
+ return val;
+ }
+ /**
+ * This interface marks Fleets which can create ships on the fly, like the fleeterpreter;
+ * if available, the parser will use this interface to create ships out of #ship definitions.
+ */
+ public static interface FleetWithDynamicShips {
+ public Ship createShip(String shiptype, String shipname);
+ }
+
+ private static Move discard(Dock dock) { return new Move(dock, IgnoreFlagD, false, null, false, true, false, false, false, false); }
+ private static Move deliver(Dock dock) { return new Move(dock, IgnoreFlagD, false, null, false, false, false, false, true, false); }
+ private static Move wait(Dock dock) { return new Move(dock, IgnoreFlagD, false, null, true, false, false, false, false, false); }
+ private static Move sendto(Dock dock, Path path) { return new Move(dock, IgnoreFlagD, false, path, false, false, false, false, true, false); }
}