import org.simantics.scl.compiler.errors.Locations;
import org.simantics.scl.compiler.internal.codegen.types.JavaTypeTranslator;
import org.simantics.scl.compiler.internal.codegen.utils.JavaNamingPolicy;
+import org.simantics.scl.compiler.internal.header.ModuleHeader;
import org.simantics.scl.compiler.module.ConcreteModule;
import org.simantics.scl.compiler.types.Type;
public JavaTypeTranslator javaTypeTranslator;
public JavaNamingPolicy namingPolicy;
public ConcreteModule module;
+ public ModuleHeader header;
private THashMap<Name, SCLValue> valueCache = new THashMap<Name, SCLValue>();
import org.cojen.classfile.TypeDesc;
import org.simantics.scl.compiler.common.datatypes.Constructor;
import org.simantics.scl.compiler.common.names.Name;
+import org.simantics.scl.compiler.constants.Constant;
import org.simantics.scl.compiler.constants.JavaTypeInstanceConstructor;
import org.simantics.scl.compiler.constants.SCLConstructor;
import org.simantics.scl.compiler.constants.StringConstant;
import org.simantics.scl.compiler.constants.generic.ClassRef;
import org.simantics.scl.compiler.constants.generic.ConvertToListFilter;
import org.simantics.scl.compiler.constants.generic.MethodRef;
+import org.simantics.scl.compiler.constants.generic.MethodRef.FieldRef;
import org.simantics.scl.compiler.constants.generic.OutputFilter;
import org.simantics.scl.compiler.constants.generic.ParameterStackItem;
import org.simantics.scl.compiler.constants.generic.Pop2OutputFilter;
import org.simantics.scl.compiler.constants.generic.PopOutputFilter;
import org.simantics.scl.compiler.constants.generic.StackItem;
import org.simantics.scl.compiler.constants.generic.ThreadLocalStackItem;
+import org.simantics.scl.compiler.constants.singletons.SafeCoerce;
import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
import org.simantics.scl.compiler.elaboration.contexts.TypeTranslationContext;
import org.simantics.scl.compiler.elaboration.errors.NotPatternException;
}
public void processDataTypes(ArrayList<DDataAst> dataTypesAst) {
+ ArrayList<Runnable> fieldAccessorGenerators = new ArrayList<Runnable>();
for(DDataAst dataTypeAst : dataTypesAst) {
TypeTranslationContext context = createTypeTranslationContext();
TVar[] typeParameters = new TVar[dataTypeAst.parameters.length];
constructors[j].fieldNames = fieldNames;
constructors[j].recordFieldNames = constructor.fieldNames;
}
+ if(constructors.length == 1) {
+ Constructor constructor = constructors[0];
+ if(constructor.recordFieldNames != null) {
+ fieldAccessorGenerators.add(new Runnable() {
+ @Override
+ public void run() {
+ Type in = Types.apply(dataType.name, dataType.parameters);
+ for(int i=0;i<constructor.recordFieldNames.length;++i) {
+ Type out = constructor.parameterTypes[i];
+ Constant accessor;
+ if(trivialDataType)
+ accessor = new SafeCoerce(dataType.parameters, in, out);
+ else
+ accessor = new CallJava(dataType.parameters, Types.NO_EFFECTS, out,
+ new Type[] {in}, new StackItem[] {new ParameterStackItem(0, in)},
+ new FieldRef(constructor.javaName, constructor.fieldNames != null ? constructor.fieldNames[i] : "c" + i,
+ javaTypeTranslator.toTypeDesc(out)),
+ null);
+ module.addFieldAccessor(constructor.recordFieldNames[i], accessor);
+ }
+ }
+ });
+ }
+ }
}
+
+ for(Runnable fieldAccessorGenerator : fieldAccessorGenerators)
+ fieldAccessorGenerator.run();
}
public void processTypeClasses(ArrayList<ProcessedDClassAst> typeClassesAst) {
import java.util.ArrayList;
import java.util.Collection;
+import java.util.List;
import org.simantics.scl.compiler.common.names.Name;
+import org.simantics.scl.compiler.constants.Constant;
import org.simantics.scl.compiler.elaboration.modules.SCLValue;
import org.simantics.scl.compiler.elaboration.modules.TypeClass;
import org.simantics.scl.compiler.elaboration.modules.TypeClassInstance;
else
return base.getValue(name);
}
+
+ @Override
+ public List<Constant> getFieldAccessors(String name) {
+ List<Constant> r1 = base.getFieldAccessors(name);
+ List<Constant> r2 = module.getFieldAccessors(name);
+ if(r1 == null)
+ return r2;
+ if(r2 == null)
+ return r1;
+ ArrayList<Constant> result = new ArrayList<Constant>(r1.size() + r2.size());
+ result.addAll(r1);
+ result.addAll(r2);
+ return result;
+ }
+
@Override
public SCLRelation getRelation(Name name) {
if(name.module.equals(module.getName()))
import org.simantics.scl.compiler.elaboration.modules.SCLValue;
import org.simantics.scl.compiler.elaboration.modules.TypeClass;
-import org.simantics.scl.compiler.elaboration.modules.TypeConstructor;
import org.simantics.scl.compiler.elaboration.modules.TypeDescriptor;
import org.simantics.scl.compiler.elaboration.relations.SCLEntityType;
import org.simantics.scl.compiler.elaboration.relations.SCLRelation;
return base.getValue(name);
}
}
-
+
@Override
public SCLRelation getRelation(String name) throws AmbiguousNameException {
SCLRelation relation = module.getRelation(name);
import org.simantics.scl.compiler.environment.EnvironmentFactory;
import org.simantics.scl.compiler.errors.ErrorLog;
-import org.simantics.scl.compiler.internal.codegen.types.JavaReferenceValidator;
import org.simantics.scl.compiler.internal.codegen.types.JavaReferenceValidatorFactory;
import org.simantics.scl.compiler.internal.header.ModuleHeader;
import org.simantics.scl.compiler.internal.parsing.declarations.DeclarationAst;
String moduleName) {
try {
if(hasErrors()) return;
+ compilationContext.header = ModuleHeader.process(compilationContext.errorLog, declarations.moduleHeader);
Elaboration elaboration = new Elaboration(compilationContext,
timer,
localEnvironmentFactory,
moduleName,
- ModuleHeader.process(compilationContext.errorLog, declarations.moduleHeader),
+ compilationContext.header,
declarations.importsAst,
jrvFactory,
declarations.valueDefinitionsAst,
--- /dev/null
+package org.simantics.scl.compiler.constants.singletons;
+
+import org.simantics.scl.compiler.constants.FunctionValue;
+import org.simantics.scl.compiler.internal.codegen.references.Val;
+import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder;
+import org.simantics.scl.compiler.types.TVar;
+import org.simantics.scl.compiler.types.Type;
+import org.simantics.scl.compiler.types.Types;
+
+public class SafeCoerce extends FunctionValue {
+ public SafeCoerce(TVar[] vars, Type in, Type out) {
+ super(vars, Types.NO_EFFECTS, out, in);
+ }
+
+ @Override
+ public Type applyExact(MethodBuilder mb, Val[] parameters) {
+ parameters[0].push(mb);
+ return getReturnType();
+ }
+
+ @Override
+ public String toString() {
+ return "safeCoerce";
+ }
+}
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.expressions.EFieldAccess;
import org.simantics.scl.compiler.elaboration.expressions.ELambda;
ArrayList<ArrayList<Variable>> blanksInExistentialFrame = new ArrayList<ArrayList<Variable>>();
SCLValue bindFunction;
- public EEntityTypeAnnotation currentEntityTypeAnnotation;
public PreQuery currentPreQuery;
THashMap<String, SCLRelation> relations = new THashMap<String, SCLRelation>();
return new EVariable(variable);
}
break;
- case '#':
- if(name.length() > 1 && Character.isLetter(name.charAt(1))) {
- if(currentEntityTypeAnnotation == null) {
- errorLog.log(location, "Attribute references cannot be made in this context.");
- return new EError(location);
- }
- return currentEntityTypeAnnotation.resolveAttribute(this, location, name.substring(1));
- }
- break;
}
return null;
}
- private FieldAccessor createFieldAccessor(char accessSeparator, String name) {
- IdAccessor accessor = new IdAccessor(name);
- accessor.accessSeparator = accessSeparator;
- return accessor;
- }
-
private Expression resolveFieldAccess(Expression base, int pos, String name) {
- ArrayList<FieldAccessor> accessors = new ArrayList<FieldAccessor>(2);
while(pos != -1) {
int p = findSeparator(name, pos+1);
- accessors.add(createFieldAccessor(
+ FieldAccessor accessor = new IdAccessor(
name.charAt(pos),
- name.substring(pos+1, p==-1 ? name.length() : p-1)));
+ name.substring(pos+1, p==-1 ? name.length() : p-1));
+ base = new EFieldAccess(base, accessor);
pos = p;
}
- return new EFieldAccess(base,
- accessors.toArray(new FieldAccessor[accessors.size()]));
+ return base;
}
- private Expression resolveIn(long location, Namespace namespace, String 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;
- }
+ private static int findSeparator(String name, int fromIndex) {
+ ++fromIndex; // the first character (that can be #) is never a separator
+ while(fromIndex < name.length()) {
+ char c = name.charAt(fromIndex);
+ if(c == '.' || c == '#')
+ return fromIndex;
+ ++fromIndex;
}
- if(value == null)
- return new EError(location);
- String deprecatedDescription = value.isDeprecated();
- if(deprecatedDescription != null)
- errorLog.logWarning(location, "Deprecated value " + value.getName().name + "." + (deprecatedDescription.isEmpty() ? "" : " " + deprecatedDescription));
- return new EConstant(location, value);
+ return -1;
}
- private Expression resolveComplexNameIn(long location, Namespace namespace, int startPos, String name) {
- int pos = name.length();
- {
- int hashPos = name.lastIndexOf('#');
- if(hashPos >= 0)
- pos = hashPos;
- }
- while(pos > startPos) {
- SCLValue value;
- try {
- value = namespace.getValue(name.substring(startPos, pos));
- } catch (AmbiguousNameException e) {
+ public Expression resolveValue(long location, Namespace namespace, String name) {
+ try {
+ 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));
+ return new EConstant(location, value);
+ } catch (AmbiguousNameException e) {
+ if(SCLCompilerConfiguration.ALLOW_OVERLOADING)
+ return resolveAmbigious(location, e.conflictingModules, name);
+ else {
errorLog.log(location, e.getMessage());
return new EError(location);
}
- if(value != null) {
- Expression result = new EConstant(location, value);
- if(pos < name.length())
- result = resolveFieldAccess(result, pos, name);
- return result;
- }
- pos = name.lastIndexOf('.', pos-1);
}
- errorLog.log(location, "Couldn't resolve variable " + name + ".");
- return new EError(location);
}
- private static int findSeparator(String name, int fromIndex) {
- while(fromIndex < name.length()) {
- char c = name.charAt(fromIndex);
- if(c == '.' || c == '#')
- return fromIndex;
- ++fromIndex;
+ private Expression resolveAmbigious(long location, String[] conflictingModules, String name) {
+ EAmbiguous.Alternative[] alternatives = new EAmbiguous.Alternative[conflictingModules.length];
+ for(int i=0;i<conflictingModules.length;++i) {
+ Name altName = Name.create(conflictingModules[i], name);
+ 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('/', '.');
+ }
+ };
}
- return -1;
+ EAmbiguous expression = new EAmbiguous(alternatives);
+ expression.location = location;
+ return expression;
}
- public Expression resolveExpression(long location, String name) {
- int p = findSeparator(name, 1 /* Initial # is not a separator */);
- if(p == -1) {
- Expression result = resolveLocalVariable(location, name);
+ public Expression resolveVariable(long location, Namespace namespace, String name, int begin) {
+ int end = findSeparator(name, begin);
+ String part = end == -1 ? (begin == 0 ? name : name.substring(begin)) : name.substring(begin, end);
+
+ if(begin == 0) {
+ Expression result = resolveLocalVariable(location, part);
if(result != null)
- return result;
+ return end == -1 ? result : resolveFieldAccess(result, end, name);
+ // FIXME.. support for records
if(localEnvironment != null) {
result = localEnvironment.resolve(environment, name);
if(result != null) {
return result;
}
}
-
- return resolveIn(location, environment.getLocalNamespace(), name);
}
- else {
- if(localEnvironment != null) {
- Expression result = localEnvironment.resolve(environment, name);
- if(result != null) {
- result.setLocationDeep(location);
- return result;
+ if(end != -1 && name.charAt(end) == '.') {
+ Namespace childNamespace = namespace.getNamespace(part);
+ if(childNamespace != null)
+ return resolveVariable(location, childNamespace, name, end+1);
+ }
+ {
+ Expression result = null;
+ if(end != -1) {
+ for(int end2 = name.length();end2 > end;end2 = name.lastIndexOf('.', end2-1)) {
+ part = name.substring(begin, end2);
+ result = resolveValue(location, namespace, part);
+ if(result != null) {
+ end = end2 == name.length() ? -1 : end2;
+ break;
+ }
}
}
-
- String prefix = name.substring(0, p);
- Expression result = resolveLocalVariable(location, prefix);
+ if(result == null)
+ result = resolveValue(location, namespace, part);
if(result != null)
- return resolveFieldAccess(result, p, name);
-
- Namespace namespace = environment.getLocalNamespace();
- int pos = 0;
- while(name.charAt(p)=='.') {
- Namespace temp = namespace.getNamespace(prefix);
- if(temp == null)
- break;
- namespace = temp;
- pos = p+1;
- p = findSeparator(name, pos);
- if(p < 0)
- return resolveIn(location, namespace, name.substring(pos));
- prefix = name.substring(pos, p);
+ return end == -1 ? result : resolveFieldAccess(result, end, name);
+ }
+ reportResolveFailure(location, namespace, part);
+ return new EError(location);
+ }
+
+ private void reportResolveFailure(long location, Namespace namespace, String name) {
+ StringBuilder message = new StringBuilder();
+ message.append("Couldn't resolve ").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;
}
-
- return resolveComplexNameIn(location, namespace, pos, name);
+ });
+ 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('?');
}
+
+ errorLog.log(location, message.toString());
+ }
+
+ public Expression resolveVariable(long location, String name) {
+ return resolveVariable(location, environment.getLocalNamespace(), name, 0);
}
public Expression resolvePattern(EVar name) {
return new EVariable(name.location, newVariable(name.name));
}
else
- return resolveExpression(name.location, name.name);
+ return resolveVariable(name.location, name.name);
}
/**
else
return prec;
}
-
- 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;
- }
- 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]);
- }
- message.append('?');
- }
-
- errorLog.log(location, message.toString());
- return null;
- }
- return value;
- }
public Case translateCase(Expression lhs, Expression rhs) {
ArrayList<Expression> parameters = new ArrayList<Expression>(4);
output.add(left);
for(EBinaryRightSide right : rights) {
// Read op
- Expression op = context.resolveExpression(right.operator.location, right.operator.name);
+ Expression op = context.resolveVariable(right.operator.location, right.operator.name);
if(op == null)
return new EError(location);
Precedence opPrec = op.getPrecedence();
+++ /dev/null
-package org.simantics.scl.compiler.elaboration.expressions;
-
-import static org.simantics.scl.compiler.elaboration.expressions.Expressions.loc;
-
-import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
-import org.simantics.scl.compiler.elaboration.java.EqRelation;
-import org.simantics.scl.compiler.elaboration.query.QAtom;
-import org.simantics.scl.compiler.elaboration.query.Query;
-import org.simantics.scl.compiler.elaboration.relations.SCLEntityType;
-import org.simantics.scl.compiler.elaboration.relations.SCLEntityType.Attribute;
-import org.simantics.scl.compiler.elaboration.relations.SCLEntityType.AttributeBinding;
-import org.simantics.scl.compiler.environment.AmbiguousNameException;
-import org.simantics.scl.compiler.environment.Environments;
-import org.simantics.scl.compiler.errors.Locations;
-import org.simantics.scl.compiler.internal.parsing.Token;
-
-import gnu.trove.map.hash.THashMap;
-
-public class EEntityTypeAnnotation extends ASTExpression {
-
- Expression expression;
- Token entityTypeName;
- SCLEntityType entityType;
- Query query; // optional
- THashMap<String, AttributeBinding> attributeBindingMap;
-
- public EEntityTypeAnnotation(Expression expression, Token entityTypeName,
- Query query) {
- this.expression = expression;
- this.entityTypeName = entityTypeName;
- this.query = query;
- }
-
- @Override
- public Expression resolve(TranslationContext context) {
- // Resolve a subexpression
- expression = expression.resolve(context);
-
- // Check that we are inside a query
- if(context.currentPreQuery == null) {
- context.getErrorLog().log(location, "Entity type annotations can be used only in queries.");
- return new EError(location);
- }
-
- // Resolve entity type
- try {
- entityType = Environments.getEntityType(context.getEnvironment(), entityTypeName.text);
- } catch (AmbiguousNameException e) {
- context.getErrorLog().log(location, e.getMessage());
- return new EError(location);
- }
- if(entityType == null) {
- context.getErrorLog().log(location, "Couldn't resolve entity type " + entityTypeName.text + ".");
- return new EError(location);
- }
-
- // Rewrite the subexpression as a separate query if it is not a variable
- Variable base;
- if(expression instanceof EVariable)
- base = ((EVariable)expression).variable;
- else {
- base = new Variable("?" + entityTypeName.text);
- context.currentPreQuery.extraVariables.add(base);
- context.currentPreQuery.sideQueries.add(loc(expression.location,
- new QAtom(EqRelation.INSTANCE, new EVariable(base), expression)));
- expression = loc(expression.location, new EVariable(base));
- }
-
- // Resolve a related query if it exists
- if(query != null) {
- EEntityTypeAnnotation oldEntityTypeAnnotation = context.currentEntityTypeAnnotation;
- attributeBindingMap = new THashMap<String, AttributeBinding>();
- context.currentEntityTypeAnnotation = this;
- query = query.resolve(context);
- context.currentPreQuery.sideQueries.add(query);
- context.currentEntityTypeAnnotation = oldEntityTypeAnnotation;
- AttributeBinding[] attributeBindings;
- if(attributeBindingMap.isEmpty())
- attributeBindings = AttributeBinding.EMPTY_ARRAY;
- else {
- attributeBindings = attributeBindingMap.values().toArray(new AttributeBinding[attributeBindingMap.size()]);
- for(AttributeBinding binding : attributeBindings)
- context.currentPreQuery.extraVariables.add(binding.variable);
- }
- context.currentPreQuery.sideQueries.add(entityType.generateQuery(context, base, attributeBindings));
- }
- else
- context.currentPreQuery.sideQueries.add(entityType.generateQuery(context, base, AttributeBinding.EMPTY_ARRAY));
- return expression;
- }
-
- @Override
- public void setLocationDeep(long loc) {
- if(location == Locations.NO_LOCATION) {
- location = loc;
- expression.setLocationDeep(loc);
- query.setLocationDeep(loc);
- }
- }
-
- public Expression resolveAttribute(TranslationContext context, long location, String name) {
- AttributeBinding binding = attributeBindingMap.get(name);
- if(binding == null) {
- Attribute attribute = entityType.getAttribute(name);
- if(attribute == null) {
- context.getErrorLog().log(location, "Attribute " + name + " is not defined in entity type " + entityTypeName.text + ".");
- return new EError(location);
- }
- binding = new AttributeBinding(attribute, new Variable("#"+name));
- attributeBindingMap.put(name, binding);
- }
- return new EVariable(binding.variable);
- }
-
- @Override
- public Expression accept(ExpressionTransformer transformer) {
- return transformer.transform(this);
- }
-
-}
package org.simantics.scl.compiler.elaboration.expressions;
+import java.util.List;
+
import org.simantics.scl.compiler.common.names.Names;
+import org.simantics.scl.compiler.constants.Constant;
import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;
import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
+import org.simantics.scl.compiler.elaboration.expressions.EAmbiguous.Alternative;
import org.simantics.scl.compiler.elaboration.expressions.accessor.FieldAccessor;
+import org.simantics.scl.compiler.elaboration.expressions.accessor.IdAccessor;
import org.simantics.scl.compiler.errors.Locations;
import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
+import org.simantics.scl.compiler.internal.header.ModuleHeader;
import org.simantics.scl.compiler.types.Type;
import org.simantics.scl.compiler.types.Types;
import org.simantics.scl.compiler.types.exceptions.MatchException;
private static final Type VARIABLE = Types.con("Simantics/Variables", "Variable");
Expression parent;
- FieldAccessor[] accessors;
+ FieldAccessor accessor;
+ boolean lastAccessor = true;
- public EFieldAccess(Expression parent, FieldAccessor[] accessors) {
- if(parent instanceof EFieldAccess) {
- EFieldAccess parentAccess = (EFieldAccess)parent;
- parent = parentAccess.parent;
- accessors = concat(parentAccess.accessors, accessors);
- }
+ public EFieldAccess(Expression parent, FieldAccessor accessor) {
this.parent = parent;
- this.accessors = accessors;
+ this.accessor = accessor;
+ if(parent instanceof EFieldAccess)
+ ((EFieldAccess)parent).lastAccessor = false;
}
@Override
public void collectRefs(TObjectIntHashMap<Object> allRefs,
TIntHashSet refs) {
parent.collectRefs(allRefs, refs);
- for(FieldAccessor accessor : accessors)
- accessor.collectRefs(allRefs, refs);
+ accessor.collectRefs(allRefs, refs);
}
@Override
public void collectVars(TObjectIntHashMap<Variable> allVars,
TIntHashSet vars) {
parent.collectVars(allVars, vars);
- for(FieldAccessor accessor : accessors)
- accessor.collectVars(allVars, vars);
+ accessor.collectVars(allVars, vars);
}
private boolean returnsValue() {
- FieldAccessor lastAccessor = accessors[accessors.length-1];
- return lastAccessor.accessSeparator=='#' && !lastAccessor.isVariableId();
+ return accessor.accessSeparator == '#' && !accessor.isVariableId();
}
@Override
// Type is already updated in checkBasicType
}
+ private Expression resolveAccessor(TypingContext context, Type requiredType) {
+ if(!(accessor instanceof IdAccessor))
+ return null;
+ IdAccessor idAccessor = (IdAccessor)accessor;
+ if(idAccessor.accessSeparator != '.')
+ return null;
+ List<Constant> accessors = context.getEnvironment().getFieldAccessors(idAccessor.fieldName);
+ if(accessors == null) {
+ context.getErrorLog().log("Couldn't resolve accessor ." + idAccessor.fieldName + ".");
+ return new EError(location);
+ }
+ Expression accessorExpression;
+ if(accessors.size() == 1)
+ accessorExpression = new ELiteral(accessors.get(0));
+ else {
+ Alternative[] alternatives = new Alternative[accessors.size()];
+ for(int i=0;i<alternatives.length;++i) {
+ final int index = i;
+ alternatives[i] = new Alternative() {
+ @Override
+ public Expression realize() {
+ return new ELiteral(accessors.get(index));
+ }
+ @Override
+ public Type getType() {
+ return accessors.get(index).getType();
+ }
+ };
+ }
+ accessorExpression = new EAmbiguous(alternatives);
+ }
+ return new EApply(location, accessorExpression, parent).checkType(context, requiredType);
+ }
+
@Override
public Expression checkBasicType(TypingContext context, Type requiredType) {
+ ModuleHeader header = context.getCompilationContext().header;
+ if(header != null && header.fields) {
+ Expression expression = resolveAccessor(context, requiredType);
+ if(expression != null)
+ return expression;
+ }
+
+ // Default case
if(returnsValue())
setType(requiredType);
else {
context.subsume(this, requiredType);
}
parent = parent.checkType(context, VARIABLE);
- for(FieldAccessor accessor : accessors)
- accessor.checkType(context);
+ accessor.checkType(context);
context.declareEffect(getLocation(), Types.READ_GRAPH);
return this;
}
@Override
public void collectFreeVariables(THashSet<Variable> vars) {
parent.collectFreeVariables(vars);
- for(FieldAccessor accessor : accessors)
- accessor.collectFreeVariables(vars);
+ accessor.collectFreeVariables(vars);
}
@Override
public Expression simplify(SimplificationContext context) {
// Simplify subexpressions
parent = parent.simplify(context);
- for(FieldAccessor accessor : accessors)
- accessor.simplify(context);
+ accessor.simplify(context);
- // ...
- Expression result = parent;
- for(int i=0;i<accessors.length;++i) {
- FieldAccessor accessor = accessors[i];
- if(accessor.accessSeparator == '.')
- result = new EApply(
- getLocation(),
- Types.READ_GRAPH,
- context.getConstant(Names.Simantics_Variables_child_),
- result,
- accessor.asExpression()
- );
- else if(i < accessors.length-1)
- result = new EApply(
- getLocation(),
- Types.READ_GRAPH,
- context.getConstant(Names.Simantics_Variables_property),
- result,
- accessor.asExpression()
- );
- else if(accessor.isVariableId())
- ;
- else
- result = new EApply(
- getLocation(),
- Types.READ_GRAPH,
- context.getConstant(Names.Simantics_Variables_untypedPropertyValue, getType()),
- result,
- accessor.asExpression()
- );
- }
- return result;
- }
-
- private static FieldAccessor[] concat(FieldAccessor[] accessors1,
- FieldAccessor[] accessors2) {
- FieldAccessor[] result = new FieldAccessor[accessors1.length + accessors2.length];
- System.arraycopy(accessors1, 0, result, 0, accessors1.length);
- System.arraycopy(accessors2, 0, result, accessors1.length, accessors2.length);
- return result;
+ if(accessor.accessSeparator == '.')
+ return new EApply(
+ getLocation(),
+ Types.READ_GRAPH,
+ context.getConstant(Names.Simantics_Variables_child_),
+ parent,
+ accessor.asExpression()
+ );
+ else if(!lastAccessor)
+ return new EApply(
+ getLocation(),
+ Types.READ_GRAPH,
+ context.getConstant(Names.Simantics_Variables_property),
+ parent,
+ accessor.asExpression()
+ );
+ else if(accessor.isVariableId())
+ return parent;
+ else
+ return new EApply(
+ getLocation(),
+ Types.READ_GRAPH,
+ context.getConstant(Names.Simantics_Variables_untypedPropertyValue, getType()),
+ parent,
+ accessor.asExpression()
+ );
}
@Override
public Expression resolve(TranslationContext context) {
parent = parent.resolve(context);
- for(FieldAccessor accessor : accessors)
- accessor.resolve(context);
+ accessor.resolve(context);
return this;
}
if(location == Locations.NO_LOCATION) {
location = loc;
parent.setLocationDeep(loc);
- for(FieldAccessor accessor : accessors)
- accessor.setLocationDeep(loc);
+ accessor.setLocationDeep(loc);
}
}
@Override
public void forVariables(VariableProcedure procedure) {
parent.forVariables(procedure);
- for(FieldAccessor accessor : accessors)
- accessor.forVariables(procedure);
+ accessor.forVariables(procedure);
}
@Override
@Override
public Expression resolve(TranslationContext context) {
- return context.resolveExpression(location, name);
+ return context.resolveVariable(location, name);
}
@Override
Expression transform(EConstant expression);
Expression transform(ECoveringBranchPoint expression);
Expression transform(EEnforce expression);
- Expression transform(EEntityTypeAnnotation expression);
Expression transform(EEquations expression);
Expression transform(EError expression);
Expression transform(EExternalConstant expression);
import org.simantics.scl.compiler.elaboration.equation.Equation;
import org.simantics.scl.compiler.elaboration.equation.EquationVisitor;
import org.simantics.scl.compiler.elaboration.expressions.accessor.ExpressionAccessor;
-import org.simantics.scl.compiler.elaboration.expressions.accessor.FieldAccessor;
import org.simantics.scl.compiler.elaboration.expressions.block.BindStatement;
import org.simantics.scl.compiler.elaboration.expressions.block.GuardStatement;
import org.simantics.scl.compiler.elaboration.expressions.block.LetStatement;
return expression;
}
- @Override
- public Expression transform(EEntityTypeAnnotation expression) {
- expression.expression = expression.expression.accept(this);
- if(expression.query != null)
- expression.query = expression.query.accept(this);
- return expression;
- }
-
@Override
public Expression transform(EError expression) {
return expression;
@Override
public Expression transform(EFieldAccess expression) {
expression.parent = expression.parent.accept(this);
- for(FieldAccessor accessor : expression.accessors)
- if(accessor instanceof ExpressionAccessor) {
- ExpressionAccessor expAcc = (ExpressionAccessor)accessor;
- expAcc.fieldName = expAcc.fieldName.accept(this);
- }
+ if(expression.accessor instanceof ExpressionAccessor) {
+ ExpressionAccessor expAcc = (ExpressionAccessor)expression.accessor;
+ expAcc.fieldName = expAcc.fieldName.accept(this);
+ }
return expression;
}
import org.simantics.scl.compiler.elaboration.equation.EquationVisitor;
import org.simantics.scl.compiler.elaboration.expressions.ERuleset.DatalogRule;
import org.simantics.scl.compiler.elaboration.expressions.accessor.ExpressionAccessor;
-import org.simantics.scl.compiler.elaboration.expressions.accessor.FieldAccessor;
import org.simantics.scl.compiler.elaboration.expressions.accessor.FieldAccessorVisitor;
import org.simantics.scl.compiler.elaboration.expressions.accessor.IdAccessor;
import org.simantics.scl.compiler.elaboration.expressions.accessor.StringAccessor;
@Override
public void visit(EFieldAccess expression) {
expression.parent.accept(this);
- for(FieldAccessor accessor : expression.accessors)
- accessor.accept(this);
+ expression.accessor.accept(this);
}
@Override
public class ExpressionAccessor extends FieldAccessor {
public Expression fieldName;
- public ExpressionAccessor(Expression fieldName) {
+ public ExpressionAccessor(char accessSeparator, Expression fieldName) {
+ super(accessSeparator);
this.fieldName = fieldName;
}
public abstract class FieldAccessor extends Symbol {
public char accessSeparator;
+
+ public FieldAccessor(char accessSeparator) {
+ this.accessSeparator = accessSeparator;
+ }
public void collectRefs(TObjectIntHashMap<Object> allRefs,
TIntHashSet refs) {
public class IdAccessor extends FieldAccessor {
public final String fieldName;
- public IdAccessor(String fieldName) {
+ public IdAccessor(char accessSeparator, String fieldName) {
+ super(accessSeparator);
this.fieldName = fieldName;
}
public class StringAccessor extends FieldAccessor {
public final String fieldName;
- public StringAccessor(String fieldName) {
+ public StringAccessor(char accessSeparator, String fieldName) {
+ super(accessSeparator);
this.fieldName = fieldName;
}
import java.util.Arrays;
-import org.simantics.scl.compiler.constants.BooleanConstant;
import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
import org.simantics.scl.compiler.elaboration.expressions.EApply;
-import org.simantics.scl.compiler.elaboration.expressions.EEntityTypeAnnotation;
-import org.simantics.scl.compiler.elaboration.expressions.ELiteral;
-import org.simantics.scl.compiler.elaboration.expressions.ESimpleLet;
import org.simantics.scl.compiler.elaboration.expressions.EVar;
import org.simantics.scl.compiler.elaboration.expressions.Expression;
import org.simantics.scl.compiler.elaboration.expressions.QueryTransformer;
-import org.simantics.scl.compiler.elaboration.expressions.Variable;
import org.simantics.scl.compiler.elaboration.java.CheckRelation;
import org.simantics.scl.compiler.elaboration.query.QAtom;
import org.simantics.scl.compiler.elaboration.query.QMapping;
if(query != null)
return query;
}
- else if(expression instanceof EEntityTypeAnnotation) {
- expression = new ESimpleLet(new Variable("_"), expression, new ELiteral(new BooleanConstant(true)));
- }
return new QAtom(CheckRelation.INSTANCE,
new Expression[] { expression.resolve(context) });
}
package org.simantics.scl.compiler.environment;
+import java.util.ArrayList;
import java.util.Collection;
+import java.util.List;
+import org.simantics.scl.compiler.constants.Constant;
import org.simantics.scl.compiler.elaboration.rules.TransformationRule;
import org.simantics.scl.compiler.module.Module;
this.localNamespace = localNamespace;
}
+ @Override
+ public List<Constant> getFieldAccessors(String name) {
+ List<Constant> result = null;
+ boolean resultIsImmutable = true;
+ for(Module module : moduleMap.values()) {
+ List<Constant> accessors = module.getFieldAccessors(name);
+ if(accessors != null) {
+ if(result == null)
+ result = accessors;
+ else if(resultIsImmutable) {
+ result = new ArrayList<Constant>(result.size() + accessors.size());
+ result.addAll(accessors);
+ resultIsImmutable = false;
+ }
+ else
+ result.addAll(accessors);
+ }
+ }
+ return result;
+ }
+
@Override
public Namespace getLocalNamespace() {
return localNamespace;
package org.simantics.scl.compiler.environment;
import java.util.Collection;
+import java.util.List;
import org.simantics.scl.compiler.common.names.Name;
+import org.simantics.scl.compiler.constants.Constant;
import org.simantics.scl.compiler.elaboration.contexts.EnvironmentalContext;
import org.simantics.scl.compiler.elaboration.modules.SCLValue;
import org.simantics.scl.compiler.elaboration.modules.TypeClass;
Namespace getLocalNamespace();
SCLValue getValue(Name name);
+ List<Constant> getFieldAccessors(String name);
SCLRelation getRelation(Name name);
SCLEntityType getEntityType(Name name);
TypeDescriptor getTypeDescriptor(TCon type);
package org.simantics.scl.compiler.environment;
+import java.util.List;
import java.util.function.Consumer;
+import org.simantics.scl.compiler.constants.Constant;
import org.simantics.scl.compiler.elaboration.modules.SCLValue;
import org.simantics.scl.compiler.elaboration.modules.TypeClass;
import org.simantics.scl.compiler.elaboration.modules.TypeDescriptor;
package org.simantics.scl.compiler.environment;
import java.util.ArrayList;
+import java.util.List;
import java.util.function.Consumer;
+import org.simantics.scl.compiler.constants.Constant;
import org.simantics.scl.compiler.elaboration.modules.SCLValue;
import org.simantics.scl.compiler.elaboration.modules.TypeClass;
import org.simantics.scl.compiler.elaboration.modules.TypeDescriptor;
throw new AmbiguousNameException(conflictingModules, name);
return result;
}
-
+
@Override
public SCLRelation getRelation(String name) throws AmbiguousNameException {
SCLRelation result = null, temp;
import org.simantics.scl.compiler.elaboration.expressions.EConstant;
import org.simantics.scl.compiler.elaboration.expressions.ECoveringBranchPoint;
import org.simantics.scl.compiler.elaboration.expressions.EEnforce;
-import org.simantics.scl.compiler.elaboration.expressions.EEntityTypeAnnotation;
import org.simantics.scl.compiler.elaboration.expressions.EError;
import org.simantics.scl.compiler.elaboration.expressions.EExternalConstant;
import org.simantics.scl.compiler.elaboration.expressions.EFieldAccess;
return super.transform(expression);
}
- @Override
- public Expression transform(EEntityTypeAnnotation expression) {
- ++codeCounter;
- return super.transform(expression);
- }
-
@Override
public Expression transform(EError expression) {
++codeCounter;
public String classLoader;
public long classLoaderLocation;
public String defaultLocalName;
+ public boolean fields;
private void read(ErrorLog errorLog, DModuleHeader header) {
for(FieldAssignment assignment : header.fields)
errorLog.log(assignment.value.location, "Expected string here.");
}
break;
+ case "fields":
+ this.fields = true;
+ break;
default:
errorLog.logWarning(assignment.location, "Unknown module header field was skipped.");
}
*/
exp = bexp (HASTYPE type)? # LocalTypeAnnotation, shift HASTYPE, shift COLON
- | bexp COLON ID WITH? queryBlock? # EntityTypeAnnotation, shift LBRACE, shift WITH
;
bexp
public static final boolean TRACE = false;
private static final int INITIAL_CAPACITY = 16;
- private static final int STATE_COUNT = 349;
+ private static final int STATE_COUNT = 345;
private static final int TERMINAL_COUNT = 83;
private static final int NONTERMINAL_COUNT = 51;
- private static final int PRODUCT_COUNT = 133;
+ private static final int PRODUCT_COUNT = 132;
private static final int[] ACTION_ROW_ID = new int[STATE_COUNT];
private static final int[] ACTION_COLUMN_ID = new int[TERMINAL_COUNT];
- private static final short[] ACTION_TABLE = new short[6396];
- private static final int[] ERROR_TABLE = new int[906];
+ private static final short[] ACTION_TABLE = new short[6360];
+ private static final int[] ERROR_TABLE = new int[895];
private static final int[] GOTO_ROW_ID = new int[STATE_COUNT];
private static final int[] GOTO_COLUMN_ID = new int[NONTERMINAL_COUNT];
- private static final short[] GOTO_TABLE = new short[1652];
+ private static final short[] GOTO_TABLE = new short[1711];
private static final int[] PRODUCT_LHS = new int[PRODUCT_COUNT];
private static final short STATE_MASK = (short)0x0fff;
"HIDING",
"ARROW",
"COLON",
- "WITH",
"MINUS",
"SYMBOL",
"LESS",
"IN",
"THEN",
"ELSE",
+ "WITH",
"RBRACKET",
"DOTDOT",
"AT",
"fundep",
"ruleDeclaration",
"query",
- "queryBlock",
"lexp",
"symbol",
"faexp",
"accessor",
"case",
+ "queryBlock",
"stringLiteral",
"symbolWithoutMinus",
"listQualifier",
return parse(0);
}
public Object parseCommands() {
- return parse(334);
+ return parse(330);
}
public Object parseImport() {
- return parse(341);
+ return parse(337);
}
public Object parseType() {
- return parse(343);
+ return parse(339);
}
public Object parseExp() {
- return parse(345);
+ return parse(341);
}
public Object parseEquationBlock() {
- return parse(347);
+ return parse(343);
}
case 5:
return reduceLocalTypeAnnotation();
case 6:
- return reduceEntityTypeAnnotation();
- case 7:
return reduceEquationBlock();
- case 8:
+ case 7:
return reduceModuleHeader();
- case 9:
+ case 8:
return reduceTypeAnnotation();
- case 10:
+ case 9:
return reduceValueDefinition();
- case 11:
+ case 10:
return reduceDataDefinition();
- case 12:
+ case 11:
return reduceTypeDefinition();
- case 13:
+ case 12:
return reduceClassDefinition();
- case 14:
+ case 13:
return reduceInstanceDefinition();
- case 15:
+ case 14:
return reduceDerivingInstanceDefinition();
- case 16:
+ case 15:
return reduceDocumentationString();
- case 17:
+ case 16:
return reduceAnnotation();
- case 18:
+ case 17:
return reducePrecedenceDefinition();
- case 19:
+ case 18:
return reduceJustImport();
- case 20:
+ case 19:
return reduceImportJava();
- case 21:
+ case 20:
return reduceEffectDefinition();
- case 22:
+ case 21:
return reduceRuleDefinition();
- case 23:
+ case 22:
return reduceMappingRelationDefinition();
- case 24:
+ case 23:
return reduceRelationDefinition();
- case 25:
+ case 24:
return reduceStatementCommand();
- case 26:
+ case 25:
return reduceImportCommand();
- case 27:
+ case 26:
return reduceGuardStatement();
- case 28:
+ case 27:
return reduceLetStatement();
- case 29:
+ case 28:
return reduceBindStatement();
- case 30:
+ case 29:
return reduceRuleStatement();
- case 31:
+ case 30:
return reduceCHRStatement();
- case 32:
+ case 31:
return reduceVerboseCHRStatement();
- case 33:
+ case 32:
return reduceConstraintStatement();
- case 34:
+ case 33:
return reduceDeclarations();
- case 35:
+ case 34:
return reduceField();
- case 36:
+ case 35:
return reduceFieldShorthand();
- case 37:
+ case 36:
return reduceVarId();
- case 38:
+ case 37:
return reduceEscapedSymbol();
- case 39:
+ case 38:
return reduceTupleConstructor();
- case 40:
+ case 39:
return reduceBinary();
- case 41:
+ case 40:
return reduceSimpleRhs();
- case 42:
+ case 41:
return reduceGuardedRhs();
- case 43:
+ case 42:
return reduceConstructor();
- case 44:
+ case 43:
return reduceRecordConstructor();
- case 45:
+ case 44:
return reduceContext();
- case 46:
+ case 45:
return reduceFundeps();
- case 47:
+ case 46:
return reduceTypeVar();
- case 48:
+ case 47:
return reduceTupleType();
- case 49:
+ case 48:
return reduceListType();
- case 50:
+ case 49:
return reduceListTypeConstructor();
- case 51:
+ case 50:
return reduceTupleTypeConstructor();
- case 52:
+ case 51:
return reduceLambda();
- case 53:
+ case 52:
return reduceLambdaMatch();
- case 54:
+ case 53:
return reduceLet();
- case 55:
+ case 54:
return reduceIf();
- case 56:
+ case 55:
return reduceMatch();
- case 57:
+ case 56:
return reduceDo();
- case 58:
+ case 57:
return reduceSelect();
- case 59:
+ case 58:
return reduceEnforce();
- case 60:
+ case 59:
return reduceVar();
- case 61:
+ case 60:
return reduceHashedId();
- case 62:
+ case 61:
return reduceBlank();
- case 63:
+ case 62:
return reduceInteger();
- case 64:
+ case 63:
return reduceFloat();
- case 65:
+ case 64:
return reduceString();
- case 66:
+ case 65:
return reduceChar();
- case 67:
+ case 66:
return reduceTuple();
- case 68:
+ case 67:
return reduceViewPattern();
- case 69:
+ case 68:
return reduceRightSection();
- case 70:
+ case 69:
return reduceLeftSection();
- case 71:
+ case 70:
return reduceListLiteral();
- case 72:
+ case 71:
return reduceRange();
- case 73:
+ case 72:
return reduceListComprehension();
- case 74:
+ case 73:
return reduceAs();
- case 75:
+ case 74:
return reduceRecord();
- case 76:
+ case 75:
return reduceTransformation();
- case 77:
+ case 76:
return reduceEq();
- case 78:
+ case 77:
return reduceRuleDeclarations();
- case 79:
+ case 78:
return reduceImportShowing();
- case 80:
+ case 79:
return reduceImportHiding();
- case 81:
+ case 80:
return reduceImportValueItem();
- case 82:
+ case 81:
return reduceFieldDescription();
- case 83:
+ case 82:
return reduceStatements();
- case 84:
+ case 83:
return reduceGuardedExpEq();
- case 85:
+ case 84:
return reduceFundep();
- case 86:
+ case 85:
return reduceQueryRuleDeclaration();
- case 87:
+ case 86:
return reduceAnnotation();
- case 88:
+ case 87:
return reduceGuardQuery();
- case 89:
+ case 88:
return reduceEqualsQuery();
- case 90:
+ case 89:
return reduceBindQuery();
- case 91:
+ case 90:
return reduceCompositeQuery();
+ case 91:
+ return reduceApply();
case 92:
- return reduceQueryBlock();
+ return reduceSymbol();
case 93:
- return reduceApply();
+ return reduceEscapedId();
case 94:
- return reduceSymbol();
+ return reduceMinus();
case 95:
- return reduceEscapedId();
+ return reduceLess();
case 96:
- return reduceMinus();
+ return reduceGreater();
case 97:
- return reduceLess();
+ return reduceDot();
case 98:
- return reduceGreater();
+ return reduceFieldAccess();
case 99:
- return reduceDot();
+ return reduceIdAccessor();
case 100:
- return reduceFieldAccess();
+ return reduceStringAccessor();
case 101:
- return reduceIdAccessor();
+ return reduceExpAccessor();
case 102:
- return reduceStringAccessor();
+ return reduceCase();
case 103:
- return reduceExpAccessor();
+ return reduceQueryBlock();
case 104:
- return reduceCase();
- case 105:
return reduceStringLiteral();
- case 106:
+ case 105:
return reduceSymbol();
- case 107:
+ case 106:
return reduceEscapedId();
- case 108:
+ case 107:
return reduceLess();
- case 109:
+ case 108:
return reduceGreater();
- case 110:
+ case 109:
return reduceDot();
- case 111:
+ case 110:
return reduceGuardQualifier();
- case 112:
+ case 111:
return reduceLetQualifier();
- case 113:
+ case 112:
return reduceBindQualifier();
- case 114:
+ case 113:
return reduceThenQualifier();
- case 115:
+ case 114:
return reduceCHRQuery();
- case 116:
+ case 115:
return reduceVerboseCHRQuery();
- case 117:
+ case 116:
return reduceSimpleCaseRhs();
- case 118:
+ case 117:
return reduceGuardedCaseRhs();
- case 119:
+ case 118:
return reduceGuardedExpArrow();
- case 120:
+ case 119:
return reduceGuardEquation();
- case 121:
+ case 120:
return reduceBasicEquation();
- case 122:
+ case 121:
return reduceEffect();
- case 123:
+ case 122:
return reduceJustEtype();
- case 124:
+ case 123:
return reduceForAll();
- case 125:
+ case 124:
return reduceApplyType();
- case 126:
+ case 125:
return reduceDummy();
default:
* exp ::= bexp (HASTYPE type)?
*/
protected abstract Object reduceLocalTypeAnnotation();
- /**
- * exp ::= bexp COLON ID (queryBlock | WITH queryBlock?)?
- */
- protected abstract Object reduceEntityTypeAnnotation();
/**
* equationBlock ::= (equation (SEMICOLON equation)*)?
*/
* query ::= QUERY_OP queryBlock
*/
protected abstract Object reduceCompositeQuery();
- /**
- * queryBlock ::= LBRACE (query (SEMICOLON (query SEMICOLON)* query)?)? RBRACE
- */
- protected abstract Object reduceQueryBlock();
/**
* lexp ::= faexp faexp*
*/
* case ::= exp caseRhs
*/
protected abstract Object reduceCase();
+ /**
+ * queryBlock ::= LBRACE (query (SEMICOLON (query SEMICOLON)* query)?)? RBRACE
+ */
+ protected abstract Object reduceQueryBlock();
/**
* stringLiteral ::= BEGIN_STRING (SUSPEND_STRING exp CONTINUE_STRING)* END_STRING
*/
import org.simantics.scl.compiler.elaboration.expressions.EBlock;
import org.simantics.scl.compiler.elaboration.expressions.EConstant;
import org.simantics.scl.compiler.elaboration.expressions.EEnforce;
-import org.simantics.scl.compiler.elaboration.expressions.EEntityTypeAnnotation;
import org.simantics.scl.compiler.elaboration.expressions.EEquations;
import org.simantics.scl.compiler.elaboration.expressions.EFieldAccess;
import org.simantics.scl.compiler.elaboration.expressions.EIf;
@Override
protected Object reduceIdAccessor() {
- return new IdAccessor(((Token)get(0)).text);
+ return new IdAccessor('.', ((Token)get(0)).text);
}
@Override
protected Object reduceStringAccessor() {
- return new StringAccessor(((Token)get(1)).text);
+ return new StringAccessor('.', ((Token)get(1)).text);
}
@Override
protected Object reduceExpAccessor() {
- return new ExpressionAccessor((Expression)get(1));
+ return new ExpressionAccessor('.', (Expression)get(1));
}
@Override
protected Object reduceFieldAccess() {
if(length() == 1)
return get(0);
- FieldAccessor[] accessors = new FieldAccessor[length()/2];
- for(int i=0;i<accessors.length;++i) {
- FieldAccessor accessor = (FieldAccessor)get(i*2+2);
- accessor.accessSeparator = ((Token)get(i*2+1)).text.charAt(0);
- accessors[i] = accessor;
+ Expression result = (Expression)get(0);
+ for(int i=2;i<length();i+=2) {
+ FieldAccessor accessor = (FieldAccessor)get(i);
+ accessor.accessSeparator = ((Token)get(i-1)).text.charAt(0);
+ result = new EFieldAccess(result, accessor);
}
- return new EFieldAccess((Expression)get(0), accessors);
+ return result;
}
@Override
protected Object reduceRuleStatement() {
return new RuleStatement((Expression)get(0), new QConjunction((Query[])get(2)));
}
-
- @Override
- protected Object reduceEntityTypeAnnotation() {
- return new EEntityTypeAnnotation((Expression)get(0), (Token)get(2),
- length() > 3
- ? new QConjunction((Query[])get(length()-1))
- : null);
- }
@Override
protected Object reduceHashedId() {
public static final int HIDING = 34;
public static final int ARROW = 35;
public static final int COLON = 36;
- public static final int WITH = 37;
- public static final int MINUS = 38;
- public static final int SYMBOL = 39;
- public static final int LESS = 40;
- public static final int GREATER = 41;
- public static final int SEPARATED_DOT = 42;
- public static final int ESCAPED_ID = 43;
- public static final int LAMBDA = 44;
- public static final int LAMBDA_MATCH = 45;
- public static final int LET = 46;
- public static final int IF = 47;
- public static final int MATCH = 48;
- public static final int DO = 49;
- public static final int MDO = 50;
- public static final int ENFORCE = 51;
- public static final int BLANK = 52;
- public static final int FLOAT = 53;
- public static final int LBRACKET = 54;
- public static final int ESCAPED_SYMBOL = 55;
- public static final int CHAR = 56;
- public static final int WHEN = 57;
- public static final int ATTACHED_HASH = 58;
- public static final int SELECT = 59;
- public static final int SELECT_FIRST = 60;
- public static final int SELECT_DISTINCT = 61;
- public static final int TRANSFORMATION = 62;
- public static final int EQ = 63;
- public static final int ATTACHED_DOT = 64;
- public static final int IN = 65;
- public static final int THEN = 66;
- public static final int ELSE = 67;
+ public static final int MINUS = 37;
+ public static final int SYMBOL = 38;
+ public static final int LESS = 39;
+ public static final int GREATER = 40;
+ public static final int SEPARATED_DOT = 41;
+ public static final int ESCAPED_ID = 42;
+ public static final int LAMBDA = 43;
+ public static final int LAMBDA_MATCH = 44;
+ public static final int LET = 45;
+ public static final int IF = 46;
+ public static final int MATCH = 47;
+ public static final int DO = 48;
+ public static final int MDO = 49;
+ public static final int ENFORCE = 50;
+ public static final int BLANK = 51;
+ public static final int FLOAT = 52;
+ public static final int LBRACKET = 53;
+ public static final int ESCAPED_SYMBOL = 54;
+ public static final int CHAR = 55;
+ public static final int WHEN = 56;
+ public static final int ATTACHED_HASH = 57;
+ public static final int SELECT = 58;
+ public static final int SELECT_FIRST = 59;
+ public static final int SELECT_DISTINCT = 60;
+ public static final int TRANSFORMATION = 61;
+ public static final int EQ = 62;
+ public static final int ATTACHED_DOT = 63;
+ public static final int IN = 64;
+ public static final int THEN = 65;
+ public static final int ELSE = 66;
+ public static final int WITH = 67;
public static final int RBRACKET = 68;
public static final int DOTDOT = 69;
public static final int AT = 70;
THashMap<String, TypeClass> typeClasses = new THashMap<String, TypeClass>();
THashMap<TCon, ArrayList<TypeClassInstance>> typeClassInstances = new THashMap<TCon, ArrayList<TypeClassInstance>>();
THashMap<String, SCLValue> values = new THashMap<String, SCLValue>();
+ THashMap<String, List<Constant>> fieldAccessors = new THashMap<String, List<Constant>>();
THashMap<String, SCLRelation> relations = new THashMap<String, SCLRelation>();
THashMap<String, SCLEntityType> entityTypes = new THashMap<String, SCLEntityType>();
THashMap<String, TransformationRule> rules = new THashMap<String, TransformationRule>();
addValue(value);
return value;
}
+
+ @Override
+ public List<Constant> getFieldAccessors(String name) {
+ return fieldAccessors.get(name);
+ }
public void addRelation(String name, SCLRelation relation) {
relations.put(name, relation);
throw new NullPointerException();
this.parentClassLoader = parentClassLoader;
}
+
+ public void addFieldAccessor(String name, Constant accessor) {
+ List<Constant> list = fieldAccessors.get(name);
+ if(list == null) {
+ list = new ArrayList<Constant>(2);
+ fieldAccessors.put(name, list);
+ }
+ list.add(accessor);
+ }
}
import java.util.Collection;
import java.util.Collections;
+import java.util.List;
+import org.simantics.scl.compiler.constants.Constant;
import org.simantics.scl.compiler.elaboration.modules.Documentation;
import org.simantics.scl.compiler.elaboration.modules.SCLValue;
import org.simantics.scl.compiler.elaboration.modules.TypeClass;
}
}
+ @Override
+ public List<Constant> getFieldAccessors(String name) {
+ return null;
+ }
+
public SCLRelation getRelation(String name) {
if(relations.containsKey(name))
return relations.get(name);
import java.util.List;
import java.util.function.Consumer;
+import org.simantics.scl.compiler.constants.Constant;
import org.simantics.scl.compiler.elaboration.modules.Documentation;
import org.simantics.scl.compiler.elaboration.modules.SCLValue;
import org.simantics.scl.compiler.elaboration.modules.TypeClass;
String getDefaultLocalName();
SCLValue getValue(String name);
+ List<Constant> getFieldAccessors(String name);
SCLRelation getRelation(String name);
SCLEntityType getEntityType(String name);
import java.util.ArrayList;
import java.util.Collection;
+import java.util.List;
import java.util.Map;
import org.simantics.scl.compiler.constants.Constant;
@Override
public void collectRules(Collection<TransformationRule> rules) {
}
+ @Override
+ public List<Constant> getFieldAccessors(String name) {
+ // TODO Not clear if this is needed.
+ return null;
+ }
};
public RuntimeModule(Module module, RuntimeModuleMap parentModuleMap,
@Test public void Random1() { test(); }
@Test public void RangeSyntax() { test(); }
@Test public void Record1() { test(); }
+ @Test public void Record2() { test(); }
@Test public void RecordShorthand() { test(); }
@Test public void RecursiveContext() { test(); }
@Test public void RecursiveValues2() { test(); }
@Test public void Sections() { test(); }
@Test public void Select1() { test(); }
@Test public void Select2() { test(); }
- @Test public void Select3() { test(); }
@Test public void Select4() { test(); }
@Test public void Select5() { test(); }
@Test public void Select6() { test(); }
main = "Not to be executed."
--
-1:9-1:10: Couldn't resolve variable b.
+1:9-1:10: Couldn't resolve b.
3:5-3:23: Pattern was expected here.
\ No newline at end of file
--- /dev/null
+module {
+ fields
+}
+
+import "Prelude"
+
+data Foo = Foo { x :: Double }
+data Bar = Bar { x :: Double, y :: Double }
+
+main = f.x + b.x + b.y
+ where
+ f = Foo 1.0
+ b = Bar 2.0 3.0
+--
+6.0
\ No newline at end of file
where
a = g a
--
-3:11-3:12: Couldn't resolve variable a.
\ No newline at end of file
+3:11-3:12: Couldn't resolve a.
\ No newline at end of file
+++ /dev/null
-import "StandardLibrary"
-import "Minigraph"
-
-main = withGraph do
- a = resource "a"
- b = map resource ["b0", "b1", "b2", "b3", "b4"]
- r = map resource ["r0", "r1"]
-
- enforce
- Statement a (r!0) (b!0)
- Statement a (r!0) (b!1)
- Statement a (r!1) (b!4)
- Statement (b!1) (r!1) (b!3)
- Statement (b!1) (r!0) (b!2)
- sort $ map uriOf $ select ?x where
- Statement a (r!0) (_ : Resource { #r1 = ?x })
---
-[b3]
a = b
--
-1:5-1:6: Couldn't resolve variable b.
\ No newline at end of file
+1:5-1:6: Couldn't resolve b.
\ No newline at end of file
c = a + b
--
-4:7-4:8: Couldn't resolve variable +.
\ No newline at end of file
+4:7-4:8: Couldn't resolve +.
\ No newline at end of file