1 package org.simantics.scl.compiler.elaboration.contexts;
3 import org.simantics.scl.compiler.compilation.CompilationContext;
4 import org.simantics.scl.compiler.environment.Environment;
5 import org.simantics.scl.compiler.errors.ErrorLog;
6 import org.simantics.scl.compiler.internal.parsing.exceptions.SCLSyntaxErrorException;
7 import org.simantics.scl.compiler.internal.parsing.types.TypeAst;
8 import org.simantics.scl.compiler.types.TCon;
9 import org.simantics.scl.compiler.types.TPred;
10 import org.simantics.scl.compiler.types.TVar;
11 import org.simantics.scl.compiler.types.Type;
12 import org.simantics.scl.compiler.types.Types;
13 import org.simantics.scl.compiler.types.exceptions.KindUnificationException;
14 import org.simantics.scl.compiler.types.kinds.Kind;
15 import org.simantics.scl.compiler.types.kinds.Kinds;
17 import gnu.trove.map.hash.THashMap;
19 public class TypeTranslationContext {
21 CompilationContext compilationContext;
23 Environment environment;
27 THashMap<String, TVar> typeVariables = new THashMap<String, TVar>();
29 public TypeTranslationContext(CompilationContext compilationContext) {
30 this.compilationContext = compilationContext;
31 this.errorLog = compilationContext.errorLog;
32 this.environment = compilationContext.environment;
36 * Convert a type AST node to a Type instance, using STAR as the expected kind.
37 * If the conversion fails with a syntax error exception, the returned value
38 * is a new type meta-variable.
40 * @param typeAst An AST node representing a type
41 * @return A Type instance.
43 public Type toType(TypeAst typeAst) {
44 return toType(typeAst, Kinds.STAR);
48 * Convert a type AST node to a Type instance.
49 * If the conversion fails with a syntax error exception, the returned value
50 * is a new type meta-variable.
52 * @param typeAst An AST node representing a type
53 * @param kind A kind as which the node should be interpreted as
54 * @return A Type instance.
56 public Type toType(TypeAst typeAst, Kind kind) {
59 type = typeAst.toType(this, kind);
60 } catch(SCLSyntaxErrorException e) {
61 errorLog.log(e.location, e.getMessage());
62 return Types.metaVar(kind);
65 type.checkKind(kindingContext, kind);
66 } catch (KindUnificationException e) {
67 errorLog.log(typeAst, "Invalid type " + type + ".");
72 public TVar resolveTypeVariable(long loc, String name, Kind expectedKind) {
73 TVar var = typeVariables.get(name);
75 var = Types.var(expectedKind);
76 typeVariables.put(name, var);
79 unify(loc, var.getKind(), expectedKind);
83 public TVar pushTypeVar(String name) {
84 return typeVariables.put(name, Types.var(Kinds.metaVar()));
87 public TVar addTypeVar(String name) {
88 TVar var = Types.var(Kinds.metaVar());
89 typeVariables.put(name, var);
93 public TVar popTypeVar(String name, TVar var) {
95 return typeVariables.remove(name);
97 return typeVariables.put(name, var);
100 public TPred toTFuncApply(TypeAst typeAst) {
101 return typeAst.toTFuncApply(this);
104 public ErrorLog getErrorLog() {
108 public Environment getEnvironment() {
112 public Kind getKind(TCon con) {
113 return environment.getTypeDescriptor(con).getKind();
117 * Unify the given kinds. An error message is logged, if the unification fails.
118 * @param loc location identifier
119 * @param provided actual kind
120 * @param expectedKind expected kind
122 public void unify(long loc, Kind provided, Kind expectedKind) {
124 Kinds.unify(provided, expectedKind);
125 } catch (KindUnificationException e) {
126 errorLog.log(loc, "Expected a type with kind " + expectedKind + " but got " + provided + ".");