package slangc.parser; import slang.streams.SyncOutput; import slang.streams.SyncInput; public final class Branch extends Node { private NodeType type; private Node[] subnodes; public Branch(NodeType type, Node... subnodes ) { this.type = type; this.subnodes = subnodes; } Branch(NodeType type, int nnodes) { this.type = type; subnodes = new Node[nnodes]; } @Override public NodeType getNodeType() { return type; } private static byte[] outbuffer = new byte[7]; public static Branch loadBinary(Scan sc, NodeType typ, SyncInput inp) { inp.readBuffer(outbuffer, 0, 1); int len = ((int) outbuffer[0]) & 0xFF; if (len == 255) { inp.readBuffer(outbuffer, 0, 4); int len = Token.decInt(outbuffer, 0); //Log.line("Type " + typ.name() + " length " + len); if (len < 0 || len > 1000) { Log.line("WARNING: Unusual length in binary cache"); } } Branch b = new Branch(typ, len); for (int i = 0; i < len; i++) { b.subnodes[i] = Node.loadBinary(sc,inp); } return b; } public void dumpBinary(SyncOutput o) { if (type.value > 1000) { throw new Error("Too many node types for this simple format!"); } outbuffer[0] = (byte) (type.value >> 8); outbuffer[1] = (byte) (type.value); if (subnodes.length > 200) { outbuffer[2] = (byte) 255; Token.encInt(outbuffer, 3, subnodes.length); o.writeBuffer(outbuffer, 0, 7); } else { outbuffer[2] = (byte) subnodes.length; o.writeBuffer(outbuffer, 0, 3); } for (int i = 0; i < subnodes.length; i++) { if (subnodes[i] == null) { //while(true){} throw new Error("Can't encode nulls in parse dumps"); } subnodes[i].dumpBinary(o); } //throw new Error("Can't dump AST nodes of type " + Type.of(this).fullName()); } public void append(Node n) { Node[] nsubnodes = new Node[subnodes.length + 1]; for (int i = 0; i < subnodes.length; i++) { nsubnodes[i] = subnodes[i]; } nsubnodes[nsubnodes.length - 1] = n; subnodes = nsubnodes; } public int countSubnodes() { return subnodes.length; } public Node getSubnode(int index) { if (index < 0 || index >= subnodes.length) { return null; } else { return subnodes[index]; } } @Override public int countErrorsRecursively() { if (!mightHaveErrors) { return 0; } int result = super.countErrorsRecursively(); for (int i = 0; i < subnodes.length; i++) { if (subnodes[i] == null) { result++; } else { result += subnodes[i].countErrorsRecursively(); } } return result; } @Override public int deleteErrorsRecursively() { int result = super.deleteErrorsRecursively(); for (int i = 0; i < subnodes.length; i++) { if (subnodes[i] == null) { result++; } else { result += subnodes[i].deleteErrorsRecursively(); } } return result; } }