/** NOT YET FINALIZED: A description (specification) of a ship */
public class ShipDescription implements Iterable<DockDescription> {
+ private Fleet fleet;
private String name;
- private LinkedHashMap<String,DockDescription> docks = new LinkedHashMap<String,DockDescription>();
- private HashMap<String,String> sections = new HashMap<String,String>();
- private HashMap<String,Constant> constants = new HashMap<String,Constant>();
+ private LinkedHashMap<String,DockDescription> docks = new LinkedHashMap<String,DockDescription>();
+ private LinkedHashMap<String,DockDescription> ports = new LinkedHashMap<String,DockDescription>();
+ private HashMap<String,String> sections = new HashMap<String,String>();
+ private HashMap<String,BitVector> constants = new HashMap<String,BitVector>();
public String getName() { return name; }
public String getSection(String sectionName) { return sections.get(sectionName); }
public DockDescription getDockDescription(String name) { return docks.get(name); }
public Iterator<DockDescription> iterator() { return docks.values().iterator(); }
+ public Iterable<DockDescription> ports() {
+ return ports.values();
+ }
+
+ public final LinkedList<PercolatedPort> percolatedPorts = new LinkedList<PercolatedPort>();
- public ShipDescription(String name, BufferedReader r) throws IOException {
+ public ShipDescription(Fleet fleet, String name, BufferedReader r) throws IOException {
if (name.endsWith(".ship")) name = name.substring(0, name.length()-".ship".length());
this.name = name;
+ this.fleet = fleet;
String sectionName = null;
StringBuffer sb = new StringBuffer();
while(true) {
sectionName = sectionName.substring(1);
while(sectionName.endsWith("="))
sectionName = sectionName.substring(0, sectionName.length()-1);
+ sectionName = sectionName.trim();
+
+ if (sectionName.indexOf(':') != -1) {
+ String subtype = sectionName.substring(sectionName.indexOf(':')+1);
+ sectionName = sectionName.substring(0, sectionName.indexOf(':'));
+ boolean good = false;
+ for(Class c = fleet.getClass(); c!=Object.class; c = c.getSuperclass()) {
+ if (subtype.equals(c.getSimpleName()))
+ good = true;
+ }
+ if (!good) {
+ sectionName = null;
+ continue;
+ }
+ }
sectionName = sectionName.trim().toLowerCase();
continue;
}
processSection(s);
}
- public Constant getConstant(String name) {
- return constants.get(name);
+ public BitVector getConstant(String name) {
+ BitVector c = constants.get(name);
+ if (c==null) throw new RuntimeException("unknown constant " + name);
+ return c;
}
private void processSection(String section) throws IOException {
if (key.startsWith("constant")) {
String constname = key.substring("constant".length()+1).trim();
String val = s.substring(s.indexOf(':')+1).trim();
- constants.put(constname, new Constant(val));
+ constants.put(constname, new BitVector(fleet.getWordWidth()).set(Integer.parseInt(val)));
}
}
} else if (section.equals("ports")) {
String key = s.substring(0, s.indexOf(':')).trim();
boolean inbox = false;
+ boolean dockless = false;
key = key.replaceAll(" +", " ");
if (key.equals("data in")) { inbox = true; }
else if (key.equals("data out")) { inbox = false; }
else if (key.equals("in")) { inbox = true; }
+ else if (key.equals("dockless out")) { inbox = false; dockless = true; }
else if (key.equals("out")) { inbox = false; }
+ else if (key.startsWith("percolate")) {
+ key = s;
+ key = key.substring("percolate".length()+1).trim();
+ PercolatedPort.PortType type = null;
+ if (key.startsWith("up")) type = PercolatedPort.PortType.UP;
+ if (key.startsWith("down")) type = PercolatedPort.PortType.DOWN;
+ if (key.startsWith("inout")) type = PercolatedPort.PortType.INOUT;
+ key = key.substring(key.indexOf(':')+1).trim();
+ String name = key.substring(0, key.indexOf(' '));
+ int width = Integer.parseInt(key.substring(key.indexOf(' ')).trim());
+ percolatedPorts.add(new PercolatedPort(name, width, type));
+ continue;
+ }
else if (key.startsWith("constant")) {
String constname = key.substring("constant".length()+1).trim();
String val = s.substring(s.indexOf(':')+1).trim();
- p.addConstant(constname, new Constant(val));
+ p.addConstant(constname, new BitVector(fleet.getWordWidth()).set(Integer.parseInt(val)));
continue;
} else if (key.startsWith("shortcut to")) {
continue;
String dest = val.indexOf('.') != -1 ? val.substring(val.indexOf('.')+1) : "";
p = docks.get(boxname);
if (p==null) {
- p = new DockDescription(this, boxname, !rightSide, inbox);
- docks.put(boxname, p);
+ p = new DockDescription(this, boxname, !rightSide, inbox, dockless);
+ ports.put(boxname, p);
+ if (!dockless) docks.put(boxname, p);
}
}
}
pw.println(tex);
}
- // FIXME: merge with BitMask
- public class Constant {
- public long setbits = 0;
- public long clearbits = 0;
- public boolean signExtend = false;
- public int numberOffset = 0;
- public int numberWidth = 0;
- public Constant(String s) {
- if (s.startsWith("0x")) {
- setbits = Long.parseLong(s.substring(2), 16);
- clearbits = ~setbits;
- } else if (s.length() == 37) {
- for(int i=36; i>=0; i--) {
- char c = s.charAt(36-i);
- switch(c) {
- case '0': clearbits |= (1<<i); break;
- case '1': setbits |= (1<<i); break;
- case '.': break;
- case 's': signExtend = true; numberOffset = i; numberWidth++; break;
- case 'u': signExtend = false; numberOffset = i; numberWidth++; break;
- }
- }
- } else {
- setbits = Long.parseLong(s);
- clearbits = ~setbits;
- }
- }
- }
-
}