--- /dev/null
+package org.simantics.scl.compiler.internal.types.ast;
+
+import java.util.ArrayList;
+import java.util.Collections;
+
+import org.simantics.scl.compiler.internal.types.TypeElaborationContext;
+import org.simantics.scl.compiler.types.TCon;
+import org.simantics.scl.compiler.types.TPred;
+import org.simantics.scl.compiler.types.Type;
+import org.simantics.scl.compiler.types.Types;
+import org.simantics.scl.compiler.types.exceptions.Problem;
+import org.simantics.scl.compiler.types.exceptions.SCLTypeParseException;
+
+public abstract class TypeAst {
+ @Override
+ public String toString() {
+ StringBuilder b = new StringBuilder();
+ toString(b);
+ return b.toString();
+ }
+
+ public abstract void toString(StringBuilder b);
+
+ public void toString(StringBuilder b, int outerPrecedence) {
+ if(getPrecedence() >= outerPrecedence) {
+ b.append('(');
+ toString(b);
+ b.append(')');
+ }
+ else
+ toString(b);
+ }
+
+ public abstract Type toType(TypeElaborationContext context) throws SCLTypeParseException;
+
+ public static Type[] toTypes(TypeElaborationContext context, TypeAst[] typeAsts) throws SCLTypeParseException {
+ Type[] result = new Type[typeAsts.length];
+ for(int i=0;i<typeAsts.length;++i)
+ result[i] = typeAsts[i].toType(context);
+ return result;
+ }
+
+ public TPred toTFuncApply(TypeElaborationContext context) throws SCLTypeParseException {
+ ArrayList<Type> parameters = new ArrayList<Type>();
+ TypeAst cur = this;
+ while(true) {
+ if(cur instanceof TApplyAst) {
+ TApplyAst apply = (TApplyAst)cur;
+ parameters.add(apply.parameter.toType(context));
+ cur = apply.function;
+ }
+ else if(cur instanceof TConAst) {
+ TConAst con = (TConAst)cur;
+ Collections.reverse(parameters);
+ return Types.pred(
+ (TCon)con.toType(context),
+ parameters.toArray(new Type[parameters.size()]));
+ }
+ else
+ throw new SCLTypeParseException(
+ new Problem(0, 0, "Invalid constraint."));
+ }
+ }
+
+ public abstract int getPrecedence();
+}