X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.scl.compiler%2Fsrc%2Forg%2Fsimantics%2Fscl%2Fcompiler%2Fcompilation%2FElaboration.java;h=f7f745841460bdbfc30aacbd0a35b5174620208f;hp=1cba44207ee7c124de787ceff3b7631421084c1b;hb=4e753de3df98d5411f8329205c0e03f2e13e3c1d;hpb=b2676209b072592da3425c2efb29f51eb5c4a0e0 diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/Elaboration.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/Elaboration.java index 1cba44207..f7f745841 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/Elaboration.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/Elaboration.java @@ -6,6 +6,7 @@ import java.util.List; import org.cojen.classfile.TypeDesc; import org.simantics.scl.compiler.common.datatypes.Constructor; +import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; import org.simantics.scl.compiler.common.names.Name; import org.simantics.scl.compiler.constants.Constant; import org.simantics.scl.compiler.constants.JavaTypeInstanceConstructor; @@ -31,6 +32,7 @@ import org.simantics.scl.compiler.elaboration.expressions.EGetConstraint; import org.simantics.scl.compiler.elaboration.expressions.EIntegerLiteral; import org.simantics.scl.compiler.elaboration.expressions.EListLiteral; import org.simantics.scl.compiler.elaboration.expressions.ELiteral; +import org.simantics.scl.compiler.elaboration.expressions.EPreCHRRulesetConstructor; import org.simantics.scl.compiler.elaboration.expressions.EVar; import org.simantics.scl.compiler.elaboration.expressions.Expression; import org.simantics.scl.compiler.elaboration.expressions.Variable; @@ -39,6 +41,7 @@ import org.simantics.scl.compiler.elaboration.fundeps.Fundep; import org.simantics.scl.compiler.elaboration.java.JavaMethodDeclaration; import org.simantics.scl.compiler.elaboration.macros.StandardMacroRule; import org.simantics.scl.compiler.elaboration.modules.DeprecatedProperty; +import org.simantics.scl.compiler.elaboration.modules.DerivedProperty; import org.simantics.scl.compiler.elaboration.modules.InlineProperty; import org.simantics.scl.compiler.elaboration.modules.MethodImplementation; import org.simantics.scl.compiler.elaboration.modules.PrivateProperty; @@ -47,6 +50,7 @@ import org.simantics.scl.compiler.elaboration.modules.TypeAlias; import org.simantics.scl.compiler.elaboration.modules.TypeClass; import org.simantics.scl.compiler.elaboration.modules.TypeClassInstance; import org.simantics.scl.compiler.elaboration.modules.TypeClassMethod; +import org.simantics.scl.compiler.elaboration.modules.TypeDescriptor; import org.simantics.scl.compiler.elaboration.query.Query; import org.simantics.scl.compiler.elaboration.query.pre.QPreGuard; import org.simantics.scl.compiler.elaboration.relations.ConcreteRelation; @@ -57,7 +61,9 @@ import org.simantics.scl.compiler.environment.AmbiguousNameException; import org.simantics.scl.compiler.environment.Environment; import org.simantics.scl.compiler.environment.EnvironmentFactory; import org.simantics.scl.compiler.environment.Environments; +import org.simantics.scl.compiler.errors.CompilationError; import org.simantics.scl.compiler.errors.ErrorLog; +import org.simantics.scl.compiler.errors.ErrorSeverity; import org.simantics.scl.compiler.errors.Locations; import org.simantics.scl.compiler.internal.codegen.effects.EffectConstructor; import org.simantics.scl.compiler.internal.codegen.effects.ThreadLocalVariable; @@ -84,6 +90,7 @@ import org.simantics.scl.compiler.internal.parsing.declarations.DInstanceAst; import org.simantics.scl.compiler.internal.parsing.declarations.DMappingRelationAst; import org.simantics.scl.compiler.internal.parsing.declarations.DRelationAst; import org.simantics.scl.compiler.internal.parsing.declarations.DRuleAst; +import org.simantics.scl.compiler.internal.parsing.declarations.DRulesetAst; import org.simantics.scl.compiler.internal.parsing.declarations.DTypeAst; import org.simantics.scl.compiler.internal.parsing.declarations.DValueAst; import org.simantics.scl.compiler.internal.parsing.declarations.DValueTypeAst; @@ -162,19 +169,24 @@ public class Elaboration { module = new ConcreteModule(moduleName); compilationContext.module = module; - if(moduleHeader != null && moduleHeader.defaultLocalName != null) - module.setDefaultLocalName(moduleHeader.defaultLocalName); + if(moduleHeader != null) { + if(moduleHeader.defaultLocalName != null) + module.setDefaultLocalName(moduleHeader.defaultLocalName); + if(moduleHeader.deprecated != null) + module.setDeprecation(moduleHeader.deprecated); + } try { if(timer != null) timer.suspendTimer(); importedEnvironment = localEnvironmentFactory.createEnvironment( + compilationContext, importsAst.toArray(new ImportDeclaration[importsAst.size()])); if(timer != null) timer.continueTimer(); compilationContext.environment = new EnvironmentOfModule(importedEnvironment, module); } catch (ImportFailureException e) { for(ImportFailure failure : e.failures) - errorLog.log(failure.location, failure.toString()); + errorLog.log(new CompilationError(failure.location, failure.toString(), ErrorSeverity.IMPORT_ERROR)); return; } for(ImportDeclaration importAst : importsAst) @@ -211,7 +223,8 @@ public class Elaboration { public void addTypesToEnvironment( ArrayList dataTypesAst, ArrayList typeAliasesAst, - ArrayList effectsAst) { + ArrayList effectsAst, + ArrayList rulesetsAst) { for(DDataAst dataType : dataTypesAst) { dataType.parameterKinds = new Kind[dataType.parameters.length]; Kind constructorKind = Kinds.STAR; @@ -226,8 +239,7 @@ public class Elaboration { NameExistenceChecks.checkIfTypeExists(errorLog, dataType.location, importedEnvironment, dataType.name); - if(module.addTypeDescriptor(dataType.name, typeConstructor)) - errorLog.log(dataType.location, "Type "+dataType.name+" has already been defined in this module."); + addTypeDescriptor(dataType.location, dataType.name, typeConstructor); dataType.typeConstructor = typeConstructor; } @@ -235,9 +247,7 @@ public class Elaboration { TypeAlias alias = new TypeAlias(Types.con(moduleName, typeAlias.name), typeAlias.parameters.length); NameExistenceChecks.checkIfTypeExists(errorLog, typeAlias.location, importedEnvironment, typeAlias.name); - if(module.addTypeDescriptor(typeAlias.name, alias)) { - errorLog.log(typeAlias.location, "Type alias "+typeAlias.name+" has already been defined in this module."); - } + addTypeDescriptor(typeAlias.location, typeAlias.name, alias); } for(DEffectAst effect : effectsAst) { @@ -248,11 +258,24 @@ public class Elaboration { TypeDesc.forClass(effect.threadLocalType) )); if(module.addEffectConstructor(effect.name, effectConstructor)) - errorLog.log(effect.location, "Type "+effect.name+" has already been defined in this module."); - } + errorLog.log(effect.location, "Effect "+effect.name+" has already been defined in this module."); + } + for(DRulesetAst ruleset : rulesetsAst) { + ruleset.type = Types.con(moduleName, ruleset.name); + ruleset.className = compilationContext.namingPolicy.getDataTypeClassName(ruleset.name); + StandardTypeConstructor typeConstructor = new StandardTypeConstructor(ruleset.type, Kinds.STAR, + TypeDesc.forClass(ruleset.className), ruleset.documentation == null ? null : ruleset.documentation.documentation); + typeConstructor.external = true; + addTypeDescriptor(ruleset.location, ruleset.name, typeConstructor); + } javaTypeTranslator = new JavaTypeTranslator(compilationContext.environment); compilationContext.javaTypeTranslator = javaTypeTranslator; } + + private void addTypeDescriptor(long location, String name, TypeDescriptor typeDescriptor) { + if(module.addTypeDescriptor(name, typeDescriptor)) + errorLog.log(location, "Type "+name+" has already been defined in this module."); + } private static final int[] EMPTY_INT_ARRAY = new int[0]; @@ -360,7 +383,7 @@ public class Elaboration { dataTypes.add(dataType); for(int j=0;j=0;--i) parameterTypes[i] = context.toType(constructor.parameters[i]); @@ -587,6 +610,7 @@ public class Elaboration { String fullName = instancePrefix + valueName; long loc = valueDefs.getDefinition(valueName).get(0).location; valueDefinitionsAst.addFrom(valueDefs, valueName, fullName); + valueDefinitionsAst.setDerived(fullName); /*valueDefinitionsAst.addAnnotation(fullName, new DAnnotationAst(new EVar("@private"), Collections.emptyList()));*/ TypeClassMethod method = typeClass.methods.get(valueName); @@ -693,7 +717,7 @@ public class Elaboration { type); if(callJava != null) { NameExistenceChecks.checkIfValueExists(errorLog, javaMethod.location, - importedEnvironment, name); + importedEnvironment, module, name); SCLValue value = module.addValue(name, callJava); value.definitionLocation = javaMethod.methodName.location; if(isPrivate) @@ -702,6 +726,18 @@ public class Elaboration { } } + public void processRulesets(ArrayList rulesetsAst) { + for(DRulesetAst ruleset : rulesetsAst) { + String constructorName = "create" + ruleset.name; + supplementedTypeAnnotations.add(new SupplementedValueType(ruleset.location, constructorName, Types.functionE(Types.PUNIT, Types.PROC, ruleset.type))); + try { + valueDefinitionsAst.add(new DValueAst(new EVar(constructorName), new EPreCHRRulesetConstructor(ruleset))); + } catch (NotPatternException e) { + throw new InternalCompilerError(ruleset.location, e); + } + } + } + /** * Convert a java class method into a {@link CallJava} instance. * Compilation errors are logged for failures in finding the named class or in accessing the method. @@ -1084,6 +1120,7 @@ public class Elaboration { int constructorTag = 0; for(Constructor constructor : dataType.constructors) { SCLValue value = new SCLValue(constructor.name); + value.definitionLocation = constructor.loc; SCLConstructor sclConstructor = new SCLConstructor( constructor.name.name, @@ -1105,7 +1142,7 @@ public class Elaboration { value.setType(constructor.getType()); NameExistenceChecks.checkIfValueExists(errorLog, constructor.loc, - importedEnvironment, constructor.name.name); + importedEnvironment, module, constructor.name.name); if(module.addValue(value)) { errorLog.log(constructor.loc, "Value " + constructor.name.name + " is already defined."); @@ -1120,7 +1157,7 @@ public class Elaboration { SCLValue value = method.createValue(); value.definitionLocation = method.location; NameExistenceChecks.checkIfValueExists(errorLog, Locations.NO_LOCATION, - importedEnvironment, value.getName().name); + importedEnvironment, module, value.getName().name); if(module.addValue(value)) { String name = method.getName(); @@ -1140,10 +1177,12 @@ public class Elaboration { long location = valueDefinitionsAst.getLocation(name); NameExistenceChecks.checkIfValueExists(errorLog, location, - importedEnvironment, value.getName().name); + importedEnvironment, module, value.getName().name); value.definitionLocation = location; if(module.addValue(value)) errorLog.log(location, "Value " + name + " is already defined."); + if(valueDefinitionsAst.isDerived(name)) + value.addProperty(DerivedProperty.INSTANCE); } for(DValueTypeAst valueTypeAst : typeAnnotationsAst) for(EVar name : valueTypeAst.names) { @@ -1181,6 +1220,25 @@ public class Elaboration { for(String name : valueDefinitionsAst.getValueNames()) { ArrayList defs = valueDefinitionsAst.getDefinition(name); + if(defs.size() != 1 || !(defs.get(0).value instanceof EPreCHRRulesetConstructor)) + continue; + try { + SCLValue value = module.getValue(name); + TranslationContext context = createTranslationContext(); + Expression expression = context.translateCases2(defs); + value.setExpression(expression); + + if(exportMap != null && exportMap.remove(name) == null) + value.addProperty(PrivateProperty.INSTANCE); + } catch(RuntimeException e) { + errorLog.setExceptionPosition(defs.get(0).location); + throw e; + } + } + for(String name : valueDefinitionsAst.getValueNames()) { + ArrayList defs = valueDefinitionsAst.getDefinition(name); + if(defs.size() == 1 && defs.get(0).value instanceof EPreCHRRulesetConstructor) + continue; try { SCLValue value = module.getValue(name); TranslationContext context = createTranslationContext();