}
protected static Signature parseSignature(StringBuffer specbuf) {
//System.out.println(">>>> " + specbuf.toString());
//System.out.flush();
Signature sig;
String spec = specbuf.toString();
if (spec.startsWith("_")) {
specbuf.delete(0, 1);
sig = new AnySignature(new OtpErlangList());
} else if (spec.matches("^[0-9].*")) {
// Integer literal
// Floats are not supported atm...
String val = "";
while ((specbuf.length() > 0) && (specbuf.substring(0, 1).matches("[0-9]"))) {
val += "" + specbuf.substring(0, 1);
specbuf.delete(0, 1);
}
// handle ranges...
if (specbuf.toString().startsWith("..")) {
int lowerValue = Integer.parseInt(val);
specbuf.delete(0, 2);
val = "";
while ((specbuf.length() > 0) && (specbuf.substring(0, 1).matches("[0-9]"))) {
val += "" + specbuf.substring(0, 1);
specbuf.delete(0, 1);
}
int upperValue = Integer.parseInt(val);
sig = new IntSignature(new OtpErlangList(),new OtpErlangList(new OtpErlangObject[]{
new OtpErlangInt(lowerValue),new OtpErlangInt(upperValue)
}));
} else {
sig = new LiteralSignature(val);
}
} else if (spec.startsWith("any()")) {
specbuf.delete(0, 5);
sig = new AnySignature(new OtpErlangList());
} else if (spec.startsWith("integer()")) {
specbuf.delete(0, 9);
sig = new IntSignature(new OtpErlangList());
} else if (spec.startsWith("non_neg_integer()")) {
specbuf.delete(0, 17);
sig = new IntSignature(new OtpErlangList(new OtpErlangObject[]{IntSignature.NonNegativeAtom}));
} else if (spec.startsWith("number()")) {
specbuf.delete(0, 8);
sig = new IntSignature(new OtpErlangList());
} else if (spec.startsWith("pos_integer()")) {
specbuf.delete(0, 13);
sig = new IntSignature(new OtpErlangList(new OtpErlangObject[]{IntSignature.PositiveAtom}));
} else if (spec.startsWith("binary()")) {
specbuf.delete(0, 8);
sig = new BinarySignature(new OtpErlangList());
} else if (spec.startsWith("boolean()")) {
specbuf.delete(0, 9);
sig = new BooleanSignature(new OtpErlangList());
} else if (spec.startsWith("atom()")) {
specbuf.delete(0, 6);
sig = new AtomSignature(new OtpErlangList());
} else if (spec.startsWith("string()")) {
specbuf.delete(0, 8);
sig = new StringSignature(new OtpErlangList());
} else if (spec.startsWith("tuple()")) {
specbuf.delete(0, 7);
sig = new TupleSignature(new OtpErlangList());
} else if (spec.startsWith("char()")) {
specbuf.delete(0, 6);
sig = new CharSignature(new OtpErlangList());
} else if (spec.startsWith("byte()")) {
specbuf.delete(0, 6);
sig = new ByteSignature(new OtpErlangList());
} else if (spec.startsWith("pid()")) {
specbuf.delete(0, 5);
sig = new PidSignature();
} else if (spec.startsWith("port()")) {
specbuf.delete(0, 6);
sig = new PortSignature();
} else if (spec.startsWith("'")) {
String lit = "";
specbuf.delete(0, 1);
while (specbuf.charAt(0) != '\'') {
lit += specbuf.charAt(0);
specbuf.delete(0, 1);
}
specbuf.delete(0, 1);
sig = new LiteralSignature(lit);
} else if (spec.startsWith("{")) {
// Tuple...
specbuf.delete(0, 1);
bufTrimmer(specbuf);
List<Signature> tupElems = new LinkedList<Signature>();
while (specbuf.charAt(0) != '}') {
tupElems.add(parseSignature(specbuf));
bufTrimmer(specbuf);
if (specbuf.charAt(0) == ',') {
// More vals...
specbuf.delete(0, 1);
bufTrimmer(specbuf);
}
}
// Swallow the closing }
specbuf.delete(0, 1);
sig = new TupleSignature(tupElems);
} else if (spec.startsWith("maybe_improper_list(")) {
specbuf.delete(0, 20);
bufTrimmer(specbuf);
sig = parseList(specbuf, false, ')');
} else if (spec.startsWith("nonempty_maybe_improper_list(")) {
specbuf.delete(0, 29);
bufTrimmer(specbuf);
sig = parseList(specbuf, true, ')');
} else if (spec.startsWith("improper_list(")) {
specbuf.delete(0, 14);
bufTrimmer(specbuf);
sig = parseList(specbuf, false, ')');
} else if (spec.startsWith("list(")) {
specbuf.delete(0, 5);
bufTrimmer(specbuf);
sig = parseList(specbuf, false, ')');
} else if (spec.startsWith("[")) {
// List spec
specbuf.delete(0, 1);
bufTrimmer(specbuf);
sig = parseList(specbuf, false, ']');
} else if (spec.startsWith("#")) {
// Record spec...
// FIXME temp
// Swallow the name if any
String name = "";
while (specbuf.charAt(0) != '{') {
name += specbuf.substring(0, 1);
specbuf.delete(0, 1);
}
RecordSignature rsig = new RecordSignature(new OtpErlangList(),new OtpErlangList());// this will throw since we provide no name for this record
int depth = 1;
while (depth > 0) {
specbuf.delete(0, 1);
bufTrimmer(specbuf);
if (specbuf.charAt(0) == '{') {
depth += 1;
} else if (specbuf.charAt(0) == '}') {
depth -= 1;
}
}
specbuf.delete(0, 1);
bufTrimmer(specbuf);
sig = rsig;
} else {
// Something else...
//System.out.println(specbuf.toString());
// FIXME
int end = specbuf.length();
if (specbuf.indexOf(" ") > 0) {
end = specbuf.indexOf(" ");
}
if ((specbuf.indexOf("]") < end) && (specbuf.indexOf("]") >= 0)) {
end = specbuf.indexOf("]");
}
if ((specbuf.indexOf("|") < end) && (specbuf.indexOf("|") >= 0)) {
end = specbuf.indexOf("|");
}
if ((specbuf.indexOf("}") < end) && (specbuf.indexOf("}") >= 0)) {
end = specbuf.indexOf("}");
}
if ((specbuf.indexOf(")") < end) && (specbuf.indexOf(")") >= 0)) {
end = specbuf.indexOf(")");
}
if ((specbuf.indexOf("(") < end) && (specbuf.indexOf("(") >= 0)) {
end = specbuf.indexOf("(");
int d = 1;
while ((d > 0) && (end < specbuf.length())) {
end++;
if (specbuf.substring(end).startsWith(")")) {
d--;
} else if (specbuf.substring(end).startsWith("(")) {
d++;
}
//System.out.println(specbuf.substring(end) + " (depth: " + d + ")");
}
}
String uk = specbuf.substring(0, end);
specbuf.delete(0, end);
if (specbuf.toString().startsWith(")")) {
uk = uk + ")";
specbuf.delete(0, 1);
}
sig = new UnknownSignature(uk);
}
bufTrimmer(specbuf);
// Handle Alternates at this level...
if (specbuf.length() > 0) {
if (specbuf.charAt(0) == '|') {
specbuf.delete(0, 1);
bufTrimmer(specbuf);
List<Signature> asigElems = new LinkedList<Signature>();
asigElems.add(sig);
Signature s = parseSignature(specbuf);
if (s instanceof AltSignature) {
asigElems.addAll(((AltSignature) s).elems);
} else {
asigElems.add(s);
}