1 package org.simantics.scl.compiler.compilation;
3 import java.util.ArrayList;
4 import java.util.Collections;
5 import java.util.Iterator;
8 import org.cojen.classfile.TypeDesc;
9 import org.simantics.scl.compiler.common.datatypes.Constructor;
10 import org.simantics.scl.compiler.common.names.Name;
11 import org.simantics.scl.compiler.constants.JavaTypeInstanceConstructor;
12 import org.simantics.scl.compiler.constants.SCLConstructor;
13 import org.simantics.scl.compiler.constants.StringConstant;
14 import org.simantics.scl.compiler.constants.generic.CallJava;
15 import org.simantics.scl.compiler.constants.generic.ClassRef;
16 import org.simantics.scl.compiler.constants.generic.ConvertToListFilter;
17 import org.simantics.scl.compiler.constants.generic.MethodRef;
18 import org.simantics.scl.compiler.constants.generic.OutputFilter;
19 import org.simantics.scl.compiler.constants.generic.ParameterStackItem;
20 import org.simantics.scl.compiler.constants.generic.PopOutputFilter;
21 import org.simantics.scl.compiler.constants.generic.StackItem;
22 import org.simantics.scl.compiler.constants.generic.ThreadLocalStackItem;
23 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
24 import org.simantics.scl.compiler.elaboration.contexts.TypeTranslationContext;
25 import org.simantics.scl.compiler.elaboration.errors.NotPatternException;
26 import org.simantics.scl.compiler.elaboration.expressions.EApply;
27 import org.simantics.scl.compiler.elaboration.expressions.EGetConstraint;
28 import org.simantics.scl.compiler.elaboration.expressions.EIntegerLiteral;
29 import org.simantics.scl.compiler.elaboration.expressions.EListLiteral;
30 import org.simantics.scl.compiler.elaboration.expressions.ELiteral;
31 import org.simantics.scl.compiler.elaboration.expressions.EVar;
32 import org.simantics.scl.compiler.elaboration.expressions.Expression;
33 import org.simantics.scl.compiler.elaboration.expressions.Variable;
34 import org.simantics.scl.compiler.elaboration.fundeps.Fundep;
35 import org.simantics.scl.compiler.elaboration.java.JavaMethodDeclaration;
36 import org.simantics.scl.compiler.elaboration.macros.StandardMacroRule;
37 import org.simantics.scl.compiler.elaboration.modules.InlineProperty;
38 import org.simantics.scl.compiler.elaboration.modules.MethodImplementation;
39 import org.simantics.scl.compiler.elaboration.modules.PrivateProperty;
40 import org.simantics.scl.compiler.elaboration.modules.SCLValue;
41 import org.simantics.scl.compiler.elaboration.modules.TypeAlias;
42 import org.simantics.scl.compiler.elaboration.modules.TypeClass;
43 import org.simantics.scl.compiler.elaboration.modules.TypeClassInstance;
44 import org.simantics.scl.compiler.elaboration.modules.TypeClassMethod;
45 import org.simantics.scl.compiler.elaboration.query.Query;
46 import org.simantics.scl.compiler.elaboration.query.pre.QPreGuard;
47 import org.simantics.scl.compiler.elaboration.relations.ConcreteRelation;
48 import org.simantics.scl.compiler.elaboration.rules.MappingRelation;
49 import org.simantics.scl.compiler.elaboration.rules.SectionName;
50 import org.simantics.scl.compiler.elaboration.rules.TransformationRule;
51 import org.simantics.scl.compiler.environment.AmbiguousNameException;
52 import org.simantics.scl.compiler.environment.Environment;
53 import org.simantics.scl.compiler.environment.EnvironmentFactory;
54 import org.simantics.scl.compiler.environment.Environments;
55 import org.simantics.scl.compiler.errors.ErrorLog;
56 import org.simantics.scl.compiler.errors.Locations;
57 import org.simantics.scl.compiler.internal.codegen.effects.EffectConstructor;
58 import org.simantics.scl.compiler.internal.codegen.effects.ThreadLocalVariable;
59 import org.simantics.scl.compiler.internal.codegen.types.JavaReferenceValidator;
60 import org.simantics.scl.compiler.internal.codegen.types.JavaTypeTranslator;
61 import org.simantics.scl.compiler.internal.codegen.types.StandardTypeConstructor;
62 import org.simantics.scl.compiler.internal.codegen.utils.Constants;
63 import org.simantics.scl.compiler.internal.codegen.utils.JavaNamingPolicy;
64 import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilderBase;
65 import org.simantics.scl.compiler.internal.deriving.InstanceDeriver;
66 import org.simantics.scl.compiler.internal.deriving.InstanceDerivers;
67 import org.simantics.scl.compiler.internal.elaboration.profiling.BranchPointInjector;
68 import org.simantics.scl.compiler.internal.elaboration.utils.StronglyConnectedComponents;
69 import org.simantics.scl.compiler.internal.parsing.declarations.ConstructorAst;
70 import org.simantics.scl.compiler.internal.parsing.declarations.DAnnotationAst;
71 import org.simantics.scl.compiler.internal.parsing.declarations.DClassAst;
72 import org.simantics.scl.compiler.internal.parsing.declarations.DDataAst;
73 import org.simantics.scl.compiler.internal.parsing.declarations.DDerivingInstanceAst;
74 import org.simantics.scl.compiler.internal.parsing.declarations.DEffectAst;
75 import org.simantics.scl.compiler.internal.parsing.declarations.DFixityAst;
76 import org.simantics.scl.compiler.internal.parsing.declarations.DInstanceAst;
77 import org.simantics.scl.compiler.internal.parsing.declarations.DMappingRelationAst;
78 import org.simantics.scl.compiler.internal.parsing.declarations.DRelationAst;
79 import org.simantics.scl.compiler.internal.parsing.declarations.DRuleAst;
80 import org.simantics.scl.compiler.internal.parsing.declarations.DTypeAst;
81 import org.simantics.scl.compiler.internal.parsing.declarations.DValueAst;
82 import org.simantics.scl.compiler.internal.parsing.declarations.DValueTypeAst;
83 import org.simantics.scl.compiler.internal.parsing.exceptions.SCLSyntaxErrorException;
84 import org.simantics.scl.compiler.internal.parsing.translation.ProcessedDClassAst;
85 import org.simantics.scl.compiler.internal.parsing.translation.ProcessedDInstanceAst;
86 import org.simantics.scl.compiler.internal.parsing.translation.RelationRepository;
87 import org.simantics.scl.compiler.internal.parsing.translation.ValueRepository;
88 import org.simantics.scl.compiler.internal.parsing.types.TypeAst;
89 import org.simantics.scl.compiler.module.ConcreteModule;
90 import org.simantics.scl.compiler.module.ImportDeclaration;
91 import org.simantics.scl.compiler.module.repository.ImportFailure;
92 import org.simantics.scl.compiler.module.repository.ImportFailureException;
93 import org.simantics.scl.compiler.types.TCon;
94 import org.simantics.scl.compiler.types.TForAll;
95 import org.simantics.scl.compiler.types.TFun;
96 import org.simantics.scl.compiler.types.TPred;
97 import org.simantics.scl.compiler.types.TVar;
98 import org.simantics.scl.compiler.types.Type;
99 import org.simantics.scl.compiler.types.Types;
100 import org.simantics.scl.compiler.types.kinds.Kind;
101 import org.simantics.scl.compiler.types.kinds.Kinds;
102 import org.simantics.scl.compiler.types.util.MultiFunction;
103 import org.simantics.scl.runtime.profiling.BranchPoint;
105 import gnu.trove.list.array.TIntArrayList;
106 import gnu.trove.map.hash.THashMap;
107 import gnu.trove.map.hash.TObjectIntHashMap;
108 import gnu.trove.procedure.TObjectObjectProcedure;
109 import gnu.trove.set.hash.THashSet;
110 import gnu.trove.set.hash.TIntHashSet;
112 public class Elaboration {
116 ArrayList<ImportDeclaration> importsAst;
117 JavaReferenceValidator<Object, Object, Object, Object> javaReferenceValidator;
118 ValueRepository valueDefinitionsAst;
119 RelationRepository relationDefinitionsAst;
122 ConcreteModule module;
123 Environment importedEnvironment;
124 Environment environment;
125 JavaNamingPolicy namingPolicy;
126 ArrayList<SupplementedValueType> supplementedTypeAnnotations = new ArrayList<SupplementedValueType>();
128 JavaTypeTranslator javaTypeTranslator;
129 ArrayList<StandardTypeConstructor> dataTypes = new ArrayList<StandardTypeConstructor>();
130 THashMap<String, ClassRef> classRefs = new THashMap<String, ClassRef>();
131 THashMap<String, BranchPoint[]> branchPoints;
133 @SuppressWarnings("unchecked")
134 public Elaboration(ErrorLog errorLog, CompilationTimer timer, EnvironmentFactory localEnvironmentFactory,
135 String moduleName, ArrayList<ImportDeclaration> importsAst,
136 JavaReferenceValidator<?, ?, ?, ?> javaReferenceValidator,
137 ValueRepository valueDefinitionsAst,
138 RelationRepository relationDefinitionsAst) {
139 this.errorLog = errorLog;
140 this.moduleName = moduleName;
141 importsAst = processRelativeImports(importsAst);
142 this.importsAst = importsAst;
143 this.javaReferenceValidator = (JavaReferenceValidator<Object, Object, Object, Object>)javaReferenceValidator;
144 this.valueDefinitionsAst = valueDefinitionsAst;
145 this.relationDefinitionsAst = relationDefinitionsAst;
147 module = new ConcreteModule(moduleName);
150 timer.suspendTimer();
151 importedEnvironment = localEnvironmentFactory.createEnvironment(
152 importsAst.toArray(new ImportDeclaration[importsAst.size()]));
154 timer.continueTimer();
155 this.environment = new EnvironmentOfModule(importedEnvironment, module);
156 } catch (ImportFailureException e) {
157 for(ImportFailure failure : e.failures)
158 errorLog.log(failure.location, failure.toString());
161 for(ImportDeclaration importAst : importsAst)
162 this.module.addDependency(new ImportDeclaration(
163 importAst.moduleName,
164 importAst.reexport ? importAst.localName : null,
167 localEnvironmentFactory.addBuiltinDependencies(module);
168 namingPolicy = new JavaNamingPolicy(moduleName);
171 private ArrayList<ImportDeclaration> processRelativeImports(ArrayList<ImportDeclaration> relativeImports) {
172 ArrayList<ImportDeclaration> absoluteImports = new ArrayList<ImportDeclaration>(relativeImports.size());
173 for(ImportDeclaration relativeImport : relativeImports) {
174 if(relativeImport.moduleName.startsWith(".")) {
175 String absoluteModuleName = convertRelativeModulePath(relativeImport.location, relativeImport.moduleName);
176 if(absoluteModuleName != null) {
177 ImportDeclaration absoluteImport = new ImportDeclaration(
178 absoluteModuleName, relativeImport.localName,
179 relativeImport.reexport, relativeImport.spec);
180 absoluteImport.location = relativeImport.location;
181 absoluteImports.add(absoluteImport);
185 absoluteImports.add(relativeImport);
187 return absoluteImports;
190 private String convertRelativeModulePath(long location, String relativeModuleName) {
191 String originalRelativeModuleName = relativeModuleName;
192 int p = moduleName.lastIndexOf('/');
193 String parentPackage = p < 0 ? "" : moduleName.substring(0, p);
194 while(relativeModuleName.startsWith(".")) {
195 if(relativeModuleName.startsWith("./")) {
196 relativeModuleName = relativeModuleName.substring(2);
198 else if(relativeModuleName.startsWith("../")) {
199 relativeModuleName = relativeModuleName.substring(3);
200 if(parentPackage.isEmpty()) {
201 errorLog.log(location, "Couldn't resolve the relative module name " + originalRelativeModuleName + " when the current module name is " + moduleName + ".");
204 p = parentPackage.lastIndexOf('/');
205 parentPackage = p < 0 ? "" : parentPackage.substring(0, p);
208 errorLog.log(location, "Couldn't resolve the relative module name " + originalRelativeModuleName + ". It has an invalid syntax.");
212 return parentPackage + "/" + relativeModuleName;
215 public void addTypesToEnvironment(
216 ArrayList<DDataAst> dataTypesAst,
217 ArrayList<DTypeAst> typeAliasesAst,
218 ArrayList<DEffectAst> effectsAst) {
219 for(DDataAst dataType : dataTypesAst) {
220 dataType.parameterKinds = new Kind[dataType.parameters.length];
221 Kind constructorKind = Kinds.STAR;
222 for(int i=dataType.parameters.length-1;i>=0;--i) {
223 Kind kind = Kinds.metaVar();
224 dataType.parameterKinds[i] = kind;
225 constructorKind = Kinds.arrow(kind, constructorKind);
228 StandardTypeConstructor typeConstructor = new StandardTypeConstructor(
229 Types.con(moduleName, dataType.name), constructorKind);
231 NameExistenceChecks.checkIfTypeExists(errorLog,
232 dataType.location, importedEnvironment, dataType.name);
233 if(module.addTypeConstructor(dataType.name, typeConstructor))
234 errorLog.log(dataType.location, "Type "+dataType.name+" has already been defined in this module.");
235 dataType.typeConstructor = typeConstructor;
238 for(DTypeAst typeAlias : typeAliasesAst) {
239 TypeAlias alias = new TypeAlias(Types.con(moduleName, typeAlias.name), typeAlias.parameters.length);
240 NameExistenceChecks.checkIfTypeExists(errorLog,
241 typeAlias.location, importedEnvironment, typeAlias.name);
242 if(module.addTypeAlias(typeAlias.name, alias)) {
243 errorLog.log(typeAlias.location, "Type alias "+typeAlias.name+" has already been defined in this module.");
247 for(DEffectAst effect : effectsAst) {
248 EffectConstructor effectConstructor = new EffectConstructor(Types.con(moduleName, effect.name));
249 effectConstructor.addThreadLocalVariable(
250 new ThreadLocalVariable(
252 TypeDesc.forClass(effect.threadLocalType)
254 if(module.addEffectConstructor(effect.name, effectConstructor))
255 errorLog.log(effect.location, "Type "+effect.name+" has already been defined in this module.");
257 javaTypeTranslator = new JavaTypeTranslator(environment);
260 private static final int[] EMPTY_INT_ARRAY = new int[0];
262 public void processTypeAliases(ArrayList<DTypeAst> typeAliasesAst) {
263 TObjectIntHashMap<String> typeAliasMap = new TObjectIntHashMap<String>();
264 for(int i=0;i<typeAliasesAst.size();++i)
265 typeAliasMap.put(typeAliasesAst.get(i).name, i);
266 TIntHashSet tempIntSet = new TIntHashSet();
267 ArrayList<DTypeAst> orderedTypeAliases = new ArrayList<DTypeAst>(typeAliasesAst.size());
268 //for(int i=0;i<typeAliasesAst.size();++i)
269 // System.out.println(i + "# " + typeAliasesAst.get(i).name);
270 new StronglyConnectedComponents(typeAliasesAst.size()) {
272 protected int[] findDependencies(int u) {
273 typeAliasesAst.get(u).type.collectReferences(typeAliasMap, tempIntSet);
274 if(tempIntSet.isEmpty())
275 return EMPTY_INT_ARRAY;
276 if(tempIntSet.contains(u)) {
277 errorLog.log(typeAliasesAst.get(u).location, "Type alias has a self reference.");
278 tempIntSet.remove(u);
280 int[] result = tempIntSet.toArray();
282 //System.out.println(u + " -> " + Arrays.toString(result));
286 protected void reportComponent(int[] component) {
287 //System.out.println("component: " + Arrays.toString(component));
288 if(component.length > 1) {
289 StringBuilder b = new StringBuilder();
290 b.append("Recursively defined type alias (");
291 long minLocation = typeAliasesAst.get(component[0]).location;
292 boolean first = true;
293 for(int u : component) {
294 DTypeAst typeAlias = typeAliasesAst.get(u);
299 b.append(typeAlias.name);
300 if(Locations.beginOf(typeAlias.location) < Locations.beginOf(minLocation))
301 minLocation = typeAlias.location;
304 errorLog.log(minLocation, b.toString());
307 orderedTypeAliases.add(typeAliasesAst.get(component[0]));
311 if(errorLog.isEmpty()) {
312 for(DTypeAst typeAlias : orderedTypeAliases) {
313 TypeAlias alias = module.getTypeAlias(typeAlias.name);
314 TypeTranslationContext context = createTypeTranslationContext();
315 for(int i=0;i<typeAlias.parameters.length;++i)
316 context.pushTypeVar(typeAlias.parameters[i]);
317 alias.body = typeAlias.type.toType(context, Kinds.metaVar());
318 for(int i=0;i<typeAlias.parameters.length;++i)
319 alias.parameters[i] = context.popTypeVar(typeAlias.parameters[i], null);
324 public void processDataTypes(ArrayList<DDataAst> dataTypesAst) {
325 for(DDataAst dataTypeAst : dataTypesAst) {
326 TypeTranslationContext context = createTypeTranslationContext();
327 TVar[] typeParameters = new TVar[dataTypeAst.parameters.length];
328 for(int i=0;i<dataTypeAst.parameters.length;++i)
329 typeParameters[i] = context.addTypeVar(dataTypeAst.parameters[i]);
330 Constructor[] constructors = new Constructor[dataTypeAst.constructors.length];
331 String className = null;
332 boolean external = false;
333 for(DAnnotationAst annotation : dataTypeAst.getAnnotations()) {
334 if(annotation.id.text.equals("@JavaType")) {
335 if(annotation.parameters.length != 1 ||
336 !(annotation.parameters[0] instanceof ELiteral) ||
337 !(((ELiteral)annotation.parameters[0]).getValue() instanceof StringConstant))
338 errorLog.log(annotation.location, "Invalid parameters. Expected @JavaType \"className\".");
340 className = ((StringConstant)((ELiteral)annotation.parameters[0]).getValue()).getValue().replace('.', '/');
347 boolean trivialDataType = dataTypeAst.constructors.length == 1 &&
348 dataTypeAst.constructors[0].parameters.length == 1;
349 if(className == null && !trivialDataType)
350 className = namingPolicy.getDataTypeClassName(dataTypeAst.name);
352 StandardTypeConstructor dataType = dataTypeAst.typeConstructor;
354 dataType.setType(Types.con(moduleName, dataTypeAst.name), typeParameters);
355 dataType.setConstructors(constructors);
357 dataType.setTypeDesc(TypeDesc.forClass(className));
358 if(!external || dataTypeAst.constructors.length > 0) {
359 dataType.isOpen = false;
361 dataType.external = external;
362 dataTypes.add(dataType);
363 for(int j=0;j<constructors.length;++j) {
364 ConstructorAst constructor = dataTypeAst.constructors[j];
365 String name = constructor.name;
366 Type[] parameterTypes = new Type[constructor.parameters.length];
367 for(int i=constructor.parameters.length-1;i>=0;--i)
368 parameterTypes[i] = context.toType(constructor.parameters[i]);
369 String javaName = constructors.length == 1 ? className
370 : namingPolicy.getConstructorClassName(name);
371 String[] fieldNames = null;
372 for(DAnnotationAst annotation : constructor.annotations)
373 if(annotation.id.text.equals("@JavaType")) {
375 javaName = ((StringConstant)((ELiteral)annotation.parameters[0])
376 .getValue()).getValue();
377 } catch(Exception e) {
378 errorLog.log(annotation.parameters[0].location, "Invalid annotation parameter.");
381 else if(annotation.id.text.equals("@FieldNames")) {
383 EListLiteral literal = (EListLiteral)annotation.parameters[0];
384 fieldNames = new String[literal.getComponents().length];
385 for(int i=0;i<fieldNames.length;++i) {
386 Expression component = literal.getComponents()[i];
387 if(component instanceof EVar)
388 fieldNames[i] = ((EVar)component).name;
389 else if(component instanceof ELiteral)
390 fieldNames[i] = ((StringConstant)((ELiteral)component).getValue()).getValue();
392 } catch(Exception e) {
393 errorLog.log(annotation.parameters[0].location, "Invalid annotation parameter.");
398 constructors[j] = new Constructor(constructor.location, dataType,
399 Name.create(moduleName, name),
400 parameterTypes, javaName);
401 constructors[j].fieldNames = fieldNames;
402 constructors[j].recordFieldNames = constructor.fieldNames;
407 public void processTypeClasses(ArrayList<ProcessedDClassAst> typeClassesAst) {
408 for(ProcessedDClassAst pClassAst : typeClassesAst) {
409 DClassAst classAst = pClassAst.orig;
411 if(module.getTypeClass(classAst.name) != null) {
412 errorLog.log(classAst.location, "Class "+classAst.name+" has already been defined in this module.");
416 TypeTranslationContext context = createTypeTranslationContext();
418 TPred[] classContext = new TPred[classAst.context.length];
419 for(int i=0;i<classContext.length;++i)
420 classContext[i] = context.toTFuncApply(classAst.context[i]);
422 TVar[] parameters = new TVar[classAst.parameters.length];
424 if(classAst.name.equals("Functor") || classAst.name.equals("Monad")) {
426 parameters[0] = context.resolveTypeVariable(pClassAst.orig.location, classAst.parameters[0], Kinds.STAR_TO_STAR);
429 for(int i=0;i<parameters.length;++i)
430 parameters[i] = context.resolveTypeVariable(pClassAst.orig.location, classAst.parameters[i], Kinds.metaVar());
433 TCon con = Types.con(moduleName, classAst.name);
434 TypeClass typeClass = new TypeClass(classAst.location,
437 namingPolicy.getTypeClassInterfaceName(con),
439 Fundep.mapFundeps(classAst.parameters, classAst.fundeps));
441 THashMap<String, TypeClassMethod> methods = typeClass.methods;
442 for(DValueTypeAst methodDecl : pClassAst.typeDeclarations) {
446 type = context.toType(methodDecl.type);
447 } catch(SCLSyntaxErrorException e) {
448 errorLog.log(e.location, e.getMessage());
451 for(EVar name : methodDecl.names) {
452 typeClass.methodNames.add(name.name);
453 methods.put(name.name,
454 new TypeClassMethod(typeClass, name.name,
455 namingPolicy.getMethodName(name.name),
456 type, Types.getArity(type),
460 } catch(RuntimeException e) {
461 errorLog.setExceptionPosition(methodDecl.location);
466 for(String methodName : pClassAst.defaultImplementations.getValueNames()) {
467 String fullName = "_" + classAst.name + "_default_" + methodName;
468 ArrayList<DValueAst> defs = pClassAst.defaultImplementations.getDefinition(methodName);
470 TypeClassMethod method = typeClass.methods.get(methodName);
472 errorLog.log(defs.get(0).location, "Method " + methodName + " is not defined in this class.");
475 method.setDefaultImplementation(Name.create(moduleName, fullName));
477 valueDefinitionsAst.addDefinitions(fullName, defs);
478 /*valueDefinitionsAst.addAnnotation(fullName, new DAnnotationAst(new EVar("@private"),
479 Collections.<Expression>emptyList()));*/
480 supplementedTypeAnnotations.add(new SupplementedValueType(defs.get(0).location, fullName, method.getType()));
483 module.addTypeClass(classAst.name, typeClass);
487 private TypeTranslationContext createTypeTranslationContext() {
488 return new TypeTranslationContext(errorLog, environment);
491 public void processDerivingInstances(ArrayList<DDerivingInstanceAst> derivingInstancesAst,
492 ArrayList<ProcessedDInstanceAst> instancesAst) {
493 for(DDerivingInstanceAst derivingInstance : derivingInstancesAst) {
494 String name = derivingInstance.name.name;
497 con = Environments.getTypeClassName(environment, name);
498 } catch (AmbiguousNameException e) {
499 errorLog.log(derivingInstance.name.location, e.getMessage());
503 errorLog.log(derivingInstance.name.location, "Couldn't resolve class " + name + ".");
506 InstanceDeriver deriver = InstanceDerivers.get(con);
508 errorLog.log(derivingInstance.location, "Doesn't know how to derive " + name + ".");
510 deriver.derive(errorLog, environment, instancesAst, derivingInstance);
514 public void processInstances(ArrayList<ProcessedDInstanceAst> instancesAst) {
515 THashSet<TPred> instanceClashCheckSet = new THashSet<TPred>();
516 for(ProcessedDInstanceAst pInstanceAst : instancesAst) {
517 DInstanceAst instanceAst = pInstanceAst.orig;
519 TypeTranslationContext context = createTypeTranslationContext();
521 String name = instanceAst.name.name;
524 typeClassCon = Environments.getTypeClassName(environment, name);
525 } catch (AmbiguousNameException e) {
526 errorLog.log(instanceAst.name.location, e.getMessage());
529 if(typeClassCon == null) {
530 errorLog.log(instanceAst.name.location, "Couldn't resolve class " + name + ".");
533 TypeClass typeClass = environment.getTypeClass(typeClassCon);
534 pInstanceAst.typeClass = typeClass;
536 if(instanceAst.types.length != typeClass.parameters.length) {
537 errorLog.log(instanceAst.location, "Wrong number of parameters to type class " + typeClassCon.name + ".");
540 Type[] parameters = new Type[instanceAst.types.length];
541 for(int i=0;i<parameters.length;++i)
542 parameters[i] = context.toType(instanceAst.types[i], typeClass.parameters[i].getKind() /* FIXME */);
543 TPred instance = Types.pred(typeClassCon, parameters);
545 if(!instanceClashCheckSet.add(instance)) {
546 errorLog.log(instanceAst.location, "Duplicate definition of the instance " + instance + ".");
550 TPred[] instanceContext = new TPred[instanceAst.context.length];
551 for(int i=0;i<instanceContext.length;++i)
552 instanceContext[i] = context.toTFuncApply(instanceAst.context[i]);
554 String javaName = namingPolicy.getInstanceClassName(instance);
555 String instancePrefix = instance.toName() + "$";
557 ValueRepository valueDefs = pInstanceAst.valueDefs;
559 THashMap<String, MethodImplementation> methodImplementations =
560 new THashMap<String, MethodImplementation>();
561 for(String valueName : valueDefs.getValueNames()) {
562 String fullName = instancePrefix + valueName;
563 long loc = valueDefs.getDefinition(valueName).get(0).location;
564 valueDefinitionsAst.addFrom(valueDefs, valueName, fullName);
565 /*valueDefinitionsAst.addAnnotation(fullName, new DAnnotationAst(new EVar("@private"),
566 Collections.<Expression>emptyList()));*/
567 TypeClassMethod method = typeClass.methods.get(valueName);
569 errorLog.log(loc, "Method " + valueName + " is not defined in the type class " + typeClass.name.name + ".");
572 Type type = method.getBaseType().replace(typeClass.parameters, parameters);
573 for(int i=instanceContext.length-1;i>=0;--i)
574 type = Types.constrained(instanceContext[i], type);
575 //System.out.println(valueName + " :: " + type);
576 supplementedTypeAnnotations.add(
577 new SupplementedValueType(loc, fullName, type));
578 methodImplementations.put(valueName,
579 new MethodImplementation(Name.create(moduleName, fullName), false));
582 // Are all necessary methods defined
583 for(String methodName : typeClass.methods.keySet())
584 if(!methodImplementations.containsKey(methodName)) {
585 Name defaultImplementation = typeClass.methods.get(methodName).getDefaultImplementation();
586 if(defaultImplementation == null)
587 errorLog.log(instanceAst.location, "Method " + methodName + " is not defined.");
589 methodImplementations.put(methodName,
590 new MethodImplementation(defaultImplementation, true));
593 JavaTypeInstanceConstructor generator = new JavaTypeInstanceConstructor(javaName, instance, instanceContext);
594 if(instanceContext.length == 0)
595 generator.setHasStaticInstance(true);
597 TypeClassInstance typeClassInstance =
598 new TypeClassInstance(instanceAst.location, typeClass, generator,
599 generator.getTypeParameters(),
600 instanceContext, instance, methodImplementations,
603 generator.setInstance(typeClassInstance);
605 module.addTypeClassInstance(typeClassCon, typeClassInstance);
606 } catch(RuntimeException e) {
607 errorLog.setExceptionPosition(instanceAst.location);
612 // Generate superclass functions
613 for(ArrayList<TypeClassInstance> instanceArray : module.getTypeInstances().values())
614 for(TypeClassInstance instance : instanceArray) {
616 TypeClass typeClass = instance.typeClass;
617 int superCount = typeClass.context.length;
619 instance.superExpressions = new SCLValue[superCount];
620 for(int i=0;i<superCount;++i) {
621 TPred type = (TPred)typeClass.context[i]
622 .replace(typeClass.parameters, instance.instance.parameters);
623 SCLValue value = new SCLValue(Name.create(moduleName,
624 instance.javaName.substring(instance.javaName.indexOf('$')+1) + "_super" + i));
625 //value.addProperty(PrivateProperty.INSTANCE);
626 module.addValue(value);
627 Expression expression = new EGetConstraint(instance.location, type);
628 value.setExpression(expression);
629 value.setType(Types.forAll(instance.generatorParameters, Types.constrained(instance.context, type)));
630 //TypeUnparsingContext tuc = new TypeUnparsingContext();
631 // TODO error handling
632 instance.superExpressions[i] = value;
634 } catch(RuntimeException e) {
635 errorLog.setExceptionPosition(instance.getLocation());
641 public void processJavaMethods(ArrayList<JavaMethodDeclaration> javaMethodDeclarations) {
642 for(JavaMethodDeclaration javaMethod : javaMethodDeclarations) {
643 String name = javaMethod.methodName.name;
644 String javaName = name;
645 ArrayList<DAnnotationAst> annotations =
646 valueDefinitionsAst.getAnnotations(name);
647 boolean isPrivate = false;
648 if(annotations != null) {
649 for(DAnnotationAst annotation : annotations)
650 if(annotation.id.text.equals("@JavaName")) {
651 Expression p0 = annotation.parameters[0];
652 if(p0 instanceof EVar)
653 javaName = ((EVar)p0).name;
654 else if(p0 instanceof ELiteral) {
655 ELiteral lit = (ELiteral)p0;
656 javaName = ((StringConstant)lit.getValue()).getValue();
659 else if(annotation.id.text.equals("@private")) {
664 Type type = createTypeTranslationContext().toType(javaMethod.type);
666 CallJava callJava = resolveMethod(
668 javaMethod.className,
671 if(callJava != null) {
672 NameExistenceChecks.checkIfValueExists(errorLog, javaMethod.location,
673 importedEnvironment, name);
674 SCLValue value = module.addValue(name, callJava);
675 value.definitionLocation = javaMethod.methodName.location;
677 value.addProperty(PrivateProperty.INSTANCE);
683 * Convert a java class method into a {@link CallJava} instance.
684 * Compilation errors are logged for failures in finding the named class or in accessing the method.
685 * The return value for errors is {@code null}.
687 * @param loc SCL source location
688 * @param className Name of the class
689 * @param methodName Name of the method
690 * @param type The expected SCL type of the method
691 * @return A new JavaCall instance, or null if the given method can not be instantiated.
693 private CallJava resolveMethod(long loc,
694 String className, String methodName, Type type) {
696 ClassRef classRef = classRefs.get(className);
697 if(classRef == null) {
698 if(classRefs.containsKey(className))
700 classRef = javaReferenceValidator.getClassRef(className);
701 classRefs.put(className, classRef);
702 if(classRef == null) {
703 errorLog.log(loc, "Didn't find class " + className + ".");
706 if(!javaReferenceValidator.isPublic(classRef.getClass())) {
707 errorLog.log(loc, "Class " + className + " is not public.");
714 List<MethodRef> methodRefs = classRef.getMethodRefs(methodName);
715 if(methodRefs.isEmpty()) {
716 errorLog.log(loc, "Didn't find any public method or field with name '" + methodName + "' from class " + className + ".");
720 ArrayList<CallJava> candidates = new ArrayList<CallJava>(2);
721 for(MethodRef methodRef : methodRefs) {
722 CallJava candidate = matchType(methodRef, type);
723 if(candidate != null)
724 candidates.add(candidate);
727 if(candidates.isEmpty()) {
728 StringBuilder b = new StringBuilder();
729 b.append("Didn't find any public method or field matching the type " + type + ". The following methods and fields were tried:");
730 for(MethodRef methodRef : methodRefs) {
734 b.append("\nbut expected something like:");
736 MultiFunction mFun = Types.matchFunction(type);
737 b.append("\n public static ");
738 b.append(javaTypeTranslator.toTypeDesc(mFun.returnType).getFullName()).append(' ').append(methodName).append('(');
739 boolean first = true;
740 for(Type parameter : mFun.parameterTypes) {
745 b.append(javaTypeTranslator.toTypeDesc(parameter).getFullName());
749 errorLog.log(loc, b.toString());
752 else if(candidates.size() == 1)
753 return candidates.get(0);
755 // Try to find the best match
756 ArrayList<CallJava> bestCandidates = new ArrayList<CallJava>(candidates.size());
757 loop: for(CallJava candidate : candidates) {
758 Iterator<CallJava> it = bestCandidates.iterator();
759 while(it.hasNext()) {
760 CallJava b = it.next();
761 switch(candidate.compareTo(javaReferenceValidator, b)) {
765 case CallJava.GREATER:
768 case CallJava.INCOMPARABLE:
772 bestCandidates.add(candidate);
775 if(bestCandidates.size() == 1) {
776 // System.out.println("Choose: " + bestCandidates.get(0).getMethodRef());
777 return bestCandidates.get(0);
780 StringBuilder b = new StringBuilder();
781 b.append("Found more than one incomparable public methods the type " + type + ":");
782 for(CallJava callJava : bestCandidates) {
784 b.append(callJava.getMethodRef());
786 errorLog.log(loc, b.toString());
792 private CallJava matchType(MethodRef methodRef, Type type) {
793 //System.out.println("-----------------------------------------------------");
794 //System.out.println("method: " + methodRef);
795 //System.out.println("type: " + type);
797 type = Types.canonical(type);
798 while(type instanceof TForAll)
799 type = Types.canonical(((TForAll)type).type);
801 TypeDesc[] expectedParameterTypes = methodRef.getParameterTypes();
803 ArrayList<Type> parameterTypes = new ArrayList<Type>();
804 Type effect = Types.NO_EFFECTS;
805 Type returnType = type;
807 StackItem[] stackItems = new StackItem[expectedParameterTypes.length];
808 TIntArrayList unresolvedItems = new TIntArrayList();
811 for(int i=0;i<expectedParameterTypes.length;++i) {
813 TypeDesc providedParameterType;
815 if(effect != Types.NO_EFFECTS || !(returnType instanceof TFun)) {
816 while(i < expectedParameterTypes.length)
817 unresolvedItems.add(i++);
820 TFun fun = (TFun)returnType;
821 parameterType = Types.canonical(fun.domain);
822 parameterTypes.add(parameterType);
823 effect = Types.canonical(fun.effect);
824 returnType = Types.canonical(fun.range);
825 providedParameterType = javaTypeTranslator.toTypeDesc(parameterType);
826 } while(providedParameterType.equals(TypeDesc.VOID));
829 TypeDesc expectedParameterType = expectedParameterTypes[i];
830 if(javaReferenceValidator.isAssignableFrom(expectedParameterType,
831 providedParameterType)) {
832 stackItems[i] = new ParameterStackItem(
833 parameterTypes.size()-1,
838 unresolvedItems.add(i++);
839 if(i == expectedParameterTypes.length) {
840 parameterTypes.remove(parameterTypes.size()-1);
841 returnType = Types.functionE(parameterType, effect, returnType);
846 //System.out.println("returnType: " + returnType);
847 if(!unresolvedItems.isEmpty()) {
848 ArrayList<TCon> concreteEffects = new ArrayList<TCon>();
849 effect.collectConcreteEffects(concreteEffects);
851 for(TCon eff : concreteEffects) {
852 EffectConstructor effC = environment.getEffectConstructor(eff);
853 for(ThreadLocalVariable var : effC.getThreadLocalVariables()) {
854 for(int i=0;i<unresolvedItems.size();++i) {
855 int id = unresolvedItems.get(i);
856 if(!expectedParameterTypes[id].equals(TypeDesc.OBJECT) &&
857 javaReferenceValidator.isAssignableFrom(expectedParameterTypes[id], var.type)) {
858 stackItems[id] = new ThreadLocalStackItem(var.variableName, var.type);
859 unresolvedItems.removeAt(i);
866 if(!unresolvedItems.isEmpty())
868 /*System.out.print("Unresolved: ");
869 boolean first = true;
870 for(int i=0;i<unresolvedItems.size();++i) {
874 System.out.print(", ");
875 System.out.print(expectedParameterTypes[unresolvedItems.get(i)]);
877 System.out.println();*/
879 OutputFilter filter = null;
881 TypeDesc providedReturnType = methodRef.getReturnType();
882 if(!providedReturnType.equals(Constants.FUNCTION)) {
883 while(returnType instanceof TFun && effect == Types.NO_EFFECTS) {
884 TFun fun = (TFun)returnType;
885 Type parameterType = Types.canonical(fun.domain);
886 if(!javaTypeTranslator.toTypeDesc(parameterType).equals(TypeDesc.VOID))
888 parameterTypes.add(parameterType);
889 effect = Types.canonical(fun.effect);
890 returnType = Types.canonical(fun.range);
893 TypeDesc expectedReturnType =
894 javaTypeTranslator.toTypeDesc(returnType);
895 if(!javaReferenceValidator.isAssignableFrom(expectedReturnType,
896 providedReturnType)) {
897 if(expectedReturnType.equals(TypeDesc.VOID))
898 filter = PopOutputFilter.INSTANCE;
899 else if(expectedReturnType.equals(Constants.LIST)
900 && providedReturnType.equals(Constants.COLLECTION))
901 filter = ConvertToListFilter.INSTANCE;
907 CallJava result = new CallJava(
908 Types.freeVarsArray(type),
911 parameterTypes.toArray(new Type[parameterTypes.size()]),
915 //System.out.println(result.getType());
919 public void processMappingRelations(ArrayList<DMappingRelationAst> mappingRelationsAst) {
920 for(DMappingRelationAst mappingRelation : mappingRelationsAst) {
921 TypeAst[] parameterTypesAst = mappingRelation.parameterTypes;
922 Type[] parameterTypes = new Type[parameterTypesAst.length];
923 TypeTranslationContext typeTranslationContext = createTypeTranslationContext();
924 for(int i=0;i<parameterTypes.length;++i)
925 parameterTypes[i] = parameterTypesAst[i].toType(typeTranslationContext, Kinds.STAR);
926 MappingRelation mRel =
927 new MappingRelation(Name.create(moduleName, mappingRelation.name), parameterTypes);
928 mRel.location = mappingRelation.location;
929 if(module.addMappingRelation(mRel))
930 errorLog.log(mappingRelation.location, "Mapping relation " + mappingRelation.name +
931 " has already been defined.");
935 THashMap<String, DRuleAst> ruleAstMap = new THashMap<String, DRuleAst>();
937 public void processRules(ArrayList<DRuleAst> rulesAst) {
938 // Find implied mapping relations
939 for(DRuleAst ruleA : rulesAst) {
940 ArrayList<Query> whereSection = ruleA.getSections().get("where");
941 if(whereSection != null)
942 for(Query query : whereSection) {
943 if(!(query instanceof QPreGuard))
945 QPreGuard guard = (QPreGuard)query;
946 if(!(guard.guard instanceof EApply))
948 EApply apply = (EApply)guard.guard;
949 if(!(apply.getFunction() instanceof EVar))
952 String name = ((EVar)apply.getFunction()).name;
953 if(module.getMappingRelation(name) != null)
956 int arity = apply.getParameters().length;
957 Type[] parameterTypes = new Type[arity];
958 for(int i=0;i<arity;++i)
959 parameterTypes[i] = Types.metaVar(Kinds.STAR);
960 MappingRelation mRel =
961 new MappingRelation(Name.create(moduleName, name), parameterTypes);
962 mRel.location = query.location;
963 module.addMappingRelation(mRel);
965 if(ruleAstMap.put(ruleA.name, ruleA) != null)
966 errorLog.log(ruleA.location, "Rule " + ruleA.name +
967 " has already been defined.");
971 for(String ruleName : ruleAstMap.keySet())
972 processRule(ruleName);
975 private TransformationRule processRule(String ruleName) {
976 TransformationRule rule = module.getRule(ruleName);
980 DRuleAst ruleAst = ruleAstMap.get(ruleName);
981 if(ruleAst.alreadyProcessing) {
982 errorLog.log(ruleAst.location, "Cyclic chain of rule extensions.");
986 TransformationRule[] extendsRules;
987 int length = ruleAst.extendsNames.length;
989 extendsRules = TransformationRule.EMPTY_ARRAY;
991 extendsRules = new TransformationRule[length];
992 for(int i=0;i<length;++i) {
994 String extendsName = ruleAst.extendsNames[i];
995 TransformationRule extendsRule;
996 if(ruleAstMap.containsKey(extendsName))
997 extendsRule = processRule(extendsName);
999 extendsRule = Environments.getRule(environment, extendsName);
1000 if(extendsRule == null)
1001 errorLog.log(ruleAst.location,
1002 "Couldn't resolve rule name " + extendsName + ".");
1004 extendsRules[i] = extendsRule;
1005 } catch(AmbiguousNameException e) {
1006 errorLog.log(ruleAst.location, e.getMessage());
1011 final THashMap<SectionName, Query[]> sections = new THashMap<SectionName, Query[]>();
1013 final TranslationContext context = createTranslationContext();
1015 THashMap<String, Variable> variables = context.getVariables();
1016 for(TransformationRule extendsRule : extendsRules) {
1017 if(extendsRule == null)
1019 for(Variable var : extendsRule.variables)
1020 if(variables.put(var.getName(), var) != null) {
1021 errorLog.log(ruleAst.location,
1022 "Variable " + var.getName() + " is defined in more than one base rule, which is not currently allowed.");
1026 context.pushExistentialFrame();
1027 ruleAst.getSections().forEachEntry(new TObjectObjectProcedure<String, ArrayList<Query>>() {
1029 public boolean execute(String sectionNameString, ArrayList<Query> queries) {
1030 Query[] resolvedQueries = new Query[queries.size()];
1031 for(int i=0;i<resolvedQueries.length;++i)
1032 resolvedQueries[i] = queries.get(i).resolve(context);
1034 SectionName sectionName = SectionName.getSectionName(sectionNameString);
1035 if(sectionName == null)
1036 context.getErrorLog().log(queries.get(0).location,
1037 "Invalid section name " + sectionNameString + ".");
1039 sections.put(sectionName, resolvedQueries);
1044 Variable[] variables = context.getVariables().values().toArray(new Variable[context.getVariables().size()]);
1046 rule = new TransformationRule(ruleAst.isAbstract,
1047 Name.create(moduleName, ruleAst.name),
1049 sections, variables);
1050 rule.location = ruleAst.location;
1051 module.addRule(rule);
1055 public void addDataTypesToEnvironment() {
1056 for(StandardTypeConstructor dataType : dataTypes) {
1057 int constructorTag = 0;
1058 for(Constructor constructor : dataType.constructors) {
1059 SCLValue value = new SCLValue(constructor.name);
1060 SCLConstructor sclConstructor =
1062 constructor.name.name,
1063 constructor.javaName,
1064 constructor.getTypeVariables(),
1066 constructor.getReturnType(),
1067 constructor.fieldNames == null
1068 ? SCLConstructor.DEFAULT_FIELD_NAMES[constructor.getParameterTypes().length]
1069 : constructor.fieldNames,
1070 constructor.recordFieldNames,
1071 constructor.getParameterTypes());
1072 if(dataType.constructors.length == 1 && (
1073 dataType.getTypeDesc() == null ||
1074 dataType.constructors[0].javaName.equals(MethodBuilderBase.getClassName(dataType.getTypeDesc()))))
1075 sclConstructor.setOnlyConstructor(true);
1076 value.setValue(sclConstructor);
1077 value.setType(constructor.getType());
1079 NameExistenceChecks.checkIfValueExists(errorLog, constructor.loc,
1080 importedEnvironment, constructor.name.name);
1081 if(module.addValue(value)) {
1082 errorLog.log(constructor.loc,
1083 "Value " + constructor.name.name + " is already defined.");
1089 public void addTypeClassesToEnvironment() {
1090 for(TypeClass typeClass : module.getTypeClasses()) {
1091 for(TypeClassMethod method : typeClass.methods.values()) {
1092 SCLValue value = method.createValue();
1093 value.definitionLocation = method.location;
1094 NameExistenceChecks.checkIfValueExists(errorLog, Locations.NO_LOCATION,
1095 importedEnvironment, value.getName().name);
1097 if(module.addValue(value)) {
1098 String name = method.getName();
1099 long location = Locations.NO_LOCATION;
1100 ArrayList<DValueAst> definitions = valueDefinitionsAst.getDefinition(name);
1101 if(definitions != null && !definitions.isEmpty())
1102 location = definitions.get(0).location;
1103 errorLog.log(location, "Value " + name + " is already defined.");
1109 public void preprocessValueDefinitions(ArrayList<DValueTypeAst> typeAnnotationsAst) {
1110 for(String name : valueDefinitionsAst.getValueNames()) {
1111 SCLValue value = new SCLValue(Name.create(moduleName, name));
1113 long location = valueDefinitionsAst.getLocation(name);
1114 NameExistenceChecks.checkIfValueExists(errorLog, location,
1115 importedEnvironment, value.getName().name);
1116 value.definitionLocation = location;
1117 if(module.addValue(value))
1118 errorLog.log(location, "Value " + name + " is already defined.");
1120 for(DValueTypeAst valueTypeAst : typeAnnotationsAst)
1121 for(EVar name : valueTypeAst.names) {
1122 SCLValue value = module.getValue(name.name);
1124 errorLog.log(valueTypeAst.location, name.name + " is not defined.");
1125 value = new SCLValue(Name.create(moduleName, name.name));
1126 module.addValue(value);
1128 value.definitionLocation = name.location;
1130 for(String name : relationDefinitionsAst.getRelationNames()) {
1131 ConcreteRelation relation = new ConcreteRelation(name);
1132 module.addRelation(name, relation);
1136 public void addValueDefinitionsToEnvironment(ArrayList<DValueTypeAst> typeAnnotationsAst) {
1137 THashMap<String, DValueTypeAst> typeMap = new THashMap<String, DValueTypeAst>();
1138 for(DValueTypeAst valueTypeAst : typeAnnotationsAst)
1139 for(EVar name : valueTypeAst.names) {
1140 if(typeMap.containsKey(name.name))
1141 errorLog.log(valueTypeAst.location, "Type of "+name.name+" has already been declared in this module.");
1143 typeMap.put(name.name, valueTypeAst);
1146 for(String name : valueDefinitionsAst.getValueNames()) {
1147 ArrayList<DValueAst> defs = valueDefinitionsAst.getDefinition(name);
1149 SCLValue value = module.getValue(name);
1150 TranslationContext context = createTranslationContext();
1151 Expression expression = context.translateCases2(defs);
1152 value.setExpression(expression);
1154 DValueTypeAst valueTypeAst = typeMap.remove(name);
1155 if(valueTypeAst != null)
1156 value.setType(Types.closure(context.toType(valueTypeAst.type)));
1158 ArrayList<DAnnotationAst> annotations = valueDefinitionsAst.getAnnotations(name);
1159 if(annotations != null)
1160 for(DAnnotationAst annotation : annotations) {
1161 handleAnnotation(value, defs, annotation);
1163 } catch(RuntimeException e) {
1164 errorLog.setExceptionPosition(defs.get(0).location);
1168 for(String name : relationDefinitionsAst.getRelationNames()) {
1169 ArrayList<DRelationAst> definitions = relationDefinitionsAst.getDefinition(name);
1170 if(definitions.size() > 1) {
1171 errorLog.log(definitions.get(1).location,
1172 "Does not yet support definition of relations by more than one rule.");
1176 DRelationAst definition = definitions.get(0);
1177 ConcreteRelation relation = (ConcreteRelation)module.getRelation(name);
1178 relation.location = definition.location;
1179 TranslationContext context = createTranslationContext();
1180 definition.translateTo(context, relation);
1184 private TranslationContext createTranslationContext() {
1185 return new TranslationContext(errorLog, environment, null);
1188 private void handleAnnotation(SCLValue value, ArrayList<DValueAst> defs, DAnnotationAst annotation) {
1189 if(annotation.id.text.equals("@macro")) {
1190 value.setMacroRule(new StandardMacroRule());
1192 else if(annotation.id.text.equals("@inline")) {
1194 int arity = defs.get(0).lhs.getFunctionDefinitionArity();
1195 int phaseMask = 0xffffffff;
1196 if(annotation.parameters.length > 0) {
1197 phaseMask = Integer.parseInt(((EIntegerLiteral)annotation.parameters[0]).getValue());
1199 value.addProperty(new InlineProperty(arity, phaseMask));
1200 } catch(NotPatternException e) {
1201 errorLog.log(annotation.location, "Inline annotation is invalid: this is not a function.");
1204 else if(annotation.id.text.equals("@private")) {
1205 value.addProperty(PrivateProperty.INSTANCE);
1207 else if(annotation.id.text.equals("@deprecated")) {
1211 errorLog.log(annotation.location, "Unknown annotation.");
1214 public void addSupplementedTypeAnnotationsToEnvironment() {
1215 for(SupplementedValueType valueType : supplementedTypeAnnotations) {
1216 Type type = Types.closure(valueType.type);
1217 String name = valueType.name;
1218 SCLValue value = module.getValue(name);
1220 errorLog.log(valueType.position,
1221 name + " is not defined.");
1222 else if(value.getType()==null)
1223 value.setType(type);
1225 errorLog.log(valueType.position,
1226 "Type of "+name+" has already been declared in this module.");
1230 public void addFixityToEnvironment(ArrayList<DFixityAst> fixityAst) {
1231 for(DFixityAst fixity : fixityAst) {
1232 for(EVar symbol : fixity.symbols) {
1233 String name = symbol.name;
1234 SCLValue value = module.getValue(name);
1236 errorLog.log(symbol.location,
1237 name + " is not defined.");
1239 value.setPrecedence(fixity.precedence);
1244 public void addCoverageBranchPoints() {
1245 branchPoints = new THashMap<String, BranchPoint[]>();
1246 BranchPointInjector injector = new BranchPointInjector();
1247 for(String valueName : valueDefinitionsAst.getValueNames()) {
1248 for(DValueAst valueAst : valueDefinitionsAst.getDefinition(valueName))
1249 valueAst.value = injector.injectBranchPoint(valueAst.value);
1250 branchPoints.put(valueName, injector.getAndClearBranchPoints());