package org.simantics.scl.compiler.elaboration.contexts;
-import gnu.trove.list.array.TIntArrayList;
-import gnu.trove.map.hash.THashMap;
-import gnu.trove.procedure.TObjectProcedure;
-import gnu.trove.set.hash.THashSet;
-
import java.util.ArrayList;
import java.util.Arrays;
import org.simantics.scl.compiler.common.names.Name;
+import org.simantics.scl.compiler.common.names.Names;
import org.simantics.scl.compiler.common.precedence.Associativity;
import org.simantics.scl.compiler.common.precedence.Precedence;
+import org.simantics.scl.compiler.compilation.CompilationContext;
+import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint;
import org.simantics.scl.compiler.elaboration.expressions.Case;
+import org.simantics.scl.compiler.elaboration.expressions.EAmbiguous;
import org.simantics.scl.compiler.elaboration.expressions.EConstant;
import org.simantics.scl.compiler.elaboration.expressions.EEntityTypeAnnotation;
import org.simantics.scl.compiler.elaboration.expressions.EError;
import org.simantics.scl.compiler.elaboration.query.pre.PreQuery;
import org.simantics.scl.compiler.elaboration.relations.SCLRelation;
import org.simantics.scl.compiler.environment.AmbiguousNameException;
-import org.simantics.scl.compiler.environment.Environment;
import org.simantics.scl.compiler.environment.Environments;
import org.simantics.scl.compiler.environment.LocalEnvironment;
import org.simantics.scl.compiler.environment.Namespace;
import org.simantics.scl.compiler.environment.filter.AcceptAllNamespaceFilter;
-import org.simantics.scl.compiler.errors.ErrorLog;
import org.simantics.scl.compiler.errors.Locations;
import org.simantics.scl.compiler.internal.parsing.declarations.DValueAst;
+import org.simantics.scl.compiler.top.SCLCompilerConfiguration;
+import org.simantics.scl.compiler.types.Type;
+
+import gnu.trove.list.array.TIntArrayList;
+import gnu.trove.map.hash.THashMap;
+import gnu.trove.procedure.TObjectProcedure;
+import gnu.trove.set.hash.THashSet;
public class TranslationContext extends TypeTranslationContext implements EnvironmentalContext {
TIntArrayList relationFrames = new TIntArrayList();
ArrayList<RelationEntry> relationEntries = new ArrayList<RelationEntry>();
+ THashMap<String, CHRConstraint> chrConstraints = new THashMap<String, CHRConstraint>();
+ TIntArrayList chrConstraintFrames = new TIntArrayList();
+ ArrayList<CHRConstraintEntry> chrConstraintEntries = new ArrayList<CHRConstraintEntry>();
+
static class Entry {
String name;
Variable variable;
}
}
- public TranslationContext(ErrorLog errorLog,
- Environment environment, LocalEnvironment localEnvironment) {
- super(errorLog, environment);
+ static class CHRConstraintEntry {
+ String name;
+ CHRConstraint constraint;
+ public CHRConstraintEntry(String name, CHRConstraint constraint) {
+ this.name = name;
+ this.constraint = constraint;
+ }
+ }
+
+ public TranslationContext(CompilationContext compilationContext, LocalEnvironment localEnvironment) {
+ super(compilationContext);
this.localEnvironment = localEnvironment;
}
public static boolean isConstructorName(String name) {
- char firstChar = name.charAt(0);
+ int p = name.lastIndexOf('.');
+ char firstChar = name.charAt(p<0 ? 0 : p+1);
return Character.isUpperCase(firstChar);
}
}
private Expression resolveIn(long location, Namespace namespace, String name) {
- SCLValue value = resolveValueIn(location, namespace, name);
+ SCLValue value;
+ try {
+ value = resolveValueIn(location, namespace, name);
+ } catch (AmbiguousNameException e) {
+ if(SCLCompilerConfiguration.ALLOW_OVERLOADING) {
+ EAmbiguous.Alternative[] alternatives = new EAmbiguous.Alternative[e.conflictingModules.length];
+ //System.out.println("Overloading:");
+ for(int i=0;i<e.conflictingModules.length;++i) {
+ Name altName = Name.create(e.conflictingModules[i], e.name);
+ //System.out.println(" " + altName);
+ SCLValue altValue = environment.getValue(altName);
+ alternatives[i] = new EAmbiguous.Alternative() {
+ @Override
+ public Type getType() {
+ return altValue.getType();
+ }
+
+ @Override
+ public Expression realize() {
+ EConstant expression = new EConstant(altValue);
+ expression.location = location;
+ return expression;
+ }
+
+ @Override
+ public String toString() {
+ return altValue.getName().toString().replace('/', '.');
+ }
+ };
+ }
+ EAmbiguous expression = new EAmbiguous(alternatives);
+ expression.location = location;
+ return expression;
+ }
+ else {
+ errorLog.log(location, e.getMessage());
+ value = null;
+ }
+ }
if(value == null)
return new EError(location);
return new EConstant(location, value);
}
}
+ public void pushCHRConstraintFrame() {
+ chrConstraintFrames.add(chrConstraintEntries.size());
+ }
+
+ public void popCHRConstraintFrame(ArrayList<CHRConstraint> constraints) {
+ int frame = chrConstraintFrames.removeAt(chrConstraintFrames.size()-1);
+ int i = chrConstraintEntries.size();
+ while(i > frame) {
+ --i;
+ CHRConstraintEntry entry = chrConstraintEntries.remove(i);
+ CHRConstraint newConstraint;
+ if(entry.constraint == null)
+ newConstraint = chrConstraints.remove(entry.name);
+ else
+ newConstraint = chrConstraints.put(entry.name, entry.constraint);
+ if(newConstraint.implicitlyDeclared)
+ constraints.add(newConstraint);
+ }
+ }
+
public void pushExistentialFrame() {
pushFrame();
existentialFrames.add(new THashSet<String>());
SCLRelation oldRelation = relations.put(name, relation);
relationEntries.add(new RelationEntry(name, oldRelation));
}
+
+ public void newCHRConstraint(String name, CHRConstraint constraint) {
+ CHRConstraint oldConstraint = chrConstraints.put(name, constraint);
+ chrConstraintEntries.add(new CHRConstraintEntry(name, oldConstraint));
+ }
public Precedence getPrecedence(Name op) {
Precedence prec = environment.getValue(op).getPrecedence();
return prec;
}
- private SCLValue resolveValueIn(long location, Namespace namespace, final String name) {
- try {
- SCLValue value = namespace.getValue(name);
- if(value == null) {
- StringBuilder message = new StringBuilder();
- message.append("Couldn't resolve variable ").append(name).append(".");
-
- final THashSet<String> candidateNames = new THashSet<String>(4);
- namespace.findValuesForPrefix("", AcceptAllNamespaceFilter.INSTANCE,
- new TObjectProcedure<SCLValue>() {
- @Override
- public boolean execute(SCLValue value) {
- if(value == null) {
- new Exception().printStackTrace();
- return true;
- }
- String valueName = value.getName().name;
- if(name.equalsIgnoreCase(valueName))
- candidateNames.add(valueName);
- return true;
- }
- });
- if(localEnvironment != null)
- localEnvironment.forNames(new TObjectProcedure<String>() {
- @Override
- public boolean execute(String valueName) {
- if(name.equalsIgnoreCase(valueName))
- candidateNames.add(valueName);
- return true;
- }
- });
-
- if(candidateNames.size() > 0) {
- message.append(" Did you mean ");
- String[] ns = candidateNames.toArray(new String[candidateNames.size()]);
- Arrays.sort(ns);
- for(int i=0;i<ns.length;++i) {
- if(i > 0) {
- message.append(", ");
- if(i == ns.length-1)
- message.append("or ");
- }
- message.append(ns[i]);
+ private SCLValue resolveValueIn(long location, Namespace namespace, final String name) throws AmbiguousNameException {
+ SCLValue value = namespace.getValue(name);
+ if(value == null) {
+ StringBuilder message = new StringBuilder();
+ message.append("Couldn't resolve variable ").append(name).append(".");
+
+ final THashSet<String> candidateNames = new THashSet<String>(4);
+ namespace.findValuesForPrefix("", AcceptAllNamespaceFilter.INSTANCE,
+ new TObjectProcedure<SCLValue>() {
+ @Override
+ public boolean execute(SCLValue value) {
+ if(value == null) {
+ new Exception().printStackTrace();
+ return true;
}
- message.append('?');
+ String valueName = value.getName().name;
+ if(name.equalsIgnoreCase(valueName))
+ candidateNames.add(valueName);
+ return true;
}
-
- errorLog.log(location, message.toString());
- return null;
+ });
+ if(localEnvironment != null)
+ localEnvironment.forNames(new TObjectProcedure<String>() {
+ @Override
+ public boolean execute(String valueName) {
+ if(name.equalsIgnoreCase(valueName))
+ candidateNames.add(valueName);
+ return true;
+ }
+ });
+
+ if(candidateNames.size() > 0) {
+ message.append(" Did you mean ");
+ String[] ns = candidateNames.toArray(new String[candidateNames.size()]);
+ Arrays.sort(ns);
+ for(int i=0;i<ns.length;++i) {
+ if(i > 0) {
+ message.append(", ");
+ if(i == ns.length-1)
+ message.append("or ");
+ }
+ message.append(ns[i]);
+ }
+ message.append('?');
}
- return value;
- } catch (AmbiguousNameException e) {
- errorLog.log(location, e.getMessage());
+
+ errorLog.log(location, message.toString());
return null;
}
+ return value;
}
public Case translateCase(Expression lhs, Expression rhs) {
cases);
}
- private static final Name BIND = Name.create("Prelude", ">>=");
-
public SCLValue getBindFunction() {
if(bindFunction == null) {
- bindFunction = getEnvironment().getValue(BIND);
+ bindFunction = getEnvironment().getValue(Names.Prelude_bind);
}
return bindFunction;
}
return null;
}
}
+
+ public CHRConstraint resolveCHRConstraint(String name) {
+ return chrConstraints.get(name);
+ }
@Override
public SCLValue getValue(Name name) {