1 package org.simantics.scl.compiler.elaboration.contexts;
3 import gnu.trove.map.hash.THashMap;
5 import org.simantics.scl.compiler.environment.Environment;
6 import org.simantics.scl.compiler.errors.ErrorLog;
7 import org.simantics.scl.compiler.internal.parsing.exceptions.SCLSyntaxErrorException;
8 import org.simantics.scl.compiler.internal.parsing.types.TypeAst;
9 import org.simantics.scl.compiler.types.TCon;
10 import org.simantics.scl.compiler.types.TPred;
11 import org.simantics.scl.compiler.types.TVar;
12 import org.simantics.scl.compiler.types.Type;
13 import org.simantics.scl.compiler.types.Types;
14 import org.simantics.scl.compiler.types.exceptions.KindUnificationException;
15 import org.simantics.scl.compiler.types.kinds.Kind;
16 import org.simantics.scl.compiler.types.kinds.Kinds;
18 public class TypeTranslationContext {
20 Environment environment;
24 THashMap<String, TVar> typeVariables = new THashMap<String, TVar>();
26 public TypeTranslationContext(ErrorLog errorLog, Environment environment) {
27 this.errorLog = errorLog;
28 this.environment = environment;
32 * Convert a type AST node to a Type instance, using STAR as the expected kind.
33 * If the conversion fails with a syntax error exception, the returned value
34 * is a new type meta-variable.
36 * @param typeAst An AST node representing a type
37 * @return A Type instance.
39 public Type toType(TypeAst typeAst) {
40 return toType(typeAst, Kinds.STAR);
44 * Convert a type AST node to a Type instance.
45 * If the conversion fails with a syntax error exception, the returned value
46 * is a new type meta-variable.
48 * @param typeAst An AST node representing a type
49 * @param kind A kind as which the node should be interpreted as
50 * @return A Type instance.
52 public Type toType(TypeAst typeAst, Kind kind) {
55 type = typeAst.toType(this, kind);
56 } catch(SCLSyntaxErrorException e) {
57 errorLog.log(e.location, e.getMessage());
58 return Types.metaVar(kind);
61 type.checkKind(kindingContext, kind);
62 } catch (KindUnificationException e) {
63 errorLog.log(typeAst, "Invalid type " + type + ".");
68 public TVar resolveTypeVariable(long loc, String name, Kind expectedKind) {
69 TVar var = typeVariables.get(name);
71 var = Types.var(expectedKind);
72 typeVariables.put(name, var);
75 unify(loc, var.getKind(), expectedKind);
79 public TVar pushTypeVar(String name) {
80 return typeVariables.put(name, Types.var(Kinds.metaVar()));
83 public TVar addTypeVar(String name) {
84 TVar var = Types.var(Kinds.metaVar());
85 typeVariables.put(name, var);
89 public TVar popTypeVar(String name, TVar var) {
91 return typeVariables.remove(name);
93 return typeVariables.put(name, var);
96 public TPred toTFuncApply(TypeAst typeAst) {
97 return typeAst.toTFuncApply(this);
100 public ErrorLog getErrorLog() {
104 public Environment getEnvironment() {
108 public Kind getKind(TCon con) {
109 return environment.getTypeConstructor(con).kind;
113 * Unify the given kinds. An error message is logged, if the unification fails.
114 * @param loc location identifier
115 * @param provided actual kind
116 * @param expectedKind expected kind
118 public void unify(long loc, Kind provided, Kind expectedKind) {
120 Kinds.unify(provided, expectedKind);
121 } catch (KindUnificationException e) {
122 errorLog.log(loc, "Expected a type with kind " + expectedKind + " but got " + provided + ".");