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.environment.filter.AcceptAllNamespaceFilter;
import org.simantics.scl.compiler.errors.Locations;
import org.simantics.scl.compiler.internal.parsing.declarations.DValueAst;
+import org.simantics.scl.compiler.module.debug.ModuleDebugInfo;
+import org.simantics.scl.compiler.module.debug.SymbolReference;
import org.simantics.scl.compiler.top.SCLCompilerConfiguration;
import org.simantics.scl.compiler.types.Type;
public static class ExistentialFrame {
THashSet<String> variables = new THashSet<String>(4);
ArrayList<Variable> blanks = new ArrayList<Variable>(2);
- boolean disallowNewExistentials;
+ public boolean disallowNewExistentials;
+
+ public EVariable createBlank(long location) {
+ Variable variable = new Variable("_");
+ blanks.add(variable);
+ EVariable result = new EVariable(variable);
+ result.location = location;
+ return result;
+ }
}
THashMap<String, Variable> variables = new THashMap<String, Variable>();
TIntArrayList chrConstraintFrames = new TIntArrayList();
ArrayList<CHRConstraintEntry> chrConstraintEntries = new ArrayList<CHRConstraintEntry>();
+ public CHRRuleset currentRuleset;
+
+ public ModuleDebugInfo moduleDebugInfo;
+
+ private String definitionName;
+
static class Entry {
String name;
Variable variable;
}
}
- public TranslationContext(CompilationContext compilationContext, LocalEnvironment localEnvironment) {
+ public TranslationContext(CompilationContext compilationContext, LocalEnvironment localEnvironment, String definitionName) {
super(compilationContext);
this.localEnvironment = localEnvironment;
+ this.moduleDebugInfo = compilationContext.moduleDebugInfo;
+ this.definitionName = definitionName;
}
public static boolean isConstructorName(String name) {
int p = name.lastIndexOf('.');
char firstChar = name.charAt(p<0 ? 0 : p+1);
- return Character.isUpperCase(firstChar);
+ return Character.isUpperCase(firstChar) || firstChar == '(';
}
/* Tries to resolve name as a local variable. It is assumed
}
case '_': {
if(name.length()==1) {
- variable = new Variable("_");
ExistentialFrame existentialFrame = getCurrentExistentialFrame();
if(existentialFrame == null || existentialFrame.disallowNewExistentials) {
errorLog.log(location, "Blank variables can be used only in queries.");
return new EError(location);
}
- existentialFrame.blanks.add(variable);
- return new EVariable(variable);
+ return existentialFrame.createBlank(location);
}
break;
}
return null;
}
- private ExistentialFrame getCurrentExistentialFrame() {
+ public ExistentialFrame getCurrentExistentialFrame() {
int size = existentialFrames.size();
if(size == 0)
return null;
return existentialFrames.get(size-1);
}
- private Expression resolveFieldAccess(Expression base, int pos, String name) {
+ private Expression resolveFieldAccess(long location, Expression base, int pos, String name) {
while(pos != -1) {
int p = findSeparator(name, pos+1);
+ int endPos = p==-1 ? name.length() : p;
FieldAccessor accessor = new IdAccessor(
name.charAt(pos),
- name.substring(pos+1, p==-1 ? name.length() : p-1));
+ name.substring(pos+1, endPos));
+ accessor.location = Locations.sublocation(location, pos+1, endPos);
base = new EFieldAccess(base, accessor);
+ base.location = Locations.sublocation(location, 0, endPos);
pos = p;
}
return base;
return -1;
}
+ public SCLValue resolveSCLValue(long location, Namespace namespace, String name) throws AmbiguousNameException {
+ SCLValue value = namespace.getValue(name);
+ if(value == null)
+ return null;
+ String deprecatedDescription = value.isDeprecated();
+ if(deprecatedDescription != null)
+ errorLog.logWarning(location, "Deprecated value " + value.getName().name + "." + (deprecatedDescription.isEmpty() ? "" : " " + deprecatedDescription));
+ if(moduleDebugInfo != null)
+ moduleDebugInfo.symbolReferences.add(new SymbolReference(value.getName(), Name.create(compilationContext.module.getName(), definitionName), location));
+ return value;
+ }
+
public Expression resolveValue(long location, Namespace namespace, String name) {
try {
- SCLValue value = namespace.getValue(name);
+ SCLValue value = resolveSCLValue(location, namespace, name);
if(value == null)
return null;
- String deprecatedDescription = value.isDeprecated();
- if(deprecatedDescription != null)
- errorLog.logWarning(location, "Deprecated value " + value.getName().name + "." + (deprecatedDescription.isEmpty() ? "" : " " + deprecatedDescription));
return new EConstant(location, value);
} catch (AmbiguousNameException e) {
if(SCLCompilerConfiguration.ALLOW_OVERLOADING)
public Expression realize() {
EConstant expression = new EConstant(altValue);
expression.location = location;
+ if(moduleDebugInfo != null)
+ moduleDebugInfo.symbolReferences.add(new SymbolReference(altValue.getName(), Name.create(compilationContext.module.getName(), definitionName), location));
return expression;
}
if(begin == 0) {
Expression result = resolveLocalVariable(location, part);
if(result != null)
- return end == -1 ? result : resolveFieldAccess(result, end, name);
+ return end == -1 ? result : resolveFieldAccess(location, result, end, name);
// FIXME.. support for records
if(localEnvironment != null) {
if(result == null)
result = resolveValue(location, namespace, part);
if(result != null)
- return end == -1 ? result : resolveFieldAccess(result, end, name);
+ return end == -1 ? result : resolveFieldAccess(location, result, end, name);
}
reportResolveFailure(location, namespace, part);
return new EError(location);
}
+ public SCLValue resolveRecordConstructor(long location, String name) throws AmbiguousNameException {
+ return resolveRecordConstructor(location, getEnvironment().getLocalNamespace(), name, 0);
+ }
+
+ public SCLValue resolveRecordConstructor(long location, Namespace namespace, String name, int begin) throws AmbiguousNameException {
+ int end = findSeparator(name, begin);
+ String part = end == -1 ? (begin == 0 ? name : name.substring(begin)) : name.substring(begin, end);
+
+ if(end != -1 && name.charAt(end) == '.') {
+ Namespace childNamespace = namespace.getNamespace(part);
+ if(childNamespace == null)
+ return null;
+ else
+ return resolveRecordConstructor(location, childNamespace, name, end+1);
+ }
+ else
+ return resolveSCLValue(location, namespace, part);
+ }
+
private void reportResolveFailure(long location, Namespace namespace, String name) {
StringBuilder message = new StringBuilder();
message.append("Couldn't resolve ").append(name).append(".");
chrConstraintFrames.add(chrConstraintEntries.size());
}
- public void popCHRConstraintFrame(ArrayList<CHRConstraint> constraints) {
+ public void popCHRConstraintFrame(CHRRuleset ruleset) {
int frame = chrConstraintFrames.removeAt(chrConstraintFrames.size()-1);
int i = chrConstraintEntries.size();
while(i > frame) {
else
newConstraint = chrConstraints.put(entry.name, entry.constraint);
if(newConstraint.implicitlyDeclared)
- constraints.add(newConstraint);
+ ruleset.addConstraint(newConstraint);
}
}
Locations.combine(definitions.get(0).location, definitions.get(definitions.size()-1).location),
cases);
}
-
- public SCLValue getBindFunction() {
- if(bindFunction == null) {
- bindFunction = getEnvironment().getValue(Names.Prelude_bind);
- }
- return bindFunction;
- }
public SCLRelation resolveRelation(long location, String name) {
SCLRelation relation = relations.get(name);