match("string");
return T_STRING;
case '[':
{
match("[");
Type elem = parse(typeVariables);
match("]");
return List(elem, false);
}
case '{':
{
match("{");
Type elem = parse(typeVariables);
skipWhiteSpace();
if(index < str.length() && str.charAt(index) == '-') {
// dictionary
match("->");
Type value = parse(typeVariables);
match("}");
return Map(elem,value);
} else if(index < str.length() && str.charAt(index) != '}') {
// record
HashMap<String,Type> fields = new HashMap<String,Type>();
String id = parseIdentifier();
fields.put(id, elem);
skipWhiteSpace();
boolean isOpen = false;
while(index < str.length() && str.charAt(index) == ',') {
match(",");
if(str.charAt(index) == '.') {
match("...");
isOpen=true;
break;
}
elem = parse(typeVariables);
id = parseIdentifier();
fields.put(id, elem);
skipWhiteSpace();
}
match("}");
return Record(isOpen,fields);
}
match("}");
return Set(elem,false);
}
default:
{
String typeVariable = parseIdentifier();
if(typeVariables.contains(typeVariable)) {
return Nominal(new NameID(Trie.fromString("$"),
typeVariable));
} else {
typeVariables = new HashSet<String>(typeVariables);
typeVariables.add(typeVariable);
match("<");
Type t = parse(typeVariables);
match(">");
NameID label = new NameID(Trie.fromString("$"),
typeVariable);
return Recursive(label, t);
}