X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Fedu%2Fberkeley%2Ffleet%2Fassembler%2FParser.java;h=e43b035bf35c25e2ed18333434d2ae0d3c0dd3b6;hb=26b5a16ee2385c03f04e4926b8e19dad36f62a95;hp=a6a55a9411b6cb8204991083cfe80f029c3aec0d;hpb=16ebccf15fb6d37c81f5db5acc725962dc976122;p=fleet.git diff --git a/src/edu/berkeley/fleet/assembler/Parser.java b/src/edu/berkeley/fleet/assembler/Parser.java index a6a55a9..e43b035 100644 --- a/src/edu/berkeley/fleet/assembler/Parser.java +++ b/src/edu/berkeley/fleet/assembler/Parser.java @@ -5,15 +5,32 @@ import edu.berkeley.sbp.chr.*; 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 */ 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(); this.fleet = fleet; } @@ -40,64 +57,130 @@ public class Parser { 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 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 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 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)parse(r), rootCodeBag); - if (fleet instanceof edu.berkeley.fleet.fpga.Fpga) - ((edu.berkeley.fleet.fpga.Fpga)fleet).dumpFabric(true); + Tree parsed = (Tree)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 ret = new ArrayList(); for(int i=0; i ret = new ArrayList(); + 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 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 */ @@ -112,40 +195,21 @@ public class Parser { for(Tree 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 t) { + private static String string(Tree t) { String ret = ""; if (t.head() != null) ret += t.head(); for(Tree c : t) @@ -153,46 +217,51 @@ public class Parser { return ret; } - String name(Tree t) { + private static String stringBody(Tree t) { + String ret = ""; + for(Tree c : t) + ret += string(c); + return ret; + } + + private static String name(Tree t) { return string(t.child(0))+string(t.child(1)); } - Destination portReference(Tree t) { - if (!"Port".equals(t.head()) && !"SubPort".equals(t.head()) && !"ShipSpecificLiteral".equals(t.head())) return null; + Path path(Dock dock, Tree 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 t) { - if (!"Port".equals(t.head()) && !"SubPort".equals(t.head()) && !"ShipSpecificLiteral".equals(t.head())) + Dock dock(Tree 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 numAllocated = new HashMap(); @@ -211,7 +280,15 @@ public class Parser { 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) { @@ -224,90 +301,245 @@ public class Parser { 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 { public long address = -1; public final String name; + private HashSet isCBD = new HashSet(); 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 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); } }