slcom/slangc/parser/Branch.sauce

123 lines
3.1 KiB
Plaintext

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<byte> 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<byte> 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;
}
}