1 package org.simantics.scl.compiler.internal.parsing.types;
3 import org.simantics.scl.compiler.elaboration.contexts.TypeTranslationContext;
4 import org.simantics.scl.compiler.elaboration.modules.TypeAlias;
5 import org.simantics.scl.compiler.elaboration.modules.TypeDescriptor;
6 import org.simantics.scl.compiler.environment.AmbiguousNameException;
7 import org.simantics.scl.compiler.environment.Environments;
8 import org.simantics.scl.compiler.internal.types.TypeElaborationContext;
9 import org.simantics.scl.compiler.types.TCon;
10 import org.simantics.scl.compiler.types.Type;
11 import org.simantics.scl.compiler.types.Types;
12 import org.simantics.scl.compiler.types.kinds.Kind;
13 import org.simantics.scl.compiler.types.kinds.Kinds;
14 import org.slf4j.Logger;
15 import org.slf4j.LoggerFactory;
17 import gnu.trove.map.hash.TObjectIntHashMap;
18 import gnu.trove.set.hash.TIntHashSet;
22 * This class represents an abstract syntax tree node for a type variable.
23 * The only property of a type variable is its name.
25 public class TVarAst extends TypeAst {
26 private static final Logger LOGGER = LoggerFactory.getLogger(TVarAst.class);
27 public final String name;
29 public TVarAst(String name) {
34 public void toString(StringBuilder b) {
39 public Type toType(TypeTranslationContext context, Kind expectedKind) {
40 char c = name.charAt(0);
44 for(int i=1;i<name.length()-1;++i)
45 if(name.charAt(i) != ',') {
47 con = Environments.getTypeDescriptorName(context.getEnvironment(), name.substring(1, name.length()-1));
48 } catch(AmbiguousNameException e) {
49 context.getErrorLog().log(location, e.getMessage());
50 return Types.metaVar(Kinds.STAR);
53 context.getErrorLog().log(location, "Didn't find type constructor " + name + ".");
54 return Types.metaVar(Kinds.STAR);
58 con = Types.con(Types.BUILTIN, name);
60 else if(Character.isLowerCase(c))
61 return context.resolveTypeVariable(location, name, expectedKind);
63 return context.resolveExistential(location, name, expectedKind);
67 tdesc = Environments.getTypeDescriptor(context.getEnvironment(), name);
68 } catch (AmbiguousNameException e) {
69 context.getErrorLog().log(location, e.getMessage());
70 return Types.metaVar(Kinds.STAR);
73 context.getErrorLog().log(location, "Didn't find type constructor " + name + ".");
74 return Types.metaVar(Kinds.STAR);
76 if(tdesc instanceof TypeAlias) {
77 TypeAlias alias = (TypeAlias)tdesc;
78 if(alias.getArity() > 0) {
79 context.getErrorLog().log(location, "The alias expects " +
80 alias.getArity() + " parameters, but none are given.");
81 return Types.metaVar(Kinds.metaVar());
89 Kind providedKind = context.getKind(con);
90 context.unify(location, providedKind, expectedKind);
95 public Type toType(TypeElaborationContext context) {
96 char c = name.charAt(0);
100 for(int i=1;i<name.length()-1;++i)
101 if(name.charAt(i) != ',') {
102 con = context.resolveTypeConstructor(name.substring(1, name.length()-1));
104 LOGGER.warn("Didn't find type constructor " + name + ".");
105 return Types.metaVar(Kinds.STAR);
109 con = Types.con(Types.BUILTIN, name);
111 else if(Character.isLowerCase(c))
112 return context.resolveTypeVariable(name);
114 return context.resolveExistential(name);
116 con = context.resolveTypeConstructor(name);
118 LOGGER.warn("Didn't find type constructor " + name + ".");
119 return Types.metaVar(Kinds.STAR);
128 * Translate this variable reference to an effect Type. Lower initial names are treated as
129 * type meta-variables. Capitalized names are resolved as effect name constants.
131 * Error messages about unresolved or ambiguous effect names are logged, with a new meta-variable
132 * as the return value.
135 public Type toEffect(TypeTranslationContext context) {
136 char c = name.charAt(0);
137 if(Character.isLowerCase(c))
138 return context.resolveTypeVariable(location, name, Kinds.EFFECT);
142 con = Environments.getEffectConstructorName(context.getEnvironment(), name);
143 } catch (AmbiguousNameException e) {
144 context.getErrorLog().log(location, e.getMessage());
145 return Types.metaVar(Kinds.EFFECT);
148 context.getErrorLog().log(location, "Didn't find effect constructor " + name + ".");
149 return Types.metaVar(Kinds.EFFECT);
156 public Type toEffect(TypeElaborationContext context) {
157 char c = name.charAt(0);
158 if(Character.isLowerCase(c))
159 return context.resolveTypeVariable(name);
161 return context.resolveExistential(name);
163 Type con = context.resolveTypeConstructor(name);
165 LOGGER.warn("Didn't find effect constructor " + name + ".");
166 return Types.metaVar(Kinds.EFFECT);
173 public int getPrecedence() {
178 public void collectReferences(TObjectIntHashMap<String> typeNameMap,
180 if(typeNameMap.containsKey(name))
181 set.add(typeNameMap.get(name));