private void propagate( TypePattern pattern, HashMap<String, SemanticType> environment, HashSet<String> generics, WyalFile.Context context) { SemanticType type = builder.convert(pattern.toSyntacticType(), generics, context); if (pattern instanceof TypePattern.Tuple) { TypePattern.Tuple tt = (TypePattern.Tuple) pattern; for (TypePattern p : tt.patterns) { propagate(p, environment, generics, context); } } if (pattern.var != null) { environment.put(pattern.var, type); } if (pattern.source != null) { SemanticType ct = propagate(pattern.source, environment, generics, context); checkIsSubtype(SemanticType.SetAny, ct, pattern); // TODO: need effective set here SemanticType.Set set_t = (SemanticType.Set) ct; checkIsSubtype(type, set_t.element(), pattern); } if (pattern.constraint != null) { SemanticType ct = propagate(pattern.constraint, environment, generics, context); checkIsSubtype(SemanticType.Bool, ct, pattern); } pattern.attributes().add(new TypeAttribute(type)); }
private SemanticType propagate( Expr.FunCall e, HashMap<String, SemanticType> environment, HashSet<String> generics, WyalFile.Context context) { SemanticType.Function fnType; try { Pair<NameID, SemanticType.Function> p = builder.resolveAsFunctionType(e.name, context); fnType = p.second(); } catch (ResolveError re) { syntaxError( "cannot resolve as function or definition call", context.file().filename(), e, re); return null; } SemanticType[] fn_generics = fnType.generics(); if (fn_generics.length != e.generics.length) { // could resolve this with inference in the future. syntaxError( "incorrect number of generic arguments provided (got " + e.generics.length + ", required " + fn_generics.length + ")", context.file().filename(), e); } SemanticType argument = propagate(e.operand, environment, generics, context); HashMap<String, SemanticType> binding = new HashMap<String, SemanticType>(); for (int i = 0; i != e.generics.length; ++i) { SemanticType.Var gv = (SemanticType.Var) fn_generics[i]; binding.put(gv.name(), builder.convert(e.generics[i], generics, context)); } fnType = (SemanticType.Function) fnType.substitute(binding); checkIsSubtype(fnType.from(), argument, e.operand); return fnType; }
private void addNamedVariables( TypePattern pattern, HashMap<String, SemanticType> environment, HashSet<String> generics, WyalFile.Context context) { SemanticType type = builder.convert(pattern.toSyntacticType(), generics, context); if (pattern.var != null) { if (environment.containsKey(pattern.var)) { internalFailure("duplicate variable name encountered", filename, pattern); } environment.put(pattern.var, type); } if (pattern instanceof TypePattern.Tuple) { TypePattern.Tuple st = (TypePattern.Tuple) pattern; for (TypePattern t : st.patterns) { addNamedVariables(t, environment, generics, context); } } pattern.attributes().add(new TypeAttribute(type)); }