--- /dev/null
+*.java text\r
+*.pgraph text\r
+*.scl text\r
+*.xml text\r
+*.svg text\r
+MANIFEST.MF text\r
+\r
+*.tg binary\r
+*.png binary\r
+*.gif binary
\ No newline at end of file
<extension>\r
<groupId>org.eclipse.tycho.extras</groupId>\r
<artifactId>tycho-pomless</artifactId>\r
- <version>0.25.0</version>\r
+ <version>0.26.0</version>\r
</extension>\r
</extensions>
\ No newline at end of file
info.acquireMutex();
try {
info.makeResident();
- return info.getCSSIds();
+ return info.getCCSIds();
} finally {
info.releaseMutex();
}
mainProgram.mutex.release();
}
} catch (IllegalAcornStateException | ProCoreException e) {
- Logger.defaultLogError(e);
+ Logger.defaultLogError("Snapshotting failed", e);
unexpectedClose = true;
} catch (InterruptedException e) {
- Logger.defaultLogError(e);
+ Logger.defaultLogError("Snapshotting interrupted", e);
} finally {
try {
if(tr != null)
try {
support.close();
} catch (DatabaseException e1) {
- Logger.defaultLogError(e1);
+ Logger.defaultLogError("Failed to close database as a safety measure due to failed snapshotting", e1);
}
}
} catch (ProCoreException e) {
- Logger.defaultLogError(e);
+ Logger.defaultLogError("Failed to end snapshotting write transaction", e);
}
}
}
@Override
public long cancelCommit(long transactionId, long changeSetId, byte[] metadata, OnChangeSetUpdate onChangeSetUpdate) throws ProCoreException {
- UnsupportedOperationException e = new UnsupportedOperationException("org.simantics.acorn.GraphClientImpl2.cancelCommit() is not supported operation! Closing down to prevent further havoc");
- clusters.notSafeToMakeSnapshot(new IllegalAcornStateException(e));
- throw e;
-// System.err.println("GraphClientImpl2.cancelCommit() called!! this is experimental and might cause havoc!");
-// try {
-// undo(new long[] {changeSetId}, onChangeSetUpdate);
-// } catch (SDBException e) {
-// e.printStackTrace();
-// throw new ProCoreException(e);
-// }
-// clusters.state.headChangeSetId++;
-// return clusters.state.headChangeSetId;
+ // Accept and finalize current transaction and then undo it
+ acceptCommit(transactionId, changeSetId, metadata);
+
+ try {
+ undo(new long[] {changeSetId+1}, onChangeSetUpdate);
+ clusters.state.headChangeSetId++;
+ return clusters.state.headChangeSetId;
+ } catch (SDBException e) {
+ Logger.defaultLogError("Failed to undo cancelled transaction", e);
+ throw new ProCoreException(e);
+ }
}
@Override
ArrayList<String> ccss = clusters.getChanges(id);
for(int j=0;j<ccss.size();j++) {
+ String ccsid = ccss.get(ccss.size()-j-1);
try {
if(ClusterUpdateProcessorBase.DEBUG)
- System.err.println("performUndo " + ccss.get(ccss.size()-j-1));
- performUndo(ccss.get(ccss.size()-j-1), clusterChanges, support);
+ System.err.println("performUndo " + ccsid);
+ performUndo(ccsid, clusterChanges, support);
} catch (DatabaseException e) {
e.printStackTrace();
}
LRU.insert(this, accessTime);
}
- public ArrayList<String> getCSSIds() throws AcornAccessVerificationException {
+ public ArrayList<String> getCCSIds() throws AcornAccessVerificationException {
if(VERIFY) verifyAccess();
return clusterChangeSetIds;
}
-Xmx500M\r
-Xshare:off\r
-XX:MaxPermSize=192m\r
--Djava.net.preferIPv4Stack=true\r
-Dorg.simantics.workbench.application.showFastViewBars=false\r
-Dorg.simantics.workbench.application.showPerspectiveBar=false\r
-Dorg.simantics.workbench.application.excludePerspectiveFromTitle=true\r
+-Djava.util.Arrays.useLegacyMergeSort=true\r
-Declipse.workaround.bug467000=true\r
</vmArgs>\r
<vmArgsWin>-Dorg.osgi.framework.os.name=win32\r
<feature id="org.simantics.desktop.product" version="1.0.0.qualifier"/>\r
</features>\r
\r
+\r
<preferencesInfo>\r
<targetfile overwrite="false"/>\r
</preferencesInfo>\r
include "Simantics/Entity" hiding (nameOf)\r
import "Simantics/Misc"\r
import "Simantics/Library"\r
-import "Simantics/DrawingTemplate"\r
\r
type Image = Resource\r
\r
Bundle-ManifestVersion: 2
Bundle-Name: General Modeling Workbench Contributions
Bundle-SymbolicName: org.simantics.modeling.ui.workbench;singleton:=true
-Bundle-Version: 1.25.0.qualifier
+Bundle-Version: 1.26.0.qualifier
Bundle-Vendor: Semantum Oy
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Require-Bundle: org.eclipse.ui
"""\r
ACTION_COMPARATOR :: Comparator Action\r
\r
-instance Eq Action where\r
- a == b = compareWithComparator ACTION_COMPARATOR a b == 0\r
-\r
instance Ord Action where\r
compare = compareWithComparator ACTION_COMPARATOR\r
\r
-package org.simantics.modeling.scl;\r
-\r
-import java.util.Collection;\r
-\r
-import org.simantics.Simantics;\r
-import org.simantics.db.ReadGraph;\r
-import org.simantics.db.RequestProcessorSpecific;\r
-import org.simantics.db.Resource;\r
-import org.simantics.db.WriteGraph;\r
-import org.simantics.db.common.request.UnaryRead;\r
-import org.simantics.db.common.request.WriteRequest;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.db.procedure.SyncListener;\r
-import org.simantics.db.request.Read;\r
-import org.simantics.layer0.Layer0;\r
-import org.simantics.modeling.ModelingUtils;\r
-import org.simantics.scl.compiler.module.repository.UpdateListener;\r
-import org.simantics.scl.compiler.source.ModuleSource;\r
-import org.simantics.scl.compiler.source.StringModuleSource;\r
-import org.simantics.scl.compiler.source.repository.ModuleSourceRepository;\r
-import org.simantics.scl.runtime.SCLContext;\r
-import org.simantics.structural2.utils.StructuralUtils;\r
-import org.simantics.scl.runtime.tuple.Tuple0;\r
-\r
-import gnu.trove.procedure.TObjectProcedure;\r
-import gnu.trove.set.hash.THashSet;\r
-\r
-public enum GraphModuleSourceRepository implements ModuleSourceRepository {\r
- INSTANCE;\r
-\r
- @Override\r
- public ModuleSource getModuleSource(final String moduleName, UpdateListener listener) {\r
- if(!moduleName.startsWith("http://"))\r
- return null;\r
-\r
- Object graph = SCLContext.getCurrent().get("graph");\r
- RequestProcessorSpecific requestProcessor;\r
- if(graph instanceof ReadGraph)\r
- requestProcessor = (ReadGraph)graph;\r
- else\r
- requestProcessor = Simantics.getSession();\r
-\r
- Read<ModuleSource> request = new ReadModuleSource(moduleName);\r
-\r
- try {\r
- if(listener != null)\r
- return requestProcessor.syncRequest(request, new ModuleListener(listener, moduleName));\r
- else\r
- return requestProcessor.syncRequest(request);\r
- } catch (DatabaseException e) {\r
- e.printStackTrace();\r
- return null;\r
- }\r
- }\r
-\r
- static class ModuleListener implements SyncListener<ModuleSource> {\r
- UpdateListener listener;\r
- boolean alreadyExecutedOnce;\r
- final String moduleName;\r
- public ModuleListener(UpdateListener listener, String moduleName) {\r
- this.listener = listener;\r
- this.moduleName = moduleName;\r
- }\r
- @Override\r
- public boolean isDisposed() {\r
- return listener == null;\r
- }\r
- private void fireUpdate(ReadGraph graph) {\r
- if(listener != null) {\r
- SCLContext context = SCLContext.getCurrent();\r
- Object oldGraph = context.put("graph", graph);\r
- try {\r
- listener.notifyAboutUpdate();\r
- } finally {\r
- listener = null;\r
- context.put("graph", oldGraph);\r
- }\r
- }\r
- }\r
- @Override\r
- public void execute(ReadGraph graph, ModuleSource result)\r
- throws DatabaseException {\r
- if(alreadyExecutedOnce)\r
- fireUpdate(graph);\r
- else\r
- alreadyExecutedOnce = true;\r
- }\r
- @Override\r
- public void exception(ReadGraph graph, Throwable t)\r
- throws DatabaseException {\r
- t.printStackTrace();\r
- if(alreadyExecutedOnce && listener != null)\r
- fireUpdate(graph);\r
- }\r
- };\r
- \r
- public static class GraphModuleSource extends StringModuleSource {\r
-\r
- private final boolean immutable;\r
-\r
- public GraphModuleSource(String moduleName, ClassLoader classLoader, String moduleText, boolean immutable) {\r
- super(moduleName, classLoader, moduleText);\r
- this.immutable = immutable;\r
- }\r
- \r
- @Override\r
- public boolean isUpdateable() {\r
- return !immutable;\r
- }\r
- \r
- @Override\r
- public void update(String newSourceText) {\r
- try {\r
- Simantics.getSession().syncRequest(new WriteModuleSource(getModuleName(), newSourceText));\r
- } catch (DatabaseException e) {\r
- e.printStackTrace();\r
- }\r
- }\r
- }\r
-\r
- static class ReadModuleSource extends UnaryRead<String, ModuleSource> {\r
- public ReadModuleSource(String moduleName) {\r
- super(moduleName);\r
- }\r
-\r
- @Override\r
- public ModuleSource perform(ReadGraph graph) throws DatabaseException {\r
- Resource moduleResource = graph.getPossibleResource(parameter);\r
- if(moduleResource == null)\r
- return null;\r
- Layer0 L0 = Layer0.getInstance(graph);\r
- if(!graph.isInstanceOf(moduleResource, L0.SCLModule))\r
- return null;\r
- String text = graph.getRelatedValue(moduleResource, L0.SCLModule_definition);\r
- boolean immutable = StructuralUtils.isImmutable(graph, moduleResource);\r
- return new GraphModuleSource(parameter, getClass().getClassLoader(), text, immutable);\r
- }\r
- }\r
- \r
- static class WriteModuleSource extends WriteRequest {\r
- private final String moduleURI;\r
- private final String sourceText;\r
- \r
- public WriteModuleSource(String moduleURI, String sourceText) {\r
- this.moduleURI = moduleURI;\r
- this.sourceText = sourceText;\r
- }\r
-\r
- @Override\r
- public void perform(WriteGraph graph) throws DatabaseException {\r
- Resource moduleResource = graph.getPossibleResource(moduleURI);\r
- if(moduleResource == null)\r
- return;\r
- Layer0 L0 = Layer0.getInstance(graph);\r
- if(!graph.isInstanceOf(moduleResource, L0.SCLModule))\r
- return;\r
- graph.claimLiteral(moduleResource, L0.SCLModule_definition, sourceText);\r
- }\r
- }\r
-\r
- @Override\r
- public void forAllModules(TObjectProcedure<String> procedure) {\r
- THashSet<String> moduleURIs;\r
- try {\r
- moduleURIs = Simantics.getSession().syncRequest(new Read<THashSet<String>>() {\r
- @Override\r
- public THashSet<String> perform(ReadGraph graph)\r
- throws DatabaseException {\r
- THashSet<String> result = new THashSet<String>(); \r
- Resource projectResource = Simantics.getProjectResource();\r
- Layer0 L0 = Layer0.getInstance(graph);\r
- for(Resource model : graph.getObjects(projectResource, L0.ConsistsOf)) {\r
- if(graph.isInstanceOf(model, L0.IndexRoot)) {\r
- for(Resource module : ModelingUtils.searchByType(graph, model, L0.SCLModule))\r
- result.add(graph.getURI(module));\r
- }\r
- }\r
- \r
- Collection<Resource> ontologies = Simantics.applySCL("Simantics/SharedOntologies", "getSharedOntologies", graph, Tuple0.INSTANCE);\r
- for (Resource ontology : ontologies) {\r
- for(Resource module : ModelingUtils.searchByType(graph, ontology, L0.SCLModule))\r
- result.add(graph.getURI(module));\r
- }\r
- \r
- return result;\r
- }\r
- });\r
- moduleURIs.forEach(procedure);\r
- } catch (DatabaseException e) {\r
- e.printStackTrace();\r
- }\r
- }\r
-\r
- @Override\r
- public void checkUpdates() {\r
- }\r
-\r
- @Override\r
- public String getDocumentation(String documentationName) {\r
- return null;\r
- }\r
-\r
- @Override\r
- public void forAllDocumentations(TObjectProcedure<String> procedure) {\r
- }\r
-\r
- @Override\r
- public void clear() {\r
- }\r
-}\r
+package org.simantics.modeling.scl;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.simantics.Simantics;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.RequestProcessorSpecific;
+import org.simantics.db.Resource;
+import org.simantics.db.WriteGraph;
+import org.simantics.db.common.request.UnaryRead;
+import org.simantics.db.common.request.WriteRequest;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.procedure.SyncListener;
+import org.simantics.db.request.Read;
+import org.simantics.layer0.Layer0;
+import org.simantics.modeling.ModelingUtils;
+import org.simantics.scl.compiler.module.repository.UpdateListener;
+import org.simantics.scl.compiler.source.ModuleSource;
+import org.simantics.scl.compiler.source.StringModuleSource;
+import org.simantics.scl.compiler.source.repository.ModuleSourceRepository;
+import org.simantics.scl.runtime.SCLContext;
+import org.simantics.structural2.utils.StructuralUtils;
+import org.simantics.scl.runtime.tuple.Tuple0;
+
+import gnu.trove.procedure.TObjectProcedure;
+import gnu.trove.set.hash.THashSet;
+
+public enum GraphModuleSourceRepository implements ModuleSourceRepository {
+ INSTANCE;
+
+ @Override
+ public ModuleSource getModuleSource(final String moduleName, UpdateListener listener) {
+ if(!moduleName.startsWith("http://"))
+ return null;
+
+ Object graph = SCLContext.getCurrent().get("graph");
+ RequestProcessorSpecific requestProcessor;
+ if(graph instanceof ReadGraph)
+ requestProcessor = (ReadGraph)graph;
+ else
+ requestProcessor = Simantics.getSession();
+
+ Read<ModuleSource> request = new ReadModuleSource(moduleName);
+
+ try {
+ if(listener != null)
+ return requestProcessor.syncRequest(request, new ModuleListener(listener, moduleName));
+ else
+ return requestProcessor.syncRequest(request);
+ } catch (DatabaseException e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ static class ModuleListener implements SyncListener<ModuleSource> {
+ UpdateListener listener;
+ boolean alreadyExecutedOnce;
+ final String moduleName;
+ public ModuleListener(UpdateListener listener, String moduleName) {
+ this.listener = listener;
+ this.moduleName = moduleName;
+ }
+ @Override
+ public boolean isDisposed() {
+ return listener == null;
+ }
+ private void fireUpdate(ReadGraph graph) {
+ if(listener != null) {
+ SCLContext context = SCLContext.getCurrent();
+ Object oldGraph = context.put("graph", graph);
+ try {
+ listener.notifyAboutUpdate();
+ } finally {
+ listener = null;
+ context.put("graph", oldGraph);
+ }
+ }
+ }
+ @Override
+ public void execute(ReadGraph graph, ModuleSource result)
+ throws DatabaseException {
+ if(alreadyExecutedOnce)
+ fireUpdate(graph);
+ else
+ alreadyExecutedOnce = true;
+ }
+ @Override
+ public void exception(ReadGraph graph, Throwable t)
+ throws DatabaseException {
+ t.printStackTrace();
+ if(alreadyExecutedOnce && listener != null)
+ fireUpdate(graph);
+ }
+ };
+
+ public static class GraphModuleSource extends StringModuleSource {
+
+ private final boolean immutable;
+
+ public GraphModuleSource(String moduleName, ClassLoader classLoader, String moduleText, boolean immutable) {
+ super(moduleName, classLoader, moduleText);
+ this.immutable = immutable;
+ }
+
+ @Override
+ public boolean isUpdateable() {
+ return !immutable;
+ }
+
+ @Override
+ public void update(String newSourceText) {
+ try {
+ Simantics.getSession().syncRequest(new WriteModuleSource(getModuleName(), newSourceText));
+ } catch (DatabaseException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ static class ReadModuleSource extends UnaryRead<String, ModuleSource> {
+ public ReadModuleSource(String moduleName) {
+ super(moduleName);
+ }
+
+ @Override
+ public ModuleSource perform(ReadGraph graph) throws DatabaseException {
+ Resource moduleResource = graph.getPossibleResource(parameter);
+ if(moduleResource == null)
+ return null;
+ Layer0 L0 = Layer0.getInstance(graph);
+ if(!graph.isInstanceOf(moduleResource, L0.SCLModule))
+ return null;
+ String text = graph.getRelatedValue(moduleResource, L0.SCLModule_definition);
+ boolean immutable = StructuralUtils.isImmutable(graph, moduleResource);
+ return new GraphModuleSource(parameter, getClass().getClassLoader(), text, immutable);
+ }
+ }
+
+ static class WriteModuleSource extends WriteRequest {
+ private final String moduleURI;
+ private final String sourceText;
+
+ public WriteModuleSource(String moduleURI, String sourceText) {
+ this.moduleURI = moduleURI;
+ this.sourceText = sourceText;
+ }
+
+ @Override
+ public void perform(WriteGraph graph) throws DatabaseException {
+ Resource moduleResource = graph.getPossibleResource(moduleURI);
+ if(moduleResource == null)
+ return;
+ Layer0 L0 = Layer0.getInstance(graph);
+ if(!graph.isInstanceOf(moduleResource, L0.SCLModule))
+ return;
+ graph.claimLiteral(moduleResource, L0.SCLModule_definition, sourceText);
+ }
+ }
+
+ @Override
+ public void forAllModules(TObjectProcedure<String> procedure) {
+ THashSet<String> moduleURIs;
+ try {
+ moduleURIs = Simantics.getSession().syncRequest(new Read<THashSet<String>>() {
+ @Override
+ public THashSet<String> perform(ReadGraph graph)
+ throws DatabaseException {
+ THashSet<String> result = new THashSet<String>();
+ Resource projectResource = Simantics.getProjectResource();
+ Layer0 L0 = Layer0.getInstance(graph);
+ for(Resource model : graph.getObjects(projectResource, L0.ConsistsOf)) {
+ if(graph.isInstanceOf(model, L0.IndexRoot)) {
+ for(Resource module : ModelingUtils.searchByType(graph, model, L0.SCLModule))
+ result.add(graph.getURI(module));
+ }
+ }
+
+ Collection<Resource> ontologies = Simantics.applySCL("Simantics/SharedOntologies", "getSharedOntologies", graph, Tuple0.INSTANCE);
+ for (Resource ontology : ontologies) {
+ for(Resource module : ModelingUtils.searchByType(graph, ontology, L0.SCLModule))
+ result.add(graph.getURI(module));
+ }
+
+ return result;
+ }
+ });
+ moduleURIs.forEach(procedure);
+ } catch (DatabaseException e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public Collection<String> getModuleNames() {
+ ArrayList<String> result = new ArrayList<>();
+ forAllModules((String name) -> {
+ result.add(name);
+ return true;
+ });
+ return result;
+ }
+}
\r
import org.simantics.db.Resource;\r
import org.simantics.scl.compiler.common.names.Name;\r
+import org.simantics.scl.compiler.common.names.Names;\r
+import org.simantics.scl.compiler.elaboration.chr.plan.PlanContext;\r
import org.simantics.scl.compiler.elaboration.expressions.EApply;\r
import org.simantics.scl.compiler.elaboration.expressions.EExternalConstant;\r
import org.simantics.scl.compiler.elaboration.expressions.EVariable;\r
import org.simantics.scl.compiler.elaboration.query.compilation.EnforcingContext;\r
import org.simantics.scl.compiler.elaboration.query.compilation.QueryCompilationContext;\r
import org.simantics.scl.compiler.elaboration.relations.SCLRelation;\r
+import org.simantics.scl.compiler.environment.Environment;\r
import org.simantics.scl.compiler.errors.Locations;\r
+import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;\r
import org.simantics.scl.compiler.types.TVar;\r
import org.simantics.scl.compiler.types.Type;\r
import org.simantics.scl.compiler.types.Types;\r
Expression possibleValue = new EApply(\r
Locations.NO_LOCATION,\r
Types.READ_GRAPH,\r
- context.getTypingContext().getConstant(POSSIBLE_RELATED_VALUE, valueType),\r
+ context.getCompilationContext().getConstant(POSSIBLE_RELATED_VALUE, valueType),\r
context.getEvidence(location, Types.pred(Types.SERIALIZABLE, valueType)),\r
new EVariable(parameters[0]),\r
new EExternalConstant(propertyRelation, RESOURCE)\r
case BB: {\r
Variable temp = new Variable("temp", valueType);\r
context.condition(new EApply(\r
- context.getTypingContext().getConstant(Name.create("Prelude", "=="), valueType),\r
+ context.getCompilationContext().getConstant(Names.Builtin_equals, valueType),\r
new Expression[] {\r
- context.getEvidence(location, Types.pred(Types.EQ, valueType)),\r
new EVariable(temp),\r
new EVariable(parameters[1])\r
}\r
return new EApply(\r
Locations.NO_LOCATION,\r
Types.WRITE_GRAPH,\r
- context.getTypingContext().getConstant(CLAIM_RELATED_VALUE, valueType),\r
+ context.getCompilationContext().getConstant(CLAIM_RELATED_VALUE, valueType),\r
context.getEvidence(location, Types.pred(Types.SERIALIZABLE, valueType)),\r
new EVariable(parameters[0]),\r
new EExternalConstant(propertyRelation, RESOURCE),\r
return 0;\r
}\r
\r
+ @Override\r
+ public void generateEnforce(PlanContext context, CodeWriter w, long location, Expression[] parameters) {\r
+ throw new UnsupportedOperationException(getClass().getSimpleName() + " does not support enforce.");\r
+ }\r
+ \r
+ @Override\r
+ public void generateIterate(PlanContext context, CodeWriter w, long location, int boundMask, Variable[] variables,\r
+ Expression[] expressions) {\r
+ throw new UnsupportedOperationException(getClass().getSimpleName() + " does not support iterate.");\r
+ }\r
}\r
\r
import org.simantics.db.Resource;\r
import org.simantics.scl.compiler.common.names.Name;\r
+import org.simantics.scl.compiler.elaboration.chr.plan.PlanContext;\r
import org.simantics.scl.compiler.elaboration.expressions.EApply;\r
import org.simantics.scl.compiler.elaboration.expressions.EExternalConstant;\r
import org.simantics.scl.compiler.elaboration.expressions.EVariable;\r
import org.simantics.scl.compiler.elaboration.query.compilation.EnforcingContext;\r
import org.simantics.scl.compiler.elaboration.query.compilation.QueryCompilationContext;\r
import org.simantics.scl.compiler.elaboration.relations.SCLRelation;\r
+import org.simantics.scl.compiler.environment.Environment;\r
import org.simantics.scl.compiler.errors.Locations;\r
+import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;\r
import org.simantics.scl.compiler.types.TVar;\r
import org.simantics.scl.compiler.types.Type;\r
import org.simantics.scl.compiler.types.Types;\r
context.iterateList(parameters[1], new EApply(\r
Locations.NO_LOCATION,\r
Types.READ_GRAPH,\r
- context.getTypingContext().getConstant(GET_OBJECTS),\r
+ context.getCompilationContext().getConstant(GET_OBJECTS),\r
new EVariable(parameters[0]),\r
new EExternalConstant(relation, Types.RESOURCE)\r
));\r
context.iterateList(parameters[0], new EApply(\r
Locations.NO_LOCATION,\r
Types.READ_GRAPH,\r
- context.getTypingContext().getConstant(GET_OBJECTS),\r
+ context.getCompilationContext().getConstant(GET_OBJECTS),\r
new EVariable(parameters[1]),\r
new EExternalConstant(inverseRelation, Types.RESOURCE)\r
));\r
? new EApply(\r
Locations.NO_LOCATION,\r
Types.READ_GRAPH,\r
- context.getTypingContext().getConstant(HAS_STATEMENT),\r
+ context.getCompilationContext().getConstant(HAS_STATEMENT),\r
new Expression[] {\r
new EVariable(parameters[0]),\r
new EExternalConstant(relation, Types.RESOURCE),\r
: new EApply(\r
Locations.NO_LOCATION,\r
Types.READ_GRAPH,\r
- context.getTypingContext().getConstant(HAS_STATEMENT),\r
+ context.getCompilationContext().getConstant(HAS_STATEMENT),\r
new Expression[] {\r
new EVariable(parameters[1]),\r
new EExternalConstant(inverseRelation, Types.RESOURCE),\r
return new EApply(\r
Locations.NO_LOCATION,\r
Types.WRITE_GRAPH,\r
- context.getTypingContext().getConstant(CLAIM),\r
+ context.getCompilationContext().getConstant(CLAIM),\r
new EVariable(parameters[0]),\r
new EExternalConstant(relation, Types.RESOURCE),\r
new EVariable(parameters[1])\r
return 0;\r
}\r
\r
+ @Override\r
+ public void generateIterate(PlanContext context, CodeWriter w, long location, int boundMask, Variable[] variables,\r
+ Expression[] expressions) {\r
+ Environment env = context.context.environment;\r
+ switch(boundMask) {\r
+ case BF:\r
+ context.iterateList(location, w, variables[1],\r
+ w.apply(location,\r
+ env.getValue(GET_OBJECTS).getValue(),\r
+ expressions[0].toVal(env, w),\r
+ w.getModuleWriter().getExternalConstant(relation, Types.RESOURCE)));\r
+ break;\r
+ case FB:\r
+ if(inverseRelation == null)\r
+ throw new IllegalArgumentException();\r
+ context.iterateList(location, w, variables[0],\r
+ w.apply(location,\r
+ env.getValue(GET_OBJECTS).getValue(),\r
+ expressions[1].toVal(env, w),\r
+ w.getModuleWriter().getExternalConstant(inverseRelation, Types.RESOURCE)));\r
+ break;\r
+ case BB:\r
+ context.check(location, w, \r
+ inverseRelation == null || relationSelectivity <= inverseRelationSelectivity\r
+ ? w.apply(location, env.getValue(HAS_STATEMENT).getValue(), \r
+ expressions[0].toVal(env, w),\r
+ w.getModuleWriter().getExternalConstant(relation, Types.RESOURCE),\r
+ expressions[1].toVal(env, w))\r
+ : w.apply(location, env.getValue(HAS_STATEMENT).getValue(), \r
+ expressions[1].toVal(env, w),\r
+ w.getModuleWriter().getExternalConstant(inverseRelation, Types.RESOURCE),\r
+ expressions[0].toVal(env, w)));\r
+ break;\r
+ default: throw new IllegalArgumentException();\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public void generateEnforce(PlanContext context, CodeWriter w, long location, Expression[] parameters) {\r
+ Environment env = context.context.environment;\r
+ w.apply(location,\r
+ env.getValue(CLAIM).getValue(),\r
+ parameters[0].toVal(env, w),\r
+ w.getModuleWriter().getExternalConstant(relation, Types.RESOURCE),\r
+ parameters[1].toVal(env, w));\r
+ }\r
}\r
-package org.simantics.modeling.scl;\r
-\r
-\r
-import org.simantics.Simantics;\r
-import org.simantics.db.ReadGraph;\r
-import org.simantics.db.common.request.UnaryRead;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.scl.compiler.module.repository.UpdateListener;\r
-import org.simantics.scl.compiler.source.ModuleSource;\r
-import org.simantics.scl.compiler.source.PrecompiledModuleSource;\r
-import org.simantics.scl.compiler.source.repository.ModuleSourceRepository;\r
-import org.simantics.scl.runtime.SCLContext;\r
-\r
-import gnu.trove.procedure.TObjectProcedure;\r
-\r
-public enum OntologyModuleSourceRepository implements ModuleSourceRepository {\r
- INSTANCE;\r
-\r
- static class ModuleSourceRequest extends UnaryRead<String, ModuleSource> {\r
-\r
- public ModuleSourceRequest(String moduleName) {\r
- super(moduleName);\r
- }\r
-\r
- @Override\r
- public ModuleSource perform(ReadGraph graph) throws DatabaseException {\r
- return new PrecompiledModuleSource(new OntologyModule(graph, parameter), -1.0);\r
- }\r
-\r
- };\r
- \r
- @Override\r
- public ModuleSource getModuleSource(final String moduleName,\r
- UpdateListener listener) {\r
- if(!moduleName.startsWith("http://"))\r
- return null; // Don't do a graph request if this cannot be a resource\r
- \r
- ReadGraph graph = (ReadGraph)SCLContext.getCurrent().get("graph");\r
- \r
- try {\r
- if(graph != null) {\r
- return new PrecompiledModuleSource(new OntologyModule(graph, moduleName), -1.0);\r
- }\r
-\r
- return Simantics.getSession().syncRequest(new ModuleSourceRequest(moduleName));\r
- } catch(DatabaseException e) {\r
- e.printStackTrace();\r
- return null;\r
- }\r
- }\r
-\r
- @Override\r
- public void forAllModules(TObjectProcedure<String> procedure) {\r
- }\r
- \r
- @Override\r
- public void checkUpdates() {\r
- }\r
-\r
- @Override\r
- public String getDocumentation(String documentationName) {\r
- return null;\r
- }\r
-\r
- @Override\r
- public void forAllDocumentations(TObjectProcedure<String> procedure) {\r
- }\r
-\r
- @Override\r
- public void clear() {\r
- }\r
-\r
-}\r
+package org.simantics.modeling.scl;
+
+
+import java.util.Collection;
+import java.util.Collections;
+
+import org.simantics.Simantics;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.common.request.UnaryRead;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.scl.compiler.module.repository.UpdateListener;
+import org.simantics.scl.compiler.source.ModuleSource;
+import org.simantics.scl.compiler.source.PrecompiledModuleSource;
+import org.simantics.scl.compiler.source.repository.ModuleSourceRepository;
+import org.simantics.scl.runtime.SCLContext;
+
+import gnu.trove.procedure.TObjectProcedure;
+
+public enum OntologyModuleSourceRepository implements ModuleSourceRepository {
+ INSTANCE;
+
+ static class ModuleSourceRequest extends UnaryRead<String, ModuleSource> {
+
+ public ModuleSourceRequest(String moduleName) {
+ super(moduleName);
+ }
+
+ @Override
+ public ModuleSource perform(ReadGraph graph) throws DatabaseException {
+ return new PrecompiledModuleSource(new OntologyModule(graph, parameter), -1.0);
+ }
+
+ };
+
+ @Override
+ public ModuleSource getModuleSource(final String moduleName,
+ UpdateListener listener) {
+ if(!moduleName.startsWith("http://"))
+ return null; // Don't do a graph request if this cannot be a resource
+
+ ReadGraph graph = (ReadGraph)SCLContext.getCurrent().get("graph");
+
+ try {
+ if(graph != null) {
+ return new PrecompiledModuleSource(new OntologyModule(graph, moduleName), -1.0);
+ }
+
+ return Simantics.getSession().syncRequest(new ModuleSourceRequest(moduleName));
+ } catch(DatabaseException e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ @Override
+ public void forAllModules(TObjectProcedure<String> procedure) {
+ }
+
+ @Override
+ public Collection<String> getModuleNames() {
+ return Collections.emptyList();
+ }
+
+}
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>\r
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>\r
<classpathentry kind="src" path="src"/>\r
- <classpathentry kind="src" path="tests"/>\r
- <classpathentry exported="true" kind="lib" path="tools/procyon-decompiler-0.5.29.jar"/>\r
<classpathentry kind="output" path="bin"/>\r
</classpath>\r
+++ /dev/null
-eclipse.preferences.version=1\r
-encoding//tests/org/simantics/scl/compiler/tests/scl/InvalidEncoding.scl=ISO-8859-1\r
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>\r
-<launchConfiguration type="org.eclipse.jdt.junit.launchconfig">\r
-<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">\r
-<listEntry value="/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/ActiveTests.java"/>\r
-</listAttribute>\r
-<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">\r
-<listEntry value="1"/>\r
-</listAttribute>\r
-<stringAttribute key="org.eclipse.jdt.junit.CONTAINER" value=""/>\r
-<booleanAttribute key="org.eclipse.jdt.junit.KEEPRUNNING_ATTR" value="false"/>\r
-<stringAttribute key="org.eclipse.jdt.junit.TESTNAME" value=""/>\r
-<stringAttribute key="org.eclipse.jdt.junit.TEST_KIND" value="org.eclipse.jdt.junit.loader.junit4"/>\r
-<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="org.simantics.scl.compiler.tests.ActiveTests"/>\r
-<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="org.simantics.scl.compiler"/>\r
-<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-XX:-UseSplitVerifier"/>\r
-</launchConfiguration>\r
Bundle-ManifestVersion: 2
Bundle-Name: SCL Compiler
Bundle-SymbolicName: org.simantics.scl.compiler
-Bundle-Version: 0.5.0.qualifier
+Bundle-Version: 0.6.1.qualifier
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Require-Bundle: gnu.trove3;bundle-version="3.0.0",
org.simantics.scl.runtime;bundle-version="0.1.4";visibility:=reexport,
org.junit;bundle-version="4.12.0";resolution:=optional,
org.objectweb.asm;bundle-version="[5.0.0,6.0.0)",
org.objectweb.asm.commons;bundle-version="[5.0.0,6.0.0)",
- org.objectweb.asm.util;bundle-version="[5.0.0,6.0.0)"
+ org.objectweb.asm.util;bundle-version="[5.0.0,6.0.0)",
+ org.slf4j.api;bundle-version="1.7.2"
Export-Package: org.cojen.classfile,
org.simantics.scl.compiler.commands,
org.simantics.scl.compiler.common.datatypes,
org.simantics.scl.compiler.compilation,
org.simantics.scl.compiler.constants,
org.simantics.scl.compiler.constants.generic,
+ org.simantics.scl.compiler.elaboration.chr,
+ org.simantics.scl.compiler.elaboration.chr.plan,
+ org.simantics.scl.compiler.elaboration.chr.planning,
+ org.simantics.scl.compiler.elaboration.chr.relations;x-friends:="org.simantics.scl.compiler.tests",
org.simantics.scl.compiler.elaboration.contexts,
org.simantics.scl.compiler.elaboration.equation,
org.simantics.scl.compiler.elaboration.errors,
org.simantics.scl.compiler.environment.filter,
org.simantics.scl.compiler.environment.specification,
org.simantics.scl.compiler.errors,
+ org.simantics.scl.compiler.internal.codegen.chr;x-friends:="org.simantics.scl.compiler.tests",
+ org.simantics.scl.compiler.internal.codegen.references,
+ org.simantics.scl.compiler.internal.codegen.types;x-friends:="org.simantics.scl.compiler.tests",
+ org.simantics.scl.compiler.internal.codegen.utils;x-friends:="org.simantics.scl.compiler.tests",
+ org.simantics.scl.compiler.internal.codegen.writer,
org.simantics.scl.compiler.internal.elaboration.constraints2,
org.simantics.scl.compiler.internal.elaboration.subsumption,
org.simantics.scl.compiler.internal.parsing,
org.simantics.scl.compiler.types.exceptions,
org.simantics.scl.compiler.types.kinds,
org.simantics.scl.compiler.types.util
-Bundle-ClassPath: tools/procyon-decompiler-0.5.29.jar,
- .
+Bundle-ClassPath: .
Service-Component: OSGI-INF/org.simantics.scl.compiler.source.repository.BuiltinModuleSourceRepository.xml
Import-Package: org.osgi.service.component.annotations
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>\r
-<launchConfiguration type="org.eclipse.jdt.junit.launchconfig">\r
-<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">\r
-<listEntry value="/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/RegressionTests.java"/>\r
-</listAttribute>\r
-<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">\r
-<listEntry value="1"/>\r
-</listAttribute>\r
-<stringAttribute key="org.eclipse.jdt.junit.CONTAINER" value=""/>\r
-<booleanAttribute key="org.eclipse.jdt.junit.KEEPRUNNING_ATTR" value="false"/>\r
-<stringAttribute key="org.eclipse.jdt.junit.TESTNAME" value=""/>\r
-<stringAttribute key="org.eclipse.jdt.junit.TEST_KIND" value="org.eclipse.jdt.junit.loader.junit4"/>\r
-<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="org.simantics.scl.compiler.tests.RegressionTests"/>\r
-<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="org.simantics.scl.compiler"/>\r
-</launchConfiguration>\r
output.. = bin/\r
bin.includes = META-INF/,\\r
.,\\r
- tools/procyon-decompiler-0.5.29.jar,\\r
OSGI-INF/org.simantics.scl.compiler.source.repository.BuiltinModuleSourceRepository.xml\r
package org.cojen.classfile;
-import java.io.Serializable;
import java.lang.ref.SoftReference;
import java.lang.reflect.Array;
import java.util.Collections;
* @author Brian S O'Neill
*/
@SuppressWarnings("rawtypes")
-public abstract class TypeDesc extends Descriptor implements Serializable {
+public abstract class TypeDesc extends Descriptor {
/**
* Type code returned from getTypeCode, which can be used with the
* newarray instruction.
+++ /dev/null
-/*
- * Copyright 2004-2010 Brian S O'Neill
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.cojen.util;
-
-import java.util.Arrays;
-
-/**
- * KeyFactory generates keys which can be hashed or compared for any kind of
- * object including arrays, arrays of arrays, and null. All hashcode
- * computations, equality tests, and ordering comparsisons fully recurse into
- * arrays.
- *
- * @author Brian S O'Neill
- */
-@SuppressWarnings({ "rawtypes", "unused", "unchecked", "serial" })
-public class KeyFactory {
- static final Object NULL = new Comparable() {
- public int compareTo(Object obj) {
- return obj == this || obj == null ? 0 : 1;
- }
- };
-
- public static Object createKey(boolean[] obj) {
- return obj == null ? NULL : new BooleanArrayKey(obj);
- }
-
- public static Object createKey(byte[] obj) {
- return obj == null ? NULL : new ByteArrayKey(obj);
- }
-
- public static Object createKey(char[] obj) {
- return obj == null ? NULL : new CharArrayKey(obj);
- }
-
- public static Object createKey(double[] obj) {
- return obj == null ? NULL : new DoubleArrayKey(obj);
- }
-
- public static Object createKey(float[] obj) {
- return obj == null ? NULL : new FloatArrayKey(obj);
- }
-
- public static Object createKey(int[] obj) {
- return obj == null ? NULL : new IntArrayKey(obj);
- }
-
- public static Object createKey(long[] obj) {
- return obj == null ? NULL : new LongArrayKey(obj);
- }
-
- public static Object createKey(short[] obj) {
- return obj == null ? NULL : new ShortArrayKey(obj);
- }
-
- public static Object createKey(Object[] obj) {
- return obj == null ? NULL : new ObjectArrayKey(obj);
- }
-
- public static Object createKey(Object obj) {
- if (obj == null) {
- return NULL;
- }
- if (!obj.getClass().isArray()) {
- return obj;
- }
- if (obj instanceof Object[]) {
- return createKey((Object[])obj);
- } else if (obj instanceof int[]) {
- return createKey((int[])obj);
- } else if (obj instanceof float[]) {
- return createKey((float[])obj);
- } else if (obj instanceof long[]) {
- return createKey((long[])obj);
- } else if (obj instanceof double[]) {
- return createKey((double[])obj);
- } else if (obj instanceof byte[]) {
- return createKey((byte[])obj);
- } else if (obj instanceof char[]) {
- return createKey((char[])obj);
- } else if (obj instanceof boolean[]) {
- return createKey((boolean[])obj);
- } else if (obj instanceof short[]) {
- return createKey((short[])obj);
- } else {
- return obj;
- }
- }
-
- static int hashCode(boolean[] a) {
- int hash = 0;
- for (int i = a.length; --i >= 0; ) {
- hash = (hash << 1) + (a[i] ? 0 : 1);
- }
- return hash == 0 ? -1 : hash;
- }
-
- static int hashCode(byte[] a) {
- int hash = 0;
- for (int i = a.length; --i >= 0; ) {
- hash = (hash << 1) + a[i];
- }
- return hash == 0 ? -1 : hash;
- }
-
- static int hashCode(char[] a) {
- int hash = 0;
- for (int i = a.length; --i >= 0; ) {
- hash = (hash << 1) + a[i];
- }
- return hash == 0 ? -1 : hash;
- }
-
- static int hashCode(double[] a) {
- int hash = 0;
- for (int i = a.length; --i >= 0; ) {
- long v = Double.doubleToLongBits(a[i]);
- hash = hash * 31 + (int)(v ^ v >>> 32);
- }
- return hash == 0 ? -1 : hash;
- }
-
- static int hashCode(float[] a) {
- int hash = 0;
- for (int i = a.length; --i >= 0; ) {
- hash = hash * 31 + Float.floatToIntBits(a[i]);
- }
- return hash == 0 ? -1 : hash;
- }
-
- static int hashCode(int[] a) {
- int hash = 0;
- for (int i = a.length; --i >= 0; ) {
- hash = (hash << 1) + a[i];
- }
- return hash == 0 ? -1 : hash;
- }
-
- static int hashCode(long[] a) {
- int hash = 0;
- for (int i = a.length; --i >= 0; ) {
- long v = a[i];
- hash = hash * 31 + (int)(v ^ v >>> 32);
- }
- return hash == 0 ? -1 : hash;
- }
-
- static int hashCode(short[] a) {
- int hash = 0;
- for (int i = a.length; --i >= 0; ) {
- hash = (hash << 1) + a[i];
- }
- return hash == 0 ? -1 : hash;
- }
-
- static int hashCode(Object[] a) {
- int hash = 0;
- for (int i = a.length; --i >= 0; ) {
- hash = hash * 31 + hashCode(a[i]);
- }
- return hash == 0 ? -1 : hash;
- }
-
- // Compute object or array hashcode and recurses into arrays within.
- static int hashCode(Object a) {
- if (a == null) {
- return -1;
- }
- if (!a.getClass().isArray()) {
- return a.hashCode();
- }
- if (a instanceof Object[]) {
- return hashCode((Object[])a);
- } else if (a instanceof int[]) {
- return hashCode((int[])a);
- } else if (a instanceof float[]) {
- return hashCode((float[])a);
- } else if (a instanceof long[]) {
- return hashCode((long[])a);
- } else if (a instanceof double[]) {
- return hashCode((double[])a);
- } else if (a instanceof byte[]) {
- return hashCode((byte[])a);
- } else if (a instanceof char[]) {
- return hashCode((char[])a);
- } else if (a instanceof boolean[]) {
- return hashCode((boolean[])a);
- } else if (a instanceof short[]) {
- return hashCode((short[])a);
- } else {
- int hash = a.getClass().hashCode();
- return hash == 0 ? -1 : hash;
- }
- }
-
- // Compares object arrays and recurses into arrays within.
- static boolean equals(Object[] a, Object[] b) {
- if (a == b) {
- return true;
- }
- if (a == null || b == null) {
- return false;
- }
- int i;
- if ((i = a.length) != b.length) {
- return false;
- }
- while (--i >= 0) {
- if (!equals(a[i], b[i])) {
- return false;
- }
- }
- return true;
- }
-
- // Compares objects or arrays and recurses into arrays within.
- static boolean equals(Object a, Object b) {
- if (a == b) {
- return true;
- }
- if (a == null || b == null) {
- return false;
- }
- Class ac = a.getClass();
- if (!(ac.isArray())) {
- return a.equals(b);
- }
- if (ac != b.getClass()) {
- return false;
- }
- if (a instanceof Object[]) {
- return equals((Object[])a, (Object[])b);
- } else if (a instanceof int[]) {
- return Arrays.equals((int[])a, (int[])b);
- } else if (a instanceof float[]) {
- return Arrays.equals((float[])a, (float[])b);
- } else if (a instanceof long[]) {
- return Arrays.equals((long[])a, (long[])b);
- } else if (a instanceof double[]) {
- return Arrays.equals((double[])a, (double[])b);
- } else if (a instanceof byte[]) {
- return Arrays.equals((byte[])a, (byte[])b);
- } else if (a instanceof char[]) {
- return Arrays.equals((char[])a, (char[])b);
- } else if (a instanceof boolean[]) {
- return Arrays.equals((boolean[])a, (boolean[])b);
- } else if (a instanceof short[]) {
- return Arrays.equals((short[])a, (short[])b);
- } else {
- return a.equals(b);
- }
- }
-
- static int compare(boolean[] a, boolean[] b) {
- if (a == b) {
- return 0;
- }
- if (a == null) {
- return 1;
- }
- if (b == null) {
- return -1;
- }
- int length = Math.min(a.length, b.length);
- for (int i=0; i<length; i++) {
- int av = a[i] ? 0 : 1;
- int bv = b[i] ? 0 : 1;
- return av < bv ? -1 : (av > bv ? 1 : 0);
- }
- return a.length < b.length ? -1 : (a.length > b.length ? 1 : 0);
- }
-
- static int compare(byte[] a, byte[] b) {
- if (a == b) {
- return 0;
- }
- if (a == null) {
- return 1;
- }
- if (b == null) {
- return -1;
- }
- int length = Math.min(a.length, b.length);
- for (int i=0; i<length; i++) {
- byte av = a[i];
- byte bv = b[i];
- return av < bv ? -1 : (av > bv ? 1 : 0);
- }
- return a.length < b.length ? -1 : (a.length > b.length ? 1 : 0);
- }
-
- static int compare(char[] a, char[] b) {
- if (a == b) {
- return 0;
- }
- if (a == null) {
- return 1;
- }
- if (b == null) {
- return -1;
- }
- int length = Math.min(a.length, b.length);
- for (int i=0; i<length; i++) {
- char av = a[i];
- char bv = b[i];
- return av < bv ? -1 : (av > bv ? 1 : 0);
- }
- return a.length < b.length ? -1 : (a.length > b.length ? 1 : 0);
- }
-
- static int compare(double[] a, double[] b) {
- if (a == b) {
- return 0;
- }
- if (a == null) {
- return 1;
- }
- if (b == null) {
- return -1;
- }
- int length = Math.min(a.length, b.length);
- for (int i=0; i<length; i++) {
- int v = Double.compare(a[i], b[i]);
- if (v != 0) {
- return v;
- }
- }
- return a.length < b.length ? -1 : (a.length > b.length ? 1 : 0);
- }
-
- static int compare(float[] a, float[] b) {
- if (a == b) {
- return 0;
- }
- if (a == null) {
- return 1;
- }
- if (b == null) {
- return -1;
- }
- int length = Math.min(a.length, b.length);
- for (int i=0; i<length; i++) {
- int v = Float.compare(a[i], b[i]);
- if (v != 0) {
- return v;
- }
- }
- return a.length < b.length ? -1 : (a.length > b.length ? 1 : 0);
- }
-
- static int compare(int[] a, int[] b) {
- if (a == b) {
- return 0;
- }
- if (a == null) {
- return 1;
- }
- if (b == null) {
- return -1;
- }
- int length = Math.min(a.length, b.length);
- for (int i=0; i<length; i++) {
- int av = a[i];
- int bv = b[i];
- return av < bv ? -1 : (av > bv ? 1 : 0);
- }
- return a.length < b.length ? -1 : (a.length > b.length ? 1 : 0);
- }
-
- static int compare(long[] a, long[] b) {
- if (a == b) {
- return 0;
- }
- if (a == null) {
- return 1;
- }
- if (b == null) {
- return -1;
- }
- int length = Math.min(a.length, b.length);
- for (int i=0; i<length; i++) {
- long av = a[i];
- long bv = b[i];
- return av < bv ? -1 : (av > bv ? 1 : 0);
- }
- return a.length < b.length ? -1 : (a.length > b.length ? 1 : 0);
- }
-
- static int compare(short[] a, short[] b) {
- if (a == b) {
- return 0;
- }
- if (a == null) {
- return 1;
- }
- if (b == null) {
- return -1;
- }
- int length = Math.min(a.length, b.length);
- for (int i=0; i<length; i++) {
- short av = a[i];
- short bv = b[i];
- return av < bv ? -1 : (av > bv ? 1 : 0);
- }
- return a.length < b.length ? -1 : (a.length > b.length ? 1 : 0);
- }
-
- // Compares object arrays and recurses into arrays within.
- static int compare(Object[] a, Object[] b) {
- if (a == b) {
- return 0;
- }
- if (a == null) {
- return 1;
- }
- if (b == null) {
- return -1;
- }
- int length = Math.min(a.length, b.length);
- for (int i=0; i<length; i++) {
- int v = compare(a[i], b[i]);
- if (v != 0) {
- return v;
- }
- }
- return a.length < b.length ? -1 : (a.length > b.length ? 1 : 0);
- }
-
- // Compares objects or arrays and recurses into arrays within.
- static int compare(Object a, Object b) {
- if (a == b) {
- return 0;
- }
- if (a == null) {
- return 1;
- }
- if (b == null) {
- return -1;
- }
- Class ac = a.getClass();
- if (!(ac.isArray())) {
- return ((Comparable)a).compareTo(b);
- }
- if (ac != b.getClass()) {
- throw new ClassCastException();
- }
- if (a instanceof Object[]) {
- return compare((Object[])a, (Object[])b);
- } else if (a instanceof int[]) {
- return compare((int[])a, (int[])b);
- } else if (a instanceof float[]) {
- return compare((float[])a, (float[])b);
- } else if (a instanceof long[]) {
- return compare((long[])a, (long[])b);
- } else if (a instanceof double[]) {
- return compare((double[])a, (double[])b);
- } else if (a instanceof byte[]) {
- return compare((byte[])a, (byte[])b);
- } else if (a instanceof char[]) {
- return compare((char[])a, (char[])b);
- } else if (a instanceof boolean[]) {
- return compare((boolean[])a, (boolean[])b);
- } else if (a instanceof short[]) {
- return compare((short[])a, (short[])b);
- } else {
- throw new ClassCastException();
- }
- }
-
- protected KeyFactory() {
- }
-
- private static interface ArrayKey extends Comparable, java.io.Serializable {
- int hashCode();
-
- boolean equals(Object obj);
-
- int compareTo(Object obj);
- }
-
- private static class BooleanArrayKey implements ArrayKey {
- protected final boolean[] mArray;
- private transient int mHash;
-
- BooleanArrayKey(boolean[] array) {
- mArray = array;
- }
-
- public int hashCode() {
- int hash = mHash;
- return hash == 0 ? mHash = KeyFactory.hashCode(mArray) : hash;
- }
-
- public boolean equals(Object obj) {
- return this == obj ? true :
- (obj instanceof BooleanArrayKey ?
- Arrays.equals(mArray, ((BooleanArrayKey) obj).mArray) : false);
- }
-
- public int compareTo(Object obj) {
- return compare(mArray, ((BooleanArrayKey) obj).mArray);
- }
- }
-
- private static class ByteArrayKey implements ArrayKey {
- protected final byte[] mArray;
- private transient int mHash;
-
- ByteArrayKey(byte[] array) {
- mArray = array;
- }
-
- public int hashCode() {
- int hash = mHash;
- return hash == 0 ? mHash = KeyFactory.hashCode(mArray) : hash;
- }
-
- public boolean equals(Object obj) {
- return this == obj ? true :
- (obj instanceof ByteArrayKey ?
- Arrays.equals(mArray, ((ByteArrayKey) obj).mArray) : false);
- }
-
- public int compareTo(Object obj) {
- return compare(mArray, ((ByteArrayKey) obj).mArray);
- }
- }
-
- private static class CharArrayKey implements ArrayKey {
- protected final char[] mArray;
- private transient int mHash;
-
- CharArrayKey(char[] array) {
- mArray = array;
- }
-
- public int hashCode() {
- int hash = mHash;
- return hash == 0 ? mHash = KeyFactory.hashCode(mArray) : hash;
- }
-
- public boolean equals(Object obj) {
- return this == obj ? true :
- (obj instanceof CharArrayKey ?
- Arrays.equals(mArray, ((CharArrayKey) obj).mArray) : false);
- }
-
- public int compareTo(Object obj) {
- return compare(mArray, ((CharArrayKey) obj).mArray);
- }
- }
-
- private static class DoubleArrayKey implements ArrayKey {
- protected final double[] mArray;
- private transient int mHash;
-
- DoubleArrayKey(double[] array) {
- mArray = array;
- }
-
- public int hashCode() {
- int hash = mHash;
- return hash == 0 ? mHash = KeyFactory.hashCode(mArray) : hash;
- }
-
- public boolean equals(Object obj) {
- return this == obj ? true :
- (obj instanceof DoubleArrayKey ?
- Arrays.equals(mArray, ((DoubleArrayKey) obj).mArray) : false);
- }
-
- public int compareTo(Object obj) {
- return compare(mArray, ((DoubleArrayKey) obj).mArray);
- }
- }
-
- private static class FloatArrayKey implements ArrayKey {
- protected final float[] mArray;
- private transient int mHash;
-
- FloatArrayKey(float[] array) {
- mArray = array;
- }
-
- public int hashCode() {
- int hash = mHash;
- return hash == 0 ? mHash = KeyFactory.hashCode(mArray) : hash;
- }
-
- public boolean equals(Object obj) {
- return this == obj ? true :
- (obj instanceof FloatArrayKey ?
- Arrays.equals(mArray, ((FloatArrayKey) obj).mArray) : false);
- }
-
- public int compareTo(Object obj) {
- return compare(mArray, ((FloatArrayKey) obj).mArray);
- }
- }
-
- private static class IntArrayKey implements ArrayKey {
- protected final int[] mArray;
- private transient int mHash;
-
- IntArrayKey(int[] array) {
- mArray = array;
- }
-
- public int hashCode() {
- int hash = mHash;
- return hash == 0 ? mHash = KeyFactory.hashCode(mArray) : hash;
- }
-
- public boolean equals(Object obj) {
- return this == obj ? true :
- (obj instanceof IntArrayKey ?
- Arrays.equals(mArray, ((IntArrayKey) obj).mArray) : false);
- }
-
- public int compareTo(Object obj) {
- return compare(mArray, ((IntArrayKey) obj).mArray);
- }
- }
-
- private static class LongArrayKey implements ArrayKey {
- protected final long[] mArray;
- private transient int mHash;
-
- LongArrayKey(long[] array) {
- mArray = array;
- }
-
- public int hashCode() {
- int hash = mHash;
- return hash == 0 ? mHash = KeyFactory.hashCode(mArray) : hash;
- }
-
- public boolean equals(Object obj) {
- return this == obj ? true :
- (obj instanceof LongArrayKey ?
- Arrays.equals(mArray, ((LongArrayKey) obj).mArray) : false);
- }
-
- public int compareTo(Object obj) {
- return compare(mArray, ((LongArrayKey) obj).mArray);
- }
- }
-
- private static class ShortArrayKey implements ArrayKey {
- protected final short[] mArray;
- private transient int mHash;
-
- ShortArrayKey(short[] array) {
- mArray = array;
- }
-
- public int hashCode() {
- int hash = mHash;
- return hash == 0 ? mHash = KeyFactory.hashCode(mArray) : hash;
- }
-
- public boolean equals(Object obj) {
- return this == obj ? true :
- (obj instanceof ShortArrayKey ?
- Arrays.equals(mArray, ((ShortArrayKey) obj).mArray) : false);
- }
-
- public int compareTo(Object obj) {
- return compare(mArray, ((ShortArrayKey) obj).mArray);
- }
- }
-
- private static class ObjectArrayKey implements ArrayKey {
- protected final Object[] mArray;
- private transient int mHash;
-
- ObjectArrayKey(Object[] array) {
- mArray = array;
- }
-
- public int hashCode() {
- int hash = mHash;
- return hash == 0 ? mHash = KeyFactory.hashCode(mArray) : hash;
- }
-
- public boolean equals(Object obj) {
- return this == obj ? true :
- (obj instanceof ObjectArrayKey ?
- KeyFactory.equals(mArray, ((ObjectArrayKey) obj).mArray) : false);
- }
-
- public int compareTo(Object obj) {
- return compare(mArray, ((ObjectArrayKey) obj).mArray);
- }
- }
-}
public abstract class ReferencedValueHashMap<K, V> extends AbstractMap<K, V>
implements Map<K, V>, Cloneable
{
+ static final Object NULL = new Comparable() {
+ public int compareTo(Object obj) {
+ return obj == this || obj == null ? 0 : 1;
+ }
+ };
+
private transient Entry<K, V>[] table;
private transient int count;
private int threshold;
public boolean containsValue(Object value) {
if (value == null) {
- value = KeyFactory.NULL;
+ value = NULL;
}
Entry[] tab = this.table;
}
count--;
} else if (e.hash == hash && key.equals(e.key)) {
- return (entryValue == KeyFactory.NULL) ? null : entryValue;
+ return (entryValue == NULL) ? null : entryValue;
} else {
prev = e;
}
}
this.count--;
} else if (e.key == null) {
- return (entryValue == KeyFactory.NULL) ? null : entryValue;
+ return (entryValue == NULL) ? null : entryValue;
} else {
prev = e;
}
public V put(K key, V value) {
if (value == null) {
- value = (V) KeyFactory.NULL;
+ value = (V) NULL;
}
// Makes sure the key is not already in the HashMap.
this.count--;
} else if (e.hash == hash && key.equals(e.key)) {
e.setValue(value);
- return (entryValue == KeyFactory.NULL) ? null : entryValue;
+ return (entryValue == NULL) ? null : entryValue;
} else {
prev = e;
}
this.count--;
} else if (e.key == null) {
e.setValue(value);
- return (entryValue == KeyFactory.NULL) ? null : entryValue;
+ return (entryValue == NULL) ? null : entryValue;
} else {
prev = e;
}
this.count--;
e.setValue(null);
- return (entryValue == KeyFactory.NULL) ? null : entryValue;
+ return (entryValue == NULL) ? null : entryValue;
} else {
prev = e;
}
this.count--;
e.setValue(null);
- return (entryValue == KeyFactory.NULL) ? null : entryValue;
+ return (entryValue == NULL) ? null : entryValue;
} else {
prev = e;
}
public V getValue() {
V value = this.value.get();
- return value == KeyFactory.NULL ? null : value;
+ return value == NULL ? null : value;
}
public V setValue(V value) {
V oldValue = getValue();
- this.value = newReference(value == null ? ((V) KeyFactory.NULL) : value);
+ this.value = newReference(value == null ? ((V) NULL) : value);
return oldValue;
}
Object thisValue = get();
if (thisValue == null) {
return false;
- } else if (thisValue == KeyFactory.NULL) {
+ } else if (thisValue == NULL) {
thisValue = null;
}
return (this.key == null ? e.getKey() == null : this.key.equals(e.getKey())) &&
public boolean containsKey(Object key) {
if (key == null) {
- key = KeyFactory.NULL;
+ key = ReferencedValueHashMap.NULL;
}
Entry[] tab = this.table;
public V get(Object key) {
if (key == null) {
- key = KeyFactory.NULL;
+ key = ReferencedValueHashMap.NULL;
}
Entry<K, V>[] tab = this.table;
public V put(K key, V value) {
if (key == null) {
- key = (K) KeyFactory.NULL;
+ key = (K) ReferencedValueHashMap.NULL;
}
cleanup();
public V remove(Object key) {
if (key == null) {
- key = KeyFactory.NULL;
+ key = ReferencedValueHashMap.NULL;
}
Entry<K, V>[] tab = this.table;
public K getKey() {
K key = Entry.this.get();
- return key == KeyFactory.NULL ? null : key;
+ return key == ReferencedValueHashMap.NULL ? null : key;
}
public V getValue() {
Object thisKey = get();
if (thisKey == null) {
return false;
- } else if (thisKey == KeyFactory.NULL) {
+ } else if (thisKey == ReferencedValueHashMap.NULL) {
thisKey = null;
}
return (thisKey == e.getKey()) &&
import java.util.Map;
import java.util.Set;
-import org.simantics.scl.compiler.common.names.Name;
+import org.simantics.scl.compiler.common.names.Names;
import org.simantics.scl.compiler.constants.StringConstant;
import org.simantics.scl.compiler.elaboration.expressions.EApply;
import org.simantics.scl.compiler.elaboration.expressions.EBlock;
import org.simantics.scl.compiler.top.ExpressionEvaluator;
import org.simantics.scl.compiler.top.LocalStorage;
import org.simantics.scl.compiler.top.SCLExpressionCompilationException;
-import org.simantics.scl.compiler.types.TCon;
import org.simantics.scl.compiler.types.Type;
import org.simantics.scl.compiler.types.Types;
import org.simantics.scl.runtime.SCLContext;
PrintStream fileOutput;
- private static final String CONTEXT_MODULE = "Expressions/Context";
- private static final TCon CONTEXT_TYPE = Types.con(CONTEXT_MODULE, "Context");
- private static final Name CONTEXT_GET = Name.create(CONTEXT_MODULE, "contextGet");
-
public CommandSession(ModuleRepository moduleRepository, SCLReportingHandler handler) {
this.moduleRepository = moduleRepository;
this.defaultHandler = new PrintDecorator(
}, Types.functionE(Types.STRING, Types.PROC, Types.UNIT)));
LOCAL_FUNCTIONS.put("reset", new LocalFunction(new FunctionImpl2<CommandSession, Tuple0, Tuple0>() {
@Override
- public Tuple0 apply(CommandSession commandSession, Tuple0 _) {
+ public Tuple0 apply(CommandSession commandSession, Tuple0 dummy) {
commandSession.removeTransientImports();
commandSession.removeVariables();
commandSession.moduleRepository.getSourceRepository().checkUpdates();
}, Types.functionE(Types.UNIT, Types.PROC, Types.UNIT)));
LOCAL_FUNCTIONS.put("variables", new LocalFunction(new FunctionImpl2<CommandSession, Tuple0, List<String>>() {
@Override
- public List<String> apply(CommandSession commandSession, Tuple0 _) {
+ public List<String> apply(CommandSession commandSession, Tuple0 dummy) {
ArrayList<String> result = new ArrayList<String>(commandSession.variableTypes.keySet());
Collections.sort(result);
return result;
}, Types.functionE(Types.STRING, Types.PROC, Types.UNIT)));
LOCAL_FUNCTIONS.put("stopPrintingToFile", new LocalFunction(new FunctionImpl2<CommandSession, Tuple0, Tuple0>() {
@Override
- public Tuple0 apply(final CommandSession commandSession, Tuple0 _) {
+ public Tuple0 apply(final CommandSession commandSession, Tuple0 dummy) {
if(commandSession.fileOutput != null) {
commandSession.fileOutput.close();
commandSession.fileOutput = null;
private LocalEnvironment createLocalEnvironment() {
return new AbstractLocalEnvironment() {
- Variable contextVariable = new Variable("context", CONTEXT_TYPE);
+ Variable contextVariable = new Variable("context", Names.Expressions_Context_Context);
@Override
public Expression resolve(Environment environment, String localName) {
Type type = variableTypes.get(localName);
if(type != null)
return new EApply(
- new EConstant(environment.getValue(CONTEXT_GET), type),
+ new EConstant(environment.getValue(Names.Expressions_Context_contextGet), type),
new EVariable(contextVariable),
new ELiteral(new StringConstant(localName))
);
--- /dev/null
+package org.simantics.scl.compiler.common.names;\r
+\r
+import org.simantics.scl.compiler.types.TCon;\r
+import org.simantics.scl.compiler.types.Type;\r
+import org.simantics.scl.compiler.types.Types;\r
+\r
+public class Names {\r
+ \r
+ public static final Name ArrayList_add = Name.create("ArrayList", "add");\r
+ public static final Name ArrayList_freeze = Name.create("ArrayList", "freeze");\r
+ public static final Name ArrayList_new = Name.create("ArrayList", "new");\r
+ public static final Name Builtin_equals = Name.create(Types.BUILTIN, "==");\r
+ public static final Name Builtin_fail = Name.create(Types.BUILTIN, "fail");\r
+ public static final Name Builtin_runProc = Name.create(Types.BUILTIN, "runProc");\r
+ public static final Name Data_XML_createElement = Name.create("Data/XML", "createElement");\r
+ public static final Type Data_XML_Element = Types.con("Data/XML", "Element");\r
+ public static final TCon Expressions_Context_Context = Types.con("Expressions/Context", "Context"); \r
+ public static final Name Expressions_Context_contextGet = Name.create("Expressions/Context", "contextGet");\r
+ public static final Name JavaBuiltin_unsafeCoerce = Name.create("JavaBuiltin", "unsafeCoerce");\r
+ public static final Name MList_add = Name.create("MList", "add");\r
+ public static final Name MList_create = Name.create("MList", "create");\r
+ public static final Name MList_removeLast = Name.create("MList", "removeLast");\r
+ public static final TCon MList_T = Types.con("MList", "T");\r
+ public static final Name MSet_add = Name.create("MSet", "add");\r
+ public static final Name MSet_contains = Name.create("MSet", "contains");\r
+ public static final Name MSet_create = Name.create("MSet", "create");\r
+ public static final Name MSet_iter = Name.create("MSet", "iter");\r
+ public static final Name MSet_mapFirst = Name.create("MSet", "mapFirst");\r
+ public static final TCon MSet_T = Types.con("MSet", "T");\r
+ public static final Name Prelude_addList = Name.create("Prelude", "addList");\r
+ public static final Name Prelude_any = Name.create("Prelude", "any");\r
+ public static final Name Prelude_appendList = Name.create("Prelude", "appendList");\r
+ public static final Name Prelude_bind = Name.create("Prelude", ">>=");\r
+ public static final Name Prelude_build = Name.create("Prelude", "build");\r
+ public static final Name Prelude_concatMap = Name.create("Prelude", "concatMap");\r
+ public static final Name Prelude_elem = Name.create("Prelude", "elem");\r
+ public static final Name Prelude_elemMaybe = Name.create("Prelude", "elemMaybe");\r
+ public static final Name Prelude_emptyList = Name.create("Prelude", "emptyList");\r
+ public static final Name Prelude_foldl = Name.create("Prelude", "foldl");\r
+ public static final Name Prelude_fromDouble = Name.create("Prelude", "fromDouble"); \r
+ public static final Name Prelude_fromInteger = Name.create("Prelude", "fromInteger"); \r
+ public static final Name Prelude_guardList = Name.create("Prelude", "guardList");\r
+ public static final Name Prelude_iterList = Name.create("Prelude", "iterList");\r
+ public static final Name Prelude_mapFirst = Name.create("Prelude", "mapFirst");\r
+ public static final Name Prelude_mapList = Name.create("Prelude", "mapList");\r
+ public static final Name Prelude_neg = Name.create("Prelude", "neg");\r
+ public static final Name Prelude_not = Name.create("Prelude", "not");\r
+ public static final Name Prelude_range = Name.create("Prelude", "range");\r
+ public static final Name Prelude_showForPrinting = Name.create("Prelude", "showForPrinting");\r
+ public static final Name Prelude_singletonList = Name.create("Prelude", "singletonList");\r
+ public static final Name R_R_runR = Name.create("R/R", "runR");\r
+ public static final Name Random_runRandom = Name.create("Random", "runRandom");\r
+ public static final Name Serialization_ioSize = Name.create("Serialization", "ioSize");\r
+ public static final Name Serialization_read = Name.create("Serialization", "read");\r
+ public static final Name Serialization_write = Name.create("Serialization", "write");\r
+ public static final Name Simantics_DB_newResource = Name.create("Simantics/DB", "newResource");\r
+ public static final Name Simantics_DB_syncRead = Name.create("Simantics/DB", "syncRead");\r
+ public static final Name Simantics_DB_syncWrite = Name.create("Simantics/DB", "syncWrite");\r
+ public static final Name Simantics_Variables_child_ = Name.create("Simantics/Variables", "child_");\r
+ public static final Name Simantics_Variables_property = Name.create("Simantics/Variables", "property");\r
+ public static final Name Simantics_Variables_untypedPropertyValue = Name.create("Simantics/Variables", "untypedPropertyValue");\r
+ public static final Name Unifiable_createUMap = Name.create("Unification", "createUMap");\r
+ public static final Name Unifiable_extractWithDefault = Name.create("Unification", "extractWithDefault");\r
+ public static final Name Unifiable_getUMapWithDefault = Name.create("Unification", "getUMapWithDefault");\r
+ public static final Name Unifiable_putUMap = Name.create("Unification", "putUMap");\r
+ public static final Name Unifiable_putUMapC = Name.create("Unification", "putUMapC");\r
+ public static final Name Unifiable_uCons = Name.create("Unification", "uCons");\r
+ public static final Name Unifiable_uId = Name.create("Unification", "uId");\r
+ public static final TCon Unifiable_UMap = Types.con("Unification", "UMap");\r
+ public static final TCon Unifiable_Unifiable = Types.con("Unification", "Unifiable");\r
+ public static final Name Unifiable_uPending = Name.create("Unification", "uPending");\r
+ public static final Name Unifiable_uTag = Name.create("Unification", "uTag");\r
+ public static final TCon Unifiable_UTag = Types.con("Unification", "UTag");\r
+ public static final Name Unifiable_uVar = Name.create("Unification", "uVar");\r
+ public static final Name Vector_anyVector = Name.create("Vector", "anyVector");\r
+ public static final Name Vector_concatMapVector = Name.create("Vector", "concatMapVector");\r
+ public static final Name Vector_iterVector = Name.create("Vector", "iterVector");\r
+ public static final Name Vector_mapFirstVector = Name.create("Vector", "mapFirstVector");\r
+ \r
+}\r
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.environment.Environment;
import org.simantics.scl.compiler.errors.ErrorLog;
import org.simantics.scl.compiler.internal.codegen.references.IVal;
import org.simantics.scl.compiler.internal.codegen.references.Val;
import org.simantics.scl.compiler.internal.codegen.utils.CodeBuilderUtils;
import org.simantics.scl.compiler.internal.codegen.utils.CodeBuildingException;
import org.simantics.scl.compiler.internal.codegen.utils.Constants;
-import org.simantics.scl.compiler.internal.codegen.utils.JavaNamingPolicy;
import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder;
import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilderBase;
import org.simantics.scl.compiler.internal.codegen.utils.ModuleBuilder;
public static final int OPTIMIZATION_PHASES = 2;
+ CompilationContext compilationContext;
ErrorLog errorLog;
- Environment environment;
- JavaNamingPolicy namingPolicy;
- JavaTypeTranslator javaTypeTranslator;
JavaReferenceValidator<Object, Object, Object, Object> validator;
ConcreteModule module;
ModuleBuilder moduleBuilder;
Map<String, byte[]> classes;
@SuppressWarnings("unchecked")
- public CodeGeneration(ErrorLog errorLog,
- Environment environment,
- JavaNamingPolicy namingPolicy, JavaTypeTranslator javaTypeTranslator,
+ public CodeGeneration(CompilationContext compilationContext,
JavaReferenceValidator<?, ?, ?, ?> javaReferenceValidator,
- ConcreteModule module) {
- this.errorLog = errorLog;
- this.environment = environment;
- this.namingPolicy = namingPolicy;
- this.javaTypeTranslator = javaTypeTranslator;
+ ConcreteModule module) {
+ this.compilationContext = compilationContext;
+ this.errorLog = compilationContext.errorLog;
this.module = module;
this.validator = (JavaReferenceValidator<Object, Object, Object, Object>) javaReferenceValidator;
- moduleBuilder = new ModuleBuilder(namingPolicy, javaTypeTranslator);
+ moduleBuilder = new ModuleBuilder(compilationContext.namingPolicy, compilationContext.javaTypeTranslator);
}
public void simplifyValues() {
//System.out.println("===== Simplify values =====");
Collection<SCLValue> values = module.getValues();
- SimplificationContext simplificationContext =
- new SimplificationContext(environment, errorLog,
- javaTypeTranslator, validator);
+ SimplificationContext simplificationContext = new SimplificationContext(compilationContext, validator);
//System.out.println("-----------------------------------------------");
SCLValue[] valueArray = values.toArray(new SCLValue[values.size()]);
}
public void convertToSSA() {
- ModuleWriter mw = new ModuleWriter(namingPolicy.getModuleClassName());
+ ModuleWriter mw = new ModuleWriter(compilationContext.namingPolicy.getModuleClassName());
for(SCLValue value : module.getValues()) {
//System.out.println(value.getName().name + " :: " + value.getType());
Expression expression = value.getExpression();
continue;
Name name = value.getName();
- DecomposedExpression decomposed =
- DecomposedExpression.decompose(expression);
SCLConstant constant = new SCLConstant(name, value.getType());
value.setValue(constant);
IVal[] parameterVals = w.getParameters();
for(int i=0;i<decomposed.parameters.length;++i)
decomposed.parameters[i].setVal(parameterVals[i]);
- w.return_(decomposed.body.toVal(environment, w));
+ w.return_(decomposed.body.toVal(compilationContext.environment, w));
} catch(RuntimeException e) {
errorLog.setExceptionPosition(value.getExpression().location);
throw e;
ssaModule.validate();
int optCount = 0;
for(int phase=0;phase<OPTIMIZATION_PHASES;++phase) {
- while(optCount++ < 100 && ssaModule.simplify(environment, phase)) {
+ while(optCount++ < 100 && ssaModule.simplify(compilationContext.environment, phase)) {
//System.out.println("simplify " + optCount);
//System.out.println("================================================================");
//System.out.println(ssaModule);
cf.setSourceFile("_SCL_DataType");
CodeBuilderUtils.makeRecord(cf, constructor.name.name,
Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL, "c",
- javaTypeTranslator.toTypeDescs(constructor.parameterTypes),
+ compilationContext.javaTypeTranslator.toTypeDescs(constructor.parameterTypes),
true);
moduleBuilder.addClass(cf);
}
cf.setSourceFile("_SCL_DataType");
CodeBuilderUtils.makeRecord(cf, constructor.name.name,
Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL, "c",
- javaTypeTranslator.toTypeDescs(constructor.parameterTypes),
+ compilationContext.javaTypeTranslator.toTypeDescs(constructor.parameterTypes),
true);
moduleBuilder.addClass(cf);
}
MethodImplementation implementation =
instance.methodImplementations.get(method.getName());
if(implementation.isDefault) {
- IVal function = environment.getValue(implementation.name).getValue();
+ IVal function = compilationContext.environment.getValue(implementation.name).getValue();
Val[] parameters = new Val[method.getArity() + 1];
MultiFunction mfun2;
--- /dev/null
+package org.simantics.scl.compiler.compilation;\r
+\r
+import org.simantics.scl.compiler.common.names.Name;\r
+import org.simantics.scl.compiler.elaboration.contexts.EnvironmentalContext;\r
+import org.simantics.scl.compiler.elaboration.expressions.EConstant;\r
+import org.simantics.scl.compiler.elaboration.expressions.EError;\r
+import org.simantics.scl.compiler.elaboration.expressions.Expression;\r
+import org.simantics.scl.compiler.elaboration.modules.SCLValue;\r
+import org.simantics.scl.compiler.environment.Environment;\r
+import org.simantics.scl.compiler.errors.ErrorLog;\r
+import org.simantics.scl.compiler.errors.Locations;\r
+import org.simantics.scl.compiler.internal.codegen.types.JavaTypeTranslator;\r
+import org.simantics.scl.compiler.internal.codegen.utils.JavaNamingPolicy;\r
+import org.simantics.scl.compiler.module.ConcreteModule;\r
+import org.simantics.scl.compiler.types.Type;\r
+\r
+import gnu.trove.map.hash.THashMap;\r
+\r
+public class CompilationContext implements EnvironmentalContext {\r
+ public final ErrorLog errorLog = new ErrorLog();\r
+ public Environment environment;\r
+ public JavaTypeTranslator javaTypeTranslator;\r
+ public JavaNamingPolicy namingPolicy;\r
+ public ConcreteModule module;\r
+ \r
+ private THashMap<Name, SCLValue> valueCache = new THashMap<Name, SCLValue>();\r
+\r
+ public SCLValue getValue(Name name) {\r
+ if(valueCache.containsKey(name))\r
+ return valueCache.get(name);\r
+ SCLValue value = environment.getValue(name);\r
+ if(value == null)\r
+ errorLog.log(Locations.NO_LOCATION, "Couldn't find " + name + ".");\r
+ valueCache.put(name, value);\r
+ return value;\r
+ }\r
+ \r
+ public Expression getConstant(Name name, Type ... typeParameters) {\r
+ SCLValue value = getValue(name);\r
+ if(value == null)\r
+ return new EError(Locations.NO_LOCATION);\r
+ return new EConstant(value, typeParameters);\r
+ }\r
+}\r
ErrorLog errorLog;
- public DeclarationClassification(ErrorLog errorLog) {
- this.errorLog = errorLog;
+ public DeclarationClassification(CompilationContext compilationContext) {
+ this.errorLog = compilationContext.errorLog;
}
public void handle(DeclarationAst declaration) {
import org.simantics.scl.compiler.elaboration.modules.SCLValue;
import org.simantics.scl.compiler.elaboration.modules.TypeClass;
import org.simantics.scl.compiler.elaboration.modules.TypeClassInstance;
-import org.simantics.scl.compiler.elaboration.modules.TypeConstructor;
+import org.simantics.scl.compiler.elaboration.modules.TypeDescriptor;
import org.simantics.scl.compiler.internal.parsing.declarations.DDocumentationAst;
import org.simantics.scl.compiler.module.ConcreteModule;
import org.simantics.scl.compiler.types.TCon;
value.setDocumentation(doc.documentation);
}
for(String name : typeDocumentation.keySet()) {
- TypeConstructor typeConstructor = module.getTypeConstructor(name);
+ TypeDescriptor typeConstructor = module.getTypeDescriptor(name);
DDocumentationAst doc = typeDocumentation.get(name);
if(typeConstructor != null && doc != null)
typeConstructor.setDocumentation(doc.documentation);
import org.simantics.scl.compiler.constants.generic.MethodRef;
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;
public class Elaboration {
// inputs
- ErrorLog errorLog;
- String moduleName;
- ArrayList<ImportDeclaration> importsAst;
- JavaReferenceValidator<Object, Object, Object, Object> javaReferenceValidator;
- ValueRepository valueDefinitionsAst;
- RelationRepository relationDefinitionsAst;
+ private final CompilationContext compilationContext;
+ private final ErrorLog errorLog;
+ private final String moduleName;
+ private final ArrayList<ImportDeclaration> importsAst;
+ final JavaReferenceValidator<Object, Object, Object, Object> javaReferenceValidator;
+ private final ValueRepository valueDefinitionsAst;
+ private final RelationRepository relationDefinitionsAst;
// creates
ConcreteModule module;
Environment importedEnvironment;
- Environment environment;
- JavaNamingPolicy namingPolicy;
ArrayList<SupplementedValueType> supplementedTypeAnnotations = new ArrayList<SupplementedValueType>();
JavaTypeTranslator javaTypeTranslator;
THashMap<String, BranchPoint[]> branchPoints;
@SuppressWarnings("unchecked")
- public Elaboration(ErrorLog errorLog, CompilationTimer timer, EnvironmentFactory localEnvironmentFactory,
+ public Elaboration(CompilationContext compilationContext, CompilationTimer timer, EnvironmentFactory localEnvironmentFactory,
String moduleName, ArrayList<ImportDeclaration> importsAst,
JavaReferenceValidator<?, ?, ?, ?> javaReferenceValidator,
ValueRepository valueDefinitionsAst,
RelationRepository relationDefinitionsAst) {
- this.errorLog = errorLog;
+ this.compilationContext = compilationContext;
+ this.errorLog = compilationContext.errorLog;
this.moduleName = moduleName;
importsAst = processRelativeImports(importsAst);
this.importsAst = importsAst;
this.relationDefinitionsAst = relationDefinitionsAst;
module = new ConcreteModule(moduleName);
+ compilationContext.module = module;
try {
if(timer != null)
timer.suspendTimer();
importsAst.toArray(new ImportDeclaration[importsAst.size()]));
if(timer != null)
timer.continueTimer();
- this.environment = new EnvironmentOfModule(importedEnvironment, module);
+ compilationContext.environment = new EnvironmentOfModule(importedEnvironment, module);
} catch (ImportFailureException e) {
for(ImportFailure failure : e.failures)
errorLog.log(failure.location, failure.toString());
false,
importAst.spec));
localEnvironmentFactory.addBuiltinDependencies(module);
- namingPolicy = new JavaNamingPolicy(moduleName);
+ compilationContext.namingPolicy = new JavaNamingPolicy(moduleName);
}
private ArrayList<ImportDeclaration> processRelativeImports(ArrayList<ImportDeclaration> relativeImports) {
NameExistenceChecks.checkIfTypeExists(errorLog,
dataType.location, importedEnvironment, dataType.name);
- if(module.addTypeConstructor(dataType.name, typeConstructor))
+ if(module.addTypeDescriptor(dataType.name, typeConstructor))
errorLog.log(dataType.location, "Type "+dataType.name+" has already been defined in this module.");
dataType.typeConstructor = typeConstructor;
}
TypeAlias alias = new TypeAlias(Types.con(moduleName, typeAlias.name), typeAlias.parameters.length);
NameExistenceChecks.checkIfTypeExists(errorLog,
typeAlias.location, importedEnvironment, typeAlias.name);
- if(module.addTypeAlias(typeAlias.name, alias)) {
+ if(module.addTypeDescriptor(typeAlias.name, alias)) {
errorLog.log(typeAlias.location, "Type alias "+typeAlias.name+" has already been defined in this module.");
}
}
if(module.addEffectConstructor(effect.name, effectConstructor))
errorLog.log(effect.location, "Type "+effect.name+" has already been defined in this module.");
}
- javaTypeTranslator = new JavaTypeTranslator(environment);
+ javaTypeTranslator = new JavaTypeTranslator(compilationContext.environment);
+ compilationContext.javaTypeTranslator = javaTypeTranslator;
}
private static final int[] EMPTY_INT_ARRAY = new int[0];
if(errorLog.isEmpty()) {
for(DTypeAst typeAlias : orderedTypeAliases) {
- TypeAlias alias = module.getTypeAlias(typeAlias.name);
+ TypeAlias alias = (TypeAlias)module.getTypeDescriptor(typeAlias.name);
TypeTranslationContext context = createTypeTranslationContext();
for(int i=0;i<typeAlias.parameters.length;++i)
context.pushTypeVar(typeAlias.parameters[i]);
boolean trivialDataType = dataTypeAst.constructors.length == 1 &&
dataTypeAst.constructors[0].parameters.length == 1;
if(className == null && !trivialDataType)
- className = namingPolicy.getDataTypeClassName(dataTypeAst.name);
+ className = compilationContext.namingPolicy.getDataTypeClassName(dataTypeAst.name);
StandardTypeConstructor dataType = dataTypeAst.typeConstructor;
for(int i=constructor.parameters.length-1;i>=0;--i)
parameterTypes[i] = context.toType(constructor.parameters[i]);
String javaName = constructors.length == 1 ? className
- : namingPolicy.getConstructorClassName(name);
+ : compilationContext.namingPolicy.getConstructorClassName(name);
String[] fieldNames = null;
for(DAnnotationAst annotation : constructor.annotations)
if(annotation.id.text.equals("@JavaType")) {
TypeClass typeClass = new TypeClass(classAst.location,
classContext,
con,
- namingPolicy.getTypeClassInterfaceName(con),
+ compilationContext.namingPolicy.getTypeClassInterfaceName(con),
parameters,
Fundep.mapFundeps(classAst.parameters, classAst.fundeps));
typeClass.methodNames.add(name.name);
methods.put(name.name,
new TypeClassMethod(typeClass, name.name,
- namingPolicy.getMethodName(name.name),
+ compilationContext.namingPolicy.getMethodName(name.name),
type, Types.getArity(type),
name.location)
);
}
private TypeTranslationContext createTypeTranslationContext() {
- return new TypeTranslationContext(errorLog, environment);
+ return new TypeTranslationContext(compilationContext);
}
public void processDerivingInstances(ArrayList<DDerivingInstanceAst> derivingInstancesAst,
String name = derivingInstance.name.name;
TCon con;
try {
- con = Environments.getTypeClassName(environment, name);
+ con = Environments.getTypeClassName(compilationContext.environment, name);
} catch (AmbiguousNameException e) {
errorLog.log(derivingInstance.name.location, e.getMessage());
continue;
if(deriver == null)
errorLog.log(derivingInstance.location, "Doesn't know how to derive " + name + ".");
else
- deriver.derive(errorLog, environment, instancesAst, derivingInstance);
+ deriver.derive(errorLog, compilationContext.environment, instancesAst, derivingInstance);
}
}
String name = instanceAst.name.name;
TCon typeClassCon;
try {
- typeClassCon = Environments.getTypeClassName(environment, name);
+ typeClassCon = Environments.getTypeClassName(compilationContext.environment, name);
} catch (AmbiguousNameException e) {
errorLog.log(instanceAst.name.location, e.getMessage());
continue;
errorLog.log(instanceAst.name.location, "Couldn't resolve class " + name + ".");
continue;
}
- TypeClass typeClass = environment.getTypeClass(typeClassCon);
+ TypeClass typeClass = compilationContext.environment.getTypeClass(typeClassCon);
pInstanceAst.typeClass = typeClass;
if(instanceAst.types.length != typeClass.parameters.length) {
for(int i=0;i<instanceContext.length;++i)
instanceContext[i] = context.toTFuncApply(instanceAst.context[i]);
- String javaName = namingPolicy.getInstanceClassName(instance);
+ String javaName = compilationContext.namingPolicy.getInstanceClassName(instance);
String instancePrefix = instance.toName() + "$";
ValueRepository valueDefs = pInstanceAst.valueDefs;
Expression expression = new EGetConstraint(instance.location, type);
value.setExpression(expression);
value.setType(Types.forAll(instance.generatorParameters, Types.constrained(instance.context, type)));
+ value.getProperties().add(new InlineProperty(instance.context.length, 0xffffffff));
//TypeUnparsingContext tuc = new TypeUnparsingContext();
// TODO error handling
instance.superExpressions[i] = value;
effect.collectConcreteEffects(concreteEffects);
for(TCon eff : concreteEffects) {
- EffectConstructor effC = environment.getEffectConstructor(eff);
+ EffectConstructor effC = compilationContext.environment.getEffectConstructor(eff);
for(ThreadLocalVariable var : effC.getThreadLocalVariables()) {
for(int i=0;i<unresolvedItems.size();++i) {
int id = unresolvedItems.get(i);
javaTypeTranslator.toTypeDesc(returnType);
if(!javaReferenceValidator.isAssignableFrom(expectedReturnType,
providedReturnType)) {
- if(expectedReturnType.equals(TypeDesc.VOID))
- filter = PopOutputFilter.INSTANCE;
+ if(expectedReturnType.equals(TypeDesc.VOID)) {
+ if(providedReturnType.equals(TypeDesc.DOUBLE) || providedReturnType.equals(TypeDesc.LONG))
+ filter = Pop2OutputFilter.INSTANCE;
+ else
+ filter = PopOutputFilter.INSTANCE;
+ }
else if(expectedReturnType.equals(Constants.LIST)
&& providedReturnType.equals(Constants.COLLECTION))
filter = ConvertToListFilter.INSTANCE;
if(ruleAstMap.containsKey(extendsName))
extendsRule = processRule(extendsName);
else {
- extendsRule = Environments.getRule(environment, extendsName);
+ extendsRule = Environments.getRule(compilationContext.environment, extendsName);
if(extendsRule == null)
errorLog.log(ruleAst.location,
"Couldn't resolve rule name " + extendsName + ".");
}
private TranslationContext createTranslationContext() {
- return new TranslationContext(errorLog, environment, null);
+ return new TranslationContext(compilationContext, null);
}
private void handleAnnotation(SCLValue value, ArrayList<DValueAst> defs, DAnnotationAst annotation) {
}
else if(annotation.id.text.equals("@inline")) {
try {
- int arity = defs.get(0).lhs.getFunctionDefinitionArity();
+ int arity = defs.get(0).lhs.getFunctionDefinitionPatternArity();
int phaseMask = 0xffffffff;
if(annotation.parameters.length > 0) {
phaseMask = Integer.parseInt(((EIntegerLiteral)annotation.parameters[0]).getValue());
import org.simantics.scl.compiler.common.names.Name;
import org.simantics.scl.compiler.elaboration.modules.SCLValue;
-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.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;
import org.simantics.scl.compiler.elaboration.rules.TransformationRule;
return base.getEntityType(name);
}
@Override
- public TypeConstructor getTypeConstructor(TCon type) {
+ public TypeDescriptor getTypeDescriptor(TCon type) {
if(type.module.equals(module.getName()))
- return module.getTypeConstructor(type.name);
+ return module.getTypeDescriptor(type.name);
else
- return base.getTypeConstructor(type);
+ return base.getTypeDescriptor(type);
}
@Override
public EffectConstructor getEffectConstructor(TCon type) {
return base.getEffectConstructor(type);
}
@Override
- public TypeAlias getTypeAlias(TCon type) {
- if(type.module.equals(module.getName()))
- return module.getTypeAlias(type.name);
- else
- return base.getTypeAlias(type);
- }
- @Override
public TypeClass getTypeClass(TCon type) {
if(type.module.equals(module.getName()))
return module.getTypeClass(type.name);
package org.simantics.scl.compiler.compilation;\r
\r
import org.simantics.scl.compiler.elaboration.modules.SCLValue;\r
-import org.simantics.scl.compiler.elaboration.modules.TypeConstructor;\r
+import org.simantics.scl.compiler.elaboration.modules.TypeDescriptor;\r
import org.simantics.scl.compiler.environment.AmbiguousNameException;\r
import org.simantics.scl.compiler.environment.Environment;\r
import org.simantics.scl.compiler.errors.ErrorLog;\r
public static void checkIfTypeExists(ErrorLog errorLog, long location,\r
Environment environment, String name) {\r
try {\r
- TypeConstructor value = environment.getLocalNamespace().getTypeConstructor(name);\r
- if(value != null)\r
+ TypeDescriptor tdesc = environment.getLocalNamespace().getTypeDescriptor(name);\r
+ if(tdesc != null)\r
errorLog.log(location,\r
"Type " + name + " is already defined in the module " + \r
- value.name.module + \r
+ tdesc.name.module + \r
" that is imported to the default namespace.");\r
} catch(AmbiguousNameException e) {\r
errorLog.log(location,\r
import java.util.function.Consumer;
import org.simantics.scl.compiler.elaboration.modules.SCLValue;
-import org.simantics.scl.compiler.elaboration.modules.TypeAlias;
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;
import org.simantics.scl.compiler.elaboration.rules.MappingRelation;
throw new AmbiguousNameException(Arrays.asList(value.getName().module, value2.getName().module), value.getName().name);
}
else {
- if(value != null)
- return value;
- return base.getValue(name);
+ if(value != null)
+ return value;
+ return base.getValue(name);
}
}
}
@Override
- public TypeConstructor getTypeConstructor(String name)
+ public TypeDescriptor getTypeDescriptor(String name)
throws AmbiguousNameException {
- TypeConstructor typeConstructor = module.getTypeConstructor(name);
- if(typeConstructor != null)
- return typeConstructor;
- return base.getTypeConstructor(name);
+ TypeDescriptor typeDescriptor = module.getTypeDescriptor(name);
+ if(typeDescriptor != null)
+ return typeDescriptor;
+ return base.getTypeDescriptor(name);
}
@Override
return typeClass;
return base.getTypeClass(name);
}
-
- @Override
- public TypeAlias getTypeAlias(String name) throws AmbiguousNameException {
- TypeAlias typeAlias = module.getTypeAlias(name);
- if(typeAlias != null)
- return typeAlias;
- return base.getTypeAlias(name);
- }
@Override
public MappingRelation getMappingRelation(String name)
import org.simantics.scl.compiler.top.StandardModuleInitializer;
public class SCLCompiler {
- ErrorLog errorLog = new ErrorLog();
- DeclarationClassification declarations = new DeclarationClassification(errorLog);
+ CompilationContext compilationContext = new CompilationContext();
+ DeclarationClassification declarations = new DeclarationClassification(compilationContext);
// publishable results
Map<String, byte[]> classes;
for(DeclarationAst declaration : (ArrayList<DeclarationAst>)parser.parseModule())
declarations.handle(declaration);
} catch(SCLSyntaxErrorException e) {
- errorLog.log(e.location, e.getMessage());
+ compilationContext.errorLog.log(e.location, e.getMessage());
} catch(Exception e) {
- errorLog.log(e);
+ compilationContext.errorLog.log(e);
} finally {
try {
sourceReader.close();
if(SCLCompilerConfiguration.ENABLE_TIMING) phaseFinished("Parsing");
}
+ private boolean hasErrors() {
+ return !compilationContext.errorLog.isEmpty();
+ }
+
public void compile(
EnvironmentFactory localEnvironmentFactory,
String moduleName,
JavaReferenceValidator<?, ?, ?, ?> javaReferenceValidator) {
try {
- if(!errorLog.isEmpty()) return;
- Elaboration elaboration = new Elaboration(errorLog,
+ if(hasErrors()) return;
+ Elaboration elaboration = new Elaboration(compilationContext,
timer,
localEnvironmentFactory,
moduleName,
if(options.computeCoverage)
elaboration.addCoverageBranchPoints();
// Elaboration
- if(!errorLog.isEmpty()) return;
+ if(hasErrors()) return;
elaboration.addTypesToEnvironment(
declarations.dataTypesAst,
declarations.typeAliasesAst,
declarations.effectsAst);
- if(!errorLog.isEmpty()) return;
+ if(hasErrors()) return;
elaboration.processTypeAliases(declarations.typeAliasesAst);
- if(!errorLog.isEmpty()) return;
+ if(hasErrors()) return;
elaboration.processDataTypes(declarations.dataTypesAst);
- if(!errorLog.isEmpty()) return;
+ if(hasErrors()) return;
elaboration.processTypeClasses(declarations.typeClassesAst);
- if(!errorLog.isEmpty()) return;
+ if(hasErrors()) return;
elaboration.processDerivingInstances(declarations.derivingInstancesAst, declarations.instancesAst);
- if(!errorLog.isEmpty()) return;
+ if(hasErrors()) return;
elaboration.processInstances(declarations.instancesAst);
- if(!errorLog.isEmpty()) return;
+ if(hasErrors()) return;
elaboration.processJavaMethods(declarations.javaMethodDeclarations);
- if(!errorLog.isEmpty()) return;
+ if(hasErrors()) return;
elaboration.addDataTypesToEnvironment();
elaboration.addTypeClassesToEnvironment();
elaboration.preprocessValueDefinitions(declarations.typeAnnotationsAst);
if(SCLCompilerConfiguration.ENABLE_TIMING) phaseFinished("Elaboration");
// Type checking
- if(!errorLog.isEmpty()) return;
+ if(hasErrors()) return;
//new TypeChecking(errorLog, elaboration.environment, elaboration.module).typeCheck();
- new TypeChecking(errorLog, elaboration.environment, elaboration.module).typeCheck();
+ new TypeChecking(compilationContext, elaboration.module).typeCheck();
if(SCLCompilerConfiguration.ENABLE_TIMING) phaseFinished("Type checking");
this.declarations = null;
// Code generation
- if(!errorLog.isEmpty()) return;
+ if(hasErrors()) return;
CodeGeneration codeGeneration = new CodeGeneration(
- errorLog,
- elaboration.environment,
- elaboration.namingPolicy,
- elaboration.javaTypeTranslator,
+ compilationContext,
elaboration.javaReferenceValidator,
elaboration.module);
codeGeneration.simplifyValues();
- if(!errorLog.isEmpty()) return;
+ if(hasErrors()) return;
codeGeneration.convertToSSA();
- if(!errorLog.isEmpty()) return;
+ if(hasErrors()) return;
codeGeneration.optimizeSSA();
if(SCLCompilerConfiguration.ENABLE_TIMING) phaseFinished("SSA conversion and optimization");
- if(!errorLog.isEmpty()) return;
+ if(hasErrors()) return;
codeGeneration.generateCode();
- if(!errorLog.isEmpty()) return;
+ if(hasErrors()) return;
codeGeneration.generateDataTypes(elaboration.dataTypes);
- if(!errorLog.isEmpty()) return;
+ if(hasErrors()) return;
codeGeneration.generateTypeClasses();
- if(!errorLog.isEmpty()) return;
+ if(hasErrors()) return;
codeGeneration.generateTypeClassInstances();
- if(!errorLog.isEmpty()) return;
+ if(hasErrors()) return;
classes = codeGeneration.classes;
module = codeGeneration.module;
moduleInitializer = StandardModuleInitializer.create(
- codeGeneration.namingPolicy.getModuleClassName(),
+ compilationContext.namingPolicy.getModuleClassName(),
codeGeneration.externalConstants);
module.setClasses(classes);
reportTiming(moduleName);
}
} catch(Exception e) {
- errorLog.log(e);
+ compilationContext.errorLog.log(e);
}
}
public ErrorLog getErrorLog() {
- return errorLog;
+ return compilationContext.errorLog;
}
public Map<String, byte[]> getClasses() {
import org.simantics.scl.compiler.elaboration.rules.MappingRelation;
import org.simantics.scl.compiler.elaboration.rules.TransformationRule;
import org.simantics.scl.compiler.environment.Environment;
-import org.simantics.scl.compiler.errors.ErrorLog;
import org.simantics.scl.compiler.internal.elaboration.constraints.Constraint;
import org.simantics.scl.compiler.internal.elaboration.constraints.ConstraintEnvironment;
import org.simantics.scl.compiler.internal.elaboration.constraints.ConstraintSolver;
import gnu.trove.set.hash.TIntHashSet;
public class TypeChecking {
- final ErrorLog errorLog;
+ final CompilationContext compilationContext;
final Environment environment;
final ConcreteModule module;
ConstraintEnvironment ce;
TypeCheckingScheduler scheduler;
- public TypeChecking(ErrorLog errorLog, Environment environment,
- ConcreteModule module) {
- this.errorLog = errorLog;
- this.environment = environment;
+ public TypeChecking(CompilationContext compilationContext, ConcreteModule module) {
+ this.compilationContext = compilationContext;
+ this.environment = compilationContext.environment;
this.module = module;
}
expression = expression.checkType(context, value.getType());
context.popEffectUpperBound();
for(EAmbiguous overloaded : context.overloadedExpressions)
- overloaded.assertResolved(errorLog);
+ overloaded.assertResolved(compilationContext.errorLog);
value.setExpression(expression);
ArrayList<EVariable> constraintDemand = context.getConstraintDemand();
for(Constraint c : red.unsolvedConstraints)
if(c.constraint.isGround())
- errorLog.log(c.getDemandLocation(), "There is no instance for <"+c.constraint+">.");
+ compilationContext.errorLog.log(c.getDemandLocation(), "There is no instance for <"+c.constraint+">.");
ArrayList<Variable> fe = new ArrayList<Variable>(red.unsolvedConstraints.size());
for(Constraint c : red.unsolvedConstraints)
Expression expression = value.getExpression();
+ int errorCountBeforeTypeChecking = compilationContext.errorLog.getErrorCount();
+ int functionArity = expression.getSyntacticFunctionArity();
+
try {
ArrayList<TVar> vars = new ArrayList<TVar>();
type = Types.removeForAll(type, vars);
ArrayList<TPred> givenConstraints = new ArrayList<TPred>();
type = Types.removePred(type, givenConstraints);
- TypingContext context = new TypingContext(errorLog, environment);
+ TypingContext context = new TypingContext(compilationContext);
context.pushEffectUpperBound(expression.location, Types.PROC);
expression = expression.checkType(context, type);
context.popEffectUpperBound();
for(EAmbiguous overloaded : context.overloadedExpressions)
- overloaded.assertResolved(errorLog);
+ overloaded.assertResolved(compilationContext.errorLog);
expression.getType().addPolarity(Polarity.POSITIVE);
context.solveSubsumptions(expression.getLocation());
+
+ if(compilationContext.errorLog.getErrorCount() != errorCountBeforeTypeChecking) {
+ int typeArity = Types.getArity(type);
+ if(typeArity != functionArity)
+ compilationContext.errorLog.log(value.definitionLocation, "Possible problem: type declaration has " + typeArity + " parameter types, but function definition has " + functionArity + " parameters.");
+ }
+
ArrayList<EVariable> demands = context.getConstraintDemand();
if(!demands.isEmpty() || !givenConstraints.isEmpty()) {
ReducedConstraints red =
ConstraintSolver.solve(ce, givenConstraints, demands, true);
givenConstraints.clear();
for(Constraint c : red.unsolvedConstraints) {
- errorLog.log(c.getDemandLocation(),
+ compilationContext.errorLog.log(c.getDemandLocation(),
"Constraint <"+c.constraint+"> is not given and cannot be derived.");
}
- if(errorLog.isEmpty()) { // To prevent exceptions
+ if(compilationContext.errorLog.isEmpty()) { // To prevent exceptions
expression = ExpressionAugmentation.augmentSolved(
red.solvedConstraints,
expression);
}
}
else {
- if(errorLog.isEmpty()) // To prevent exceptions
+ if(compilationContext.errorLog.isEmpty()) // To prevent exceptions
expression = expression.decomposeMatching();
}
expression = expression.closure(vars.toArray(new TVar[vars.size()]));
value.setExpression(expression);
} catch(Exception e) {
- errorLog.log(expression.location, e);
+ compilationContext.errorLog.log(expression.location, e);
}
}
});
public void typeCheck() {
ce = new ConstraintEnvironment(environment);
- scheduler = new TypeCheckingScheduler(errorLog, environment);
+ scheduler = new TypeCheckingScheduler(compilationContext);
typeCheckValues();
typeCheckRelations();
for(MappingRelation mappingRelation : module.getMappingRelations())
for(Type parameterType : mappingRelation.parameterTypes)
if(!parameterType.isGround()) {
- errorLog.log(mappingRelation.location, "Parameter types of the mapping relation are not completely determined.");
+ compilationContext.errorLog.log(mappingRelation.location, "Parameter types of the mapping relation are not completely determined.");
break;
}
}
import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
import org.simantics.scl.compiler.elaboration.expressions.Variable;
import org.simantics.scl.compiler.elaboration.modules.SCLValue;
-import org.simantics.scl.compiler.environment.Environment;
-import org.simantics.scl.compiler.errors.ErrorLog;
import org.simantics.scl.compiler.internal.elaboration.constraints.Constraint;
import org.simantics.scl.compiler.internal.elaboration.utils.StronglyConnectedComponents;
import org.simantics.scl.compiler.types.TPred;
* @author Hannu Niemistö
*/
public class TypeCheckingScheduler {
- final ErrorLog errorLog;
- final Environment environment;
+ private final CompilationContext compilationContext;
- ArrayList<TypeInferableDefinition> definitions = new ArrayList<TypeInferableDefinition>();
- ArrayList<Runnable> postTypeCheckingRunnables = new ArrayList<Runnable>();
+ private final ArrayList<TypeInferableDefinition> definitions = new ArrayList<TypeInferableDefinition>();
+ private final ArrayList<Runnable> postTypeCheckingRunnables = new ArrayList<Runnable>();
- public TypeCheckingScheduler(ErrorLog errorLog, Environment environment) {
- this.errorLog = errorLog;
- this.environment = environment;
+ public TypeCheckingScheduler(CompilationContext compilationContext) {
+ this.compilationContext = compilationContext;
}
public void addTypeInferableDefinition(TypeInferableDefinition definition) {
}
private void typeCheck(int[] component) {
- TypingContext context = new TypingContext(errorLog, environment);
+ TypingContext context = new TypingContext(compilationContext);
context.recursiveValues = new THashSet<SCLValue>();
for(int c : component)
constraintMap.put(cons.constraint, cons);
}
Constraint cons = constraintMap.get(constraint);
- errorLog.log(cons.getDemandLocation(),
+ compilationContext.errorLog.log(cons.getDemandLocation(),
"Constrain " + constraint +
" contains free variables not mentioned in the type of the value.");
}
import org.simantics.scl.compiler.types.Types;
public class BooleanConstant extends Constant {
+ public static final BooleanConstant TRUE = new BooleanConstant(true);
+ public static final BooleanConstant FALSE = new BooleanConstant(false);
+
boolean value;
public BooleanConstant(boolean value) {
--- /dev/null
+package org.simantics.scl.compiler.constants;\r
+\r
+import org.simantics.scl.compiler.internal.codegen.continuations.Cont;\r
+import org.simantics.scl.compiler.internal.codegen.references.Val;\r
+import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder;\r
+\r
+public interface ComparisonFunction {\r
+\r
+ void generateCondition(MethodBuilder mb, Val[] parameters, Cont then_, Cont else_);\r
+\r
+}\r
import org.objectweb.asm.Label;
+import org.simantics.scl.compiler.internal.codegen.continuations.Cont;
import org.simantics.scl.compiler.internal.codegen.references.Val;
import org.simantics.scl.compiler.internal.codegen.types.JavaTypeTranslator;
import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder;
import org.simantics.scl.compiler.types.Type;
import org.simantics.scl.compiler.types.Types;
-public class JavaComparisonOperation extends FunctionValue {
+public class JavaComparisonOperation extends FunctionValue implements ComparisonFunction {
+ public static final JavaComparisonOperation IEQUAL = new JavaComparisonOperation("==", Types.INTEGER);
+ public static final JavaComparisonOperation INOT_EQUAL = new JavaComparisonOperation("!=", Types.INTEGER);
+ public static final JavaComparisonOperation ILESS = new JavaComparisonOperation("<", Types.INTEGER);
+ public static final JavaComparisonOperation ILESS_OR_EQUAL = new JavaComparisonOperation("<=", Types.INTEGER);
+ public static final JavaComparisonOperation IGREATER = new JavaComparisonOperation(">", Types.INTEGER);
+ public static final JavaComparisonOperation IGREATER_OR_EQUAL = new JavaComparisonOperation(">=", Types.INTEGER);
String op;
JavaTypeTranslator tt = mb.getJavaTypeTranslator();
Label thenBranch = mb.createLabel();
Label joinPoint = mb.createLabel();
+ Type type = parameterTypes[0];
mb.push(parameters[0], type);
mb.push(parameters[1], type);
- mb.ifComparisonBranch(thenBranch, op, tt.toTypeDesc(parameterTypes[0]));
+ mb.ifComparisonBranch(thenBranch, op, tt.toTypeDesc(type));
mb.loadConstant(false);
mb.branch(joinPoint);
return "(" + op + ")";
}
+ @Override
+ public void generateCondition(MethodBuilder mb, Val[] parameters, Cont then_, Cont else_) {
+ JavaTypeTranslator tt = mb.getJavaTypeTranslator();
+ Type type = parameterTypes[0];
+ mb.push(parameters[0], type);
+ mb.push(parameters[1], type);
+ mb.ifComparisonBranch(mb.getLabel(then_), op, tt.toTypeDesc(type));
+ mb.jump(else_);
+ mb.ensureExists(then_);
+ }
+
}
package org.simantics.scl.compiler.constants;
import org.objectweb.asm.Label;
+import org.simantics.scl.compiler.internal.codegen.continuations.Cont;
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 JavaComparisonToZeroOperation extends FunctionValue {
+public class JavaComparisonToZeroOperation extends FunctionValue implements ComparisonFunction {
+ public static final JavaComparisonToZeroOperation IEQUAL = new JavaComparisonToZeroOperation("==");
+ public static final JavaComparisonToZeroOperation INOT_EQUAL = new JavaComparisonToZeroOperation("!=");
+ public static final JavaComparisonToZeroOperation ILESS = new JavaComparisonToZeroOperation("<");
+ public static final JavaComparisonToZeroOperation ILESS_OR_EQUAL = new JavaComparisonToZeroOperation("<=");
+ public static final JavaComparisonToZeroOperation IGREATER = new JavaComparisonToZeroOperation(">");
+ public static final JavaComparisonToZeroOperation IGREATER_OR_EQUAL = new JavaComparisonToZeroOperation(">=");
String op;
return getReturnType();
}
+ @Override
+ public void generateCondition(MethodBuilder mb, Val[] parameters, Cont then_, Cont else_) {
+ mb.push(parameters[0], Types.INTEGER);
+ mb.ifZeroComparisonBranch(mb.getLabel(then_), op);
+ mb.jump(else_);
+ mb.ensureExists(then_);
+ }
+
@Override
public String toString() {
return op;
if(isPrivate && !hasMoreThanOneOccurences())\r
context.removeConstant(name);\r
else\r
- def = def.copy();\r
+ def = (SSAFunction)def.copy();\r
\r
if(parameters.length >= def.getArity()) {\r
if(parameters.length != def.getArity())\r
definition.simplify(context);\r
if(inlineArity == Integer.MAX_VALUE && definition.isSimpleEnoughForInline()) {\r
inlineArity = definition.getArity();\r
- inlinableDefinition = definition.copy();\r
+ inlinableDefinition = (SSAFunction)definition.copy();\r
context.markModified("mark inlineable " + name);\r
// FIXME this will make self calling function inlinable that may crash the compiler\r
}\r
\r
public void saveInlinableDefinition() {\r
if(inlineArity < Integer.MAX_VALUE)\r
- inlinableDefinition = definition.copy();\r
+ inlinableDefinition = (SSAFunction)definition.copy();\r
}\r
}\r
package org.simantics.scl.compiler.constants;\r
\r
+import java.util.Arrays;\r
+\r
import org.cojen.classfile.TypeDesc;\r
+import org.objectweb.asm.Label;\r
+import org.objectweb.asm.Opcodes;\r
+import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
+import org.simantics.scl.compiler.internal.codegen.continuations.Cont;\r
+import org.simantics.scl.compiler.internal.codegen.references.IVal;\r
import org.simantics.scl.compiler.internal.codegen.references.Val;\r
import org.simantics.scl.compiler.internal.codegen.utils.Constants;\r
+import org.simantics.scl.compiler.internal.codegen.utils.LocalVariable;\r
import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder;\r
import org.simantics.scl.compiler.types.TVar;\r
import org.simantics.scl.compiler.types.Type;\r
public StringInterpolation(String[] textParts) {\r
this(stringTypeArray(textParts.length-1), textParts);\r
}\r
+ \r
+ @Override\r
+ public String toString() {\r
+ StringBuilder b = new StringBuilder();\r
+ b.append('"');\r
+ boolean first = true;\r
+ for(String textPart : textParts) {\r
+ if(first)\r
+ first = false;\r
+ else\r
+ b.append("\\(.)");\r
+ b.append(textPart);\r
+ }\r
+ b.append('"');\r
+ return b.toString();\r
+ }\r
\r
private static Type[] stringTypeArray(int length) {\r
Type[] result = new Type[length];\r
\r
@Override\r
public Type applyExact(MethodBuilder mb, Val[] parameters) {\r
+ if(textParts.length==1) {\r
+ mb.loadConstant(textParts[0]);\r
+ }\r
+ else if(textParts.length==2) {\r
+ if(parameters[0].getType() == Types.STRING) {\r
+ // Optimized special cases "asd" + x, x + "asd"\r
+ if(textParts[0].isEmpty()) {\r
+ mb.push(parameters[0], Types.STRING);\r
+ if(!textParts[1].isEmpty()) {\r
+ mb.loadConstant(textParts[1]);\r
+ mb.invokeVirtual("java/lang/String", "concat", TypeDesc.STRING, new TypeDesc[] {TypeDesc.STRING});\r
+ }\r
+ return Types.STRING;\r
+ }\r
+ else if(textParts[1].isEmpty()) {\r
+ mb.loadConstant(textParts[0]);\r
+ mb.push(parameters[0], Types.STRING);\r
+ mb.invokeVirtual("java/lang/String", "concat", TypeDesc.STRING, new TypeDesc[] {TypeDesc.STRING});\r
+ return Types.STRING;\r
+ }\r
+ }\r
+ }\r
+ else if(textParts.length==3) {\r
+ if(parameters[0].getType() == Types.STRING && parameters[1].getType() == Types.STRING\r
+ && textParts[0].isEmpty() && textParts[1].isEmpty() && textParts[2].isEmpty()) {\r
+ mb.push(parameters[0], Types.STRING);\r
+ mb.push(parameters[1], Types.STRING);\r
+ mb.invokeVirtual("java/lang/String", "concat", TypeDesc.STRING, new TypeDesc[] {TypeDesc.STRING});\r
+ return Types.STRING;\r
+ }\r
+ }\r
mb.newObject(STRING_BUILDER);\r
mb.dup();\r
mb.invokeConstructor(STRING_BUILDER, Constants.EMPTY_TYPEDESC_ARRAY);\r
\r
return Types.STRING;\r
}\r
+ \r
+ @Override\r
+ public int hashCode() {\r
+ return Arrays.hashCode(textParts) ^ Arrays.hashCode(parameterTypes);\r
+ }\r
\r
+ @Override\r
+ public boolean equals(Object obj) {\r
+ if(this == obj)\r
+ return true;\r
+ if(obj == null || obj.getClass() != getClass())\r
+ return false;\r
+ StringInterpolation other = (StringInterpolation)obj;\r
+ return Arrays.equals(textParts, other.textParts) && Arrays.equals(parameterTypes, other.parameterTypes);\r
+ }\r
+ \r
+ @Override\r
+ public int constructorTag() {\r
+ return textParts.length == 2 && parameterTypes[0] == Types.STRING ? 0 : -1;\r
+ }\r
+ \r
+ @Override\r
+ public void deconstruct(MethodBuilder mb, IVal parameter, Cont success, Label failure) {\r
+ if(textParts.length != 2)\r
+ throw new InternalCompilerError("String interpolation with more than one open string parts cannot be used as a pattern.");\r
+ mb.push(parameter, Types.STRING);\r
+ LocalVariable temp = mb.createLocalVariable(null, TypeDesc.STRING);\r
+ mb.storeLocal(temp);\r
+ if(!textParts[0].isEmpty()) {\r
+ mb.loadLocal(temp);\r
+ mb.loadConstant(textParts[0]);\r
+ mb.invokeVirtual("java/lang/String", "startsWith", TypeDesc.BOOLEAN, new TypeDesc[] {TypeDesc.STRING});\r
+ mb.ifZeroComparisonBranch(failure, "==");\r
+ }\r
+ if(!textParts[1].isEmpty()) {\r
+ mb.loadLocal(temp);\r
+ mb.loadConstant(textParts[1]);\r
+ mb.invokeVirtual("java/lang/String", "endsWith", TypeDesc.BOOLEAN, new TypeDesc[] {TypeDesc.STRING});\r
+ mb.ifZeroComparisonBranch(failure, "==");\r
+ }\r
+ mb.loadLocal(temp);\r
+ mb.loadConstant(textParts[0].length());\r
+ mb.loadLocal(temp);\r
+ mb.invokeVirtual("java/lang/String", "length", TypeDesc.INT, Constants.EMPTY_TYPEDESC_ARRAY);\r
+ mb.loadConstant(textParts[1].length());\r
+ mb.math(Opcodes.ISUB);\r
+ mb.invokeVirtual("java/lang/String", "substring", TypeDesc.STRING, new TypeDesc[] {TypeDesc.INT, TypeDesc.INT});\r
+ mb.storeLocal(temp);\r
+ mb.jump(success, new LocalVariableConstant(Types.STRING, temp));\r
+ }\r
+ \r
}\r
+++ /dev/null
-package org.simantics.scl.compiler.constants;\r
-\r
-import org.simantics.scl.compiler.internal.codegen.references.Val;\r
-import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder;\r
-import org.simantics.scl.compiler.types.TVar;\r
-import org.simantics.scl.compiler.types.Type;\r
-import org.simantics.scl.compiler.types.Types;\r
-import org.simantics.scl.compiler.types.kinds.Kinds;\r
-\r
-public class UnsafeCoerce extends FunctionValue { \r
- private static TVar A = Types.var(Kinds.STAR);\r
- private static TVar B = Types.var(Kinds.STAR);\r
- public static final UnsafeCoerce INSTANCE = new UnsafeCoerce();\r
- \r
- private UnsafeCoerce() {\r
- super(new TVar[] {A, B}, Types.NO_EFFECTS, B, A);\r
- }\r
- \r
- @Override\r
- public Type applyExact(MethodBuilder mb, Val[] parameters) {\r
- mb.pushBoxed(parameters[0]);\r
- return getReturnType();\r
- }\r
-}\r
Type[] parameterTypes, StackItem[] stackItems, MethodRef methodRef,\r
OutputFilter filter) {\r
super(typeParameters, effect, returnType, parameterTypes);\r
+ if(stackItems == null) {\r
+ stackItems = new StackItem[parameterTypes.length];\r
+ for(int i=0;i<parameterTypes.length;++i)\r
+ stackItems[i] = new ParameterStackItem(i, parameterTypes[i]);\r
+ }\r
this.stackItems = stackItems;\r
this.methodRef = methodRef;\r
this.filter = filter;\r
--- /dev/null
+package org.simantics.scl.compiler.constants.generic;\r
+\r
+import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder;\r
+\r
+public enum Pop2OutputFilter implements OutputFilter {\r
+ INSTANCE;\r
+\r
+ @Override\r
+ public void filter(MethodBuilder mb) {\r
+ mb.pop2();\r
+ }\r
+}\r
public void filter(MethodBuilder mb) {
mb.pop();
}
-
}
--- /dev/null
+package org.simantics.scl.compiler.constants.singletons;\r
+\r
+import org.objectweb.asm.Opcodes;\r
+import org.simantics.scl.compiler.constants.FunctionValue;\r
+import org.simantics.scl.compiler.internal.codegen.references.Val;\r
+import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder;\r
+import org.simantics.scl.compiler.types.TVar;\r
+import org.simantics.scl.compiler.types.Type;\r
+import org.simantics.scl.compiler.types.Types;\r
+\r
+public class IncreaseByOne extends FunctionValue {\r
+\r
+ public static final IncreaseByOne INSTANCE = new IncreaseByOne();\r
+ \r
+ private IncreaseByOne() {\r
+ super(TVar.EMPTY_ARRAY, Types.NO_EFFECTS, Types.INTEGER, Types.INTEGER);\r
+ }\r
+ \r
+ @Override\r
+ public Type applyExact(MethodBuilder mb, Val[] parameters) {\r
+ parameters[0].push(mb);\r
+ mb.loadConstant(1);\r
+ mb.math(Opcodes.IADD);\r
+ return Types.INTEGER;\r
+ }\r
+\r
+ @Override\r
+ public String toString() {\r
+ return "increaseByOne";\r
+ }\r
+}\r
--- /dev/null
+package org.simantics.scl.compiler.constants.singletons;\r
+\r
+import org.cojen.classfile.TypeDesc;\r
+import org.simantics.scl.compiler.constants.FunctionValue;\r
+import org.simantics.scl.compiler.internal.codegen.references.Val;\r
+import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder;\r
+import org.simantics.scl.compiler.types.TVar;\r
+import org.simantics.scl.compiler.types.Type;\r
+import org.simantics.scl.compiler.types.Types;\r
+import org.simantics.scl.compiler.types.kinds.Kinds;\r
+\r
+public class ListElement extends FunctionValue { \r
+ private static TVar A = Types.var(Kinds.STAR);\r
+ public static final ListElement INSTANCE = new ListElement();\r
+ \r
+ private ListElement() {\r
+ super(new TVar[] {A}, Types.NO_EFFECTS, A, Types.list(A), Types.INTEGER);\r
+ }\r
+ \r
+ @Override\r
+ public Type applyExact(MethodBuilder mb, Val[] parameters) {\r
+ parameters[0].push(mb);\r
+ parameters[1].push(mb);\r
+ mb.invokeInterface("java/util/List", "get", TypeDesc.OBJECT, new TypeDesc[] {TypeDesc.INT});\r
+ return getReturnType();\r
+ }\r
+\r
+ @Override\r
+ public String toString() {\r
+ return "get";\r
+ }\r
+}\r
--- /dev/null
+package org.simantics.scl.compiler.constants.singletons;\r
+\r
+import org.cojen.classfile.TypeDesc;\r
+import org.simantics.scl.compiler.constants.FunctionValue;\r
+import org.simantics.scl.compiler.internal.codegen.references.Val;\r
+import org.simantics.scl.compiler.internal.codegen.utils.Constants;\r
+import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder;\r
+import org.simantics.scl.compiler.types.TVar;\r
+import org.simantics.scl.compiler.types.Type;\r
+import org.simantics.scl.compiler.types.Types;\r
+import org.simantics.scl.compiler.types.kinds.Kinds;\r
+\r
+public class ListLength extends FunctionValue { \r
+ private static TVar A = Types.var(Kinds.STAR);\r
+ public static final ListLength INSTANCE = new ListLength();\r
+ \r
+ private ListLength() {\r
+ super(new TVar[] {A}, Types.NO_EFFECTS, Types.INTEGER, Types.list(A));\r
+ }\r
+ \r
+ @Override\r
+ public Type applyExact(MethodBuilder mb, Val[] parameters) {\r
+ parameters[0].push(mb);\r
+ mb.invokeInterface("java/util/List", "size", TypeDesc.INT, Constants.EMPTY_TYPEDESC_ARRAY);\r
+ return getReturnType();\r
+ }\r
+\r
+ @Override\r
+ public String toString() {\r
+ return "length";\r
+ }\r
+}\r
--- /dev/null
+package org.simantics.scl.compiler.constants.singletons;\r
+\r
+import org.objectweb.asm.Label;\r
+import org.simantics.scl.compiler.constants.ComparisonFunction;\r
+import org.simantics.scl.compiler.constants.FunctionValue;\r
+import org.simantics.scl.compiler.internal.codegen.continuations.Cont;\r
+import org.simantics.scl.compiler.internal.codegen.references.Val;\r
+import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder;\r
+import org.simantics.scl.compiler.types.TVar;\r
+import org.simantics.scl.compiler.types.Type;\r
+import org.simantics.scl.compiler.types.Types;\r
+import org.simantics.scl.compiler.types.kinds.Kinds;\r
+\r
+public class NullCheck extends FunctionValue implements ComparisonFunction {\r
+ private static final TVar A = Types.var(Kinds.STAR);\r
+ public static final NullCheck INSTANCE = \r
+ new NullCheck();\r
+ \r
+ private NullCheck() {\r
+ super(new TVar[] {A}, Types.NO_EFFECTS, Types.BOOLEAN, A);\r
+ }\r
+ \r
+ @Override\r
+ public Type applyExact(MethodBuilder mb, Val[] parameters) {\r
+ parameters[0].push(mb);\r
+ Label join = mb.createLabel();\r
+ Label isNull = mb.createLabel();\r
+ mb.ifNullBranch(isNull, true);\r
+ mb.loadConstant(false);\r
+ mb.branch(join);\r
+ mb.setLocation(isNull);\r
+ mb.loadConstant(true);\r
+ mb.setLocation(join);\r
+ return getReturnType();\r
+ }\r
+ \r
+ @Override\r
+ public void generateCondition(MethodBuilder mb, Val[] parameters, Cont then_, Cont else_) {\r
+ parameters[0].push(mb);\r
+ mb.ifNullBranch(mb.getLabel(then_), true);\r
+ mb.jump(else_);\r
+ mb.ensureExists(then_);\r
+ }\r
+\r
+ @Override\r
+ public String toString() {\r
+ return "nullCheck";\r
+ }\r
+}\r
mb.pushBoxed(parameters[0]);\r
return getReturnType();\r
}\r
+\r
+ @Override\r
+ public String toString() {\r
+ return "unsafeCoerce";\r
+ }\r
}\r
--- /dev/null
+package org.simantics.scl.compiler.elaboration.chr;\r
+\r
+import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
+import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint;\r
+import org.simantics.scl.compiler.elaboration.chr.relations.ExternalCHRRelation;\r
+import org.simantics.scl.compiler.elaboration.chr.relations.SpecialCHRRelation;\r
+import org.simantics.scl.compiler.elaboration.chr.relations.UnresolvedCHRRelation;\r
+import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;\r
+import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
+import org.simantics.scl.compiler.elaboration.contexts.TypingContext;\r
+import org.simantics.scl.compiler.elaboration.expressions.Expression;\r
+import org.simantics.scl.compiler.elaboration.expressions.Variable;\r
+import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure;\r
+import org.simantics.scl.compiler.elaboration.expressions.printing.ExpressionToStringVisitor;\r
+import org.simantics.scl.compiler.elaboration.relations.SCLRelation;\r
+import org.simantics.scl.compiler.errors.Locations;\r
+import org.simantics.scl.compiler.internal.parsing.Symbol;\r
+import org.simantics.scl.compiler.types.TVar;\r
+import org.simantics.scl.compiler.types.Type;\r
+import org.simantics.scl.compiler.types.Types;\r
+import org.simantics.scl.compiler.types.kinds.Kinds;\r
+\r
+import gnu.trove.map.hash.TObjectIntHashMap;\r
+import gnu.trove.set.hash.THashSet;\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
+public class CHRLiteral extends Symbol {\r
+ \r
+ public CHRRelation relation;\r
+ public Type[] typeParameters;\r
+ public Expression[] parameters;\r
+ public boolean killAfterMatch;\r
+ public boolean negated;\r
+ public boolean passive = true;\r
+ \r
+ public CHRLiteral(long location, CHRRelation relation, Expression[] parameters, boolean remove, boolean negated) {\r
+ this.location = location;\r
+ this.relation = relation;\r
+ this.parameters = parameters;\r
+ this.killAfterMatch = remove;\r
+ this.negated = negated;\r
+ }\r
+\r
+ public void resolve(TranslationContext context) {\r
+ if(relation instanceof UnresolvedCHRRelation) {\r
+ UnresolvedCHRRelation unresolved = (UnresolvedCHRRelation)relation;\r
+ CHRConstraint constraint = context.resolveCHRConstraint(unresolved.name);\r
+ if(constraint != null) {\r
+ relation = constraint;\r
+ passive = false;\r
+ }\r
+ else {\r
+ SCLRelation sclRelation = context.resolveRelation(unresolved.location, unresolved.name);\r
+ if(sclRelation != null)\r
+ relation = new ExternalCHRRelation(sclRelation);\r
+ else {\r
+ Type[] parameterTypes = new Type[parameters.length];\r
+ for(int i=0;i<parameterTypes.length;++i)\r
+ parameterTypes[i] = Types.metaVar(Kinds.STAR);\r
+ constraint = new CHRConstraint(location, unresolved.name, parameterTypes);\r
+ constraint.implicitlyDeclared = true;\r
+ context.newCHRConstraint(constraint.name, constraint);\r
+ relation = constraint;\r
+ passive = false;\r
+ //context.getErrorLog().log(unresolved.location, "Couldn't resolve constraint " + unresolved.name + ".");\r
+ }\r
+ }\r
+ }\r
+ for(int i=0;i<parameters.length;++i)\r
+ parameters[i] = parameters[i].resolve(context);\r
+ }\r
+\r
+ public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {\r
+ for(Expression parameter : parameters)\r
+ parameter.collectRefs(allRefs, refs);\r
+ }\r
+\r
+ public void checkType(TypingContext context) {\r
+ if(relation == SpecialCHRRelation.EXECUTE) {\r
+ if(parameters.length != 1)\r
+ throw new InternalCompilerError("Wrong number of parameters for EXECUTE constraint.");\r
+ parameters[0] = parameters[0].checkIgnoredType(context);\r
+ }\r
+ else {\r
+ TVar[] typeVariables = relation.getTypeVariables();\r
+ typeParameters = typeVariables.length == 0 ? Type.EMPTY_ARRAY : new Type[typeVariables.length];\r
+ for(int i=0;i<typeVariables.length;++i)\r
+ typeParameters[i] = Types.metaVar(typeVariables[i].getKind());\r
+ Type[] parameterTypes = Types.replace(relation.getParameterTypes(), typeVariables, typeParameters);\r
+ if(parameterTypes.length != parameters.length)\r
+ context.getErrorLog().log(location, "Constraint is applied with wrong number of parameters");\r
+ else\r
+ for(int i=0;i<parameters.length;++i)\r
+ parameters[i] = parameters[i].checkType(context, parameterTypes[i]);\r
+ }\r
+ }\r
+\r
+ public void collectVars(TObjectIntHashMap<Variable> allVars, TIntHashSet vars) {\r
+ for(Expression parameter : parameters)\r
+ parameter.collectVars(allVars, vars);\r
+ }\r
+\r
+ public void forVariables(VariableProcedure procedure) {\r
+ for(Expression parameter : parameters)\r
+ parameter.forVariables(procedure);\r
+ }\r
+\r
+ public void collectFreeVariables(THashSet<Variable> vars) {\r
+ for(Expression parameter : parameters)\r
+ parameter.collectFreeVariables(vars);\r
+ }\r
+\r
+ public void setLocationDeep(long loc) {\r
+ if(location == Locations.NO_LOCATION) {\r
+ this.location = loc;\r
+ for(Expression parameter : parameters)\r
+ parameter.setLocationDeep(loc);\r
+ }\r
+ }\r
+ \r
+ public void simplify(SimplificationContext context) {\r
+ for(int i=0;i<parameters.length;++i)\r
+ parameters[i] = parameters[i].simplify(context);\r
+ }\r
+ \r
+ public String toString() {\r
+ StringBuilder b = new StringBuilder();\r
+ ExpressionToStringVisitor visitor = new ExpressionToStringVisitor(b);\r
+ visitor.visit(this);\r
+ return b.toString();\r
+ }\r
+\r
+ public void collectQueryEffects(THashSet<Type> effects) {\r
+ }\r
+\r
+ public void collectEnforceEffects(THashSet<Type> effects) {\r
+ }\r
+}\r
--- /dev/null
+package org.simantics.scl.compiler.elaboration.chr;\r
+\r
+import org.simantics.scl.compiler.elaboration.chr.plan.PostCommitOp;\r
+import org.simantics.scl.compiler.elaboration.chr.plan.PreCommitOp;\r
+import org.simantics.scl.compiler.elaboration.chr.planning.QueryPlanningContext;\r
+import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;\r
+import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
+import org.simantics.scl.compiler.elaboration.contexts.TypingContext;\r
+import org.simantics.scl.compiler.elaboration.expressions.Expression;\r
+import org.simantics.scl.compiler.elaboration.expressions.Variable;\r
+import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure;\r
+import org.simantics.scl.compiler.elaboration.expressions.printing.ExpressionToStringVisitor;\r
+import org.simantics.scl.compiler.errors.Locations;\r
+import org.simantics.scl.compiler.internal.parsing.Symbol;\r
+\r
+import gnu.trove.map.hash.TObjectIntHashMap;\r
+import gnu.trove.set.hash.THashSet;\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
+public class CHRQuery extends Symbol {\r
+ public CHRLiteral[] literals;\r
+\r
+ public CHRQuery(CHRLiteral[] literals) {\r
+ this.literals = literals;\r
+ }\r
+\r
+ public void resolve(TranslationContext context) {\r
+ for(CHRLiteral literal : literals)\r
+ literal.resolve(context);\r
+ }\r
+\r
+ public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {\r
+ for(CHRLiteral literal : literals)\r
+ literal.collectRefs(allRefs, refs);\r
+ }\r
+\r
+ public void checkType(TypingContext context) {\r
+ for(CHRLiteral literal : literals)\r
+ literal.checkType(context);\r
+ }\r
+ \r
+ public void collectVars(TObjectIntHashMap<Variable> allVars, TIntHashSet vars) {\r
+ for(CHRLiteral literal : literals)\r
+ literal.collectVars(allVars, vars);\r
+ }\r
+\r
+ public void forVariables(VariableProcedure procedure) {\r
+ for(CHRLiteral literal : literals)\r
+ literal.forVariables(procedure);\r
+ }\r
+\r
+ public void collectFreeVariables(THashSet<Variable> vars) {\r
+ for(CHRLiteral literal : literals)\r
+ literal.collectFreeVariables(vars);\r
+ }\r
+\r
+ public void setLocationDeep(long loc) {\r
+ if(location == Locations.NO_LOCATION) {\r
+ this.location = loc;\r
+ for(CHRLiteral literal : literals)\r
+ literal.setLocationDeep(loc);\r
+ }\r
+ }\r
+ \r
+ public void createQueryPlan(QueryPlanningContext context, Expression inputFact, int activeLiteralId) {\r
+ for(int i=0;i<literals.length;++i) {\r
+ CHRLiteral literal = literals[i];\r
+ if(i == activeLiteralId)\r
+ context.activate(literal, inputFact, i);\r
+ else\r
+ context.add(literal, i);\r
+ }\r
+ context.createQueryPlan();\r
+ }\r
+ \r
+ public void simplify(SimplificationContext context) {\r
+ for(CHRLiteral literal : literals)\r
+ literal.simplify(context);\r
+ }\r
+\r
+ public void createEnforcePlan(QueryPlanningContext context, int priority) {\r
+ context.addPlanOp(new PreCommitOp(location));\r
+ for(CHRLiteral literal : literals)\r
+ context.claim(context, literal);\r
+ context.addPlanOp(new PostCommitOp(location, priority));\r
+ }\r
+ \r
+ public String toString() {\r
+ StringBuilder b = new StringBuilder();\r
+ ExpressionToStringVisitor visitor = new ExpressionToStringVisitor(b);\r
+ visitor.visit(this);\r
+ return b.toString();\r
+ }\r
+}\r
--- /dev/null
+package org.simantics.scl.compiler.elaboration.chr;\r
+\r
+import org.simantics.scl.compiler.types.TVar;\r
+import org.simantics.scl.compiler.types.Type;\r
+import org.simantics.scl.compiler.types.Types;\r
+import org.simantics.scl.compiler.types.kinds.Kinds;\r
+\r
+public interface CHRRelation {\r
+ public static final TVar A = Types.var(Kinds.STAR);\r
+ \r
+ TVar[] getTypeVariables();\r
+ Type[] getParameterTypes();\r
+}\r
--- /dev/null
+package org.simantics.scl.compiler.elaboration.chr;\r
+\r
+import org.simantics.scl.compiler.compilation.CompilationContext;\r
+import org.simantics.scl.compiler.elaboration.chr.plan.PlanOp;\r
+import org.simantics.scl.compiler.elaboration.chr.plan.PrioritizedPlan;\r
+import org.simantics.scl.compiler.elaboration.chr.planning.QueryPlanningContext;\r
+import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint;\r
+import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;\r
+import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
+import org.simantics.scl.compiler.elaboration.contexts.TypingContext;\r
+import org.simantics.scl.compiler.elaboration.expressions.EVariable;\r
+import org.simantics.scl.compiler.elaboration.expressions.Variable;\r
+import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure;\r
+import org.simantics.scl.compiler.elaboration.expressions.printing.ExpressionToStringVisitor;\r
+import org.simantics.scl.compiler.errors.Locations;\r
+import org.simantics.scl.compiler.internal.parsing.Symbol;\r
+import org.simantics.scl.compiler.types.Types;\r
+import org.simantics.scl.compiler.types.kinds.Kinds;\r
+\r
+import gnu.trove.map.hash.TObjectIntHashMap;\r
+import gnu.trove.set.hash.THashSet;\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
+public class CHRRule extends Symbol {\r
+ public int priority;\r
+ public CHRQuery head;\r
+ public CHRQuery body;\r
+ public Variable[] existentialVariables;\r
+ \r
+ // Analysis\r
+ public int firstPriorityExecuted;\r
+ public int lastPriorityExecuted;\r
+ \r
+ public CHRRule(long location, CHRQuery head, CHRQuery body, Variable[] existentialVariables) {\r
+ this.location = location;\r
+ this.head = head;\r
+ this.body = body;\r
+ this.existentialVariables = existentialVariables;\r
+ }\r
+\r
+ public void resolve(TranslationContext context) {\r
+ context.pushExistentialFrame();\r
+ head.resolve(context);\r
+ body.resolve(context);\r
+ existentialVariables = context.popExistentialFrame();\r
+ }\r
+\r
+ public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {\r
+ head.collectRefs(allRefs, refs);\r
+ body.collectRefs(allRefs, refs);\r
+ }\r
+\r
+ public void checkType(TypingContext context) {\r
+ for(Variable variable : existentialVariables)\r
+ variable.setType(Types.metaVar(Kinds.STAR));\r
+ head.checkType(context);\r
+ body.checkType(context);\r
+ }\r
+ \r
+ public void collectVars(TObjectIntHashMap<Variable> allVars, TIntHashSet vars) {\r
+ head.collectVars(allVars, vars);\r
+ body.collectVars(allVars, vars);\r
+ }\r
+\r
+ public void forVariables(VariableProcedure procedure) {\r
+ head.forVariables(procedure);\r
+ body.forVariables(procedure);\r
+ }\r
+\r
+ public void collectFreeVariables(THashSet<Variable> vars) {\r
+ head.collectFreeVariables(vars);\r
+ body.collectFreeVariables(vars);\r
+ }\r
+\r
+ public void setLocationDeep(long loc) {\r
+ if(location == Locations.NO_LOCATION) {\r
+ this.location = loc;\r
+ head.setLocationDeep(loc);\r
+ body.setLocationDeep(loc);\r
+ }\r
+ }\r
+ \r
+ public void simplify(SimplificationContext context) {\r
+ head.simplify(context);\r
+ body.simplify(context);\r
+ }\r
+\r
+ public void compile(CompilationContext compilationContext, CHRConstraint initConstraint) {\r
+ boolean hasActiveLiteral = false;\r
+ for(int i=0;i<head.literals.length;++i) {\r
+ CHRLiteral literal = head.literals[i];\r
+ if(literal.passive)\r
+ continue;\r
+ CHRConstraint constraint = (CHRConstraint)literal.relation;\r
+ \r
+ Variable activeFact = new Variable("activeFact", constraint.factType);\r
+ QueryPlanningContext context = new QueryPlanningContext(compilationContext, existentialVariables);\r
+ head.createQueryPlan(context, new EVariable(activeFact), i);\r
+ body.createEnforcePlan(context, priority);\r
+ constraint.plans.add(new PrioritizedPlan(priority, activeFact, context.getPlanOps()));\r
+ \r
+ hasActiveLiteral = true;\r
+ }\r
+ if(!hasActiveLiteral) {\r
+ Variable activeFact = new Variable("activeFact", initConstraint.factType);\r
+ QueryPlanningContext context = new QueryPlanningContext(compilationContext, existentialVariables);\r
+ head.createQueryPlan(context, null, -1);\r
+ body.createEnforcePlan(context, priority);\r
+ /*System.out.println(this);\r
+ for(PlanOp planOp : context.getPlanOps())\r
+ System.out.println(" " + planOp);*/\r
+ initConstraint.plans.add(new PrioritizedPlan(priority, activeFact, context.getPlanOps()));\r
+ }\r
+ }\r
+ \r
+ public String toString() {\r
+ StringBuilder b = new StringBuilder();\r
+ ExpressionToStringVisitor visitor = new ExpressionToStringVisitor(b);\r
+ visitor.visit(this);\r
+ return b.toString();\r
+ }\r
+ \r
+}\r
--- /dev/null
+package org.simantics.scl.compiler.elaboration.chr;\r
+\r
+import java.util.ArrayList;\r
+\r
+import org.cojen.classfile.TypeDesc;\r
+import org.simantics.scl.compiler.compilation.CompilationContext;\r
+import org.simantics.scl.compiler.constants.BooleanConstant;\r
+import org.simantics.scl.compiler.constants.Constant;\r
+import org.simantics.scl.compiler.constants.IntegerConstant;\r
+import org.simantics.scl.compiler.constants.JavaMethod;\r
+import org.simantics.scl.compiler.constants.generic.CallJava;\r
+import org.simantics.scl.compiler.constants.generic.MethodRef.FieldRef;\r
+import org.simantics.scl.compiler.constants.generic.MethodRef.SetFieldRef;\r
+import org.simantics.scl.compiler.elaboration.chr.analysis.UsageAnalysis;\r
+import org.simantics.scl.compiler.elaboration.chr.plan.PlanOp;\r
+import org.simantics.scl.compiler.elaboration.chr.plan.PlanRealizer;\r
+import org.simantics.scl.compiler.elaboration.chr.plan.PrioritizedPlan;\r
+import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint;\r
+import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;\r
+import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
+import org.simantics.scl.compiler.elaboration.contexts.TypingContext;\r
+import org.simantics.scl.compiler.elaboration.expressions.Variable;\r
+import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure;\r
+import org.simantics.scl.compiler.errors.Locations;\r
+import org.simantics.scl.compiler.internal.codegen.chr.CHRCodeGenerator;\r
+import org.simantics.scl.compiler.internal.codegen.references.BoundVar;\r
+import org.simantics.scl.compiler.internal.codegen.references.IVal;\r
+import org.simantics.scl.compiler.internal.codegen.types.StandardTypeConstructor;\r
+import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;\r
+import org.simantics.scl.compiler.internal.parsing.Symbol;\r
+import org.simantics.scl.compiler.types.TCon;\r
+import org.simantics.scl.compiler.types.TVar;\r
+import org.simantics.scl.compiler.types.Type;\r
+import org.simantics.scl.compiler.types.Types;\r
+\r
+import gnu.trove.map.hash.TObjectIntHashMap;\r
+import gnu.trove.set.hash.THashSet;\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
+public class CHRRuleset extends Symbol {\r
+ \r
+ public static final String INIT_CONSTRAINT = "__INIT__";\r
+ \r
+ public ArrayList<CHRConstraint> constraints = new ArrayList<CHRConstraint>();\r
+ public ArrayList<CHRRule> rules = new ArrayList<CHRRule>();\r
+ \r
+ public CHRConstraint initConstraint;\r
+ public int priorityCount;\r
+ \r
+ public String storeClassName;\r
+ public TCon storeType;\r
+ public BoundVar storeVariable;\r
+ public TypeDesc storeTypeDesc;\r
+ public Constant activateProcedure;\r
+ public Constant readCurrentId;\r
+ public Constant writeCurrentId;\r
+ \r
+ // FIXME remove and change the parameter of Expression.toVal\r
+ private CompilationContext cachedContext;\r
+ \r
+ // For code generation\r
+ public BoundVar this_;\r
+ public BoundVar[] parameters;\r
+ public TypeDesc[] parameterTypeDescs;\r
+ \r
+ public CHRRuleset() {\r
+ initConstraint = new CHRConstraint(Locations.NO_LOCATION, INIT_CONSTRAINT, Type.EMPTY_ARRAY);\r
+ constraints.add(initConstraint);\r
+ }\r
+ \r
+ public void resolve(TranslationContext context) {\r
+ for(CHRConstraint constraint : constraints)\r
+ context.newCHRConstraint(constraint.name, constraint);\r
+ priorityCount = 0;\r
+ for(CHRRule rule : rules) {\r
+ rule.resolve(context);\r
+ rule.priority = priorityCount++;\r
+ }\r
+ /*for(CHRConstraint constraint : constraints) {\r
+ Variable newVariable = context.newVariable("claim" + constraint.factClassName);\r
+ }*/\r
+ }\r
+\r
+ public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {\r
+ for(CHRRule rule : rules)\r
+ rule.collectRefs(allRefs, refs);\r
+ }\r
+\r
+ public void checkType(TypingContext context) {\r
+ for(CHRRule rule : rules)\r
+ rule.checkType(context);\r
+ }\r
+\r
+ public void collectVars(TObjectIntHashMap<Variable> allVars, TIntHashSet vars) {\r
+ for(CHRRule rule : rules)\r
+ rule.collectVars(allVars, vars);\r
+ }\r
+\r
+ public void forVariables(VariableProcedure procedure) {\r
+ for(CHRRule rule : rules)\r
+ rule.forVariables(procedure);\r
+ }\r
+\r
+ public void collectFreeVariables(THashSet<Variable> vars) {\r
+ for(CHRRule rule : rules)\r
+ rule.collectFreeVariables(vars);\r
+ }\r
+\r
+ public void setLocationDeep(long loc) {\r
+ if(location == Locations.NO_LOCATION) {\r
+ this.location = loc;\r
+ for(CHRRule rule : rules)\r
+ rule.setLocationDeep(loc);\r
+ }\r
+ }\r
+\r
+ public void compile(SimplificationContext context) {\r
+ initializeCodeGeneration(context.getCompilationContext());\r
+ UsageAnalysis.analyzeUsage(this);\r
+ for(CHRRule rule : rules)\r
+ rule.compile(context.getCompilationContext(), initConstraint);\r
+ // remove init constraint if it is not useful\r
+ if(initConstraint.plans.isEmpty()) {\r
+ constraints.remove(0);\r
+ initConstraint = null;\r
+ }\r
+ for(CHRConstraint constraint : constraints) {\r
+ constraint.plans.sort((PrioritizedPlan a, PrioritizedPlan b) -> {\r
+ return Integer.compare(a.priority, b.priority);\r
+ });\r
+ /*System.out.println(constraint.name);\r
+ for(PrioritizedPlan plan : constraint.plans) {\r
+ System.out.println(" priority " + plan.priority);\r
+ for(PlanOp op : plan.ops)\r
+ System.out.println(" " + op);\r
+ }*/\r
+ }\r
+ }\r
+\r
+ public void simplify(SimplificationContext context) {\r
+ for(CHRRule rule : rules)\r
+ rule.simplify(context);\r
+ }\r
+ \r
+ public void initializeCodeGeneration(CompilationContext context) {\r
+ cachedContext = context; // FIXME remove\r
+ \r
+ String suffix = context.namingPolicy.getFreshClosureClassNameSuffix();\r
+ storeType = Types.con(context.namingPolicy.getModuleName(), "CHR" + suffix);\r
+ storeClassName = context.namingPolicy.getModuleClassName() + suffix;\r
+ storeTypeDesc = TypeDesc.forClass(storeClassName);\r
+ storeVariable = new BoundVar(storeType); \r
+ for(CHRConstraint constraint : constraints)\r
+ constraint.initializeCodeGeneration(context, this);\r
+ activateProcedure = new JavaMethod(true, storeClassName, "activate", Types.PROC, Types.UNIT, storeType, Types.INTEGER);\r
+ readCurrentId = new CallJava(TVar.EMPTY_ARRAY, Types.PROC, Types.INTEGER, new Type[] {storeType},\r
+ null, new FieldRef(storeClassName, "currentId", CHRCodeGenerator.FACT_ID_TYPE), null);\r
+ writeCurrentId = new CallJava(TVar.EMPTY_ARRAY, Types.PROC, Types.UNIT, new Type[] {storeType, Types.INTEGER},\r
+ null, new SetFieldRef(storeClassName, "currentId", CHRCodeGenerator.FACT_ID_TYPE), null);\r
+ if(context.module != null) // for unit testing\r
+ context.module.addTypeDescriptor(storeType.name, new StandardTypeConstructor(storeType, TVar.EMPTY_ARRAY, storeTypeDesc));\r
+ }\r
+ \r
+ public void generateCode(CodeWriter w) {\r
+ CHRRulesetObject object = new CHRRulesetObject(storeVariable, this);\r
+ w.defineObject(object);\r
+ for(CHRConstraint constraint : constraints) {\r
+ //System.out.println(constraint);\r
+ for(PrioritizedPlan plan : constraint.plans) {\r
+ /*System.out.println(" plan " + plan.priority);\r
+ for(PlanOp planOp : plan.ops)\r
+ System.out.println(" " + planOp);*/\r
+ PlanRealizer realizer = new PlanRealizer(cachedContext, this, storeVariable, plan.ops);\r
+ CodeWriter methodWriter = object.createMethod(w.getModuleWriter(), TVar.EMPTY_ARRAY, Types.PROC, Types.BOOLEAN, new Type[] {constraint.factType});\r
+ plan.implementation = methodWriter.getFunction();\r
+ plan.activeFact.setVal(methodWriter.getParameters()[0]);\r
+ realizer.nextOp(methodWriter);\r
+ if(methodWriter.isUnfinished())\r
+ methodWriter.return_(BooleanConstant.TRUE);\r
+ }\r
+ }\r
+ if(initConstraint != null) {\r
+ IVal initFact = w.apply(location, initConstraint.constructor, IntegerConstant.ZERO);\r
+ w.apply(location, initConstraint.addProcedure, storeVariable, initFact);\r
+ w.apply(location, activateProcedure, storeVariable, new IntegerConstant(Integer.MAX_VALUE));\r
+ }\r
+ }\r
+\r
+ public void collectEffects(THashSet<Type> effects) {\r
+ for(CHRRule rule : rules) {\r
+ for(CHRLiteral literal : rule.head.literals)\r
+ literal.collectQueryEffects(effects);\r
+ for(CHRLiteral literal : rule.head.literals)\r
+ literal.collectEnforceEffects(effects);\r
+ }\r
+ }\r
+}\r
--- /dev/null
+package org.simantics.scl.compiler.elaboration.chr;\r
+\r
+import org.simantics.scl.compiler.constants.Constant;\r
+import org.simantics.scl.compiler.constants.JavaConstructor;\r
+import org.simantics.scl.compiler.internal.codegen.chr.CHRCodeGenerator;\r
+import org.simantics.scl.compiler.internal.codegen.references.BoundVar;\r
+import org.simantics.scl.compiler.internal.codegen.ssa.SSAObject;\r
+import org.simantics.scl.compiler.internal.codegen.utils.ModuleBuilder;\r
+import org.simantics.scl.compiler.types.Types;\r
+\r
+public class CHRRulesetObject extends SSAObject {\r
+ CHRRuleset ruleset;\r
+\r
+ public CHRRulesetObject(BoundVar target, CHRRuleset ruleset) {\r
+ super(ruleset.storeType);\r
+ this.setTarget(target);\r
+ this.ruleset = ruleset;\r
+ }\r
+ \r
+ @Override\r
+ public Constant liftClosure(BoundVar newTarget, BoundVar[] parameters) {\r
+ ruleset.this_ = newTarget;\r
+ ruleset.parameters = parameters;\r
+ return new JavaConstructor(ruleset.storeClassName, Types.PROC, ruleset.storeType, Types.getTypes(parameters));\r
+ }\r
+ \r
+ @Override\r
+ public void generateCode(ModuleBuilder moduleBuilder) {\r
+ CHRCodeGenerator.generateStore(moduleBuilder, ruleset);\r
+ }\r
+}\r
--- /dev/null
+package org.simantics.scl.compiler.elaboration.chr.analysis;\r
+\r
+import java.util.ArrayList;\r
+\r
+import org.simantics.scl.compiler.elaboration.chr.CHRLiteral;\r
+import org.simantics.scl.compiler.elaboration.chr.CHRRule;\r
+import org.simantics.scl.compiler.elaboration.chr.CHRRuleset;\r
+import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint;\r
+\r
+import gnu.trove.map.hash.THashMap;\r
+\r
+public class UsageAnalysis {\r
+ public static void analyzeUsage(CHRRuleset ruleset) {\r
+ THashMap<CHRConstraint,ArrayList<CHRRule>> headConstraintMap = createHeadConstraintMap(ruleset);\r
+ calculateFirstPriorities(ruleset, headConstraintMap);\r
+ calculateLastPriorities(ruleset, headConstraintMap);\r
+ for(CHRRule rule : ruleset.rules)\r
+ determinePassiveLiterals(rule);\r
+ //printPriorities(ruleset);\r
+ }\r
+\r
+ private static void calculateFirstPriorities(CHRRuleset ruleset,\r
+ THashMap<CHRConstraint, ArrayList<CHRRule>> headConstraintMap) {\r
+ for(CHRRule rule : ruleset.rules)\r
+ rule.firstPriorityExecuted = Integer.MAX_VALUE;\r
+ for(CHRConstraint constraint : ruleset.constraints) {\r
+ constraint.firstPriorityAdded = Integer.MAX_VALUE;\r
+ constraint.firstPriorityRemoved = Integer.MAX_VALUE;\r
+ }\r
+ for(CHRRule rule : ruleset.rules)\r
+ calculateFirstPriority(headConstraintMap, rule);\r
+ }\r
+\r
+ private static void calculateFirstPriority(THashMap<CHRConstraint, ArrayList<CHRRule>> headConstraintMap, CHRRule rule) {\r
+ int result = rule.priority;\r
+ for(CHRLiteral literal : rule.head.literals)\r
+ if(literal.relation instanceof CHRConstraint) {\r
+ CHRConstraint constraint = (CHRConstraint)literal.relation;\r
+ int constraintPriority = constraint.firstPriorityAdded;\r
+ if(constraintPriority == Integer.MAX_VALUE)\r
+ return;\r
+ result = Math.max(result, constraint.firstPriorityAdded);\r
+ }\r
+ rule.firstPriorityExecuted = result;\r
+ for(CHRLiteral literal : rule.head.literals)\r
+ if(literal.killAfterMatch && literal.relation instanceof CHRConstraint) {\r
+ CHRConstraint constraint = (CHRConstraint)literal.relation;\r
+ if(constraint.firstPriorityRemoved != Integer.MAX_VALUE)\r
+ continue;\r
+ constraint.firstPriorityRemoved = result;\r
+ }\r
+ for(CHRLiteral literal : rule.body.literals)\r
+ if(literal.relation instanceof CHRConstraint) {\r
+ CHRConstraint constraint = (CHRConstraint)literal.relation;\r
+ if(constraint.firstPriorityAdded != Integer.MAX_VALUE)\r
+ continue;\r
+ constraint.firstPriorityAdded = result;\r
+ ArrayList<CHRRule> list = headConstraintMap.get(constraint);\r
+ if(list == null)\r
+ continue;\r
+ for(CHRRule lowerPriorityRule : list)\r
+ if(lowerPriorityRule.priority < rule.priority)\r
+ calculateFirstPriority(headConstraintMap, lowerPriorityRule);\r
+ }\r
+ }\r
+\r
+ private static void calculateLastPriorities(CHRRuleset ruleset,\r
+ THashMap<CHRConstraint, ArrayList<CHRRule>> headConstraintMap) {\r
+ for(CHRRule rule : ruleset.rules)\r
+ rule.lastPriorityExecuted = Integer.MIN_VALUE;\r
+ for(CHRConstraint constraint : ruleset.constraints) {\r
+ constraint.lastPriorityAdded = Integer.MIN_VALUE;\r
+ constraint.lastPriorityRemoved = Integer.MIN_VALUE;\r
+ }\r
+ for(int i=ruleset.rules.size()-1;i>=0;--i) {\r
+ CHRRule rule = ruleset.rules.get(i);\r
+ if(rule.lastPriorityExecuted == Integer.MIN_VALUE)\r
+ calculateLastPriority(headConstraintMap, rule, rule.priority);\r
+ }\r
+ }\r
+\r
+ private static void calculateLastPriority(THashMap<CHRConstraint, ArrayList<CHRRule>> headConstraintMap,\r
+ CHRRule rule, int priority) {\r
+ rule.lastPriorityExecuted = priority;\r
+ for(CHRLiteral literal : rule.head.literals)\r
+ if(literal.killAfterMatch && literal.relation instanceof CHRConstraint) {\r
+ CHRConstraint constraint = (CHRConstraint)literal.relation;\r
+ if(constraint.lastPriorityRemoved != Integer.MIN_VALUE)\r
+ continue;\r
+ constraint.lastPriorityRemoved = priority;\r
+ }\r
+ for(CHRLiteral literal : rule.body.literals)\r
+ if(literal.relation instanceof CHRConstraint) {\r
+ CHRConstraint constraint = (CHRConstraint)literal.relation;\r
+ if(constraint.lastPriorityAdded != Integer.MIN_VALUE)\r
+ continue;\r
+ constraint.lastPriorityAdded = priority;\r
+ ArrayList<CHRRule> list = headConstraintMap.get(constraint);\r
+ if(list == null)\r
+ continue;\r
+ for(CHRRule lowerPriorityRule : list)\r
+ if(lowerPriorityRule.lastPriorityExecuted == Integer.MIN_VALUE)\r
+ calculateLastPriority(headConstraintMap, lowerPriorityRule, priority);\r
+ }\r
+ }\r
+\r
+ private static THashMap<CHRConstraint, ArrayList<CHRRule>> createHeadConstraintMap(CHRRuleset ruleset) {\r
+ THashMap<CHRConstraint, ArrayList<CHRRule>> map = new THashMap<CHRConstraint, ArrayList<CHRRule>>(); \r
+ for(CHRRule rule : ruleset.rules)\r
+ for(CHRLiteral literal : rule.head.literals)\r
+ if(literal.relation instanceof CHRConstraint) {\r
+ ArrayList<CHRRule> list = map.get(literal.relation);\r
+ if(list == null) {\r
+ list = new ArrayList<CHRRule>();\r
+ map.put((CHRConstraint)literal.relation, list);\r
+ list.add(rule);\r
+ }\r
+ else if(list.get(list.size()-1) != rule)\r
+ list.add(rule);\r
+ }\r
+ return map;\r
+ }\r
+ \r
+ private static void printPriorities(CHRRuleset ruleset) {\r
+ System.out.println("-------------------------------");\r
+ for(CHRConstraint constraint : ruleset.constraints) {\r
+ System.out.print(" [" + constraint.firstPriorityAdded + ".." + constraint.lastPriorityAdded + "]");\r
+ if(constraint.firstPriorityRemoved != Integer.MAX_VALUE)\r
+ System.out.print("R[" + constraint.firstPriorityRemoved + ".." + constraint.lastPriorityRemoved + "]");\r
+ System.out.print(" ");\r
+ System.out.println(constraint);\r
+ }\r
+ for(CHRRule rule : ruleset.rules) {\r
+ System.out.print(rule.priority);\r
+ System.out.print(" [" + rule.firstPriorityExecuted + ".." + rule.lastPriorityExecuted + "] ");\r
+ System.out.println(rule);\r
+ }\r
+ }\r
+\r
+ private static void determinePassiveLiterals(CHRRule rule) {\r
+ for(CHRLiteral literal : rule.head.literals) {\r
+ if(literal.passive)\r
+ continue;\r
+ CHRConstraint constraint = (CHRConstraint)literal.relation;\r
+ if(constraint.lastPriorityAdded < rule.priority)\r
+ literal.passive = true;\r
+ }\r
+ }\r
+}\r
--- /dev/null
+package org.simantics.scl.compiler.elaboration.chr.plan;\r
+\r
+import org.simantics.scl.compiler.compilation.CompilationContext;\r
+import org.simantics.scl.compiler.constants.BooleanConstant;\r
+import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint;\r
+import org.simantics.scl.compiler.elaboration.expressions.Expression;\r
+import org.simantics.scl.compiler.elaboration.expressions.Variable;\r
+import org.simantics.scl.compiler.internal.codegen.references.IVal;\r
+import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;\r
+\r
+public class AccessFactOp extends PlanOp {\r
+\r
+ Expression inputFact;\r
+ CHRConstraint constraint;\r
+ Variable[] variables;\r
+ boolean killAfterMatch;\r
+ \r
+ public AccessFactOp(long location, Expression inputFact, CHRConstraint constraint, Variable[] variables,\r
+ boolean killAfterMatch) {\r
+ super(location);\r
+ this.inputFact = inputFact;\r
+ this.constraint = constraint;\r
+ this.variables = variables;\r
+ this.killAfterMatch = killAfterMatch;\r
+ }\r
+\r
+ @Override\r
+ public void toString(StringBuilder b) {\r
+ b.append("ACCESS ");\r
+ if(killAfterMatch)\r
+ b.append("- ");\r
+ b.append(constraint);\r
+ for(Variable variable : variables)\r
+ b.append(' ').append(variable);\r
+ b.append(" = ").append(inputFact);\r
+ }\r
+\r
+ @Override\r
+ public void generateCode(CompilationContext context, PlanContext planContext, CodeWriter w) {\r
+ IVal inputVal = inputFact.toVal(context.environment, w);\r
+ for(int i=0;i<variables.length;++i)\r
+ variables[i].setVal(w.apply(location, constraint.accessComponent(i), inputVal));\r
+ IVal activeId = w.apply(location, constraint.accessId, inputVal);\r
+ CodeWriter end = constraint.mayBeRemoved() ? w.createBlock() : null;\r
+ planContext.partnerFacts.add(new PartnerFact(true, activeId, constraint, inputVal, constraint.mayBeRemoved(), killAfterMatch, null, null, end == null ? null : end.getContinuation()));\r
+ planContext.nextOp(w);\r
+ if(end != null)\r
+ end.return_(BooleanConstant.FALSE);\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.simantics.scl.compiler.elaboration.chr.plan;\r
+\r
+import org.simantics.scl.compiler.compilation.CompilationContext;\r
+import org.simantics.scl.compiler.elaboration.expressions.Expression;\r
+import org.simantics.scl.compiler.elaboration.expressions.Variable;\r
+import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;\r
+\r
+public class AssignOp extends PlanOp {\r
+ public Variable variable;\r
+ public Expression expression;\r
+ \r
+ public AssignOp(long location, Variable variable, Expression expression) {\r
+ super(location);\r
+ this.variable = variable;\r
+ this.expression = expression;\r
+ }\r
+\r
+ @Override\r
+ public void toString(StringBuilder b) {\r
+ b.append("ASSIGN ").append(variable).append(" = ").append(expression);\r
+ }\r
+\r
+ @Override\r
+ public void generateCode(CompilationContext context, PlanContext planContext, CodeWriter w) {\r
+ variable.setVal(expression.toVal(context.environment, w));\r
+ planContext.nextOp(w);\r
+ }\r
+\r
+ \r
+}\r
--- /dev/null
+package org.simantics.scl.compiler.elaboration.chr.plan;\r
+\r
+import org.simantics.scl.compiler.compilation.CompilationContext;\r
+import org.simantics.scl.compiler.elaboration.expressions.Expression;\r
+import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;\r
+\r
+public class CheckOp extends PlanOp {\r
+ public Expression condition;\r
+\r
+ public CheckOp(long location, Expression condition) {\r
+ super(location);\r
+ this.condition = condition;\r
+ }\r
+ \r
+ @Override\r
+ public void toString(StringBuilder b) {\r
+ b.append("CHECK ").append(condition);\r
+ }\r
+\r
+ @Override\r
+ public void generateCode(CompilationContext context, PlanContext planContext, CodeWriter w) {\r
+ planContext.check(location, w, condition.toVal(context.environment, w));\r
+ }\r
+}\r
--- /dev/null
+package org.simantics.scl.compiler.elaboration.chr.plan;\r
+\r
+import org.simantics.scl.compiler.compilation.CompilationContext;\r
+import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint;\r
+import org.simantics.scl.compiler.elaboration.expressions.Expression;\r
+import org.simantics.scl.compiler.internal.codegen.references.IVal;\r
+import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;\r
+\r
+public class ClaimOp extends PlanOp {\r
+\r
+ CHRConstraint constraint;\r
+ Expression[] parameters;\r
+\r
+ public ClaimOp(long location, CHRConstraint constraint, Expression[] parameters) {\r
+ super(location);\r
+ this.constraint = constraint;\r
+ this.parameters = parameters;\r
+ }\r
+\r
+ @Override\r
+ public void toString(StringBuilder b) {\r
+ b.append("CLAIM ").append(constraint);\r
+ for (Expression parameter : parameters)\r
+ b.append(" (").append(parameter).append(')');\r
+ }\r
+\r
+ @Override\r
+ public void generateCode(CompilationContext context, PlanContext planContext, CodeWriter w) {\r
+ IVal[] parameterVars = new IVal[parameters.length+1];\r
+ parameterVars[0] = planContext.generateNewId(location, w);\r
+ for(int i=0;i<parameters.length;++i)\r
+ parameterVars[i+1] = parameters[i].toVal(context.environment, w);\r
+ IVal newFact = w.apply(location, constraint.constructor, parameterVars);\r
+ w.apply(location, constraint.addProcedure, planContext.storeVar, newFact);\r
+ planContext.nextOp(w);\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.simantics.scl.compiler.elaboration.chr.plan;\r
+\r
+import org.simantics.scl.compiler.compilation.CompilationContext;\r
+import org.simantics.scl.compiler.elaboration.expressions.Expression;\r
+import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;\r
+\r
+public class ExecuteOp extends PlanOp {\r
+ Expression expression;\r
+ \r
+ public ExecuteOp(long location, Expression expression) {\r
+ super(location);\r
+ this.expression = expression;\r
+ }\r
+\r
+ @Override\r
+ public void toString(StringBuilder b) {\r
+ b.append("EXECUTE ").append(expression);\r
+\r
+ }\r
+\r
+ @Override\r
+ public void generateCode(CompilationContext context, PlanContext planContext, CodeWriter w) {\r
+ expression.toVal(context.environment, w);\r
+ planContext.nextOp(w);\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.simantics.scl.compiler.elaboration.chr.plan;\r
+\r
+import java.util.ArrayList;\r
+\r
+import org.simantics.scl.compiler.compilation.CompilationContext;\r
+import org.simantics.scl.compiler.constants.Constant;\r
+import org.simantics.scl.compiler.constants.JavaComparisonOperation;\r
+import org.simantics.scl.compiler.constants.singletons.NullCheck;\r
+import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint;\r
+import org.simantics.scl.compiler.elaboration.expressions.Expression;\r
+import org.simantics.scl.compiler.elaboration.expressions.Variable;\r
+import org.simantics.scl.compiler.internal.codegen.continuations.ICont;\r
+import org.simantics.scl.compiler.internal.codegen.references.IVal;\r
+import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;\r
+import org.simantics.scl.compiler.types.Types;\r
+\r
+public class IterateConstraintOp extends PlanOp {\r
+ \r
+ public CHRConstraint constraint;\r
+ public Variable[] variables;\r
+ public Expression[] expressions;\r
+ public int boundMask;\r
+ public boolean killAfterMatch;\r
+ public boolean passive;\r
+ \r
+ public IterateConstraintOp(long location, CHRConstraint constraint, Variable[] variables, Expression[] expressions,\r
+ int boundMask, boolean killAfterMatch, boolean passive) {\r
+ super(location);\r
+ this.constraint = constraint;\r
+ this.variables = variables;\r
+ this.expressions = expressions;\r
+ this.boundMask = boundMask;\r
+ this.killAfterMatch = killAfterMatch;\r
+ this.passive = passive;\r
+ \r
+ }\r
+\r
+ @Override\r
+ public void toString(StringBuilder b) {\r
+ b.append("ITERATE ").append(constraint);\r
+ for(int i=0;i<expressions.length;++i)\r
+ if((boundMask & (1 << i)) != 0) {\r
+ b.append(" (").append(expressions[i]).append(")");\r
+ }\r
+ else {\r
+ b.append(" ").append(variables[i]);\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public void generateCode(CompilationContext context, PlanContext planContext, CodeWriter w) {\r
+ CodeWriter body = w.createBlock(constraint.factType);\r
+ CodeWriter nextFact = w.createBlock();\r
+ ICont bodyContinuation = body.getContinuation();\r
+ CodeWriter end = w.createBlock();\r
+ IVal fact = body.getParameters()[0];\r
+\r
+ ArrayList<IVal> parameters = new ArrayList<IVal>(expressions.length+1);\r
+ parameters.add(planContext.storeVar);\r
+ for(int i=0;i<expressions.length;++i)\r
+ if(((boundMask>>i)&1)==1)\r
+ parameters.add(expressions[i].toVal(context.environment, w));\r
+ w.jump(bodyContinuation, w.apply(location,\r
+ constraint.fetchFromIndex(context, boundMask), parameters.toArray(new IVal[parameters.size()])));\r
+\r
+ body.branchAwayIf(body.apply(location, NullCheck.INSTANCE.createSpecialization(constraint.factType), fact),\r
+ end.getContinuation());\r
+ IVal id = body.apply(location, constraint.accessId, fact);\r
+ for(PartnerFact partnerFact : planContext.partnerFacts)\r
+ if(partnerFact.active && !passive) {\r
+ body.branchAwayUnless(body.apply(location, JavaComparisonOperation.ILESS, id, partnerFact.id),\r
+ nextFact.getContinuation());\r
+ }\r
+ else if(partnerFact.constraint == constraint) {\r
+ body.branchAwayIf(body.apply(location, JavaComparisonOperation.IEQUAL, id, partnerFact.id),\r
+ nextFact.getContinuation());\r
+ }\r
+\r
+ for(int i=0;i<variables.length;++i)\r
+ if(((boundMask>>i)&1)==0)\r
+ variables[i].setVal(body.apply(location, constraint.accessComponent(i), fact));\r
+ Constant nextElement = constraint.nextElement(context, boundMask);\r
+ planContext.partnerFacts.add(new PartnerFact(false, id, constraint, fact, constraint.mayBeRemoved(), killAfterMatch, nextElement, bodyContinuation, end.getContinuation()));\r
+ planContext.nextOp(body);\r
+ if(body.isUnfinished()) \r
+ body.jump(nextFact.getContinuation());\r
+ nextFact.jump(bodyContinuation, nextFact.apply(location, nextElement, fact));\r
+\r
+ w.continueAs(end);\r
+ } \r
+}\r
--- /dev/null
+package org.simantics.scl.compiler.elaboration.chr.plan;\r
+\r
+\r
+import org.simantics.scl.compiler.compilation.CompilationContext;\r
+import org.simantics.scl.compiler.elaboration.expressions.Expression;\r
+import org.simantics.scl.compiler.elaboration.expressions.Variable;\r
+import org.simantics.scl.compiler.internal.codegen.references.IVal;\r
+import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;\r
+\r
+public class IterateListOp extends PlanOp {\r
+ public Variable variable;\r
+ public Expression list;\r
+ \r
+ public IterateListOp(long location, Variable variable, Expression list) {\r
+ super(location);\r
+ this.variable = variable;\r
+ this.list = list;\r
+ } \r
+ \r
+ @Override\r
+ public void toString(StringBuilder b) {\r
+ b.append("ITERATE ").append(variable).append(" <- ").append(list);\r
+ }\r
+\r
+ @Override\r
+ public void generateCode(CompilationContext context, PlanContext planContext, CodeWriter w) {\r
+ IVal listValue = list.toVal(context.environment, w);\r
+ planContext.iterateList(location, w, variable, listValue);\r
+ }\r
+}\r
--- /dev/null
+package org.simantics.scl.compiler.elaboration.chr.plan;\r
+\r
+import org.simantics.scl.compiler.compilation.CompilationContext;\r
+import org.simantics.scl.compiler.elaboration.expressions.Expression;\r
+import org.simantics.scl.compiler.elaboration.expressions.Variable;\r
+import org.simantics.scl.compiler.elaboration.relations.SCLRelation;\r
+import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;\r
+\r
+public class IterateRelationOp extends PlanOp {\r
+ \r
+ public SCLRelation relation;\r
+ public Variable[] variables;\r
+ public Expression[] expressions;\r
+ public int boundMask;\r
+ \r
+ public IterateRelationOp(long location, SCLRelation relation, Variable[] variables, Expression[] expressions,\r
+ int boundMask) {\r
+ super(location);\r
+ this.relation = relation;\r
+ this.variables = variables;\r
+ this.expressions = expressions;\r
+ this.boundMask = boundMask;\r
+ \r
+ }\r
+\r
+ @Override\r
+ public void toString(StringBuilder b) {\r
+ b.append("ITERATE ").append(relation);\r
+ for(int i=0;i<expressions.length;++i)\r
+ if((boundMask & (1 << i)) != 0) {\r
+ b.append(" (").append(expressions[i]).append(")");\r
+ }\r
+ else {\r
+ b.append(" ").append(variables[i]);\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public void generateCode(CompilationContext context, PlanContext planContext, CodeWriter w) {\r
+ relation.generateIterate(planContext, w, location, boundMask, variables, expressions);\r
+ } \r
+}\r
--- /dev/null
+package org.simantics.scl.compiler.elaboration.chr.plan;\r
+\r
+import java.util.ArrayList;\r
+\r
+import org.simantics.scl.compiler.compilation.CompilationContext;\r
+import org.simantics.scl.compiler.elaboration.expressions.Expression;\r
+import org.simantics.scl.compiler.internal.codegen.references.IVal;\r
+import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;\r
+import org.simantics.scl.compiler.internal.elaboration.matching2.PatternMatchingCompiler2;\r
+import org.simantics.scl.compiler.internal.elaboration.matching2.Row2;\r
+\r
+public class MatchOp extends PlanOp {\r
+ public Expression scrutinee;\r
+ public Expression pattern;\r
+ \r
+ public MatchOp(long location, Expression scrutinee, Expression pattern) {\r
+ super(location);\r
+ this.scrutinee = scrutinee;\r
+ this.pattern = pattern;\r
+ }\r
+ \r
+ @Override\r
+ public void toString(StringBuilder b) {\r
+ b.append("MATCH ").append(pattern).append(" = ").append(scrutinee);\r
+ }\r
+\r
+ @Override\r
+ public void generateCode(CompilationContext context, PlanContext planContext, CodeWriter w) {\r
+ CodeWriter body = w.createBlock();\r
+ CodeWriter end = w.createBlock();\r
+ \r
+ IVal[] scrutineeVals = new IVal[1];\r
+ scrutineeVals[0] = scrutinee.toVal(context.environment, w);\r
+\r
+ ArrayList<Row2> rows = new ArrayList<Row2>(1);\r
+ rows.add(new Row2(new Expression[] {pattern}, body.getContinuation()));\r
+\r
+ PatternMatchingCompiler2.split(w, context.environment, scrutineeVals, end.getContinuation(), rows);\r
+ \r
+ planContext.nextOp(body);\r
+ if(body.isUnfinished())\r
+ body.jump(end.getContinuation());\r
+ \r
+ w.continueAs(end);\r
+ }\r
+}\r
--- /dev/null
+package org.simantics.scl.compiler.elaboration.chr.plan;\r
+\r
+import org.simantics.scl.compiler.constants.Constant;\r
+import org.simantics.scl.compiler.constants.JavaComparisonOperation;\r
+import org.simantics.scl.compiler.constants.JavaComparisonToZeroOperation;\r
+import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint;\r
+import org.simantics.scl.compiler.internal.codegen.continuations.ICont;\r
+import org.simantics.scl.compiler.internal.codegen.references.IVal;\r
+import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;\r
+\r
+public class PartnerFact {\r
+ public final boolean active;\r
+ public final IVal id;\r
+ public final CHRConstraint constraint;\r
+ public final IVal factVar;\r
+ public final boolean mayBeRemoved;\r
+ public final boolean killAfterMatch;\r
+\r
+ public final Constant nextFact;\r
+ public final ICont continueCont;\r
+ public final ICont finishCont;\r
+ \r
+ public PartnerFact(boolean active, IVal id, CHRConstraint constraint, IVal factVar, boolean mayBeRemoved, boolean killAfterMatch,\r
+ Constant nextFact, ICont continueCont, ICont finishCont) {\r
+ this.active = active;\r
+ this.id = id;\r
+ this.constraint = constraint;\r
+ this.factVar = factVar;\r
+ this.mayBeRemoved = mayBeRemoved;\r
+ this.killAfterMatch = killAfterMatch;\r
+ this.nextFact = nextFact;\r
+ this.continueCont = continueCont;\r
+ this.finishCont = finishCont;\r
+ }\r
+ \r
+ public IVal isAlive(long location, CodeWriter w) {\r
+ return w.apply(location, JavaComparisonOperation.IEQUAL, w.apply(location, constraint.accessId, factVar), id);\r
+ }\r
+ \r
+ public IVal isAlive(long location, CodeWriter w, IVal fact) {\r
+ return w.apply(location, JavaComparisonToZeroOperation.IGREATER_OR_EQUAL, w.apply(location, constraint.accessId, fact));\r
+ }\r
+}\r
--- /dev/null
+package org.simantics.scl.compiler.elaboration.chr.plan;\r
+\r
+import java.util.ArrayList;\r
+\r
+import org.simantics.scl.compiler.compilation.CompilationContext;\r
+import org.simantics.scl.compiler.constants.IntegerConstant;\r
+import org.simantics.scl.compiler.constants.JavaComparisonOperation;\r
+import org.simantics.scl.compiler.constants.singletons.IncreaseByOne;\r
+import org.simantics.scl.compiler.constants.singletons.ListElement;\r
+import org.simantics.scl.compiler.constants.singletons.ListLength;\r
+import org.simantics.scl.compiler.elaboration.chr.CHRRuleset;\r
+import org.simantics.scl.compiler.elaboration.expressions.Variable;\r
+import org.simantics.scl.compiler.internal.codegen.continuations.ICont;\r
+import org.simantics.scl.compiler.internal.codegen.references.IVal;\r
+import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;\r
+import org.simantics.scl.compiler.types.Type;\r
+import org.simantics.scl.compiler.types.Types;\r
+\r
+public abstract class PlanContext {\r
+ public CompilationContext context;\r
+ public CHRRuleset ruleset;\r
+ public IVal storeVar;\r
+ public ArrayList<PartnerFact> partnerFacts = new ArrayList<PartnerFact>();\r
+ public IVal currentId;\r
+ \r
+ public PlanContext(CompilationContext context, CHRRuleset ruleset, IVal storeVar) {\r
+ this.context = context;\r
+ this.ruleset = ruleset;\r
+ this.storeVar = storeVar;\r
+ }\r
+\r
+ public abstract void nextOp(CodeWriter w);\r
+\r
+ public IVal generateNewId(long location, CodeWriter w) {\r
+ if(currentId == null)\r
+ currentId = w.apply(location, ruleset.readCurrentId, storeVar);\r
+ IVal result = currentId;\r
+ currentId = w.apply(location, IncreaseByOne.INSTANCE, currentId);\r
+ return result;\r
+ }\r
+ \r
+ public void iterateList(long location, CodeWriter w, Variable variable, IVal listValue) {\r
+ Type componentType = variable.getType();\r
+ IVal listLength = w.apply(location, ListLength.INSTANCE.createSpecialization(componentType), listValue);\r
+ \r
+ CodeWriter body = w.createBlock(Types.INTEGER);\r
+ ICont bodyContinuation = body.getContinuation();\r
+ CodeWriter end = w.createBlock();\r
+ \r
+ w.jump(body.getContinuation(), IntegerConstant.ZERO);\r
+ \r
+ IVal index = body.getParameters()[0];\r
+ body.branchAwayIf(body.apply(location, JavaComparisonOperation.IEQUAL, index, listLength),\r
+ end.getContinuation());\r
+ variable.setVal(body.apply(location, ListElement.INSTANCE.createSpecialization(componentType), listValue, index));\r
+ nextOp(body);\r
+ if(body.isUnfinished())\r
+ body.jump(bodyContinuation, body.apply(location, IncreaseByOne.INSTANCE, index));\r
+ \r
+ w.continueAs(end);\r
+ }\r
+\r
+ public void check(long location, CodeWriter w, IVal booleanValue) {\r
+ CodeWriter end = w.createBlock();\r
+ w.branchAwayUnless(booleanValue, end.getContinuation());\r
+ nextOp(w);\r
+ if(w.isUnfinished())\r
+ w.jump(end.getContinuation());\r
+ w.continueAs(end);\r
+ }\r
+}\r
--- /dev/null
+package org.simantics.scl.compiler.elaboration.chr.plan;\r
+\r
+import org.simantics.scl.compiler.compilation.CompilationContext;\r
+import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;\r
+\r
+public abstract class PlanOp {\r
+ public long location;\r
+\r
+ public PlanOp(long location) {\r
+ this.location = location;\r
+ }\r
+ \r
+ @Override\r
+ public String toString() {\r
+ StringBuilder b = new StringBuilder();\r
+ toString(b);\r
+ return b.toString();\r
+ }\r
+\r
+ public abstract void toString(StringBuilder b);\r
+ public abstract void generateCode(CompilationContext context, PlanContext planContext, CodeWriter w);\r
+}\r
--- /dev/null
+package org.simantics.scl.compiler.elaboration.chr.plan;\r
+\r
+import java.util.List;\r
+\r
+import org.simantics.scl.compiler.compilation.CompilationContext;\r
+import org.simantics.scl.compiler.elaboration.chr.CHRRuleset;\r
+import org.simantics.scl.compiler.internal.codegen.references.IVal;\r
+import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;\r
+\r
+public class PlanRealizer extends PlanContext {\r
+ List<PlanOp> ops;\r
+ int id = 0;\r
+\r
+ public PlanRealizer(CompilationContext context, CHRRuleset ruleset, IVal storeVar, List<PlanOp> ops) {\r
+ super(context, ruleset, storeVar);\r
+ this.ops = ops;\r
+ }\r
+\r
+ @Override\r
+ public void nextOp(CodeWriter w) {\r
+ PlanOp planOp = ops.get(id);\r
+ ++id;\r
+ planOp.generateCode(context, this, w);\r
+ }\r
+ \r
+}\r
--- /dev/null
+package org.simantics.scl.compiler.elaboration.chr.plan;\r
+\r
+import org.simantics.scl.compiler.compilation.CompilationContext;\r
+import org.simantics.scl.compiler.constants.IntegerConstant;\r
+import org.simantics.scl.compiler.constants.singletons.NullCheck;\r
+import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint;\r
+import org.simantics.scl.compiler.internal.codegen.continuations.ICont;\r
+import org.simantics.scl.compiler.internal.codegen.references.IVal;\r
+import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;\r
+\r
+public class PostCommitOp extends PlanOp {\r
+ int priority;\r
+ \r
+ public PostCommitOp(long location, int priority) {\r
+ super(location);\r
+ this.priority = priority;\r
+ }\r
+\r
+ @Override\r
+ public void toString(StringBuilder b) {\r
+ b.append("POST_COMMIT " + priority);\r
+ }\r
+\r
+ @Override\r
+ public void generateCode(CompilationContext context, PlanContext planContext, CodeWriter w) {\r
+ if(planContext.currentId != null) {\r
+ w.apply(location, planContext.ruleset.writeCurrentId, planContext.storeVar, planContext.currentId);\r
+ planContext.currentId = null;\r
+ w.apply(location, planContext.ruleset.activateProcedure, planContext.storeVar, new IntegerConstant(priority));\r
+ }\r
+ for(PartnerFact activeFact : planContext.partnerFacts) {\r
+ if(activeFact.killAfterMatch) {\r
+ if(activeFact.nextFact == null)\r
+ w.jump(activeFact.finishCont);\r
+ else {\r
+ CodeWriter iterateAlive = w.createBlock(activeFact.constraint.factType);\r
+ w.jump(iterateAlive.getContinuation(), w.apply(location, activeFact.nextFact, activeFact.factVar));\r
+ iterateUntilLiveFactFound(iterateAlive, activeFact); \r
+ }\r
+ break;\r
+ }\r
+ else if(activeFact.mayBeRemoved) {\r
+ if(activeFact.nextFact == null) {\r
+ w.branchAwayUnless(activeFact.isAlive(location, w), activeFact.finishCont);\r
+ }\r
+ else {\r
+ CodeWriter failure = w.createBlock();\r
+ CodeWriter iterateAlive = w.createBlock(activeFact.constraint.factType);\r
+ w.branchAwayUnless(activeFact.isAlive(location, w), failure.getContinuation());\r
+ failure.jump(iterateAlive.getContinuation(), failure.apply(location, activeFact.nextFact, activeFact.factVar));\r
+ iterateUntilLiveFactFound(iterateAlive, activeFact); \r
+ }\r
+ }\r
+ }\r
+ // PostCommit does not call nextOp\r
+ }\r
+ \r
+ private void iterateUntilLiveFactFound(CodeWriter w, PartnerFact activeFact) {\r
+ ICont initialContinuation = w.getContinuation();\r
+ CHRConstraint constraint = activeFact.constraint;\r
+ IVal fact = w.getParameters()[0];\r
+ CodeWriter dead = w.createBlock();\r
+ w.branchAwayIf(w.apply(location, NullCheck.INSTANCE.createSpecialization(constraint.factType), fact), activeFact.finishCont);\r
+ w.branchAwayUnless(activeFact.isAlive(location, w, fact), dead.getContinuation());\r
+ w.jump(activeFact.continueCont, fact);\r
+ dead.jump(initialContinuation, dead.apply(location, activeFact.nextFact, fact));\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.simantics.scl.compiler.elaboration.chr.plan;\r
+\r
+import org.simantics.scl.compiler.compilation.CompilationContext;\r
+import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;\r
+\r
+public class PreCommitOp extends PlanOp {\r
+ public PreCommitOp(long location) {\r
+ super(location);\r
+ }\r
+\r
+ @Override\r
+ public void toString(StringBuilder b) {\r
+ b.append("PRE_COMMIT");\r
+ }\r
+\r
+ @Override\r
+ public void generateCode(CompilationContext context, PlanContext planContext, CodeWriter w) {\r
+ for(PartnerFact activeFact : planContext.partnerFacts) {\r
+ if(activeFact.killAfterMatch)\r
+ w.apply(location, activeFact.constraint.removeProcedure, planContext.storeVar, activeFact.factVar);\r
+ }\r
+ planContext.nextOp(w);\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.simantics.scl.compiler.elaboration.chr.plan;\r
+\r
+import java.util.List;\r
+\r
+import org.simantics.scl.compiler.elaboration.expressions.Variable;\r
+import org.simantics.scl.compiler.internal.codegen.ssa.SSAFunction;\r
+\r
+public class PrioritizedPlan {\r
+ public int priority;\r
+ public Variable activeFact;\r
+ public List<PlanOp> ops;\r
+ public SSAFunction implementation;\r
+ \r
+ public PrioritizedPlan(int priority, Variable activeFact, List<PlanOp> ops) {\r
+ this.priority = priority;\r
+ this.activeFact = activeFact;\r
+ this.ops = ops;\r
+ }\r
+}\r
--- /dev/null
+package org.simantics.scl.compiler.elaboration.chr.planning;\r
+\r
+import java.util.Arrays;\r
+\r
+public class PlanPriorityQueue {\r
+ PrePlanItem[] items = new PrePlanItem[16];\r
+ int size = 0;\r
+\r
+ public PrePlanItem head() {\r
+ return items[0];\r
+ }\r
+\r
+ public void pop() {\r
+ items[0].queuePos = -1;\r
+ --size;\r
+ if (size > 0) {\r
+ PrePlanItem e = items[size];\r
+ items[0] = e;\r
+ e.queuePos = 0;\r
+ adjustDown(e);\r
+ }\r
+ items[size] = null;\r
+ }\r
+\r
+ public void add(PrePlanItem e) {\r
+ if (size == items.length)\r
+ items = Arrays.copyOf(items, size + size / 2);\r
+ items[size] = e;\r
+ e.queuePos = size;\r
+ ++size;\r
+ adjustUp(e);\r
+ }\r
+\r
+ private boolean adjustUp(PrePlanItem e) {\r
+ int pos = e.queuePos;\r
+ while (pos > 0) {\r
+ int upId = (pos - 1) / 2;\r
+ PrePlanItem upE = items[upId];\r
+ if (e.compare(upE) >= 0)\r
+ break;\r
+ items[pos] = upE;\r
+ upE.queuePos = pos;\r
+ pos = upId;\r
+ }\r
+ if (e.queuePos != pos) {\r
+ items[pos] = e;\r
+ e.queuePos = pos;\r
+ return true;\r
+ } else\r
+ return false;\r
+ }\r
+\r
+ private void adjustDown(PrePlanItem e) {\r
+ int pos = e.queuePos;\r
+ while (true) {\r
+ int downId = pos * 2 + 1;\r
+ if (downId >= size)\r
+ break;\r
+ if (downId + 1 < size\r
+ && items[downId].compare(items[downId + 1]) > 0)\r
+ ++downId;\r
+ PrePlanItem downE = items[downId];\r
+ if (e.compare(downE) > 0) {\r
+ items[pos] = downE;\r
+ downE.queuePos = pos;\r
+ pos = downId;\r
+ } else\r
+ break;\r
+ }\r
+ if (e.queuePos != pos) {\r
+ items[pos] = e;\r
+ e.queuePos = pos;\r
+ }\r
+ }\r
+\r
+ public void adjust(PrePlanItem e) {\r
+ if(e.queuePos == -1)\r
+ return;\r
+ if (!adjustUp(e))\r
+ adjustDown(e);\r
+ }\r
+\r
+ public boolean isEmpty() {\r
+ return size == 0;\r
+ }\r
+}\r
--- /dev/null
+package org.simantics.scl.compiler.elaboration.chr.planning;\r
+\r
+public abstract class PrePlanItem {\r
+ int queuePos;\r
+ /* Primary priorities:\r
+ * 0 = check\r
+ * 1 = functional calculation\r
+ * 2 = almost completely bound relation\r
+ * 3 = completely inbound relation\r
+ */\r
+ public double primaryPriority = Double.POSITIVE_INFINITY;\r
+ public int secondaryPriority;\r
+ public long location;\r
+ \r
+ public PrePlanItem(int secondaryPriority) {\r
+ this.secondaryPriority = secondaryPriority;\r
+ }\r
+\r
+ public int compare(PrePlanItem other) {\r
+ if(primaryPriority < other.primaryPriority)\r
+ return -1;\r
+ if(primaryPriority > other.primaryPriority)\r
+ return 1;\r
+ return Integer.compare(secondaryPriority, other.secondaryPriority); \r
+ }\r
+\r
+ public abstract void initializeListeners(QueryPlanningContext context);\r
+ public abstract void variableSolved(QueryPlanningContext context, int variableId);\r
+\r
+ public abstract void generate(QueryPlanningContext context);\r
+}\r
--- /dev/null
+package org.simantics.scl.compiler.elaboration.chr.planning;\r
+\r
+import java.util.ArrayList;\r
+\r
+import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
+import org.simantics.scl.compiler.compilation.CompilationContext;\r
+import org.simantics.scl.compiler.elaboration.chr.CHRLiteral;\r
+import org.simantics.scl.compiler.elaboration.chr.plan.AccessFactOp;\r
+import org.simantics.scl.compiler.elaboration.chr.plan.ClaimOp;\r
+import org.simantics.scl.compiler.elaboration.chr.plan.ExecuteOp;\r
+import org.simantics.scl.compiler.elaboration.chr.plan.PlanOp;\r
+import org.simantics.scl.compiler.elaboration.chr.planning.items.CheckPrePlanItem;\r
+import org.simantics.scl.compiler.elaboration.chr.planning.items.EqualsPrePlanItem;\r
+import org.simantics.scl.compiler.elaboration.chr.planning.items.GenericPrePlanItem;\r
+import org.simantics.scl.compiler.elaboration.chr.planning.items.MemberPrePlanItem;\r
+import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint;\r
+import org.simantics.scl.compiler.elaboration.chr.relations.SpecialCHRRelation;\r
+import org.simantics.scl.compiler.elaboration.expressions.EApplyType;\r
+import org.simantics.scl.compiler.elaboration.expressions.EConstant;\r
+import org.simantics.scl.compiler.elaboration.expressions.EExternalConstant;\r
+import org.simantics.scl.compiler.elaboration.expressions.ELiteral;\r
+import org.simantics.scl.compiler.elaboration.expressions.EVariable;\r
+import org.simantics.scl.compiler.elaboration.expressions.Expression;\r
+import org.simantics.scl.compiler.elaboration.expressions.Variable;\r
+\r
+import gnu.trove.impl.Constants;\r
+import gnu.trove.map.hash.TObjectIntHashMap;\r
+import gnu.trove.procedure.TIntProcedure;\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
+public class QueryPlanningContext {\r
+ CompilationContext compilationContext;\r
+ public PlanPriorityQueue priorityQueue = new PlanPriorityQueue();\r
+ ArrayList<Variable> variables;\r
+ TObjectIntHashMap<Variable> variableMap;\r
+ ArrayList<ArrayList<PrePlanItem>> itemsContainingVariable;\r
+ ArrayList<PlanOp> planOps = new ArrayList<PlanOp>(); \r
+ \r
+ public QueryPlanningContext(CompilationContext compilationContext, Variable[] variables) {\r
+ this.compilationContext = compilationContext;\r
+ this.variables = new ArrayList<Variable>(variables.length*2);\r
+ this.variableMap = new TObjectIntHashMap<Variable>(variables.length, Constants.DEFAULT_LOAD_FACTOR, -1);\r
+ itemsContainingVariable = new ArrayList<ArrayList<PrePlanItem>>(variables.length*2);\r
+ for(Variable variable : variables)\r
+ addVariable(variable);\r
+ }\r
+ \r
+ private void addVariable(Variable variable) {\r
+ int id = variables.size();\r
+ variables.add(variable);\r
+ variableMap.put(variable, id);\r
+ itemsContainingVariable.add(new ArrayList<PrePlanItem>(2));\r
+ }\r
+\r
+ public void add(CHRLiteral literal, int secondaryPriority) {\r
+ if(literal.relation instanceof SpecialCHRRelation) {\r
+ switch((SpecialCHRRelation)literal.relation) {\r
+ case CHECK:\r
+ addCheck(literal.location, literal.parameters[0], secondaryPriority);\r
+ return;\r
+ case EQUALS:\r
+ addGenericEquals(literal.location, literal.parameters[0], literal.parameters[1], secondaryPriority);\r
+ return;\r
+ case MEMBER:\r
+ addMember(literal.location, literal.parameters[0], literal.parameters[1], secondaryPriority);\r
+ return;\r
+ case EXECUTE:\r
+ throw new InternalCompilerError(literal.location, "EXECUTE constraint is not allowed in query compilation.");\r
+ }\r
+ }\r
+ \r
+ addGenericConstraint(literal, secondaryPriority);\r
+ }\r
+ \r
+ private TIntHashSet getVars(Expression expression, int initialCapacity) {\r
+ TIntHashSet variableSet = new TIntHashSet(initialCapacity);\r
+ expression.collectVars(variableMap, variableSet);\r
+ return variableSet;\r
+ }\r
+ \r
+ private TIntHashSet[] getVars(Expression[] expressions, int initialCapacity) {\r
+ TIntHashSet[] variableSets = new TIntHashSet[expressions.length];\r
+ for(int i=0;i<expressions.length;++i)\r
+ variableSets[i] = getVars(expressions[i], initialCapacity);\r
+ return variableSets;\r
+ }\r
+ \r
+ /**\r
+ * Returns true, if the expression is so simple, it does not involve any computation.\r
+ */\r
+ private static boolean isSimpleExpression(Expression expression) {\r
+ while(expression instanceof EApplyType)\r
+ expression = ((EApplyType)expression).getExpression();\r
+ return expression instanceof EVariable \r
+ || expression instanceof EConstant\r
+ || expression instanceof ELiteral\r
+ || expression instanceof EExternalConstant;\r
+ }\r
+ \r
+ private Expression toSimpleExpression(Expression expression, int secondaryPriority) {\r
+ if(isSimpleExpression(expression)) \r
+ return expression;\r
+ else {\r
+ Variable temp = new Variable("temp", expression.getType());\r
+ addVariable(temp);\r
+ addOneSidedEquals(expression.location, new EVariable(temp), expression, secondaryPriority);\r
+ return new EVariable(temp);\r
+ }\r
+ }\r
+ \r
+ private Expression[] toSimpleExpressions(Expression[] expressions, int secondaryPriority) {\r
+ Expression[] result = new Expression[expressions.length];\r
+ for(int i=0;i<expressions.length;++i)\r
+ result[i] = toSimpleExpression(expressions[i], secondaryPriority);\r
+ return result;\r
+ }\r
+\r
+ private void addGenericConstraint(CHRLiteral literal, int secondaryPriority) {\r
+ if(literal.killAfterMatch)\r
+ ((CHRConstraint)literal.relation).setMayBeRemoved();\r
+ Expression[] parameters = toSimpleExpressions(literal.parameters, secondaryPriority);\r
+ add(literal.location, new GenericPrePlanItem(literal, literal.relation, parameters, getVars(parameters, 1), secondaryPriority));\r
+ }\r
+\r
+ private void addMember(long location, Expression p1, Expression p2, int secondaryPriority) {\r
+ Expression expression1 = toSimpleExpression(p1, secondaryPriority);\r
+ Expression expression2 = toSimpleExpression(p2, secondaryPriority);\r
+ add(location, new MemberPrePlanItem(expression1, expression2,\r
+ getVars(expression1, 1), getVars(expression2, 1), secondaryPriority));\r
+ }\r
+ \r
+ private void addOneSidedEquals(long location, Expression expression1, Expression expression2, int secondaryPriority) {\r
+ add(location, new EqualsPrePlanItem(expression1, expression2,\r
+ getVars(expression1, 1), getVars(expression2, 4), secondaryPriority));\r
+ }\r
+\r
+ private void addGenericEquals(long location, Expression p1, Expression p2, int secondaryPriority) {\r
+ if(isSimpleExpression(p1))\r
+ addOneSidedEquals(location, p1, p2, secondaryPriority);\r
+ else if(isSimpleExpression(p2))\r
+ addOneSidedEquals(location, p2, p1, secondaryPriority);\r
+ else {\r
+ Variable temp = new Variable("temp", p1.getType());\r
+ addVariable(temp);\r
+ addOneSidedEquals(p1.location, new EVariable(temp), p1, secondaryPriority);\r
+ addOneSidedEquals(p2.location, new EVariable(temp), p2, secondaryPriority);\r
+ }\r
+ }\r
+\r
+ private void addCheck(long location, Expression condition, int secondaryPriority) {\r
+ TIntHashSet variableSet = new TIntHashSet(4);\r
+ condition.collectVars(variableMap, variableSet);\r
+ add(location, new CheckPrePlanItem(condition, variableSet, secondaryPriority));\r
+ }\r
+\r
+ private void add(long location, PrePlanItem item) {\r
+ priorityQueue.add(item);\r
+ item.initializeListeners(this);\r
+ item.location = location;\r
+ }\r
+\r
+ public void listen(TIntHashSet variableSet, PrePlanItem item) {\r
+ variableSet.forEach(new TIntProcedure() {\r
+ @Override\r
+ public boolean execute(int variableId) {\r
+ listen(variableId, item);\r
+ return true;\r
+ }\r
+ });\r
+ }\r
+\r
+ public void listen(int variableId, PrePlanItem item) {\r
+ itemsContainingVariable.get(variableId).add(item);\r
+ }\r
+\r
+ public void createQueryPlan() {\r
+ while(!priorityQueue.isEmpty()) {\r
+ PrePlanItem head = priorityQueue.head();\r
+ priorityQueue.pop();\r
+ head.generate(this);\r
+ }\r
+ }\r
+ \r
+ public ArrayList<PlanOp> getPlanOps() {\r
+ return planOps;\r
+ }\r
+ \r
+ private final TIntProcedure BIND_PROCEDURE = new TIntProcedure() {\r
+ @Override\r
+ public boolean execute(int variableId) {\r
+ ArrayList<PrePlanItem> l = itemsContainingVariable.get(variableId);\r
+ for(PrePlanItem item : l)\r
+ item.variableSolved(QueryPlanningContext.this, variableId);\r
+ l.clear();\r
+ return true;\r
+ }\r
+ };\r
+\r
+ public void bind(TIntHashSet variableSet) {\r
+ variableSet.forEach(BIND_PROCEDURE);\r
+ }\r
+\r
+ public void addPlanOp(PlanOp planOp) {\r
+ planOps.add(planOp);\r
+ }\r
+\r
+ public CompilationContext getCompilationContext() {\r
+ return compilationContext;\r
+ }\r
+\r
+ public void activate(CHRLiteral literal, Expression inputFact, int secondaryPriority) {\r
+ Variable[] variables = new Variable[literal.parameters.length];\r
+ for(int i=0;i<literal.parameters.length;++i)\r
+ variables[i] = new Variable("activeFactComponent" + i, literal.parameters[i].getType());\r
+ if(literal.killAfterMatch)\r
+ ((CHRConstraint)literal.relation).setMayBeRemoved();\r
+ planOps.add(new AccessFactOp(literal.location, inputFact, (CHRConstraint)literal.relation, variables, literal.killAfterMatch));\r
+ for(int i=0;i<literal.parameters.length;++i)\r
+ addOneSidedEquals(literal.parameters[i].location, new EVariable(variables[i]), literal.parameters[i], secondaryPriority);\r
+ }\r
+\r
+ public void claim(QueryPlanningContext context, CHRLiteral literal) {\r
+ if(literal.relation instanceof CHRConstraint) {\r
+ CHRConstraint constraint = (CHRConstraint)literal.relation;\r
+ addPlanOp(new ClaimOp(literal.location, constraint, literal.parameters));\r
+ }\r
+ else if(literal.relation instanceof SpecialCHRRelation) {\r
+ switch((SpecialCHRRelation)literal.relation) {\r
+ case EXECUTE:\r
+ addPlanOp(new ExecuteOp(literal.location, literal.parameters[0]));\r
+ break;\r
+ default:\r
+ context.getCompilationContext().errorLog.log(\r
+ literal.location,\r
+ "Cannot enforce this constraint.");\r
+ }\r
+ }\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.simantics.scl.compiler.elaboration.chr.planning.items;\r
+\r
+import org.simantics.scl.compiler.elaboration.chr.plan.CheckOp;\r
+import org.simantics.scl.compiler.elaboration.chr.planning.PrePlanItem;\r
+import org.simantics.scl.compiler.elaboration.chr.planning.QueryPlanningContext;\r
+import org.simantics.scl.compiler.elaboration.expressions.Expression;\r
+\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
+public class CheckPrePlanItem extends PrePlanItem {\r
+ public Expression condition;\r
+ public TIntHashSet variableSet;\r
+\r
+ public CheckPrePlanItem(Expression condition, TIntHashSet variableSet, int secondaryPriority) {\r
+ super(secondaryPriority);\r
+ this.variableSet = variableSet;\r
+ this.condition = condition;\r
+ if(variableSet.isEmpty())\r
+ primaryPriority = 0.0;\r
+ }\r
+\r
+ @Override\r
+ public void initializeListeners(QueryPlanningContext context) {\r
+ context.listen(variableSet, this);\r
+ }\r
+\r
+ @Override\r
+ public void variableSolved(QueryPlanningContext context, int variableId) {\r
+ variableSet.remove(variableId);\r
+ if(variableSet.isEmpty()) {\r
+ primaryPriority = 0.0;\r
+ context.priorityQueue.adjust(this);\r
+ }\r
+ }\r
+ \r
+ @Override\r
+ public void generate(QueryPlanningContext context) {\r
+ context.addPlanOp(new CheckOp(location, condition));\r
+ context.bind(variableSet);\r
+ }\r
+}\r
--- /dev/null
+package org.simantics.scl.compiler.elaboration.chr.planning.items;\r
+\r
+import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
+import org.simantics.scl.compiler.elaboration.chr.plan.AssignOp;\r
+import org.simantics.scl.compiler.elaboration.chr.plan.CheckOp;\r
+import org.simantics.scl.compiler.elaboration.chr.plan.MatchOp;\r
+import org.simantics.scl.compiler.elaboration.chr.planning.PrePlanItem;\r
+import org.simantics.scl.compiler.elaboration.chr.planning.QueryPlanningContext;\r
+import org.simantics.scl.compiler.elaboration.expressions.EApply;\r
+import org.simantics.scl.compiler.elaboration.expressions.EConstant;\r
+import org.simantics.scl.compiler.elaboration.expressions.EVariable;\r
+import org.simantics.scl.compiler.elaboration.expressions.Expression;\r
+import org.simantics.scl.compiler.elaboration.expressions.Variable;\r
+import org.simantics.scl.compiler.elaboration.java.Builtins;\r
+\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
+public class EqualsPrePlanItem extends PrePlanItem {\r
+ public Expression expression1, expression2;\r
+ public TIntHashSet variableSet1, variableSet2;\r
+\r
+ public EqualsPrePlanItem(Expression expression1, Expression expression2, TIntHashSet variableSet1, TIntHashSet variableSet2, int secondaryPriority) {\r
+ super(secondaryPriority);\r
+ this.expression1 = expression1;\r
+ this.expression2 = expression2;\r
+ this.variableSet1 = variableSet1;\r
+ this.variableSet2 = variableSet2;\r
+ updatePrimaryPriority();\r
+ }\r
+\r
+ private void updatePrimaryPriority() {\r
+ if(variableSet2.isEmpty()) {\r
+ if(variableSet1.isEmpty())\r
+ primaryPriority = 0;\r
+ else \r
+ primaryPriority = 1;\r
+ }\r
+ else {\r
+ if(variableSet1.isEmpty() && expression2.isPattern(0))\r
+ primaryPriority = 0.0;\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public void initializeListeners(QueryPlanningContext context) {\r
+ context.listen(variableSet1, this);\r
+ context.listen(variableSet2, this);\r
+ }\r
+\r
+ @Override\r
+ public void variableSolved(QueryPlanningContext context, int variableId) {\r
+ variableSet1.remove(variableId);\r
+ variableSet2.remove(variableId);\r
+ updatePrimaryPriority();\r
+ context.priorityQueue.adjust(this);\r
+ }\r
+ \r
+ @Override\r
+ public void generate(QueryPlanningContext context) {\r
+ if(variableSet1.isEmpty() && variableSet2.isEmpty()) {\r
+ context.addPlanOp(new CheckOp(location, new EApply(location, new EConstant(Builtins.EQUALS, expression1.getType()), expression1, expression2)));\r
+ }\r
+ else if(variableSet2.isEmpty()) {\r
+ Variable variable = ((EVariable)expression1).getVariable();\r
+ context.addPlanOp(new AssignOp(location, variable, expression2));\r
+ context.bind(variableSet1);\r
+ }\r
+ else if(variableSet1.isEmpty()) {\r
+ if(expression2 instanceof EVariable) {\r
+ Variable variable = ((EVariable)expression2).getVariable();\r
+ context.addPlanOp(new AssignOp(location, variable, expression1));\r
+ }\r
+ else {\r
+ context.addPlanOp(new MatchOp(location, expression1, expression2));\r
+ }\r
+ context.bind(variableSet2);\r
+ }\r
+ else\r
+ throw new InternalCompilerError("Unsolvable query.");\r
+ }\r
+}\r
--- /dev/null
+package org.simantics.scl.compiler.elaboration.chr.planning.items;\r
+\r
+import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
+import org.simantics.scl.compiler.elaboration.chr.CHRLiteral;\r
+import org.simantics.scl.compiler.elaboration.chr.CHRRelation;\r
+import org.simantics.scl.compiler.elaboration.chr.plan.CheckOp;\r
+import org.simantics.scl.compiler.elaboration.chr.plan.IterateConstraintOp;\r
+import org.simantics.scl.compiler.elaboration.chr.plan.IterateRelationOp;\r
+import org.simantics.scl.compiler.elaboration.chr.planning.PrePlanItem;\r
+import org.simantics.scl.compiler.elaboration.chr.planning.QueryPlanningContext;\r
+import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint;\r
+import org.simantics.scl.compiler.elaboration.chr.relations.ExternalCHRRelation;\r
+import org.simantics.scl.compiler.elaboration.expressions.EApply;\r
+import org.simantics.scl.compiler.elaboration.expressions.EConstant;\r
+import org.simantics.scl.compiler.elaboration.expressions.EVariable;\r
+import org.simantics.scl.compiler.elaboration.expressions.Expression;\r
+import org.simantics.scl.compiler.elaboration.expressions.Variable;\r
+import org.simantics.scl.compiler.elaboration.java.Builtins;\r
+import org.simantics.scl.compiler.elaboration.relations.SCLRelation;\r
+\r
+import gnu.trove.set.hash.THashSet;\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
+public class GenericPrePlanItem extends PrePlanItem {\r
+ public CHRLiteral literal;\r
+ public CHRRelation relation;\r
+ public Expression[] expressions;\r
+ public TIntHashSet[] variableSets;\r
+ TIntHashSet allVars;\r
+\r
+ public GenericPrePlanItem(CHRLiteral literal, CHRRelation relation, Expression[] expressions,\r
+ TIntHashSet[] variableSets, int secondaryPriority) {\r
+ super(secondaryPriority);\r
+ this.literal = literal;\r
+ this.relation = relation;\r
+ this.expressions = expressions;\r
+ this.variableSets = variableSets;\r
+ allVars = new TIntHashSet();\r
+ for(TIntHashSet variableSet : variableSets)\r
+ allVars.addAll(variableSet);\r
+ updatePrimaryPriority();\r
+ }\r
+\r
+ private void updatePrimaryPriority() {\r
+ int boundCount = 0;\r
+ int boundMask = 0;\r
+ for(int i=0;i<variableSets.length;++i)\r
+ if(variableSets[i].isEmpty()) {\r
+ ++boundCount;\r
+ boundMask |= 1 << i;\r
+ }\r
+ if(boundCount == variableSets.length)\r
+ primaryPriority = 0;\r
+ else {\r
+ if(relation instanceof ExternalCHRRelation) {\r
+ SCLRelation sclRelation = ((ExternalCHRRelation)relation).relation;\r
+ double selectivity = sclRelation.getSelectivity(boundMask);\r
+ if(selectivity == Double.POSITIVE_INFINITY)\r
+ primaryPriority = Double.POSITIVE_INFINITY;\r
+ else if(selectivity < 1.0)\r
+ primaryPriority = 0.0;\r
+ else if(selectivity == 1.0)\r
+ primaryPriority = 1.0;\r
+ else\r
+ primaryPriority = 3.0 - ((double)boundCount) / variableSets.length;\r
+ }\r
+ else\r
+ primaryPriority = 3.0 - ((double)boundCount) / variableSets.length;\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public void initializeListeners(QueryPlanningContext context) {\r
+ context.listen(allVars, this);\r
+ }\r
+\r
+ @Override\r
+ public void variableSolved(QueryPlanningContext context, int variableId) {\r
+ for(TIntHashSet variableSet : variableSets)\r
+ variableSet.remove(variableId);\r
+ allVars.remove(variableId);\r
+ updatePrimaryPriority();\r
+ context.priorityQueue.adjust(this);\r
+ }\r
+ \r
+ @Override\r
+ public void generate(QueryPlanningContext context) {\r
+ int boundMask = 0;\r
+ Expression[] boundExpressions = new Expression[expressions.length];\r
+ Variable[] freeVariables = new Variable[expressions.length];\r
+ int freeVariableCount = 0;\r
+ for(int i=0;i<expressions.length;++i)\r
+ if(variableSets[i].isEmpty()) {\r
+ boundExpressions[i] = expressions[i];\r
+ boundMask |= 1 << i;\r
+ }\r
+ else {\r
+ freeVariables[i] = ((EVariable)expressions[i]).getVariable();\r
+ ++freeVariableCount;\r
+ }\r
+ if(relation instanceof CHRConstraint)\r
+ context.addPlanOp(new IterateConstraintOp(location, (CHRConstraint)relation, freeVariables, boundExpressions, boundMask,\r
+ killAfterMatch(), literal.passive));\r
+ else if(relation instanceof ExternalCHRRelation)\r
+ context.addPlanOp(new IterateRelationOp(location, ((ExternalCHRRelation)relation).relation,\r
+ freeVariables, boundExpressions, boundMask));\r
+ else\r
+ throw new InternalCompilerError();\r
+ if(freeVariableCount > 1) {\r
+ THashSet<Variable> usedVariables = new THashSet<Variable>(freeVariableCount);\r
+ for(int i=0;i<freeVariables.length;++i) {\r
+ Variable variable = freeVariables[i];\r
+ if(variable == null)\r
+ continue;\r
+ if(!usedVariables.add(variable)) {\r
+ Variable auxiliary = new Variable(variable.getName(), variable.getType());\r
+ freeVariables[i] = auxiliary;\r
+ context.addPlanOp(new CheckOp(location, new EApply(location, new EConstant(Builtins.EQUALS, variable.getType()), new EVariable(auxiliary), new EVariable(variable))));\r
+ }\r
+ }\r
+ }\r
+ context.bind(allVars);\r
+ }\r
+\r
+ private boolean killAfterMatch() {\r
+ return literal.killAfterMatch && relation instanceof CHRConstraint;\r
+ }\r
+}\r
--- /dev/null
+package org.simantics.scl.compiler.elaboration.chr.planning.items;\r
+\r
+import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
+import org.simantics.scl.compiler.common.names.Names;\r
+import org.simantics.scl.compiler.elaboration.chr.plan.CheckOp;\r
+import org.simantics.scl.compiler.elaboration.chr.plan.IterateListOp;\r
+import org.simantics.scl.compiler.elaboration.chr.planning.PrePlanItem;\r
+import org.simantics.scl.compiler.elaboration.chr.planning.QueryPlanningContext;\r
+import org.simantics.scl.compiler.elaboration.expressions.EApply;\r
+import org.simantics.scl.compiler.elaboration.expressions.EConstant;\r
+import org.simantics.scl.compiler.elaboration.expressions.EVariable;\r
+import org.simantics.scl.compiler.elaboration.expressions.Expression;\r
+\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
+public class MemberPrePlanItem extends PrePlanItem {\r
+ public Expression expression1, expression2;\r
+ public TIntHashSet variableSet1, variableSet2;\r
+\r
+ public MemberPrePlanItem(Expression expression1, Expression expression2, TIntHashSet variableSet1, TIntHashSet variableSet2, int secondaryPriority) {\r
+ super(secondaryPriority);\r
+ this.expression1 = expression1;\r
+ this.expression2 = expression2;\r
+ this.variableSet1 = variableSet1;\r
+ this.variableSet2 = variableSet2;\r
+ updatePrimaryPriority();\r
+ }\r
+\r
+ private void updatePrimaryPriority() {\r
+ if(variableSet2.isEmpty()) {\r
+ if(variableSet1.isEmpty())\r
+ primaryPriority = 0;\r
+ else \r
+ primaryPriority = 2.0;\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public void initializeListeners(QueryPlanningContext context) {\r
+ context.listen(variableSet1, this);\r
+ context.listen(variableSet2, this);\r
+ }\r
+\r
+ @Override\r
+ public void variableSolved(QueryPlanningContext context, int variableId) {\r
+ variableSet1.remove(variableId);\r
+ variableSet2.remove(variableId);\r
+ updatePrimaryPriority();\r
+ context.priorityQueue.adjust(this);\r
+ }\r
+\r
+ @Override\r
+ public void generate(QueryPlanningContext context) {\r
+ if(!variableSet2.isEmpty())\r
+ throw new InternalCompilerError("Unsolvable query.");\r
+ if(variableSet1.isEmpty())\r
+ context.addPlanOp(new CheckOp(location,\r
+ new EApply(location,\r
+ new EConstant(context.getCompilationContext().getValue(Names.Prelude_elem)),\r
+ expression1,\r
+ expression2)));\r
+ else\r
+ context.addPlanOp(new IterateListOp(location, ((EVariable)expression1).getVariable(), expression2));\r
+ context.bind(variableSet1);\r
+ }\r
+}\r
--- /dev/null
+package org.simantics.scl.compiler.elaboration.chr.relations;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+\r
+import org.cojen.classfile.TypeDesc;\r
+import org.simantics.scl.compiler.compilation.CompilationContext;\r
+import org.simantics.scl.compiler.constants.Constant;\r
+import org.simantics.scl.compiler.constants.JavaConstructor;\r
+import org.simantics.scl.compiler.constants.JavaMethod;\r
+import org.simantics.scl.compiler.constants.generic.CallJava;\r
+import org.simantics.scl.compiler.constants.generic.MethodRef.FieldRef;\r
+import org.simantics.scl.compiler.constants.generic.MethodRef.ObjectMethodRef;\r
+import org.simantics.scl.compiler.constants.generic.ParameterStackItem;\r
+import org.simantics.scl.compiler.constants.generic.StackItem;\r
+import org.simantics.scl.compiler.elaboration.chr.CHRRelation;\r
+import org.simantics.scl.compiler.elaboration.chr.CHRRuleset;\r
+import org.simantics.scl.compiler.elaboration.chr.plan.PrioritizedPlan;\r
+import org.simantics.scl.compiler.internal.codegen.chr.CHRCodeGenerator;\r
+import org.simantics.scl.compiler.internal.codegen.references.IVal;\r
+import org.simantics.scl.compiler.internal.codegen.types.JavaTypeTranslator;\r
+import org.simantics.scl.compiler.internal.codegen.types.StandardTypeConstructor;\r
+import org.simantics.scl.compiler.internal.parsing.Symbol;\r
+import org.simantics.scl.compiler.types.TCon;\r
+import org.simantics.scl.compiler.types.TVar;\r
+import org.simantics.scl.compiler.types.Type;\r
+import org.simantics.scl.compiler.types.Types;\r
+\r
+import gnu.trove.map.hash.TIntObjectHashMap;\r
+\r
+public class CHRConstraint extends Symbol implements CHRRelation {\r
+ public final String name;\r
+ public final Type[] parameterTypes;\r
+ \r
+ public boolean implicitlyDeclared;\r
+\r
+ // Analysis\r
+ public int firstPriorityAdded;\r
+ public int lastPriorityAdded;\r
+ public int firstPriorityRemoved;\r
+ public int lastPriorityRemoved;\r
+ \r
+ // Transient info\r
+ public CHRRuleset parentRuleset;\r
+ public String factClassName;\r
+ public Type factType;\r
+ public TypeDesc factTypeDesc;\r
+ \r
+ public TCon typeConstructor;\r
+ public Constant constructor;\r
+ public Constant accessId;\r
+ public Constant[] accessors;\r
+ public Constant addProcedure;\r
+ public Constant removeProcedure;\r
+ public Constant isAlive;\r
+ \r
+ public TIntObjectHashMap<IndexInfo> indices;\r
+ \r
+ // Query plans\r
+ public ArrayList<PrioritizedPlan> plans = new ArrayList<PrioritizedPlan>();\r
+ \r
+ public static class IndexInfo {\r
+ public final int indexMask;\r
+ public final String indexName;\r
+ public final Constant firstFact;\r
+ public final Constant nextFact;\r
+ \r
+ public IndexInfo(int indexMask, String indexName, Constant firstFact, Constant nextFact) {\r
+ this.indexMask = indexMask;\r
+ this.indexName = indexName;\r
+ this.firstFact = firstFact;\r
+ this.nextFact = nextFact;\r
+ }\r
+ }\r
+ \r
+ public CHRConstraint(long location, String name, Type[] parameterTypes) {\r
+ this.location = location;\r
+ this.name = name;\r
+ this.parameterTypes = parameterTypes;\r
+ }\r
+\r
+ public void initializeCodeGeneration(CompilationContext context, CHRRuleset parentRuleset) {\r
+ JavaTypeTranslator jtt = context.javaTypeTranslator;\r
+ \r
+ this.parentRuleset = parentRuleset;\r
+ this.factClassName = parentRuleset.storeClassName + "$" + name;\r
+ TCon factTypeConstructor = Types.con(parentRuleset.storeType.module, parentRuleset.storeType.name + "$" + name); \r
+ this.factType = Types.apply(factTypeConstructor, TVar.EMPTY_ARRAY);\r
+ this.factTypeDesc = TypeDesc.forClass(factClassName);\r
+ \r
+ Type[] constructorTypes = new Type[parameterTypes.length+1];\r
+ constructorTypes[0] = Types.INTEGER;\r
+ for(int i=0;i<parameterTypes.length;++i)\r
+ constructorTypes[i+1] = parameterTypes[i];\r
+ this.constructor = new JavaConstructor(factClassName, Types.PROC, factType, constructorTypes);\r
+ this.accessId = new CallJava(TVar.EMPTY_ARRAY, Types.NO_EFFECTS, Types.INTEGER, new Type[] {factType},\r
+ null, new FieldRef(factClassName, "id", CHRCodeGenerator.FACT_ID_TYPE), null);\r
+ this.accessors = new Constant[parameterTypes.length];\r
+ for(int i=0;i<parameterTypes.length;++i)\r
+ this.accessors[i] = new CallJava(TVar.EMPTY_ARRAY, Types.NO_EFFECTS, parameterTypes[i], new Type[] {factType},\r
+ null, new FieldRef(factClassName, "c" + i, jtt.toTypeDesc(parameterTypes[i])), null);\r
+ this.addProcedure = new CallJava(TVar.EMPTY_ARRAY, Types.PROC, Types.UNIT, new Type[] {parentRuleset.storeType, factType},\r
+ new StackItem[] {new ParameterStackItem(1, factType), new ParameterStackItem(0, parentRuleset.storeType)},\r
+ new ObjectMethodRef(false, factClassName, "add", TypeDesc.VOID, new TypeDesc[] {parentRuleset.storeTypeDesc}),\r
+ null);\r
+ \r
+ this.indices = new TIntObjectHashMap<IndexInfo>(Math.min(10, 1 << parameterTypes.length));\r
+ \r
+ if(context.module != null) // for unit testing\r
+ context.module.addTypeDescriptor(factTypeConstructor.name, new StandardTypeConstructor(factTypeConstructor, TVar.EMPTY_ARRAY, factTypeDesc));\r
+ }\r
+\r
+ @Override\r
+ public TVar[] getTypeVariables() {\r
+ return TVar.EMPTY_ARRAY;\r
+ }\r
+\r
+ @Override\r
+ public Type[] getParameterTypes() {\r
+ return parameterTypes;\r
+ }\r
+ \r
+ @Override\r
+ public String toString() {\r
+ return name;\r
+ }\r
+ \r
+ public Collection<IndexInfo> getIndices() {\r
+ return indices.valueCollection();\r
+ }\r
+ \r
+ public boolean mayBeRemoved() {\r
+ return removeProcedure != null;\r
+ }\r
+\r
+ private IndexInfo createIndexInfo(CompilationContext context, int indexMask) {\r
+ ArrayList<Type> keyTypeList = new ArrayList<Type>(parameterTypes.length+1);\r
+ keyTypeList.add(parentRuleset.storeType);\r
+ for(int i=0;i<parameterTypes.length;++i)\r
+ if(((indexMask>>i)&1)==1)\r
+ keyTypeList.add(parameterTypes[i]);\r
+ String indexName = nameOfIndex(indexMask, parameterTypes.length);\r
+ Constant accessIndex;\r
+ if(indexMask == 0) {\r
+ accessIndex = new CallJava(TVar.EMPTY_ARRAY, Types.PROC, factType, new Type[] {parentRuleset.storeType},\r
+ null, new FieldRef(parentRuleset.storeClassName, name + "$" + indexName, factTypeDesc), null);\r
+ }\r
+ else {\r
+ Type[] keyTypes = keyTypeList.toArray(new Type[keyTypeList.size()]);\r
+ accessIndex = new JavaMethod(true, parentRuleset.storeClassName, name + "$" + indexName, Types.PROC, factType, keyTypes);\r
+ }\r
+ return new IndexInfo(\r
+ indexMask,\r
+ indexName,\r
+ accessIndex,\r
+ new CallJava(TVar.EMPTY_ARRAY, Types.PROC, factType, new Type[] {factType},\r
+ null, new FieldRef(factClassName, indexName + "Next", factTypeDesc), null)\r
+ );\r
+ }\r
+\r
+ public Constant accessComponent(int i) {\r
+ return accessors[i];\r
+ }\r
+ \r
+ public IVal fetchFromIndex(CompilationContext context, int boundMask) {\r
+ IndexInfo indexInfo = indices.get(boundMask);\r
+ if(indexInfo == null) {\r
+ indexInfo = createIndexInfo(context, boundMask);\r
+ indices.put(boundMask, indexInfo);\r
+ }\r
+ return indexInfo.firstFact;\r
+ }\r
+\r
+ public Constant nextElement(CompilationContext context, int boundMask) {\r
+ IndexInfo indexInfo = indices.get(boundMask);\r
+ if(indexInfo == null) {\r
+ indexInfo = createIndexInfo(context, boundMask);\r
+ indices.put(boundMask, indexInfo);\r
+ }\r
+ return indexInfo.nextFact;\r
+ }\r
+\r
+ \r
+ public static String nameOfIndex(int indexMask, int length) {\r
+ char[] chars = new char[length];\r
+ for(int i=0;i<length;++i)\r
+ chars[i] = ((indexMask>>i)&1) == 1 ? 'b' : 'f';\r
+ return new String(chars);\r
+ }\r
+\r
+ public void setMayBeRemoved() {\r
+ if(removeProcedure == null) {\r
+ removeProcedure = new CallJava(TVar.EMPTY_ARRAY, Types.PROC, Types.UNIT, new Type[] {parentRuleset.storeType, factType},\r
+ new StackItem[] {new ParameterStackItem(1, factType), new ParameterStackItem(0, parentRuleset.storeType)},\r
+ new ObjectMethodRef(false, factClassName, "remove", TypeDesc.VOID, new TypeDesc[] {parentRuleset.storeTypeDesc}),\r
+ null);\r
+ isAlive = new JavaMethod(true, factClassName, "isAlive", Types.PROC, Types.BOOLEAN, factType);\r
+ }\r
+ }\r
+\r
+ public int getMinimumPriority() {\r
+ return plans.get(0).priority;\r
+ }\r
+ \r
+ public boolean isPassive() {\r
+ return plans.isEmpty();\r
+ }\r
+}\r
--- /dev/null
+package org.simantics.scl.compiler.elaboration.chr.relations;\r
+\r
+import org.simantics.scl.compiler.elaboration.chr.CHRRelation;\r
+import org.simantics.scl.compiler.elaboration.relations.SCLRelation;\r
+import org.simantics.scl.compiler.types.TVar;\r
+import org.simantics.scl.compiler.types.Type;\r
+\r
+public class ExternalCHRRelation implements CHRRelation {\r
+ public final SCLRelation relation;\r
+\r
+ public ExternalCHRRelation(SCLRelation relation) {\r
+ this.relation = relation;\r
+ }\r
+\r
+ @Override\r
+ public TVar[] getTypeVariables() {\r
+ return relation.getTypeVariables();\r
+ }\r
+\r
+ @Override\r
+ public Type[] getParameterTypes() {\r
+ return relation.getParameterTypes();\r
+ }\r
+ \r
+ @Override\r
+ public String toString() {\r
+ return relation.toString();\r
+ }\r
+}\r
--- /dev/null
+package org.simantics.scl.compiler.elaboration.chr.relations;\r
+\r
+import org.simantics.scl.compiler.elaboration.chr.CHRRelation;\r
+import org.simantics.scl.compiler.types.TVar;\r
+import org.simantics.scl.compiler.types.Type;\r
+import org.simantics.scl.compiler.types.Types;\r
+\r
+public enum SpecialCHRRelation implements CHRRelation { \r
+ EQUALS(A, A),\r
+ MEMBER(A, Types.list(A)),\r
+ CHECK(Types.BOOLEAN),\r
+ EXECUTE(Types.UNIT);\r
+ \r
+ private final TVar[] typeVariables;\r
+ private final Type[] parameterTypes;\r
+ \r
+ private SpecialCHRRelation(Type ... parameterTypes) {\r
+ this.typeVariables = Types.freeVarsArray(parameterTypes);\r
+ this.parameterTypes = parameterTypes;\r
+ }\r
+\r
+ @Override\r
+ public TVar[] getTypeVariables() {\r
+ return typeVariables;\r
+ }\r
+ \r
+ @Override\r
+ public Type[] getParameterTypes() {\r
+ return parameterTypes;\r
+ }\r
+}\r
--- /dev/null
+package org.simantics.scl.compiler.elaboration.chr.relations;\r
+\r
+import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
+import org.simantics.scl.compiler.elaboration.chr.CHRRelation;\r
+import org.simantics.scl.compiler.internal.parsing.Symbol;\r
+import org.simantics.scl.compiler.types.TVar;\r
+import org.simantics.scl.compiler.types.Type;\r
+\r
+public class UnresolvedCHRRelation extends Symbol implements CHRRelation {\r
+ public String name;\r
+\r
+ public UnresolvedCHRRelation(long location, String name) {\r
+ this.location = location;\r
+ this.name = name;\r
+ }\r
+\r
+ @Override\r
+ public Type[] getParameterTypes() {\r
+ throw new InternalCompilerError("Encountered unresolved CHRRelation during type checking.");\r
+ }\r
+\r
+ @Override\r
+ public TVar[] getTypeVariables() {\r
+ throw new InternalCompilerError("Encountered unresolved CHRRelation during type checking.");\r
+ }\r
+}\r
--- /dev/null
+package org.simantics.scl.compiler.elaboration.chr.translation;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Arrays;\r
+\r
+import org.simantics.scl.compiler.elaboration.chr.CHRLiteral;\r
+import org.simantics.scl.compiler.elaboration.chr.CHRQuery;\r
+import org.simantics.scl.compiler.elaboration.chr.CHRRule;\r
+import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint;\r
+import org.simantics.scl.compiler.elaboration.chr.relations.SpecialCHRRelation;\r
+import org.simantics.scl.compiler.elaboration.chr.relations.UnresolvedCHRRelation;\r
+import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
+import org.simantics.scl.compiler.elaboration.expressions.EApply;\r
+import org.simantics.scl.compiler.elaboration.expressions.EBinary;\r
+import org.simantics.scl.compiler.elaboration.expressions.EVar;\r
+import org.simantics.scl.compiler.elaboration.expressions.Expression;\r
+import org.simantics.scl.compiler.elaboration.expressions.block.CHRStatement;\r
+import org.simantics.scl.compiler.elaboration.expressions.block.ConstraintStatement;\r
+import org.simantics.scl.compiler.elaboration.expressions.list.ListAssignment;\r
+import org.simantics.scl.compiler.elaboration.expressions.list.ListGenerator;\r
+import org.simantics.scl.compiler.elaboration.expressions.list.ListGuard;\r
+import org.simantics.scl.compiler.elaboration.expressions.list.ListQualifier;\r
+import org.simantics.scl.compiler.environment.AmbiguousNameException;\r
+import org.simantics.scl.compiler.environment.Environments;\r
+import org.simantics.scl.compiler.errors.Locations;\r
+import org.simantics.scl.compiler.internal.parsing.types.TypeAst;\r
+\r
+public class CHRTranslation {\r
+\r
+ private static CHRLiteral convertExpression(boolean isHead, Expression expression) {\r
+ if(isHead)\r
+ return new CHRLiteral(expression.location, SpecialCHRRelation.CHECK, new Expression[] {expression}, false, false);\r
+ else\r
+ return new CHRLiteral(expression.location, SpecialCHRRelation.EXECUTE, new Expression[] {expression}, false, false);\r
+ }\r
+\r
+ private static CHRLiteral convertConstraint(boolean remove, boolean negated, Expression expression) {\r
+ ArrayList<Expression> parameters = new ArrayList<Expression>(4);\r
+ while(expression instanceof EApply) {\r
+ EApply apply = (EApply)expression;\r
+ for(int i=apply.parameters.length-1;i>=0;--i)\r
+ parameters.add(apply.parameters[i]);\r
+ expression = apply.function;\r
+ }\r
+ EVar var = (EVar)expression;\r
+ Expression[] parametersArray = new Expression[parameters.size()];\r
+ for(int i=0,j=parametersArray.length-1;i<parametersArray.length;++i,--j)\r
+ parametersArray[i] = parameters.get(j);\r
+ return new CHRLiteral(expression.location, new UnresolvedCHRRelation(var.location, var.name), parametersArray, remove, negated);\r
+ }\r
+ \r
+ private static CHRLiteral convertListQualifier(TranslationContext context, boolean isHead, ListQualifier qualifier) {\r
+ if(qualifier instanceof ListGuard) {\r
+ Expression originalExpression = ((ListGuard)qualifier).condition;\r
+ if(originalExpression instanceof EVar && ((EVar)originalExpression).name.equals("True"))\r
+ return null;\r
+ Expression currentExpression = originalExpression;\r
+ boolean remove = false;\r
+ boolean negated = false;\r
+ if(currentExpression instanceof EBinary) {\r
+ EBinary binary = (EBinary)currentExpression;\r
+ if(binary.negation==null || !binary.rights.isEmpty())\r
+ return convertExpression(isHead, originalExpression);\r
+ currentExpression = binary.left;\r
+ remove = true;\r
+ }\r
+ else if(currentExpression instanceof EApply) {\r
+ EApply apply = (EApply)currentExpression;\r
+ if(apply.function instanceof EVar && ((EVar)apply.function).name.equals("not")) {\r
+ negated = true;\r
+ if(apply.parameters.length == 1)\r
+ currentExpression = apply.parameters[0];\r
+ else {\r
+ currentExpression = new EApply(\r
+ Locations.combine(apply.parameters[0].location, apply.parameters[apply.parameters.length-1].location),\r
+ apply.parameters[0],\r
+ Arrays.copyOfRange(apply.parameters, 1, apply.parameters.length));\r
+ }\r
+ }\r
+ }\r
+ if(isConstraint(context, currentExpression))\r
+ return convertConstraint(remove, negated, currentExpression);\r
+ else\r
+ return convertExpression(isHead, originalExpression);\r
+ }\r
+ else if(qualifier instanceof ListAssignment) {\r
+ ListAssignment assignment = (ListAssignment)qualifier;\r
+ return new CHRLiteral(assignment.location, SpecialCHRRelation.EQUALS, new Expression[] {\r
+ assignment.pattern, assignment.value \r
+ }, false, false);\r
+ }\r
+ else if(qualifier instanceof ListGenerator) {\r
+ ListGenerator generator = (ListGenerator)qualifier;\r
+ return new CHRLiteral(generator.location, SpecialCHRRelation.MEMBER, new Expression[] {\r
+ generator.pattern, generator.value\r
+ }, false, false);\r
+ }\r
+ else {\r
+ context.getErrorLog().log(qualifier.location, "Invalid CHR literal.");\r
+ return null;\r
+ }\r
+ }\r
+ \r
+ private static boolean isConstraint(TranslationContext context, Expression expression) {\r
+ while(expression instanceof EApply)\r
+ expression = ((EApply)expression).function;\r
+ if(!(expression instanceof EVar))\r
+ return false;\r
+ String name = ((EVar)expression).name;\r
+ if(TranslationContext.isConstructorName(name))\r
+ return true;\r
+ try {\r
+ return Environments.getRelation(context.getEnvironment(), name) != null;\r
+ } catch (AmbiguousNameException e) {\r
+ return true;\r
+ }\r
+ }\r
+\r
+ public static CHRRule convertCHRStatement(TranslationContext context, CHRStatement statement) {\r
+ ArrayList<CHRLiteral> head = new ArrayList<CHRLiteral>(statement.head.length);\r
+ for(ListQualifier qualifier : statement.head) {\r
+ CHRLiteral literal = convertListQualifier(context, true, qualifier);\r
+ if(literal != null)\r
+ head.add(literal);\r
+ }\r
+ ArrayList<CHRLiteral> body = new ArrayList<CHRLiteral>(statement.body.length);\r
+ for(ListQualifier qualifier : statement.body) {\r
+ CHRLiteral literal = convertListQualifier(context, false, qualifier);\r
+ if(literal != null)\r
+ body.add(literal);\r
+ }\r
+ return new CHRRule(statement.location,\r
+ new CHRQuery(head.toArray(new CHRLiteral[head.size()])),\r
+ new CHRQuery(body.toArray(new CHRLiteral[body.size()])),\r
+ null);\r
+ }\r
+\r
+ public static CHRConstraint convertConstraintStatement(TranslationContext context, ConstraintStatement statement) {\r
+ return new CHRConstraint(statement.location, statement.name.text, TypeAst.toTypes(context, statement.parameterTypes));\r
+ }\r
+ \r
+}\r
import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
import org.simantics.scl.compiler.common.names.Name;
+import org.simantics.scl.compiler.common.names.Names;
+import org.simantics.scl.compiler.compilation.CompilationContext;
import org.simantics.scl.compiler.constants.Constant;
import org.simantics.scl.compiler.elaboration.expressions.Case;
import org.simantics.scl.compiler.elaboration.expressions.EApply;
import gnu.trove.map.hash.THashMap;
public class SimplificationContext implements EnvironmentalContext {
+ CompilationContext compilationContext;
Environment environment;
ErrorLog errorLog;
- public static final Name MAP_LIST = Name.create("Prelude", "mapList");
- public static final Name GUARD_LIST = Name.create("Prelude", "guardList");
- public static final Name CONCAT_MAP = Name.create("Prelude", "concatMap");
- public static final Name EMPTY_LIST = Name.create("Prelude", "emptyList");
- public static final Name SINGLETON_LIST = Name.create("Prelude", "singletonList");
- public static final Name APPEND_LIST = Name.create("Prelude", "appendList");
- public static final Name ADD_LIST = Name.create("Prelude", "addList");
- public static final Name FROM_INTEGER = Name.create("Prelude", "fromInteger");
- public static final Name FROM_DOUBLE = Name.create("Prelude", "fromDouble");
-
THashMap<Name, SCLValue> constants = new THashMap<Name, SCLValue>();
THashMap<Variable, Expression> inlinedVariables = new THashMap<Variable, Expression>();
JavaTypeTranslator javaTypeTranslator;
JavaReferenceValidator<?, ?, ?, ?> validator;
- public SimplificationContext(Environment environment, ErrorLog errorLog,
- JavaTypeTranslator javaTypeTranslator, JavaReferenceValidator<?, ?, ?, ?> validator) {
- this.environment = environment;
- this.errorLog = errorLog;
- this.javaTypeTranslator = javaTypeTranslator;
+ public SimplificationContext(CompilationContext compilationContext, JavaReferenceValidator<?, ?, ?, ?> validator) {
+ this.compilationContext = compilationContext;
+ this.environment = compilationContext.environment;
+ this.errorLog = compilationContext.errorLog;
+ this.javaTypeTranslator = compilationContext.javaTypeTranslator;
this.validator = validator;
}
public Expression mapList(Expression f, Expression l) {
try {
MultiFunction mfun = Types.matchFunction(f.getType(), 1);
- return apply(getConstant(MAP_LIST, new Type[] {mfun.parameterTypes[0], mfun.returnType}), f, l);
+ return apply(getConstant(Names.Prelude_mapList, new Type[] {mfun.parameterTypes[0], mfun.returnType}), f, l);
} catch (MatchException e) {
throw new InternalCompilerError(e);
}
}
public Expression guardList(Expression cond) {
- return apply(getConstant(GUARD_LIST), cond);
+ return apply(getConstant(Names.Prelude_guardList), cond);
}
public Expression concatMap(Expression f, Expression l) {
try {
MultiFunction mfun = Types.matchFunction(f.getType(), 1);
- return apply(getConstant(CONCAT_MAP, new Type[] {
+ return apply(getConstant(Names.Prelude_concatMap, new Type[] {
mfun.parameterTypes[0], mfun.effect,
Types.matchApply(Types.LIST, mfun.returnType)}
), f, l);
}
public Expression emptyList(Type type) {
- return getConstant(EMPTY_LIST, type);
+ return getConstant(Names.Prelude_emptyList, type);
}
public Expression singletonList(Expression e) {
- return apply(getConstant(SINGLETON_LIST, e.getType()), e);
+ return apply(getConstant(Names.Prelude_singletonList, e.getType()), e);
}
public Expression match(Expression scrutinee, Expression pattern, Expression value) {
return new EApply(
Locations.NO_LOCATION,
Types.PROC,
- getConstant(Name.create("Prelude", "iterList"), variable.getType(), Types.PROC, Types.tupleConstructor(0)),
+ getConstant(Names.Prelude_iterList, variable.getType(), Types.PROC, Types.tupleConstructor(0)),
new Expression[] {
new ESimpleLambda(Types.PROC, variable, continuation),
list
return new EApply(
Locations.NO_LOCATION,
Types.PROC,
- getConstant(Name.create("Vector", "iterVector"), variable.getType(), Types.PROC, Types.tupleConstructor(0)),
+ getConstant(Names.Vector_iterVector, variable.getType(), Types.PROC, Types.tupleConstructor(0)),
new Expression[] {
new ESimpleLambda(Types.PROC, variable, continuation),
vector
result[i] = new EVariable(parameters[i]);
return result;
}
+
+ public CompilationContext getCompilationContext() {
+ return compilationContext;
+ }
}
\ No newline at end of file
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.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;
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);
}
}
}
+ 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();
}
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]);
+ 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;
+
+ 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) {
package org.simantics.scl.compiler.elaboration.contexts;
+import org.simantics.scl.compiler.compilation.CompilationContext;
import org.simantics.scl.compiler.environment.Environment;
import org.simantics.scl.compiler.errors.ErrorLog;
import org.simantics.scl.compiler.internal.parsing.exceptions.SCLSyntaxErrorException;
public class TypeTranslationContext {
+ CompilationContext compilationContext;
+
Environment environment;
ErrorLog errorLog;
THashMap<String, TVar> typeVariables = new THashMap<String, TVar>();
- public TypeTranslationContext(ErrorLog errorLog, Environment environment) {
- this.errorLog = errorLog;
- this.environment = environment;
+ public TypeTranslationContext(CompilationContext compilationContext) {
+ this.compilationContext = compilationContext;
+ this.errorLog = compilationContext.errorLog;
+ this.environment = compilationContext.environment;
}
/**
}
public Kind getKind(TCon con) {
- return environment.getTypeConstructor(con).kind;
+ return environment.getTypeDescriptor(con).getKind();
}
/**
import java.util.ArrayList;
import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
-import org.simantics.scl.compiler.common.names.Name;
+import org.simantics.scl.compiler.compilation.CompilationContext;
import org.simantics.scl.compiler.constants.NoRepConstant;
import org.simantics.scl.compiler.elaboration.expressions.EAmbiguous;
import org.simantics.scl.compiler.elaboration.expressions.EApply;
-import org.simantics.scl.compiler.elaboration.expressions.EConstant;
-import org.simantics.scl.compiler.elaboration.expressions.EError;
import org.simantics.scl.compiler.elaboration.expressions.ELiteral;
import org.simantics.scl.compiler.elaboration.expressions.EPlaceholder;
import org.simantics.scl.compiler.elaboration.expressions.EVariable;
import org.simantics.scl.compiler.elaboration.modules.SCLValue;
import org.simantics.scl.compiler.environment.Environment;
import org.simantics.scl.compiler.errors.ErrorLog;
-import org.simantics.scl.compiler.errors.Locations;
import org.simantics.scl.compiler.internal.elaboration.constraints.Constraint;
import org.simantics.scl.compiler.internal.elaboration.constraints.ConstraintEnvironment;
import org.simantics.scl.compiler.internal.elaboration.constraints.ConstraintSolver;
import gnu.trove.map.hash.THashMap;
import gnu.trove.set.hash.THashSet;
-public class TypingContext implements EnvironmentalContext {
+public class TypingContext {
- private ErrorLog errorLog;
+ private CompilationContext compilationContext;
// Subsumption
private ArrayList<Subsumption> effectSubsumptions = new ArrayList<Subsumption>();
//TypeUnparsingContext tuc = new TypeUnparsingContext();
Environment environment;
- THashMap<Name, SCLValue> constants = new THashMap<Name, SCLValue>();
- public TypingContext(ErrorLog errorLog, Environment environment) {
- this.errorLog = errorLog;
- this.environment = environment;
+ public TypingContext(CompilationContext compilationContext) {
+ this.compilationContext = compilationContext;
+ this.environment = compilationContext.environment;
}
/**
try {
Types.unify(a, Types.NO_EFFECTS);
} catch(UnificationException e) {
- errorLog.log(loc, "No side-effects allowed here.");
+ compilationContext.errorLog.log(loc, "No side-effects allowed here.");
return;
}
}
try {
subsume(sub.loc, a, b);
} catch (UnificationException e) {
- errorLog.log(sub.loc, "Type " + a + " is not a subtype of " + b + ".");
+ compilationContext.errorLog.log(sub.loc, "Type " + a + " is not a subtype of " + b + ".");
}
nontrivialSubs = true;
}
try {
Types.unify(sub.a, sub.b);
} catch (UnificationException e) {
- errorLog.log(sub.loc, "Unification of types failed.");
+ compilationContext.errorLog.log(sub.loc, "Unification of types failed.");
return false;
}
if(type instanceof TMetaVar)
return ((TMetaVar)type).getKind() == Kinds.EFFECT;
else if(type instanceof TCon)
- return environment.getTypeConstructor((TCon)type).kind == Kinds.EFFECT;
+ return environment.getTypeDescriptor((TCon)type).getKind() == Kinds.EFFECT;
else if(type instanceof TVar)
return ((TVar)type).getKind() == Kinds.EFFECT;
else if(type instanceof TUnion)
public void solveSubsumptions(long globalLoc) {
if(expandSubsumptions())
- new SubSolver(errorLog, effectSubsumptions, potentialSingletonEffects, globalLoc).solve();
+ new SubSolver(compilationContext.errorLog, effectSubsumptions, potentialSingletonEffects, globalLoc).solve();
}
public void declareEffect(long loc, Type effect) {
}
public ErrorLog getErrorLog() {
- return errorLog;
+ return compilationContext.errorLog;
}
public boolean isInPattern() {
public void typeError(long loc, Type requiredType, Type givenType) {
TypeUnparsingContext tuc = new TypeUnparsingContext();
- errorLog.log(loc, "Expected <" + requiredType.toString(tuc) + "> got <" + givenType.toString(tuc) + ">.");
+ compilationContext.errorLog.log(loc, "Expected <" + requiredType.toString(tuc) + "> got <" + givenType.toString(tuc) + ">.");
}
public Expression solveConstraints(Environment environment, Expression expression) {
expression);
for(Constraint c : red.unsolvedConstraints)
- errorLog.log(c.getDemandLocation(), "There is no instance for <"+c.constraint+">.");
+ compilationContext.errorLog.log(c.getDemandLocation(), "There is no instance for <"+c.constraint+">.");
}
else
expression = expression.decomposeMatching();
return expression;
}
-
- public SCLValue getValue(Name name) {
- if(constants.containsKey(name))
- return constants.get(name);
- SCLValue value = environment.getValue(name);
- if(value == null)
- errorLog.log(Locations.NO_LOCATION, "Couldn't find " + name + ".");
- constants.put(name, value);
- return value;
- }
-
- public Expression getConstant(Name name, Type ... typeParameters) {
- SCLValue value = getValue(name);
- if(value == null)
- return new EError(Locations.NO_LOCATION);
- return new EConstant(value, typeParameters);
- }
public Environment getEnvironment() {
- return environment;
+ return compilationContext.environment;
+ }
+
+ public CompilationContext getCompilationContext() {
+ return compilationContext;
}
}
-package org.simantics.scl.compiler.elaboration.expressions;\r
-\r
-import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;\r
-import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;\r
-import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
-import org.simantics.scl.compiler.elaboration.contexts.TypingContext;\r
-import org.simantics.scl.compiler.errors.Locations;\r
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;\r
-import org.simantics.scl.compiler.internal.parsing.Symbol;\r
-import org.simantics.scl.compiler.types.Type;\r
-\r
-import gnu.trove.map.hash.TObjectIntHashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
-public class Case extends Symbol {\r
- public Expression[] patterns;\r
- public Expression value;\r
- \r
- long lhs;\r
- \r
- public Case(Expression[] patterns, Expression value) {\r
- this.patterns = patterns;\r
- this.value = value;\r
- }\r
- \r
- public Case(Expression pattern, Expression value) {\r
- this(new Expression[] {pattern}, value);\r
- }\r
-\r
- public void setLhs(long lhs) {\r
- this.lhs = lhs;\r
- }\r
- \r
- public long getLhs() {\r
- return lhs;\r
- }\r
-\r
- public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {\r
- value.collectRefs(allRefs, refs);\r
- }\r
-\r
- public void collectVars(TObjectIntHashMap<Variable> allVars,\r
- TIntHashSet vars) {\r
- value.collectVars(allVars, vars);\r
- }\r
-\r
- public void collectFreeVariables(THashSet<Variable> vars) {\r
- value.collectFreeVariables(vars);\r
- for(int i=patterns.length-1;i>=0;--i)\r
- patterns[i].removeFreeVariables(vars);\r
- }\r
-\r
- public void resolve(TranslationContext context) {\r
- context.pushFrame();\r
- for(int i=0;i<patterns.length;++i)\r
- patterns[i] = patterns[i].resolveAsPattern(context);\r
- value = value.resolve(context);\r
- context.popFrame();\r
- }\r
-\r
- public void simplify(SimplificationContext context) {\r
- for(int i=0;i<patterns.length;++i)\r
- patterns[i] = patterns[i].simplify(context);\r
- value = value.simplify(context);\r
- }\r
-\r
- public void setLocationDeep(long loc) {\r
- if(location == Locations.NO_LOCATION) {\r
- location = loc;\r
- for(Expression pattern : patterns)\r
- pattern.setLocationDeep(loc);\r
- value.setLocationDeep(loc);\r
- }\r
- }\r
-\r
- public Case replace(ReplaceContext context) {\r
- Expression[] newPatterns = new Expression[patterns.length]; \r
- for(int i=0;i<patterns.length;++i)\r
- newPatterns[i] = patterns[i].replaceInPattern(context);\r
- Expression newValue = value.replace(context);\r
- Case result = new Case(newPatterns, newValue);\r
- result.setLhs(lhs);\r
- return result;\r
- }\r
-\r
- public Expression[] getPatterns() {\r
- return patterns;\r
- }\r
-\r
- public void checkType(TypingContext context, Type[] parameterTypes,\r
- Type requiredType) {\r
- if(patterns.length != parameterTypes.length) {\r
- context.getErrorLog().log(location, "This case has different arity ("+patterns.length+\r
- ") than than the first case (+"+parameterTypes.length+"+).");\r
- return;\r
- }\r
- for(int i=0;i<patterns.length;++i)\r
- patterns[i] = patterns[i].checkTypeAsPattern(context, parameterTypes[i]);\r
- value = value.checkType(context, requiredType);\r
- }\r
- \r
- public void checkIgnoredType(TypingContext context, Type[] parameterTypes) {\r
- if(patterns.length != parameterTypes.length) {\r
- context.getErrorLog().log(location, "This case has different arity ("+patterns.length+\r
- ") than than the first case (+"+parameterTypes.length+"+).");\r
- return;\r
- }\r
- for(int i=0;i<patterns.length;++i)\r
- patterns[i] = patterns[i].checkTypeAsPattern(context, parameterTypes[i]);\r
- value = value.checkIgnoredType(context);\r
- }\r
- \r
- public void decorate(ExpressionDecorator decorator) {\r
- for(int i=0;i<patterns.length;++i)\r
- patterns[i] = patterns[i].decorate(decorator);\r
- value = value.decorate(decorator);\r
- }\r
-\r
- public void forVariables(VariableProcedure procedure) {\r
- value.forVariables(procedure);\r
- }\r
-}\r
+package org.simantics.scl.compiler.elaboration.expressions;
+
+import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;
+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.errors.Locations;
+import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
+import org.simantics.scl.compiler.internal.parsing.Symbol;
+import org.simantics.scl.compiler.types.Type;
+
+import gnu.trove.map.hash.TObjectIntHashMap;
+import gnu.trove.set.hash.THashSet;
+import gnu.trove.set.hash.TIntHashSet;
+
+public class Case extends Symbol {
+ public Expression[] patterns;
+ public Expression value;
+
+ long lhs;
+
+ public Case(Expression[] patterns, Expression value) {
+ this.patterns = patterns;
+ this.value = value;
+ }
+
+ public Case(Expression pattern, Expression value) {
+ this(new Expression[] {pattern}, value);
+ }
+
+ public void setLhs(long lhs) {
+ this.lhs = lhs;
+ }
+
+ public long getLhs() {
+ return lhs;
+ }
+
+ public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {
+ value.collectRefs(allRefs, refs);
+ }
+
+ public void collectVars(TObjectIntHashMap<Variable> allVars,
+ TIntHashSet vars) {
+ value.collectVars(allVars, vars);
+ }
+
+ public void collectFreeVariables(THashSet<Variable> vars) {
+ value.collectFreeVariables(vars);
+ for(int i=patterns.length-1;i>=0;--i)
+ patterns[i].removeFreeVariables(vars);
+ }
+
+ public void resolve(TranslationContext context) {
+ context.pushFrame();
+ for(int i=0;i<patterns.length;++i)
+ patterns[i] = patterns[i].resolveAsPattern(context);
+ value = value.resolve(context);
+ context.popFrame();
+ }
+
+ public void simplify(SimplificationContext context) {
+ for(int i=0;i<patterns.length;++i)
+ patterns[i] = patterns[i].simplify(context);
+ value = value.simplify(context);
+ }
+
+ public void setLocationDeep(long loc) {
+ if(location == Locations.NO_LOCATION) {
+ location = loc;
+ for(Expression pattern : patterns)
+ pattern.setLocationDeep(loc);
+ value.setLocationDeep(loc);
+ }
+ }
+
+ public Case replace(ReplaceContext context) {
+ Expression[] newPatterns = new Expression[patterns.length];
+ for(int i=0;i<patterns.length;++i)
+ newPatterns[i] = patterns[i].replaceInPattern(context);
+ Expression newValue = value.replace(context);
+ Case result = new Case(newPatterns, newValue);
+ result.setLhs(lhs);
+ return result;
+ }
+
+ public Expression[] getPatterns() {
+ return patterns;
+ }
+
+ public void checkType(TypingContext context, Type[] parameterTypes,
+ Type requiredType) {
+ if(patterns.length != parameterTypes.length) {
+ context.getErrorLog().log(location, "This case has different arity ("+patterns.length+
+ ") than than the first case (+"+parameterTypes.length+"+).");
+ return;
+ }
+ for(int i=0;i<patterns.length;++i)
+ patterns[i] = patterns[i].checkTypeAsPattern(context, parameterTypes[i]);
+ value = value.checkType(context, requiredType);
+ }
+
+ public void checkIgnoredType(TypingContext context, Type[] parameterTypes) {
+ if(patterns.length != parameterTypes.length) {
+ context.getErrorLog().log(location, "This case has different arity ("+patterns.length+
+ ") than than the first case (+"+parameterTypes.length+"+).");
+ return;
+ }
+ for(int i=0;i<patterns.length;++i)
+ patterns[i] = patterns[i].checkTypeAsPattern(context, parameterTypes[i]);
+ value = value.checkIgnoredType(context);
+ }
+
+ public void decorate(ExpressionDecorator decorator) {
+ for(int i=0;i<patterns.length;++i)
+ patterns[i] = patterns[i].decorate(decorator);
+ value = value.decorate(decorator);
+ }
+
+ public void forVariables(VariableProcedure procedure) {
+ value.forVariables(procedure);
+ }
+}
}
@Override
- public int getFunctionDefinitionArity() throws NotPatternException {
- return expression.getFunctionDefinitionArity();
+ public int getFunctionDefinitionPatternArity() throws NotPatternException {
+ return expression.getFunctionDefinitionPatternArity();
}
@Override
expression = expression.checkIgnoredType(context);
return this;
}
+
+ @Override
+ public int getSyntacticFunctionArity() {
+ return expression.getSyntacticFunctionArity();
+ }
}
-package org.simantics.scl.compiler.elaboration.expressions;\r
-\r
-import java.util.ArrayList;\r
-\r
-import org.simantics.scl.compiler.common.names.Name;\r
-import org.simantics.scl.compiler.constants.NoRepConstant;\r
-import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;\r
-import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;\r
-import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
-import org.simantics.scl.compiler.elaboration.contexts.TypingContext;\r
-import org.simantics.scl.compiler.elaboration.errors.NotPatternException;\r
-import org.simantics.scl.compiler.elaboration.expressions.lhstype.LhsType;\r
-import org.simantics.scl.compiler.elaboration.expressions.lhstype.PatternMatchingLhs;\r
-import org.simantics.scl.compiler.elaboration.java.ListConstructor;\r
-import org.simantics.scl.compiler.elaboration.macros.MacroRule;\r
-import org.simantics.scl.compiler.elaboration.modules.SCLValue;\r
-import org.simantics.scl.compiler.environment.Environment;\r
-import org.simantics.scl.compiler.errors.Locations;\r
-import org.simantics.scl.compiler.internal.codegen.references.IVal;\r
-import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;\r
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;\r
-import org.simantics.scl.compiler.internal.interpreted.IApply;\r
-import org.simantics.scl.compiler.internal.interpreted.IExpression;\r
-import org.simantics.scl.compiler.internal.interpreted.IListLiteral;\r
-import org.simantics.scl.compiler.top.ExpressionInterpretationContext;\r
-import org.simantics.scl.compiler.types.Skeletons;\r
-import org.simantics.scl.compiler.types.TFun;\r
-import org.simantics.scl.compiler.types.Type;\r
-import org.simantics.scl.compiler.types.Types;\r
-import org.simantics.scl.compiler.types.exceptions.MatchException;\r
-import org.simantics.scl.compiler.types.exceptions.UnificationException;\r
-import org.simantics.scl.compiler.types.kinds.Kinds;\r
-import org.simantics.scl.compiler.types.util.MultiFunction;\r
-\r
-import gnu.trove.map.hash.TObjectIntHashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
-public class EApply extends Expression {\r
- Expression function;\r
- Expression[] parameters;\r
- Type effect = Types.NO_EFFECTS;\r
- \r
- public EApply(Expression function, Expression ... parameters) {\r
- this.function = function;\r
- this.parameters = parameters;\r
- }\r
- \r
- public EApply(Expression function, Expression parameter) {\r
- this(function, new Expression[] {parameter});\r
- }\r
-\r
- public EApply(long loc, Expression function, Expression ... parameters) {\r
- super(loc);\r
- this.function = function;\r
- this.parameters = parameters;\r
- }\r
- \r
- public EApply(long loc, Type effect, Expression function, Expression ... parameters) {\r
- super(loc);\r
- this.effect = effect;\r
- this.function = function;\r
- this.parameters = parameters;\r
- }\r
- \r
- public void set(Expression function, Expression[] parameters) {\r
- this.function = function;\r
- this.parameters = parameters;\r
- }\r
-\r
- public Expression getFunction() {\r
- return function;\r
- }\r
- \r
- public Expression[] getParameters() {\r
- return parameters;\r
- }\r
- \r
-\r
- public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {\r
- function.collectRefs(allRefs, refs);\r
- for(Expression parameter : parameters)\r
- parameter.collectRefs(allRefs, refs);\r
- }\r
- \r
- public void collectVars(TObjectIntHashMap<Variable> allVars, TIntHashSet vars) {\r
- function.collectVars(allVars, vars);\r
- for(Expression parameter : parameters)\r
- parameter.collectVars(allVars, vars);\r
- }\r
- \r
- @Override\r
- protected void updateType() throws MatchException {\r
- MultiFunction mfun = Types.matchFunction(function.getType(), parameters.length);\r
- /*for(int i=0;i<parameters.length;++i)\r
- if(!Types.equals(parameters[i].getType(), mfun.parameterTypes[i]))\r
- throw new MatchException();*/\r
- effect = mfun.effect;\r
- setType(mfun.returnType);\r
- }\r
-\r
- @Override\r
- public IVal toVal(Environment env, CodeWriter w) {\r
- IVal functionVal = function.toVal(env, w);\r
- IVal[] parameterVals = new IVal[parameters.length];\r
- for(int i=0;i<parameters.length;++i)\r
- parameterVals[i] = parameters[i].toVal(env, w);\r
- Type type = getType();\r
- effect = Types.simplifyFinalEffect(effect);\r
- return w.applyWithEffect(location, effect, type, functionVal, parameterVals);\r
- }\r
-\r
- @Override\r
- public void collectFreeVariables(THashSet<Variable> vars) {\r
- function.collectFreeVariables(vars);\r
- for(Expression parameter : parameters)\r
- parameter.collectFreeVariables(vars);\r
- }\r
- \r
- private void combineApplications() {\r
- if(function instanceof EApply) {\r
- EApply apply = (EApply)function;\r
- if(Types.canonical(apply.effect) == Types.NO_EFFECTS) {\r
- function = apply.function;\r
- parameters = Expression.concat(apply.parameters, parameters); \r
- } \r
- }\r
- }\r
-\r
- @Override\r
- public Expression simplify(SimplificationContext context) {\r
- function = function.simplify(context);\r
- for(int i=0;i<parameters.length;++i)\r
- parameters[i] = parameters[i].simplify(context);\r
- combineApplications();\r
- \r
- // Try to apply macro rule\r
- if(function instanceof EConstant) {\r
- EConstant constant = (EConstant)function;\r
- MacroRule rule = constant.value.getMacroRule();\r
- if(rule != null) {\r
- Expression simplified = rule.apply(context, constant.typeParameters, this);\r
- if(simplified != null)\r
- // There may be more to simplify after macro application\r
- // However this may cause performance problems (O(n^2) algorithm in pathologic cases)\r
- return simplified.simplify(context);\r
- }\r
- }\r
- \r
- return this;\r
- }\r
- \r
- @Override\r
- public EVar getPatternHead() throws NotPatternException {\r
- return function.getPatternHead();\r
- }\r
-\r
- @Override\r
- public LhsType getLhsType() throws NotPatternException {\r
- LhsType lhsType = function.getLhsType();\r
- if(lhsType instanceof PatternMatchingLhs)\r
- for(Expression parameter : parameters)\r
- parameter.collectVariableNames((PatternMatchingLhs)lhsType);\r
- return lhsType;\r
- }\r
- \r
- @Override\r
- public Expression resolve(TranslationContext context) {\r
- function = function.resolve(context);\r
- for(int i=0;i<parameters.length;++i)\r
- parameters[i] = parameters[i].resolve(context);\r
- //combineApplications();\r
- return this;\r
- }\r
- \r
- @Override\r
- public Expression resolveAsPattern(TranslationContext context) {\r
- function = function.resolveAsPattern(context);\r
- for(int i=0;i<parameters.length;++i)\r
- parameters[i] = parameters[i].resolveAsPattern(context);\r
- combineApplications();\r
- if(!(function instanceof EConstant || function instanceof EError)) {\r
- context.getErrorLog().log(location, "Only constants can be applied in patterns.");\r
- return new EError();\r
- }\r
- return this;\r
- }\r
- \r
- @Override\r
- public void getParameters(TranslationContext context,\r
- ArrayList<Expression> parameters) {\r
- function.getParameters(context, parameters);\r
- for(Expression parameter : this.parameters)\r
- parameters.add(parameter);\r
- }\r
- \r
- @Override\r
- public void removeFreeVariables(THashSet<Variable> vars) {\r
- function.removeFreeVariables(vars);\r
- for(Expression parameter : parameters)\r
- parameter.removeFreeVariables(vars);\r
- }\r
-\r
- @Override\r
- public Expression replace(ReplaceContext context) {\r
- return new EApply(\r
- getLocation(), \r
- effect.replace(context.tvarMap),\r
- function.replace(context),\r
- replace(context, parameters));\r
- }\r
- \r
- @Override\r
- public void setLocationDeep(long loc) {\r
- if(location == Locations.NO_LOCATION) {\r
- location = loc;\r
- function.setLocationDeep(loc);\r
- for(Expression parameter : parameters)\r
- parameter.setLocationDeep(loc);\r
- }\r
- }\r
- \r
- @Override\r
- public int getFunctionDefinitionArity() throws NotPatternException {\r
- return function.getFunctionDefinitionArity() + parameters.length;\r
- }\r
- \r
- @Override\r
- public IExpression toIExpression(ExpressionInterpretationContext target) {\r
- IExpression[] parametersI = toIExpressions(target, parameters);\r
- \r
- Expression function = this.function;\r
- while(function instanceof EApplyType)\r
- function = ((EApplyType)function).expression;\r
- \r
- // Special cases\r
- if(function instanceof EConstant) {\r
- SCLValue functionValue = ((EConstant)function).value;\r
- Name name = functionValue.getName();\r
- if(name.module.equals("Builtin")) {\r
- IVal val = functionValue.getValue();\r
- if(val instanceof ListConstructor) {\r
- if(((ListConstructor)val).arity == parametersI.length)\r
- return new IListLiteral(parametersI);\r
- }\r
- }\r
- }\r
- //System.out.println("--> " + function + " " + function.getClass().getSimpleName());\r
- \r
- // The basic case\r
- return new IApply(function.toIExpression(target), parametersI);\r
- }\r
- \r
- private void inferType(TypingContext context, boolean ignoreResult) {\r
- function = function.inferType(context);\r
- function = context.instantiate(function);\r
- MultiFunction mfun;\r
- try {\r
- mfun = Types.unifyFunction(function.getType(), parameters.length);\r
- } catch (UnificationException e) {\r
- int arity = Types.getArity(function.getType());\r
- if(arity == 0)\r
- context.getErrorLog().log(location, "Application of non-function.");\r
- else\r
- context.getErrorLog().log(location, "Function of arity " + arity + \r
- " is applied with " + parameters.length + " parameters.");\r
- setType(Types.metaVar(Kinds.STAR));\r
- for(int i=0;i<parameters.length;++i)\r
- parameters[i] = parameters[i].inferType(context);\r
- return;\r
- }\r
- if((ignoreResult && Skeletons.canonicalSkeleton(mfun.returnType) instanceof TFun &&\r
- Types.canonical(mfun.effect) == Types.NO_EFFECTS) ||\r
- (context.isInPattern() && Skeletons.canonicalSkeleton(mfun.returnType) instanceof TFun)) {\r
- context.getErrorLog().log(location, "The function is applied with too few parameters.");\r
- }\r
- \r
- // Check parameter types\r
- for(int i=0;i<parameters.length;++i)\r
- parameters[i] = parameters[i].checkType(context, mfun.parameterTypes[i]);\r
-\r
- effect = mfun.effect;\r
- \r
- context.declareEffect(location, mfun.effect);\r
- setType(mfun.returnType);\r
- }\r
- \r
- @Override\r
- public Expression inferType(TypingContext context) {\r
- inferType(context, false);\r
- return this;\r
- }\r
- \r
- @Override\r
- public Expression checkIgnoredType(TypingContext context) {\r
- inferType(context, true);\r
- if(Types.canonical(getType()) != Types.UNIT)\r
- return new ESimpleLet(location, null, this, new ELiteral(NoRepConstant.PUNIT));\r
- return this;\r
- }\r
-\r
- @Override\r
- public Expression decorate(ExpressionDecorator decorator) {\r
- if(decorator.decorateSubstructure(this)) {\r
- function = function.decorate(decorator);\r
- for(int i=0;i<parameters.length;++i)\r
- parameters[i] = parameters[i].decorate(decorator);\r
- }\r
- return decorator.decorate(this);\r
- }\r
- \r
- public Type getLocalEffect() {\r
- return effect;\r
- }\r
- \r
- public Expression toANormalForm(Expression root) {\r
- Expression expression = root;\r
- for(int i=parameters.length-1;i>=0;--i) {\r
- Expression parameter = parameters[i];\r
- if(parameter.isEffectful()) {\r
- Variable var = new Variable("aNormalTemp" + i, parameter.getType());\r
- expression = new ESimpleLet(var, parameter, expression);\r
- parameters[i] = new EVariable(var);\r
- }\r
- }\r
- if(function.isEffectful()) {\r
- Variable var = new Variable("aNormalTempF", function.getType());\r
- expression = new ESimpleLet(var, function, expression);\r
- function = new EVariable(var);\r
- }\r
- return expression;\r
- }\r
- \r
- @Override\r
- public boolean isEffectful() {\r
- if(effect != Types.NO_EFFECTS)\r
- return true; \r
- for(Expression parameter : parameters)\r
- if(parameter.isEffectful())\r
- return true;\r
- if(function.isEffectful())\r
- return true;\r
- return false;\r
- }\r
- \r
- @Override\r
- public boolean isFunctionPattern() {\r
- return !isConstructorApplication();\r
- }\r
- \r
- @Override\r
- public boolean isConstructorApplication() {\r
- return function.isConstructorApplication();\r
- }\r
-\r
- @Override\r
- public void collectEffects(THashSet<Type> effects) {\r
- effects.add(effect);\r
- function.collectEffects(effects);\r
- for(Expression parameter : parameters)\r
- parameter.collectEffects(effects);\r
- }\r
-\r
- @Override\r
- public void accept(ExpressionVisitor visitor) {\r
- visitor.visit(this);\r
- }\r
- \r
- @Override\r
- public boolean isFunctionDefinitionLhs() {\r
- try {\r
- EVar patternHead = function.getPatternHead();\r
- return !Character.isUpperCase(patternHead.name.charAt(0));\r
- } catch(NotPatternException e) {\r
- return false;\r
- }\r
- }\r
-\r
- @Override\r
- public void forVariables(VariableProcedure procedure) {\r
- function.forVariables(procedure);\r
- for(Expression parameter : parameters)\r
- parameter.forVariables(procedure);\r
- }\r
- \r
- @Override\r
- public boolean isPattern(int arity) {\r
- if(!function.isPattern(arity+parameters.length))\r
- return false;\r
- for(Expression parameter : parameters)\r
- if(!parameter.isPattern(0))\r
- return false;\r
- return true;\r
- }\r
-\r
- @Override\r
- public Expression accept(ExpressionTransformer transformer) {\r
- return transformer.transform(this);\r
- }\r
-}\r
+package org.simantics.scl.compiler.elaboration.expressions;
+
+import java.util.ArrayList;
+
+import org.simantics.scl.compiler.common.names.Name;
+import org.simantics.scl.compiler.constants.NoRepConstant;
+import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;
+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.errors.NotPatternException;
+import org.simantics.scl.compiler.elaboration.expressions.lhstype.LhsType;
+import org.simantics.scl.compiler.elaboration.expressions.lhstype.PatternMatchingLhs;
+import org.simantics.scl.compiler.elaboration.java.ListConstructor;
+import org.simantics.scl.compiler.elaboration.macros.MacroRule;
+import org.simantics.scl.compiler.elaboration.modules.SCLValue;
+import org.simantics.scl.compiler.environment.Environment;
+import org.simantics.scl.compiler.errors.Locations;
+import org.simantics.scl.compiler.internal.codegen.references.IVal;
+import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;
+import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
+import org.simantics.scl.compiler.internal.interpreted.IApply;
+import org.simantics.scl.compiler.internal.interpreted.IExpression;
+import org.simantics.scl.compiler.internal.interpreted.IListLiteral;
+import org.simantics.scl.compiler.top.ExpressionInterpretationContext;
+import org.simantics.scl.compiler.types.Skeletons;
+import org.simantics.scl.compiler.types.TFun;
+import org.simantics.scl.compiler.types.Type;
+import org.simantics.scl.compiler.types.Types;
+import org.simantics.scl.compiler.types.exceptions.MatchException;
+import org.simantics.scl.compiler.types.exceptions.UnificationException;
+import org.simantics.scl.compiler.types.kinds.Kinds;
+import org.simantics.scl.compiler.types.util.MultiFunction;
+
+import gnu.trove.map.hash.TObjectIntHashMap;
+import gnu.trove.set.hash.THashSet;
+import gnu.trove.set.hash.TIntHashSet;
+
+public class EApply extends Expression {
+ public Expression function;
+ public Expression[] parameters;
+ Type effect = Types.NO_EFFECTS;
+
+ public EApply(Expression function, Expression ... parameters) {
+ this.function = function;
+ this.parameters = parameters;
+ }
+
+ public EApply(Expression function, Expression parameter) {
+ this(function, new Expression[] {parameter});
+ }
+
+ public EApply(long loc, Expression function, Expression ... parameters) {
+ super(loc);
+ this.function = function;
+ this.parameters = parameters;
+ }
+
+ public EApply(long loc, Type effect, Expression function, Expression ... parameters) {
+ super(loc);
+ this.effect = effect;
+ this.function = function;
+ this.parameters = parameters;
+ }
+
+ public void set(Expression function, Expression[] parameters) {
+ this.function = function;
+ this.parameters = parameters;
+ }
+
+ public Expression getFunction() {
+ return function;
+ }
+
+ public Expression[] getParameters() {
+ return parameters;
+ }
+
+
+ public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {
+ function.collectRefs(allRefs, refs);
+ for(Expression parameter : parameters)
+ parameter.collectRefs(allRefs, refs);
+ }
+
+ public void collectVars(TObjectIntHashMap<Variable> allVars, TIntHashSet vars) {
+ function.collectVars(allVars, vars);
+ for(Expression parameter : parameters)
+ parameter.collectVars(allVars, vars);
+ }
+
+ @Override
+ protected void updateType() throws MatchException {
+ MultiFunction mfun = Types.matchFunction(function.getType(), parameters.length);
+ /*for(int i=0;i<parameters.length;++i)
+ if(!Types.equals(parameters[i].getType(), mfun.parameterTypes[i]))
+ throw new MatchException();*/
+ effect = mfun.effect;
+ setType(mfun.returnType);
+ }
+
+ @Override
+ public IVal toVal(Environment env, CodeWriter w) {
+ IVal functionVal = function.toVal(env, w);
+ IVal[] parameterVals = new IVal[parameters.length];
+ for(int i=0;i<parameters.length;++i)
+ parameterVals[i] = parameters[i].toVal(env, w);
+ Type type = getType();
+ effect = Types.simplifyFinalEffect(effect);
+ return w.applyWithEffect(location, effect, type, functionVal, parameterVals);
+ }
+
+ @Override
+ public void collectFreeVariables(THashSet<Variable> vars) {
+ function.collectFreeVariables(vars);
+ for(Expression parameter : parameters)
+ parameter.collectFreeVariables(vars);
+ }
+
+ private void combineApplications() {
+ if(function instanceof EApply) {
+ EApply apply = (EApply)function;
+ if(Types.canonical(apply.effect) == Types.NO_EFFECTS) {
+ function = apply.function;
+ parameters = Expression.concat(apply.parameters, parameters);
+ }
+ }
+ }
+
+ @Override
+ public Expression simplify(SimplificationContext context) {
+ function = function.simplify(context);
+ for(int i=0;i<parameters.length;++i)
+ parameters[i] = parameters[i].simplify(context);
+ combineApplications();
+
+ // Try to apply macro rule
+ if(function instanceof EConstant) {
+ EConstant constant = (EConstant)function;
+ MacroRule rule = constant.value.getMacroRule();
+ if(rule != null) {
+ Expression simplified = rule.apply(context, constant.typeParameters, this);
+ if(simplified != null)
+ // There may be more to simplify after macro application
+ // However this may cause performance problems (O(n^2) algorithm in pathologic cases)
+ return simplified.simplify(context);
+ }
+ }
+
+ return this;
+ }
+
+ @Override
+ public EVar getPatternHead() throws NotPatternException {
+ return function.getPatternHead();
+ }
+
+ @Override
+ public LhsType getLhsType() throws NotPatternException {
+ LhsType lhsType = function.getLhsType();
+ if(lhsType instanceof PatternMatchingLhs)
+ for(Expression parameter : parameters)
+ parameter.collectVariableNames((PatternMatchingLhs)lhsType);
+ return lhsType;
+ }
+
+ @Override
+ public Expression resolve(TranslationContext context) {
+ function = function.resolve(context);
+ for(int i=0;i<parameters.length;++i)
+ parameters[i] = parameters[i].resolve(context);
+ //combineApplications();
+ return this;
+ }
+
+ @Override
+ public Expression resolveAsPattern(TranslationContext context) {
+ function = function.resolveAsPattern(context);
+ for(int i=0;i<parameters.length;++i)
+ parameters[i] = parameters[i].resolveAsPattern(context);
+ combineApplications();
+ if(!(function instanceof EConstant || function instanceof EError)) {
+ context.getErrorLog().log(location, "Only constants can be applied in patterns.");
+ return new EError();
+ }
+ return this;
+ }
+
+ @Override
+ public void getParameters(TranslationContext context,
+ ArrayList<Expression> parameters) {
+ function.getParameters(context, parameters);
+ for(Expression parameter : this.parameters)
+ parameters.add(parameter);
+ }
+
+ @Override
+ public void removeFreeVariables(THashSet<Variable> vars) {
+ function.removeFreeVariables(vars);
+ for(Expression parameter : parameters)
+ parameter.removeFreeVariables(vars);
+ }
+
+ @Override
+ public Expression replace(ReplaceContext context) {
+ return new EApply(
+ getLocation(),
+ effect.replace(context.tvarMap),
+ function.replace(context),
+ replace(context, parameters));
+ }
+
+ @Override
+ public void setLocationDeep(long loc) {
+ if(location == Locations.NO_LOCATION) {
+ location = loc;
+ function.setLocationDeep(loc);
+ for(Expression parameter : parameters)
+ parameter.setLocationDeep(loc);
+ }
+ }
+
+ @Override
+ public int getFunctionDefinitionPatternArity() throws NotPatternException {
+ return function.getFunctionDefinitionPatternArity() + parameters.length;
+ }
+
+ @Override
+ public IExpression toIExpression(ExpressionInterpretationContext target) {
+ IExpression[] parametersI = toIExpressions(target, parameters);
+
+ Expression function = this.function;
+ while(function instanceof EApplyType)
+ function = ((EApplyType)function).expression;
+
+ // Special cases
+ if(function instanceof EConstant) {
+ SCLValue functionValue = ((EConstant)function).value;
+ Name name = functionValue.getName();
+ if(name.module.equals("Builtin")) {
+ IVal val = functionValue.getValue();
+ if(val instanceof ListConstructor) {
+ if(((ListConstructor)val).arity == parametersI.length)
+ return new IListLiteral(parametersI);
+ }
+ }
+ }
+ //System.out.println("--> " + function + " " + function.getClass().getSimpleName());
+
+ // The basic case
+ return new IApply(function.toIExpression(target), parametersI);
+ }
+
+ private void inferType(TypingContext context, boolean ignoreResult) {
+ function = function.inferType(context);
+ function = context.instantiate(function);
+ MultiFunction mfun;
+ try {
+ mfun = Types.unifyFunction(function.getType(), parameters.length);
+ } catch (UnificationException e) {
+ int arity = Types.getArity(function.getType());
+ if(arity == 0)
+ context.getErrorLog().log(location, "Application of non-function.");
+ else
+ context.getErrorLog().log(location, "Function of arity " + arity +
+ " is applied with " + parameters.length + " parameters.");
+ setType(Types.metaVar(Kinds.STAR));
+ for(int i=0;i<parameters.length;++i)
+ parameters[i] = parameters[i].inferType(context);
+ return;
+ }
+ if((ignoreResult && Skeletons.canonicalSkeleton(mfun.returnType) instanceof TFun &&
+ Types.canonical(mfun.effect) == Types.NO_EFFECTS) ||
+ (context.isInPattern() && Skeletons.canonicalSkeleton(mfun.returnType) instanceof TFun)) {
+ context.getErrorLog().log(location, "The function is applied with too few parameters.");
+ }
+
+ // Check parameter types
+ for(int i=0;i<parameters.length;++i)
+ parameters[i] = parameters[i].checkType(context, mfun.parameterTypes[i]);
+
+ effect = mfun.effect;
+
+ context.declareEffect(location, mfun.effect);
+ setType(mfun.returnType);
+ }
+
+ @Override
+ public Expression inferType(TypingContext context) {
+ inferType(context, false);
+ return this;
+ }
+
+ @Override
+ public Expression checkIgnoredType(TypingContext context) {
+ inferType(context, true);
+ if(Types.canonical(getType()) != Types.UNIT)
+ return new ESimpleLet(location, null, this, new ELiteral(NoRepConstant.PUNIT));
+ return this;
+ }
+
+ @Override
+ public Expression decorate(ExpressionDecorator decorator) {
+ if(decorator.decorateSubstructure(this)) {
+ function = function.decorate(decorator);
+ for(int i=0;i<parameters.length;++i)
+ parameters[i] = parameters[i].decorate(decorator);
+ }
+ return decorator.decorate(this);
+ }
+
+ public Type getLocalEffect() {
+ return effect;
+ }
+
+ public Expression toANormalForm(Expression root) {
+ Expression expression = root;
+ for(int i=parameters.length-1;i>=0;--i) {
+ Expression parameter = parameters[i];
+ if(parameter.isEffectful()) {
+ Variable var = new Variable("aNormalTemp" + i, parameter.getType());
+ expression = new ESimpleLet(var, parameter, expression);
+ parameters[i] = new EVariable(var);
+ }
+ }
+ if(function.isEffectful()) {
+ Variable var = new Variable("aNormalTempF", function.getType());
+ expression = new ESimpleLet(var, function, expression);
+ function = new EVariable(var);
+ }
+ return expression;
+ }
+
+ @Override
+ public boolean isEffectful() {
+ if(effect != Types.NO_EFFECTS)
+ return true;
+ for(Expression parameter : parameters)
+ if(parameter.isEffectful())
+ return true;
+ if(function.isEffectful())
+ return true;
+ return false;
+ }
+
+ @Override
+ public boolean isFunctionPattern() {
+ return !isConstructorApplication();
+ }
+
+ @Override
+ public boolean isConstructorApplication() {
+ return function.isConstructorApplication();
+ }
+
+ @Override
+ public void collectEffects(THashSet<Type> effects) {
+ effects.add(effect);
+ function.collectEffects(effects);
+ for(Expression parameter : parameters)
+ parameter.collectEffects(effects);
+ }
+
+ @Override
+ public void accept(ExpressionVisitor visitor) {
+ visitor.visit(this);
+ }
+
+ @Override
+ public boolean isFunctionDefinitionLhs() {
+ try {
+ EVar patternHead = function.getPatternHead();
+ return !Character.isUpperCase(patternHead.name.charAt(0));
+ } catch(NotPatternException e) {
+ return false;
+ }
+ }
+
+ @Override
+ public void forVariables(VariableProcedure procedure) {
+ function.forVariables(procedure);
+ for(Expression parameter : parameters)
+ parameter.forVariables(procedure);
+ }
+
+ @Override
+ public boolean isPattern(int arity) {
+ if(!function.isPattern(arity+parameters.length))
+ return false;
+ for(Expression parameter : parameters)
+ if(!parameter.isPattern(0))
+ return false;
+ return true;
+ }
+
+ @Override
+ public Expression accept(ExpressionTransformer transformer) {
+ return transformer.transform(this);
+ }
+
+ @Override
+ public boolean equalsExpression(Expression expression) {
+ if(expression.getClass() != getClass())
+ return false;
+ EApply other = (EApply)expression;
+ if(parameters.length != other.parameters.length)
+ return false;
+ if(!function.equalsExpression(other.function))
+ return false;
+ for(int i=0;i<parameters.length;++i)
+ if(!parameters[i].equalsExpression(other.parameters[i]))
+ return false;
+ return true;
+ }
+}
\r
@Override\r
public void collectFreeVariables(THashSet<Variable> vars) {\r
- vars.add(var);\r
- pattern.collectFreeVariables(vars);\r
+ throw new InternalCompilerError(location, "Cannot collect free variables for a pattern.");\r
+ }\r
+ \r
+ @Override\r
+ public void removeFreeVariables(THashSet<Variable> vars) {\r
+ vars.remove(var);\r
+ pattern.removeFreeVariables(vars);\r
}\r
\r
@Override\r
-package org.simantics.scl.compiler.elaboration.expressions;\r
-\r
-import java.util.ArrayList;\r
-\r
-import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
-import org.simantics.scl.compiler.common.names.Name;\r
-import org.simantics.scl.compiler.common.precedence.Associativity;\r
-import org.simantics.scl.compiler.common.precedence.Precedence;\r
-import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
-import org.simantics.scl.compiler.elaboration.errors.NotPatternException;\r
-import org.simantics.scl.compiler.elaboration.expressions.lhstype.FunctionDefinitionLhs;\r
-import org.simantics.scl.compiler.elaboration.expressions.lhstype.LhsType;\r
-import org.simantics.scl.compiler.elaboration.modules.SCLValue;\r
-import org.simantics.scl.compiler.errors.Locations;\r
-\r
-\r
-\r
-public class EBinary extends ASTExpression {\r
- public static final int NEGATION_LEVEL = 6;\r
- \r
- public Expression left;\r
- public ArrayList<EBinaryRightSide> rights = new ArrayList<EBinaryRightSide>();\r
- public EVar negation;\r
-\r
- public EBinary(Expression left, EVar negation) {\r
- this.left = left;\r
- this.negation = negation;\r
- }\r
-\r
- private EBinary(Expression left, EVar operator, Expression right) {\r
- this.left = left;\r
- rights.add(new EBinaryRightSide(operator, right));\r
- }\r
-\r
- public static EBinary create(Expression left, EVar operator, Expression right) {\r
- if(left instanceof EBinary) {\r
- EBinary left_ = (EBinary)left;\r
- left_.rights.add(new EBinaryRightSide(operator, right));\r
- return left_;\r
- }\r
- else\r
- return new EBinary(left, operator, right);\r
- }\r
-\r
- @Override\r
- public Expression resolve(TranslationContext context) {\r
- return parseOperators(context).resolve(context);\r
- }\r
-\r
- private static final Name NEG = Name.create("Prelude", "neg");\r
- \r
- public Expression parseOperators(TranslationContext context) {\r
- ArrayList<Expression> output = new ArrayList<Expression>();\r
- ArrayList<Expression> ops = new ArrayList<Expression>();\r
- ArrayList<EVar> opAsts = new ArrayList<EVar>();\r
- \r
- EVar negation = this.negation;\r
- \r
- output.add(left);\r
- for(EBinaryRightSide right : rights) {\r
- // Read op\r
- Expression op = context.resolveExpression(right.operator.location, right.operator.name);\r
- if(op == null)\r
- return new EError(location);\r
- Precedence opPrec = op.getPrecedence();\r
- while(!ops.isEmpty()) {\r
- Expression oldOp = ops.get(ops.size()-1);\r
- Precedence oldOpPrecedence = oldOp.getPrecedence();\r
- \r
- if(oldOpPrecedence.level < opPrec.level)\r
- break;\r
- if(oldOpPrecedence.level == opPrec.level) {\r
- if(opPrec.associativity == Associativity.RIGHT)\r
- break;\r
- if(opPrec.associativity == Associativity.NONASSOC) {\r
- context.getErrorLog().log(right.operator.location, \r
- "Operator " + right.operator.name + " is not associative.");\r
- return new EError(location); \r
- }\r
- }\r
- \r
- // Pop op \r
- ops.remove(ops.size()-1);\r
- Expression r = output.remove(output.size()-1);\r
- Expression l = output.remove(output.size()-1);\r
- output.add(binary(l, oldOp, opAsts.remove(opAsts.size()-1), r));\r
- }\r
- if(negation != null && ops.isEmpty()) {\r
- if(opPrec.level <= NEGATION_LEVEL) { \r
- SCLValue neg = context.getEnvironment().getValue(NEG);\r
- if(neg == null) {\r
- context.getErrorLog().log(location, \r
- "Couldn't resolve variable neg.");\r
- return new EError(location);\r
- }\r
- output.set(0, unary(neg, negation, output.get(0)));\r
- negation = null;\r
- }\r
- }\r
- ops.add(op);\r
- opAsts.add(right.operator);\r
- \r
- // Read value\r
- output.add(right.right);\r
- }\r
- \r
- // Pop rest\r
- while(!ops.isEmpty()) { \r
- Expression oldOp = ops.remove(ops.size()-1);\r
- Expression r = output.remove(output.size()-1);\r
- Expression l = output.remove(output.size()-1);\r
- output.add(binary(l, oldOp, opAsts.remove(opAsts.size()-1), r));\r
- }\r
- if(negation != null) {\r
- SCLValue neg = context.getEnvironment().getValue(NEG);\r
- if(neg == null) {\r
- context.getErrorLog().log(location, \r
- "Couldn't resolve variable neg.");\r
- return new EError(location);\r
- }\r
- output.set(0, unary(neg, negation, output.get(0)));\r
- }\r
- \r
- return output.get(0);\r
- \r
- //System.out.println("parseOperators: " + this);\r
- //return parse(context, left, rights.listIterator(), new Precedence(-1, Associativity.NONASSOC));\r
- }\r
-\r
- /*\r
- private Expression parse(TranslationContext context,\r
- Expression lhs, ListIterator<EBinaryRightSide> it, Precedence minPrec) {\r
- while(it.hasNext()) {\r
- EBinaryRightSide right = it.next();\r
- SCLValue op = context.resolveValue(right.operator.name);\r
- if(op == null) {\r
- context.getErrorLog().log(right.operator, \r
- "Couldn't resolve variable " + right.operator.name + ".");\r
- return lhs;\r
- }\r
- Precedence opPrec = op.getPrecedence();\r
- if(minPrec.level > opPrec.level)\r
- break;\r
- Expression rhs = right.right;\r
- while(it.hasNext()) {\r
- EVar var = it.next().operator;\r
- SCLValue nextOp = context.resolveValue(var.name);\r
- if(nextOp == null) {\r
- context.getErrorLog().log(var, \r
- "Couldn't resolve variable " + var.name + ".");\r
- return lhs;\r
- }\r
- it.previous();\r
- Precedence nextPrec = nextOp.getPrecedence();\r
- int precDiff = opPrec.level - nextPrec.level;\r
- if(precDiff == 0) {\r
- if(opPrec.associativity == Associativity.LEFT)\r
- break;\r
- else if(opPrec.associativity == Associativity.NONASSOC) {\r
- context.getErrorLog().log(it.next().operator, "Nonassociative operator.");\r
- return lhs;\r
- }\r
- }\r
- else if(precDiff > 0)\r
- break;\r
- rhs = parse(context, rhs, it, nextPrec);\r
- }\r
- lhs = binary(lhs, op, right.operator, rhs);\r
- } \r
- return lhs;\r
- }\r
- */\r
- private Expression binary(Expression lhs, Expression op, EVar opAst, Expression rhs) {\r
- return new EApply(Locations.combine(lhs.location, rhs.location), op, lhs, rhs); \r
- }\r
- \r
- private Expression unary(SCLValue operator, EVar opAst, Expression expression) {\r
- EConstant op = new EConstant(opAst.location, operator);\r
- return new EApply(expression.location /*wrong*/, op, expression);\r
- }\r
- \r
- @Override\r
- public EVar getPatternHead() throws NotPatternException {\r
- if(rights.size() == 1)\r
- return rights.get(0).operator;\r
- else\r
- throw new NotPatternException(this);\r
- }\r
- \r
- @Override\r
- public LhsType getLhsType() throws NotPatternException {\r
- if(rights.size() == 1)\r
- return new FunctionDefinitionLhs(rights.get(0).operator.name);\r
- else\r
- throw new InternalCompilerError();\r
- }\r
- \r
- @Override\r
- public void getParameters(TranslationContext context,\r
- ArrayList<Expression> parameters) {\r
- parseOperators(context).getParameters(context, parameters);\r
- }\r
-\r
- public static Expression negate(EVar op, Expression expression) {\r
- if(expression instanceof EBinary) {\r
- ((EBinary)expression).negation = op;\r
- return expression;\r
- }\r
- /*else if(expression instanceof EIntegerLiteral) {\r
- EIntegerLiteral literal = (EIntegerLiteral)expression;\r
- literal.value = -literal.value;\r
- return expression;\r
- }*/\r
- else\r
- return new EBinary(expression, op);\r
- }\r
- \r
- @Override\r
- public int getFunctionDefinitionArity() throws NotPatternException {\r
- return 2;\r
- }\r
- \r
- @Override\r
- public void setLocationDeep(long loc) {\r
- if(location == Locations.NO_LOCATION) {\r
- location = loc;\r
- left.setLocationDeep(loc);\r
- if(negation != null)\r
- negation.setLocationDeep(loc);\r
- for(EBinaryRightSide right : rights)\r
- right.setLocationDeep(loc);\r
- }\r
- }\r
- \r
- @Override\r
- public Expression accept(ExpressionTransformer transformer) {\r
- return transformer.transform(this);\r
- }\r
-\r
-}\r
+package org.simantics.scl.compiler.elaboration.expressions;
+
+import java.util.ArrayList;
+
+import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
+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.elaboration.contexts.TranslationContext;
+import org.simantics.scl.compiler.elaboration.errors.NotPatternException;
+import org.simantics.scl.compiler.elaboration.expressions.lhstype.FunctionDefinitionLhs;
+import org.simantics.scl.compiler.elaboration.expressions.lhstype.LhsType;
+import org.simantics.scl.compiler.elaboration.modules.SCLValue;
+import org.simantics.scl.compiler.errors.Locations;
+
+
+
+public class EBinary extends ASTExpression {
+ public static final int NEGATION_LEVEL = 6;
+
+ public Expression left;
+ public ArrayList<EBinaryRightSide> rights = new ArrayList<EBinaryRightSide>();
+ public EVar negation;
+
+ public EBinary(Expression left, EVar negation) {
+ this.left = left;
+ this.negation = negation;
+ }
+
+ private EBinary(Expression left, EVar operator, Expression right) {
+ this.left = left;
+ rights.add(new EBinaryRightSide(operator, right));
+ }
+
+ public static EBinary create(Expression left, EVar operator, Expression right) {
+ if(left instanceof EBinary) {
+ EBinary left_ = (EBinary)left;
+ left_.rights.add(new EBinaryRightSide(operator, right));
+ return left_;
+ }
+ else
+ return new EBinary(left, operator, right);
+ }
+
+ @Override
+ public Expression resolve(TranslationContext context) {
+ return parseOperators(context).resolve(context);
+ }
+
+ public Expression parseOperators(TranslationContext context) {
+ ArrayList<Expression> output = new ArrayList<Expression>();
+ ArrayList<Expression> ops = new ArrayList<Expression>();
+ ArrayList<EVar> opAsts = new ArrayList<EVar>();
+
+ EVar negation = this.negation;
+
+ output.add(left);
+ for(EBinaryRightSide right : rights) {
+ // Read op
+ Expression op = context.resolveExpression(right.operator.location, right.operator.name);
+ if(op == null)
+ return new EError(location);
+ Precedence opPrec = op.getPrecedence();
+ while(!ops.isEmpty()) {
+ Expression oldOp = ops.get(ops.size()-1);
+ Precedence oldOpPrecedence = oldOp.getPrecedence();
+
+ if(oldOpPrecedence.level < opPrec.level)
+ break;
+ if(oldOpPrecedence.level == opPrec.level) {
+ if(opPrec.associativity == Associativity.RIGHT)
+ break;
+ if(opPrec.associativity == Associativity.NONASSOC) {
+ context.getErrorLog().log(right.operator.location,
+ "Operator " + right.operator.name + " is not associative.");
+ return new EError(location);
+ }
+ }
+
+ // Pop op
+ ops.remove(ops.size()-1);
+ Expression r = output.remove(output.size()-1);
+ Expression l = output.remove(output.size()-1);
+ output.add(binary(l, oldOp, opAsts.remove(opAsts.size()-1), r));
+ }
+ if(negation != null && ops.isEmpty()) {
+ if(opPrec.level <= NEGATION_LEVEL) {
+ SCLValue neg = context.getEnvironment().getValue(Names.Prelude_neg);
+ if(neg == null) {
+ context.getErrorLog().log(location,
+ "Couldn't resolve variable neg.");
+ return new EError(location);
+ }
+ output.set(0, unary(neg, negation, output.get(0)));
+ negation = null;
+ }
+ }
+ ops.add(op);
+ opAsts.add(right.operator);
+
+ // Read value
+ output.add(right.right);
+ }
+
+ // Pop rest
+ while(!ops.isEmpty()) {
+ Expression oldOp = ops.remove(ops.size()-1);
+ Expression r = output.remove(output.size()-1);
+ Expression l = output.remove(output.size()-1);
+ output.add(binary(l, oldOp, opAsts.remove(opAsts.size()-1), r));
+ }
+ if(negation != null) {
+ SCLValue neg = context.getEnvironment().getValue(Names.Prelude_neg);
+ if(neg == null) {
+ context.getErrorLog().log(location,
+ "Couldn't resolve variable neg.");
+ return new EError(location);
+ }
+ output.set(0, unary(neg, negation, output.get(0)));
+ }
+
+ return output.get(0);
+
+ //System.out.println("parseOperators: " + this);
+ //return parse(context, left, rights.listIterator(), new Precedence(-1, Associativity.NONASSOC));
+ }
+
+ /*
+ private Expression parse(TranslationContext context,
+ Expression lhs, ListIterator<EBinaryRightSide> it, Precedence minPrec) {
+ while(it.hasNext()) {
+ EBinaryRightSide right = it.next();
+ SCLValue op = context.resolveValue(right.operator.name);
+ if(op == null) {
+ context.getErrorLog().log(right.operator,
+ "Couldn't resolve variable " + right.operator.name + ".");
+ return lhs;
+ }
+ Precedence opPrec = op.getPrecedence();
+ if(minPrec.level > opPrec.level)
+ break;
+ Expression rhs = right.right;
+ while(it.hasNext()) {
+ EVar var = it.next().operator;
+ SCLValue nextOp = context.resolveValue(var.name);
+ if(nextOp == null) {
+ context.getErrorLog().log(var,
+ "Couldn't resolve variable " + var.name + ".");
+ return lhs;
+ }
+ it.previous();
+ Precedence nextPrec = nextOp.getPrecedence();
+ int precDiff = opPrec.level - nextPrec.level;
+ if(precDiff == 0) {
+ if(opPrec.associativity == Associativity.LEFT)
+ break;
+ else if(opPrec.associativity == Associativity.NONASSOC) {
+ context.getErrorLog().log(it.next().operator, "Nonassociative operator.");
+ return lhs;
+ }
+ }
+ else if(precDiff > 0)
+ break;
+ rhs = parse(context, rhs, it, nextPrec);
+ }
+ lhs = binary(lhs, op, right.operator, rhs);
+ }
+ return lhs;
+ }
+ */
+ private Expression binary(Expression lhs, Expression op, EVar opAst, Expression rhs) {
+ return new EApply(Locations.combine(lhs.location, rhs.location), op, lhs, rhs);
+ }
+
+ private Expression unary(SCLValue operator, EVar opAst, Expression expression) {
+ EConstant op = new EConstant(opAst.location, operator);
+ return new EApply(expression.location /*wrong*/, op, expression);
+ }
+
+ @Override
+ public EVar getPatternHead() throws NotPatternException {
+ if(rights.size() == 1)
+ return rights.get(0).operator;
+ else
+ throw new NotPatternException(this);
+ }
+
+ @Override
+ public LhsType getLhsType() throws NotPatternException {
+ if(rights.size() == 1)
+ return new FunctionDefinitionLhs(rights.get(0).operator.name);
+ else
+ throw new InternalCompilerError();
+ }
+
+ @Override
+ public void getParameters(TranslationContext context,
+ ArrayList<Expression> parameters) {
+ parseOperators(context).getParameters(context, parameters);
+ }
+
+ public static Expression negate(EVar op, Expression expression) {
+ if(expression instanceof EBinary) {
+ ((EBinary)expression).negation = op;
+ return expression;
+ }
+ /*else if(expression instanceof EIntegerLiteral) {
+ EIntegerLiteral literal = (EIntegerLiteral)expression;
+ literal.value = -literal.value;
+ return expression;
+ }*/
+ else
+ return new EBinary(expression, op);
+ }
+
+ @Override
+ public int getFunctionDefinitionPatternArity() throws NotPatternException {
+ return 2;
+ }
+
+ @Override
+ public void setLocationDeep(long loc) {
+ if(location == Locations.NO_LOCATION) {
+ location = loc;
+ left.setLocationDeep(loc);
+ if(negation != null)
+ negation.setLocationDeep(loc);
+ for(EBinaryRightSide right : rights)
+ right.setLocationDeep(loc);
+ }
+ }
+
+ @Override
+ public Expression accept(ExpressionTransformer transformer) {
+ return transformer.transform(this);
+ }
+
+}
import java.util.List;
import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
+import org.simantics.scl.compiler.elaboration.chr.CHRRuleset;
+import org.simantics.scl.compiler.elaboration.chr.translation.CHRTranslation;
import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
+import org.simantics.scl.compiler.elaboration.expressions.block.CHRStatement;
+import org.simantics.scl.compiler.elaboration.expressions.block.ConstraintStatement;
import org.simantics.scl.compiler.elaboration.expressions.block.GuardStatement;
import org.simantics.scl.compiler.elaboration.expressions.block.LetStatement;
import org.simantics.scl.compiler.elaboration.expressions.block.RuleStatement;
import org.simantics.scl.compiler.elaboration.expressions.block.Statement;
+import org.simantics.scl.compiler.elaboration.expressions.block.StatementGroup;
import org.simantics.scl.compiler.errors.Locations;
public class EBlock extends ASTExpression {
@Override
public Expression resolve(TranslationContext context) {
- if(statements.isEmpty()) {
- context.getErrorLog().log(location, "Block must contain at least one statement.");
- return new EError(location);
- }
+ if(statements.isEmpty())
+ throw new InternalCompilerError();
int i = statements.size()-1;
Statement last = statements.get(i);
if(!(last instanceof GuardStatement)) {
Expression in = ((GuardStatement)last).value;
while(--i >= 0) {
Statement cur = statements.get(i);
- if(cur instanceof RuleStatement) {
- int endId = i+1;
- while(i>0 && statements.get(i-1) instanceof RuleStatement)
- --i;
- in = extractRules(i, endId, in);
- }
- else if(cur instanceof LetStatement && ((LetStatement)cur).pattern.isFunctionPattern()) {
+ StatementGroup group = cur.getStatementGroup();
+ if(group == null)
+ in = cur.toExpression(context, monadic, in);
+ else {
int endId = i+1;
- while(i>0 && (cur = statements.get(i-1)) instanceof LetStatement &&
- ((LetStatement)cur).pattern.isFunctionPattern())
+ while(i>0 && statements.get(i-1).getStatementGroup() == group)
--i;
- in = extractLet(i, endId, in);
+ switch(group) {
+ case LetFunction:
+ in = extractLet(i, endId, in);
+ break;
+ case Rule:
+ in = extractRules(i, endId, in);
+ break;
+ case CHR:
+ in = extractCHRRules(context, i, endId, in);
+ break;
+ }
}
- else
- in = cur.toExpression(context, monadic, in);
}
return in.resolve(context);
}
private Expression extractRules(int begin, int end, Expression in) {
return new EPreRuleset(statements.subList(begin, end).toArray(new RuleStatement[end-begin]), in);
}
+
+ private Expression extractCHRRules(TranslationContext context, int begin, int end, Expression in) {
+ CHRRuleset ruleset = new CHRRuleset();
+ ruleset.location = Locations.combine(statements.get(begin).location, statements.get(end-1).location);
+ for(int i=begin;i<end;++i) {
+ Statement statement = statements.get(i);
+ if(statement instanceof CHRStatement)
+ ruleset.rules.add(CHRTranslation.convertCHRStatement(context, (CHRStatement)statement));
+ else if(statement instanceof ConstraintStatement)
+ ruleset.constraints.add(CHRTranslation.convertConstraintStatement(context, (ConstraintStatement)statement));
+ else
+ throw new InternalCompilerError("Invalid CHR statement.");
+ }
+ return new ECHRRuleset(ruleset, in);
+ }
@SuppressWarnings("unchecked")
private Expression extractLet(int begin, int end, Expression in) {
return transformer.transform(this);
}
+ @Override
+ public int getSyntacticFunctionArity() {
+ if(monadic)
+ return 0;
+ Statement lastStatement = statements.getLast();
+ if(!(lastStatement instanceof GuardStatement))
+ return 0;
+ return ((GuardStatement)lastStatement).value.getSyntacticFunctionArity();
+ }
}
--- /dev/null
+package org.simantics.scl.compiler.elaboration.expressions;\r
+\r
+import org.simantics.scl.compiler.elaboration.chr.CHRRuleset;\r
+import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;\r
+import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
+import org.simantics.scl.compiler.elaboration.contexts.TypingContext;\r
+import org.simantics.scl.compiler.environment.Environment;\r
+import org.simantics.scl.compiler.errors.Locations;\r
+import org.simantics.scl.compiler.internal.codegen.references.IVal;\r
+import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;\r
+import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;\r
+import org.simantics.scl.compiler.internal.interpreted.IExpression;\r
+import org.simantics.scl.compiler.top.ExpressionInterpretationContext;\r
+import org.simantics.scl.compiler.types.Type;\r
+import org.simantics.scl.compiler.types.exceptions.MatchException;\r
+\r
+import gnu.trove.map.hash.TObjectIntHashMap;\r
+import gnu.trove.set.hash.THashSet;\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
+public class ECHRRuleset extends Expression {\r
+ CHRRuleset ruleset;\r
+ Expression in;\r
+ \r
+ public ECHRRuleset(CHRRuleset ruleset, Expression in) {\r
+ this.ruleset = ruleset;\r
+ this.in = in;\r
+ }\r
+ \r
+ @Override\r
+ public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {\r
+ ruleset.collectRefs(allRefs, refs);\r
+ in.collectRefs(allRefs, refs);\r
+ }\r
+ @Override\r
+ public void collectVars(TObjectIntHashMap<Variable> allVars, TIntHashSet vars) {\r
+ ruleset.collectVars(allVars, vars);\r
+ in.collectVars(allVars, vars);\r
+ }\r
+ @Override\r
+ public void forVariables(VariableProcedure procedure) {\r
+ ruleset.forVariables(procedure);\r
+ in.forVariables(procedure);\r
+ }\r
+ @Override\r
+ protected void updateType() throws MatchException {\r
+ setType(in.getType());\r
+ }\r
+ @Override\r
+ public IVal toVal(Environment env, CodeWriter w) {\r
+ ruleset.generateCode(w);\r
+ return in.toVal(env, w);\r
+ }\r
+ @Override\r
+ public void collectFreeVariables(THashSet<Variable> vars) {\r
+ ruleset.collectFreeVariables(vars);\r
+ in.collectFreeVariables(vars);\r
+ }\r
+ @Override\r
+ public Expression resolve(TranslationContext context) {\r
+ context.pushFrame();\r
+ context.pushCHRConstraintFrame();\r
+ ruleset.resolve(context);\r
+ in = in.resolve(context);\r
+ context.popCHRConstraintFrame(ruleset.constraints);\r
+ context.popFrame();\r
+ return this;\r
+ }\r
+ @Override\r
+ public void setLocationDeep(long loc) {\r
+ if(location == Locations.NO_LOCATION) {\r
+ this.location = loc;\r
+ ruleset.setLocationDeep(loc);\r
+ in.setLocationDeep(loc);\r
+ }\r
+ }\r
+ @Override\r
+ public Expression decorate(ExpressionDecorator decorator) {\r
+ in = in.decorate(decorator);\r
+ return this;\r
+ }\r
+ @Override\r
+ public void collectEffects(THashSet<Type> effects) {\r
+ ruleset.collectEffects(effects);\r
+ in.collectEffects(effects);\r
+ }\r
+ @Override\r
+ public void accept(ExpressionVisitor visitor) {\r
+ visitor.visit(this);\r
+ }\r
+ \r
+ @Override\r
+ public Expression inferType(TypingContext context) {\r
+ ruleset.checkType(context);\r
+ in = in.inferType(context);\r
+ return this;\r
+ }\r
+ \r
+ @Override\r
+ public Expression simplify(SimplificationContext context) {\r
+ ruleset.simplify(context);\r
+ ruleset.compile(context);\r
+ in = in.simplify(context);\r
+ return this;\r
+ }\r
+ \r
+ @Override\r
+ public Expression accept(ExpressionTransformer transformer) {\r
+ return transformer.transform(this);\r
+ }\r
+ \r
+ @Override\r
+ public IExpression toIExpression(ExpressionInterpretationContext context) {\r
+ throw new UnsupportedOperationException();\r
+ }\r
+\r
+}\r
return this;\r
}\r
else\r
- return applyPUnit(context);\r
+ return applyPUnit(context.getCompilationContext());\r
}\r
\r
@Override\r
return transformer.transform(this);\r
}\r
\r
+ @Override\r
+ public boolean equalsExpression(Expression expression) {\r
+ if(expression.getClass() != getClass())\r
+ return false;\r
+ EConstant other = (EConstant)expression;\r
+ return value == other.value && Types.equals(typeParameters, other.typeParameters);\r
+ }\r
}\r
package org.simantics.scl.compiler.elaboration.expressions;\r
\r
-import org.simantics.scl.compiler.common.names.Name;\r
+import org.simantics.scl.compiler.common.names.Names;\r
import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;\r
import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
import org.simantics.scl.compiler.elaboration.contexts.TypingContext;\r
accessor.collectFreeVariables(vars);\r
}\r
\r
- private static final Name CHILD = Name.create("Simantics/Variables", "child_");\r
- private static final Name PROPERTY = Name.create("Simantics/Variables", "property");\r
- private static final Name PROPERTY_VALUE = Name.create("Simantics/Variables", "untypedPropertyValue");\r
-\r
@Override\r
public Expression simplify(SimplificationContext context) {\r
// Simplify subexpressions\r
result = new EApply(\r
getLocation(),\r
Types.READ_GRAPH,\r
- context.getConstant(CHILD),\r
+ context.getConstant(Names.Simantics_Variables_child_),\r
result,\r
accessor.asExpression()\r
);\r
result = new EApply(\r
getLocation(),\r
Types.READ_GRAPH,\r
- context.getConstant(PROPERTY),\r
+ context.getConstant(Names.Simantics_Variables_property),\r
result,\r
accessor.asExpression()\r
);\r
result = new EApply(\r
getLocation(),\r
Types.READ_GRAPH,\r
- context.getConstant(PROPERTY_VALUE, getType()),\r
+ context.getConstant(Names.Simantics_Variables_untypedPropertyValue, getType()),\r
result,\r
accessor.asExpression()\r
);\r
-package org.simantics.scl.compiler.elaboration.expressions;\r
-\r
-import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;\r
-import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;\r
-import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
-import org.simantics.scl.compiler.elaboration.contexts.TypingContext;\r
-import org.simantics.scl.compiler.environment.Environment;\r
-import org.simantics.scl.compiler.errors.Locations;\r
-import org.simantics.scl.compiler.internal.codegen.references.IVal;\r
-import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;\r
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;\r
-import org.simantics.scl.compiler.internal.interpreted.IExpression;\r
-import org.simantics.scl.compiler.internal.interpreted.IIf;\r
-import org.simantics.scl.compiler.top.ExpressionInterpretationContext;\r
-import org.simantics.scl.compiler.types.Type;\r
-import org.simantics.scl.compiler.types.Types;\r
-import org.simantics.scl.compiler.types.exceptions.MatchException;\r
-\r
-import gnu.trove.map.hash.TObjectIntHashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
-public class EIf extends Expression {\r
- public Expression condition;\r
- public Expression then_;\r
- public Expression else_;\r
- \r
- public EIf(Expression condition, Expression then_, Expression else_) {\r
- this.condition = condition;\r
- this.then_ = then_;\r
- this.else_ = else_;\r
- }\r
-\r
- public EIf(long loc, Expression condition, Expression then_, Expression else_) {\r
- super(loc);\r
- this.condition = condition;\r
- this.then_ = then_;\r
- this.else_ = else_;\r
- }\r
-\r
- public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {\r
- condition.collectRefs(allRefs, refs);\r
- then_.collectRefs(allRefs, refs);\r
- else_.collectRefs(allRefs, refs);\r
- }\r
-\r
- @Override\r
- public void collectVars(TObjectIntHashMap<Variable> allVars,\r
- TIntHashSet vars) {\r
- condition.collectVars(allVars, vars);\r
- then_.collectVars(allVars, vars);\r
- else_.collectVars(allVars, vars);\r
- }\r
-\r
- @Override\r
- protected void updateType() throws MatchException {\r
- setType(then_.getType());\r
- }\r
- \r
- @Override\r
- public IVal toVal(Environment env, CodeWriter w) {\r
- IVal conditionVal = condition.toVal(env, w); \r
- \r
- CodeWriter thenBlock = w.createBlock();\r
- CodeWriter elseBlock = w.createBlock();\r
- \r
- CodeWriter joinPoint = w.createBlock(getType());\r
- \r
- w.if_(conditionVal, thenBlock.getContinuation(), elseBlock.getContinuation());\r
- \r
- IVal thenVal = then_.toVal(env, thenBlock);\r
- thenBlock.jump(joinPoint.getContinuation(), thenVal);\r
- \r
- IVal elseVal = else_.toVal(env, elseBlock);\r
- elseBlock.jump(joinPoint.getContinuation(), elseVal);\r
- \r
- w.continueAs(joinPoint);\r
- \r
- return w.getParameters()[0];\r
- }\r
-\r
- @Override\r
- public void collectFreeVariables(THashSet<Variable> vars) {\r
- condition.collectFreeVariables(vars);\r
- then_.collectFreeVariables(vars);\r
- else_.collectFreeVariables(vars);\r
- }\r
-\r
- @Override\r
- public Expression simplify(SimplificationContext context) {\r
- condition = condition.simplify(context);\r
- then_ = then_.simplify(context);\r
- else_ = else_.simplify(context);\r
- return this;\r
- }\r
-\r
- @Override\r
- public Expression resolve(TranslationContext context) {\r
- condition = condition.resolve(context);\r
- then_ = then_.resolve(context);\r
- else_ = else_.resolve(context);\r
- return this;\r
- }\r
-\r
- @Override\r
- public Expression replace(ReplaceContext context) {\r
- return new EIf(condition.replace(context), \r
- then_.replace(context), \r
- else_.replace(context));\r
- }\r
- \r
- @Override\r
- public Expression checkBasicType(TypingContext context, Type requiredType) {\r
- condition = condition.checkType(context, Types.BOOLEAN);\r
- then_ = then_.checkType(context, requiredType);\r
- else_ = else_.checkType(context, requiredType);\r
- return this;\r
- }\r
- \r
- @Override\r
- public Expression checkIgnoredType(TypingContext context) {\r
- condition = condition.checkType(context, Types.BOOLEAN);\r
- then_ = then_.checkIgnoredType(context);\r
- else_ = else_.checkIgnoredType(context);\r
- return this;\r
- }\r
- \r
- @Override\r
- public Expression decorate(ExpressionDecorator decorator) {\r
- condition = condition.decorate(decorator);\r
- then_ = then_.decorate(decorator);\r
- else_ = else_.decorate(decorator); \r
- return decorator.decorate(this);\r
- }\r
- \r
- @Override\r
- public boolean isEffectful() {\r
- return condition.isEffectful() || then_.isEffectful() || else_.isEffectful();\r
- }\r
-\r
- @Override\r
- public void collectEffects(THashSet<Type> effects) {\r
- condition.collectEffects(effects);\r
- then_.collectEffects(effects);\r
- else_.collectEffects(effects);\r
- }\r
- \r
- @Override\r
- public void setLocationDeep(long loc) {\r
- if(location == Locations.NO_LOCATION) {\r
- location = loc;\r
- condition.setLocationDeep(loc);\r
- then_.setLocationDeep(loc);\r
- else_.setLocationDeep(loc);\r
- }\r
- }\r
- \r
- @Override\r
- public void accept(ExpressionVisitor visitor) {\r
- visitor.visit(this);\r
- }\r
- \r
- @Override\r
- public IExpression toIExpression(ExpressionInterpretationContext target) {\r
- return new IIf(condition.toIExpression(target), then_.toIExpression(target), else_.toIExpression(target));\r
- }\r
- \r
- public Expression getCondition() {\r
- return condition;\r
- }\r
- \r
- public Expression getThen() {\r
- return then_;\r
- }\r
- \r
- public Expression getElse() {\r
- return else_;\r
- }\r
-\r
- @Override\r
- public void forVariables(VariableProcedure procedure) {\r
- condition.forVariables(procedure);\r
- then_.forVariables(procedure);\r
- else_.forVariables(procedure);\r
- }\r
- @Override\r
- public Expression accept(ExpressionTransformer transformer) {\r
- return transformer.transform(this);\r
- }\r
-\r
-}\r
+package org.simantics.scl.compiler.elaboration.expressions;
+
+import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;
+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.environment.Environment;
+import org.simantics.scl.compiler.errors.Locations;
+import org.simantics.scl.compiler.internal.codegen.references.IVal;
+import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;
+import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
+import org.simantics.scl.compiler.internal.interpreted.IConstant;
+import org.simantics.scl.compiler.internal.interpreted.IExpression;
+import org.simantics.scl.compiler.internal.interpreted.IIf;
+import org.simantics.scl.compiler.top.ExpressionInterpretationContext;
+import org.simantics.scl.compiler.types.Type;
+import org.simantics.scl.compiler.types.Types;
+import org.simantics.scl.compiler.types.exceptions.MatchException;
+import org.simantics.scl.runtime.tuple.Tuple0;
+
+import gnu.trove.map.hash.TObjectIntHashMap;
+import gnu.trove.set.hash.THashSet;
+import gnu.trove.set.hash.TIntHashSet;
+
+public class EIf extends Expression {
+ public Expression condition;
+ public Expression then_;
+ public Expression else_; // may be null
+
+ public EIf(Expression condition, Expression then_, Expression else_) {
+ this.condition = condition;
+ this.then_ = then_;
+ this.else_ = else_;
+ }
+
+ public EIf(long loc, Expression condition, Expression then_, Expression else_) {
+ super(loc);
+ this.condition = condition;
+ this.then_ = then_;
+ this.else_ = else_;
+ }
+
+ public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {
+ condition.collectRefs(allRefs, refs);
+ then_.collectRefs(allRefs, refs);
+ if(else_ != null)
+ else_.collectRefs(allRefs, refs);
+ }
+
+ @Override
+ public void collectVars(TObjectIntHashMap<Variable> allVars,
+ TIntHashSet vars) {
+ condition.collectVars(allVars, vars);
+ then_.collectVars(allVars, vars);
+ if(else_ != null)
+ else_.collectVars(allVars, vars);
+ }
+
+ @Override
+ protected void updateType() throws MatchException {
+ setType(then_.getType());
+ }
+
+ @Override
+ public IVal toVal(Environment env, CodeWriter w) {
+ IVal conditionVal = condition.toVal(env, w);
+ CodeWriter joinPoint = w.createBlock(getType());
+ CodeWriter thenBlock = w.createBlock();
+ if(else_ != null) {
+ CodeWriter elseBlock = w.createBlock();
+ w.if_(conditionVal, thenBlock.getContinuation(), elseBlock.getContinuation());
+
+ IVal elseVal = else_.toVal(env, elseBlock);
+ elseBlock.jump(joinPoint.getContinuation(), elseVal);
+ }
+ else {
+ w.if_(conditionVal, thenBlock.getContinuation(), joinPoint.getContinuation());
+ }
+ IVal thenVal = then_.toVal(env, thenBlock);
+ thenBlock.jump(joinPoint.getContinuation(), thenVal);
+ w.continueAs(joinPoint);
+
+ return w.getParameters()[0];
+ }
+
+ @Override
+ public void collectFreeVariables(THashSet<Variable> vars) {
+ condition.collectFreeVariables(vars);
+ then_.collectFreeVariables(vars);
+ if(else_ != null)
+ else_.collectFreeVariables(vars);
+ }
+
+ @Override
+ public Expression simplify(SimplificationContext context) {
+ condition = condition.simplify(context);
+ then_ = then_.simplify(context);
+ if(else_ != null)
+ else_ = else_.simplify(context);
+ return this;
+ }
+
+ @Override
+ public Expression resolve(TranslationContext context) {
+ condition = condition.resolve(context);
+ then_ = then_.resolve(context);
+ if(else_ != null)
+ else_ = else_.resolve(context);
+ return this;
+ }
+
+ @Override
+ public Expression replace(ReplaceContext context) {
+ return new EIf(condition.replace(context),
+ then_.replace(context),
+ else_ == null ? null : else_.replace(context));
+ }
+
+ @Override
+ public Expression checkBasicType(TypingContext context, Type requiredType) {
+ condition = condition.checkType(context, Types.BOOLEAN);
+ then_ = then_.checkType(context, requiredType);
+ if(else_ != null)
+ else_ = else_.checkType(context, requiredType);
+ else
+ context.getErrorLog().log(location, "Else branch is required because the return value of the if expression is used.");
+ return this;
+ }
+
+ @Override
+ public Expression checkIgnoredType(TypingContext context) {
+ condition = condition.checkType(context, Types.BOOLEAN);
+ then_ = then_.checkIgnoredType(context);
+ if(else_ != null)
+ else_ = else_.checkIgnoredType(context);
+ return this;
+ }
+
+ @Override
+ public Expression decorate(ExpressionDecorator decorator) {
+ condition = condition.decorate(decorator);
+ then_ = then_.decorate(decorator);
+ if(else_ != null)
+ else_ = else_.decorate(decorator);
+ return decorator.decorate(this);
+ }
+
+ @Override
+ public boolean isEffectful() {
+ return condition.isEffectful() || then_.isEffectful() || (else_ != null && else_.isEffectful());
+ }
+
+ @Override
+ public void collectEffects(THashSet<Type> effects) {
+ condition.collectEffects(effects);
+ then_.collectEffects(effects);
+ if(else_ != null)
+ else_.collectEffects(effects);
+ }
+
+ @Override
+ public void setLocationDeep(long loc) {
+ if(location == Locations.NO_LOCATION) {
+ location = loc;
+ condition.setLocationDeep(loc);
+ then_.setLocationDeep(loc);
+ if(else_ != null)
+ else_.setLocationDeep(loc);
+ }
+ }
+
+ @Override
+ public void accept(ExpressionVisitor visitor) {
+ visitor.visit(this);
+ }
+
+ @Override
+ public IExpression toIExpression(ExpressionInterpretationContext target) {
+ return new IIf(condition.toIExpression(target), then_.toIExpression(target),
+ else_ != null ? else_.toIExpression(target) : new IConstant(Tuple0.INSTANCE));
+ }
+
+ @Override
+ public void forVariables(VariableProcedure procedure) {
+ condition.forVariables(procedure);
+ then_.forVariables(procedure);
+ if(else_ != null)
+ else_.forVariables(procedure);
+ }
+ @Override
+ public Expression accept(ExpressionTransformer transformer) {
+ return transformer.transform(this);
+ }
+
+ @Override
+ public int getSyntacticFunctionArity() {
+ return Math.max(then_.getSyntacticFunctionArity(), else_.getSyntacticFunctionArity());
+ }
+}
\r
\r
import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
+import org.simantics.scl.compiler.common.names.Names;\r
import org.simantics.scl.compiler.constants.DoubleConstant;\r
import org.simantics.scl.compiler.constants.FloatConstant;\r
import org.simantics.scl.compiler.constants.IntegerConstant;\r
if(primitive != null)\r
return primitive;\r
return context.apply(\r
- context.getConstant(SimplificationContext.FROM_INTEGER, getType()),\r
+ context.getConstant(Names.Prelude_fromInteger, getType()),\r
constraint.simplify(context),\r
context.literal(new IntegerConstant(Integer.parseInt(value)))\r
);\r
-package org.simantics.scl.compiler.elaboration.expressions;\r
-\r
-import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;\r
-import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;\r
-import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
-import org.simantics.scl.compiler.elaboration.contexts.TypingContext;\r
-import org.simantics.scl.compiler.errors.Locations;\r
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;\r
-import org.simantics.scl.compiler.types.Type;\r
-import org.simantics.scl.compiler.types.Types;\r
-import org.simantics.scl.compiler.types.exceptions.MatchException;\r
-import org.simantics.scl.compiler.types.exceptions.UnificationException;\r
-import org.simantics.scl.compiler.types.kinds.Kinds;\r
-import org.simantics.scl.compiler.types.util.MultiFunction;\r
-\r
-import gnu.trove.map.hash.TObjectIntHashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
-public class ELambda extends SimplifiableExpression {\r
- public Case[] cases;\r
- Type effect = Types.NO_EFFECTS;\r
- \r
- public ELambda(Case[] cases) {\r
- this.cases = cases;\r
- }\r
- \r
- public ELambda(Case case_) {\r
- this(new Case[] {case_});\r
- }\r
-\r
- public ELambda(long loc, Case ... cases) {\r
- super(loc);\r
- this.cases = cases;\r
- }\r
- \r
- public ELambda(long loc, Expression pat, Expression exp) {\r
- this(loc, new Case(new Expression[] {pat}, exp));\r
- }\r
-\r
- public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {\r
- for(Case case_ : cases)\r
- case_.collectRefs(allRefs, refs);\r
- }\r
- \r
- @Override\r
- public void collectVars(TObjectIntHashMap<Variable> allVars,\r
- TIntHashSet vars) {\r
- for(Case case_ : cases)\r
- case_.collectVars(allVars, vars);\r
- }\r
-\r
- public Expression decomposeMatching() {\r
- Expression[] patterns = cases[0].patterns;\r
- int arity = patterns.length;\r
- \r
- // Simple cases\r
- if(cases.length == 1 && \r
- !(cases[0].value instanceof GuardedExpressionGroup)) {\r
- boolean noMatchingNeeded = true;\r
- for(int i=0;i<arity;++i)\r
- if(!(patterns[i] instanceof EVariable)) {\r
- noMatchingNeeded = false;\r
- break;\r
- }\r
- if(noMatchingNeeded) {\r
- Expression decomposed = cases[0].value.decomposeMatching();\r
- Type effect = this.effect;\r
- for(int i=arity-1;i>=0;--i) {\r
- Variable var = ((EVariable)patterns[i]).getVariable(); \r
- decomposed = new ESimpleLambda(getLocation(), var, effect, decomposed);\r
- effect = Types.NO_EFFECTS;\r
- }\r
- return decomposed;\r
- }\r
- }\r
- \r
- // Complex case\r
- Variable[] vars = new Variable[arity];\r
- Expression[] scrutinee = new Expression[arity];\r
- for(int i=0;i<arity;++i) {\r
- vars[i] = new Variable("temp" + i);\r
- Type type = patterns[i].getType();\r
- vars[i].setType(type);\r
- scrutinee[i] = new EVariable(getLocation(), vars[i]);\r
- scrutinee[i].setType(type);\r
- }\r
- Expression decomposed = new EMatch(getLocation(), scrutinee, cases);\r
- Type curEffect = this.effect;\r
- for(int i=arity-1;i>=0;--i) { \r
- decomposed = new ESimpleLambda(getLocation(), vars[i], curEffect, decomposed); \r
- curEffect = Types.NO_EFFECTS; \r
- }\r
- return decomposed;\r
- }\r
- \r
- @Override\r
- protected void updateType() throws MatchException {\r
- setType(Types.functionE(Types.getTypes(cases[0].patterns), effect, cases[0].value.getType()));\r
- }\r
- \r
- @Override\r
- public Expression simplify(SimplificationContext context) {\r
- return decomposeMatching().simplify(context);\r
- }\r
-\r
- @Override\r
- public void collectFreeVariables(THashSet<Variable> vars) {\r
- for(Case case_ : cases)\r
- case_.collectFreeVariables(vars);\r
- }\r
-\r
- @Override\r
- public Expression resolve(TranslationContext context) {\r
- for(Case case_ : cases)\r
- case_.resolve(context);\r
- return this;\r
- }\r
- \r
- @Override\r
- public void setLocationDeep(long loc) {\r
- if(location == Locations.NO_LOCATION) {\r
- location = loc;\r
- for(Case case_ : cases)\r
- case_.setLocationDeep(loc);\r
- }\r
- }\r
- \r
- @Override\r
- public Expression replace(ReplaceContext context) {\r
- Case[] newCases = new Case[cases.length];\r
- for(int i=0;i<cases.length;++i)\r
- newCases[i] = cases[i].replace(context);\r
- return new ELambda(newCases);\r
- }\r
-\r
- public Case[] getCases() {\r
- return cases;\r
- }\r
- \r
- public Expression checkBasicType(TypingContext context, Type requiredType) {\r
- int arity = cases[0].patterns.length;\r
- MultiFunction mfun;\r
- try {\r
- mfun = Types.unifyFunction(requiredType, arity);\r
- } catch (UnificationException e) {\r
- int requiredArity = Types.getArity(requiredType);\r
- context.getErrorLog().log(cases[0].getLhs(), "Arity is " + requiredArity + " but "\r
- + arity + " patterns have been given.");\r
- setType(Types.metaVar(Kinds.STAR));\r
- return this;\r
- }\r
- \r
- effect = mfun.effect;\r
- context.pushEffectUpperBound(location, mfun.effect);\r
- for(Case case_ : cases)\r
- case_.checkType(context, mfun.parameterTypes, mfun.returnType);\r
- context.popEffectUpperBound();\r
- return this;\r
- }\r
- \r
- @Override\r
- public Expression inferType(TypingContext context) {\r
- int arity = cases[0].patterns.length;\r
- effect = Types.metaVar(Kinds.EFFECT);\r
- context.pushEffectUpperBound(location, effect);\r
- Type[] parameterTypes = new Type[arity]; \r
- for(int i=0;i<parameterTypes.length;++i)\r
- parameterTypes[i] = Types.metaVar(Kinds.STAR);\r
- Type requiredType = Types.metaVar(Kinds.STAR);\r
- for(Case case_ : cases)\r
- case_.checkType(context, parameterTypes, requiredType);\r
- context.popEffectUpperBound();\r
- return this;\r
- }\r
-\r
- @Override\r
- public Expression decorate(ExpressionDecorator decorator) {\r
- if(decorator.decorateSubstructure(this))\r
- for(Case case_ : cases)\r
- case_.decorate(decorator);\r
- return decorator.decorate(this);\r
- }\r
- \r
- @Override\r
- public boolean isEffectful() {\r
- return false;\r
- }\r
-\r
- @Override\r
- public void collectEffects(THashSet<Type> effects) {\r
- for(Case case_ : cases) {\r
- for(Expression pattern : case_.patterns)\r
- pattern.collectEffects(effects);\r
- case_.value.collectEffects(effects);\r
- }\r
- }\r
- \r
- @Override\r
- public void accept(ExpressionVisitor visitor) {\r
- visitor.visit(this);\r
- }\r
-\r
- @Override\r
- public void forVariables(VariableProcedure procedure) {\r
- for(Case case_ : cases)\r
- case_.forVariables(procedure);\r
- }\r
- \r
- @Override\r
- public Expression accept(ExpressionTransformer transformer) {\r
- return transformer.transform(this);\r
- }\r
-\r
-}\r
+package org.simantics.scl.compiler.elaboration.expressions;
+
+import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;
+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.errors.Locations;
+import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
+import org.simantics.scl.compiler.types.Type;
+import org.simantics.scl.compiler.types.Types;
+import org.simantics.scl.compiler.types.exceptions.MatchException;
+import org.simantics.scl.compiler.types.exceptions.UnificationException;
+import org.simantics.scl.compiler.types.kinds.Kinds;
+import org.simantics.scl.compiler.types.util.MultiFunction;
+
+import gnu.trove.map.hash.TObjectIntHashMap;
+import gnu.trove.set.hash.THashSet;
+import gnu.trove.set.hash.TIntHashSet;
+
+public class ELambda extends SimplifiableExpression {
+ public Case[] cases;
+ Type effect = Types.NO_EFFECTS;
+
+ public ELambda(Case[] cases) {
+ this.cases = cases;
+ }
+
+ public ELambda(Case case_) {
+ this(new Case[] {case_});
+ }
+
+ public ELambda(long loc, Case ... cases) {
+ super(loc);
+ this.cases = cases;
+ }
+
+ public ELambda(long loc, Expression pat, Expression exp) {
+ this(loc, new Case(new Expression[] {pat}, exp));
+ }
+
+ public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {
+ for(Case case_ : cases)
+ case_.collectRefs(allRefs, refs);
+ }
+
+ @Override
+ public void collectVars(TObjectIntHashMap<Variable> allVars,
+ TIntHashSet vars) {
+ for(Case case_ : cases)
+ case_.collectVars(allVars, vars);
+ }
+
+ public Expression decomposeMatching() {
+ Expression[] patterns = cases[0].patterns;
+ int arity = patterns.length;
+
+ // Simple cases
+ if(cases.length == 1 &&
+ !(cases[0].value instanceof GuardedExpressionGroup)) {
+ boolean noMatchingNeeded = true;
+ for(int i=0;i<arity;++i)
+ if(!(patterns[i] instanceof EVariable)) {
+ noMatchingNeeded = false;
+ break;
+ }
+ if(noMatchingNeeded) {
+ Expression decomposed = cases[0].value.decomposeMatching();
+ Type effect = this.effect;
+ for(int i=arity-1;i>=0;--i) {
+ Variable var = ((EVariable)patterns[i]).getVariable();
+ decomposed = new ESimpleLambda(getLocation(), var, effect, decomposed);
+ effect = Types.NO_EFFECTS;
+ }
+ return decomposed;
+ }
+ }
+
+ // Complex case
+ Variable[] vars = new Variable[arity];
+ Expression[] scrutinee = new Expression[arity];
+ for(int i=0;i<arity;++i) {
+ vars[i] = new Variable("temp" + i);
+ Type type = patterns[i].getType();
+ vars[i].setType(type);
+ scrutinee[i] = new EVariable(getLocation(), vars[i]);
+ scrutinee[i].setType(type);
+ }
+ Expression decomposed = new EMatch(getLocation(), scrutinee, cases);
+ Type curEffect = this.effect;
+ for(int i=arity-1;i>=0;--i) {
+ decomposed = new ESimpleLambda(getLocation(), vars[i], curEffect, decomposed);
+ curEffect = Types.NO_EFFECTS;
+ }
+ return decomposed;
+ }
+
+ @Override
+ protected void updateType() throws MatchException {
+ setType(Types.functionE(Types.getTypes(cases[0].patterns), effect, cases[0].value.getType()));
+ }
+
+ @Override
+ public Expression simplify(SimplificationContext context) {
+ return decomposeMatching().simplify(context);
+ }
+
+ @Override
+ public void collectFreeVariables(THashSet<Variable> vars) {
+ for(Case case_ : cases)
+ case_.collectFreeVariables(vars);
+ }
+
+ @Override
+ public Expression resolve(TranslationContext context) {
+ for(Case case_ : cases)
+ case_.resolve(context);
+ return this;
+ }
+
+ @Override
+ public void setLocationDeep(long loc) {
+ if(location == Locations.NO_LOCATION) {
+ location = loc;
+ for(Case case_ : cases)
+ case_.setLocationDeep(loc);
+ }
+ }
+
+ @Override
+ public Expression replace(ReplaceContext context) {
+ Case[] newCases = new Case[cases.length];
+ for(int i=0;i<cases.length;++i)
+ newCases[i] = cases[i].replace(context);
+ return new ELambda(newCases);
+ }
+
+ public Case[] getCases() {
+ return cases;
+ }
+
+ public Expression checkBasicType(TypingContext context, Type requiredType) {
+ int arity = cases[0].patterns.length;
+ MultiFunction mfun;
+ try {
+ mfun = Types.unifyFunction(requiredType, arity);
+ } catch (UnificationException e) {
+ int requiredArity = Types.getArity(requiredType);
+ context.getErrorLog().log(cases[0].getLhs(), "Arity is " + requiredArity + " but "
+ + arity + " patterns have been given.");
+ setType(Types.metaVar(Kinds.STAR));
+ return this;
+ }
+
+ effect = mfun.effect;
+ context.pushEffectUpperBound(location, mfun.effect);
+ for(Case case_ : cases)
+ case_.checkType(context, mfun.parameterTypes, mfun.returnType);
+ context.popEffectUpperBound();
+ return this;
+ }
+
+ @Override
+ public Expression inferType(TypingContext context) {
+ int arity = cases[0].patterns.length;
+ effect = Types.metaVar(Kinds.EFFECT);
+ context.pushEffectUpperBound(location, effect);
+ Type[] parameterTypes = new Type[arity];
+ for(int i=0;i<parameterTypes.length;++i)
+ parameterTypes[i] = Types.metaVar(Kinds.STAR);
+ Type requiredType = Types.metaVar(Kinds.STAR);
+ for(Case case_ : cases)
+ case_.checkType(context, parameterTypes, requiredType);
+ context.popEffectUpperBound();
+ return this;
+ }
+
+ @Override
+ public Expression decorate(ExpressionDecorator decorator) {
+ if(decorator.decorateSubstructure(this))
+ for(Case case_ : cases)
+ case_.decorate(decorator);
+ return decorator.decorate(this);
+ }
+
+ @Override
+ public boolean isEffectful() {
+ return false;
+ }
+
+ @Override
+ public void collectEffects(THashSet<Type> effects) {
+ for(Case case_ : cases) {
+ for(Expression pattern : case_.patterns)
+ pattern.collectEffects(effects);
+ case_.value.collectEffects(effects);
+ }
+ }
+
+ @Override
+ public void accept(ExpressionVisitor visitor) {
+ visitor.visit(this);
+ }
+
+ @Override
+ public void forVariables(VariableProcedure procedure) {
+ for(Case case_ : cases)
+ case_.forVariables(procedure);
+ }
+
+ @Override
+ public Expression accept(ExpressionTransformer transformer) {
+ return transformer.transform(this);
+ }
+
+ @Override
+ public int getSyntacticFunctionArity() {
+ int result = 0;
+ for(Case case_ : cases)
+ result = Math.max(result, case_.patterns.length + case_.value.getSyntacticFunctionArity());
+ return result;
+ }
+
+}
-package org.simantics.scl.compiler.elaboration.expressions;\r
-\r
-import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
-import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;\r
-import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;\r
-import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
-import org.simantics.scl.compiler.elaboration.contexts.TypingContext;\r
-import org.simantics.scl.compiler.environment.Environment;\r
-import org.simantics.scl.compiler.errors.Locations;\r
-import org.simantics.scl.compiler.internal.codegen.references.IVal;\r
-import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;\r
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;\r
-import org.simantics.scl.compiler.internal.interpreted.IExpression;\r
-import org.simantics.scl.compiler.top.ExpressionInterpretationContext;\r
-import org.simantics.scl.compiler.types.TVar;\r
-import org.simantics.scl.compiler.types.Type;\r
-import org.simantics.scl.compiler.types.Types;\r
-import org.simantics.scl.compiler.types.exceptions.MatchException;\r
-\r
-import gnu.trove.map.hash.TObjectIntHashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
-public class ELambdaType extends Expression {\r
- public TVar[] parameters;\r
- public Expression value;\r
- \r
- public ELambdaType(TVar[] parameters, Expression value) {\r
- super(value.getLocation());\r
- this.parameters = parameters;\r
- this.value = value;\r
- }\r
-\r
- public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {\r
- value.collectRefs(allRefs, refs);\r
- }\r
- \r
- @Override\r
- public void collectVars(TObjectIntHashMap<Variable> allVars,\r
- TIntHashSet vars) {\r
- value.collectVars(allVars, vars);\r
- }\r
- \r
- @Override\r
- protected void updateType() throws MatchException {\r
- setType(Types.forAll(parameters, value.getType()));\r
- }\r
-\r
- @Override\r
- public IVal toVal(Environment env, CodeWriter w) {\r
- return lambdaToVal(env, w);\r
- }\r
-\r
- @Override\r
- public void collectFreeVariables(THashSet<Variable> vars) {\r
- value.collectFreeVariables(vars);\r
- }\r
-\r
- @Override\r
- public Expression simplify(SimplificationContext context) {\r
- value = value.simplify(context);\r
- return this;\r
- }\r
-\r
- @Override\r
- public Expression resolve(TranslationContext context) {\r
- value = value.resolve(context);\r
- return this;\r
- }\r
-\r
- @Override\r
- public Expression replace(ReplaceContext context) {\r
- TVar[] newParameters = new TVar[parameters.length];\r
- for(int i=0;i<parameters.length;++i) {\r
- TVar var = Types.var(parameters[i].getKind());\r
- newParameters[i] = var;\r
- context.tvarMap.put(parameters[i], var);\r
- }\r
- \r
- ELambdaType result = new ELambdaType(newParameters, value.replace(context));\r
- for(int i=0;i<parameters.length;++i)\r
- context.tvarMap.remove(parameters[i]);\r
- return result;\r
- }\r
- \r
- @Override\r
- public IExpression toIExpression(ExpressionInterpretationContext target) {\r
- return value.toIExpression(target);\r
- }\r
- \r
- @Override\r
- public Expression inferType(TypingContext context) {\r
- throw new InternalCompilerError("Should not type check " + getClass().getSimpleName() + ".");\r
- }\r
- \r
- @Override\r
- public Expression decorate(ExpressionDecorator decorator) {\r
- value = value.decorate(decorator);\r
- return decorator.decorate(this);\r
- }\r
-\r
- @Override\r
- public void collectEffects(THashSet<Type> effects) {\r
- }\r
- \r
- @Override\r
- public void setLocationDeep(long loc) {\r
- if(location == Locations.NO_LOCATION) {\r
- location = loc;\r
- value.setLocationDeep(loc);\r
- }\r
- }\r
- \r
- @Override\r
- public void accept(ExpressionVisitor visitor) {\r
- visitor.visit(this);\r
- }\r
-\r
- @Override\r
- public void forVariables(VariableProcedure procedure) {\r
- value.forVariables(procedure);\r
- }\r
- \r
- @Override\r
- public Expression accept(ExpressionTransformer transformer) {\r
- return transformer.transform(this);\r
- }\r
-\r
-}\r
+package org.simantics.scl.compiler.elaboration.expressions;
+
+import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
+import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;
+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.environment.Environment;
+import org.simantics.scl.compiler.errors.Locations;
+import org.simantics.scl.compiler.internal.codegen.references.IVal;
+import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;
+import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
+import org.simantics.scl.compiler.internal.interpreted.IExpression;
+import org.simantics.scl.compiler.top.ExpressionInterpretationContext;
+import org.simantics.scl.compiler.types.TVar;
+import org.simantics.scl.compiler.types.Type;
+import org.simantics.scl.compiler.types.Types;
+import org.simantics.scl.compiler.types.exceptions.MatchException;
+
+import gnu.trove.map.hash.TObjectIntHashMap;
+import gnu.trove.set.hash.THashSet;
+import gnu.trove.set.hash.TIntHashSet;
+
+public class ELambdaType extends Expression {
+ public TVar[] parameters;
+ public Expression value;
+
+ public ELambdaType(TVar[] parameters, Expression value) {
+ super(value.getLocation());
+ this.parameters = parameters;
+ this.value = value;
+ }
+
+ public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {
+ value.collectRefs(allRefs, refs);
+ }
+
+ @Override
+ public void collectVars(TObjectIntHashMap<Variable> allVars,
+ TIntHashSet vars) {
+ value.collectVars(allVars, vars);
+ }
+
+ @Override
+ protected void updateType() throws MatchException {
+ setType(Types.forAll(parameters, value.getType()));
+ }
+
+ @Override
+ public IVal toVal(Environment env, CodeWriter w) {
+ return lambdaToVal(env, w);
+ }
+
+ @Override
+ public void collectFreeVariables(THashSet<Variable> vars) {
+ value.collectFreeVariables(vars);
+ }
+
+ @Override
+ public Expression simplify(SimplificationContext context) {
+ value = value.simplify(context);
+ return this;
+ }
+
+ @Override
+ public Expression resolve(TranslationContext context) {
+ value = value.resolve(context);
+ return this;
+ }
+
+ @Override
+ public Expression replace(ReplaceContext context) {
+ TVar[] newParameters = new TVar[parameters.length];
+ for(int i=0;i<parameters.length;++i) {
+ TVar var = Types.var(parameters[i].getKind());
+ newParameters[i] = var;
+ context.tvarMap.put(parameters[i], var);
+ }
+
+ ELambdaType result = new ELambdaType(newParameters, value.replace(context));
+ for(int i=0;i<parameters.length;++i)
+ context.tvarMap.remove(parameters[i]);
+ return result;
+ }
+
+ @Override
+ public IExpression toIExpression(ExpressionInterpretationContext target) {
+ return value.toIExpression(target);
+ }
+
+ @Override
+ public Expression inferType(TypingContext context) {
+ throw new InternalCompilerError("Should not type check " + getClass().getSimpleName() + ".");
+ }
+
+ @Override
+ public Expression decorate(ExpressionDecorator decorator) {
+ value = value.decorate(decorator);
+ return decorator.decorate(this);
+ }
+
+ @Override
+ public void collectEffects(THashSet<Type> effects) {
+ }
+
+ @Override
+ public void setLocationDeep(long loc) {
+ if(location == Locations.NO_LOCATION) {
+ location = loc;
+ value.setLocationDeep(loc);
+ }
+ }
+
+ @Override
+ public void accept(ExpressionVisitor visitor) {
+ visitor.visit(this);
+ }
+
+ @Override
+ public void forVariables(VariableProcedure procedure) {
+ value.forVariables(procedure);
+ }
+
+ @Override
+ public Expression accept(ExpressionTransformer transformer) {
+ return transformer.transform(this);
+ }
+
+ @Override
+ public int getSyntacticFunctionArity() {
+ return value.getSyntacticFunctionArity();
+ }
+
+}
-package org.simantics.scl.compiler.elaboration.expressions;\r
-\r
-import java.util.ArrayList;\r
-\r
-import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
-import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;\r
-import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;\r
-import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
-import org.simantics.scl.compiler.elaboration.contexts.TypingContext;\r
-import org.simantics.scl.compiler.environment.Environment;\r
-import org.simantics.scl.compiler.errors.Locations;\r
-import org.simantics.scl.compiler.internal.codegen.references.BoundVar;\r
-import org.simantics.scl.compiler.internal.codegen.references.IVal;\r
-import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;\r
-import org.simantics.scl.compiler.internal.codegen.writer.RecursiveDefinitionWriter;\r
-import org.simantics.scl.compiler.internal.elaboration.decomposed.DecomposedExpression;\r
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;\r
-import org.simantics.scl.compiler.internal.elaboration.utils.StronglyConnectedComponents;\r
-import org.simantics.scl.compiler.types.Type;\r
-import org.simantics.scl.compiler.types.Types;\r
-import org.simantics.scl.compiler.types.exceptions.MatchException;\r
-import org.simantics.scl.compiler.types.kinds.Kinds;\r
-\r
-import gnu.trove.map.hash.TObjectIntHashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
-public class ELet extends Expression {\r
- public Assignment[] assignments;\r
- public Expression in;\r
- \r
- public ELet(long loc, Assignment[] assignments, Expression in) {\r
- super(loc);\r
- this.assignments = assignments;\r
- this.in = in;\r
- }\r
-\r
- @Override\r
- public void collectRefs(final TObjectIntHashMap<Object> allRefs, final TIntHashSet refs) {\r
- for(Assignment assign : assignments)\r
- assign.value.collectRefs(allRefs, refs);\r
- in.collectRefs(allRefs, refs);\r
- }\r
- \r
- @Override\r
- public void collectVars(TObjectIntHashMap<Variable> allVars,\r
- TIntHashSet vars) {\r
- for(Assignment assign : assignments)\r
- assign.value.collectVars(allVars, vars);\r
- in.collectVars(allVars, vars);\r
- }\r
- \r
- @Override\r
- protected void updateType() throws MatchException {\r
- setType(in.getType());\r
- }\r
- \r
- /**\r
- * Splits let \r
- */\r
- @Override\r
- public Expression simplify(SimplificationContext context) {\r
- \r
- // Simplify assignments\r
- for(Assignment assignment : assignments) {\r
- assignment.value = assignment.value.simplify(context);\r
- }\r
- \r
- // Find strongly connected components\r
- final TObjectIntHashMap<Variable> allVars = new TObjectIntHashMap<Variable>(\r
- 2*assignments.length, 0.5f, -1);\r
-\r
- for(int i=0;i<assignments.length;++i)\r
- for(Variable var : assignments[i].pattern.getFreeVariables())\r
- allVars.put(var, i);\r
- final boolean isRecursive[] = new boolean[assignments.length];\r
- final ArrayList<int[]> components = new ArrayList<int[]>(Math.max(10, assignments.length)); \r
- new StronglyConnectedComponents(assignments.length) {\r
- @Override\r
- protected int[] findDependencies(int u) {\r
- TIntHashSet vars = new TIntHashSet();\r
- assignments[u].value.collectVars(allVars, vars);\r
- if(vars.contains(u))\r
- isRecursive[u] = true;\r
- return vars.toArray();\r
- }\r
-\r
- @Override\r
- protected void reportComponent(int[] component) {\r
- components.add(component);\r
- }\r
-\r
- }.findComponents();\r
-\r
- // Simplify in\r
- Expression result = in.simplify(context);\r
- \r
- // Handle each component\r
- for(int j=components.size()-1;j>=0;--j) {\r
- int[] component = components.get(j);\r
- boolean recursive = component.length > 1 || isRecursive[component[0]];\r
- if(recursive) {\r
- Assignment[] cAssignments = new Assignment[component.length];\r
- for(int i=0;i<component.length;++i)\r
- cAssignments[i] = assignments[component[i]];\r
- result = new ELet(location, cAssignments, result);\r
- }\r
- else {\r
- Assignment assignment = assignments[component[0]];\r
- Expression pattern = assignment.pattern;\r
- \r
- if(pattern instanceof EVariable) {\r
- EVariable pvar = (EVariable)pattern;\r
- result = new ESimpleLet(location, pvar.variable, assignment.value, result);\r
- }\r
- else {\r
- result = new EMatch(location, new Expression[] {assignment.value},\r
- new Case(new Expression[] {pattern}, result));\r
- }\r
- }\r
- }\r
- \r
- return result;\r
- }\r
-\r
- @Override\r
- public void collectFreeVariables(THashSet<Variable> vars) {\r
- in.collectFreeVariables(vars);\r
- for(Assignment assign : assignments)\r
- assign.value.collectFreeVariables(vars);\r
- for(Assignment assign : assignments) \r
- assign.pattern.removeFreeVariables(vars);\r
- }\r
-\r
- @Override\r
- public Expression resolve(TranslationContext context) {\r
- throw new InternalCompilerError("ELet should be already resolved.");\r
- }\r
- \r
- @Override\r
- public Expression replace(ReplaceContext context) {\r
- Assignment[] newAssignments = new Assignment[assignments.length];\r
- for(int i=0;i<assignments.length;++i)\r
- newAssignments[i] = assignments[i].replace(context); \r
- Expression newIn = in.replace(context);\r
- return new ELet(getLocation(), newAssignments, newIn);\r
- }\r
- \r
- @Override\r
- public IVal toVal(Environment env, CodeWriter w) {\r
- // Create bound variables\r
- BoundVar[] vars = new BoundVar[assignments.length];\r
- for(int i=0;i<assignments.length;++i) {\r
- Expression pattern = assignments[i].pattern;\r
- if(!(pattern instanceof EVariable))\r
- throw new InternalCompilerError("Cannot handle pattern targets in recursive assignments.");\r
- vars[i] = new BoundVar(pattern.getType());\r
- ((EVariable)pattern).getVariable().setVal(vars[i]);\r
- }\r
- \r
- // Create values\r
- RecursiveDefinitionWriter rdw = w.createRecursiveDefinition();\r
- long range = Locations.NO_LOCATION;\r
- for(Assignment assign2 : assignments) {\r
- range = Locations.combine(range, assign2.pattern.location);\r
- range = Locations.combine(range, assign2.value.location);\r
- }\r
- rdw.setLocation(range);\r
- for(int i=0;i<assignments.length;++i) {\r
- DecomposedExpression decomposed = \r
- DecomposedExpression.decompose(assignments[i].value);\r
- CodeWriter newW = rdw.createFunction(vars[i], \r
- decomposed.typeParameters,\r
- decomposed.effect,\r
- decomposed.returnType, \r
- decomposed.parameterTypes);\r
- IVal[] parameters = newW.getParameters();\r
- for(int j=0;j<parameters.length;++j)\r
- decomposed.parameters[j].setVal(parameters[j]);\r
- newW.return_(decomposed.body.toVal(env, newW));\r
- }\r
- return in.toVal(env, w);\r
- }\r
- \r
- private void checkAssignments(TypingContext context) {\r
- for(Assignment assign : assignments)\r
- assign.pattern = assign.pattern.checkTypeAsPattern(context, Types.metaVar(Kinds.STAR));\r
- for(Assignment assign : assignments)\r
- assign.value = assign.value.checkType(context, assign.pattern.getType());\r
- }\r
- \r
- @Override\r
- public Expression inferType(TypingContext context) {\r
- checkAssignments(context);\r
- in = in.inferType(context);\r
- return this;\r
- }\r
- \r
- @Override\r
- public Expression checkBasicType(TypingContext context, Type requiredType) {\r
- checkAssignments(context);\r
- in = in.checkType(context, requiredType);\r
- return this;\r
- }\r
- \r
- @Override\r
- public Expression checkIgnoredType(TypingContext context) {\r
- checkAssignments(context);\r
- in = in.checkIgnoredType(context);\r
- return this;\r
- }\r
-\r
- @Override\r
- public Expression decorate(ExpressionDecorator decorator) {\r
- in = in.decorate(decorator);\r
- for(Assignment assignment : assignments)\r
- assignment.decorate(decorator);\r
- return decorator.decorate(this);\r
- }\r
-\r
- @Override\r
- public void collectEffects(THashSet<Type> effects) {\r
- for(Assignment assignment : assignments) {\r
- assignment.pattern.collectEffects(effects);\r
- assignment.value.collectEffects(effects);\r
- }\r
- in.collectEffects(effects);\r
- }\r
- \r
- @Override\r
- public void setLocationDeep(long loc) {\r
- if(location == Locations.NO_LOCATION) {\r
- location = loc;\r
- for(Assignment assignment : assignments)\r
- assignment.setLocationDeep(loc);\r
- in.setLocationDeep(loc);\r
- }\r
- }\r
- \r
- @Override\r
- public void accept(ExpressionVisitor visitor) {\r
- visitor.visit(this);\r
- }\r
-\r
- @Override\r
- public void forVariables(VariableProcedure procedure) {\r
- for(Assignment assignment : assignments)\r
- assignment.forVariables(procedure);\r
- in.forVariables(procedure);\r
- }\r
- \r
- @Override\r
- public Expression accept(ExpressionTransformer transformer) {\r
- return transformer.transform(this);\r
- }\r
-\r
-}\r
+package org.simantics.scl.compiler.elaboration.expressions;
+
+import java.util.ArrayList;
+
+import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
+import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;
+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.environment.Environment;
+import org.simantics.scl.compiler.errors.Locations;
+import org.simantics.scl.compiler.internal.codegen.references.BoundVar;
+import org.simantics.scl.compiler.internal.codegen.references.IVal;
+import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;
+import org.simantics.scl.compiler.internal.codegen.writer.RecursiveDefinitionWriter;
+import org.simantics.scl.compiler.internal.elaboration.decomposed.DecomposedExpression;
+import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
+import org.simantics.scl.compiler.internal.elaboration.utils.StronglyConnectedComponents;
+import org.simantics.scl.compiler.types.Type;
+import org.simantics.scl.compiler.types.Types;
+import org.simantics.scl.compiler.types.exceptions.MatchException;
+import org.simantics.scl.compiler.types.kinds.Kinds;
+
+import gnu.trove.map.hash.TObjectIntHashMap;
+import gnu.trove.set.hash.THashSet;
+import gnu.trove.set.hash.TIntHashSet;
+
+public class ELet extends Expression {
+ public Assignment[] assignments;
+ public Expression in;
+
+ public ELet(long loc, Assignment[] assignments, Expression in) {
+ super(loc);
+ this.assignments = assignments;
+ this.in = in;
+ }
+
+ @Override
+ public void collectRefs(final TObjectIntHashMap<Object> allRefs, final TIntHashSet refs) {
+ for(Assignment assign : assignments)
+ assign.value.collectRefs(allRefs, refs);
+ in.collectRefs(allRefs, refs);
+ }
+
+ @Override
+ public void collectVars(TObjectIntHashMap<Variable> allVars,
+ TIntHashSet vars) {
+ for(Assignment assign : assignments)
+ assign.value.collectVars(allVars, vars);
+ in.collectVars(allVars, vars);
+ }
+
+ @Override
+ protected void updateType() throws MatchException {
+ setType(in.getType());
+ }
+
+ /**
+ * Splits let
+ */
+ @Override
+ public Expression simplify(SimplificationContext context) {
+
+ // Simplify assignments
+ for(Assignment assignment : assignments) {
+ assignment.value = assignment.value.simplify(context);
+ }
+
+ // Find strongly connected components
+ final TObjectIntHashMap<Variable> allVars = new TObjectIntHashMap<Variable>(
+ 2*assignments.length, 0.5f, -1);
+
+ for(int i=0;i<assignments.length;++i)
+ for(Variable var : assignments[i].pattern.getFreeVariables())
+ allVars.put(var, i);
+ final boolean isRecursive[] = new boolean[assignments.length];
+ final ArrayList<int[]> components = new ArrayList<int[]>(Math.max(10, assignments.length));
+ new StronglyConnectedComponents(assignments.length) {
+ @Override
+ protected int[] findDependencies(int u) {
+ TIntHashSet vars = new TIntHashSet();
+ assignments[u].value.collectVars(allVars, vars);
+ if(vars.contains(u))
+ isRecursive[u] = true;
+ return vars.toArray();
+ }
+
+ @Override
+ protected void reportComponent(int[] component) {
+ components.add(component);
+ }
+
+ }.findComponents();
+
+ // Simplify in
+ Expression result = in.simplify(context);
+
+ // Handle each component
+ for(int j=components.size()-1;j>=0;--j) {
+ int[] component = components.get(j);
+ boolean recursive = component.length > 1 || isRecursive[component[0]];
+ if(recursive) {
+ Assignment[] cAssignments = new Assignment[component.length];
+ for(int i=0;i<component.length;++i)
+ cAssignments[i] = assignments[component[i]];
+ result = new ELet(location, cAssignments, result);
+ }
+ else {
+ Assignment assignment = assignments[component[0]];
+ Expression pattern = assignment.pattern;
+
+ if(pattern instanceof EVariable) {
+ EVariable pvar = (EVariable)pattern;
+ result = new ESimpleLet(location, pvar.variable, assignment.value, result);
+ }
+ else {
+ result = new EMatch(location, new Expression[] {assignment.value},
+ new Case(new Expression[] {pattern}, result));
+ }
+ }
+ }
+
+ return result;
+ }
+
+ @Override
+ public void collectFreeVariables(THashSet<Variable> vars) {
+ in.collectFreeVariables(vars);
+ for(Assignment assign : assignments)
+ assign.value.collectFreeVariables(vars);
+ for(Assignment assign : assignments)
+ assign.pattern.removeFreeVariables(vars);
+ }
+
+ @Override
+ public Expression resolve(TranslationContext context) {
+ throw new InternalCompilerError("ELet should be already resolved.");
+ }
+
+ @Override
+ public Expression replace(ReplaceContext context) {
+ Assignment[] newAssignments = new Assignment[assignments.length];
+ for(int i=0;i<assignments.length;++i)
+ newAssignments[i] = assignments[i].replace(context);
+ Expression newIn = in.replace(context);
+ return new ELet(getLocation(), newAssignments, newIn);
+ }
+
+ @Override
+ public IVal toVal(Environment env, CodeWriter w) {
+ // Create bound variables
+ BoundVar[] vars = new BoundVar[assignments.length];
+ for(int i=0;i<assignments.length;++i) {
+ Expression pattern = assignments[i].pattern;
+ if(!(pattern instanceof EVariable))
+ throw new InternalCompilerError("Cannot handle pattern targets in recursive assignments.");
+ vars[i] = new BoundVar(pattern.getType());
+ ((EVariable)pattern).getVariable().setVal(vars[i]);
+ }
+
+ // Create values
+ RecursiveDefinitionWriter rdw = w.createRecursiveDefinition();
+ long range = Locations.NO_LOCATION;
+ for(Assignment assign2 : assignments) {
+ range = Locations.combine(range, assign2.pattern.location);
+ range = Locations.combine(range, assign2.value.location);
+ }
+ rdw.setLocation(range);
+ for(int i=0;i<assignments.length;++i) {
+ DecomposedExpression decomposed =
+ DecomposedExpression.decompose(assignments[i].value);
+ CodeWriter newW = rdw.createFunction(vars[i],
+ decomposed.typeParameters,
+ decomposed.effect,
+ decomposed.returnType,
+ decomposed.parameterTypes);
+ IVal[] parameters = newW.getParameters();
+ for(int j=0;j<parameters.length;++j)
+ decomposed.parameters[j].setVal(parameters[j]);
+ newW.return_(decomposed.body.toVal(env, newW));
+ }
+ return in.toVal(env, w);
+ }
+
+ private void checkAssignments(TypingContext context) {
+ for(Assignment assign : assignments)
+ assign.pattern = assign.pattern.checkTypeAsPattern(context, Types.metaVar(Kinds.STAR));
+ for(Assignment assign : assignments)
+ assign.value = assign.value.checkType(context, assign.pattern.getType());
+ }
+
+ @Override
+ public Expression inferType(TypingContext context) {
+ checkAssignments(context);
+ in = in.inferType(context);
+ return this;
+ }
+
+ @Override
+ public Expression checkBasicType(TypingContext context, Type requiredType) {
+ checkAssignments(context);
+ in = in.checkType(context, requiredType);
+ return this;
+ }
+
+ @Override
+ public Expression checkIgnoredType(TypingContext context) {
+ checkAssignments(context);
+ in = in.checkIgnoredType(context);
+ return this;
+ }
+
+ @Override
+ public Expression decorate(ExpressionDecorator decorator) {
+ in = in.decorate(decorator);
+ for(Assignment assignment : assignments)
+ assignment.decorate(decorator);
+ return decorator.decorate(this);
+ }
+
+ @Override
+ public void collectEffects(THashSet<Type> effects) {
+ for(Assignment assignment : assignments) {
+ assignment.pattern.collectEffects(effects);
+ assignment.value.collectEffects(effects);
+ }
+ in.collectEffects(effects);
+ }
+
+ @Override
+ public void setLocationDeep(long loc) {
+ if(location == Locations.NO_LOCATION) {
+ location = loc;
+ for(Assignment assignment : assignments)
+ assignment.setLocationDeep(loc);
+ in.setLocationDeep(loc);
+ }
+ }
+
+ @Override
+ public void accept(ExpressionVisitor visitor) {
+ visitor.visit(this);
+ }
+
+ @Override
+ public void forVariables(VariableProcedure procedure) {
+ for(Assignment assignment : assignments)
+ assignment.forVariables(procedure);
+ in.forVariables(procedure);
+ }
+
+ @Override
+ public Expression accept(ExpressionTransformer transformer) {
+ return transformer.transform(this);
+ }
+
+ @Override
+ public int getSyntacticFunctionArity() {
+ return in.getSyntacticFunctionArity();
+ }
+
+}
return transformer.transform(this);\r
}\r
\r
+ @Override\r
+ public boolean equalsExpression(Expression expression) {\r
+ if(expression.getClass() != getClass())\r
+ return false;\r
+ ELiteral other = (ELiteral)expression;\r
+ return value.equals(other.value);\r
+ }\r
+\r
}\r
-package org.simantics.scl.compiler.elaboration.expressions;\r
-\r
-import java.util.ArrayList;\r
-\r
-import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;\r
-import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;\r
-import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
-import org.simantics.scl.compiler.elaboration.contexts.TypingContext;\r
-import org.simantics.scl.compiler.environment.Environment;\r
-import org.simantics.scl.compiler.errors.Locations;\r
-import org.simantics.scl.compiler.internal.codegen.references.IVal;\r
-import org.simantics.scl.compiler.internal.codegen.ssa.exits.Throw;\r
-import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;\r
-import org.simantics.scl.compiler.internal.elaboration.matching.PatternMatchingCompiler;\r
-import org.simantics.scl.compiler.internal.elaboration.matching.Row;\r
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;\r
-import org.simantics.scl.compiler.types.Type;\r
-import org.simantics.scl.compiler.types.Types;\r
-import org.simantics.scl.compiler.types.kinds.Kinds;\r
-\r
-import gnu.trove.map.hash.TObjectIntHashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
-public class EMatch extends Expression {\r
-\r
- public Expression[] scrutinee;\r
- public Case[] cases;\r
- \r
- public EMatch(Expression[] scrutinee, Case ... cases) {\r
- this.scrutinee = scrutinee;\r
- this.cases = cases;\r
- }\r
- \r
- public EMatch(Expression scrutinee, Case ... cases) {\r
- this(new Expression[] {scrutinee}, cases);\r
- }\r
-\r
- public EMatch(long loc, Expression[] scrutinee, Case ... cases) {\r
- super(loc);\r
- this.scrutinee = scrutinee;\r
- this.cases = cases;\r
- }\r
-\r
- public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {\r
- for(Expression s : scrutinee)\r
- s.collectRefs(allRefs, refs);\r
- for(Case case_ : cases)\r
- case_.collectRefs(allRefs, refs);\r
- }\r
- \r
- @Override\r
- public void collectVars(TObjectIntHashMap<Variable> allVars,\r
- TIntHashSet vars) {\r
- for(Expression s : scrutinee)\r
- s.collectVars(allVars, vars);\r
- for(Case case_ : cases)\r
- case_.collectVars(allVars, vars);\r
- }\r
- \r
- @Override\r
- protected void updateType() {\r
- setType(cases[0].value.getType());\r
- }\r
-\r
- @Override\r
- public IVal toVal(Environment env, CodeWriter w) {\r
- ArrayList<Row> rows = new ArrayList<Row>(cases.length);\r
- for(Case case_ : cases)\r
- rows.add(new Row(case_.patterns, case_.value));\r
- \r
- IVal[] scrutineeVals = new IVal[scrutinee.length];\r
- for(int i=0;i<scrutinee.length;++i)\r
- scrutineeVals[i] = scrutinee[i].toVal(env, w);\r
- \r
- CodeWriter joinPoint = w.createBlock(getType());\r
- CodeWriter failurePoint = w.createBlock(); // TODO generate only one failurePoint per function\r
- PatternMatchingCompiler.split(w, env, scrutineeVals, joinPoint.getContinuation(), failurePoint.getContinuation(), rows);\r
- failurePoint.throw_(location, Throw.MatchingException, "Matching failure at: " + toString());\r
- w.continueAs(joinPoint);\r
- return w.getParameters()[0];\r
- }\r
-\r
- @Override\r
- public void collectFreeVariables(THashSet<Variable> vars) {\r
- for(Expression s : scrutinee)\r
- s.collectFreeVariables(vars);\r
- for(Case case_ : cases)\r
- case_.collectFreeVariables(vars);\r
- }\r
- \r
- @Override\r
- public Expression simplify(SimplificationContext context) {\r
- for(int i=0;i<scrutinee.length;++i)\r
- scrutinee[i] = scrutinee[i].simplify(context);\r
- for(Case case_ : cases)\r
- case_.simplify(context); \r
- if(cases.length == 1 && scrutinee.length == 1) {\r
- Case case_ = cases[0];\r
- Expression pattern = case_.patterns[0];\r
- if(case_.patterns[0] instanceof EVariable\r
- && !(case_.value instanceof GuardedExpressionGroup)) {\r
- Variable var = ((EVariable)pattern).variable;\r
- return new ESimpleLet(var, scrutinee[0], case_.value);\r
- }\r
- }\r
- return this;\r
- }\r
-\r
- @Override\r
- public Expression resolve(TranslationContext context) {\r
- for(int i=0;i<scrutinee.length;++i)\r
- scrutinee[i] = scrutinee[i].resolve(context);\r
- for(Case case_ : cases)\r
- case_.resolve(context);\r
- return this;\r
- }\r
- \r
- @Override\r
- public void setLocationDeep(long loc) {\r
- if(location == Locations.NO_LOCATION) {\r
- location = loc;\r
- for(Case case_ : cases)\r
- case_.setLocationDeep(loc);\r
- for(Expression e : scrutinee)\r
- e.setLocationDeep(loc);\r
- }\r
- }\r
- \r
- @Override\r
- public Expression replace(ReplaceContext context) {\r
- Expression[] newScrutinee = new Expression[scrutinee.length];\r
- for(int i=0;i<scrutinee.length;++i)\r
- newScrutinee[i] = scrutinee[i].replace(context);\r
- Case[] newCases = new Case[cases.length];\r
- for(int i=0;i<cases.length;++i)\r
- newCases[i] = cases[i].replace(context);\r
- return new EMatch(getLocation(), newScrutinee, newCases);\r
- }\r
- \r
- @Override\r
- public Expression checkBasicType(TypingContext context, Type requiredType) {\r
- Type[] scrutineeTypes = new Type[scrutinee.length];\r
- for(int i=0;i<scrutinee.length;++i) {\r
- scrutinee[i] = scrutinee[i].checkType(context, Types.metaVar(Kinds.STAR));\r
- scrutineeTypes[i] = scrutinee[i].getType();\r
- }\r
- for(Case case_ : cases)\r
- case_.checkType(context, scrutineeTypes, requiredType);\r
- setType(requiredType);\r
- return this;\r
- }\r
- \r
- @Override\r
- public Expression checkIgnoredType(TypingContext context) {\r
- Type[] scrutineeTypes = new Type[scrutinee.length];\r
- for(int i=0;i<scrutinee.length;++i) {\r
- scrutinee[i] = scrutinee[i].checkType(context, Types.metaVar(Kinds.STAR));\r
- scrutineeTypes[i] = scrutinee[i].getType();\r
- }\r
- for(Case case_ : cases)\r
- case_.checkIgnoredType(context, scrutineeTypes);\r
- setType(Types.UNIT);\r
- return this;\r
- }\r
-\r
- @Override\r
- public Expression decorate(ExpressionDecorator decorator) {\r
- for(int i=0;i<scrutinee.length;++i)\r
- scrutinee[i] = scrutinee[i].decorate(decorator);\r
- for(Case case_ : cases)\r
- case_.decorate(decorator);\r
- return decorator.decorate(this);\r
- }\r
-\r
- @Override\r
- public void collectEffects(THashSet<Type> effects) {\r
- for(Expression s : scrutinee)\r
- s.collectEffects(effects);\r
- for(Case case_ : cases) {\r
- for(Expression pattern : case_.patterns)\r
- pattern.collectEffects(effects);\r
- case_.value.collectEffects(effects);\r
- }\r
- }\r
- \r
- @Override\r
- public void accept(ExpressionVisitor visitor) {\r
- visitor.visit(this);\r
- }\r
- \r
- public Expression[] getScrutinee() {\r
- return scrutinee;\r
- }\r
- \r
- public Case[] getCases() {\r
- return cases;\r
- }\r
-\r
- @Override\r
- public void forVariables(VariableProcedure procedure) {\r
- for(Expression s : scrutinee)\r
- s.forVariables(procedure);\r
- for(Case case_ : cases)\r
- case_.forVariables(procedure);\r
- }\r
- \r
- @Override\r
- public Expression accept(ExpressionTransformer transformer) {\r
- return transformer.transform(this);\r
- }\r
-\r
-}\r
+package org.simantics.scl.compiler.elaboration.expressions;
+
+import java.util.ArrayList;
+
+import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;
+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.environment.Environment;
+import org.simantics.scl.compiler.errors.Locations;
+import org.simantics.scl.compiler.internal.codegen.references.IVal;
+import org.simantics.scl.compiler.internal.codegen.ssa.exits.Throw;
+import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;
+import org.simantics.scl.compiler.internal.elaboration.matching.PatternMatchingCompiler;
+import org.simantics.scl.compiler.internal.elaboration.matching.Row;
+import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
+import org.simantics.scl.compiler.types.Type;
+import org.simantics.scl.compiler.types.Types;
+import org.simantics.scl.compiler.types.kinds.Kinds;
+
+import gnu.trove.map.hash.TObjectIntHashMap;
+import gnu.trove.set.hash.THashSet;
+import gnu.trove.set.hash.TIntHashSet;
+
+public class EMatch extends Expression {
+
+ public Expression[] scrutinee;
+ public Case[] cases;
+
+ public EMatch(Expression[] scrutinee, Case ... cases) {
+ this.scrutinee = scrutinee;
+ this.cases = cases;
+ }
+
+ public EMatch(Expression scrutinee, Case ... cases) {
+ this(new Expression[] {scrutinee}, cases);
+ }
+
+ public EMatch(long loc, Expression[] scrutinee, Case ... cases) {
+ super(loc);
+ this.scrutinee = scrutinee;
+ this.cases = cases;
+ }
+
+ public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {
+ for(Expression s : scrutinee)
+ s.collectRefs(allRefs, refs);
+ for(Case case_ : cases)
+ case_.collectRefs(allRefs, refs);
+ }
+
+ @Override
+ public void collectVars(TObjectIntHashMap<Variable> allVars,
+ TIntHashSet vars) {
+ for(Expression s : scrutinee)
+ s.collectVars(allVars, vars);
+ for(Case case_ : cases)
+ case_.collectVars(allVars, vars);
+ }
+
+ @Override
+ protected void updateType() {
+ setType(cases[0].value.getType());
+ }
+
+ @Override
+ public IVal toVal(Environment env, CodeWriter w) {
+ ArrayList<Row> rows = new ArrayList<Row>(cases.length);
+ for(Case case_ : cases)
+ rows.add(new Row(case_.patterns, case_.value));
+
+ IVal[] scrutineeVals = new IVal[scrutinee.length];
+ for(int i=0;i<scrutinee.length;++i)
+ scrutineeVals[i] = scrutinee[i].toVal(env, w);
+
+ CodeWriter joinPoint = w.createBlock(getType());
+ CodeWriter failurePoint = w.createBlock(); // TODO generate only one failurePoint per function
+ PatternMatchingCompiler.split(w, env, scrutineeVals, joinPoint.getContinuation(), failurePoint.getContinuation(), rows);
+ failurePoint.throw_(location, Throw.MatchingException, "Matching failure at: " + toString());
+ w.continueAs(joinPoint);
+ return w.getParameters()[0];
+ }
+
+ @Override
+ public void collectFreeVariables(THashSet<Variable> vars) {
+ for(Expression s : scrutinee)
+ s.collectFreeVariables(vars);
+ for(Case case_ : cases)
+ case_.collectFreeVariables(vars);
+ }
+
+ @Override
+ public Expression simplify(SimplificationContext context) {
+ for(int i=0;i<scrutinee.length;++i)
+ scrutinee[i] = scrutinee[i].simplify(context);
+ for(Case case_ : cases)
+ case_.simplify(context);
+ if(cases.length == 1 && scrutinee.length == 1) {
+ Case case_ = cases[0];
+ Expression pattern = case_.patterns[0];
+ if(case_.patterns[0] instanceof EVariable
+ && !(case_.value instanceof GuardedExpressionGroup)) {
+ Variable var = ((EVariable)pattern).variable;
+ return new ESimpleLet(var, scrutinee[0], case_.value);
+ }
+ }
+ return this;
+ }
+
+ @Override
+ public Expression resolve(TranslationContext context) {
+ for(int i=0;i<scrutinee.length;++i)
+ scrutinee[i] = scrutinee[i].resolve(context);
+ for(Case case_ : cases)
+ case_.resolve(context);
+ return this;
+ }
+
+ @Override
+ public void setLocationDeep(long loc) {
+ if(location == Locations.NO_LOCATION) {
+ location = loc;
+ for(Case case_ : cases)
+ case_.setLocationDeep(loc);
+ for(Expression e : scrutinee)
+ e.setLocationDeep(loc);
+ }
+ }
+
+ @Override
+ public Expression replace(ReplaceContext context) {
+ Expression[] newScrutinee = new Expression[scrutinee.length];
+ for(int i=0;i<scrutinee.length;++i)
+ newScrutinee[i] = scrutinee[i].replace(context);
+ Case[] newCases = new Case[cases.length];
+ for(int i=0;i<cases.length;++i)
+ newCases[i] = cases[i].replace(context);
+ return new EMatch(getLocation(), newScrutinee, newCases);
+ }
+
+ @Override
+ public Expression checkBasicType(TypingContext context, Type requiredType) {
+ Type[] scrutineeTypes = new Type[scrutinee.length];
+ for(int i=0;i<scrutinee.length;++i) {
+ scrutinee[i] = scrutinee[i].checkType(context, Types.metaVar(Kinds.STAR));
+ scrutineeTypes[i] = scrutinee[i].getType();
+ }
+ for(Case case_ : cases)
+ case_.checkType(context, scrutineeTypes, requiredType);
+ setType(requiredType);
+ return this;
+ }
+
+ @Override
+ public Expression checkIgnoredType(TypingContext context) {
+ Type[] scrutineeTypes = new Type[scrutinee.length];
+ for(int i=0;i<scrutinee.length;++i) {
+ scrutinee[i] = scrutinee[i].checkType(context, Types.metaVar(Kinds.STAR));
+ scrutineeTypes[i] = scrutinee[i].getType();
+ }
+ for(Case case_ : cases)
+ case_.checkIgnoredType(context, scrutineeTypes);
+ setType(Types.UNIT);
+ return this;
+ }
+
+ @Override
+ public Expression decorate(ExpressionDecorator decorator) {
+ for(int i=0;i<scrutinee.length;++i)
+ scrutinee[i] = scrutinee[i].decorate(decorator);
+ for(Case case_ : cases)
+ case_.decorate(decorator);
+ return decorator.decorate(this);
+ }
+
+ @Override
+ public void collectEffects(THashSet<Type> effects) {
+ for(Expression s : scrutinee)
+ s.collectEffects(effects);
+ for(Case case_ : cases) {
+ for(Expression pattern : case_.patterns)
+ pattern.collectEffects(effects);
+ case_.value.collectEffects(effects);
+ }
+ }
+
+ @Override
+ public void accept(ExpressionVisitor visitor) {
+ visitor.visit(this);
+ }
+
+ public Expression[] getScrutinee() {
+ return scrutinee;
+ }
+
+ public Case[] getCases() {
+ return cases;
+ }
+
+ @Override
+ public void forVariables(VariableProcedure procedure) {
+ for(Expression s : scrutinee)
+ s.forVariables(procedure);
+ for(Case case_ : cases)
+ case_.forVariables(procedure);
+ }
+
+ @Override
+ public Expression accept(ExpressionTransformer transformer) {
+ return transformer.transform(this);
+ }
+
+ @Override
+ public int getSyntacticFunctionArity() {
+ int result = 0;
+ for(Case case_ : cases)
+ result = Math.max(result, case_.value.getSyntacticFunctionArity());
+ return result;
+ }
+}
-package org.simantics.scl.compiler.elaboration.expressions;\r
-\r
-import java.util.ArrayList;\r
-import java.util.List;\r
-\r
-import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
-import org.simantics.scl.compiler.elaboration.errors.NotPatternException;\r
-import org.simantics.scl.compiler.elaboration.expressions.block.LetStatement;\r
-import org.simantics.scl.compiler.elaboration.expressions.lhstype.FunctionDefinitionLhs;\r
-import org.simantics.scl.compiler.elaboration.expressions.lhstype.LhsType;\r
-import org.simantics.scl.compiler.errors.Locations;\r
-\r
-import gnu.trove.map.hash.THashMap;\r
-import gnu.trove.procedure.TObjectObjectProcedure;\r
-\r
-public class EPreLet extends ASTExpression {\r
-\r
- List<LetStatement> assignments;\r
- Expression in;\r
- \r
- public EPreLet(List<LetStatement> assignments, Expression in) {\r
- this.assignments = assignments;\r
- this.in = in;\r
- }\r
- \r
- @Override\r
- public Expression resolve(final TranslationContext context) {\r
- context.pushFrame();\r
- THashMap<String, ArrayList<LetStatement>> functionDefinitions =\r
- new THashMap<String, ArrayList<LetStatement>>();\r
- ArrayList<LetStatement> otherDefinitions = new ArrayList<LetStatement>();\r
- final THashMap<String, Variable> localVars = new THashMap<String, Variable>();\r
- try {\r
- for(LetStatement assign : assignments) {\r
- LhsType lhsType = assign.pattern.getLhsType();\r
- if(!(assign.pattern instanceof EVar) && lhsType instanceof FunctionDefinitionLhs) {\r
- String name = ((FunctionDefinitionLhs)lhsType).functionName;\r
- ArrayList<LetStatement> group = functionDefinitions.get(name);\r
- if(group == null) {\r
- group = new ArrayList<LetStatement>(2);\r
- functionDefinitions.put(name, group);\r
- }\r
- group.add(assign);\r
- localVars.put(name, context.newVariable(name));\r
- }\r
- else {\r
- otherDefinitions.add(assign);\r
- assign.pattern = assign.pattern.resolveAsPattern(context);\r
- }\r
- }\r
- } catch (NotPatternException e) {\r
- context.getErrorLog().log(e.getExpression().location, "Not a pattern.");\r
- return new EError();\r
- }\r
- \r
- final ArrayList<Assignment> as = new ArrayList<Assignment>(functionDefinitions.size() + otherDefinitions.size());\r
- functionDefinitions.forEachEntry(new TObjectObjectProcedure<String, ArrayList<LetStatement>>() {\r
- @Override\r
- public boolean execute(String name, ArrayList<LetStatement> cases) {\r
- as.add(new Assignment(\r
- new EVariable(cases.size()==1 ? cases.get(0).pattern.location : location, localVars.get(name)), \r
- context.translateCases(cases)));\r
- return true;\r
- }\r
- });\r
- for(LetStatement stat : otherDefinitions)\r
- as.add(new Assignment(\r
- stat.pattern /* already resolved above */, \r
- stat.value.resolve(context)));\r
- Expression inExpr = in.resolve(context);\r
- context.popFrame();\r
- \r
- ELet result = new ELet(location, as.toArray(new Assignment[as.size()]), inExpr);\r
- /*System.out.println("-----------------------------------------");\r
- System.out.println(this);\r
- System.out.println("-----------------------------------------");\r
- System.out.println(result);\r
- System.out.println("-----------------------------------------");*/\r
- return result;\r
- }\r
-\r
- @Override\r
- public void setLocationDeep(long loc) {\r
- if(location == Locations.NO_LOCATION) {\r
- location = loc;\r
- for(LetStatement assignment : assignments)\r
- assignment.setLocationDeep(loc);\r
- in.setLocationDeep(loc);\r
- }\r
- }\r
- \r
- @Override\r
- public Expression accept(ExpressionTransformer transformer) {\r
- return transformer.transform(this);\r
- }\r
-\r
-}\r
+package org.simantics.scl.compiler.elaboration.expressions;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
+import org.simantics.scl.compiler.elaboration.errors.NotPatternException;
+import org.simantics.scl.compiler.elaboration.expressions.block.LetStatement;
+import org.simantics.scl.compiler.elaboration.expressions.lhstype.FunctionDefinitionLhs;
+import org.simantics.scl.compiler.elaboration.expressions.lhstype.LhsType;
+import org.simantics.scl.compiler.errors.Locations;
+
+import gnu.trove.map.hash.THashMap;
+import gnu.trove.procedure.TObjectObjectProcedure;
+
+public class EPreLet extends ASTExpression {
+
+ List<LetStatement> assignments;
+ Expression in;
+
+ public EPreLet(List<LetStatement> assignments, Expression in) {
+ this.assignments = assignments;
+ this.in = in;
+ }
+
+ @Override
+ public Expression resolve(final TranslationContext context) {
+ context.pushFrame();
+ THashMap<String, ArrayList<LetStatement>> functionDefinitions =
+ new THashMap<String, ArrayList<LetStatement>>();
+ ArrayList<LetStatement> otherDefinitions = new ArrayList<LetStatement>();
+ final THashMap<String, Variable> localVars = new THashMap<String, Variable>();
+ try {
+ for(LetStatement assign : assignments) {
+ LhsType lhsType = assign.pattern.getLhsType();
+ if(!(assign.pattern instanceof EVar) && lhsType instanceof FunctionDefinitionLhs) {
+ String name = ((FunctionDefinitionLhs)lhsType).functionName;
+ ArrayList<LetStatement> group = functionDefinitions.get(name);
+ if(group == null) {
+ group = new ArrayList<LetStatement>(2);
+ functionDefinitions.put(name, group);
+ }
+ group.add(assign);
+ localVars.put(name, context.newVariable(name));
+ }
+ else {
+ otherDefinitions.add(assign);
+ assign.pattern = assign.pattern.resolveAsPattern(context);
+ }
+ }
+ } catch (NotPatternException e) {
+ context.getErrorLog().log(e.getExpression().location, "Not a pattern.");
+ return new EError();
+ }
+
+ final ArrayList<Assignment> as = new ArrayList<Assignment>(functionDefinitions.size() + otherDefinitions.size());
+ functionDefinitions.forEachEntry(new TObjectObjectProcedure<String, ArrayList<LetStatement>>() {
+ @Override
+ public boolean execute(String name, ArrayList<LetStatement> cases) {
+ as.add(new Assignment(
+ new EVariable(cases.size()==1 ? cases.get(0).pattern.location : location, localVars.get(name)),
+ context.translateCases(cases)));
+ return true;
+ }
+ });
+ for(LetStatement stat : otherDefinitions)
+ as.add(new Assignment(
+ stat.pattern /* already resolved above */,
+ stat.value.resolve(context)));
+ Expression inExpr = in.resolve(context);
+ context.popFrame();
+
+ ELet result = new ELet(location, as.toArray(new Assignment[as.size()]), inExpr);
+ /*System.out.println("-----------------------------------------");
+ System.out.println(this);
+ System.out.println("-----------------------------------------");
+ System.out.println(result);
+ System.out.println("-----------------------------------------");*/
+ return result;
+ }
+
+ @Override
+ public void setLocationDeep(long loc) {
+ if(location == Locations.NO_LOCATION) {
+ location = loc;
+ for(LetStatement assignment : assignments)
+ assignment.setLocationDeep(loc);
+ in.setLocationDeep(loc);
+ }
+ }
+
+ @Override
+ public Expression accept(ExpressionTransformer transformer) {
+ return transformer.transform(this);
+ }
+
+ @Override
+ public int getSyntacticFunctionArity() {
+ return in.getSyntacticFunctionArity();
+ }
+
+}
-package org.simantics.scl.compiler.elaboration.expressions;\r
-\r
-import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
-import org.simantics.scl.compiler.elaboration.expressions.ERuleset.DatalogRule;\r
-import org.simantics.scl.compiler.elaboration.expressions.block.RuleStatement;\r
-import org.simantics.scl.compiler.elaboration.relations.LocalRelation;\r
-import org.simantics.scl.compiler.errors.Locations;\r
-\r
-import gnu.trove.map.hash.THashMap;\r
-\r
-public class EPreRuleset extends ASTExpression {\r
-\r
- RuleStatement[] statements;\r
- Expression in;\r
- \r
- public EPreRuleset(RuleStatement[] statements, Expression in) {\r
- this.statements = statements;\r
- this.in = in;\r
- }\r
-\r
- @Override\r
- public Expression resolve(TranslationContext context) {\r
- THashMap<String, LocalRelation> relations = new THashMap<String, LocalRelation>(); \r
- DatalogRule[] rules = new DatalogRule[statements.length];\r
- context.pushRelationFrame();\r
- try {\r
- for(int i=0;i<statements.length;++i) {\r
- RuleStatement statement = statements[i];\r
- Expression head = statement.head;\r
- if(!(head instanceof EApply)) {\r
- context.getErrorLog().log(head.location, "Invalid rule head.");\r
- return new EError();\r
- }\r
- EApply apply = (EApply)head;\r
- if(!(apply.function instanceof EVar)) {\r
- context.getErrorLog().log(head.location, "Invalid relation in rule head.");\r
- return new EError();\r
- }\r
- String relationName = ((EVar)apply.function).name;\r
- LocalRelation relation = relations.get(relationName);\r
- if(relation == null) {\r
- relation = new LocalRelation(relationName, apply.parameters.length);\r
- relations.put(relationName, relation);\r
- context.newRelation(relationName, relation);\r
- }\r
- else if(apply.parameters.length != relation.getArity()) {\r
- context.getErrorLog().log(apply.location, "Different rules have different relation arity.");\r
- return new EError();\r
- }\r
- rules[i] = new DatalogRule(relation, apply.parameters, statement.body);\r
- }\r
- for(DatalogRule rule : rules) {\r
- context.pushExistentialFrame();\r
- for(int i=0;i<rule.headParameters.length;++i)\r
- rule.headParameters[i] = rule.headParameters[i].resolve(context);\r
- rule.body = rule.body.resolve(context);\r
- rule.variables = context.popExistentialFrame();\r
- }\r
- return new ERuleset(\r
- relations.values().toArray(new LocalRelation[relations.size()]),\r
- rules,\r
- in.resolve(context));\r
- } finally {\r
- context.popRelationFrame();\r
- }\r
- }\r
-\r
- @Override\r
- public void setLocationDeep(long loc) {\r
- if(location == Locations.NO_LOCATION) {\r
- location = loc;\r
- for(RuleStatement statement : statements)\r
- statement.setLocationDeep(loc);\r
- in.setLocationDeep(loc);\r
- }\r
- }\r
- \r
- @Override\r
- public Expression accept(ExpressionTransformer transformer) {\r
- return transformer.transform(this);\r
- }\r
-\r
-}\r
+package org.simantics.scl.compiler.elaboration.expressions;
+
+import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
+import org.simantics.scl.compiler.elaboration.expressions.ERuleset.DatalogRule;
+import org.simantics.scl.compiler.elaboration.expressions.block.RuleStatement;
+import org.simantics.scl.compiler.elaboration.relations.LocalRelation;
+import org.simantics.scl.compiler.errors.Locations;
+
+import gnu.trove.map.hash.THashMap;
+
+public class EPreRuleset extends ASTExpression {
+
+ RuleStatement[] statements;
+ Expression in;
+
+ public EPreRuleset(RuleStatement[] statements, Expression in) {
+ this.statements = statements;
+ this.in = in;
+ }
+
+ @Override
+ public Expression resolve(TranslationContext context) {
+ THashMap<String, LocalRelation> relations = new THashMap<String, LocalRelation>();
+ DatalogRule[] rules = new DatalogRule[statements.length];
+ context.pushRelationFrame();
+ try {
+ for(int i=0;i<statements.length;++i) {
+ RuleStatement statement = statements[i];
+ Expression head = statement.head;
+ if(!(head instanceof EApply)) {
+ context.getErrorLog().log(head.location, "Invalid rule head.");
+ return new EError();
+ }
+ EApply apply = (EApply)head;
+ if(!(apply.function instanceof EVar)) {
+ context.getErrorLog().log(head.location, "Invalid relation in rule head.");
+ return new EError();
+ }
+ String relationName = ((EVar)apply.function).name;
+ LocalRelation relation = relations.get(relationName);
+ if(relation == null) {
+ relation = new LocalRelation(relationName, apply.parameters.length);
+ relations.put(relationName, relation);
+ context.newRelation(relationName, relation);
+ }
+ else if(apply.parameters.length != relation.getArity()) {
+ context.getErrorLog().log(apply.location, "Different rules have different relation arity.");
+ return new EError();
+ }
+ rules[i] = new DatalogRule(relation, apply.parameters, statement.body);
+ }
+ for(DatalogRule rule : rules) {
+ context.pushExistentialFrame();
+ for(int i=0;i<rule.headParameters.length;++i)
+ rule.headParameters[i] = rule.headParameters[i].resolve(context);
+ rule.body = rule.body.resolve(context);
+ rule.variables = context.popExistentialFrame();
+ }
+ return new ERuleset(
+ relations.values().toArray(new LocalRelation[relations.size()]),
+ rules,
+ in.resolve(context));
+ } finally {
+ context.popRelationFrame();
+ }
+ }
+
+ @Override
+ public void setLocationDeep(long loc) {
+ if(location == Locations.NO_LOCATION) {
+ location = loc;
+ for(RuleStatement statement : statements)
+ statement.setLocationDeep(loc);
+ in.setLocationDeep(loc);
+ }
+ }
+
+ @Override
+ public Expression accept(ExpressionTransformer transformer) {
+ return transformer.transform(this);
+ }
+
+ @Override
+ public int getSyntacticFunctionArity() {
+ return in.getSyntacticFunctionArity();
+ }
+
+}
package org.simantics.scl.compiler.elaboration.expressions;\r
\r
-import org.simantics.scl.compiler.common.names.Name;\r
+import org.simantics.scl.compiler.common.names.Names;\r
import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
import org.simantics.scl.compiler.elaboration.modules.SCLValue;\r
import org.simantics.scl.compiler.errors.Locations;\r
this.from = from;\r
this.to = to;\r
}\r
-\r
- private static final Name RANGE = Name.create("Prelude", "range");\r
\r
@Override\r
public Expression resolve(TranslationContext context) {\r
from = from.resolve(context);\r
to = to.resolve(context);\r
- SCLValue rangeFunction = context.getEnvironment().getValue(RANGE);\r
+ SCLValue rangeFunction = context.getEnvironment().getValue(Names.Prelude_range);\r
return new EApply(location, new EConstant(rangeFunction), from, to);\r
} \r
\r
\r
\r
import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
+import org.simantics.scl.compiler.common.names.Names;\r
import org.simantics.scl.compiler.constants.DoubleConstant;\r
import org.simantics.scl.compiler.constants.FloatConstant;\r
import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;\r
if(primitive != null)\r
return primitive;\r
return context.apply(\r
- context.getConstant(SimplificationContext.FROM_DOUBLE, getType()),\r
+ context.getConstant(Names.Prelude_fromDouble, getType()),\r
constraint.simplify(context),\r
context.literal(new DoubleConstant(Double.parseDouble(value)))\r
);\r
import java.util.Set;\r
\r
import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
-import org.simantics.scl.compiler.common.names.Name;\r
+import org.simantics.scl.compiler.common.names.Names;\r
import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
import org.simantics.scl.compiler.elaboration.contexts.TypingContext;\r
import org.simantics.scl.compiler.elaboration.expressions.printing.ExpressionToStringVisitor;\r
import org.simantics.scl.compiler.internal.elaboration.utils.ForcedClosure;\r
import org.simantics.scl.compiler.internal.elaboration.utils.StronglyConnectedComponents;\r
import org.simantics.scl.compiler.top.SCLCompilerConfiguration;\r
-import org.simantics.scl.compiler.types.TCon;\r
import org.simantics.scl.compiler.types.Type;\r
import org.simantics.scl.compiler.types.Types;\r
import org.simantics.scl.compiler.types.exceptions.MatchException;\r
Variable handleFunc;\r
}\r
\r
- public static final TCon MSet = Types.con("MSet", "T");\r
- private static final Name MSet_add = Name.create("MSet", "add");\r
- private static final Name MSet_create = Name.create("MSet", "create");\r
-\r
- private static final TCon MList = Types.con("MList", "T");\r
- private static final Name MList_add = Name.create("MList", "add");\r
- private static final Name MList_create = Name.create("MList", "create");\r
- private static final Name MList_removeLast = Name.create("MList", "removeLast");\r
- \r
public Expression compile(TypingContext context) {\r
// Create a map from relations to their ids\r
TObjectIntHashMap<SCLRelation> relationsToIds = new TObjectIntHashMap<SCLRelation>(relations.length,\r
LocalRelation relation = relations[i];\r
Type[] parameterTypes = relation.getParameterTypes();\r
stacks[i] = newVar("stack" + relation.getName(),\r
- Types.apply(MList, Types.tuple(parameterTypes))\r
+ Types.apply(Names.MList_T, Types.tuple(parameterTypes))\r
);\r
}\r
\r
ArrayList<Expression> seedExpressions = new ArrayList<Expression>(); \r
for(DatalogRule rule : rules) {\r
int id = diffables.get(rule.headRelation).id;\r
- Expression appendExp = apply(context, Types.PROC, MList_add, Types.tuple(rule.headRelation.getParameterTypes()),\r
+ Expression appendExp = apply(context.getCompilationContext(), Types.PROC, Names.MList_add, Types.tuple(rule.headRelation.getParameterTypes()),\r
var(stacks[id]),\r
tuple(rule.headParameters)\r
);\r
for(Expression updateExpression : updateExpressions[i])\r
handleRow = seq(updateExpression, handleRow);\r
handleRow = if_(\r
- apply(context, Types.PROC, MSet_add, rowType,\r
+ apply(context.getCompilationContext(), Types.PROC, Names.MSet_add, rowType,\r
var(relation.table), var(row)),\r
handleRow,\r
tuple()\r
apply(Types.PROC, var(loops[(i+1)%relations.length]), addInteger(var(counter), integer(-1)))\r
);\r
Expression body = matchWithDefault(\r
- apply(context, Types.PROC, MList_removeLast, rowType, var(stacks[i])),\r
+ apply(context.getCompilationContext(), Types.PROC, Names.MList_removeLast, rowType, var(stacks[i])),\r
Just(as(row, tuple(vars(parameters)))), handleRow,\r
failure);\r
\r
// Create stacks\r
for(int i=0;i<stacks.length;++i)\r
continuation = let(stacks[i],\r
- apply(context, Types.PROC, MList_create, Types.tuple(relations[i].getParameterTypes()), tuple()),\r
+ apply(context.getCompilationContext(), Types.PROC, Names.MList_create, Types.tuple(relations[i].getParameterTypes()), tuple()),\r
continuation);\r
\r
continuation = ForcedClosure.forceClosure(continuation, SCLCompilerConfiguration.EVERY_DATALOG_STRATUM_IN_SEPARATE_METHOD);\r
// Create relations\r
for(LocalRelation relation : relations)\r
continuation = let(relation.table,\r
- apply(context, Types.PROC, MSet_create, Types.tuple(relation.getParameterTypes()), tuple()),\r
+ apply(context.getCompilationContext(), Types.PROC, Names.MSet_create, Types.tuple(relation.getParameterTypes()), tuple()),\r
continuation);\r
\r
return seq(continuation, in);\r
import static org.simantics.scl.compiler.elaboration.expressions.Expressions.var;\r
\r
import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
-import org.simantics.scl.compiler.common.names.Name;\r
+import org.simantics.scl.compiler.common.names.Names;\r
import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;\r
import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
import org.simantics.scl.compiler.elaboration.contexts.TypingContext;\r
else {\r
Variable accumulator = newVar("accum", Types.apply(ARRAY_LIST, elType));\r
result =\r
- apply(context, Types.PROC, Name.create("ArrayList", "freeze"), elType,\r
+ apply(context.getCompilationContext(), Types.PROC, Names.ArrayList_freeze, elType,\r
var(accumulator));\r
Expression innerExpression = \r
- apply(context, Types.PROC, Name.create("ArrayList", "add"), elType,\r
+ apply(context.getCompilationContext(), Types.PROC, Names.ArrayList_add, elType,\r
var(accumulator), expression);\r
try {\r
QueryCompilationContext queryCompilationContext =\r
return new EError(getLocation());\r
}\r
result = let(accumulator,\r
- apply(context, Types.PROC, Name.create("ArrayList", "new"), elType, tuple()),\r
+ apply(context.getCompilationContext(), Types.PROC, Names.ArrayList_new, elType, tuple()),\r
result\r
);\r
}\r
-package org.simantics.scl.compiler.elaboration.expressions;\r
-\r
-import java.util.ArrayList;\r
-\r
-import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
-import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;\r
-import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;\r
-import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
-import org.simantics.scl.compiler.elaboration.contexts.TypingContext;\r
-import org.simantics.scl.compiler.environment.Environment;\r
-import org.simantics.scl.compiler.errors.Locations;\r
-import org.simantics.scl.compiler.internal.codegen.references.IVal;\r
-import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;\r
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;\r
-import org.simantics.scl.compiler.internal.interpreted.IExpression;\r
-import org.simantics.scl.compiler.internal.interpreted.ILambda;\r
-import org.simantics.scl.compiler.top.ExpressionInterpretationContext;\r
-import org.simantics.scl.compiler.top.SCLCompilerConfiguration;\r
-import org.simantics.scl.compiler.types.Type;\r
-import org.simantics.scl.compiler.types.Types;\r
-import org.simantics.scl.compiler.types.exceptions.MatchException;\r
-import org.simantics.scl.compiler.types.exceptions.UnificationException;\r
-import org.simantics.scl.compiler.types.kinds.Kinds;\r
-import org.simantics.scl.compiler.types.util.MultiFunction;\r
-\r
-import gnu.trove.map.hash.TObjectIntHashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
-public class ESimpleLambda extends Expression {\r
- public Variable parameter;\r
- public Expression value;\r
- public Type effect = Types.NO_EFFECTS;\r
- \r
- public ESimpleLambda(Variable parameter, Expression value) {\r
- this.parameter = parameter;\r
- this.value = value;\r
- }\r
- \r
- public ESimpleLambda(Type effect, Variable parameter, Expression value) {\r
- this.parameter = parameter;\r
- this.value = value;\r
- this.effect = effect;\r
- }\r
-\r
- public ESimpleLambda(long loc, Variable parameter, Expression value) {\r
- super(loc);\r
- this.parameter = parameter;\r
- this.value = value;\r
- }\r
- \r
- public ESimpleLambda(long loc, Variable parameter, Type effect, Expression value) {\r
- super(loc);\r
- this.parameter = parameter;\r
- this.value = value;\r
- this.effect = effect;\r
- }\r
-\r
- public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {\r
- value.collectRefs(allRefs, refs);\r
- }\r
- \r
- @Override\r
- public void collectVars(TObjectIntHashMap<Variable> allVars,\r
- TIntHashSet vars) {\r
- value.collectVars(allVars, vars);\r
- }\r
-\r
- public Expression decomposeMatching() {\r
- value = value.decomposeMatching();\r
- return this;\r
- }\r
-\r
- @Override\r
- protected void updateType() throws MatchException {\r
- setType(Types.functionE(Types.canonical(parameter.type),\r
- effect, value.getType()));\r
- }\r
- \r
- @Override\r
- public IVal toVal(Environment env, CodeWriter w) {\r
- return lambdaToVal(env, w);\r
- }\r
-\r
- @Override\r
- public void collectFreeVariables(THashSet<Variable> vars) {\r
- value.collectFreeVariables(vars);\r
- vars.remove(parameter);\r
- }\r
-\r
- @Override\r
- public Expression simplify(SimplificationContext context) {\r
- value = value.simplify(context);\r
- return this;\r
- }\r
-\r
- @Override\r
- public Expression resolve(TranslationContext context) {\r
- value = value.resolve(context);\r
- return this;\r
- }\r
-\r
- @Override\r
- public Expression replace(ReplaceContext context) {\r
- Variable newParameter = parameter.copy();\r
- context.varMap.put(parameter, new EVariable(newParameter));\r
- ESimpleLambda result = new ESimpleLambda(getLocation(),\r
- newParameter, \r
- effect.replace(context.tvarMap),\r
- value.replace(context));\r
- // not absolutely needed, but maybe good for performance\r
- context.varMap.remove(parameter); \r
- return result;\r
- }\r
- \r
- public Type getLocalEffect() {\r
- if(SCLCompilerConfiguration.DEBUG)\r
- if(effect == null)\r
- throw new InternalCompilerError();\r
- return effect;\r
- }\r
- \r
- public void setEffect(Type effect) {\r
- if(effect == null)\r
- throw new InternalCompilerError();\r
- this.effect = effect;\r
- }\r
- \r
- @Override\r
- public IExpression toIExpression(ExpressionInterpretationContext context) {\r
- // Find parameters of the whole function definition\r
- ArrayList<Variable> parameters = new ArrayList<Variable>(2);\r
- parameters.add(parameter);\r
- Expression cur = value;\r
- while(true) {\r
- if(cur instanceof ESimpleLambda) {\r
- ESimpleLambda lambda = (ESimpleLambda)cur;\r
- parameters.add(lambda.parameter);\r
- cur = lambda.value;\r
- }\r
- else if(cur instanceof ELambdaType) {\r
- cur = ((ELambdaType)cur).value;\r
- }\r
- else\r
- break;\r
- \r
- }\r
- \r
- // Free variables;\r
- ExpressionInterpretationContext innerContext = context.createNewContext();\r
- THashSet<Variable> freeVariables = cur.getFreeVariables();\r
- for(Variable parameter : parameters)\r
- freeVariables.remove(parameter);\r
- int i=0;\r
- int[] inheritedVariableIds = new int[freeVariables.size()];\r
- for(Variable var : freeVariables) {\r
- innerContext.push(var);\r
- inheritedVariableIds[i++] = context.getVariableId(var);\r
- }\r
- \r
- // Parameters\r
- for(Variable parameter : parameters)\r
- innerContext.push(parameter);\r
- \r
- // Construct lambda\r
- IExpression body = cur.toIExpression(innerContext); \r
- return new ILambda(inheritedVariableIds,\r
- parameters.size(),\r
- innerContext.getMaxVariableId(),\r
- body);\r
- }\r
- \r
- public Expression checkBasicType(TypingContext context, Type requiredType) {\r
- MultiFunction mfun;\r
- try {\r
- mfun = Types.unifyFunction(requiredType, 1);\r
- } catch (UnificationException e) {\r
- context.getErrorLog().log(location, "Required type is <" + requiredType + "> which is incompatible with lambda.");\r
- setType(Types.metaVar(Kinds.STAR));\r
- return this;\r
- }\r
- \r
- effect = mfun.effect;\r
- context.pushEffectUpperBound(location, mfun.effect);\r
- parameter.setType(mfun.parameterTypes[0]);\r
- value = value.checkType(context, mfun.returnType);\r
- context.popEffectUpperBound();\r
- return this;\r
- }\r
- \r
- @Override\r
- public Expression inferType(TypingContext context) {\r
- effect = Types.metaVar(Kinds.EFFECT);\r
- context.pushEffectUpperBound(location, effect);\r
- if(parameter.type == null)\r
- parameter.setType(Types.metaVar(Kinds.STAR));\r
- value = value.checkType(context, Types.metaVar(Kinds.STAR));\r
- context.popEffectUpperBound();\r
- return this;\r
- }\r
-\r
- @Override\r
- public Expression decorate(ExpressionDecorator decorator) {\r
- if(decorator.decorateSubstructure(this))\r
- value = value.decorate(decorator);\r
- return decorator.decorate(this);\r
- }\r
-\r
- @Override\r
- public boolean isEffectful() {\r
- return false;\r
- }\r
- \r
- @Override\r
- public void collectEffects(THashSet<Type> effects) {\r
- }\r
- \r
- @Override\r
- public void setLocationDeep(long loc) {\r
- if(location == Locations.NO_LOCATION) {\r
- location = loc;\r
- value.setLocationDeep(loc);\r
- }\r
- }\r
- \r
- @Override\r
- public void accept(ExpressionVisitor visitor) {\r
- visitor.visit(this);\r
- }\r
- \r
- public Expression getValue() {\r
- return value;\r
- }\r
- \r
- public Variable getParameter() {\r
- return parameter;\r
- }\r
-\r
- @Override\r
- public void forVariables(VariableProcedure procedure) {\r
- value.forVariables(procedure);\r
- }\r
- \r
- @Override\r
- public Expression accept(ExpressionTransformer transformer) {\r
- return transformer.transform(this);\r
- }\r
-\r
-}\r
+package org.simantics.scl.compiler.elaboration.expressions;
+
+import java.util.ArrayList;
+
+import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
+import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;
+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.environment.Environment;
+import org.simantics.scl.compiler.errors.Locations;
+import org.simantics.scl.compiler.internal.codegen.references.IVal;
+import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;
+import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
+import org.simantics.scl.compiler.internal.interpreted.IExpression;
+import org.simantics.scl.compiler.internal.interpreted.ILambda;
+import org.simantics.scl.compiler.top.ExpressionInterpretationContext;
+import org.simantics.scl.compiler.top.SCLCompilerConfiguration;
+import org.simantics.scl.compiler.types.Type;
+import org.simantics.scl.compiler.types.Types;
+import org.simantics.scl.compiler.types.exceptions.MatchException;
+import org.simantics.scl.compiler.types.exceptions.UnificationException;
+import org.simantics.scl.compiler.types.kinds.Kinds;
+import org.simantics.scl.compiler.types.util.MultiFunction;
+
+import gnu.trove.map.hash.TObjectIntHashMap;
+import gnu.trove.set.hash.THashSet;
+import gnu.trove.set.hash.TIntHashSet;
+
+public class ESimpleLambda extends Expression {
+ public Variable parameter;
+ public Expression value;
+ public Type effect = Types.NO_EFFECTS;
+
+ public ESimpleLambda(Variable parameter, Expression value) {
+ this.parameter = parameter;
+ this.value = value;
+ }
+
+ public ESimpleLambda(Type effect, Variable parameter, Expression value) {
+ this.parameter = parameter;
+ this.value = value;
+ this.effect = effect;
+ }
+
+ public ESimpleLambda(long loc, Variable parameter, Expression value) {
+ super(loc);
+ this.parameter = parameter;
+ this.value = value;
+ }
+
+ public ESimpleLambda(long loc, Variable parameter, Type effect, Expression value) {
+ super(loc);
+ this.parameter = parameter;
+ this.value = value;
+ this.effect = effect;
+ }
+
+ public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {
+ value.collectRefs(allRefs, refs);
+ }
+
+ @Override
+ public void collectVars(TObjectIntHashMap<Variable> allVars,
+ TIntHashSet vars) {
+ value.collectVars(allVars, vars);
+ }
+
+ public Expression decomposeMatching() {
+ value = value.decomposeMatching();
+ return this;
+ }
+
+ @Override
+ protected void updateType() throws MatchException {
+ setType(Types.functionE(Types.canonical(parameter.type),
+ effect, value.getType()));
+ }
+
+ @Override
+ public IVal toVal(Environment env, CodeWriter w) {
+ return lambdaToVal(env, w);
+ }
+
+ @Override
+ public void collectFreeVariables(THashSet<Variable> vars) {
+ value.collectFreeVariables(vars);
+ vars.remove(parameter);
+ }
+
+ @Override
+ public Expression simplify(SimplificationContext context) {
+ value = value.simplify(context);
+ return this;
+ }
+
+ @Override
+ public Expression resolve(TranslationContext context) {
+ value = value.resolve(context);
+ return this;
+ }
+
+ @Override
+ public Expression replace(ReplaceContext context) {
+ Variable newParameter = parameter.copy();
+ context.varMap.put(parameter, new EVariable(newParameter));
+ ESimpleLambda result = new ESimpleLambda(getLocation(),
+ newParameter,
+ effect.replace(context.tvarMap),
+ value.replace(context));
+ // not absolutely needed, but maybe good for performance
+ context.varMap.remove(parameter);
+ return result;
+ }
+
+ public Type getLocalEffect() {
+ if(SCLCompilerConfiguration.DEBUG)
+ if(effect == null)
+ throw new InternalCompilerError();
+ return effect;
+ }
+
+ public void setEffect(Type effect) {
+ if(effect == null)
+ throw new InternalCompilerError();
+ this.effect = effect;
+ }
+
+ @Override
+ public IExpression toIExpression(ExpressionInterpretationContext context) {
+ // Find parameters of the whole function definition
+ ArrayList<Variable> parameters = new ArrayList<Variable>(2);
+ parameters.add(parameter);
+ Expression cur = value;
+ while(true) {
+ if(cur instanceof ESimpleLambda) {
+ ESimpleLambda lambda = (ESimpleLambda)cur;
+ parameters.add(lambda.parameter);
+ cur = lambda.value;
+ }
+ else if(cur instanceof ELambdaType) {
+ cur = ((ELambdaType)cur).value;
+ }
+ else
+ break;
+
+ }
+
+ // Free variables;
+ ExpressionInterpretationContext innerContext = context.createNewContext();
+ THashSet<Variable> freeVariables = cur.getFreeVariables();
+ for(Variable parameter : parameters)
+ freeVariables.remove(parameter);
+ int i=0;
+ int[] inheritedVariableIds = new int[freeVariables.size()];
+ for(Variable var : freeVariables) {
+ innerContext.push(var);
+ inheritedVariableIds[i++] = context.getVariableId(var);
+ }
+
+ // Parameters
+ for(Variable parameter : parameters)
+ innerContext.push(parameter);
+
+ // Construct lambda
+ IExpression body = cur.toIExpression(innerContext);
+ return new ILambda(inheritedVariableIds,
+ parameters.size(),
+ innerContext.getMaxVariableId(),
+ body);
+ }
+
+ public Expression checkBasicType(TypingContext context, Type requiredType) {
+ MultiFunction mfun;
+ try {
+ mfun = Types.unifyFunction(requiredType, 1);
+ } catch (UnificationException e) {
+ context.getErrorLog().log(location, "Required type is <" + requiredType + "> which is incompatible with lambda.");
+ setType(Types.metaVar(Kinds.STAR));
+ return this;
+ }
+
+ effect = mfun.effect;
+ context.pushEffectUpperBound(location, mfun.effect);
+ parameter.setType(mfun.parameterTypes[0]);
+ value = value.checkType(context, mfun.returnType);
+ context.popEffectUpperBound();
+ return this;
+ }
+
+ @Override
+ public Expression inferType(TypingContext context) {
+ effect = Types.metaVar(Kinds.EFFECT);
+ context.pushEffectUpperBound(location, effect);
+ if(parameter.type == null)
+ parameter.setType(Types.metaVar(Kinds.STAR));
+ value = value.checkType(context, Types.metaVar(Kinds.STAR));
+ context.popEffectUpperBound();
+ return this;
+ }
+
+ @Override
+ public Expression decorate(ExpressionDecorator decorator) {
+ if(decorator.decorateSubstructure(this))
+ value = value.decorate(decorator);
+ return decorator.decorate(this);
+ }
+
+ @Override
+ public boolean isEffectful() {
+ return false;
+ }
+
+ @Override
+ public void collectEffects(THashSet<Type> effects) {
+ }
+
+ @Override
+ public void setLocationDeep(long loc) {
+ if(location == Locations.NO_LOCATION) {
+ location = loc;
+ value.setLocationDeep(loc);
+ }
+ }
+
+ @Override
+ public void accept(ExpressionVisitor visitor) {
+ visitor.visit(this);
+ }
+
+ public Expression getValue() {
+ return value;
+ }
+
+ public Variable getParameter() {
+ return parameter;
+ }
+
+ @Override
+ public void forVariables(VariableProcedure procedure) {
+ value.forVariables(procedure);
+ }
+
+ @Override
+ public Expression accept(ExpressionTransformer transformer) {
+ return transformer.transform(this);
+ }
+
+ @Override
+ public int getSyntacticFunctionArity() {
+ return 1 + value.getSyntacticFunctionArity();
+ }
+
+}
-package org.simantics.scl.compiler.elaboration.expressions;\r
-\r
-import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;\r
-import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;\r
-import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
-import org.simantics.scl.compiler.elaboration.contexts.TypingContext;\r
-import org.simantics.scl.compiler.environment.Environment;\r
-import org.simantics.scl.compiler.errors.Locations;\r
-import org.simantics.scl.compiler.internal.codegen.references.IVal;\r
-import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;\r
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;\r
-import org.simantics.scl.compiler.internal.interpreted.IExpression;\r
-import org.simantics.scl.compiler.internal.interpreted.ILet;\r
-import org.simantics.scl.compiler.internal.interpreted.ISeq;\r
-import org.simantics.scl.compiler.top.ExpressionInterpretationContext;\r
-import org.simantics.scl.compiler.types.Type;\r
-import org.simantics.scl.compiler.types.exceptions.MatchException;\r
-\r
-import gnu.trove.map.hash.TObjectIntHashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
-public class ESimpleLet extends Expression {\r
- Variable variable; // may be null\r
- Expression value;\r
- Expression in;\r
- \r
- public ESimpleLet(Variable variable, Expression value, Expression in) {\r
- if(value == null)\r
- throw new NullPointerException();\r
- if(in == null)\r
- throw new NullPointerException();\r
- this.variable = variable;\r
- this.value = value;\r
- this.in = in;\r
- }\r
-\r
- public ESimpleLet(long loc, Variable variable, Expression value, Expression in) {\r
- super(loc);\r
- if(value == null)\r
- throw new NullPointerException();\r
- if(in == null)\r
- throw new NullPointerException();\r
- this.variable = variable;\r
- this.value = value;\r
- this.in = in;\r
- }\r
-\r
- public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {\r
- value.collectRefs(allRefs, refs);\r
- in.collectRefs(allRefs, refs);\r
- }\r
- \r
- @Override\r
- public void collectVars(TObjectIntHashMap<Variable> allVars,\r
- TIntHashSet vars) {\r
- value.collectVars(allVars, vars);\r
- in.collectVars(allVars, vars);\r
- }\r
-\r
- @Override\r
- protected void updateType() throws MatchException {\r
- setType(in.getType());\r
- }\r
- \r
- @Override\r
- public IVal toVal(Environment env, CodeWriter w) {\r
- IVal valueVal = value.toVal(env, w);\r
- if(variable != null)\r
- variable.setVal(valueVal);\r
- return in.toVal(env, w);\r
- }\r
-\r
- @Override\r
- public void collectFreeVariables(THashSet<Variable> vars) {\r
- value.collectFreeVariables(vars);\r
- in.collectFreeVariables(vars);\r
- vars.remove(variable);\r
- }\r
-\r
- @Override\r
- public Expression simplify(SimplificationContext context) {\r
- value = value.simplify(context);\r
- if(value instanceof EConstant || value instanceof ELiteral) {\r
- context.addInlinedVariable(variable, value);\r
- return in.simplify(context);\r
- }\r
- in = in.simplify(context);\r
- return this;\r
- }\r
-\r
- @Override\r
- public Expression resolve(TranslationContext context) {\r
- value = value.resolve(context);\r
- in = in.resolve(context);\r
- return this;\r
- }\r
-\r
- @Override\r
- public Expression replace(ReplaceContext context) {\r
- if(variable == null)\r
- return new ESimpleLet(location,\r
- null, \r
- value.replace(context), \r
- in.replace(context));\r
- else {\r
- Variable newVariable = variable.copy();\r
- context.varMap.put(variable, new EVariable(newVariable));\r
- ESimpleLet result = new ESimpleLet(location, newVariable, \r
- value.replace(context), \r
- in.replace(context));\r
- context.varMap.remove(variable);\r
- return result;\r
- }\r
- }\r
- \r
- @Override\r
- public void setLocationDeep(long loc) {\r
- if(location == Locations.NO_LOCATION) {\r
- location = loc;\r
- value.setLocationDeep(loc);\r
- in.setLocationDeep(loc);\r
- }\r
- }\r
-\r
- @Override\r
- public IExpression toIExpression(ExpressionInterpretationContext context) {\r
- if(variable == null) {\r
- IExpression valueI = value.toIExpression(context);\r
- IExpression inI = in.toIExpression(context);\r
- return new ISeq(valueI, inI);\r
- }\r
- else {\r
- IExpression valueI = value.toIExpression(context);\r
- int variableId = context.push(variable);\r
- IExpression inI = in.toIExpression(context);\r
- context.pop(variable);\r
- return new ILet(variableId, valueI, inI);\r
- }\r
- }\r
-\r
- private void checkBinding(TypingContext context) {\r
- if(variable == null)\r
- value = value.checkIgnoredType(context);\r
- else if(variable.getType() == null) {\r
- value = value.inferType(context);\r
- variable.setType(value.getType());\r
- }\r
- else\r
- value = value.checkType(context, variable.type);\r
- /*else {\r
- if(variable.getType() == null)\r
- variable.setType(Types.metaVar(Kinds.STAR));\r
- value = value.checkType(context, variable.type);\r
- }*/\r
- }\r
- \r
- @Override\r
- public Expression inferType(TypingContext context) {\r
- checkBinding(context);\r
- in = in.inferType(context);\r
- return this;\r
- }\r
- \r
- @Override\r
- public Expression checkBasicType(TypingContext context, Type requiredType) {\r
- checkBinding(context);\r
- in = in.checkType(context, requiredType);\r
- return this;\r
- }\r
- \r
- @Override\r
- public Expression checkIgnoredType(TypingContext context) {\r
- checkBinding(context);\r
- in = in.checkIgnoredType(context);\r
- return this;\r
- }\r
-\r
- @Override\r
- public Expression decorate(ExpressionDecorator decorator) {\r
- value = value.decorate(decorator);\r
- in = in.decorate(decorator);\r
- return decorator.decorate(this);\r
- }\r
-\r
- @Override\r
- public void collectEffects(THashSet<Type> effects) {\r
- value.collectEffects(effects);\r
- in.collectEffects(effects);\r
- }\r
- \r
- @Override\r
- public void accept(ExpressionVisitor visitor) {\r
- visitor.visit(this);\r
- }\r
- \r
- public Expression getValue() {\r
- return value;\r
- }\r
- \r
- public Variable getVariable() {\r
- return variable;\r
- }\r
- \r
- public Expression getIn() {\r
- return in;\r
- }\r
-\r
- @Override\r
- public void forVariables(VariableProcedure procedure) {\r
- value.forVariables(procedure);\r
- in.forVariables(procedure);\r
- }\r
- \r
- @Override\r
- public Expression accept(ExpressionTransformer transformer) {\r
- return transformer.transform(this);\r
- }\r
-\r
-}\r
+package org.simantics.scl.compiler.elaboration.expressions;
+
+import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;
+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.environment.Environment;
+import org.simantics.scl.compiler.errors.Locations;
+import org.simantics.scl.compiler.internal.codegen.references.IVal;
+import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;
+import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
+import org.simantics.scl.compiler.internal.interpreted.IExpression;
+import org.simantics.scl.compiler.internal.interpreted.ILet;
+import org.simantics.scl.compiler.internal.interpreted.ISeq;
+import org.simantics.scl.compiler.top.ExpressionInterpretationContext;
+import org.simantics.scl.compiler.types.Type;
+import org.simantics.scl.compiler.types.exceptions.MatchException;
+
+import gnu.trove.map.hash.TObjectIntHashMap;
+import gnu.trove.set.hash.THashSet;
+import gnu.trove.set.hash.TIntHashSet;
+
+public class ESimpleLet extends Expression {
+ Variable variable; // may be null
+ Expression value;
+ Expression in;
+
+ public ESimpleLet(Variable variable, Expression value, Expression in) {
+ if(value == null)
+ throw new NullPointerException();
+ if(in == null)
+ throw new NullPointerException();
+ this.variable = variable;
+ this.value = value;
+ this.in = in;
+ }
+
+ public ESimpleLet(long loc, Variable variable, Expression value, Expression in) {
+ super(loc);
+ if(value == null)
+ throw new NullPointerException();
+ if(in == null)
+ throw new NullPointerException();
+ this.variable = variable;
+ this.value = value;
+ this.in = in;
+ }
+
+ public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {
+ value.collectRefs(allRefs, refs);
+ in.collectRefs(allRefs, refs);
+ }
+
+ @Override
+ public void collectVars(TObjectIntHashMap<Variable> allVars,
+ TIntHashSet vars) {
+ value.collectVars(allVars, vars);
+ in.collectVars(allVars, vars);
+ }
+
+ @Override
+ protected void updateType() throws MatchException {
+ setType(in.getType());
+ }
+
+ @Override
+ public IVal toVal(Environment env, CodeWriter w) {
+ IVal valueVal = value.toVal(env, w);
+ if(variable != null)
+ variable.setVal(valueVal);
+ return in.toVal(env, w);
+ }
+
+ @Override
+ public void collectFreeVariables(THashSet<Variable> vars) {
+ value.collectFreeVariables(vars);
+ in.collectFreeVariables(vars);
+ vars.remove(variable);
+ }
+
+ @Override
+ public Expression simplify(SimplificationContext context) {
+ value = value.simplify(context);
+ if(value instanceof EConstant || value instanceof ELiteral) {
+ context.addInlinedVariable(variable, value);
+ return in.simplify(context);
+ }
+ in = in.simplify(context);
+ return this;
+ }
+
+ @Override
+ public Expression resolve(TranslationContext context) {
+ value = value.resolve(context);
+ in = in.resolve(context);
+ return this;
+ }
+
+ @Override
+ public Expression replace(ReplaceContext context) {
+ if(variable == null)
+ return new ESimpleLet(location,
+ null,
+ value.replace(context),
+ in.replace(context));
+ else {
+ Variable newVariable = variable.copy();
+ context.varMap.put(variable, new EVariable(newVariable));
+ ESimpleLet result = new ESimpleLet(location, newVariable,
+ value.replace(context),
+ in.replace(context));
+ context.varMap.remove(variable);
+ return result;
+ }
+ }
+
+ @Override
+ public void setLocationDeep(long loc) {
+ if(location == Locations.NO_LOCATION) {
+ location = loc;
+ value.setLocationDeep(loc);
+ in.setLocationDeep(loc);
+ }
+ }
+
+ @Override
+ public IExpression toIExpression(ExpressionInterpretationContext context) {
+ if(variable == null) {
+ IExpression valueI = value.toIExpression(context);
+ IExpression inI = in.toIExpression(context);
+ return new ISeq(valueI, inI);
+ }
+ else {
+ IExpression valueI = value.toIExpression(context);
+ int variableId = context.push(variable);
+ IExpression inI = in.toIExpression(context);
+ context.pop(variable);
+ return new ILet(variableId, valueI, inI);
+ }
+ }
+
+ private void checkBinding(TypingContext context) {
+ if(variable == null)
+ value = value.checkIgnoredType(context);
+ else if(variable.getType() == null) {
+ value = value.inferType(context);
+ variable.setType(value.getType());
+ }
+ else
+ value = value.checkType(context, variable.type);
+ /*else {
+ if(variable.getType() == null)
+ variable.setType(Types.metaVar(Kinds.STAR));
+ value = value.checkType(context, variable.type);
+ }*/
+ }
+
+ @Override
+ public Expression inferType(TypingContext context) {
+ checkBinding(context);
+ in = in.inferType(context);
+ return this;
+ }
+
+ @Override
+ public Expression checkBasicType(TypingContext context, Type requiredType) {
+ checkBinding(context);
+ in = in.checkType(context, requiredType);
+ return this;
+ }
+
+ @Override
+ public Expression checkIgnoredType(TypingContext context) {
+ checkBinding(context);
+ in = in.checkIgnoredType(context);
+ return this;
+ }
+
+ @Override
+ public Expression decorate(ExpressionDecorator decorator) {
+ value = value.decorate(decorator);
+ in = in.decorate(decorator);
+ return decorator.decorate(this);
+ }
+
+ @Override
+ public void collectEffects(THashSet<Type> effects) {
+ value.collectEffects(effects);
+ in.collectEffects(effects);
+ }
+
+ @Override
+ public void accept(ExpressionVisitor visitor) {
+ visitor.visit(this);
+ }
+
+ public Expression getValue() {
+ return value;
+ }
+
+ public Variable getVariable() {
+ return variable;
+ }
+
+ public Expression getIn() {
+ return in;
+ }
+
+ @Override
+ public void forVariables(VariableProcedure procedure) {
+ value.forVariables(procedure);
+ in.forVariables(procedure);
+ }
+
+ @Override
+ public Expression accept(ExpressionTransformer transformer) {
+ return transformer.transform(this);
+ }
+
+ @Override
+ public int getSyntacticFunctionArity() {
+ return in.getSyntacticFunctionArity();
+ }
+}
package org.simantics.scl.compiler.elaboration.expressions;\r
\r
-import org.simantics.scl.compiler.common.names.Name;\r
+import org.simantics.scl.compiler.common.names.Names;\r
import org.simantics.scl.compiler.constants.StringInterpolation;\r
import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
import org.simantics.scl.compiler.elaboration.modules.SCLValue;\r
@Override\r
public Expression resolve(TranslationContext context) {\r
Expression[] components = new Expression[expressions.length];\r
- SCLValue showForPrinting = context.getEnvironment().getValue(Name.create("Prelude", "showForPrinting"));\r
+ SCLValue showForPrinting = context.getEnvironment().getValue(Names.Prelude_showForPrinting);\r
for(int i=0;i<expressions.length;++i)\r
components[i] = new EApply(new EConstant(showForPrinting), expressions[i]);\r
return new EApply(new ELiteral(new StringInterpolation(strings)), components).resolve(context);\r
public Expression accept(ExpressionTransformer transformer) {\r
return transformer.transform(this);\r
}\r
+ \r
+ @Override\r
+ public Expression resolveAsPattern(TranslationContext context) {\r
+ for(int i=0;i<expressions.length;++i)\r
+ expressions[i] = expressions[i].resolveAsPattern(context);\r
+ if(expressions.length > 1) {\r
+ context.getErrorLog().log(location, "String interpolation can be a pattern only if has one hole.");\r
+ return new EError();\r
+ }\r
+ return new EApply(new ELiteral(new StringInterpolation(strings)), expressions);\r
+ }\r
\r
\r
}\r
-package org.simantics.scl.compiler.elaboration.expressions;\r
-\r
-import java.util.ArrayList;\r
-\r
-import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
-import org.simantics.scl.compiler.elaboration.errors.NotPatternException;\r
-import org.simantics.scl.compiler.elaboration.expressions.lhstype.FunctionDefinitionLhs;\r
-import org.simantics.scl.compiler.elaboration.expressions.lhstype.LhsType;\r
-import org.simantics.scl.compiler.elaboration.expressions.lhstype.PatternMatchingLhs;\r
-import org.simantics.scl.compiler.errors.Locations;\r
-\r
-public class EVar extends ASTExpression {\r
- public final String name;\r
-\r
- public EVar(long location, String name) {\r
- this.location = location;\r
- this.name = name;\r
- }\r
- \r
- public EVar(String name) {\r
- this(Locations.NO_LOCATION, name);\r
- }\r
- \r
- @Override\r
- public EVar getPatternHead() {\r
- return this;\r
- }\r
- \r
- @Override\r
- public LhsType getLhsType() throws NotPatternException {\r
- if(TranslationContext.isConstructorName(name))\r
- return new PatternMatchingLhs();\r
- else\r
- return new FunctionDefinitionLhs(name);\r
- }\r
- \r
- @Override\r
- protected void collectVariableNames(PatternMatchingLhs lhsType)\r
- throws NotPatternException {\r
- if(!TranslationContext.isConstructorName(name))\r
- lhsType.variableNames.add(name);\r
- }\r
-\r
- @Override\r
- public Expression resolve(TranslationContext context) {\r
- return context.resolveExpression(location, name);\r
- }\r
- \r
- @Override\r
- public void getParameters(TranslationContext translationContext,\r
- ArrayList<Expression> parameters) {\r
- }\r
- \r
- @Override\r
- public Expression resolveAsPattern(TranslationContext context) {\r
- return context.resolvePattern(this);\r
- }\r
- \r
- @Override\r
- public int getFunctionDefinitionArity() throws NotPatternException {\r
- if(TranslationContext.isConstructorName(name))\r
- throw new NotPatternException(this);\r
- else\r
- return 0;\r
- }\r
- \r
- @Override\r
- public boolean isConstructorApplication() {\r
- return TranslationContext.isConstructorName(name);\r
- }\r
- \r
- @Override\r
- public void setLocationDeep(long loc) {\r
- if(location == Locations.NO_LOCATION)\r
- location = loc;\r
- }\r
- \r
- @Override\r
- public Expression accept(ExpressionTransformer transformer) {\r
- return transformer.transform(this);\r
- }\r
-}\r
+package org.simantics.scl.compiler.elaboration.expressions;
+
+import java.util.ArrayList;
+
+import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
+import org.simantics.scl.compiler.elaboration.errors.NotPatternException;
+import org.simantics.scl.compiler.elaboration.expressions.lhstype.FunctionDefinitionLhs;
+import org.simantics.scl.compiler.elaboration.expressions.lhstype.LhsType;
+import org.simantics.scl.compiler.elaboration.expressions.lhstype.PatternMatchingLhs;
+import org.simantics.scl.compiler.errors.Locations;
+
+public class EVar extends ASTExpression {
+ public final String name;
+
+ public EVar(long location, String name) {
+ this.location = location;
+ this.name = name;
+ }
+
+ public EVar(String name) {
+ this(Locations.NO_LOCATION, name);
+ }
+
+ @Override
+ public EVar getPatternHead() {
+ return this;
+ }
+
+ @Override
+ public LhsType getLhsType() throws NotPatternException {
+ if(TranslationContext.isConstructorName(name))
+ return new PatternMatchingLhs();
+ else
+ return new FunctionDefinitionLhs(name);
+ }
+
+ @Override
+ protected void collectVariableNames(PatternMatchingLhs lhsType)
+ throws NotPatternException {
+ if(!TranslationContext.isConstructorName(name))
+ lhsType.variableNames.add(name);
+ }
+
+ @Override
+ public Expression resolve(TranslationContext context) {
+ return context.resolveExpression(location, name);
+ }
+
+ @Override
+ public void getParameters(TranslationContext translationContext,
+ ArrayList<Expression> parameters) {
+ }
+
+ @Override
+ public Expression resolveAsPattern(TranslationContext context) {
+ return context.resolvePattern(this);
+ }
+
+ @Override
+ public int getFunctionDefinitionPatternArity() throws NotPatternException {
+ if(TranslationContext.isConstructorName(name))
+ throw new NotPatternException(this);
+ else
+ return 0;
+ }
+
+ @Override
+ public boolean isConstructorApplication() {
+ return TranslationContext.isConstructorName(name);
+ }
+
+ @Override
+ public void setLocationDeep(long loc) {
+ if(location == Locations.NO_LOCATION)
+ location = loc;
+ }
+
+ @Override
+ public Expression accept(ExpressionTransformer transformer) {
+ return transformer.transform(this);
+ }
+}
return this;\r
}\r
else\r
- return applyPUnit(context);\r
+ return applyPUnit(context.getCompilationContext());\r
}\r
\r
@Override\r
public Expression accept(ExpressionTransformer transformer) {\r
return transformer.transform(this);\r
}\r
+ \r
+ @Override\r
+ public boolean equalsExpression(Expression expression) {\r
+ if(expression.getClass() != getClass())\r
+ return false;\r
+ EVariable other = (EVariable)expression;\r
+ return variable == other.variable;\r
+ }\r
\r
}\r
--- /dev/null
+package org.simantics.scl.compiler.elaboration.expressions;\r
+\r
+import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
+import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;\r
+import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
+import org.simantics.scl.compiler.elaboration.contexts.TypingContext;\r
+import org.simantics.scl.compiler.environment.Environment;\r
+import org.simantics.scl.compiler.errors.Locations;\r
+import org.simantics.scl.compiler.internal.codegen.references.IVal;\r
+import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;\r
+import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;\r
+import org.simantics.scl.compiler.types.Type;\r
+import org.simantics.scl.compiler.types.Types;\r
+import org.simantics.scl.compiler.types.exceptions.MatchException;\r
+import org.simantics.scl.compiler.types.util.MultiFunction;\r
+\r
+import gnu.trove.map.hash.TObjectIntHashMap;\r
+import gnu.trove.set.hash.THashSet;\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
+public class EViewPattern extends Expression {\r
+ public Expression expression;\r
+ public Expression pattern;\r
+ \r
+ public EViewPattern(Expression expression, Expression pattern) {\r
+ this.expression = expression;\r
+ this.pattern = pattern;\r
+ }\r
+\r
+ @Override\r
+ public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {\r
+ expression.collectRefs(allRefs, refs);\r
+ pattern.collectRefs(allRefs, refs);\r
+ }\r
+\r
+ @Override\r
+ public void collectVars(TObjectIntHashMap<Variable> allVars, TIntHashSet vars) {\r
+ expression.collectVars(allVars, vars);\r
+ pattern.collectVars(allVars, vars);\r
+ }\r
+\r
+ @Override\r
+ public void forVariables(VariableProcedure procedure) {\r
+ expression.forVariables(procedure);\r
+ pattern.forVariables(procedure);\r
+ }\r
+ \r
+ @Override\r
+ public Expression inferType(TypingContext context) {\r
+ context.setInPattern(false);\r
+ expression = expression.inferType(context);\r
+ context.setInPattern(true);\r
+ MultiFunction mfun;\r
+ try {\r
+ mfun = Types.matchFunction(expression.getType(), 1);\r
+ } catch (MatchException e) {\r
+ context.getErrorLog().log(expression.location, "Expected a function as a transformation expression.");\r
+ return new EError(location);\r
+ }\r
+ setType(mfun.parameterTypes[0]);\r
+ pattern.checkType(context, mfun.returnType);\r
+ return this;\r
+ }\r
+\r
+ @Override\r
+ protected void updateType() throws MatchException {\r
+ MultiFunction mfun = Types.matchFunction(expression.getType(), 1);\r
+ setType(mfun.parameterTypes[0]);\r
+ }\r
+\r
+ @Override\r
+ public IVal toVal(Environment env, CodeWriter w) {\r
+ throw new InternalCompilerError(location, "EViewPattern.toVal should not be invoked.");\r
+ }\r
+\r
+ @Override\r
+ public void collectFreeVariables(THashSet<Variable> vars) {\r
+ throw new InternalCompilerError(location, "Cannot collect free variables for a pattern.");\r
+ }\r
+ \r
+ @Override\r
+ public void removeFreeVariables(THashSet<Variable> vars) {\r
+ expression.collectFreeVariables(vars);\r
+ pattern.removeFreeVariables(vars);\r
+ }\r
+\r
+ @Override\r
+ public Expression resolve(TranslationContext context) {\r
+ context.getErrorLog().log("View pattern cannot occur only in patterns. Maybe you are missing '\\' in front of a lambda experssion?");\r
+ return new EError(location);\r
+ }\r
+\r
+ @Override\r
+ public Expression resolveAsPattern(TranslationContext context) {\r
+ expression = expression.resolve(context);\r
+ pattern = pattern.resolveAsPattern(context);\r
+ return this;\r
+ }\r
+ \r
+ @Override\r
+ public void setLocationDeep(long loc) {\r
+ if(location == Locations.NO_LOCATION) {\r
+ location = loc; \r
+ expression.setLocationDeep(loc);\r
+ pattern.setLocationDeep(loc);\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public Expression decorate(ExpressionDecorator decorator) {\r
+ expression = expression.decorate(decorator);\r
+ return this;\r
+ }\r
+\r
+ @Override\r
+ public void collectEffects(THashSet<Type> effects) {\r
+ expression.collectEffects(effects);\r
+ }\r
+\r
+ @Override\r
+ public void accept(ExpressionVisitor visitor) {\r
+ visitor.visit(this);\r
+ }\r
+\r
+ @Override\r
+ public Expression accept(ExpressionTransformer transformer) {\r
+ return transformer.transform(this);\r
+ }\r
+ \r
+ @Override\r
+ public Expression simplify(SimplificationContext context) {\r
+ expression = expression.simplify(context);\r
+ pattern = pattern.simplify(context);\r
+ return this;\r
+ }\r
+\r
+}\r
-package org.simantics.scl.compiler.elaboration.expressions;\r
-\r
-import java.util.ArrayList;\r
-\r
-import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
-import org.simantics.scl.compiler.common.precedence.Precedence;\r
-import org.simantics.scl.compiler.constants.NoRepConstant;\r
-import org.simantics.scl.compiler.elaboration.contexts.EnvironmentalContext;\r
-import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;\r
-import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;\r
-import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
-import org.simantics.scl.compiler.elaboration.contexts.TypingContext;\r
-import org.simantics.scl.compiler.elaboration.errors.NotPatternException;\r
-import org.simantics.scl.compiler.elaboration.expressions.lhstype.LhsType;\r
-import org.simantics.scl.compiler.elaboration.expressions.lhstype.PatternMatchingLhs;\r
-import org.simantics.scl.compiler.elaboration.expressions.printing.ExpressionToStringVisitor;\r
-import org.simantics.scl.compiler.elaboration.query.QAtom;\r
-import org.simantics.scl.compiler.elaboration.relations.SCLRelation;\r
-import org.simantics.scl.compiler.environment.Environment;\r
-import org.simantics.scl.compiler.internal.codegen.references.IVal;\r
-import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;\r
-import org.simantics.scl.compiler.internal.elaboration.decomposed.DecomposedExpression;\r
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;\r
-import org.simantics.scl.compiler.internal.interpreted.IExpression;\r
-import org.simantics.scl.compiler.internal.parsing.Symbol;\r
-import org.simantics.scl.compiler.top.ExpressionInterpretationContext;\r
-import org.simantics.scl.compiler.types.TForAll;\r
-import org.simantics.scl.compiler.types.TFun;\r
-import org.simantics.scl.compiler.types.TPred;\r
-import org.simantics.scl.compiler.types.TVar;\r
-import org.simantics.scl.compiler.types.Type;\r
-import org.simantics.scl.compiler.types.Types;\r
-import org.simantics.scl.compiler.types.exceptions.MatchException;\r
-import org.simantics.scl.compiler.types.kinds.Kinds;\r
-import org.simantics.scl.compiler.types.util.Typed;\r
-\r
-import gnu.trove.map.hash.TObjectIntHashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
-public abstract class Expression extends Symbol implements Typed {\r
- public static final Expression[] EMPTY_ARRAY = new Expression[0];\r
- \r
- transient\r
- private Type type;\r
- \r
- public Expression() {\r
- }\r
- \r
- public Expression(long loc) {\r
- this.location = loc;\r
- }\r
- \r
- @Override\r
- public Type getType() {\r
- if(type == null) {\r
- try {\r
- updateType();\r
- } catch (MatchException e) {\r
- throw new InternalCompilerError(e);\r
- }\r
- if(type == null)\r
- throw new InternalCompilerError(getClass().getSimpleName() + \r
- ".updateType couldn't compute its type.");\r
- }\r
- return type;\r
- }\r
-\r
- public void setType(Type type) {\r
- if(type == null)\r
- throw new NullPointerException();\r
- this.type = type;\r
- }\r
- \r
- /**\r
- * Infers the type of the expression without any context. Adds type\r
- * applications and lambdas if needed. \r
- */\r
- public Expression inferType(TypingContext context) {\r
- return checkBasicType(context, Types.metaVar(Kinds.STAR));\r
- }\r
-\r
- public Expression checkBasicType(TypingContext context, Type requiredType) {\r
- return context.subsume(inferType(context), requiredType);\r
- }\r
- \r
- protected Expression applyPUnit(EnvironmentalContext context) {\r
- Type type = Types.canonical(getType());\r
- if(type instanceof TFun) {\r
- TFun fun = (TFun)type;\r
- if(fun.getCanonicalDomain() == Types.PUNIT) {\r
- EApply result = new EApply(location, this, new ELiteral(NoRepConstant.PUNIT));\r
- result.effect = fun.getCanonicalEffect();\r
- return result;\r
- }\r
- }\r
- return this;\r
- }\r
-\r
- public Expression checkIgnoredType(TypingContext context) {\r
- Expression expression = inferType(context);\r
- if(Types.canonical(expression.getType()) != Types.UNIT)\r
- expression = new ESimpleLet(location, null, expression, new ELiteral(NoRepConstant.PUNIT));\r
- return expression;\r
- }\r
- \r
- /**\r
- * Checks the type of the expression against the given type. Adds type\r
- * applications and lambdas if needed.\r
- */\r
- public final Expression checkType(TypingContext context, Type requiredType) {\r
- //System.out.println("checkType: " + this + " :: " + requiredType);\r
- if(!context.isInPattern()) {\r
- requiredType = Types.canonical(requiredType);\r
- if(requiredType instanceof TForAll) {\r
- TForAll forAll = (TForAll)requiredType;\r
- TVar var = forAll.var;\r
- TVar newVar = Types.var(var.getKind());\r
- requiredType = Types.canonical(forAll.type).replace(var, newVar);\r
- return new ELambdaType(new TVar[] {newVar}, checkType(context, requiredType));\r
- }\r
- while(requiredType instanceof TFun) {\r
- TFun fun = (TFun)requiredType;\r
- if(fun.domain instanceof TPred) { // No need to canonicalize\r
- ArrayList<Variable> constraints = new ArrayList<Variable>(2);\r
- while(true) {\r
- constraints.add(new Variable("constraint", fun.domain));\r
- requiredType = Types.canonical(fun.range);\r
- if(!(requiredType instanceof TFun))\r
- break;\r
- fun = (TFun)requiredType;\r
- if(!(fun.domain instanceof TPred))\r
- break;\r
- }\r
- context.pushConstraintFrame(constraints.toArray(new Variable[constraints.size()]));\r
- Expression expression = checkType(context, requiredType);\r
- context.popConstraintFrame();\r
- for(int i=constraints.size()-1;i>=0;--i)\r
- expression = new ESimpleLambda(constraints.get(i), expression);\r
- return expression;\r
- }\r
- else if(fun.domain == Types.PUNIT) {\r
- context.pushEffectUpperBound(location, fun.effect);\r
- Expression expr = checkType(context, fun.range);\r
- context.popEffectUpperBound(); \r
- \r
- // Wrap\r
- Variable var = new Variable("punit", Types.PUNIT);\r
- return new ESimpleLambda(location, var, fun.effect, expr);\r
- }\r
- else\r
- break;\r
- }\r
- }\r
- return checkBasicType(context, requiredType); \r
- }\r
-\r
- public abstract void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs);\r
- public abstract void collectVars(TObjectIntHashMap<Variable> allVars, TIntHashSet vars);\r
- public abstract void forVariables(VariableProcedure procedure);\r
- \r
- public Expression decomposeMatching() {\r
- return this;\r
- }\r
-\r
- public String toString() {\r
- StringBuilder b = new StringBuilder();\r
- ExpressionToStringVisitor visitor = new ExpressionToStringVisitor(b);\r
- accept(visitor);\r
- return b.toString();\r
- }\r
-\r
- protected abstract void updateType() throws MatchException;\r
- \r
- public static class TypeValidationException extends Exception {\r
- private static final long serialVersionUID = 3181298127162041248L; \r
- \r
- long loc;\r
-\r
- public TypeValidationException(long loc) {\r
- this.loc = loc;\r
- }\r
- \r
- public long getLoc() {\r
- return loc;\r
- }\r
-\r
- public TypeValidationException(long loc, Throwable cause) {\r
- super(cause);\r
- this.loc = loc;\r
- }\r
- }\r
- \r
- public static void assertEquals(long loc, Type a, Type b) throws TypeValidationException {\r
- if(!Types.equals(a, b))\r
- throw new TypeValidationException(loc);\r
- }\r
-\r
- public abstract IVal toVal(Environment env, CodeWriter w);\r
- \r
- public Expression closure(TVar ... vars) {\r
- if(vars.length == 0)\r
- return this;\r
- return new ELambdaType(vars, this);\r
- }\r
- \r
- public abstract void collectFreeVariables(THashSet<Variable> vars);\r
- \r
- public Expression simplify(SimplificationContext context) {\r
- throw new InternalCompilerError(location, getClass().getSimpleName() + " does not support simplify method.");\r
- }\r
-\r
- public abstract Expression resolve(TranslationContext context);\r
- \r
- /**\r
- * Returns head of the pattern.\r
- */\r
- public EVar getPatternHead() throws NotPatternException {\r
- throw new NotPatternException(this);\r
- }\r
- \r
- public LhsType getLhsType() throws NotPatternException {\r
- throw new NotPatternException(this);\r
- }\r
-\r
- protected void collectVariableNames(PatternMatchingLhs lhsType) throws NotPatternException {\r
- throw new NotPatternException(this);\r
- }\r
-\r
- public void getParameters(TranslationContext translationContext,\r
- ArrayList<Expression> parameters) {\r
- throw new InternalCompilerError("Class " + getClass().getSimpleName() + " does not support getParameters."); \r
- }\r
-\r
- public Expression resolveAsPattern(TranslationContext context) {\r
- context.getErrorLog().log(location, "Pattern was expected here.");\r
- return new EError();\r
- }\r
-\r
- public void removeFreeVariables(THashSet<Variable> vars) {\r
- throw new InternalCompilerError(getClass().getSimpleName() + " is not a pattern.");\r
- }\r
- \r
- public Expression checkTypeAsPattern(TypingContext context, Type requiredType) {\r
- if(context.isInPattern())\r
- throw new InternalCompilerError("Already in a pattern.");\r
- context.setInPattern(true);\r
- Expression expression = checkType(context, requiredType);\r
- context.setInPattern(false);\r
- return expression;\r
- }\r
-\r
- public THashSet<Variable> getFreeVariables() {\r
- THashSet<Variable> result = new THashSet<Variable>();\r
- collectFreeVariables(result);\r
- return result;\r
- } \r
-\r
- public static Expression[] concat(Expression[] a, Expression[] b) {\r
- if(a.length == 0)\r
- return b;\r
- if(b.length == 0)\r
- return a;\r
- Expression[] result = new Expression[a.length + b.length];\r
- for(int i=0;i<a.length;++i)\r
- result[i] = a[i];\r
- for(int i=0;i<b.length;++i)\r
- result[i+a.length] = b[i];\r
- return result;\r
- }\r
-\r
- public Expression replace(ReplaceContext context) {\r
- throw new InternalCompilerError(getClass().getSimpleName() + " does not support replace.");\r
- }\r
- \r
- public static Expression[] replace(ReplaceContext context, Expression[] expressions) {\r
- Expression[] result = new Expression[expressions.length];\r
- for(int i=0;i<expressions.length;++i)\r
- result[i] = expressions[i].replace(context);\r
- return result;\r
- }\r
- \r
- public Expression copy() {\r
- return replace(new ReplaceContext(null));\r
- }\r
- \r
- public Expression copy(TypingContext typingContext) {\r
- return replace(new ReplaceContext(typingContext));\r
- }\r
-\r
- public abstract void setLocationDeep(long loc);\r
-\r
- public Expression replaceInPattern(ReplaceContext context) {\r
- context.inPattern = true;\r
- Expression result = replace(context);\r
- context.inPattern = false;\r
- return result;\r
- }\r
-\r
- public int getFunctionDefinitionArity() throws NotPatternException {\r
- throw new NotPatternException(this);\r
- }\r
- \r
- public IVal lambdaToVal(Environment env, CodeWriter w) {\r
- DecomposedExpression decomposed = DecomposedExpression.decompose(this);\r
- CodeWriter newW = w.createFunction(decomposed.typeParameters, decomposed.effect, decomposed.returnType, decomposed.parameterTypes);\r
- IVal[] parameters = newW.getParameters();\r
- IVal functionVal = newW.getFunction().getTarget();\r
- for(int i=0;i<parameters.length;++i)\r
- decomposed.parameters[i].setVal(parameters[i]);\r
- newW.return_(decomposed.body.toVal(env, newW));\r
- return functionVal;\r
- }\r
- \r
- public IExpression toIExpression(ExpressionInterpretationContext context) {\r
- throw new UnsupportedOperationException();\r
- }\r
- \r
- public static IExpression[] toIExpressions(ExpressionInterpretationContext target, Expression[] expressions) {\r
- IExpression[] result = new IExpression[expressions.length];\r
- for(int i=0;i<expressions.length;++i)\r
- result[i] = expressions[i].toIExpression(target);\r
- return result;\r
- }\r
- \r
- public Expression applyType(Type type) {\r
- return new EApplyType(location, this, type);\r
- }\r
- \r
- public abstract Expression decorate(ExpressionDecorator decorator);\r
-\r
- public boolean isEffectful() {\r
- return true;\r
- }\r
-\r
- public boolean isFunctionPattern() {\r
- return false;\r
- }\r
-\r
- public boolean isConstructorApplication() {\r
- return false;\r
- }\r
- \r
- public abstract void collectEffects(THashSet<Type> effects);\r
- \r
- public Type getEffect() {\r
- THashSet<Type> effects = new THashSet<Type>();\r
- collectEffects(effects);\r
- return Types.union(effects.toArray(new Type[effects.size()]));\r
- }\r
- \r
- public abstract void accept(ExpressionVisitor visitor);\r
- \r
- public void collectRelationRefs(\r
- final TObjectIntHashMap<SCLRelation> allRefs, final TIntHashSet refs) {\r
- accept(new StandardExpressionVisitor() {\r
- @Override\r
- public void visit(QAtom query) {\r
- int id = allRefs.get(query.relation);\r
- if(id >= 0)\r
- refs.add(id);\r
- }\r
- });\r
- }\r
-\r
- public boolean isFunctionDefinitionLhs() {\r
- return false;\r
- }\r
-\r
- public Precedence getPrecedence() {\r
- return Precedence.DEFAULT;\r
- }\r
-\r
- public boolean isPattern(int arity) {\r
- return false;\r
- }\r
- \r
- public abstract Expression accept(ExpressionTransformer transformer);\r
-}\r
+package org.simantics.scl.compiler.elaboration.expressions;
+
+import java.util.ArrayList;
+
+import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
+import org.simantics.scl.compiler.common.precedence.Precedence;
+import org.simantics.scl.compiler.constants.NoRepConstant;
+import org.simantics.scl.compiler.elaboration.contexts.EnvironmentalContext;
+import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;
+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.errors.NotPatternException;
+import org.simantics.scl.compiler.elaboration.expressions.lhstype.LhsType;
+import org.simantics.scl.compiler.elaboration.expressions.lhstype.PatternMatchingLhs;
+import org.simantics.scl.compiler.elaboration.expressions.printing.ExpressionToStringVisitor;
+import org.simantics.scl.compiler.elaboration.query.QAtom;
+import org.simantics.scl.compiler.elaboration.relations.SCLRelation;
+import org.simantics.scl.compiler.environment.Environment;
+import org.simantics.scl.compiler.internal.codegen.references.IVal;
+import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;
+import org.simantics.scl.compiler.internal.elaboration.decomposed.DecomposedExpression;
+import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
+import org.simantics.scl.compiler.internal.interpreted.IExpression;
+import org.simantics.scl.compiler.internal.parsing.Symbol;
+import org.simantics.scl.compiler.top.ExpressionInterpretationContext;
+import org.simantics.scl.compiler.types.TForAll;
+import org.simantics.scl.compiler.types.TFun;
+import org.simantics.scl.compiler.types.TPred;
+import org.simantics.scl.compiler.types.TVar;
+import org.simantics.scl.compiler.types.Type;
+import org.simantics.scl.compiler.types.Types;
+import org.simantics.scl.compiler.types.exceptions.MatchException;
+import org.simantics.scl.compiler.types.kinds.Kinds;
+import org.simantics.scl.compiler.types.util.Typed;
+
+import gnu.trove.map.hash.TObjectIntHashMap;
+import gnu.trove.set.hash.THashSet;
+import gnu.trove.set.hash.TIntHashSet;
+
+public abstract class Expression extends Symbol implements Typed {
+ public static final Expression[] EMPTY_ARRAY = new Expression[0];
+
+ transient
+ private Type type;
+
+ public Expression() {
+ }
+
+ public Expression(long loc) {
+ this.location = loc;
+ }
+
+ @Override
+ public Type getType() {
+ if(type == null) {
+ try {
+ updateType();
+ } catch (MatchException e) {
+ throw new InternalCompilerError(e);
+ }
+ if(type == null)
+ throw new InternalCompilerError(getClass().getSimpleName() +
+ ".updateType couldn't compute its type.");
+ }
+ return type;
+ }
+
+ public void setType(Type type) {
+ if(type == null)
+ throw new NullPointerException();
+ this.type = type;
+ }
+
+ /**
+ * Infers the type of the expression without any context. Adds type
+ * applications and lambdas if needed.
+ */
+ public Expression inferType(TypingContext context) {
+ return checkBasicType(context, Types.metaVar(Kinds.STAR));
+ }
+
+ public Expression checkBasicType(TypingContext context, Type requiredType) {
+ return context.subsume(inferType(context), requiredType);
+ }
+
+ protected Expression applyPUnit(EnvironmentalContext context) {
+ Type type = Types.canonical(getType());
+ if(type instanceof TFun) {
+ TFun fun = (TFun)type;
+ if(fun.getCanonicalDomain() == Types.PUNIT) {
+ EApply result = new EApply(location, this, new ELiteral(NoRepConstant.PUNIT));
+ result.effect = fun.getCanonicalEffect();
+ return result;
+ }
+ }
+ return this;
+ }
+
+ public Expression checkIgnoredType(TypingContext context) {
+ Expression expression = inferType(context);
+ if(Types.canonical(expression.getType()) != Types.UNIT)
+ expression = new ESimpleLet(location, null, expression, new ELiteral(NoRepConstant.PUNIT));
+ return expression;
+ }
+
+ /**
+ * Checks the type of the expression against the given type. Adds type
+ * applications and lambdas if needed.
+ */
+ public final Expression checkType(TypingContext context, Type requiredType) {
+ //System.out.println("checkType: " + this + " :: " + requiredType);
+ if(!context.isInPattern()) {
+ requiredType = Types.canonical(requiredType);
+ if(requiredType instanceof TForAll) {
+ TForAll forAll = (TForAll)requiredType;
+ TVar var = forAll.var;
+ TVar newVar = Types.var(var.getKind());
+ requiredType = Types.canonical(forAll.type).replace(var, newVar);
+ return new ELambdaType(new TVar[] {newVar}, checkType(context, requiredType));
+ }
+ while(requiredType instanceof TFun) {
+ TFun fun = (TFun)requiredType;
+ if(fun.domain instanceof TPred) { // No need to canonicalize
+ ArrayList<Variable> constraints = new ArrayList<Variable>(2);
+ while(true) {
+ constraints.add(new Variable("constraint", fun.domain));
+ requiredType = Types.canonical(fun.range);
+ if(!(requiredType instanceof TFun))
+ break;
+ fun = (TFun)requiredType;
+ if(!(fun.domain instanceof TPred))
+ break;
+ }
+ context.pushConstraintFrame(constraints.toArray(new Variable[constraints.size()]));
+ Expression expression = checkType(context, requiredType);
+ context.popConstraintFrame();
+ for(int i=constraints.size()-1;i>=0;--i)
+ expression = new ESimpleLambda(constraints.get(i), expression);
+ return expression;
+ }
+ else if(fun.domain == Types.PUNIT) {
+ context.pushEffectUpperBound(location, fun.effect);
+ Expression expr = checkType(context, fun.range);
+ context.popEffectUpperBound();
+
+ // Wrap
+ Variable var = new Variable("punit", Types.PUNIT);
+ return new ESimpleLambda(location, var, fun.effect, expr);
+ }
+ else
+ break;
+ }
+ }
+ return checkBasicType(context, requiredType);
+ }
+
+ public abstract void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs);
+ public abstract void collectVars(TObjectIntHashMap<Variable> allVars, TIntHashSet vars);
+ public abstract void forVariables(VariableProcedure procedure);
+
+ public Expression decomposeMatching() {
+ return this;
+ }
+
+ public String toString() {
+ StringBuilder b = new StringBuilder();
+ ExpressionToStringVisitor visitor = new ExpressionToStringVisitor(b);
+ accept(visitor);
+ return b.toString();
+ }
+
+ protected abstract void updateType() throws MatchException;
+
+ public static class TypeValidationException extends Exception {
+ private static final long serialVersionUID = 3181298127162041248L;
+
+ long loc;
+
+ public TypeValidationException(long loc) {
+ this.loc = loc;
+ }
+
+ public long getLoc() {
+ return loc;
+ }
+
+ public TypeValidationException(long loc, Throwable cause) {
+ super(cause);
+ this.loc = loc;
+ }
+ }
+
+ public static void assertEquals(long loc, Type a, Type b) throws TypeValidationException {
+ if(!Types.equals(a, b))
+ throw new TypeValidationException(loc);
+ }
+
+ public abstract IVal toVal(Environment env, CodeWriter w);
+
+ public Expression closure(TVar ... vars) {
+ if(vars.length == 0)
+ return this;
+ return new ELambdaType(vars, this);
+ }
+
+ public abstract void collectFreeVariables(THashSet<Variable> vars);
+
+ public Expression simplify(SimplificationContext context) {
+ System.out.println("#############################");
+ System.out.println(this);
+ throw new InternalCompilerError(location, getClass().getSimpleName() + " does not support simplify method.");
+ }
+
+ public abstract Expression resolve(TranslationContext context);
+
+ /**
+ * Returns head of the pattern.
+ */
+ public EVar getPatternHead() throws NotPatternException {
+ throw new NotPatternException(this);
+ }
+
+ public LhsType getLhsType() throws NotPatternException {
+ throw new NotPatternException(this);
+ }
+
+ protected void collectVariableNames(PatternMatchingLhs lhsType) throws NotPatternException {
+ throw new NotPatternException(this);
+ }
+
+ public void getParameters(TranslationContext translationContext,
+ ArrayList<Expression> parameters) {
+ throw new InternalCompilerError("Class " + getClass().getSimpleName() + " does not support getParameters.");
+ }
+
+ public Expression resolveAsPattern(TranslationContext context) {
+ context.getErrorLog().log(location, "Pattern was expected here.");
+ return new EError();
+ }
+
+ public void removeFreeVariables(THashSet<Variable> vars) {
+ throw new InternalCompilerError(getClass().getSimpleName() + " is not a pattern.");
+ }
+
+ public Expression checkTypeAsPattern(TypingContext context, Type requiredType) {
+ if(context.isInPattern())
+ throw new InternalCompilerError("Already in a pattern.");
+ context.setInPattern(true);
+ Expression expression = checkType(context, requiredType);
+ context.setInPattern(false);
+ return expression;
+ }
+
+ public THashSet<Variable> getFreeVariables() {
+ THashSet<Variable> result = new THashSet<Variable>();
+ collectFreeVariables(result);
+ return result;
+ }
+
+ public static Expression[] concat(Expression[] a, Expression[] b) {
+ if(a.length == 0)
+ return b;
+ if(b.length == 0)
+ return a;
+ Expression[] result = new Expression[a.length + b.length];
+ for(int i=0;i<a.length;++i)
+ result[i] = a[i];
+ for(int i=0;i<b.length;++i)
+ result[i+a.length] = b[i];
+ return result;
+ }
+
+ public Expression replace(ReplaceContext context) {
+ throw new InternalCompilerError(getClass().getSimpleName() + " does not support replace.");
+ }
+
+ public static Expression[] replace(ReplaceContext context, Expression[] expressions) {
+ Expression[] result = new Expression[expressions.length];
+ for(int i=0;i<expressions.length;++i)
+ result[i] = expressions[i].replace(context);
+ return result;
+ }
+
+ public Expression copy() {
+ return replace(new ReplaceContext(null));
+ }
+
+ public Expression copy(TypingContext typingContext) {
+ return replace(new ReplaceContext(typingContext));
+ }
+
+ public abstract void setLocationDeep(long loc);
+
+ public Expression replaceInPattern(ReplaceContext context) {
+ context.inPattern = true;
+ Expression result = replace(context);
+ context.inPattern = false;
+ return result;
+ }
+
+ public int getFunctionDefinitionPatternArity() throws NotPatternException {
+ throw new NotPatternException(this);
+ }
+
+ public IVal lambdaToVal(Environment env, CodeWriter w) {
+ DecomposedExpression decomposed = DecomposedExpression.decompose(this);
+ CodeWriter newW = w.createFunction(decomposed.typeParameters, decomposed.effect, decomposed.returnType, decomposed.parameterTypes);
+ IVal[] parameters = newW.getParameters();
+ IVal functionVal = newW.getFunction().getTarget();
+ for(int i=0;i<parameters.length;++i)
+ decomposed.parameters[i].setVal(parameters[i]);
+ newW.return_(decomposed.body.toVal(env, newW));
+ return functionVal;
+ }
+
+ public IExpression toIExpression(ExpressionInterpretationContext context) {
+ throw new UnsupportedOperationException();
+ }
+
+ public static IExpression[] toIExpressions(ExpressionInterpretationContext target, Expression[] expressions) {
+ IExpression[] result = new IExpression[expressions.length];
+ for(int i=0;i<expressions.length;++i)
+ result[i] = expressions[i].toIExpression(target);
+ return result;
+ }
+
+ public Expression applyType(Type type) {
+ return new EApplyType(location, this, type);
+ }
+
+ public abstract Expression decorate(ExpressionDecorator decorator);
+
+ public boolean isEffectful() {
+ return true;
+ }
+
+ public boolean isFunctionPattern() {
+ return false;
+ }
+
+ public boolean isConstructorApplication() {
+ return false;
+ }
+
+ public abstract void collectEffects(THashSet<Type> effects);
+
+ public Type getEffect() {
+ THashSet<Type> effects = new THashSet<Type>();
+ collectEffects(effects);
+ return Types.union(effects.toArray(new Type[effects.size()]));
+ }
+
+ public abstract void accept(ExpressionVisitor visitor);
+
+ public void collectRelationRefs(
+ final TObjectIntHashMap<SCLRelation> allRefs, final TIntHashSet refs) {
+ accept(new StandardExpressionVisitor() {
+ @Override
+ public void visit(QAtom query) {
+ int id = allRefs.get(query.relation);
+ if(id >= 0)
+ refs.add(id);
+ }
+ });
+ }
+
+ public boolean isFunctionDefinitionLhs() {
+ return false;
+ }
+
+ public Precedence getPrecedence() {
+ return Precedence.DEFAULT;
+ }
+
+ public boolean isPattern(int arity) {
+ return false;
+ }
+
+ public abstract Expression accept(ExpressionTransformer transformer);
+
+ // TODO implement for all expressions
+ public boolean equalsExpression(Expression expression) {
+ return false;
+ }
+
+ /**
+ * This method returns a lower bound for the function arity of the value this expression defines.
+ * The lower bound is calculated purely looking the syntax of the expression, not the
+ * types of the constants and variables the expression refers to.
+ */
+ public int getSyntacticFunctionArity() {
+ return 0;
+ }
+}
Expression transform(EBinary expression);
Expression transform(EBind expression);
Expression transform(EBlock expression);
+ Expression transform(ECHRRuleset expression);
Expression transform(EConstant expression);
+ Expression transform(ECoveringBranchPoint expression);
Expression transform(EEnforce expression);
Expression transform(EEntityTypeAnnotation expression);
Expression transform(EEquations expression);
Expression transform(EPlaceholder expression);
Expression transform(EPreLet expression);
Expression transform(EPreRuleset expression);
- Expression transform(ECoveringBranchPoint expression);
Expression transform(ERange expression);
Expression transform(ERealLiteral expression);
Expression transform(ERecord expression);
Expression transform(ETypeAnnotation expression);
Expression transform(EVar expression);
Expression transform(EVariable expression);
+ Expression transform(EViewPattern expression);
Expression transform(EWhen expression);
Expression transform(GuardedExpressionGroup expression);
void visit(EApplyType expression);\r
void visit(EAsPattern expression);\r
void visit(EBind expression);\r
+ void visit(ECHRRuleset echrRuleset);\r
void visit(EConstant expression);\r
void visit(ECoveringBranchPoint expression);\r
void visit(EEnforce expression);\r
void visit(ETransformation expression);\r
void visit(ETypeAnnotation expression);\r
void visit(EVariable expression);\r
+ void visit(EViewPattern expression);\r
void visit(EWhen expression);\r
void visit(GuardedExpressionGroup expression);\r
}\r
}\r
\r
public static Expression isZeroInteger(Expression value) {\r
- return apply(Types.NO_EFFECTS, new ELiteral(new JavaComparisonToZeroOperation("==")), value);\r
+ return apply(Types.NO_EFFECTS, new ELiteral(JavaComparisonToZeroOperation.IEQUAL), value);\r
}\r
\r
public static Expression addInteger(Expression a, Expression b) {\r
-package org.simantics.scl.compiler.elaboration.expressions;\r
-\r
-import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;\r
-import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;\r
-import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
-import org.simantics.scl.compiler.elaboration.contexts.TypingContext;\r
-import org.simantics.scl.compiler.environment.Environment;\r
-import org.simantics.scl.compiler.errors.Locations;\r
-import org.simantics.scl.compiler.internal.codegen.continuations.ICont;\r
-import org.simantics.scl.compiler.internal.codegen.references.IVal;\r
-import org.simantics.scl.compiler.internal.codegen.ssa.exits.Throw;\r
-import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;\r
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;\r
-import org.simantics.scl.compiler.types.Type;\r
-import org.simantics.scl.compiler.types.Types;\r
-import org.simantics.scl.compiler.types.exceptions.MatchException;\r
-\r
-import gnu.trove.map.hash.TObjectIntHashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
-public class GuardedExpressionGroup extends Expression {\r
- public GuardedExpression[] expressions;\r
-\r
- public GuardedExpressionGroup(GuardedExpression[] expressions) {\r
- this.expressions = expressions;\r
- }\r
-\r
- @Override\r
- public void collectRefs(TObjectIntHashMap<Object> allRefs,\r
- TIntHashSet refs) {\r
- for(GuardedExpression expression : expressions) {\r
- for(Expression guard : expression.guards)\r
- guard.collectRefs(allRefs, refs);\r
- expression.value.collectRefs(allRefs, refs);\r
- }\r
- }\r
-\r
- @Override\r
- public void collectVars(TObjectIntHashMap<Variable> allVars,\r
- TIntHashSet vars) {\r
- for(GuardedExpression expression : expressions) {\r
- for(Expression guard : expression.guards)\r
- guard.collectVars(allVars, vars);\r
- expression.value.collectVars(allVars, vars);\r
- }\r
- }\r
-\r
- @Override\r
- protected void updateType() throws MatchException {\r
- setType(expressions[0].value.getType());\r
- }\r
-\r
- @Override\r
- public IVal toVal(Environment env, CodeWriter w) {\r
- CodeWriter success = w.createBlock(getType());\r
- IVal result = success.getParameters()[0];\r
- CodeWriter failure = w.createBlock();\r
- compile(env, w, success.getContinuation(), failure.getContinuation());\r
- w.continueAs(success);\r
- failure.throw_(location, Throw.MatchingException, "Matching failure at: " + toString());\r
- return result;\r
- //throw new InternalCompilerError("GuardedExpressionGroup should be handled in match compilation.");\r
- }\r
-\r
- @Override\r
- public void collectFreeVariables(THashSet<Variable> vars) {\r
- for(GuardedExpression expression : expressions) {\r
- for(Expression guard : expression.guards)\r
- guard.collectFreeVariables(vars);\r
- expression.value.collectFreeVariables(vars);\r
- }\r
- }\r
-\r
- @Override\r
- public Expression simplify(SimplificationContext context) {\r
- for(GuardedExpression expression : expressions) {\r
- for(int i=0;i<expression.guards.length;++i)\r
- expression.guards[i] = expression.guards[i].simplify(context);\r
- expression.value = expression.value.simplify(context);\r
- }\r
- return this;\r
- }\r
-\r
- @Override\r
- public Expression resolve(TranslationContext context) {\r
- for(GuardedExpression expression : expressions) {\r
- for(int i=0;i<expression.guards.length;++i)\r
- expression.guards[i] = expression.guards[i].resolve(context);\r
- expression.value = expression.value.resolve(context);\r
- }\r
- return this;\r
- }\r
- \r
- @Override\r
- public Expression checkBasicType(TypingContext context, Type requiredType) {\r
- for(GuardedExpression expression : expressions) {\r
- for(int i=0;i<expression.guards.length;++i)\r
- expression.guards[i] = expression.guards[i].checkType(context, Types.BOOLEAN);\r
- expression.value = expression.value.checkType(context, requiredType);\r
- }\r
- return this;\r
- }\r
- \r
- public void compile(Environment env, CodeWriter firstWriter, ICont success,\r
- ICont lastFailure) {\r
- // Create all code blocks\r
- CodeWriter[] writers = new CodeWriter[expressions.length]; \r
- ICont[] failures = new ICont[expressions.length];\r
- writers[0] = firstWriter;\r
- failures[expressions.length-1] = lastFailure;\r
- for(int i=1;i<expressions.length;++i) {\r
- CodeWriter writer = firstWriter.createBlock();\r
- writers[i] = writer;\r
- failures[i-1] = writer.getContinuation();\r
- }\r
- \r
- // Compile\r
- for(int i=0;i<expressions.length;++i) {\r
- CodeWriter w = writers[i];\r
- ICont failure = failures[i];\r
- \r
- for(Expression guard : expressions[i].guards) {\r
- CodeWriter nextW = w.createBlock();\r
- w.if_(guard.toVal(env, w), nextW.getContinuation(), failure);\r
- w = nextW;\r
- }\r
- \r
- w.jump(success, expressions[i].value.toVal(env, w));\r
- }\r
- }\r
- \r
- @Override\r
- public Expression replace(ReplaceContext context) {\r
- GuardedExpression[] newExpressions = new GuardedExpression[expressions.length];\r
- for(int i=0;i<expressions.length;++i)\r
- newExpressions[i] = expressions[i].replace(context);\r
- return new GuardedExpressionGroup(newExpressions); \r
- }\r
-\r
- @Override\r
- public Expression decorate(ExpressionDecorator decorator) {\r
- for(GuardedExpression expression : expressions)\r
- expression.decorate(decorator);\r
- return decorator.decorate(this);\r
- }\r
-\r
- @Override\r
- public void collectEffects(THashSet<Type> effects) {\r
- for(GuardedExpression ge : expressions) {\r
- for(Expression guard : ge.guards)\r
- guard.collectEffects(effects);\r
- ge.value.collectEffects(effects);\r
- }\r
- }\r
- \r
- @Override\r
- public void setLocationDeep(long loc) {\r
- if(location == Locations.NO_LOCATION) {\r
- location = loc;\r
- for(GuardedExpression expression : expressions)\r
- expression.setLocationDeep(loc);\r
- }\r
- }\r
- \r
- @Override\r
- public void accept(ExpressionVisitor visitor) {\r
- visitor.visit(this);\r
- }\r
-\r
- @Override\r
- public void forVariables(VariableProcedure procedure) {\r
- for(GuardedExpression expression : expressions)\r
- expression.forVariables(procedure);\r
- }\r
-\r
- @Override\r
- public Expression accept(ExpressionTransformer transformer) {\r
- return transformer.transform(this);\r
- }\r
-}\r
+package org.simantics.scl.compiler.elaboration.expressions;
+
+import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;
+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.environment.Environment;
+import org.simantics.scl.compiler.errors.Locations;
+import org.simantics.scl.compiler.internal.codegen.continuations.ICont;
+import org.simantics.scl.compiler.internal.codegen.references.IVal;
+import org.simantics.scl.compiler.internal.codegen.ssa.exits.Throw;
+import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;
+import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
+import org.simantics.scl.compiler.types.Type;
+import org.simantics.scl.compiler.types.Types;
+import org.simantics.scl.compiler.types.exceptions.MatchException;
+
+import gnu.trove.map.hash.TObjectIntHashMap;
+import gnu.trove.set.hash.THashSet;
+import gnu.trove.set.hash.TIntHashSet;
+
+public class GuardedExpressionGroup extends Expression {
+ public GuardedExpression[] expressions;
+
+ public GuardedExpressionGroup(GuardedExpression[] expressions) {
+ this.expressions = expressions;
+ }
+
+ @Override
+ public void collectRefs(TObjectIntHashMap<Object> allRefs,
+ TIntHashSet refs) {
+ for(GuardedExpression expression : expressions) {
+ for(Expression guard : expression.guards)
+ guard.collectRefs(allRefs, refs);
+ expression.value.collectRefs(allRefs, refs);
+ }
+ }
+
+ @Override
+ public void collectVars(TObjectIntHashMap<Variable> allVars,
+ TIntHashSet vars) {
+ for(GuardedExpression expression : expressions) {
+ for(Expression guard : expression.guards)
+ guard.collectVars(allVars, vars);
+ expression.value.collectVars(allVars, vars);
+ }
+ }
+
+ @Override
+ protected void updateType() throws MatchException {
+ setType(expressions[0].value.getType());
+ }
+
+ @Override
+ public IVal toVal(Environment env, CodeWriter w) {
+ CodeWriter success = w.createBlock(getType());
+ IVal result = success.getParameters()[0];
+ CodeWriter failure = w.createBlock();
+ compile(env, w, success.getContinuation(), failure.getContinuation());
+ w.continueAs(success);
+ failure.throw_(location, Throw.MatchingException, "Matching failure at: " + toString());
+ return result;
+ //throw new InternalCompilerError("GuardedExpressionGroup should be handled in match compilation.");
+ }
+
+ @Override
+ public void collectFreeVariables(THashSet<Variable> vars) {
+ for(GuardedExpression expression : expressions) {
+ for(Expression guard : expression.guards)
+ guard.collectFreeVariables(vars);
+ expression.value.collectFreeVariables(vars);
+ }
+ }
+
+ @Override
+ public Expression simplify(SimplificationContext context) {
+ for(GuardedExpression expression : expressions) {
+ for(int i=0;i<expression.guards.length;++i)
+ expression.guards[i] = expression.guards[i].simplify(context);
+ expression.value = expression.value.simplify(context);
+ }
+ return this;
+ }
+
+ @Override
+ public Expression resolve(TranslationContext context) {
+ for(GuardedExpression expression : expressions) {
+ for(int i=0;i<expression.guards.length;++i)
+ expression.guards[i] = expression.guards[i].resolve(context);
+ expression.value = expression.value.resolve(context);
+ }
+ return this;
+ }
+
+ @Override
+ public Expression checkBasicType(TypingContext context, Type requiredType) {
+ for(GuardedExpression expression : expressions) {
+ for(int i=0;i<expression.guards.length;++i)
+ expression.guards[i] = expression.guards[i].checkType(context, Types.BOOLEAN);
+ expression.value = expression.value.checkType(context, requiredType);
+ }
+ return this;
+ }
+
+ public void compile(Environment env, CodeWriter firstWriter, ICont success,
+ ICont lastFailure) {
+ // Create all code blocks
+ CodeWriter[] writers = new CodeWriter[expressions.length];
+ ICont[] failures = new ICont[expressions.length];
+ writers[0] = firstWriter;
+ failures[expressions.length-1] = lastFailure;
+ for(int i=1;i<expressions.length;++i) {
+ CodeWriter writer = firstWriter.createBlock();
+ writers[i] = writer;
+ failures[i-1] = writer.getContinuation();
+ }
+
+ // Compile
+ for(int i=0;i<expressions.length;++i) {
+ CodeWriter w = writers[i];
+ ICont failure = failures[i];
+
+ for(Expression guard : expressions[i].guards) {
+ CodeWriter nextW = w.createBlock();
+ w.if_(guard.toVal(env, w), nextW.getContinuation(), failure);
+ w = nextW;
+ }
+
+ w.jump(success, expressions[i].value.toVal(env, w));
+ }
+ }
+
+ @Override
+ public Expression replace(ReplaceContext context) {
+ GuardedExpression[] newExpressions = new GuardedExpression[expressions.length];
+ for(int i=0;i<expressions.length;++i)
+ newExpressions[i] = expressions[i].replace(context);
+ return new GuardedExpressionGroup(newExpressions);
+ }
+
+ @Override
+ public Expression decorate(ExpressionDecorator decorator) {
+ for(GuardedExpression expression : expressions)
+ expression.decorate(decorator);
+ return decorator.decorate(this);
+ }
+
+ @Override
+ public void collectEffects(THashSet<Type> effects) {
+ for(GuardedExpression ge : expressions) {
+ for(Expression guard : ge.guards)
+ guard.collectEffects(effects);
+ ge.value.collectEffects(effects);
+ }
+ }
+
+ @Override
+ public void setLocationDeep(long loc) {
+ if(location == Locations.NO_LOCATION) {
+ location = loc;
+ for(GuardedExpression expression : expressions)
+ expression.setLocationDeep(loc);
+ }
+ }
+
+ @Override
+ public void accept(ExpressionVisitor visitor) {
+ visitor.visit(this);
+ }
+
+ @Override
+ public void forVariables(VariableProcedure procedure) {
+ for(GuardedExpression expression : expressions)
+ expression.forVariables(procedure);
+ }
+
+ @Override
+ public Expression accept(ExpressionTransformer transformer) {
+ return transformer.transform(this);
+ }
+
+ @Override
+ public int getSyntacticFunctionArity() {
+ return expressions[0].value.getSyntacticFunctionArity();
+ }
+}
package org.simantics.scl.compiler.elaboration.expressions;
+import org.simantics.scl.compiler.elaboration.chr.CHRLiteral;
+import org.simantics.scl.compiler.elaboration.chr.CHRRule;
import org.simantics.scl.compiler.elaboration.equation.EqBasic;
import org.simantics.scl.compiler.elaboration.equation.EqGuard;
import org.simantics.scl.compiler.elaboration.equation.Equation;
return expression;
}
+ @Override
+ public Expression transform(EViewPattern expression) {
+ expression.expression = expression.expression.accept(this);
+ expression.pattern = expression.pattern.accept(this);
+ return expression;
+ }
+
@Override
public Expression transform(EBlock expression) {
for(Statement statement : expression.statements)
statement.body = statement.body.accept(this);
}
+ @Override
+ public Expression transform(ECHRRuleset expression) {
+ expression.in = expression.in.accept(this);
+ for(CHRRule rule : expression.ruleset.rules) {
+ for(CHRLiteral lit : rule.head.literals)
+ for(int i=0;i<lit.parameters.length;++i)
+ lit.parameters[i] = lit.parameters[i].accept(this);
+ for(CHRLiteral lit : rule.body.literals)
+ for(int i=0;i<lit.parameters.length;++i)
+ lit.parameters[i] = lit.parameters[i].accept(this);
+ }
+ return expression;
+ }
+
@Override
public Expression transform(EConstant expression) {
return expression;
public Expression transform(EIf expression) {
expression.condition = expression.condition.accept(this);
expression.then_ = expression.then_.accept(this);
- expression.else_ = expression.else_.accept(this);
+ if(expression.else_ != null)
+ expression.else_ = expression.else_.accept(this);
return expression;
}
package org.simantics.scl.compiler.elaboration.expressions;\r
\r
+import org.simantics.scl.compiler.elaboration.chr.CHRLiteral;\r
+import org.simantics.scl.compiler.elaboration.chr.CHRRule;\r
import org.simantics.scl.compiler.elaboration.equation.EqBasic;\r
import org.simantics.scl.compiler.elaboration.equation.EqGuard;\r
import org.simantics.scl.compiler.elaboration.equation.Equation;\r
public void visit(EIf expression) {\r
expression.condition.accept(this);\r
expression.then_.accept(this);\r
- expression.else_.accept(this);\r
+ if(expression.else_ != null)\r
+ expression.else_.accept(this);\r
}\r
\r
@Override\r
for(Case case_ : expression.cases)\r
visit(case_);\r
}\r
+ \r
+ @Override\r
+ public void visit(EViewPattern expression) {\r
+ expression.expression.accept(this);\r
+ expression.pattern.accept(this);\r
+ }\r
\r
public void visit(Case case_) {\r
for(Expression pattern : case_.patterns)\r
equation.accept(this);\r
}\r
\r
+ @Override\r
+ public void visit(ECHRRuleset ruleset) {\r
+ for(CHRRule rule : ruleset.ruleset.rules) {\r
+ for(CHRLiteral literal : rule.head.literals)\r
+ for(Expression parameter : literal.parameters)\r
+ parameter.accept(this);\r
+ for(CHRLiteral literal : rule.body.literals)\r
+ for(Expression parameter : literal.parameters)\r
+ parameter.accept(this);\r
+ }\r
+ ruleset.in.accept(this);\r
+ }\r
+\r
}\r
public void accept(StatementVisitor visitor) {\r
visitor.visit(this);\r
}\r
+\r
+ @Override\r
+ public StatementGroup getStatementGroup() {\r
+ return null;\r
+ }\r
}\r
--- /dev/null
+package org.simantics.scl.compiler.elaboration.expressions.block;\r
+\r
+import org.simantics.scl.compiler.elaboration.contexts.EnvironmentalContext;\r
+import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
+import org.simantics.scl.compiler.elaboration.expressions.Expression;\r
+import org.simantics.scl.compiler.elaboration.expressions.list.ListQualifier;\r
+import org.simantics.scl.compiler.errors.Locations;\r
+\r
+public class CHRStatement extends Statement {\r
+\r
+ public ListQualifier[] head;\r
+ public ListQualifier[] body;\r
+\r
+ public CHRStatement(ListQualifier[] head, ListQualifier[] body) {\r
+ this.head = head;\r
+ this.body = body;\r
+ }\r
+\r
+ @Override\r
+ public Expression toExpression(EnvironmentalContext context, boolean monadic, Expression in) {\r
+ throw new UnsupportedOperationException();\r
+ }\r
+\r
+ @Override\r
+ public void setLocationDeep(long loc) {\r
+ if(location == Locations.NO_LOCATION) {\r
+ location = loc;\r
+ for(ListQualifier lq : head)\r
+ lq.setLocationDeep(loc);\r
+ for(ListQualifier lq : body)\r
+ lq.setLocationDeep(loc);\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public void resolvePattern(TranslationContext context) {\r
+ throw new UnsupportedOperationException();\r
+ }\r
+\r
+ @Override\r
+ public boolean mayBeRecursive() {\r
+ return true;\r
+ }\r
+\r
+ @Override\r
+ public void accept(StatementVisitor visitor) {\r
+ throw new UnsupportedOperationException();\r
+ }\r
+ \r
+ @Override\r
+ public StatementGroup getStatementGroup() {\r
+ return StatementGroup.CHR;\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.simantics.scl.compiler.elaboration.expressions.block;\r
+\r
+import org.simantics.scl.compiler.elaboration.contexts.EnvironmentalContext;\r
+import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
+import org.simantics.scl.compiler.elaboration.expressions.Expression;\r
+import org.simantics.scl.compiler.errors.Locations;\r
+import org.simantics.scl.compiler.internal.parsing.Token;\r
+import org.simantics.scl.compiler.internal.parsing.types.TypeAst;\r
+\r
+public class ConstraintStatement extends Statement {\r
+\r
+ public Token name;\r
+ public TypeAst[] parameterTypes;\r
+ \r
+ public ConstraintStatement(Token name, TypeAst[] parameterTypes) {\r
+ this.name = name;\r
+ this.parameterTypes = parameterTypes;\r
+ }\r
+ \r
+ @Override\r
+ public void setLocationDeep(long loc) {\r
+ if(location == Locations.NO_LOCATION) {\r
+ location = loc;\r
+ for(TypeAst parameterType : parameterTypes)\r
+ if(parameterType.location == Locations.NO_LOCATION)\r
+ parameterType.location = location;\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public Expression toExpression(EnvironmentalContext context, boolean monadic, Expression in) {\r
+ throw new UnsupportedOperationException();\r
+ }\r
+\r
+ @Override\r
+ public void resolvePattern(TranslationContext context) {\r
+ throw new UnsupportedOperationException();\r
+ }\r
+\r
+ @Override\r
+ public boolean mayBeRecursive() {\r
+ throw new UnsupportedOperationException();\r
+ }\r
+\r
+ @Override\r
+ public void accept(StatementVisitor visitor) {\r
+ throw new UnsupportedOperationException();\r
+ }\r
+\r
+ @Override\r
+ public StatementGroup getStatementGroup() {\r
+ return StatementGroup.CHR;\r
+ }\r
+}\r
public void accept(StatementVisitor visitor) {\r
visitor.visit(this);\r
}\r
+\r
+ @Override\r
+ public StatementGroup getStatementGroup() {\r
+ return null;\r
+ }\r
}\r
public void accept(StatementVisitor visitor) {\r
visitor.visit(this);\r
}\r
+\r
+ @Override\r
+ public StatementGroup getStatementGroup() {\r
+ if(pattern.isFunctionPattern())\r
+ return StatementGroup.LetFunction;\r
+ else\r
+ return null;\r
+ }\r
}
\ No newline at end of file
public void accept(StatementVisitor visitor) {\r
visitor.visit(this);\r
}\r
+\r
+ @Override\r
+ public StatementGroup getStatementGroup() {\r
+ return StatementGroup.Rule;\r
+ }\r
}\r
}\r
\r
public abstract void accept(StatementVisitor visitor);\r
+ public abstract StatementGroup getStatementGroup();\r
\r
}\r
--- /dev/null
+package org.simantics.scl.compiler.elaboration.expressions.block;\r
+\r
+public enum StatementGroup {\r
+ Rule,\r
+ CHR,\r
+ LetFunction\r
+}\r
\r
import java.util.Map.Entry;\r
\r
+import org.simantics.scl.compiler.elaboration.chr.CHRLiteral;\r
+import org.simantics.scl.compiler.elaboration.chr.CHRQuery;\r
+import org.simantics.scl.compiler.elaboration.chr.CHRRule;\r
+import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint;\r
import org.simantics.scl.compiler.elaboration.expressions.Assignment;\r
import org.simantics.scl.compiler.elaboration.expressions.Case;\r
import org.simantics.scl.compiler.elaboration.expressions.EApply;\r
import org.simantics.scl.compiler.elaboration.expressions.EApplyType;\r
import org.simantics.scl.compiler.elaboration.expressions.EAsPattern;\r
import org.simantics.scl.compiler.elaboration.expressions.EBind;\r
+import org.simantics.scl.compiler.elaboration.expressions.ECHRRuleset;\r
import org.simantics.scl.compiler.elaboration.expressions.EConstant;\r
import org.simantics.scl.compiler.elaboration.expressions.ECoveringBranchPoint;\r
import org.simantics.scl.compiler.elaboration.expressions.EEnforce;\r
import org.simantics.scl.compiler.elaboration.expressions.ETransformation;\r
import org.simantics.scl.compiler.elaboration.expressions.ETypeAnnotation;\r
import org.simantics.scl.compiler.elaboration.expressions.EVariable;\r
+import org.simantics.scl.compiler.elaboration.expressions.EViewPattern;\r
import org.simantics.scl.compiler.elaboration.expressions.EWhen;\r
import org.simantics.scl.compiler.elaboration.expressions.Expression;\r
import org.simantics.scl.compiler.elaboration.expressions.ExpressionVisitor;\r
@Override\r
public void visit(EIf expression) {\r
b.append("if ");\r
- expression.getCondition().accept(this);\r
+ expression.condition.accept(this);\r
++indentation;\r
newLine();\r
b.append("then ");\r
- expression.getThen().accept(this);\r
- newLine();\r
- b.append("else ");\r
- expression.getElse().accept(this);\r
+ expression.then_.accept(this);\r
+ if(expression.else_ != null) {\r
+ newLine();\r
+ b.append("else ");\r
+ expression.else_.accept(this);\r
+ }\r
--indentation;\r
}\r
\r
}\r
--indentation;\r
}\r
+ \r
+ @Override\r
+ public void visit(EViewPattern expression) {\r
+ b.append('(');\r
+ expression.expression.accept(this);\r
+ b.append(" -> ");\r
+ expression.pattern.accept(this);\r
+ b.append(')');\r
+ }\r
\r
@Override\r
public void visit(ELambdaType expression) {\r
public void visit(EEquations eEquations) {\r
b.append("eq");\r
}\r
+\r
+ @Override\r
+ public void visit(ECHRRuleset echrRuleset) {\r
+ b.append("CHRRuleset");\r
+ }\r
+\r
+ public void visit(CHRRule rule) {\r
+ visit(rule.head);\r
+ b.append(" => ");\r
+ visit(rule.body);\r
+ }\r
+\r
+ public void visit(CHRQuery query) {\r
+ boolean first = true;\r
+ for(CHRLiteral literal : query.literals) {\r
+ if(first)\r
+ first = false;\r
+ else\r
+ b.append(", ");\r
+ visit(literal);\r
+ }\r
+ }\r
+\r
+ public void visit(CHRLiteral literal) {\r
+ if(literal.passive && literal.relation instanceof CHRConstraint)\r
+ b.append("@passive ");\r
+ if(literal.killAfterMatch)\r
+ b.append('-');\r
+ b.append(literal.relation);\r
+ for(Expression parameter : literal.parameters) {\r
+ b.append(' ');\r
+ showPar(parameter);\r
+ }\r
+ }\r
}\r
import org.simantics.databoard.binding.mutable.Variant;
import org.simantics.scl.compiler.common.datatypes.Constructor;
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.constants.BooleanConstant;
import org.simantics.scl.compiler.constants.Constant;
import org.simantics.scl.compiler.constants.JavaStaticField;
public static SCLValue Nothing;
public static SCLValue Just;
+ public static SCLValue EQUALS;
+
private Builtins() {
super(Types.BUILTIN);
StandardTypeConstructor Boolean = new StandardTypeConstructor(Types.BOOLEAN, Kinds.STAR, TypeDesc.BOOLEAN);
Boolean.documentation = "Data type representing truth values `True` and `False`.";
- addTypeConstructor("Boolean", Boolean);
- addTypeConstructor("Byte", new StandardTypeConstructor(Types.BYTE, Kinds.STAR, TypeDesc.BYTE,
+ addTypeDescriptor("Boolean", Boolean);
+ addTypeDescriptor("Byte", new StandardTypeConstructor(Types.BYTE, Kinds.STAR, TypeDesc.BYTE,
"8-bit signed integer"));
- addTypeConstructor("Character", new StandardTypeConstructor(Types.CHARACTER, Kinds.STAR, TypeDesc.CHAR,
+ addTypeDescriptor("Character", new StandardTypeConstructor(Types.CHARACTER, Kinds.STAR, TypeDesc.CHAR,
"16-bit Unicode character."));
- addTypeConstructor("Short", new StandardTypeConstructor(Types.SHORT, Kinds.STAR, TypeDesc.SHORT,
+ addTypeDescriptor("Short", new StandardTypeConstructor(Types.SHORT, Kinds.STAR, TypeDesc.SHORT,
"16-bit signed integer"));
- addTypeConstructor("Integer", new StandardTypeConstructor(Types.INTEGER, Kinds.STAR, TypeDesc.INT,
+ addTypeDescriptor("Integer", new StandardTypeConstructor(Types.INTEGER, Kinds.STAR, TypeDesc.INT,
"32-bit signed integer"));
- addTypeConstructor("Long", new StandardTypeConstructor(Types.LONG, Kinds.STAR, TypeDesc.LONG,
+ addTypeDescriptor("Long", new StandardTypeConstructor(Types.LONG, Kinds.STAR, TypeDesc.LONG,
"64-bit signed integer"));
- addTypeConstructor("Float", new StandardTypeConstructor(Types.FLOAT, Kinds.STAR, TypeDesc.FLOAT,
+ addTypeDescriptor("Float", new StandardTypeConstructor(Types.FLOAT, Kinds.STAR, TypeDesc.FLOAT,
"32-bit floating point number"));
- addTypeConstructor("Double", new StandardTypeConstructor(Types.DOUBLE, Kinds.STAR, TypeDesc.DOUBLE,
+ addTypeDescriptor("Double", new StandardTypeConstructor(Types.DOUBLE, Kinds.STAR, TypeDesc.DOUBLE,
"64-bit floating point number"));
- addTypeConstructor("String", new StandardTypeConstructor(Types.STRING, Kinds.STAR, TypeDesc.STRING,
+ addTypeDescriptor("String", new StandardTypeConstructor(Types.STRING, Kinds.STAR, TypeDesc.STRING,
"Unicode string"));
- addTypeConstructor("BooleanArray", new StandardTypeConstructor(Types.BOOLEAN_ARRAY, Kinds.STAR, TypeDesc.forClass(boolean[].class)));
- addTypeConstructor("ByteArray", new StandardTypeConstructor(Types.BYTE_ARRAY, Kinds.STAR, TypeDesc.forClass(byte[].class)));
- addTypeConstructor("CharacterArray", new StandardTypeConstructor(Types.CHARACTER_ARRAY, Kinds.STAR, TypeDesc.forClass(char[].class)));
- addTypeConstructor("ShortArray", new StandardTypeConstructor(Types.SHORT_ARRAY, Kinds.STAR, TypeDesc.forClass(short[].class)));
- addTypeConstructor("IntegerArray", new StandardTypeConstructor(Types.INTEGER_ARRAY, Kinds.STAR, TypeDesc.forClass(int[].class)));
- addTypeConstructor("LongArray", new StandardTypeConstructor(Types.LONG_ARRAY, Kinds.STAR, TypeDesc.forClass(long[].class)));
- addTypeConstructor("FloatArray", new StandardTypeConstructor(Types.FLOAT_ARRAY, Kinds.STAR, TypeDesc.forClass(float[].class)));
- addTypeConstructor("DoubleArray", new StandardTypeConstructor(Types.DOUBLE_ARRAY, Kinds.STAR, TypeDesc.forClass(double[].class)));
+ addTypeDescriptor("BooleanArray", new StandardTypeConstructor(Types.BOOLEAN_ARRAY, Kinds.STAR, TypeDesc.forClass(boolean[].class)));
+ addTypeDescriptor("ByteArray", new StandardTypeConstructor(Types.BYTE_ARRAY, Kinds.STAR, TypeDesc.forClass(byte[].class)));
+ addTypeDescriptor("CharacterArray", new StandardTypeConstructor(Types.CHARACTER_ARRAY, Kinds.STAR, TypeDesc.forClass(char[].class)));
+ addTypeDescriptor("ShortArray", new StandardTypeConstructor(Types.SHORT_ARRAY, Kinds.STAR, TypeDesc.forClass(short[].class)));
+ addTypeDescriptor("IntegerArray", new StandardTypeConstructor(Types.INTEGER_ARRAY, Kinds.STAR, TypeDesc.forClass(int[].class)));
+ addTypeDescriptor("LongArray", new StandardTypeConstructor(Types.LONG_ARRAY, Kinds.STAR, TypeDesc.forClass(long[].class)));
+ addTypeDescriptor("FloatArray", new StandardTypeConstructor(Types.FLOAT_ARRAY, Kinds.STAR, TypeDesc.forClass(float[].class)));
+ addTypeDescriptor("DoubleArray", new StandardTypeConstructor(Types.DOUBLE_ARRAY, Kinds.STAR, TypeDesc.forClass(double[].class)));
- addTypeConstructor("Array", new StandardTypeConstructor(Types.con(Types.BUILTIN, "Array"), Kinds.STAR_TO_STAR, TypeDesc.forClass(Object[].class)));
+ addTypeDescriptor("Array", new StandardTypeConstructor(Types.con(Types.BUILTIN, "Array"), Kinds.STAR_TO_STAR, TypeDesc.forClass(Object[].class)));
- addTypeConstructor("Maybe", MaybeType.INSTANCE);
+ addTypeDescriptor("Maybe", MaybeType.INSTANCE);
- addTypeConstructor("Variant", new StandardTypeConstructor(Types.VARIANT, Kinds.STAR, TypeDesc.forClass(Variant.class)));
+ addTypeDescriptor("Variant", new StandardTypeConstructor(Types.VARIANT, Kinds.STAR, TypeDesc.forClass(Variant.class)));
addEffectConstructor("Proc", new EffectConstructor(Types.PROC));
- //addTypeConstructor("->", new StandardTypeConstructor(Kinds.STAR_TO_STAR_TO_STAR, Constants.FUNCTION));
- addTypeConstructor("[]", new StandardTypeConstructor(Types.LIST, Kinds.STAR_TO_STAR, Constants.LIST));
- addTypeConstructor("@", new StandardTypeConstructor(Types.PUNIT, Kinds.STAR, Constants.TUPLE[0]));
- addTypeConstructor("TypeProxy", new StandardTypeConstructor(Types.TYPE_PROXY, Kinds.STAR_TO_STAR, Constants.TUPLE[0]));
+ //addTypeDescriptor("->", new StandardTypeConstructor(Kinds.STAR_TO_STAR_TO_STAR, Constants.FUNCTION));
+ addTypeDescriptor("[]", new StandardTypeConstructor(Types.LIST, Kinds.STAR_TO_STAR, Constants.LIST));
+ addTypeDescriptor("@", new StandardTypeConstructor(Types.PUNIT, Kinds.STAR, Constants.TUPLE[0]));
+ addTypeDescriptor("TypeProxy", new StandardTypeConstructor(Types.TYPE_PROXY, Kinds.STAR_TO_STAR, Constants.TUPLE[0]));
// *** Tuples ***
TCon constructor = Types.tupleConstructor(arity);
StandardTypeConstructor typeConstructor =
new StandardTypeConstructor(constructor, tupleKind, Constants.TUPLE[arity]);
- addTypeConstructor(constructor.name, typeConstructor);
+ addTypeDescriptor(constructor.name, typeConstructor);
Type returnType = Types.apply(constructor, vars);
typeConstructor.setType(constructor, vars);
Constant cons;
Fundep.EMPTY_ARRAY);
addTypeClass("VecComp", VecCompC);
- addTypeConstructor("Vector", new VectorType(Types.VECTOR));
+ addTypeDescriptor("Vector", new VectorType(Types.VECTOR));
addValue("getVector", new GetVector(Types.NO_EFFECTS, Types.VECTOR));
addValue("lengthVector", new LengthVector(Types.VECTOR));
//addValue("createVectorFromList", CreateVectorFromList.INSTANCE);
- addTypeConstructor("MVector", new VectorType(Types.MVECTOR));
+ addTypeDescriptor("MVector", new VectorType(Types.MVECTOR));
addValue("createMVector", CreateMVector.INSTANCE);
addValue("createMVectorProto", CreateMVectorProto.INSTANCE);
addValue("getMVector", new GetVector(Types.PROC, Types.MVECTOR));
x.createOccurrence()));
runProcFunction.addBlock(block);
- SCLConstant runProc = new SCLConstant(Name.create(Types.BUILTIN, "runProc"), runProcFunction.getType());
+ SCLConstant runProc = new SCLConstant(Names.Builtin_runProc, runProcFunction.getType());
runProc.setDefinition(runProcFunction);
runProc.setInlineArity(1, 0xffffffff);
runProc.setBase(new JavaStaticMethod("org/simantics/scl/runtime/procedure/Procedures",
Types.NO_EFFECTS,
TypeDesc.forClass(TUnion.class),
Type, -1));
- /*addValue("TUnion", new JavaStaticMethod(
+ addValue("TUnion2", new JavaStaticMethod(
"org/simantics/scl/compiler/types/Types",
"union",
Types.NO_EFFECTS,
- Type, Types.list(Type)));*/
+ Type, Type, Type));
StandardTypeConstructor TypeC = new StandardTypeConstructor(Type, Kinds.STAR,
TypeDesc.forClass("org/simantics/scl/compiler/types/Type"));
TypeC.setType(Type);
TypeC.isOpen = true;
TypeC.documentation = "Represents an SCL data type.";
- addTypeConstructor("Type", TypeC);
+ addTypeDescriptor("Type", TypeC);
// typeOf :: Typeable a => a -> Type
addValue("typeOf", TypeOfConstant.INSTANCE)
BindingC.setType(Types.BINDING, A);
BindingC.documentation = "`Binding` represents a data type in the form supported by Databoard library. " +
"It is used to serialize and deserialize values.";
- addTypeConstructor("Binding", BindingC);
+ addTypeDescriptor("Binding", BindingC);
// typeOf :: Typeable a => a -> TypeReps
addValue("binding", BindingConstant.INSTANCE)
addRelation("Execute10", new ExecuteRelation(10));
}
- addValue("newEq", EqualsFunction.INSTANCE);
- addValue("newHash", HashCodeFunction.INSTANCE);
+ {
+ EQUALS = new SCLValue(Names.Builtin_equals, EqualsFunction.INSTANCE);
+ EQUALS.setPrecedence(new Precedence(4, Associativity.NONASSOC));
+ addValue(EQUALS);
+ addValue("hashCode", HashCodeFunction.INSTANCE);
+ }
+
// Coverage
{
StandardTypeConstructor branchPoint = new StandardTypeConstructor(Types.BRANCH_POINT, Kinds.STAR,
TypeDesc.forClass(BranchPoint.class));
- addTypeConstructor("BranchPoint", branchPoint);
+ addTypeDescriptor("BranchPoint", branchPoint);
addValue("visitBranchPoint", VisitBranchPoint.INSTANCE);
}
\r
import org.cojen.classfile.TypeDesc;\r
import org.objectweb.asm.Label;\r
+import org.simantics.scl.compiler.constants.ComparisonFunction;\r
import org.simantics.scl.compiler.constants.FunctionValue;\r
+import org.simantics.scl.compiler.internal.codegen.continuations.Cont;\r
import org.simantics.scl.compiler.internal.codegen.references.Val;\r
import org.simantics.scl.compiler.internal.codegen.utils.Constants;\r
import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder;\r
import org.simantics.scl.compiler.types.Types;\r
import org.simantics.scl.compiler.types.kinds.Kinds;\r
\r
-public class EqualsFunction extends FunctionValue {\r
+public class EqualsFunction extends FunctionValue implements ComparisonFunction {\r
private static final TVar A = Types.var(Kinds.STAR);\r
public static final EqualsFunction INSTANCE = new EqualsFunction();\r
\r
mb.invokeStatic("java/util/Objects", "equals", TypeDesc.BOOLEAN, Constants.OBJECTS[2]);\r
return Types.BOOLEAN;\r
}\r
+ \r
+ @Override\r
+ public String toString() {\r
+ return "==";\r
+ }\r
+\r
+ @Override\r
+ public void generateCondition(MethodBuilder mb, Val[] parameters, Cont then_, Cont else_) {\r
+ parameters[0].push(mb);\r
+ parameters[1].push(mb);\r
+ TypeDesc parameterType = mb.getJavaTypeTranslator().getTypeDesc(parameters[0]);\r
+ if(parameterType.isPrimitive()) {\r
+ if(parameterType.equals(TypeDesc.VOID)) {\r
+ mb.jump(then_);\r
+ }\r
+ else {\r
+ mb.ifComparisonBranch(mb.getLabel(then_), "==", parameterType);\r
+ mb.jump(else_);\r
+ mb.ensureExists(then_);\r
+ }\r
+ }\r
+ else {\r
+ mb.invokeStatic("java/util/Objects", "equals", TypeDesc.BOOLEAN, Constants.OBJECTS[2]);\r
+ mb.ifZeroComparisonBranch(mb.getLabel(else_), "==");\r
+ mb.jump(then_);\r
+ mb.ensureExists(else_);\r
+ }\r
+ }\r
}\r
@Override
public String toString() {
- return "[...]";
+ return "[.." + arity + "..]";
}
}
package org.simantics.scl.compiler.elaboration.java;
-import org.simantics.scl.compiler.common.names.Name;
+import org.simantics.scl.compiler.common.names.Names;
import org.simantics.scl.compiler.elaboration.expressions.EApply;
import org.simantics.scl.compiler.elaboration.expressions.EVariable;
import org.simantics.scl.compiler.elaboration.expressions.Expression;
case BB:
context.condition(
new EApply(
- context.getConstant(Name.create("Prelude", "elem"), typeParameters),
+ context.getConstant(Names.Prelude_elem, typeParameters),
new Expression[] {
- context.getEvidence(location, Types.pred(Types.EQ, typeParameters[0])),
new EVariable(parameters[0]),
new EVariable(parameters[1])
}
package org.simantics.scl.compiler.elaboration.java;
-import org.simantics.scl.compiler.common.names.Name;
+import org.simantics.scl.compiler.common.names.Names;
import org.simantics.scl.compiler.elaboration.expressions.EApply;
import org.simantics.scl.compiler.elaboration.expressions.EVariable;
import org.simantics.scl.compiler.elaboration.expressions.Expression;
case BB:
context.condition(
new EApply(
- context.getConstant(Name.create("Prelude", "elemMaybe"), typeParameters),
+ context.getConstant(Names.Prelude_elemMaybe, typeParameters),
new Expression[] {
- context.getEvidence(location, Types.pred(Types.EQ, typeParameters[0])),
new EVariable(parameters[0]),
new EVariable(parameters[1])
}
package org.simantics.scl.compiler.elaboration.modules;\r
\r
+import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
import org.simantics.scl.compiler.types.TCon;\r
import org.simantics.scl.compiler.types.TVar;\r
import org.simantics.scl.compiler.types.Type;\r
+import org.simantics.scl.compiler.types.kinds.Kind;\r
\r
-public class TypeAlias {\r
- TCon con;\r
- \r
+public class TypeAlias extends TypeDescriptor { \r
public TVar[] parameters;\r
public Type body;\r
+ public String documentation;\r
\r
- public TypeAlias(TCon con, int arity) {\r
- this.con = con;\r
+ public TypeAlias(TCon name, int arity) {\r
+ super(name);\r
this.parameters = new TVar[arity];\r
}\r
\r
- public TCon getCon() {\r
- return con;\r
- }\r
-\r
public int getArity() {\r
return parameters.length;\r
}\r
+\r
+ @Override\r
+ public Kind getKind() {\r
+ throw new InternalCompilerError("Unsupported method TypeAlias.getKind invoked.");\r
+ }\r
+ \r
+ @Override\r
+ public void setDocumentation(String documentation) {\r
+ this.documentation = documentation;\r
+ }\r
+ \r
+ @Override\r
+ public String getDocumentation() {\r
+ return documentation;\r
+ }\r
}\r
import org.simantics.scl.compiler.types.kinds.Kind;\r
import org.simantics.scl.compiler.types.kinds.Kinds;\r
\r
-public abstract class TypeConstructor {\r
+public abstract class TypeConstructor extends TypeDescriptor {\r
public Kind kind;\r
\r
- public TCon name;\r
public TVar[] parameters;\r
public Type type;\r
\r
public boolean isOpen = true;\r
\r
public TypeConstructor(Kind kind) {\r
+ super(null);\r
this.kind = kind;\r
}\r
\r
public TypeConstructor(TCon name, Kind kind) {\r
- this.name = name;\r
+ super(name);\r
this.kind = kind;\r
\r
ArrayList<TVar> vars = new ArrayList<TVar>(2);\r
}\r
\r
public TypeConstructor(TCon name, TVar ... parameters) {\r
+ super(name);\r
setType(name, parameters);\r
Kind kind = Kinds.STAR;\r
for(int i = parameters.length-1;i>=0;--i)\r
this.parameters = parameters;\r
this.type = Types.apply(name, parameters);\r
}\r
- \r
+ \r
public void setConstructors(Constructor ... constructors) {\r
this.constructors = constructors;\r
}\r
\r
public abstract TypeDesc construct(JavaTypeTranslator translator, Type[] parameters);\r
\r
+ @Override\r
public void setDocumentation(String documentation) {\r
this.documentation = documentation;\r
}\r
+ \r
+ @Override\r
+ public Kind getKind() {\r
+ return kind;\r
+ }\r
+ \r
+ @Override\r
+ public String getDocumentation() {\r
+ return documentation;\r
+ }\r
}\r
--- /dev/null
+package org.simantics.scl.compiler.elaboration.modules;\r
+\r
+import org.simantics.scl.compiler.types.TCon;\r
+import org.simantics.scl.compiler.types.kinds.Kind;\r
+\r
+public abstract class TypeDescriptor {\r
+ public TCon name;\r
+ public TypeDescriptor(TCon name) {\r
+ this.name = name;\r
+ }\r
+ public abstract Kind getKind();\r
+ public abstract void setDocumentation(String documentation);\r
+ public abstract String getDocumentation();\r
+}\r
package org.simantics.scl.compiler.elaboration.query;
-import org.simantics.scl.compiler.common.names.Name;
+import org.simantics.scl.compiler.common.names.Names;
import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;
import org.simantics.scl.compiler.elaboration.expressions.EApply;
import org.simantics.scl.compiler.elaboration.expressions.QueryTransformer;
@Override
public void generate(QueryCompilationContext context) {
context.condition(new EApply(
- context.getConstant(Name.create("Prelude", "not"), Type.EMPTY_ARRAY),
+ context.getConstant(Names.Prelude_not, Type.EMPTY_ARRAY),
innerContext.getContinuation()));
}
});
package org.simantics.scl.compiler.elaboration.query.compilation;
+import org.simantics.scl.compiler.compilation.CompilationContext;
import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
import org.simantics.scl.compiler.elaboration.expressions.EVariable;
import org.simantics.scl.compiler.errors.ErrorLog;
context.addConstraintDemand(evidence);
return evidence;
}
+
+ public CompilationContext getCompilationContext() {
+ return context.getCompilationContext();
+ }
}
import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
import org.simantics.scl.compiler.common.names.Name;
+import org.simantics.scl.compiler.common.names.Names;
+import org.simantics.scl.compiler.compilation.CompilationContext;
import org.simantics.scl.compiler.constants.BooleanConstant;
-import org.simantics.scl.compiler.elaboration.contexts.EnvironmentalContext;
import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
import org.simantics.scl.compiler.elaboration.expressions.Case;
import org.simantics.scl.compiler.elaboration.expressions.EApply;
import org.simantics.scl.compiler.elaboration.expressions.Expression;
import org.simantics.scl.compiler.elaboration.expressions.Variable;
import org.simantics.scl.compiler.elaboration.java.Builtins;
-import org.simantics.scl.compiler.elaboration.modules.SCLValue;
import org.simantics.scl.compiler.errors.Locations;
import org.simantics.scl.compiler.types.TPred;
import org.simantics.scl.compiler.types.Type;
import org.simantics.scl.compiler.types.Types;
import org.simantics.scl.compiler.types.exceptions.MatchException;
-public class QueryCompilationContext implements EnvironmentalContext {
- private static final Name EQUALS = Name.create("Prelude", "==");
-
+public class QueryCompilationContext {
TypingContext context;
QueryCompilationMode mode;
Type resultType;
}
case GET_ALL: {
try {
- return new EApply(context.getConstant(Name.create("Prelude", "appendList"),
+ return new EApply(context.getCompilationContext().getConstant(Names.Prelude_appendList,
Types.matchApply(Types.LIST, a.getType())), a, b);
} catch (MatchException e) {
throw new InternalCompilerError();
condition(new EApply(
location,
Types.PROC,
- context.getConstant(EQUALS, type),
+ context.getCompilationContext().getConstant(Names.Builtin_equals, type),
new Expression[] {
- getEvidence(location, Types.pred(Types.EQ, type)),
a,
b
}
continuation = new EApply(
Locations.NO_LOCATION,
Types.PROC,
- context.getConstant(Name.create("Prelude", "iterList"), variable.getType(), Types.PROC, Types.tupleConstructor(0)),
+ context.getCompilationContext().getConstant(Names.Prelude_iterList, variable.getType(), Types.PROC, Types.tupleConstructor(0)),
new Expression[] {
new ESimpleLambda(Types.PROC, variable, continuation),
list
continuation = new EApply(
Locations.NO_LOCATION,
Types.PROC,
- context.getConstant(Name.create("Prelude", "any"), variable.getType(), Types.PROC),
+ context.getCompilationContext().getConstant(Names.Prelude_any, variable.getType(), Types.PROC),
new Expression[] {
new ESimpleLambda(Types.PROC, variable, continuation),
list
continuation = new EApply(
Locations.NO_LOCATION,
Types.PROC,
- context.getConstant(Name.create("Prelude", "concatMap"), variable.getType(), Types.PROC,
+ context.getCompilationContext().getConstant(Names.Prelude_concatMap, variable.getType(), Types.PROC,
Types.matchApply(Types.LIST, continuation.getType())),
new Expression[] {
new ESimpleLambda(Types.PROC, variable, continuation),
continuation = new EApply(
Locations.NO_LOCATION,
Types.PROC,
- context.getConstant(Name.create("Prelude", "mapFirst"), variable.getType(), Types.PROC,
+ context.getCompilationContext().getConstant(Names.Prelude_mapFirst, variable.getType(), Types.PROC,
Types.matchApply(Types.MAYBE, continuation.getType())),
new Expression[] {
new ESimpleLambda(Types.PROC, variable, continuation),
continuation = new EApply(
Locations.NO_LOCATION,
Types.PROC,
- context.getConstant(Name.create("Vector", "iterVector"), variable.getType(), Types.PROC, continuation.getType()),
+ context.getCompilationContext().getConstant(Names.Vector_iterVector, variable.getType(), Types.PROC, continuation.getType()),
new Expression[] {
new ESimpleLambda(Types.PROC, variable, continuation),
vector
continuation = new EApply(
Locations.NO_LOCATION,
Types.PROC,
- context.getConstant(Name.create("Vector", "anyVector"), variable.getType(), Types.PROC),
+ context.getCompilationContext().getConstant(Names.Vector_anyVector, variable.getType(), Types.PROC),
new Expression[] {
new ESimpleLambda(Types.PROC, variable, continuation),
vector
continuation = new EApply(
Locations.NO_LOCATION,
Types.PROC,
- context.getConstant(Name.create("Vector", "concatMapVector"), variable.getType(), Types.PROC,
+ context.getCompilationContext().getConstant(Names.Vector_concatMapVector, variable.getType(), Types.PROC,
Types.matchApply(Types.LIST, continuation.getType())),
new Expression[] {
new ESimpleLambda(Types.PROC, variable, continuation),
continuation = new EApply(
Locations.NO_LOCATION,
Types.PROC,
- context.getConstant(Name.create("Vector", "mapFirstVector"), variable.getType(), Types.PROC,
+ context.getCompilationContext().getConstant(Names.Vector_mapFirstVector, variable.getType(), Types.PROC,
Types.matchApply(Types.MAYBE, continuation.getType())),
new Expression[] {
new ESimpleLambda(Types.PROC, variable, continuation),
}
}
- private static final Name MSet_iter = Name.create("MSet", "iter");
- private static final Name MSet_mapFirst = Name.create("MSet", "mapFirst");
-
public void iterateMSet(Variable variable, Expression set) {
try {
switch(mode) {
case ITERATE:
- continuation = apply(context, Types.PROC, MSet_iter, variable.getType(), Types.PROC, continuation.getType(),
+ continuation = apply(context.getCompilationContext(), Types.PROC, Names.MSet_iter, variable.getType(), Types.PROC, continuation.getType(),
lambda(Types.PROC, variable, continuation),
set
);
break;
case GET_FIRST:
- continuation = apply(context, Types.PROC, MSet_mapFirst, variable.getType(), Types.PROC,
+ continuation = apply(context.getCompilationContext(), Types.PROC, Names.MSet_mapFirst, variable.getType(), Types.PROC,
Types.matchApply(Types.MAYBE, continuation.getType()),
lambda(Types.PROC, variable, continuation),
set
}
public Expression getConstant(Name name, Type[] typeParameters) {
- return context.getConstant(name, typeParameters);
+ return context.getCompilationContext().getConstant(name, typeParameters);
}
public QueryCompilationContext createCheckContext() {
return evidence;
}
- @Override
- public SCLValue getValue(Name name) {
- return context.getValue(name);
+ public CompilationContext getCompilationContext() {
+ return context.getCompilationContext();
}
}
package org.simantics.scl.compiler.elaboration.relations;
+import org.simantics.scl.compiler.elaboration.chr.plan.PlanContext;
import org.simantics.scl.compiler.elaboration.expressions.Expression;
import org.simantics.scl.compiler.elaboration.expressions.Variable;
import org.simantics.scl.compiler.elaboration.query.compilation.EnforcingContext;
+import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;
import org.simantics.scl.compiler.types.Type;
public abstract class AbstractRelation implements SCLRelation {
public Expression generateEnforce(long location, EnforcingContext context, Type[] typeParameters, Variable[] parameters) {
throw new UnsupportedOperationException(getClass().getSimpleName() + " does not support enforce.");
}
+
+ @Override
+ public void generateEnforce(PlanContext context, CodeWriter w, long location, Expression[] parameters) {
+ throw new UnsupportedOperationException(getClass().getSimpleName() + " does not support enforce.");
+ }
+
+ @Override
+ public void generateIterate(PlanContext context, CodeWriter w, long location, int boundMask, Variable[] variables,
+ Expression[] expressions) {
+ throw new UnsupportedOperationException(getClass().getSimpleName() + " does not support iterate.");
+ }
}
import java.util.ArrayList;
import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
+import org.simantics.scl.compiler.elaboration.chr.plan.PlanContext;
import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;
import org.simantics.scl.compiler.elaboration.expressions.EVariable;
import org.simantics.scl.compiler.elaboration.expressions.Expression;
import org.simantics.scl.compiler.elaboration.query.compilation.EnforcingContext;
import org.simantics.scl.compiler.elaboration.query.compilation.QueryCompilationContext;
import org.simantics.scl.compiler.elaboration.query.compilation.UnsolvableQueryException;
+import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;
import org.simantics.scl.compiler.internal.parsing.Symbol;
import org.simantics.scl.compiler.types.TVar;
import org.simantics.scl.compiler.types.Type;
return name;
}
+ @Override
+ public void generateEnforce(PlanContext context, CodeWriter w, long location, Expression[] parameters) {
+ throw new UnsupportedOperationException(getClass().getSimpleName() + " does not support enforce.");
+ }
+
+ @Override
+ public void generateIterate(PlanContext context, CodeWriter w, long location, int boundMask, Variable[] variables,
+ Expression[] expressions) {
+ throw new UnsupportedOperationException(getClass().getSimpleName() + " does not support iterate.");
+ }
}
import static org.simantics.scl.compiler.elaboration.expressions.Expressions.vars;
import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
-import org.simantics.scl.compiler.common.names.Name;
-import org.simantics.scl.compiler.elaboration.expressions.ERuleset;
+import org.simantics.scl.compiler.common.names.Names;
import org.simantics.scl.compiler.elaboration.expressions.EVariable;
import org.simantics.scl.compiler.elaboration.expressions.Expressions;
import org.simantics.scl.compiler.elaboration.expressions.Variable;
private void createTable() {
this.table = newVar("table" + name,
- Types.apply(ERuleset.MSet, Types.tuple(parameterTypes)));
+ Types.apply(Names.MSet_T, Types.tuple(parameterTypes)));
}
public int getArity() {
return 0;
}
- private static final Name MSet_contains = Name.create("MSet", "contains");
- private static final Name EQ = Name.create("Prelude", "==");
@Override
public void generate(long location,
QueryCompilationContext context,
if(table == null)
throw new InternalCompilerError(location, "Variable table is undefined.");
if(boundVariables + 1 == 1 << parameters.length)
- context.condition(apply(context, Types.PROC,
- MSet_contains, Types.tuple(parameterTypes),
+ context.condition(apply(context.getCompilationContext(), Types.PROC,
+ Names.MSet_contains, Types.tuple(parameterTypes),
var(table),
tuple(vars(parameters))
));
Variable row = new Variable("row", Types.tuple(parameterTypes));
for(int i=0;i<parameters.length;++i)
if(((boundVariables>>i)&1) == 1)
- context.condition(apply(context, Types.NO_EFFECTS,
- EQ, parameterTypes[i],
- context.getEvidence(location, Types.pred(Types.EQ, parameterTypes[i])),
+ context.condition(apply(context.getCompilationContext(), Types.NO_EFFECTS,
+ Names.Builtin_equals, parameterTypes[i],
var(aux[i]),
var(parameters[i])
));
package org.simantics.scl.compiler.elaboration.relations;
+import org.simantics.scl.compiler.elaboration.chr.plan.PlanContext;
import org.simantics.scl.compiler.elaboration.expressions.Expression;
import org.simantics.scl.compiler.elaboration.expressions.Variable;
import org.simantics.scl.compiler.elaboration.query.compilation.EnforcingContext;
import org.simantics.scl.compiler.elaboration.query.compilation.QueryCompilationContext;
+import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;
import org.simantics.scl.compiler.types.TVar;
import org.simantics.scl.compiler.types.Type;
Type[] typeParameters,
Variable[] parameters);
+ void generateIterate(
+ PlanContext context,
+ CodeWriter w,
+ long location,
+ int boundMask,
+ Variable[] variables,
+ Expression[] expressions);
+ void generateEnforce(
+ PlanContext context,
+ CodeWriter w,
+ long location,
+ Expression[] parameters);
}
import static org.simantics.scl.compiler.elaboration.expressions.Expressions.var;
import org.simantics.scl.compiler.common.names.Name;
+import org.simantics.scl.compiler.common.names.Names;
import org.simantics.scl.compiler.elaboration.expressions.EApply;
import org.simantics.scl.compiler.elaboration.expressions.EVariable;
import org.simantics.scl.compiler.elaboration.expressions.Expression;
type = type.replace(getTypeVariables(), typeParameters);
Expression continuation = context.getContinuation();
+ System.out.println("continuation = " + continuation + " :: " + continuation.getType());
Variable set = new Variable("set", Types.apply(Types.con("MSet", "T"), type));
Variable f = new Variable("f", Types.functionE(type, Types.PROC, continuation.getType()));
Variable innerSolved = new Variable("tcTemp", solved.getType());
+ System.out.println("set :: " + set.getType());
+ System.out.println("f :: " + f.getType());
+ System.out.println("tcTemp :: " + innerSolved.getType());
QueryCompilationContext newContext = context.createSubcontext(new EApply(
new EVariable(f), new EVariable(innerSolved)
innerParameters, boundVariables);
continuation = context.disjunction(continuation, newContext.getContinuation());
- continuation = if_(apply(context, Types.PROC, Name.create("MSet", "add"), type,
+ continuation = if_(apply(context.getCompilationContext(), Types.PROC, Names.MSet_add, type,
var(set), var(solved)),
continuation,
context.failure());
continuation = lambda(Types.PROC, solved, continuation);
continuation = letRec(f, continuation, apply(var(f), var(bound)));
continuation = let(set,
- apply(context, Types.PROC, Name.create("MSet", "create"), type, tuple()),
+ apply(context.getCompilationContext(), Types.PROC, Names.MSet_create, type, tuple()),
continuation);
context.setContinuation(continuation);
\r
import org.simantics.scl.compiler.common.names.Name;\r
import org.simantics.scl.compiler.elaboration.modules.SCLValue;\r
-import org.simantics.scl.compiler.elaboration.modules.TypeAlias;\r
import org.simantics.scl.compiler.elaboration.modules.TypeClass;\r
import org.simantics.scl.compiler.elaboration.modules.TypeClassInstance;\r
-import org.simantics.scl.compiler.elaboration.modules.TypeConstructor;\r
+import org.simantics.scl.compiler.elaboration.modules.TypeDescriptor;\r
import org.simantics.scl.compiler.elaboration.relations.SCLEntityType;\r
import org.simantics.scl.compiler.elaboration.relations.SCLRelation;\r
import org.simantics.scl.compiler.internal.codegen.effects.EffectConstructor;\r
}\r
\r
@Override\r
- public TypeConstructor getTypeConstructor(TCon type) {\r
+ public TypeDescriptor getTypeDescriptor(TCon type) {\r
Module module = getModule(type.module);\r
if(module == null)\r
return null;\r
- return module.getTypeConstructor(type.name);\r
+ return module.getTypeDescriptor(type.name);\r
}\r
\r
@Override\r
return module.getEffectConstructor(type.name);\r
}\r
\r
- @Override\r
- public TypeAlias getTypeAlias(TCon type) {\r
- Module module = getModule(type.module);\r
- if(module == null)\r
- return null;\r
- return module.getTypeAlias(type.name);\r
- }\r
-\r
@Override\r
public TypeClass getTypeClass(TCon type) {\r
Module module = getModule(type.module);\r
import java.util.function.Consumer;
import org.simantics.scl.compiler.elaboration.modules.SCLValue;
-import org.simantics.scl.compiler.elaboration.modules.TypeAlias;
import org.simantics.scl.compiler.elaboration.modules.TypeClass;
import org.simantics.scl.compiler.elaboration.modules.TypeConstructor;
import org.simantics.scl.compiler.elaboration.relations.SCLEntityType;
throws AmbiguousNameException {
return null;
}
-
+
@Override
- public TypeConstructor getTypeConstructor(String name)
- throws AmbiguousNameException {
+ public TypeConstructor getTypeDescriptor(String name) throws AmbiguousNameException {
return null;
}
return null;
}
- @Override
- public TypeAlias getTypeAlias(String name) throws AmbiguousNameException {
- return null;
- }
-
@Override
public MappingRelation getMappingRelation(String name)
throws AmbiguousNameException {
import org.simantics.scl.compiler.common.names.Name;
import org.simantics.scl.compiler.elaboration.contexts.EnvironmentalContext;
import org.simantics.scl.compiler.elaboration.modules.SCLValue;
-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.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;
import org.simantics.scl.compiler.elaboration.rules.TransformationRule;
SCLValue getValue(Name name);
SCLRelation getRelation(Name name);
SCLEntityType getEntityType(Name name);
- TypeConstructor getTypeConstructor(TCon type);
+ TypeDescriptor getTypeDescriptor(TCon type);
EffectConstructor getEffectConstructor(TCon type);
- TypeAlias getTypeAlias(TCon type);
TypeClass getTypeClass(TCon type);
Collection<TypeClassInstance> getInstances(TCon typeClass);
void collectRules(Collection<TransformationRule> rules);
import java.util.function.Consumer;
import org.simantics.scl.compiler.common.names.Name;
+import org.simantics.scl.compiler.compilation.CompilationContext;
import org.simantics.scl.compiler.elaboration.contexts.TypeTranslationContext;
import org.simantics.scl.compiler.elaboration.modules.SCLValue;
-import org.simantics.scl.compiler.elaboration.modules.TypeAlias;
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;
import org.simantics.scl.compiler.elaboration.rules.MappingRelation;
import org.simantics.scl.compiler.elaboration.rules.TransformationRule;
import org.simantics.scl.compiler.environment.filter.AcceptAllNamespaceFilter;
-import org.simantics.scl.compiler.errors.ErrorLog;
import org.simantics.scl.compiler.internal.codegen.effects.EffectConstructor;
import org.simantics.scl.compiler.internal.parsing.exceptions.SCLSyntaxErrorException;
import org.simantics.scl.compiler.internal.parsing.parser.SCLParserImpl;
* @return A TypeConstructor instance, or null if not found.
* @throws AmbiguousNameException if the same name is found in multiple imported modules.
*/
- public static TypeConstructor getTypeConstructor(Environment environment, String localName) throws AmbiguousNameException {
- return getEnvironmentEntry(environment, localName, getTypeConstructor);
+ public static TypeDescriptor getTypeDescriptor(Environment environment, String localName) throws AmbiguousNameException {
+ return getEnvironmentEntry(environment, localName, getTypeDescriptor);
}
/**
public static TypeClass getTypeClass(Environment environment, String localName) throws AmbiguousNameException {
return getEnvironmentEntry(environment, localName, getTypeClass);
}
-
- /**
- * Get the TypeAlias object representing a type alias defined in a given environment.
- * The name can be a local name or a fully scoped name with modules separated by periods.
- * @param environment the environment
- * @param localName the name to be searched for
- * @return A TypeAlias instance, or null if not found.
- * @throws AmbiguousNameException if the same name is found in multiple imported modules.
- */
- public static TypeAlias getTypeAlias(Environment environment, String localName) throws AmbiguousNameException {
- return getEnvironmentEntry(environment, localName, getTypeAlias);
- }
/**
* Get the Name object representing an SCL value defined in a given environment.
* @return A TCon instance, or null if not found.
* @throws AmbiguousNameException if the same name is used in multiple imported modules.
*/
- public static TCon getTypeConstructorName(Environment environment, String localName) throws AmbiguousNameException {
- TypeConstructor typeConstructor = getTypeConstructor(environment, localName);
- if(typeConstructor == null)
+ public static TCon getTypeDescriptorName(Environment environment, String localName) throws AmbiguousNameException {
+ TypeDescriptor typeDescriptor = getTypeDescriptor(environment, localName);
+ if(typeDescriptor == null)
return null;
else
- return typeConstructor.name;
+ return typeDescriptor.name;
}
/**
*/
public static Type getType(Environment environment, String typeText) throws SCLExpressionCompilationException {
SCLParserImpl parser = new SCLParserImpl(new StringReader(typeText));
- ErrorLog errorLog = new ErrorLog();
+ CompilationContext compilationContext = new CompilationContext();
+ compilationContext.environment = environment;
try {
TypeAst typeAst = (TypeAst)parser.parseType();
- TypeTranslationContext context = new TypeTranslationContext(errorLog, environment);
+ TypeTranslationContext context = new TypeTranslationContext(compilationContext);
Type type = context.toType(typeAst);
- if(errorLog.isEmpty())
+ if(compilationContext.errorLog.isEmpty())
return type;
} catch(SCLSyntaxErrorException e) {
- errorLog.log(e.location, e.getMessage());
+ compilationContext.errorLog.log(e.location, e.getMessage());
} catch(Exception e) {
- errorLog.log(e);
+ compilationContext.errorLog.log(e);
}
- throw new SCLExpressionCompilationException(errorLog.getErrors());
+ throw new SCLExpressionCompilationException(compilationContext.errorLog.getErrors());
}
/**
}
};
- private static final NamespaceValueAccessor<TypeConstructor> getTypeConstructor = new NamespaceValueAccessor<TypeConstructor>() {
+ private static final NamespaceValueAccessor<TypeDescriptor> getTypeDescriptor = new NamespaceValueAccessor<TypeDescriptor>() {
@Override
- public TypeConstructor get(Namespace ns, String name) throws AmbiguousNameException {
- return ns.getTypeConstructor(name);
+ public TypeDescriptor get(Namespace ns, String name) throws AmbiguousNameException {
+ return ns.getTypeDescriptor(name);
}
};
}
};
- private static final NamespaceValueAccessor<TypeAlias> getTypeAlias = new NamespaceValueAccessor<TypeAlias>() {
- @Override
- public TypeAlias get(Namespace ns, String name) throws AmbiguousNameException {
- return ns.getTypeAlias(name);
- }
- };
-
private static <T> T getEnvironmentEntry(Environment environment, String localName, NamespaceValueAccessor<T> accessor) throws AmbiguousNameException {
Namespace namespace = environment.getLocalNamespace();
int curPos = 0;
int pos = localName.indexOf('.', curPos);
if(pos < 0)
return accessor.get(namespace, localName.substring(curPos));
- namespace = namespace.getNamespace(localName.substring(curPos, pos));
- if(namespace == null)
- return null;
+ Namespace newNamespace = namespace.getNamespace(localName.substring(curPos, pos));
+ if(newNamespace == null)
+ return accessor.get(namespace, localName.substring(curPos));
+ namespace = newNamespace;
curPos = pos + 1;
}
}
import java.util.function.Consumer;
import org.simantics.scl.compiler.elaboration.modules.SCLValue;
-import org.simantics.scl.compiler.elaboration.modules.TypeAlias;
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;
import org.simantics.scl.compiler.elaboration.rules.MappingRelation;
SCLEntityType getEntityType(String name) throws AmbiguousNameException;
/**
- * Get a TypeConstructor for a given name. The same instance is returned on each call.
+ * Get a TypeDescriptor for a given name. The same instance is returned on each call.
* @param name the name of a defined entity type
- * @return The return value is a TypeConstructor provided by any source included in the namespace,
+ * @return The return value is a TypeDescriptor provided by any source included in the namespace,
* or null if the name is not found.
* @exception AmbiguousNameException if the name matches with multiple imported modules.
*/
- TypeConstructor getTypeConstructor(String name) throws AmbiguousNameException;
+ TypeDescriptor getTypeDescriptor(String name) throws AmbiguousNameException;
/**
* Get an EffectConstructor for a given name. The same instance is returned on each call.
*/
TypeClass getTypeClass(String name) throws AmbiguousNameException;
- /**
- * Get a TypeAlias for a given name. The same instance is returned on each call.
- * @param name the name of a defined entity type
- * @return The return value is a TypeAlias provided by any source included in the namespace,
- * or null if the name is not found.
- * @exception AmbiguousNameException if the name matches with multiple imported modules.
- */
- TypeAlias getTypeAlias(String name) throws AmbiguousNameException;
-
TransformationRule getRule(String name) throws AmbiguousNameException;
MappingRelation getMappingRelation(String name) throws AmbiguousNameException;
import java.util.function.Consumer;
import org.simantics.scl.compiler.elaboration.modules.SCLValue;
-import org.simantics.scl.compiler.elaboration.modules.TypeAlias;
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;
import org.simantics.scl.compiler.elaboration.rules.MappingRelation;
this.module = module;
this.filter = filter;
}
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder();
- sb.append("ModuleImport \"").append(module).append("\"").append(" with filter ").append(filter);
- return sb.toString();
- }
}
public NamespaceImpl(THashMap<String, Namespace> namespaceMap,
}
@Override
- public TypeConstructor getTypeConstructor(String name)
+ public TypeDescriptor getTypeDescriptor(String name)
throws AmbiguousNameException {
- TypeConstructor result = null, temp;
+ TypeDescriptor result = null, temp;
Module resultModule = null;
ArrayList<String> conflictingModules = null;
for(ModuleImport moduleImport : moduleImports) {
Module module = moduleImport.module;
- temp = module.getTypeConstructor(name);
+ temp = module.getTypeDescriptor(name);
if(temp != null) {
if(result != null) {
if(conflictingModules == null) {
return result;
}
- @Override
- public TypeAlias getTypeAlias(String name) throws AmbiguousNameException {
- TypeAlias result = null, temp;
- Module resultModule = null;
- ArrayList<String> conflictingModules = null;
- for(ModuleImport moduleImport : moduleImports) {
- Module module = moduleImport.module;
- temp = module.getTypeAlias(name);
- if(temp != null) {
- if(result != null) {
- if(conflictingModules == null) {
- conflictingModules = new ArrayList<String>(2);
- conflictingModules.add(resultModule.getName());
- }
- conflictingModules.add(module.getName());
- }
- else {
- result = temp;
- resultModule = module;
- }
- }
- }
- if(conflictingModules != null)
- throw new AmbiguousNameException(conflictingModules, name);
- return result;
- }
-
@Override
public MappingRelation getMappingRelation(String name) throws AmbiguousNameException {
MappingRelation result = null, temp;
public String toString() {
return getErrorsAsString();
}
+
+ public int getErrorCount() {
+ return errors.size();
+ }
}
package org.simantics.scl.compiler.internal.codegen.analysis;\r
\r
import org.simantics.scl.compiler.common.names.Name;\r
+import org.simantics.scl.compiler.common.names.Names;\r
import org.simantics.scl.compiler.constants.SCLConstant;\r
import org.simantics.scl.compiler.internal.codegen.references.Val;\r
import org.simantics.scl.compiler.internal.codegen.references.ValRef;\r
return isLoopingBlockWithBreaker(apply.getParent(), breaker);\r
}\r
} \r
-\r
- private static final Name BUILD = Name.create("Prelude", "build");\r
\r
private static boolean isAppliedAtMostOnce(LetApply apply, ValRef funRef, SSAFunction function) {\r
ValRef applyFunctionRef = apply.getFunction();\r
if(!(applyFunction instanceof SCLConstant))\r
return false; // Not necessarily the right answer\r
Name name = ((SCLConstant)applyFunction).getName();\r
- if(name == BUILD)\r
+ if(name == Names.Prelude_build)\r
return true;\r
return false;\r
}\r
\r
import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
import org.simantics.scl.compiler.common.names.Name;\r
+import org.simantics.scl.compiler.common.names.Names;\r
import org.simantics.scl.compiler.constants.SCLConstant;\r
import org.simantics.scl.compiler.internal.codegen.continuations.ContRef;\r
import org.simantics.scl.compiler.internal.codegen.references.BoundVar;\r
}\r
}\r
\r
- private static final Name BUILD = Name.create("Prelude", "build");\r
- \r
private static boolean callsOnlyOnce(Name name, int arity) {\r
- if(name == BUILD)\r
+ if(name == Names.Prelude_build)\r
return arity == 1;\r
else\r
return false;\r
--- /dev/null
+package org.simantics.scl.compiler.internal.codegen.chr;\r
+\r
+import java.util.ArrayList;\r
+\r
+import org.cojen.classfile.TypeDesc;\r
+import org.objectweb.asm.Label;\r
+import org.objectweb.asm.Opcodes;\r
+import org.simantics.scl.compiler.elaboration.chr.CHRRuleset;\r
+import org.simantics.scl.compiler.elaboration.chr.plan.PrioritizedPlan;\r
+import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint;\r
+import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint.IndexInfo;\r
+import org.simantics.scl.compiler.internal.codegen.references.BoundVar;\r
+import org.simantics.scl.compiler.internal.codegen.types.JavaTypeTranslator;\r
+import org.simantics.scl.compiler.internal.codegen.utils.ClassBuilder;\r
+import org.simantics.scl.compiler.internal.codegen.utils.CodeBuilderUtils;\r
+import org.simantics.scl.compiler.internal.codegen.utils.Constants;\r
+import org.simantics.scl.compiler.internal.codegen.utils.LocalVariable;\r
+import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder;\r
+import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilderBase;\r
+import org.simantics.scl.compiler.internal.codegen.utils.ModuleBuilder;\r
+\r
+import gnu.trove.list.array.TIntArrayList;\r
+import gnu.trove.set.hash.THashSet;\r
+\r
+public class CHRCodeGenerator {\r
+ \r
+ public static final TypeDesc FACT_ID_TYPE = TypeDesc.INT;\r
+ public static final String CHRHashIndex_name = "org/simantics/scl/runtime/chr/CHRHashIndex";\r
+ public static final TypeDesc CHRHashIndex = TypeDesc.forClass(CHRHashIndex_name);\r
+ public static final String FactActivationQueue_name = "org/simantics/scl/runtime/chr/FactActivationQueue";\r
+ public static final TypeDesc FactActivationQueue = TypeDesc.forClass(FactActivationQueue_name);\r
+ public static final String Fact_name = "org/simantics/scl/runtime/chr/Fact";\r
+ public static final TypeDesc Fact = TypeDesc.forClass(Fact_name);\r
+ public static final String QUEUE = "queue";\r
+ \r
+ private static class StoreInitialization {\r
+ final int access;\r
+ final String fieldName;\r
+ final TypeDesc fieldType;\r
+ final String className;\r
+ public StoreInitialization(int access, String fieldName, TypeDesc fieldType, String className) {\r
+ this.access = access;\r
+ this.fieldName = fieldName;\r
+ this.fieldType = fieldType;\r
+ this.className = className;\r
+ }\r
+ }\r
+ \r
+ public static void generateStore(ModuleBuilder moduleBuilder, CHRRuleset ruleset) {\r
+ ClassBuilder storeClassBuilder = new ClassBuilder(moduleBuilder, Opcodes.ACC_PUBLIC, ruleset.storeClassName, "java/lang/Object");\r
+ if(ruleset.parameters == null)\r
+ ruleset.parameters = new BoundVar[0];\r
+ ruleset.parameterTypeDescs = moduleBuilder.getJavaTypeTranslator().getTypeDescs(ruleset.parameters); \r
+ \r
+ ArrayList<StoreInitialization> hashIndexInitializations = new ArrayList<>();\r
+ for(CHRConstraint constraint : ruleset.constraints)\r
+ generateFact(storeClassBuilder, constraint, hashIndexInitializations);\r
+ \r
+ // Fields\r
+ for(int i=0;i<ruleset.parameterTypeDescs.length;++i)\r
+ storeClassBuilder.addField(Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL, "p" + i, ruleset.parameterTypeDescs[i]);\r
+ storeClassBuilder.addField(Opcodes.ACC_PUBLIC, "currentId", FACT_ID_TYPE);\r
+ for(StoreInitialization ini : hashIndexInitializations)\r
+ storeClassBuilder.addField(ini.access, ini.fieldName, ini.fieldType);\r
+ storeClassBuilder.addField(Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL, QUEUE, FactActivationQueue);\r
+ \r
+ // Constructors\r
+ \r
+ {\r
+ MethodBuilderBase mb = storeClassBuilder.addConstructor(Opcodes.ACC_PUBLIC, ruleset.parameterTypeDescs);\r
+ mb.loadThis();\r
+ mb.invokeConstructor(storeClassBuilder.getSuperClassName(), Constants.EMPTY_TYPEDESC_ARRAY);\r
+ for(int i=0;i<ruleset.parameterTypeDescs.length;++i) {\r
+ mb.loadThis();\r
+ mb.loadLocal(mb.getParameter(i));\r
+ mb.storeField(ruleset.storeClassName, "p" + i, ruleset.parameterTypeDescs[i]);\r
+ }\r
+ mb.loadThis();\r
+ mb.loadConstant(1);\r
+ mb.storeField(storeClassBuilder.getClassName(), "currentId", TypeDesc.INT);\r
+ for(StoreInitialization ini : hashIndexInitializations) {\r
+ mb.loadThis();\r
+ mb.newObject(ini.className);\r
+ mb.dup();\r
+ mb.invokeConstructor(ini.className, Constants.EMPTY_TYPEDESC_ARRAY);\r
+ mb.storeField(ruleset.storeClassName, ini.fieldName, ini.fieldType);\r
+ }\r
+ {\r
+ mb.loadThis();\r
+ mb.newObject(FactActivationQueue_name);\r
+ mb.dup();\r
+ mb.loadConstant(ruleset.priorityCount);\r
+ mb.invokeConstructor(FactActivationQueue_name, new TypeDesc[] {TypeDesc.INT});\r
+ mb.storeField(ruleset.storeClassName, QUEUE, FactActivationQueue);\r
+ }\r
+ mb.returnVoid();\r
+ mb.finish();\r
+ }\r
+ \r
+ // Activate\r
+ \r
+ {\r
+ MethodBuilderBase mb = storeClassBuilder.addMethodBase(Opcodes.ACC_PUBLIC, "activate", TypeDesc.VOID, new TypeDesc[] {TypeDesc.INT});\r
+ mb.loadThis();\r
+ mb.loadField(ruleset.storeClassName, QUEUE, FactActivationQueue);\r
+ mb.loadThis();\r
+ mb.loadLocal(mb.getParameter(0));\r
+ mb.invokeVirtual(FactActivationQueue_name, "activate", TypeDesc.VOID, new TypeDesc[] {TypeDesc.OBJECT, TypeDesc.INT});\r
+ mb.returnVoid();\r
+ mb.finish();\r
+ }\r
+ \r
+ moduleBuilder.addClass(storeClassBuilder);\r
+ }\r
+ \r
+ private static void generateFact(ClassBuilder storeClassBuilder, CHRConstraint constraint, ArrayList<StoreInitialization> hashIndexInitializations) {\r
+ CHRRuleset ruleset = constraint.parentRuleset;\r
+ boolean supportsRemoval = constraint.mayBeRemoved();\r
+ \r
+ ModuleBuilder moduleBuilder = storeClassBuilder.getModuleBuilder();\r
+ JavaTypeTranslator jtt = moduleBuilder.getJavaTypeTranslator();\r
+ TypeDesc storeTypeDesc = storeClassBuilder.getType();\r
+ TypeDesc[] storeTypeDescArray = new TypeDesc[] { storeTypeDesc };\r
+ \r
+ String factClassName = storeClassBuilder.getClassName() + "$" + constraint.name;\r
+ TypeDesc factTypeDesc = TypeDesc.forClass(factClassName);\r
+ ClassBuilder factClassBuilder = new ClassBuilder(moduleBuilder, Opcodes.ACC_PUBLIC, factClassName, "java/lang/Object", Fact_name);\r
+ \r
+ // Fields\r
+ \r
+ /* public int id;\r
+ public int c0; // key\r
+ public int c1;\r
+ public ExampleFact bfPrev;\r
+ public ExampleFact bfNext;\r
+ */\r
+ TypeDesc[] parameterTypeDescs = jtt.toTypeDescs(constraint.parameterTypes);\r
+ factClassBuilder.addField(Opcodes.ACC_PUBLIC, "id", FACT_ID_TYPE);\r
+ for(int i=0;i<constraint.parameterTypes.length;++i)\r
+ factClassBuilder.addField(Opcodes.ACC_PUBLIC, "c" + i, parameterTypeDescs[i]);\r
+ \r
+ for(IndexInfo indexInfo : constraint.getIndices()) {\r
+ if(supportsRemoval)\r
+ factClassBuilder.addField(Opcodes.ACC_PUBLIC, indexInfo.indexName + "Prev", factTypeDesc);\r
+ factClassBuilder.addField(Opcodes.ACC_PUBLIC, indexInfo.indexName + "Next", factTypeDesc);\r
+ \r
+ String hashIndexField = constraint.name + "$" + indexInfo.indexName;\r
+ if(indexInfo.indexMask == 0) {\r
+ // If there are now bound parameters, use just a direct reference to a fact\r
+ storeClassBuilder.addField(Opcodes.ACC_PUBLIC, hashIndexField, factTypeDesc);\r
+ }\r
+ else {\r
+ ClassBuilder hashClass = generateSpecializedHashIndex(storeClassBuilder, constraint, indexInfo, factTypeDesc, factClassName);\r
+ moduleBuilder.addClass(hashClass);\r
+ hashIndexInitializations.add(new StoreInitialization(Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL, hashIndexField, CHRHashIndex, hashClass.getClassName()));\r
+ }\r
+ }\r
+ \r
+ // Method: get\r
+ \r
+ hashIndexInitializations.add(new StoreInitialization(Opcodes.ACC_PRIVATE | Opcodes.ACC_FINAL, constraint.name + "$temp", factTypeDesc, factClassName));\r
+\r
+ \r
+ {\r
+ /*\r
+ public ExampleFact ExampleFact$bf(int c0) {\r
+ ExampleFact$temp.c0 = c0;\r
+ return (ExampleFact)ExampleFact_bfIndex.getEqual(ExampleFact$temp);\r
+ }\r
+ */\r
+ for(IndexInfo indexInfo : constraint.getIndices()) {\r
+ /*if(indexInfo.indexMask == 0) {\r
+ MethodBuilderBase mb = storeClassBuilder.addMethodBase(Opcodes.ACC_PUBLIC, constraint.name + "$" + indexInfo.indexName,\r
+ factTypeDesc, Constants.EMPTY_TYPEDESC_ARRAY);\r
+ mb.loadThis();\r
+ mb.loadField(storeClassBuilder.getClassName(), constraint.name + "$" + indexInfo.indexName, factTypeDesc);\r
+ mb.returnValue(factTypeDesc);\r
+ mb.finish();\r
+ }*/\r
+ if(indexInfo.indexMask != 0) {\r
+ ArrayList<TypeDesc> getParameterTypeDescs = new ArrayList<TypeDesc>(constraint.parameterTypes.length);\r
+ for(int i=0;i<constraint.parameterTypes.length;++i)\r
+ if(((indexInfo.indexMask>>i)&1)==1)\r
+ getParameterTypeDescs.add(parameterTypeDescs[i]);\r
+ MethodBuilderBase mb = storeClassBuilder.addMethodBase(Opcodes.ACC_PUBLIC, constraint.name + "$" + indexInfo.indexName, factTypeDesc,\r
+ getParameterTypeDescs.toArray(new TypeDesc[getParameterTypeDescs.size()]));\r
+ mb.loadThis();\r
+ mb.loadField(storeClassBuilder.getClassName(), constraint.name + "$temp", factTypeDesc);\r
+ LocalVariable tempFactVar = mb.createLocalVariable("temp", factTypeDesc);\r
+ mb.storeLocal(tempFactVar);\r
+ int parameterId=0;\r
+ for(int i=0;i<constraint.parameterTypes.length;++i)\r
+ if(((indexInfo.indexMask>>i)&1)==1) {\r
+ mb.loadLocal(tempFactVar);\r
+ mb.loadLocal(mb.getParameter(parameterId++));\r
+ mb.storeField(factClassName, "c"+i, parameterTypeDescs[i]);\r
+ }\r
+\r
+ mb.loadThis();\r
+ mb.loadField(storeClassBuilder.getClassName(), constraint.name + "$" + indexInfo.indexName, CHRHashIndex);\r
+ mb.loadLocal(tempFactVar);\r
+ mb.invokeVirtual(CHRHashIndex_name, supportsRemoval ? "getEqual" : "getEqualNoRemovals", TypeDesc.OBJECT, Constants.OBJECTS[1]);\r
+ mb.checkCast(factTypeDesc);\r
+ \r
+ mb.returnValue(factTypeDesc);\r
+ mb.finish();\r
+ }\r
+ } \r
+ }\r
+ \r
+ // Method: add\r
+ \r
+ {\r
+ MethodBuilderBase mb = factClassBuilder.addMethodBase(Opcodes.ACC_PUBLIC, "add", TypeDesc.VOID, storeTypeDescArray);\r
+ LocalVariable storeParameter = mb.getParameter(0);\r
+ for(IndexInfo indexInfo : constraint.getIndices()) {\r
+ String linkedListPrev = indexInfo.indexName + "Prev";\r
+ String linkedListNext = indexInfo.indexName + "Next";\r
+ String storeHashIndexName = constraint.name + "$" + indexInfo.indexName;\r
+ \r
+ // public void add(ExampleStore store) {\r
+ // bfNext = (ExampleFact)store.ExampleFact_bfIndex.addFreshAndReturnOld(this);\r
+ // if(bfNext != null)\r
+ // bfNext.bfPrev = this;\r
+ // }\r
+ \r
+ if(indexInfo.indexMask == 0) {\r
+ mb.loadThis();\r
+ mb.loadLocal(storeParameter);\r
+ mb.loadField(storeClassBuilder.getClassName(), storeHashIndexName, factTypeDesc);\r
+ if(supportsRemoval)\r
+ mb.dupX1();\r
+ mb.storeField(factClassName, linkedListNext, factTypeDesc);\r
+ if(supportsRemoval) {\r
+ Label cont = new Label();\r
+ mb.ifNullBranch(cont, true);\r
+ mb.loadThis();\r
+ mb.loadField(factClassName, linkedListNext, factTypeDesc);\r
+ mb.loadThis();\r
+ mb.storeField(factClassName, linkedListPrev, factTypeDesc);\r
+ mb.setLocation(cont);\r
+ }\r
+ mb.loadLocal(storeParameter);\r
+ mb.loadThis();\r
+ mb.storeField(storeClassBuilder.getClassName(), storeHashIndexName, factTypeDesc);\r
+ }\r
+ else {\r
+ // bfNext = (ExampleFact)store.ExampleFact_bfIndex.addFreshAndReturnOld(this);\r
+ mb.loadThis();\r
+ mb.loadLocal(storeParameter);\r
+ mb.loadField(storeClassBuilder.getClassName(), storeHashIndexName, CHRHashIndex);\r
+ mb.loadThis();\r
+ mb.invokeVirtual(CHRHashIndex_name, supportsRemoval ? "addFreshAndReturnOld" : "addFreshAndReturnOld", TypeDesc.OBJECT, Constants.OBJECTS[1]);\r
+ mb.checkCast(factTypeDesc);\r
+ if(supportsRemoval)\r
+ mb.dupX1();\r
+ mb.storeField(factClassName, linkedListNext, factTypeDesc);\r
+ // leaves bfNext on the stack\r
+\r
+ //if(bfNext != null)\r
+ // bfNext.bfPrev = this;\r
+ if(supportsRemoval) {\r
+ Label cont = new Label();\r
+ mb.ifNullBranch(cont, true);\r
+ mb.loadThis();\r
+ mb.loadField(factClassName, linkedListNext, factTypeDesc);\r
+ mb.loadThis();\r
+ mb.storeField(factClassName, linkedListPrev, factTypeDesc);\r
+ mb.setLocation(cont);\r
+ }\r
+ }\r
+ } \r
+ if(!constraint.isPassive()) {\r
+ mb.loadLocal(storeParameter);\r
+ mb.loadField(storeClassBuilder.getClassName(), QUEUE, FactActivationQueue);\r
+ mb.loadConstant(constraint.getMinimumPriority());\r
+ mb.loadThis();\r
+ mb.invokeVirtual(FactActivationQueue_name, "add", TypeDesc.VOID, new TypeDesc[] {TypeDesc.INT, Fact});\r
+ }\r
+ mb.returnVoid();\r
+ mb.finish();\r
+ }\r
+ \r
+ // Method: remove\r
+\r
+ if(supportsRemoval) {\r
+ // public void remove(ExampleStore store) {\r
+ // if(bfPrev == null) {\r
+ // if(bfNext == null)\r
+ // store.ExampleFact_bfIndex.removeKnownToExistKey(this);\r
+ // else {\r
+ // bfNext.bfPrev = null;\r
+ // store.ExampleFact_bfIndex.replaceKnownToExistKey(this, bfNext);\r
+ // }\r
+ // }\r
+ // else {\r
+ // bfPrev.bfNext = bfNext;\r
+ // if(bfNext != null)\r
+ // bfNext.bfPrev = bfPrev;\r
+ // }\r
+ // }\r
+ \r
+ MethodBuilderBase mb = factClassBuilder.addMethodBase(Opcodes.ACC_PUBLIC, "remove", TypeDesc.VOID, storeTypeDescArray);\r
+ LocalVariable storeParameter = mb.getParameter(0);\r
+ for(IndexInfo indexInfo : constraint.getIndices()) {\r
+ String linkedListPrev = indexInfo.indexName + "Prev";\r
+ String linkedListNext = indexInfo.indexName + "Next";\r
+ String storeHashIndexName = constraint.name + "$" + indexInfo.indexName;\r
+ \r
+ Label nextIndex = mb.createLabel();\r
+ \r
+ // if(bfPrev == null) {\r
+ mb.loadThis();\r
+ mb.loadField(factClassName, linkedListPrev, factTypeDesc);\r
+ Label else1 = new Label();\r
+ mb.ifNullBranch(else1, false);\r
+ \r
+ // if(bfNext == null)\r
+ mb.loadThis();\r
+ mb.loadField(factClassName, linkedListNext, factTypeDesc);\r
+ Label else2 = new Label();\r
+ mb.ifNullBranch(else2, false);\r
+ \r
+ // store.ExampleFact_bfIndex.removeKnownToExistKey(this);\r
+ if(indexInfo.indexMask == 0) {\r
+ mb.loadLocal(storeParameter);\r
+ mb.loadNull();\r
+ mb.storeField(storeClassBuilder.getClassName(), storeHashIndexName, factTypeDesc);\r
+ }\r
+ else {\r
+ mb.loadLocal(storeParameter);\r
+ mb.loadField(storeClassBuilder.getClassName(), storeHashIndexName, CHRHashIndex);\r
+ mb.loadThis();\r
+ mb.invokeVirtual(CHRHashIndex_name, "removeKnownToExistKey", TypeDesc.VOID, Constants.OBJECTS[1]);\r
+ }\r
+ mb.branch(nextIndex);\r
+ \r
+ // else {\r
+ mb.setLocation(else2);\r
+ // bfNext.bfPrev = null;\r
+ mb.loadThis();\r
+ mb.loadField(factClassName, linkedListNext, factTypeDesc);\r
+ mb.loadNull();\r
+ mb.storeField(factClassName, linkedListPrev, factTypeDesc);\r
+ // store.ExampleFact_bfIndex.replaceKnownToExistKey(this, bfNext);\r
+ if(indexInfo.indexMask == 0) {\r
+ mb.loadLocal(storeParameter);\r
+ mb.loadThis();\r
+ mb.loadField(factClassName, linkedListNext, factTypeDesc);\r
+ mb.storeField(storeClassBuilder.getClassName(), storeHashIndexName, factTypeDesc);\r
+ }\r
+ else {\r
+ mb.loadLocal(storeParameter);\r
+ mb.loadField(storeClassBuilder.getClassName(), storeHashIndexName, CHRHashIndex);\r
+ mb.loadThis();\r
+ mb.loadThis();\r
+ mb.loadField(factClassName, linkedListNext, factTypeDesc);\r
+ mb.invokeVirtual(CHRHashIndex_name, "replaceKnownToExistKey", TypeDesc.VOID, Constants.OBJECTS[2]);\r
+ }\r
+ mb.branch(nextIndex);\r
+ // }\r
+ \r
+ // else {\r
+ mb.setLocation(else1);\r
+ // bfPrev.bfNext = bfNext;\r
+ mb.loadThis();\r
+ mb.loadField(factClassName, linkedListPrev, factTypeDesc);\r
+ mb.loadThis();\r
+ mb.loadField(factClassName, linkedListNext, factTypeDesc);\r
+ mb.storeField(factClassName, linkedListNext, factTypeDesc);\r
+ // if(bfNext != null)\r
+ mb.loadThis();\r
+ mb.loadField(factClassName, linkedListNext, factTypeDesc);\r
+ Label else3 = new Label();\r
+ mb.ifNullBranch(else3, true);\r
+ // bfNext.bfPrev = bfPrev;\r
+ mb.loadThis();\r
+ mb.loadField(factClassName, linkedListNext, factTypeDesc);\r
+ mb.loadThis();\r
+ mb.loadField(factClassName, linkedListPrev, factTypeDesc);\r
+ mb.storeField(factClassName, linkedListPrev, factTypeDesc);\r
+ mb.setLocation(else3);\r
+ mb.branch(nextIndex);\r
+ // }\r
+ \r
+ mb.setLocation(nextIndex);\r
+ }\r
+ mb.loadThis();\r
+ mb.loadConstant(-1);\r
+ mb.storeField(factClassName, "id", FACT_ID_TYPE);\r
+ mb.returnVoid();\r
+ mb.finish();\r
+ }\r
+ \r
+ // Method: isAlive\r
+\r
+ {\r
+ // @Override\r
+ // public boolean isAlive() {\r
+ // return id >= 0;\r
+ // }\r
+ \r
+ MethodBuilderBase mb = factClassBuilder.addMethodBase(Opcodes.ACC_PUBLIC, "isAlive", TypeDesc.BOOLEAN, Constants.EMPTY_TYPEDESC_ARRAY);\r
+ if(supportsRemoval) {\r
+ mb.loadThis();\r
+ mb.loadField(factClassName, "id", FACT_ID_TYPE);\r
+\r
+ Label thenBranch = mb.createLabel();\r
+ mb.ifZeroComparisonBranch(thenBranch, "<");\r
+ mb.loadConstant(true);\r
+ mb.returnValue(TypeDesc.BOOLEAN);\r
+\r
+ mb.setLocation(thenBranch);\r
+ mb.loadConstant(false);\r
+ mb.returnValue(TypeDesc.BOOLEAN);\r
+ }\r
+ else {\r
+ mb.loadConstant(true);\r
+ mb.returnValue(TypeDesc.BOOLEAN);\r
+ }\r
+ mb.finish();\r
+ }\r
+ \r
+ // activate parts\r
+ \r
+ THashSet<BoundVar> usedParameters = new THashSet<BoundVar>();\r
+ for(int i=0;i<constraint.plans.size();++i) {\r
+ PrioritizedPlan plan = constraint.plans.get(i);\r
+ MethodBuilder mb = factClassBuilder.addMethod(Opcodes.ACC_PUBLIC, "activate" + i, TypeDesc.BOOLEAN, new TypeDesc[] {storeTypeDesc});\r
+ LocalVariable storeVar = mb.getParameter(0);\r
+ LocalVariable factVar = new LocalVariable(0, factTypeDesc);\r
+ mb.setLocalVariable(ruleset.this_, storeVar);\r
+ mb.setLocalVariable(plan.implementation.getParameters()[0], factVar);\r
+ \r
+ // Set closure parameters\r
+ usedParameters.clear();\r
+ plan.implementation.forValRefs(valRef -> {\r
+ if(valRef.getBinding() instanceof BoundVar)\r
+ usedParameters.add((BoundVar)valRef.getBinding());\r
+ });\r
+ for(int j=0;j<ruleset.parameters.length;++j) {\r
+ BoundVar parameter = ruleset.parameters[j];\r
+ if(!usedParameters.contains(parameter))\r
+ continue;\r
+ mb.loadLocal(storeVar);\r
+ mb.loadField(storeClassBuilder.getClassName(), "p"+j, ruleset.parameterTypeDescs[j]);\r
+ mb.store(parameter);\r
+ }\r
+ \r
+ // Generate code\r
+ //System.out.println("=== activate" + i + " ==========================================================");\r
+ //System.out.println(plan.implementation);\r
+ plan.implementation.markGenerateOnFly();\r
+ plan.implementation.generateCodeWithAlreadyPreparedParameters(mb);\r
+ mb.finish();\r
+ }\r
+ \r
+ // Method: activate\r
+\r
+ {\r
+ // @Override\r
+ // public int activate(Object context, int priority) {\r
+ // return -1;\r
+ // }\r
+ \r
+ MethodBuilderBase mb = factClassBuilder.addMethodBase(Opcodes.ACC_PUBLIC, "activate", TypeDesc.INT, new TypeDesc[] {TypeDesc.OBJECT, TypeDesc.INT});\r
+ Label defaultLabel = mb.createLabel();\r
+ \r
+ if(!constraint.isPassive()) {\r
+ // Check if the fact is alive\r
+ mb.loadThis();\r
+ mb.loadField(factClassName, "id", TypeDesc.INT);\r
+ mb.ifZeroComparisonBranch(defaultLabel, "<");\r
+\r
+ mb.loadLocal(mb.getParameter(0));\r
+ mb.checkCast(storeTypeDesc);\r
+ LocalVariable storeVariable = new LocalVariable(1, storeTypeDesc);\r
+ mb.storeLocal(storeVariable);\r
+\r
+ TIntArrayList priorities = new TIntArrayList(constraint.plans.size());\r
+ ArrayList<Label> labels = new ArrayList<Label>();\r
+ int lastPriority = -1;\r
+ for(PrioritizedPlan plan : constraint.plans)\r
+ if(plan.priority != lastPriority) {\r
+ priorities.add(plan.priority);\r
+ labels.add(mb.createLabel());\r
+ lastPriority = plan.priority;\r
+ }\r
+\r
+ mb.loadLocal(mb.getParameter(1));\r
+ mb.switch_(priorities.toArray(), labels.toArray(new Label[labels.size()]), defaultLabel);\r
+ int labelId = -1;\r
+ for(int i=0;i<constraint.plans.size();++i) {\r
+ PrioritizedPlan plan = constraint.plans.get(i);\r
+ if(labelId == -1 || plan.priority != priorities.get(labelId)) {\r
+ if(labelId >= 0) {\r
+ mb.loadConstant(plan.priority);\r
+ mb.returnValue(TypeDesc.INT);\r
+ }\r
+ ++labelId;\r
+ mb.setLocation(labels.get(labelId));\r
+ }\r
+ mb.loadThis();\r
+ mb.loadLocal(storeVariable);\r
+ mb.invokeVirtual(factClassName, "activate" + i, TypeDesc.BOOLEAN, new TypeDesc[] {storeTypeDesc});\r
+ mb.ifZeroComparisonBranch(defaultLabel, "==");\r
+ }\r
+ mb.setLocation(defaultLabel);\r
+ }\r
+ mb.loadConstant(-1);\r
+ mb.returnValue(TypeDesc.INT);\r
+ mb.finish();\r
+ }\r
+ \r
+ // Constructors\r
+ \r
+ {\r
+ // public ExampleFact(int id, int c0, int c1) {\r
+ // this.id = id; \r
+ // this.c0 = c0;\r
+ // this.c1 = c1;\r
+ // }\r
+ \r
+ TypeDesc[] constructorParameters = new TypeDesc[parameterTypeDescs.length+1];\r
+ constructorParameters[0] = FACT_ID_TYPE;\r
+ for(int i=0;i<parameterTypeDescs.length;++i)\r
+ constructorParameters[i+1] = parameterTypeDescs[i];\r
+ MethodBuilderBase mb = factClassBuilder.addConstructor(Opcodes.ACC_PUBLIC, constructorParameters);\r
+ mb.loadThis();\r
+ mb.invokeConstructor(factClassBuilder.getSuperClassName(), Constants.EMPTY_TYPEDESC_ARRAY);\r
+ mb.loadThis();\r
+ mb.loadLocal(mb.getParameter(0));\r
+ mb.storeField(factClassName, "id", FACT_ID_TYPE);\r
+ for(int i=0;i<constraint.parameterTypes.length;++i) {\r
+ mb.loadThis();\r
+ mb.loadLocal(mb.getParameter(i+1));\r
+ mb.storeField(factClassName, "c" + i, parameterTypeDescs[i]);\r
+ }\r
+ mb.returnVoid();\r
+ mb.finish();\r
+ }\r
+ factClassBuilder.addDefaultConstructor();\r
+ \r
+ moduleBuilder.addClass(factClassBuilder);\r
+ }\r
+\r
+ private static ClassBuilder generateSpecializedHashIndex(ClassBuilder storeClassBuilder, CHRConstraint constraint, IndexInfo indexInfo, TypeDesc factClassTypeDesc, String factClassName) {\r
+ // new CHRHashIndex() {\r
+ // @Override\r
+ // protected boolean keyEquals(Object a, Object b) {\r
+ // return ((ExampleFact)a).c0 == ((ExampleFact)b).c0;\r
+ // }\r
+ // @Override\r
+ // protected int keyHashCode(Object key) {\r
+ // return ((ExampleFact)key).c0;\r
+ // }\r
+ // }\r
+\r
+ ModuleBuilder moduleBuilder = storeClassBuilder.getModuleBuilder();\r
+ JavaTypeTranslator jtt = moduleBuilder.getJavaTypeTranslator();\r
+ \r
+ String hashIndexClassName = factClassName + "$" + indexInfo.indexName; \r
+ ClassBuilder hashIndexClassBuilder = new ClassBuilder(moduleBuilder, Opcodes.ACC_PUBLIC, hashIndexClassName, "org/simantics/scl/runtime/chr/CHRHashIndex");\r
+ \r
+ // Method: keyEquals\r
+\r
+ {\r
+\r
+ // @Override\r
+ // protected boolean keyEquals(Object a, Object b) {\r
+ // return ((ExampleFact)a).c0 == ((ExampleFact)b).c0;\r
+ // }\r
+ \r
+ MethodBuilderBase mb = hashIndexClassBuilder.addMethodBase(Opcodes.ACC_PROTECTED, "keyEquals", TypeDesc.BOOLEAN, Constants.OBJECTS[2]);\r
+ mb.loadLocal(mb.getParameter(0));\r
+ mb.checkCast(factClassTypeDesc);\r
+ LocalVariable aVar = mb.createLocalVariable("a", factClassTypeDesc);\r
+ mb.storeLocal(aVar);\r
+ \r
+ mb.loadLocal(mb.getParameter(1));\r
+ mb.checkCast(factClassTypeDesc);\r
+ LocalVariable bVar = mb.createLocalVariable("b", factClassTypeDesc);\r
+ mb.storeLocal(bVar);\r
+\r
+ Label failure = mb.createLabel();\r
+ \r
+ int curMask = indexInfo.indexMask;\r
+ for(int i=0;i<constraint.parameterTypes.length;++i,curMask>>=1)\r
+ if((curMask&1) == 1) {\r
+ TypeDesc fieldTypeDesc = jtt.toTypeDesc(constraint.parameterTypes[i]);\r
+ if(fieldTypeDesc.equals(TypeDesc.VOID))\r
+ continue;\r
+ mb.loadLocal(aVar);\r
+ mb.loadField(factClassName, "c"+i, fieldTypeDesc);\r
+ \r
+ mb.loadLocal(bVar);\r
+ mb.loadField(factClassName, "c"+i, fieldTypeDesc);\r
+\r
+ CodeBuilderUtils.equals(mb, fieldTypeDesc, failure);\r
+ }\r
+ mb.loadConstant(true);\r
+ mb.returnValue(TypeDesc.BOOLEAN);\r
+ \r
+ mb.setLocation(failure);\r
+ mb.loadConstant(false);\r
+ mb.returnValue(TypeDesc.BOOLEAN);\r
+ mb.finish();\r
+ }\r
+ \r
+ // Method: keyHashCode\r
+\r
+ {\r
+ // @Override\r
+ // protected int keyHashCode(Object key) {\r
+ // return (0x811C9DC5^((ExampleFact)key).c0)*16777619;\r
+ // }\r
+ \r
+ MethodBuilderBase mb = hashIndexClassBuilder.addMethodBase(Opcodes.ACC_PROTECTED, "keyHashCode", TypeDesc.INT, Constants.OBJECTS[1]);\r
+ mb.loadLocal(mb.getParameter(0));\r
+ mb.checkCast(factClassTypeDesc);\r
+ LocalVariable factVar = mb.createLocalVariable("fact", factClassTypeDesc);\r
+ mb.storeLocal(factVar);\r
+\r
+ mb.loadConstant(0x811C9DC5);\r
+\r
+ int curMask = indexInfo.indexMask;\r
+ for(int i=0;i<constraint.parameterTypes.length;++i,curMask>>=1)\r
+ if((curMask&1) == 1) {\r
+ TypeDesc fieldTypeDesc = jtt.toTypeDesc(constraint.parameterTypes[i]);\r
+ if(fieldTypeDesc.equals(TypeDesc.VOID))\r
+ continue;\r
+ mb.loadLocal(factVar);\r
+ mb.loadField(factClassName, "c"+i, fieldTypeDesc);\r
+ CodeBuilderUtils.hashCode(mb, fieldTypeDesc);\r
+ mb.math(Opcodes.IXOR);\r
+ mb.loadConstant(16777619);\r
+ mb.math(Opcodes.IMUL);\r
+\r
+ }\r
+ mb.returnValue(TypeDesc.INT);\r
+ mb.finish();\r
+ }\r
+\r
+ hashIndexClassBuilder.addDefaultConstructor();\r
+ \r
+ return hashIndexClassBuilder;\r
+ }\r
+}\r
--- /dev/null
+package org.simantics.scl.compiler.internal.codegen.chr;\r
+\r
+import org.simantics.scl.runtime.chr.CHRHashIndex;\r
+import org.simantics.scl.runtime.chr.Fact;\r
+import org.simantics.scl.runtime.chr.FactActivationQueue;\r
+\r
+public class ExampleStore {\r
+ /*\r
+ * constraint ExampleFact Integer Integer where\r
+ * index(bf)\r
+ * \r
+ * =>\r
+ * \r
+ * data Store // class Module$123\r
+ * data ExampleFact // class Module$123/ExampleFact\r
+ * \r
+ * add :: Store -> ExampleFact -> <Proc> ()\r
+ * remove :: Store -> ExampleFact -> <Proc> ()\r
+ * get_bf :: Store -> Integer -> <Proc> ExampleFact\r
+ * next_bf :: ExampleFact -> <Proc> Maybe ExampleFact\r
+ * idOf :: ExampleFact -> <Proc> Integer\r
+ * isAlive :: ExampleFact -> <Proc> Boolean\r
+ */\r
+ \r
+ CHRHashIndex ExampleFact_bfIndex = new CHRHashIndex() {\r
+ @Override\r
+ protected boolean keyEquals(Object a, Object b) {\r
+ return ((ExampleFact)a).c0 == ((ExampleFact)b).c0;\r
+ }\r
+ @Override\r
+ protected int keyHashCode(Object key) {\r
+ return ((ExampleFact)key).c0;\r
+ }\r
+ };\r
+ \r
+ public FactActivationQueue queue = new FactActivationQueue(2);\r
+ \r
+ private ExampleFact ExampleFact_temp = new ExampleFact();\r
+ \r
+ public ExampleFact getExampleFact_bf(int c0) {\r
+ ExampleFact_temp.c0 = c0;\r
+ return (ExampleFact)ExampleFact_bfIndex.getEqual(ExampleFact_temp);\r
+ }\r
+ \r
+ public static class ExampleFact implements Fact {\r
+ public int id;\r
+ public int c0; // key\r
+ public int c1;\r
+ public ExampleFact bfPrev;\r
+ public ExampleFact bfNext;\r
+ \r
+ public ExampleFact() {\r
+ }\r
+ \r
+ public ExampleFact(int c0, int c1) {\r
+ this.c0 = c0;\r
+ this.c1 = c1;\r
+ }\r
+ \r
+ public void add(ExampleStore store) {\r
+ bfNext = (ExampleFact)store.ExampleFact_bfIndex.addFreshAndReturnOld(this);\r
+ if(bfNext != null)\r
+ bfNext.bfPrev = this;\r
+ }\r
+ \r
+ public void remove(ExampleStore store) {\r
+ if(bfPrev == null) {\r
+ if(bfNext == null)\r
+ store.ExampleFact_bfIndex.removeKnownToExistKey(this);\r
+ else {\r
+ bfNext.bfPrev = null;\r
+ store.ExampleFact_bfIndex.replaceKnownToExistKey(this, bfNext);\r
+ }\r
+ }\r
+ else {\r
+ bfPrev.bfNext = bfNext;\r
+ if(bfNext != null)\r
+ bfNext.bfPrev = bfPrev;\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public int activate(Object context, int priority) {\r
+ return -1;\r
+ }\r
+\r
+ @Override\r
+ public boolean isAlive() {\r
+ return id >= 0;\r
+ }\r
+ }\r
+\r
+}\r
package org.simantics.scl.compiler.internal.codegen.optimization;\r
\r
import org.simantics.scl.compiler.common.names.Name;\r
+import org.simantics.scl.compiler.common.names.Names;\r
import org.simantics.scl.compiler.constants.SCLConstant;\r
import org.simantics.scl.compiler.internal.codegen.analysis.StatementBrowser;\r
import org.simantics.scl.compiler.internal.codegen.references.BoundVar;\r
\r
public enum FoldlBuildFusion implements Optimization {\r
INSTANCE;\r
-\r
- private static final Name BUILD = Name.create("Prelude", "build");\r
\r
private static class Analysis extends StatementBrowser {\r
\r
Val buildFunction = buildApplication.getFunction().getBinding();\r
if(!(buildFunction instanceof SCLConstant))\r
return;\r
- if(((SCLConstant)buildFunction).getName() != BUILD)\r
+ if(((SCLConstant)buildFunction).getName() != Names.Prelude_build)\r
return;\r
}\r
\r
package org.simantics.scl.compiler.internal.codegen.optimization;\r
\r
import org.simantics.scl.compiler.common.names.Name;\r
+import org.simantics.scl.compiler.common.names.Names;\r
\r
import gnu.trove.map.hash.THashMap;\r
\r
public static final THashMap<Name, Optimization> OPTIMIZATIONS = new THashMap<Name, Optimization>();\r
\r
static {\r
- OPTIMIZATIONS.put(Name.create("Prelude", "foldl"), FoldlBuildFusion.INSTANCE);\r
+ OPTIMIZATIONS.put(Names.Prelude_foldl, FoldlBuildFusion.INSTANCE);\r
}\r
\r
}\r
return occurrence;\r
}\r
\r
- private void replaceBy(Val other) {\r
+ public void replaceBy(Val other) {\r
ValRef cur = occurrence;\r
if(cur != null) {\r
while(true) {\r
import org.simantics.scl.compiler.internal.codegen.utils.SSALambdaLiftingContext;\r
import org.simantics.scl.compiler.internal.codegen.utils.SSASimplificationContext;\r
import org.simantics.scl.compiler.internal.codegen.utils.SSAValidationContext;\r
+import org.simantics.scl.compiler.internal.codegen.utils.ValRefVisitor;\r
import org.simantics.scl.compiler.top.SCLCompilerConfiguration;\r
import org.simantics.scl.compiler.types.TVar;\r
import org.simantics.scl.compiler.types.Type;\r
stat.prepare(mb);\r
exit.prepare(mb);\r
}\r
+\r
+ public void forValRefs(ValRefVisitor visitor) {\r
+ for(SSAStatement statement = firstStatement;\r
+ statement != null; statement = statement.next)\r
+ statement.forValRefs(visitor);\r
+ exit.forValRefs(visitor);\r
+ }\r
\r
}\r
--- /dev/null
+package org.simantics.scl.compiler.internal.codegen.ssa;\r
+\r
+import java.util.ArrayList;\r
+\r
+import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
+import org.simantics.scl.compiler.constants.Constant;\r
+import org.simantics.scl.compiler.internal.codegen.references.BoundVar;\r
+import org.simantics.scl.compiler.internal.codegen.references.Val;\r
+import org.simantics.scl.compiler.internal.codegen.references.ValRef;\r
+import org.simantics.scl.compiler.internal.codegen.ssa.binders.BoundVarBinder;\r
+import org.simantics.scl.compiler.internal.codegen.ssa.binders.ClosureBinder;\r
+import org.simantics.scl.compiler.internal.codegen.utils.CopyContext;\r
+import org.simantics.scl.compiler.internal.codegen.utils.ModuleBuilder;\r
+import org.simantics.scl.compiler.internal.codegen.utils.Printable;\r
+import org.simantics.scl.compiler.internal.codegen.utils.SSALambdaLiftingContext;\r
+import org.simantics.scl.compiler.internal.codegen.utils.SSASimplificationContext;\r
+import org.simantics.scl.compiler.internal.codegen.utils.SSAValidationContext;\r
+import org.simantics.scl.compiler.internal.codegen.utils.ValRefVisitor;\r
+import org.simantics.scl.compiler.types.TVar;\r
+import org.simantics.scl.compiler.types.Type;\r
+\r
+public abstract class SSAClosure implements Printable, BoundVarBinder{ \r
+ Val target;\r
+ \r
+ ClosureBinder parent;\r
+ SSAClosure prev;\r
+ SSAClosure next;\r
+ \r
+ public void setParent(ClosureBinder parent) {\r
+ this.parent = parent;\r
+ }\r
+\r
+ public SSAClosure getNext() {\r
+ return next;\r
+ }\r
+\r
+ public void setPrev(SSAClosure function) {\r
+ this.prev = function;\r
+ }\r
+\r
+ public void setNext(SSAClosure function) {\r
+ this.next = function;\r
+ }\r
+\r
+ public SSAFunction getParentFunction() {\r
+ return parent.getParentFunction();\r
+ }\r
+ \r
+ public ClosureBinder getParent() {\r
+ return parent;\r
+ }\r
+\r
+ public Val getTarget() {\r
+ return target;\r
+ }\r
+ \r
+ public void setTarget(Val target) {\r
+ this.target = target;\r
+ if(target instanceof BoundVar)\r
+ ((BoundVar) target).parent = this; \r
+ }\r
+ \r
+ public void setTarget(BoundVar target) {\r
+ this.target = target;\r
+ target.parent = this; \r
+ }\r
+ \r
+ public void detach() {\r
+ if(prev == null)\r
+ parent.setFirstClosure(next);\r
+ else\r
+ prev.next = next;\r
+ if(next != null)\r
+ next.prev = prev;\r
+ }\r
+ \r
+ public void remove() {\r
+ destroy();\r
+ detach();\r
+ }\r
+\r
+ public SSAClosure copy() {\r
+ return copy(new CopyContext());\r
+ }\r
+ \r
+ public abstract void destroy();\r
+ public abstract SSAClosure copy(CopyContext context);\r
+ public abstract void markGenerateOnFly();\r
+ public abstract void replace(TVar[] vars, Type[] replacements);\r
+ public abstract void collectFreeVariables(ArrayList<ValRef> freeVars);\r
+ public abstract void simplify(SSASimplificationContext context);\r
+ public abstract void validate(SSAValidationContext context);\r
+ public abstract void lambdaLift(SSALambdaLiftingContext context);\r
+ public abstract boolean isValue();\r
+ public abstract Type getType();\r
+ public abstract void parametrize(BoundVar[] parameters);\r
+\r
+ public Constant liftClosure(BoundVar newTarget, BoundVar[] newVarsList) {\r
+ throw new InternalCompilerError("Unsupported method liftClosure");\r
+ }\r
+\r
+ public void generateCode(ModuleBuilder moduleBuilder) {\r
+ throw new InternalCompilerError("Unsupported method generateCode");\r
+ }\r
+\r
+ public abstract void forValRefs(ValRefVisitor visitor);\r
+ \r
+}\r
import org.simantics.scl.compiler.internal.codegen.utils.PrintingContext;\r
import org.simantics.scl.compiler.internal.codegen.utils.SSASimplificationContext;\r
import org.simantics.scl.compiler.internal.codegen.utils.SSAValidationContext;\r
+import org.simantics.scl.compiler.internal.codegen.utils.ValRefVisitor;\r
import org.simantics.scl.compiler.types.TVar;\r
import org.simantics.scl.compiler.types.Type;\r
import org.simantics.scl.compiler.types.Types;\r
\r
public void prepare(MethodBuilder mb) {\r
}\r
+\r
+ public abstract void forValRefs(ValRefVisitor visitor);\r
}
\ No newline at end of file
import org.simantics.scl.compiler.internal.codegen.references.BoundVar;
import org.simantics.scl.compiler.internal.codegen.references.Val;
import org.simantics.scl.compiler.internal.codegen.references.ValRef;
-import org.simantics.scl.compiler.internal.codegen.ssa.binders.BoundVarBinder;
-import org.simantics.scl.compiler.internal.codegen.ssa.binders.FunctionBinder;
import org.simantics.scl.compiler.internal.codegen.ssa.exits.Jump;
import org.simantics.scl.compiler.internal.codegen.ssa.statements.LetApply;
import org.simantics.scl.compiler.internal.codegen.ssa.statements.LetFunctions;
import org.simantics.scl.compiler.internal.codegen.types.JavaTypeTranslator;
import org.simantics.scl.compiler.internal.codegen.utils.CopyContext;
import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder;
-import org.simantics.scl.compiler.internal.codegen.utils.Printable;
import org.simantics.scl.compiler.internal.codegen.utils.PrintingContext;
import org.simantics.scl.compiler.internal.codegen.utils.SSALambdaLiftingContext;
import org.simantics.scl.compiler.internal.codegen.utils.SSASimplificationContext;
import org.simantics.scl.compiler.internal.codegen.utils.SSAValidationContext;
+import org.simantics.scl.compiler.internal.codegen.utils.ValRefVisitor;
import org.simantics.scl.compiler.types.TVar;
import org.simantics.scl.compiler.types.Type;
import org.simantics.scl.compiler.types.Types;
-public final class SSAFunction implements Printable, BoundVarBinder {
- Val target;
-
+public final class SSAFunction extends SSAClosure {
TVar[] typeParameters;
Type effect;
SSABlock firstBlock;
SSABlock lastBlock;
- ReturnCont returnCont;
-
- FunctionBinder parent;
- SSAFunction prev;
- SSAFunction next;
+ ReturnCont returnCont;
public SSAFunction(TVar[] typeParameters, Type effect, Type returnType) {
this(typeParameters, effect, new ReturnCont(returnType));
this.effect = Types.canonical(effect);
returnCont.setParent(this);
}
-
- public Val getTarget() {
- return target;
- }
-
- public void setTarget(Val target) {
- this.target = target;
- if(target instanceof BoundVar)
- ((BoundVar) target).parent = this;
- }
-
- public void setTarget(BoundVar target) {
- this.target = target;
- target.parent = this;
- }
public boolean hasEffect() {
return effect != Types.NO_EFFECTS;
for(int i=0,j=0;i<firstBlock.parameters.length;++i)
if(!tt.toTypeDesc(firstBlock.parameters[i].getType()).equals(TypeDesc.VOID))
mb.setLocalVariable(firstBlock.parameters[i], mb.getParameter(j++));
+ generateCodeWithAlreadyPreparedParameters(mb);
+ }
+
+ public void generateCodeWithAlreadyPreparedParameters(MethodBuilder mb) {
for(SSABlock block = firstBlock; block != null; block = block.next)
block.prepare(mb);
firstBlock.generateCode(mb);
//context.reset(); // FIXME not good when there are nested functions
}
- public void simplify(SSASimplificationContext context) {
- /*if(target instanceof BoundVar) {
- tryToMakeMonadic(context);
- }*/
+ @Override
+ public void simplify(SSASimplificationContext context) {
for(SSABlock block = firstBlock; block != null; block = block.next)
block.simplify(context);
if(firstBlock == lastBlock && firstBlock.firstStatement == firstBlock.lastStatement &&
private void simplifySingleLambda(SSASimplificationContext context) {
LetFunctions letF = (LetFunctions)firstBlock.firstStatement;
- SSAFunction f = letF.getFirstFunction();
+ if(!(letF.getFirstClosure() instanceof SSAFunction))
+ return;
+ SSAFunction f = (SSAFunction)letF.getFirstClosure();
if(f.getNext() != null)
return;
Val fVal = f.getTarget();
this.returnCont = returnCont;
returnCont.setParent(this);
}
-
- /*public void tryToMakeMonadic(SSASimplificationContext context) {
- if(monadic)
- return;
- if(!Types.isApply(BTypes.PROC, 1, getReturnType()))
- return;
- for(ValRef ref = target.getOccurrence(); ref != null; ref = ref.getNext()) {
- ValRefBinder parent = ref.getParent();
- if(!(parent instanceof LetApply))
- return;
- LetApply apply = (LetApply)parent;
- if(apply.getFunction() != ref)
- return;
- if(apply.getParameters().length != getParameters().length)
- return;
- if(!apply.hasEffect())
- return;
- }
- makeMonadic(context);
- }*/
-
- /*private void makeMonadic(SSASimplificationContext context) {
- Type oldReturnType = returnCont.getType();
- Type newReturnType;
- try {
- newReturnType = Types.matchApply(BTypes.PROC, oldReturnType);
- } catch (MatchException e) {
- throw new InternalCompilerError();
- }
-
- //
- returnCont.setType(newReturnType);
- monadic = true;
-
- //
- SSABlock block = new SSABlock(oldReturnType);
- addBlock(block);
-
- returnCont.replaceWith(block);
-
- BoundVar x = new BoundVar(newReturnType);
- LetApply apply = new LetApply(x, block.parameters[0].createOccurrence());
- apply.setMonadic(true);
- block.addStatement(apply);
-
- block.setExit(new Jump(returnCont.createOccurrence(), x.createOccurrence()));
- context.markModified("SSAFunction.make-monadic");
- }*/
public ValRef isEqualToConstant() {
if(firstBlock.parameters.length > 0)
return firstBlock.parameters.length;
}
+ @Override
public void markGenerateOnFly() {
for(SSABlock block = firstBlock; block != null; block = block.next)
block.markGenerateOnFly();
}
- public SSAFunction copy(CopyContext context) {
+ @Override
+ public SSAClosure copy(CopyContext context) {
TVar[] newTypeParameters = context.copyParameters(typeParameters);
SSAFunction newFunction = new SSAFunction(newTypeParameters, effect, context.copy(returnCont));
for(SSABlock block = firstBlock;
newFunction.addBlock(context.copy(block));
return newFunction;
}
-
- public SSAFunction copy() {
- return copy(new CopyContext());
- }
-
+
+ @Override
public void replace(TVar[] vars, Type[] replacements) {
returnCont.replace(vars, replacements);
for(SSABlock block = firstBlock;
this.typeParameters = typeParameters;
}
+ @Override
public Type getType() {
Type type = returnCont.getType();
type = Types.functionE(
return returnCont.getType();
}
+ @Override
public void destroy() {
for(SSABlock block = firstBlock;
block != null; block = block.next)
block.destroy();
}
- public void detach() {
- if(prev == null)
- parent.setFirstFunction(next);
- else
- prev.next = next;
- if(next != null)
- next.prev = prev;
- }
-
- public void remove() {
- destroy();
- detach();
- }
-
- public void addSibling(SSAFunction function) {
- function.parent = parent;
- function.next = next;
- function.prev = this;
-
- next.prev = function;
- next = function;
- }
-
- public SSAFunction getNext() {
- return next;
- }
-
- public void setParent(FunctionBinder parent) {
- this.parent = parent;
- }
-
- public void setPrev(SSAFunction function) {
- this.prev = function;
- }
-
- public void setNext(SSAFunction function) {
- this.next = function;
- }
-
+ @Override
public void collectFreeVariables(ArrayList<ValRef> vars) {
for(SSABlock block = firstBlock;
block != null; block = block.next)
block.collectFreeVariables(this, vars);
}
-
- @Override
- public SSAFunction getParentFunction() {
- return parent.getParentFunction();
- }
-
- public FunctionBinder getParent() {
- return parent;
- }
+ @Override
public void lambdaLift(SSALambdaLiftingContext context) {
for(SSABlock block = firstBlock;
block != null; block = block.next)
block.lambdaLift(context);
}
- public void addParametersInFront(BoundVar[] parameters) {
+ @Override
+ public void parametrize(BoundVar[] parameters) {
Cont proxy = null;
for(ContRef ref = firstBlock.getOccurrence(); ref != null; ref = ref.getNext())
proxy = ref.addParametersInFront(parameters, firstBlock.parameters, proxy);
return effect;
}
- public int getBlockCount() {
- int count = 0;
- for(SSABlock block = firstBlock;block != null;block = block.next)
- ++count;
- return count;
+ @Override
+ public boolean isValue() {
+ return getArity() == 0;
+ }
+
+ @Override
+ public void forValRefs(ValRefVisitor visitor) {
+ for(SSABlock block = firstBlock;
+ block != null; block = block.next)
+ block.forValRefs(visitor);
}
}
import org.simantics.scl.compiler.internal.codegen.utils.SSASimplificationContext;
import org.simantics.scl.compiler.internal.codegen.utils.SSAValidationContext;
import org.simantics.scl.compiler.top.SCLCompilerConfiguration;
-import org.simantics.scl.compiler.types.Type;
-import org.simantics.scl.runtime.tuple.Tuple2;
import gnu.trove.map.hash.THashMap;
import gnu.trove.procedure.TObjectObjectProcedure;
public class SSAModule {
THashMap<Name, SCLConstant> functions = new THashMap<Name, SCLConstant>();
- ArrayList<Tuple2> staticFields = new ArrayList<Tuple2>();
+ ArrayList<StaticField> staticFields = new ArrayList<StaticField>();
+ public ArrayList<SSAClosure> closuresToGenerate = new ArrayList<SSAClosure>();
public void put(Name name, SCLConstant function) {
functions.put(name, function);
});
JavaTypeTranslator javaTypeTranslator = moduleBuilder.getJavaTypeTranslator();
- for(Tuple2 tuple : staticFields) {
- classFile.addField(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, (String)tuple.c0,
- javaTypeTranslator.toTypeDesc((Type)tuple.c1));
+ for(StaticField tuple : staticFields) {
+ classFile.addField(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, tuple.name,
+ javaTypeTranslator.toTypeDesc(tuple.type));
}
classFile.addDefaultConstructor();
moduleBuilder.addClass(classFile);
+
+ for(SSAClosure closure : closuresToGenerate)
+ closure.generateCode(moduleBuilder);
}
/**
});
}
- public void addStaticField(Tuple2 tuple) {
+ public void addStaticField(StaticField tuple) {
staticFields.add(tuple);
}
--- /dev/null
+package org.simantics.scl.compiler.internal.codegen.ssa;\r
+\r
+import java.util.ArrayList;\r
+\r
+import org.simantics.scl.compiler.internal.codegen.references.BoundVar;\r
+import org.simantics.scl.compiler.internal.codegen.references.ValRef;\r
+import org.simantics.scl.compiler.internal.codegen.ssa.binders.ClosureBinder;\r
+import org.simantics.scl.compiler.internal.codegen.utils.CopyContext;\r
+import org.simantics.scl.compiler.internal.codegen.utils.PrintingContext;\r
+import org.simantics.scl.compiler.internal.codegen.utils.SSALambdaLiftingContext;\r
+import org.simantics.scl.compiler.internal.codegen.utils.SSASimplificationContext;\r
+import org.simantics.scl.compiler.internal.codegen.utils.SSAValidationContext;\r
+import org.simantics.scl.compiler.internal.codegen.utils.ValRefVisitor;\r
+import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;\r
+import org.simantics.scl.compiler.internal.codegen.writer.ModuleWriter;\r
+import org.simantics.scl.compiler.types.TVar;\r
+import org.simantics.scl.compiler.types.Type;\r
+\r
+public class SSAObject extends SSAClosure implements ClosureBinder {\r
+ Type type;\r
+ SSAClosure firstClosure;\r
+ \r
+ public SSAObject(Type type) {\r
+ this.type = type;\r
+ }\r
+\r
+ @Override\r
+ public void toString(PrintingContext context) {\r
+ for(SSAClosure closure = firstClosure; closure != null; closure = closure.getNext()) {\r
+ context.indentation();\r
+ context.append(closure.getTarget());\r
+ context.append("(" + closure.getTarget().occurrenceCount() + ")");\r
+ context.append(" :: ");\r
+ context.append(closure.getTarget().getType());\r
+ context.append(" = \n");\r
+ context.indent();\r
+ closure.toString(context);\r
+ context.dedent();\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public SSAClosure getFirstClosure() {\r
+ return firstClosure;\r
+ }\r
+ \r
+ @Override\r
+ public void setFirstClosure(SSAClosure function) {\r
+ this.firstClosure = function; \r
+ if(function == null)\r
+ detach();\r
+ }\r
+ \r
+ @Override\r
+ public void destroy() {\r
+ for(SSAClosure closure = firstClosure; closure != null; closure = closure.getNext())\r
+ closure.destroy();\r
+ }\r
+\r
+ @Override\r
+ public SSAClosure copy(CopyContext context) {\r
+ SSAObject result = new SSAObject(context.copyType(type));\r
+ for(SSAClosure closure = firstClosure; closure != null; closure = closure.getNext()) {\r
+ SSAClosure newFunction = closure.copy(context);\r
+ newFunction.setTarget(context.copy(closure.getTarget()));\r
+ result.addClosure(newFunction);\r
+ }\r
+ return result; \r
+ }\r
+\r
+ public void addClosure(SSAClosure closure) {\r
+ closure.setParent(this); \r
+ closure.setNext(firstClosure);\r
+ if(firstClosure != null)\r
+ firstClosure.setPrev(closure);\r
+ firstClosure = closure;\r
+ }\r
+ \r
+ @Override\r
+ public void markGenerateOnFly() {\r
+ for(SSAClosure closure = firstClosure; closure != null; closure = closure.getNext())\r
+ closure.markGenerateOnFly();\r
+ }\r
+\r
+ @Override\r
+ public void replace(TVar[] vars, Type[] replacements) {\r
+ for(SSAClosure closure = firstClosure; closure != null; closure = closure.getNext())\r
+ closure.replace(vars, replacements);\r
+ }\r
+\r
+ @Override\r
+ public void collectFreeVariables(ArrayList<ValRef> freeVars) {\r
+ for(SSAClosure closure = firstClosure; closure != null; closure = closure.getNext())\r
+ closure.collectFreeVariables(freeVars);\r
+ }\r
+\r
+ @Override\r
+ public void simplify(SSASimplificationContext context) {\r
+ for(SSAClosure closure = firstClosure; closure != null; closure = closure.getNext())\r
+ closure.simplify(context);\r
+ }\r
+\r
+ @Override\r
+ public void validate(SSAValidationContext context) {\r
+ for(SSAClosure closure = firstClosure; closure != null; closure = closure.getNext())\r
+ closure.validate(context);\r
+ }\r
+\r
+ @Override\r
+ public void lambdaLift(SSALambdaLiftingContext context) {\r
+ for(SSAClosure closure = firstClosure; closure != null; closure = closure.getNext())\r
+ closure.lambdaLift(context);\r
+ }\r
+\r
+ @Override\r
+ public boolean isValue() {\r
+ return false;\r
+ }\r
+\r
+ @Override\r
+ public void parametrize(BoundVar[] parameters) {\r
+ // TODO Auto-generated method stub\r
+ \r
+ }\r
+\r
+ @Override\r
+ public Type getType() {\r
+ return type;\r
+ }\r
+ \r
+ public CodeWriter createMethod(ModuleWriter moduleWriter, TVar[] typeParameters, Type effect, Type returnType, Type[] parameterTypes) {\r
+ SSAFunction function = new SSAFunction(typeParameters, effect, returnType);\r
+ SSABlock block = new SSABlock(parameterTypes);\r
+ function.addBlock(block);\r
+ BoundVar target = new BoundVar(function.getType());\r
+ function.setTarget(target);\r
+ addClosure(function);\r
+ return new CodeWriter(moduleWriter, block);\r
+ }\r
+\r
+ @Override\r
+ public void forValRefs(ValRefVisitor visitor) {\r
+ for(SSAClosure closure = firstClosure; closure != null; closure = closure.getNext())\r
+ closure.forValRefs(visitor);\r
+ }\r
+\r
+}\r
import org.simantics.scl.compiler.internal.codegen.utils.SSALambdaLiftingContext;\r
import org.simantics.scl.compiler.internal.codegen.utils.SSASimplificationContext;\r
import org.simantics.scl.compiler.internal.codegen.utils.SSAValidationContext;\r
+import org.simantics.scl.compiler.internal.codegen.utils.ValRefVisitor;\r
import org.simantics.scl.compiler.types.TVar;\r
import org.simantics.scl.compiler.types.Type;\r
import org.simantics.scl.compiler.types.Types;\r
\r
public void prepare(MethodBuilder mb) { \r
}\r
+\r
+ public abstract void forValRefs(ValRefVisitor visitor);\r
}\r
--- /dev/null
+package org.simantics.scl.compiler.internal.codegen.ssa;\r
+\r
+import org.simantics.scl.compiler.types.Type;\r
+\r
+public class StaticField {\r
+ public final String name;\r
+ public final Type type;\r
+ \r
+ public StaticField(String name, Type type) {\r
+ this.name = name;\r
+ this.type = type;\r
+ }\r
+}\r
--- /dev/null
+package org.simantics.scl.compiler.internal.codegen.ssa.binders;\r
+\r
+import org.simantics.scl.compiler.internal.codegen.ssa.SSAClosure;\r
+import org.simantics.scl.compiler.internal.codegen.ssa.SSAFunction;\r
+\r
+public interface ClosureBinder {\r
+ SSAClosure getFirstClosure();\r
+ void setFirstClosure(SSAClosure function);\r
+ SSAFunction getParentFunction();\r
+}\r
+++ /dev/null
-package org.simantics.scl.compiler.internal.codegen.ssa.binders;\r
-\r
-import org.simantics.scl.compiler.internal.codegen.ssa.SSAFunction;\r
-\r
-public interface FunctionBinder {\r
- SSAFunction getFirstFunction();\r
- void setFirstFunction(SSAFunction function);\r
- SSAFunction getParentFunction();\r
-}\r
import org.objectweb.asm.Label;
import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
import org.simantics.scl.compiler.constants.BooleanConstant;
+import org.simantics.scl.compiler.constants.ComparisonFunction;
import org.simantics.scl.compiler.internal.codegen.continuations.Cont;
import org.simantics.scl.compiler.internal.codegen.continuations.ContRef;
+import org.simantics.scl.compiler.internal.codegen.references.BoundVar;
import org.simantics.scl.compiler.internal.codegen.references.Val;
import org.simantics.scl.compiler.internal.codegen.references.ValRef;
import org.simantics.scl.compiler.internal.codegen.ssa.SSABlock;
import org.simantics.scl.compiler.internal.codegen.ssa.SSAExit;
import org.simantics.scl.compiler.internal.codegen.ssa.SSAFunction;
import org.simantics.scl.compiler.internal.codegen.ssa.binders.ValRefBinder;
+import org.simantics.scl.compiler.internal.codegen.ssa.statements.LetApply;
import org.simantics.scl.compiler.internal.codegen.utils.CopyContext;
import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder;
import org.simantics.scl.compiler.internal.codegen.utils.PrintingContext;
import org.simantics.scl.compiler.internal.codegen.utils.SSASimplificationContext;
import org.simantics.scl.compiler.internal.codegen.utils.SSAValidationContext;
+import org.simantics.scl.compiler.internal.codegen.utils.ValRefVisitor;
import org.simantics.scl.compiler.types.TVar;
import org.simantics.scl.compiler.types.Type;
import org.simantics.scl.compiler.types.Types;
@Override
public void generateCode(MethodBuilder mb) {
+ Val binding = condition.getBinding();
+ simplifyTestCode: if(binding instanceof BoundVar) {
+ BoundVar boundVar = (BoundVar)binding;
+ if(!boundVar.generateOnFly)
+ break simplifyTestCode;
+ LetApply apply = (LetApply)boundVar.getParent();
+ Val function = apply.getFunction().getBinding();
+ if(!(function instanceof ComparisonFunction))
+ break simplifyTestCode;
+
+ Val[] ps = ValRef.getBindings(apply.getParameters());
+ ((ComparisonFunction)function).generateCondition(mb, ps, thenTarget.getBinding(), elseTarget.getBinding());
+ return;
+ }
mb.push(condition.getBinding(), Types.BOOLEAN);
Label elseLabel = mb.getLabel(elseTarget.getBinding());
mb.ifZeroComparisonBranch(elseLabel, "==");
return SSABlock.EMPTY_ARRAY;
}
}
+
+ @Override
+ public void forValRefs(ValRefVisitor visitor) {
+ visitor.visit(condition);
+ }
}
import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder;\r
import org.simantics.scl.compiler.internal.codegen.utils.PrintingContext;\r
import org.simantics.scl.compiler.internal.codegen.utils.SSAValidationContext;\r
+import org.simantics.scl.compiler.internal.codegen.utils.ValRefVisitor;\r
import org.simantics.scl.compiler.types.TVar;\r
import org.simantics.scl.compiler.types.Type;\r
\r
else\r
return SSABlock.EMPTY_ARRAY;\r
}\r
+\r
+ @Override\r
+ public void forValRefs(ValRefVisitor visitor) {\r
+ for(ValRef parameter : parameters)\r
+ visitor.visit(parameter);\r
+ }\r
}\r
import org.objectweb.asm.Label;
import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
import org.simantics.scl.compiler.constants.BooleanConstant;
+import org.simantics.scl.compiler.constants.IntegerConstant;
import org.simantics.scl.compiler.internal.codegen.continuations.BranchRef;
import org.simantics.scl.compiler.internal.codegen.continuations.Cont;
import org.simantics.scl.compiler.internal.codegen.continuations.ContRef;
import org.simantics.scl.compiler.internal.codegen.utils.PrintingContext;
import org.simantics.scl.compiler.internal.codegen.utils.SSASimplificationContext;
import org.simantics.scl.compiler.internal.codegen.utils.SSAValidationContext;
+import org.simantics.scl.compiler.internal.codegen.utils.ValRefVisitor;
import org.simantics.scl.compiler.types.TVar;
import org.simantics.scl.compiler.types.Type;
import org.simantics.scl.compiler.types.Types;
public BranchRef[] getBranches() {
return branches;
}
+
+ private boolean isIntegerSwitch() {
+ if(scrutinee.getType() != Types.INTEGER)
+ return false;
+ for(BranchRef branch : branches)
+ if(branch.constructor != null && !(branch.constructor instanceof IntegerConstant))
+ return false;
+ return true;
+ }
+
+ private void generateIntegerSwitch(MethodBuilder mb) {
+ int defaultId;
+ for(defaultId=0;defaultId<branches.length-1&&branches[defaultId].constructor!=null;++defaultId);
+ int[] values = new int[defaultId];
+ Label[] labels = new Label[defaultId];
+ Cont[] continuations = new Cont[defaultId+1];
+ for(int i=0;i<defaultId;++i) {
+ values[i] = ((IntegerConstant)branches[i].constructor).getValue();
+ Cont cont = branches[i].cont.getBinding();
+ labels[i] = mb.getLabel(cont);
+ continuations[i] = cont;
+ }
+ Label defaultLabel;
+ {
+ Cont cont = branches[defaultId].cont.getBinding();
+ defaultLabel = mb.getLabel(cont);
+ continuations[defaultId] = cont;
+ }
+ mb.push(scrutinee, Types.INTEGER);
+ mb.switch_(values, labels, defaultLabel);
+ for(Cont cont : continuations)
+ mb.ensureExists(cont);
+ }
@Override
public void generateCode(MethodBuilder mb) {
+ if(isIntegerSwitch()) {
+ generateIntegerSwitch(mb);
+ return;
+ }
for(int i=0;i<branches.length;++i) {
BranchRef branch = branches[i];
- if(branch.constructor == null) {
+ if(branch.constructor == null)
mb.jump(branch.cont);
- }
else if(i < branches.length-1) {
Label failure = mb.createLabel();
branch.constructor.deconstruct(mb, scrutinee,
branch.cont.getBinding(), failure);
mb.setLocation(failure);
}
- else {
+ else
branch.constructor.deconstruct(mb, scrutinee,
branch.cont.getBinding(), null);
- }
}
}
Cont cont = branch.cont.getBinding();
if(cont instanceof SSABlock) {
SSABlock block = (SSABlock)cont;
- if(cont.hasMoreThanOneOccurences()) {
+ //if(cont.hasMoreThanOneOccurences()) {
context.append(cont);
context.append('\n');
context.addBlock(block);
- }
+ /*}
else {
block.parametersToString(context);
context.append('\n');
block.bodyToString(context);
- }
+ }*/
}
else {
context.append(cont);
}
return result.toArray(new SSABlock[result.size()]);
}
+
+ @Override
+ public void forValRefs(ValRefVisitor visitor) {
+ visitor.visit(scrutinee);
+ }
}
import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder;
import org.simantics.scl.compiler.internal.codegen.utils.PrintingContext;
import org.simantics.scl.compiler.internal.codegen.utils.SSAValidationContext;
+import org.simantics.scl.compiler.internal.codegen.utils.ValRefVisitor;
import org.simantics.scl.compiler.types.TVar;
import org.simantics.scl.compiler.types.Type;
import org.simantics.scl.runtime.exceptions.MatchingException;
public SSABlock[] getSuccessors() {
return SSABlock.EMPTY_ARRAY;
}
+
+ @Override
+ public void forValRefs(ValRefVisitor visitor) {
+ }
}
\r
import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
import org.simantics.scl.compiler.constants.Constant;\r
+import org.simantics.scl.compiler.constants.SCLConstant;\r
import org.simantics.scl.compiler.internal.codegen.continuations.ContRef;\r
import org.simantics.scl.compiler.internal.codegen.references.BoundVar;\r
import org.simantics.scl.compiler.internal.codegen.references.Val;\r
import org.simantics.scl.compiler.internal.codegen.utils.PrintingContext;\r
import org.simantics.scl.compiler.internal.codegen.utils.SSASimplificationContext;\r
import org.simantics.scl.compiler.internal.codegen.utils.SSAValidationContext;\r
+import org.simantics.scl.compiler.internal.codegen.utils.ValRefVisitor;\r
import org.simantics.scl.compiler.top.SCLCompilerConfiguration;\r
import org.simantics.scl.compiler.types.TVar;\r
import org.simantics.scl.compiler.types.Type;\r
context.markModified("LetApply.dead-let-statement");\r
return;\r
}\r
+ // TODO this is quite heavy way for inlining constants\r
+ for(int i=0;i<parameters.length;++i) {\r
+ ValRef parameter = parameters[i];\r
+ Val value = parameter.getBinding();\r
+ if(!(value instanceof SCLConstant))\r
+ continue;\r
+ SCLConstant constant = (SCLConstant)value;\r
+ if(constant.inlineArity != 0)\r
+ continue;\r
+ SSAFunction definition = constant.definition;\r
+ SSABlock block = definition.getFirstBlock();\r
+ if(block.getFirstStatement() != null || !(block.getExit() instanceof Jump))\r
+ continue;\r
+ Jump jump = (Jump)block.getExit();\r
+ if(jump.getTarget().getBinding() != definition.getReturnCont())\r
+ continue;\r
+ if(jump.getParameter(0).getTypeParameters().length > 0)\r
+ continue;\r
+ parameter.replaceBy(jump.getParameter(0).getBinding());\r
+ }\r
Val functionVal = getFunction().getBinding();\r
if(functionVal instanceof BoundVar) {\r
BoundVarBinder parent_ = ((BoundVar)functionVal).parent;\r
public void prepare(MethodBuilder mb) {\r
function.getBinding().prepare(mb);\r
}\r
+\r
+ @Override\r
+ public void forValRefs(ValRefVisitor visitor) {\r
+ visitor.visit(function);\r
+ for(ValRef parameter : parameters)\r
+ visitor.visit(parameter);\r
+ }\r
}\r
import java.util.ArrayList;\r
\r
import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
+import org.simantics.scl.compiler.constants.Constant;\r
import org.simantics.scl.compiler.constants.SCLConstant;\r
import org.simantics.scl.compiler.internal.codegen.references.BoundVar;\r
import org.simantics.scl.compiler.internal.codegen.references.ValRef;\r
+import org.simantics.scl.compiler.internal.codegen.ssa.SSAClosure;\r
import org.simantics.scl.compiler.internal.codegen.ssa.SSAFunction;\r
import org.simantics.scl.compiler.internal.codegen.ssa.SSAStatement;\r
-import org.simantics.scl.compiler.internal.codegen.ssa.binders.FunctionBinder;\r
+import org.simantics.scl.compiler.internal.codegen.ssa.binders.ClosureBinder;\r
import org.simantics.scl.compiler.internal.codegen.utils.CopyContext;\r
import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder;\r
import org.simantics.scl.compiler.internal.codegen.utils.PrintingContext;\r
import org.simantics.scl.compiler.internal.codegen.utils.SSALambdaLiftingContext;\r
import org.simantics.scl.compiler.internal.codegen.utils.SSASimplificationContext;\r
import org.simantics.scl.compiler.internal.codegen.utils.SSAValidationContext;\r
+import org.simantics.scl.compiler.internal.codegen.utils.ValRefVisitor;\r
import org.simantics.scl.compiler.types.TVar;\r
import org.simantics.scl.compiler.types.Type;\r
+import org.simantics.scl.compiler.types.Types;\r
\r
import gnu.trove.map.hash.THashMap;\r
import gnu.trove.set.hash.THashSet;\r
\r
-public class LetFunctions extends SSAStatement implements FunctionBinder {\r
+public class LetFunctions extends SSAStatement implements ClosureBinder {\r
long recursiveGroupLocation;\r
- SSAFunction firstFunction;\r
+ SSAClosure firstClosure;\r
\r
public LetFunctions() {\r
}\r
\r
- public LetFunctions(SSAFunction function) {\r
- firstFunction = function;\r
- function.setParent(this);\r
+ public LetFunctions(SSAClosure closure) {\r
+ firstClosure = closure;\r
+ closure.setParent(this);\r
}\r
\r
@Override\r
public void toString(PrintingContext context) {\r
- for(SSAFunction function = firstFunction; function != null; function = function.getNext()) {\r
+ for(SSAClosure closure = firstClosure; closure != null; closure = closure.getNext()) {\r
context.indentation();\r
- context.append(function.getTarget());\r
- context.append("(" + function.getTarget().occurrenceCount() + ")");\r
+ context.append(closure.getTarget());\r
+ context.append("(" + closure.getTarget().occurrenceCount() + ")");\r
context.append(" :: ");\r
- context.append(function.getTarget().getType());\r
+ context.append(closure.getTarget().getType());\r
context.append(" = \n");\r
context.indent();\r
- function.toString(context);\r
+ closure.toString(context);\r
context.dedent();\r
}\r
}\r
\r
- public void addFunction(SSAFunction function) {\r
- function.setParent(this); \r
- function.setNext(firstFunction);\r
- if(firstFunction != null)\r
- firstFunction.setPrev(function);\r
- firstFunction = function;\r
+ public void addClosure(SSAClosure closure) {\r
+ closure.setParent(this); \r
+ closure.setNext(firstClosure);\r
+ if(firstClosure != null)\r
+ firstClosure.setPrev(closure);\r
+ firstClosure = closure;\r
}\r
\r
@Override\r
\r
@Override\r
public void validate(SSAValidationContext context) {\r
- for(SSAFunction function = firstFunction; function != null; function = function.getNext()) {\r
- if(!(function.getTarget() instanceof BoundVar))\r
+ for(SSAClosure closure = firstClosure; closure != null; closure = closure.getNext()) {\r
+ if(!(closure.getTarget() instanceof BoundVar))\r
throw new InternalCompilerError();\r
- function.validate(context);\r
+ closure.validate(context);\r
}\r
}\r
\r
@Override\r
public void destroy() {\r
- for(SSAFunction function = firstFunction; function != null; function = function.getNext())\r
- function.destroy();\r
+ for(SSAClosure closure = firstClosure; closure != null; closure = closure.getNext())\r
+ closure.destroy();\r
}\r
\r
@Override\r
public SSAStatement copy(CopyContext context) {\r
LetFunctions result = new LetFunctions();\r
- for(SSAFunction function = firstFunction; function != null; function = function.getNext()) {\r
- SSAFunction newFunction = function.copy(context);\r
- newFunction.setTarget(context.copy(function.getTarget()));\r
- result.addFunction(newFunction);\r
+ for(SSAClosure closure = firstClosure; closure != null; closure = closure.getNext()) {\r
+ SSAClosure newFunction = closure.copy(context);\r
+ newFunction.setTarget(context.copy(closure.getTarget()));\r
+ result.addClosure(newFunction);\r
}\r
return result; \r
}\r
\r
@Override\r
public void replace(TVar[] vars, Type[] replacements) {\r
- for(SSAFunction function = firstFunction; function != null; function = function.getNext()) {\r
- ((BoundVar)function.getTarget()).replace(vars, replacements);\r
- function.replace(vars, replacements);\r
+ for(SSAClosure closure = firstClosure; closure != null; closure = closure.getNext()) {\r
+ ((BoundVar)closure.getTarget()).replace(vars, replacements);\r
+ closure.replace(vars, replacements);\r
}\r
}\r
\r
@Override\r
public void addBoundVariablesTo(SSAValidationContext context) {\r
- for(SSAFunction function = firstFunction; function != null; function = function.getNext())\r
- context.validBoundVariables.add((BoundVar)function.getTarget()); \r
+ for(SSAClosure closure = firstClosure; closure != null; closure = closure.getNext())\r
+ context.validBoundVariables.add((BoundVar)closure.getTarget()); \r
}\r
\r
@Override\r
- public SSAFunction getFirstFunction() {\r
- return firstFunction;\r
+ public SSAClosure getFirstClosure() {\r
+ return firstClosure;\r
}\r
\r
@Override\r
- public void setFirstFunction(SSAFunction function) {\r
- this.firstFunction = function; \r
+ public void setFirstClosure(SSAClosure function) {\r
+ this.firstClosure = function; \r
if(function == null)\r
detach();\r
}\r
boolean hasValues = false;\r
boolean isRecursive = false;\r
\r
- // Lambda lift functions and collect free variables\r
+ // Lambda lift substructure and collect free variables\r
THashSet<BoundVar> targets = new THashSet<BoundVar>();\r
ArrayList<ValRef> freeVars = new ArrayList<ValRef>(); \r
- for(SSAFunction function = firstFunction; \r
- function != null; \r
- function = function.getNext()) {\r
- hasValues |= function.getArity() == 0;\r
- function.lambdaLift(context);\r
- targets.add((BoundVar)function.getTarget());\r
- function.collectFreeVariables(freeVars);\r
+ for(SSAClosure closure = firstClosure; \r
+ closure != null; \r
+ closure = closure.getNext()) {\r
+ hasValues |= closure.isValue();\r
+ closure.lambdaLift(context);\r
+ targets.add((BoundVar)closure.getTarget());\r
+ closure.collectFreeVariables(freeVars);\r
+ }\r
+ \r
+ if(!(firstClosure instanceof SSAFunction) && firstClosure.getNext() == null) {\r
+ THashMap<BoundVar, BoundVar> varMap = new THashMap<BoundVar, BoundVar>(); \r
+ ArrayList<BoundVar> oldVarsList = new ArrayList<BoundVar>(4);\r
+ ArrayList<BoundVar> newVarsList = new ArrayList<BoundVar>(4);\r
+ BoundVar newTarget = null;\r
+ for(ValRef ref : freeVars) {\r
+ BoundVar var = (BoundVar)ref.getBinding();\r
+ if(targets.contains(var)) {\r
+ if(newTarget == null)\r
+ newTarget = new BoundVar(var.getType());\r
+ ref.replaceBy(newTarget);\r
+ continue;\r
+ }\r
+ BoundVar newVar = varMap.get(var);\r
+ if(newVar == null) {\r
+ newVar = new BoundVar(var.getType());\r
+ oldVarsList.add(var);\r
+ newVarsList.add(newVar);\r
+ varMap.put(var, newVar);\r
+ }\r
+ ref.replaceBy(newVar);\r
+ }\r
+ Constant constant = firstClosure.liftClosure(newTarget, newVarsList.toArray(new BoundVar[newVarsList.size()]));\r
+ new LetApply(targets.iterator().next(), Types.PROC, constant.createOccurrence(), ValRef.createOccurrences(oldVarsList))\r
+ .insertBefore(this);\r
+ detach();\r
+ context.addClosure(firstClosure);\r
+ return;\r
}\r
\r
// Classify by BoundVars\r
if(boundVars.add(var))\r
boundVarsList.add(var);\r
newFreeVars.add(ref);\r
- /*BoundVar inVar = map.get(outVar);\r
- if(inVar == null) {\r
- inVar = new BoundVar(outVar.getType());\r
- map.put(outVar, inVar);\r
- outParameters.add(outVar);\r
- inParameters.add(inVar);\r
- }\r
- ref.replaceBy(inVar);*/\r
}\r
BoundVar[] outVars = boundVarsList.toArray(new BoundVar[boundVarsList.size()]);\r
freeVars = newFreeVars;\r
\r
// Modify functions\r
- THashMap<SSAFunction, THashMap<BoundVar, BoundVar>> varMap = new THashMap<SSAFunction, THashMap<BoundVar, BoundVar>>();\r
- THashMap<SSAFunction, BoundVar[]> inVarsMap = new THashMap<SSAFunction, BoundVar[]>();\r
- THashMap<SSAFunction, BoundVar> oldTargets = new THashMap<SSAFunction, BoundVar>();\r
- for(SSAFunction function = firstFunction; \r
- function != null; \r
- function = function.getNext()) {\r
- THashMap<BoundVar, BoundVar> map = new THashMap<BoundVar, BoundVar>(2*outVars.length);\r
+ THashMap<SSAClosure, THashMap<BoundVar, BoundVar>> varMap = new THashMap<SSAClosure, THashMap<BoundVar, BoundVar>>();\r
+ THashMap<SSAClosure, BoundVar[]> inVarsMap = new THashMap<SSAClosure, BoundVar[]>();\r
+ THashMap<SSAClosure, BoundVar> oldTargets = new THashMap<SSAClosure, BoundVar>();\r
+ for(SSAClosure closure = firstClosure; \r
+ closure != null; \r
+ closure = closure.getNext()) {\r
+ THashMap<BoundVar, BoundVar> map = new THashMap<BoundVar, BoundVar>(outVars.length);\r
BoundVar[] inVars = new BoundVar[outVars.length]; \r
for(int i=0;i<inVars.length;++i) {\r
inVars[i] = new BoundVar(outVars[i].getType());\r
map.put(outVars[i], inVars[i]);\r
}\r
- inVarsMap.put(function, inVars);\r
- varMap.put(function, map);\r
+ inVarsMap.put(closure, inVars);\r
+ varMap.put(closure, map);\r
\r
- function.addParametersInFront(inVars); \r
- SCLConstant functionConstant = new SCLConstant(context.createName(), function.getType());\r
+ closure.parametrize(inVars); \r
+ SCLConstant functionConstant = new SCLConstant(context.createName(), closure.getType());\r
context.addConstant(functionConstant); \r
- oldTargets.put(function, (BoundVar)function.getTarget());\r
- function.setTarget(functionConstant);\r
- functionConstant.setDefinition(function); \r
+ oldTargets.put(closure, (BoundVar)closure.getTarget());\r
+ closure.setTarget(functionConstant);\r
+ functionConstant.setDefinition((SSAFunction)closure); \r
functionConstant.setPrivate(true);\r
// TODO handle type parameters\r
\r
ValRef.createOccurrences(outVars)).insertBefore(this);*/\r
}\r
\r
- for(SSAFunction function = firstFunction; \r
- function != null; \r
- function = function.getNext()) {\r
- BoundVar oldTarget = oldTargets.get(function);\r
+ for(SSAClosure closure = firstClosure; \r
+ closure != null; \r
+ closure = closure.getNext()) {\r
+ BoundVar oldTarget = oldTargets.get(closure);\r
for(ValRef ref : oldTarget.getOccurences()) {\r
SSAFunction parent = ref.getParentFunction();\r
BoundVar[] vars = inVarsMap.get(parent);\r
if(vars == null)\r
vars = outVars;\r
if(vars.length > 0)\r
- ref.replaceByApply(function.getTarget(), vars);\r
+ ref.replaceByApply(closure.getTarget(), vars);\r
else\r
- ref.replaceBy(function.getTarget());\r
+ ref.replaceBy(closure.getTarget());\r
}\r
}\r
\r
\r
@Override\r
public void simplify(SSASimplificationContext context) {\r
- for(SSAFunction function = firstFunction; \r
+ for(SSAClosure function = firstClosure; \r
function != null; \r
function = function.getNext())\r
function.simplify(context);\r
public void setRecursiveGroupLocation(long recursiveGroupLocation) {\r
this.recursiveGroupLocation = recursiveGroupLocation;\r
}\r
+ \r
+ @Override\r
+ public void forValRefs(ValRefVisitor visitor) {\r
+ for(SSAClosure closure = firstClosure; closure != null; closure = closure.getNext())\r
+ closure.forValRefs(visitor); \r
+ }\r
}\r
import org.cojen.classfile.TypeDesc;
import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
+import org.simantics.scl.compiler.elaboration.modules.TypeAlias;
import org.simantics.scl.compiler.elaboration.modules.TypeConstructor;
+import org.simantics.scl.compiler.elaboration.modules.TypeDescriptor;
import org.simantics.scl.compiler.environment.Environment;
import org.simantics.scl.compiler.internal.codegen.utils.Constants;
import org.simantics.scl.compiler.types.TApply;
parameters[len-i-1] = temp;
}
}
+
+ private TypeConstructor getTypeConstructor(TCon con) {
+ TypeDescriptor typeDescriptor = environment.getTypeDescriptor(con);
+ if(typeDescriptor == null)
+ throw new InternalCompilerError("Didn't find type constructor " + con.module + "/" + con.name + ".");
+ if(typeDescriptor instanceof TypeAlias)
+ throw new InternalCompilerError("Type " + con.module + "/" + con.name + " is a type alias.");
+ return (TypeConstructor)typeDescriptor;
+ }
public TypeDesc toTypeDesc(Type type) {
while(true) {
- if(type instanceof TCon) {
- TCon con = (TCon)type;
- TypeConstructor typeConstructor = environment.getTypeConstructor(con);
- if(typeConstructor == null)
- throw new InternalCompilerError("Didn't find type constructor " + con.module + "/" + con.name + ".");
- return typeConstructor.construct(this, Type.EMPTY_ARRAY);
- }
+ if(type instanceof TCon)
+ return getTypeConstructor((TCon)type).construct(this, Type.EMPTY_ARRAY);
else if(type instanceof TApply) {
int i=0;
while(true) {
type = Types.canonical(apply.function);
if(type instanceof TCon) {
reverseParameters(i);
- return environment.getTypeConstructor((TCon)type).construct(this, parameters);
+ return getTypeConstructor((TCon)type).construct(this, parameters);
}
else if(type instanceof TApply)
;
import org.cojen.classfile.TypeDesc;
import org.simantics.scl.compiler.elaboration.modules.TypeConstructor;
import org.simantics.scl.compiler.types.TCon;
+import org.simantics.scl.compiler.types.TVar;
import org.simantics.scl.compiler.types.Type;
import org.simantics.scl.compiler.types.kinds.Kind;
this.typeDesc = typeDesc;
this.documentation = documentation;
}
+
+ public StandardTypeConstructor(TCon name, TVar[] parameters, TypeDesc typeDesc) {
+ super(name, parameters);
+ this.typeDesc = typeDesc;
+ }
public void setTypeDesc(TypeDesc typeDesc) {
this.typeDesc = typeDesc;
System.out.println();
}*/
}
+
+ public ModuleBuilder getModuleBuilder() {
+ return moduleBuilder;
+ }
}
tsmb.loadField(classBuilder.getClassName(), fieldNamePrefix+i, type);
tsmb.loadLocal(other);
tsmb.loadField(classBuilder.getClassName(), fieldNamePrefix+i, type);
- if(type.isPrimitive())
- tsmb.ifComparisonBranch(failure, "!=", type);
- else {
- Label isNull = tsmb.createLabel();
- Label finished = tsmb.createLabel();
- tsmb.swap();
- tsmb.dup();
- tsmb.ifNullBranch(isNull, true);
- tsmb.swap();
- tsmb.invokeVirtual("java/lang/Object", "equals", TypeDesc.BOOLEAN, Constants.OBJECTS[1]);
- tsmb.ifZeroComparisonBranch(failure, "==");
- tsmb.branch(finished);
- tsmb.setLocation(isNull);
- tsmb.pop();
- tsmb.ifNullBranch(failure, false);
- tsmb.setLocation(finished);
- }
+ equals(tsmb, type, failure);
}
// Return
tsmb.math(Opcodes.IMUL);
tsmb.loadThis();
tsmb.loadField(classBuilder.getClassName(), fieldNamePrefix+i, type);
- switch(type.getTypeCode()) {
- case TypeDesc.INT_CODE:
- break;
- case TypeDesc.OBJECT_CODE: {
- Label isNull = tsmb.createLabel();
- Label finished = tsmb.createLabel();
- tsmb.dup();
- tsmb.ifNullBranch(isNull, true);
- tsmb.invokeVirtual("java/lang/Object", "hashCode", TypeDesc.INT, Constants.EMPTY_TYPEDESC_ARRAY);
- tsmb.branch(finished);
- tsmb.setLocation(isNull);
- tsmb.pop();
- tsmb.loadConstant(0);
- tsmb.setLocation(finished);
- } break;
- case TypeDesc.DOUBLE_CODE:
- tsmb.invokeStatic("java/lang/Double", "doubleToLongBits", TypeDesc.LONG, new TypeDesc[] { TypeDesc.DOUBLE });
- case TypeDesc.LONG_CODE:
- tsmb.dup2();
- tsmb.loadConstant(32);
- tsmb.math(Opcodes.LSHR);
- tsmb.math(Opcodes.LXOR);
- tsmb.convert(TypeDesc.LONG, TypeDesc.INT);
- break;
- case TypeDesc.FLOAT_CODE:
- tsmb.invokeStatic("java/lang/Float", "floatToIntBits", TypeDesc.INT, new TypeDesc[] { TypeDesc.FLOAT });
- break;
- default:
- tsmb.convert(type, TypeDesc.INT);
- }
+ hashCode(tsmb, type);
tsmb.math(Opcodes.IADD);
}
tsmb.returnValue(TypeDesc.INT);
}
}
+ public static void equals(MethodBuilderBase mb, TypeDesc typeDesc, Label failure) {
+ if(typeDesc.isPrimitive())
+ mb.ifComparisonBranch(failure, "!=", typeDesc);
+ else {
+ Label isNull = mb.createLabel();
+ Label finished = mb.createLabel();
+ mb.swap();
+ mb.dup();
+ mb.ifNullBranch(isNull, true);
+ mb.swap();
+ mb.invokeVirtual("java/lang/Object", "equals", TypeDesc.BOOLEAN, Constants.OBJECTS[1]);
+ mb.ifZeroComparisonBranch(failure, "==");
+ mb.branch(finished);
+ mb.setLocation(isNull);
+ mb.pop();
+ mb.ifNullBranch(failure, false);
+ mb.setLocation(finished);
+ }
+ }
+
+ /**
+ * Calculates the hash code of a value in stack.
+ */
+ public static void hashCode(MethodBuilderBase mb, TypeDesc typeDesc) {
+ switch(typeDesc.getTypeCode()) {
+ case TypeDesc.INT_CODE:
+ break;
+ case TypeDesc.OBJECT_CODE: {
+ Label isNull = mb.createLabel();
+ Label finished = mb.createLabel();
+ mb.dup();
+ mb.ifNullBranch(isNull, true);
+ mb.invokeVirtual("java/lang/Object", "hashCode", TypeDesc.INT, Constants.EMPTY_TYPEDESC_ARRAY);
+ mb.branch(finished);
+ mb.setLocation(isNull);
+ mb.pop();
+ mb.loadConstant(0);
+ mb.setLocation(finished);
+ } break;
+ case TypeDesc.DOUBLE_CODE:
+ mb.invokeStatic("java/lang/Double", "doubleToLongBits", TypeDesc.LONG, new TypeDesc[] { TypeDesc.DOUBLE });
+ case TypeDesc.LONG_CODE:
+ mb.dup2();
+ mb.loadConstant(32);
+ mb.math(Opcodes.LSHR);
+ mb.math(Opcodes.LXOR);
+ mb.convert(TypeDesc.LONG, TypeDesc.INT);
+ break;
+ case TypeDesc.FLOAT_CODE:
+ mb.invokeStatic("java/lang/Float", "floatToIntBits", TypeDesc.INT, new TypeDesc[] { TypeDesc.FLOAT });
+ break;
+ default:
+ mb.convert(typeDesc, TypeDesc.INT);
+ }
+ }
+
public static void constructRecord(TypeDesc clazz, MethodBuilder mb,
Type[] parameterTypes, Val... parameters) {
if(parameters.length == 0) {
return NameMangling.mangle(name);
}
+ public String getFreshClosureClassNameSuffix() {
+ return "$" + (++closureCount);
+ }
+
public String getFreshClosureClassName() {
return moduleClassName + "$" + (++closureCount);
}
storeLocal(lv);
}
+ /**
+ * Generates the continuation code if it does not already exist.
+ */
public void ensureExists(Cont continuation) {
if(!generatedConts.contains(continuation))
((SSABlock)continuation).generateCode(this);
public <T> void addPreparation(PreparationStep<T> step, T result) {
preparationSteps.put(step, result);
}
+
+ public LocalVariable cacheValue(IVal val, Type type) {
+ if(val instanceof BoundVar) {
+ BoundVar boundVar = (BoundVar)val;
+ if(!boundVar.generateOnFly)
+ return getLocalVariable(boundVar);
+ }
+ push(val, type);
+ LocalVariable temp = createLocalVariable(null, getJavaTypeTranslator().toTypeDesc(type));
+ storeLocal(temp);
+ return temp;
+ }
}
public void newObject(TypeDesc type) {
methodVisitor.visitTypeInsn(Opcodes.NEW, getClassName(type));
}
+
+ public void newObject(String type) {
+ methodVisitor.visitTypeInsn(Opcodes.NEW, type);
+ }
public void newObject(TypeDesc type, int dimensions) {
methodVisitor.visitMultiANewArrayInsn(type.getDescriptor(), dimensions);
public static String getClassName(Class<?> clazz) {
return clazz.getName().replace('.', '/');
}
+
+ public void switch_(int[] values, Label[] labels, Label defaultLabel) {
+ int lo = values[0];
+ int hi = values[values.length-1];
+ long table_space_cost = 4 + ((long) hi - lo + 1); // words
+ long table_time_cost = 3; // comparisons
+ long lookup_space_cost = 3 + 2 * (long) values.length;
+ long lookup_time_cost = values.length;
+ if(values.length > 0 &&
+ table_space_cost + 3 * table_time_cost <=
+ lookup_space_cost + 3 * lookup_time_cost) {
+ Label[] table = new Label[hi - lo + 1];
+ for(int i=0,j=0;i<table.length;++i) {
+ int id = lo+i;
+ if(values[j] == id) {
+ table[i] = labels[j];
+ ++j;
+ }
+ else
+ table[i] = defaultLabel;
+ }
+ methodVisitor.visitTableSwitchInsn(lo, hi, defaultLabel, table);
+ }
+ else
+ methodVisitor.visitLookupSwitchInsn(defaultLabel, values, labels);
+ }
}
import org.simantics.scl.compiler.common.names.Name;\r
import org.simantics.scl.compiler.constants.SCLConstant;\r
import org.simantics.scl.compiler.errors.ErrorLog;\r
+import org.simantics.scl.compiler.internal.codegen.ssa.SSAClosure;\r
import org.simantics.scl.compiler.internal.codegen.ssa.SSAModule;\r
\r
public class SSALambdaLiftingContext {\r
public ErrorLog getErrorLog() {\r
return errorLog;\r
}\r
+ \r
+ public void addClosure(SSAClosure closure) {\r
+ module.closuresToGenerate.add(closure);\r
+ }\r
}\r
--- /dev/null
+package org.simantics.scl.compiler.internal.codegen.utils;\r
+\r
+import org.simantics.scl.compiler.internal.codegen.references.ValRef;\r
+\r
+@FunctionalInterface\r
+public interface ValRefVisitor {\r
+ public void visit(ValRef valRef);\r
+}\r
import org.simantics.scl.compiler.internal.codegen.references.ValRef;
import org.simantics.scl.compiler.internal.codegen.ssa.SSABlock;
import org.simantics.scl.compiler.internal.codegen.ssa.SSAFunction;
+import org.simantics.scl.compiler.internal.codegen.ssa.SSAObject;
import org.simantics.scl.compiler.internal.codegen.ssa.exits.If;
import org.simantics.scl.compiler.internal.codegen.ssa.exits.Jump;
import org.simantics.scl.compiler.internal.codegen.ssa.exits.Switch;
ModuleWriter moduleWriter;
SSABlock block;
- CodeWriter(ModuleWriter moduleWriter, SSABlock block) {
+ public CodeWriter(ModuleWriter moduleWriter, SSABlock block) {
this.moduleWriter = moduleWriter;
this.block = block;
}
- public IVal apply(int lineNumber, IVal function, IVal ... parameters) {
+ public IVal apply(long lineNumber, IVal function, IVal ... parameters) {
try {
MultiFunction mfun = Types.matchFunction(function.getType(), parameters.length);
return applyWithEffect(lineNumber,
}
}
- public IVal applyWithEffectChecked(int lineNumber, Type effect, Type returnType, IVal function, IVal ... parameters) {
+ public IVal applyWithEffectChecked(long lineNumber, Type effect, Type returnType, IVal function, IVal ... parameters) {
try {
MultiFunction mfun = Types.matchFunction(function.getType(), parameters.length);
if(!Types.equals(effect, mfun.effect))
return var;
}
+ public CodeWriter createBlock() {
+ SSABlock newBlock = new SSABlock(Type.EMPTY_ARRAY);
+ block.getParent().addBlock(newBlock);
+ return new CodeWriter(moduleWriter, newBlock);
+ }
+
public CodeWriter createBlock(Type ... parameterTypes) {
SSABlock newBlock = new SSABlock(parameterTypes);
block.getParent().addBlock(newBlock);
elseTarget.createOccurrence()));
block = null;
}
+
+ public void branchAwayIf(IVal condition, ICont target) {
+ SSABlock newBlock = new SSABlock(Type.EMPTY_ARRAY);
+ block.getParent().addBlock(newBlock);
+ block.setExit(new If(condition.createOccurrence(),
+ target.createOccurrence(),
+ newBlock.createOccurrence()));
+ this.block = newBlock;
+ }
+
+ public void branchAwayUnless(IVal condition, ICont target) {
+ SSABlock newBlock = new SSABlock(Type.EMPTY_ARRAY);
+ block.getParent().addBlock(newBlock);
+ block.setExit(new If(condition.createOccurrence(),
+ newBlock.createOccurrence(),
+ target.createOccurrence()));
+ this.block = newBlock;
+ }
public void return_(IVal val) {
jump(block.getParent().getReturnCont(), val);
public SSAFunction getFunction() {
return block.getParent();
- }
+ }
+
+ public boolean isUnfinished() {
+ return block != null;
+ }
+
+ public void defineObject(SSAObject object) {
+ this.block.addStatement(new LetFunctions(object));
+ }
}
import org.simantics.scl.compiler.internal.codegen.ssa.SSABlock;
import org.simantics.scl.compiler.internal.codegen.ssa.SSAFunction;
import org.simantics.scl.compiler.internal.codegen.ssa.SSAModule;
+import org.simantics.scl.compiler.internal.codegen.ssa.StaticField;
import org.simantics.scl.compiler.types.TVar;
import org.simantics.scl.compiler.types.Type;
import org.simantics.scl.runtime.tuple.Tuple2;
String name = "externalConstant" + externalConstantId;
JavaStaticField constant = new JavaStaticField(moduleClassName, name, type, -1);
externalConstantMap.put(tuple, constant);
- module.addStaticField(new Tuple2(name, type));
+ module.addStaticField(new StaticField(name, type));
return constant;
}
}
function.addBlock(block);\r
function.setTarget(target);\r
\r
- let.addFunction(function);\r
+ let.addClosure(function);\r
\r
return new CodeWriter(moduleWriter, block);\r
}\r
+++ /dev/null
-package org.simantics.scl.compiler.internal.deriving;
-
-import java.util.ArrayList;
-
-import org.simantics.scl.compiler.common.datatypes.Constructor;
-import org.simantics.scl.compiler.elaboration.errors.NotPatternException;
-import org.simantics.scl.compiler.elaboration.expressions.EApply;
-import org.simantics.scl.compiler.elaboration.expressions.EVar;
-import org.simantics.scl.compiler.elaboration.expressions.EVariable;
-import org.simantics.scl.compiler.elaboration.expressions.Expression;
-import org.simantics.scl.compiler.elaboration.expressions.Variable;
-import org.simantics.scl.compiler.elaboration.modules.TypeConstructor;
-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.errors.ErrorLog;
-import org.simantics.scl.compiler.internal.parsing.declarations.DDerivingInstanceAst;
-import org.simantics.scl.compiler.internal.parsing.declarations.DInstanceAst;
-import org.simantics.scl.compiler.internal.parsing.declarations.DValueAst;
-import org.simantics.scl.compiler.internal.parsing.expressions.Expressions;
-import org.simantics.scl.compiler.internal.parsing.translation.ProcessedDInstanceAst;
-import org.simantics.scl.compiler.internal.parsing.translation.ValueRepository;
-import org.simantics.scl.compiler.internal.parsing.types.TVarAst;
-import org.simantics.scl.compiler.types.TCon;
-
-class EqDeriver implements InstanceDeriver {
-
- @Override
- public void derive(
- ErrorLog errorLog,
- Environment environment,
- ArrayList<ProcessedDInstanceAst> instancesAst,
- DDerivingInstanceAst der) {
- // Analyze
- if(der.types.length != 1) {
- errorLog.log(der.location, "Invalid number of parameters to " + der.name);
- return;
- }
- TVarAst headType = DerivingUtils.getHeadType(der.types[0]);
- if(headType == null) {
- errorLog.log(der.types[0].location, "Cannot derive Eq instance for the type " + headType + ".");
- return;
- }
- TCon con;
- try {
- con = Environments.getTypeConstructorName(environment, headType.name);
- } catch (AmbiguousNameException e1) {
- errorLog.log(headType.location, e1.getMessage());
- return;
- }
- if(con == null) {
- errorLog.log(headType.location, "Couldn't resolve " + headType.name);
- return;
- }
- TypeConstructor tcon = environment.getTypeConstructor(con);
- if(tcon == null) {
- errorLog.log(headType.location, "Didn't find type constructor for " + headType.name);
- return;
- }
- if(tcon.isOpen) {
- errorLog.log(headType.location, "Cannot derive instance for open data types.");
- return;
- }
-
- // Generate
- DInstanceAst instanceAst = new DInstanceAst(der.location, der.context, der.name, der.types);
- ValueRepository valueDefs = new ValueRepository();
- for(Constructor constructor : tcon.constructors) {
- int l = constructor.parameterTypes.length;
- String[] par1 = new String[l];
- String[] par2 = new String[l];
- for(int i=0;i<l;++i) {
- par1[i] = "a" + i;
- par2[i] = "b" + i;
- }
- Expression lhs = new EApply(
- new EVar("=="),
- new EApply(new EVar(constructor.name.name), Expressions.vars(par1)),
- new EApply(new EVar(constructor.name.name), Expressions.vars(par2))
- );
- Expression value = new EVar("True");
- for(int i=l-1;i>=0;--i)
- value = new EApply(
- new EVar("&&"),
- new EApply(
- new EVar("=="),
- new EVar(par1[i]),
- new EVar(par2[i])),
- value);
- try {
- DValueAst valueAst = new DValueAst(lhs, value);
- valueAst.setLocationDeep(der.location);
- valueDefs.add(valueAst);
- } catch (NotPatternException e) {
- errorLog.log(e.getExpression().location, "Not a pattern.");
- }
- }
- {
- Expression lhs = new EApply(
- new EVar("=="),
- new EVariable(new Variable("_")),
- new EVariable(new Variable("_")));
- Expression value = new EVar("False");
- try {
- DValueAst valueAst = new DValueAst(lhs, value);
- valueAst.setLocationDeep(der.location);
- valueDefs.add(valueAst);
- /*valueDefs.addAnnotation("==", new DAnnotationAst(new EVar("@private"),
- Collections.<Expression>emptyList()));*/
- } catch (NotPatternException e) {
- errorLog.log(e.getExpression().location, "Not a pattern.");
- }
- }
- instancesAst.add(new ProcessedDInstanceAst(instanceAst, valueDefs));
- }
-
-}
+++ /dev/null
-package org.simantics.scl.compiler.internal.deriving;
-
-import java.util.ArrayList;
-
-import org.simantics.scl.compiler.common.datatypes.Constructor;
-import org.simantics.scl.compiler.constants.IntegerConstant;
-import org.simantics.scl.compiler.elaboration.errors.NotPatternException;
-import org.simantics.scl.compiler.elaboration.expressions.EApply;
-import org.simantics.scl.compiler.elaboration.expressions.ELiteral;
-import org.simantics.scl.compiler.elaboration.expressions.EVar;
-import org.simantics.scl.compiler.elaboration.expressions.Expression;
-import org.simantics.scl.compiler.elaboration.modules.TypeConstructor;
-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.errors.ErrorLog;
-import org.simantics.scl.compiler.internal.parsing.declarations.DDerivingInstanceAst;
-import org.simantics.scl.compiler.internal.parsing.declarations.DInstanceAst;
-import org.simantics.scl.compiler.internal.parsing.declarations.DValueAst;
-import org.simantics.scl.compiler.internal.parsing.expressions.Expressions;
-import org.simantics.scl.compiler.internal.parsing.translation.ProcessedDInstanceAst;
-import org.simantics.scl.compiler.internal.parsing.translation.ValueRepository;
-import org.simantics.scl.compiler.internal.parsing.types.TVarAst;
-import org.simantics.scl.compiler.types.TCon;
-
-class HashableDeriver implements InstanceDeriver {
-
- @Override
- public void derive(
- ErrorLog errorLog,
- Environment environment,
- ArrayList<ProcessedDInstanceAst> instancesAst,
- DDerivingInstanceAst der) {
- // Analyze
- if(der.types.length != 1) {
- errorLog.log(der.location, "Invalid number of parameters to " + der.name);
- return;
- }
- TVarAst headType = DerivingUtils.getHeadType(der.types[0]);
- if(headType == null) {
- errorLog.log(der.types[0].location, "Cannot derive Hashable instance for the type " + headType + ".");
- return;
- }
- TCon con;
- try {
- con = Environments.getTypeConstructorName(environment, headType.name);
- } catch (AmbiguousNameException e1) {
- errorLog.log(headType.location, e1.getMessage());
- return;
- }
- if(con == null) {
- errorLog.log(headType.location, "Couldn't resolve " + headType.name);
- return;
- }
- TypeConstructor tcon = environment.getTypeConstructor(con);
- if(tcon == null) {
- errorLog.log(headType.location, "Didn't find type constructor for " + headType.name);
- return;
- }
- if(tcon.isOpen) {
- errorLog.log(headType.location, "Cannot derive instance for open data types.");
- return;
- }
-
- // Generate
- DInstanceAst instanceAst = new DInstanceAst(der.location, der.context, der.name, der.types);
- ValueRepository valueDefs = new ValueRepository();
- int cId = 0;
- for(Constructor constructor : tcon.constructors) {
- int l = constructor.parameterTypes.length;
- String[] par = new String[l];
- for(int i=0;i<l;++i) {
- par[i] = "v" + i;
- }
- Expression lhs = new EApply(
- new EVar("hashP"),
- new EApply(new EVar(constructor.name.name), Expressions.vars(par)),
- new EVar("accum")
- );
- Expression value = new EVar("accum");
- for(int i=0;i<l;++i) {
- value = new EApply(new EVar("hashP"),
- new EVar(par[i]),
- value
- );
- }
- if(tcon.constructors.length > 1)
- value = new EApply(new EVar("hashP"),
- new ELiteral(new IntegerConstant(cId)),
- value
- );
-
- try {
- DValueAst valueAst = new DValueAst(lhs, value);
- valueAst.setLocationDeep(der.location);
- valueDefs.add(valueAst);
- } catch (NotPatternException e) {
- errorLog.log(e.getExpression().location, "Not a pattern.");
- }
- ++ cId;
- }
- instancesAst.add(new ProcessedDInstanceAst(instanceAst, valueDefs));
- }
-
-}
import java.util.ArrayList;
import org.simantics.scl.compiler.common.datatypes.Constructor;
-import org.simantics.scl.compiler.common.names.Name;
+import org.simantics.scl.compiler.common.names.Names;
import org.simantics.scl.compiler.constants.ByteConstant;
import org.simantics.scl.compiler.constants.IntegerConstant;
import org.simantics.scl.compiler.elaboration.errors.NotPatternException;
import org.simantics.scl.compiler.elaboration.expressions.Expression;
import org.simantics.scl.compiler.elaboration.expressions.block.LetStatement;
import org.simantics.scl.compiler.elaboration.modules.SCLValue;
+import org.simantics.scl.compiler.elaboration.modules.TypeAlias;
import org.simantics.scl.compiler.elaboration.modules.TypeConstructor;
+import org.simantics.scl.compiler.elaboration.modules.TypeDescriptor;
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.types.TCon;
class IODeriver implements InstanceDeriver {
-
- private static final Name WRITE = Name.create("Serialization", "write");
- private static final Name READ = Name.create("Serialization", "read");
- private static final Name IO_SIZE = Name.create("Serialization", "ioSize");
@Override
public void derive(
}
TCon con;
try {
- con = Environments.getTypeConstructorName(environment, headType.name);
+ con = Environments.getTypeDescriptorName(environment, headType.name);
} catch (AmbiguousNameException e1) {
errorLog.log(headType.location, e1.getMessage());
return;
errorLog.log(headType.location, "Couldn't resolve " + headType.name);
return;
}
- TypeConstructor tcon = environment.getTypeConstructor(con);
- if(tcon == null) {
+ TypeDescriptor tdesc = environment.getTypeDescriptor(con);
+ if(tdesc == null) {
errorLog.log(headType.location, "Didn't find type constructor for " + headType.name);
return;
}
+ if(tdesc instanceof TypeAlias) {
+ errorLog.log(headType.location, "Cannot derive instance for a type alias.");
+ return;
+ }
+ TypeConstructor tcon = (TypeConstructor)tdesc;
if(tcon.isOpen) {
errorLog.log(headType.location, "Cannot derive instance for open data types.");
return;
DInstanceAst instanceAst = new DInstanceAst(der.location, der.context, der.name, der.types);
ValueRepository valueDefs = new ValueRepository();
- SCLValue write = environment.getValue(WRITE);
- SCLValue read = environment.getValue(READ);
- SCLValue ioSize = environment.getValue(IO_SIZE);
+ SCLValue write = environment.getValue(Names.Serialization_write);
+ SCLValue read = environment.getValue(Names.Serialization_read);
+ SCLValue ioSize = environment.getValue(Names.Serialization_ioSize);
// Generate write
for(int id=0;id<tcon.constructors.length;++id) {
new THashMap<TCon, InstanceDeriver>();\r
\r
static {\r
- MAP.put(Types.EQ, new EqDeriver());\r
- MAP.put(Types.HASHABLE, new HashableDeriver());\r
MAP.put(Types.IO, new IODeriver());\r
MAP.put(Types.ORD, new OrdDeriver());\r
MAP.put(Types.SHOW, new ShowDeriver());\r
import org.simantics.scl.compiler.elaboration.expressions.ELiteral;
import org.simantics.scl.compiler.elaboration.expressions.EVar;
import org.simantics.scl.compiler.elaboration.expressions.Expression;
+import org.simantics.scl.compiler.elaboration.modules.TypeAlias;
import org.simantics.scl.compiler.elaboration.modules.TypeConstructor;
+import org.simantics.scl.compiler.elaboration.modules.TypeDescriptor;
import org.simantics.scl.compiler.environment.AmbiguousNameException;
import org.simantics.scl.compiler.environment.Environment;
import org.simantics.scl.compiler.environment.Environments;
}
TCon con;
try {
- con = Environments.getTypeConstructorName(environment, headType.name);
+ con = Environments.getTypeDescriptorName(environment, headType.name);
} catch (AmbiguousNameException e1) {
errorLog.log(headType.location, e1.getMessage());
return;
errorLog.log(headType.location, "Couldn't resolve " + headType.name);
return;
}
- TypeConstructor tcon = environment.getTypeConstructor(con);
- if(tcon == null) {
+ TypeDescriptor tdesc = environment.getTypeDescriptor(con);
+ if(tdesc == null) {
errorLog.log(headType.location, "Didn't find type constructor for " + headType.name);
return;
}
+ if(tdesc instanceof TypeAlias) {
+ errorLog.log(headType.location, "Cannot derive instance for a type alias.");
+ return;
+ }
+ TypeConstructor tcon = (TypeConstructor)tdesc;
if(tcon.isOpen) {
errorLog.log(headType.location, "Cannot derive instance for open data types.");
return;
import org.simantics.scl.compiler.elaboration.expressions.ELiteral;
import org.simantics.scl.compiler.elaboration.expressions.EVar;
import org.simantics.scl.compiler.elaboration.expressions.Expression;
+import org.simantics.scl.compiler.elaboration.modules.TypeAlias;
import org.simantics.scl.compiler.elaboration.modules.TypeConstructor;
+import org.simantics.scl.compiler.elaboration.modules.TypeDescriptor;
import org.simantics.scl.compiler.environment.AmbiguousNameException;
import org.simantics.scl.compiler.environment.Environment;
import org.simantics.scl.compiler.environment.Environments;
}
TCon con;
try {
- con = Environments.getTypeConstructorName(environment, headType.name);
+ con = Environments.getTypeDescriptorName(environment, headType.name);
} catch (AmbiguousNameException e1) {
errorLog.log(headType.location, e1.getMessage());
return;
errorLog.log(headType.location, "Couldn't resolve " + headType.name);
return;
}
- TypeConstructor tcon = environment.getTypeConstructor(con);
- if(tcon == null) {
+ TypeDescriptor tdesc = environment.getTypeDescriptor(con);
+ if(tdesc == null) {
errorLog.log(headType.location, "Didn't find type constructor for " + headType.name);
return;
}
+ if(tdesc instanceof TypeAlias) {
+ errorLog.log(headType.location, "Cannot derive instance for a type alias.");
+ return;
+ }
+ TypeConstructor tcon = (TypeConstructor)tdesc;
if(tcon.isOpen) {
errorLog.log(headType.location, "Cannot derive instance for open data types.");
return;
package org.simantics.scl.compiler.internal.elaboration.constraints;
+import java.util.ArrayList;
+
import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
import org.simantics.scl.compiler.constants.ClassConstant;
import org.simantics.scl.compiler.constants.StringConstant;
else if(parameter instanceof TUnion) {
TUnion union = (TUnion)parameter;
- /*TPred[] demands = new TPred[union.effects.length];
- for(int i=0;i<union.effects.length;++i)
- demands[i] = Types.pred(Types.TYPEABLE, union.effects[i]);*/
if(union.effects.length == 0)
- return new Reduction(
+ return new Reduction(
new EConstant(Builtins.INSTANCE.getValue("TPure")),
Type.EMPTY_ARRAY,
TPred.EMPTY_ARRAY);
+ else if(union.effects.length == 2) {
+ return new Reduction(
+ new EConstant(Builtins.INSTANCE.getValue("TUnion2")),
+ Type.EMPTY_ARRAY, new TPred[] {
+ Types.pred(Types.TYPEABLE, union.effects[0]),
+ Types.pred(Types.TYPEABLE, union.effects[1])
+ });
+ }
}
}
// Standard case
- THashMap<TVar, Type> substitution = new THashMap<TVar, Type>();
+ THashMap<TVar, Type> substitution = new THashMap<TVar, Type>();
+ ArrayList<Reduction> reductions = new ArrayList<Reduction>(1);
for(TypeClassInstance inst : environment.getInstances(constraint.typeClass)) {
if(Types.match(inst.instance, constraint, substitution)) {
TPred[] demands = new TPred[inst.context.length];
parameter = inst.generatorParameters[i]; // TODO Is this correct?
parameters[i] = parameter;
}
- return new Reduction(new ELiteral(inst.generator), parameters, demands);
+ reductions.add(new Reduction(new ELiteral(inst.generator), parameters, demands));
}
- else
- substitution.clear();
+ substitution.clear();
+ }
+ //System.out.println(constraint.typeClass + " -> " + reductions.size());
+ if(reductions.size() == 1)
+ return reductions.get(0);
+ else if(reductions.size() > 1) {
+ throw new InternalCompilerError("Found more than one matching instances for " + constraint.typeClass + ".");
}
return null;
}
DEFAULTS_IGNORE.add(Types.SHOW);\r
DEFAULTS_IGNORE.add(Types.con("Json2", "JSON"));\r
DEFAULTS_IGNORE.add(Types.VEC_COMP);\r
- DEFAULTS_IGNORE.add(Types.EQ);\r
DEFAULTS_IGNORE.add(Types.ORD);\r
DEFAULTS_IGNORE.add(Types.TYPEABLE);\r
DEFAULTS_IGNORE.add(Types.SERIALIZABLE);\r
package org.simantics.scl.compiler.internal.elaboration.matching;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
import org.simantics.scl.compiler.elaboration.expressions.EExternalConstant;
import org.simantics.scl.compiler.elaboration.expressions.ELiteral;
import org.simantics.scl.compiler.elaboration.expressions.EVariable;
+import org.simantics.scl.compiler.elaboration.expressions.EViewPattern;
import org.simantics.scl.compiler.elaboration.expressions.Expression;
import org.simantics.scl.compiler.elaboration.expressions.GuardedExpressionGroup;
import org.simantics.scl.compiler.elaboration.modules.SCLValue;
return newVals;
}
- private static void split(CodeWriter w, final Environment env, IVal[] scrutinee, final ICont success, ICont failure, List<Row> rows, int columnId) {
+ private static void splitByConstructors(CodeWriter w, final Environment env, IVal[] scrutinee, final ICont success, ICont failure, List<Row> rows, int columnId) {
THashMap<Object, ExpressionMatrix> matrixMap = new THashMap<Object, ExpressionMatrix>();
ArrayList<Branch> branches = new ArrayList<Branch>();
ArrayList<ExpressionMatrix> matrices = new ArrayList<ExpressionMatrix>();
Expression constructor_ = applyConstructor.getFunction();
while(constructor_ instanceof EApplyType)
constructor_ = ((EApplyType)constructor_).getExpression();
- SCLValue constructor = ((EConstant)constructor_).getValue();
- // TODO How type parameters are handled???
Expression[] parameters = applyConstructor.getParameters();
-
- ExpressionMatrix matrix = matrixMap.get(constructor.getName());
- if(matrix == null) {
- CodeWriter newW = w.createBlock(Types.getTypes(parameters));
- branches.add(new Branch((Constant)constructor.getValue(), newW.getContinuation()));
- matrix = new ExpressionMatrix(newW, replace(scrutinee, columnId, newW.getParameters()));
- matrices.add(matrix);
- matrixMap.put(constructor.getName(), matrix);
+ // TODO How type parameters are handled???
+ if(constructor_ instanceof EConstant) {
+ SCLValue constructor = ((EConstant)constructor_).getValue();
+
+ ExpressionMatrix matrix = matrixMap.get(constructor.getName());
+ if(matrix == null) {
+ CodeWriter newW = w.createBlock(Types.getTypes(parameters));
+ branches.add(new Branch((Constant)constructor.getValue(), newW.getContinuation()));
+ matrix = new ExpressionMatrix(newW, replace(scrutinee, columnId, newW.getParameters()));
+ matrices.add(matrix);
+ matrixMap.put(constructor.getName(), matrix);
+ }
+ matrix.rows.add(row.replace(columnId, parameters));
+ }
+ else if(constructor_ instanceof ELiteral) {
+ Constant constructor = ((ELiteral)constructor_).getValue();
+
+ ExpressionMatrix matrix = matrixMap.get(constructor);
+ if(matrix == null) {
+ CodeWriter newW = w.createBlock(Types.getTypes(parameters));
+ branches.add(new Branch(constructor, newW.getContinuation()));
+ matrix = new ExpressionMatrix(newW, replace(scrutinee, columnId, newW.getParameters()));
+ matrices.add(matrix);
+ matrixMap.put(constructor, matrix);
+ }
+ matrix.rows.add(row.replace(columnId, parameters));
}
- matrix.rows.add(row.replace(columnId, parameters));
}
else if(pattern instanceof EConstant) {
EConstant applyConstructor = (EConstant)pattern;
} catch (MatchException e) {
throw new InternalCompilerError();
}
- TypeConstructor cons = env.getTypeConstructor(con);
+ TypeConstructor cons = (TypeConstructor)env.getTypeDescriptor(con);
int maxBranchCount = cons.isOpen ? Integer.MAX_VALUE
: cons.constructors.length;
if(branches.size() < maxBranchCount)
w.switch_(scrutinee[columnId], branches.toArray(new Branch[branches.size()]));
}
+ private static void splitByViewPattern(CodeWriter w, Environment env, IVal[] scrutinee, ICont success,
+ ICont failure, List<Row> rows, int viewPatternColumn) {
+ Row firstRow = rows.get(0);
+ EViewPattern firstViewPattern = (EViewPattern)firstRow.patterns[viewPatternColumn];
+ firstRow.patterns[viewPatternColumn] = firstViewPattern.pattern;
+ int i;
+ for(i=1;i<rows.size();++i) {
+ Row row = rows.get(i);
+ Expression pattern = row.patterns[viewPatternColumn];
+ while(true) {
+ if(pattern instanceof EApplyType)
+ pattern = ((EApplyType)pattern).getExpression();
+ else if(pattern instanceof EAsPattern) {
+ EAsPattern asPattern = (EAsPattern)pattern;
+ pattern = asPattern.getPattern();
+ asPattern.getVariable().setVal(scrutinee[viewPatternColumn]);
+ }
+ else
+ break;
+ row.patterns[viewPatternColumn] = pattern;
+ }
+ if(!(pattern instanceof EViewPattern))
+ break;
+ EViewPattern otherViewPattern = (EViewPattern)pattern;
+ if(!otherViewPattern.expression.equalsExpression(firstViewPattern.expression))
+ break;
+ row.patterns[viewPatternColumn] = otherViewPattern.pattern;
+ }
+
+ IVal[] newScrutinee = Arrays.copyOf(scrutinee, scrutinee.length);
+ newScrutinee[viewPatternColumn] =
+ w.apply(firstViewPattern.location,
+ firstViewPattern.expression.toVal(env, w),
+ scrutinee[viewPatternColumn]);
+ if(i == rows.size()) {
+ split(w, env, newScrutinee, success, failure, rows);
+ }
+ else {
+ CodeWriter cont = w.createBlock();
+ split(w, env, newScrutinee, success, cont.getContinuation(), rows.subList(0, i));
+ split(cont, env, scrutinee, success, failure, rows.subList(i, rows.size()));
+ }
+ }
+
public static void split(CodeWriter w, Environment env, IVal[] scrutinee, ICont success, ICont failure, List<Row> rows) {
Row firstRow = rows.get(0);
Expression[] patterns = firstRow.patterns;
if(scrutinee.length != patterns.length)
- throw new InternalCompilerError();
+ throw new InternalCompilerError("Scrutinee and patterns have a different length");
// Find a non-variable pattern and split by it
+ int viewPatternColumn = -1;
for(int i=0;i<patterns.length;++i) {
- if(!(patterns[i] instanceof EVariable)) {
- split(w, env, scrutinee, success, failure, rows, i);
+ Expression pattern = patterns[i];
+ if(pattern instanceof EViewPattern) {
+ if(viewPatternColumn == -1)
+ viewPatternColumn = i;
+ }
+ else if(!(pattern instanceof EVariable)) {
+ splitByConstructors(w, env, scrutinee, success, failure, rows, i);
return;
}
}
+
+ if(viewPatternColumn >= 0) {
+ splitByViewPattern(w, env, scrutinee, success, failure, rows, viewPatternColumn);
+ return;
+ }
- // No matching needed
+ // The first row has only variable patterns: no matching needed
for(int i=0;i<patterns.length;++i)
((EVariable)patterns[i]).getVariable().setVal(scrutinee[i]);
if(firstRow.value instanceof GuardedExpressionGroup) {
package org.simantics.scl.compiler.internal.elaboration.matching;\r
\r
\r
+import java.util.Arrays;\r
+\r
import org.simantics.scl.compiler.elaboration.expressions.Expression;\r
\r
public class Row {\r
newPatterns[j++] = patterns[i];\r
return new Row(newPatterns, value);\r
}\r
+ \r
+ @Override\r
+ public String toString() {\r
+ return Arrays.toString(patterns) + " -> " + value;\r
+ }\r
}\r
--- /dev/null
+package org.simantics.scl.compiler.internal.elaboration.matching2;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Arrays;\r
+import java.util.List;\r
+\r
+import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
+import org.simantics.scl.compiler.constants.Constant;\r
+import org.simantics.scl.compiler.elaboration.expressions.EApply;\r
+import org.simantics.scl.compiler.elaboration.expressions.EApplyType;\r
+import org.simantics.scl.compiler.elaboration.expressions.EAsPattern;\r
+import org.simantics.scl.compiler.elaboration.expressions.EConstant;\r
+import org.simantics.scl.compiler.elaboration.expressions.EExternalConstant;\r
+import org.simantics.scl.compiler.elaboration.expressions.ELiteral;\r
+import org.simantics.scl.compiler.elaboration.expressions.EVariable;\r
+import org.simantics.scl.compiler.elaboration.expressions.EViewPattern;\r
+import org.simantics.scl.compiler.elaboration.expressions.Expression;\r
+import org.simantics.scl.compiler.elaboration.modules.SCLValue;\r
+import org.simantics.scl.compiler.elaboration.modules.TypeConstructor;\r
+import org.simantics.scl.compiler.environment.Environment;\r
+import org.simantics.scl.compiler.internal.codegen.continuations.Branch;\r
+import org.simantics.scl.compiler.internal.codegen.continuations.ICont;\r
+import org.simantics.scl.compiler.internal.codegen.references.IVal;\r
+import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;\r
+import org.simantics.scl.compiler.types.TCon;\r
+import org.simantics.scl.compiler.types.Types;\r
+import org.simantics.scl.compiler.types.exceptions.MatchException;\r
+\r
+import gnu.trove.map.hash.THashMap;\r
+\r
+public class PatternMatchingCompiler2 {\r
+\r
+ private static class ExpressionMatrix {\r
+ final CodeWriter w;\r
+ final IVal[] scrutinee;\r
+ final List<Row2> rows = new ArrayList<Row2>();\r
+\r
+ public ExpressionMatrix(CodeWriter w, IVal[] scrutinee) {\r
+ this.w = w;\r
+ this.scrutinee = scrutinee;\r
+ }\r
+ }\r
+\r
+ public static IVal[] replace(IVal[] vals, int columnToReplace, IVal ... substitution) {\r
+ IVal[] newVals = new IVal[vals.length-1+substitution.length];\r
+ int j=0;\r
+ for(int i=0;i<columnToReplace;++i)\r
+ newVals[j++] = vals[i];\r
+ for(int i=0;i<substitution.length;++i)\r
+ newVals[j++] = substitution[i];\r
+ for(int i=columnToReplace+1;i<vals.length;++i)\r
+ newVals[j++] = vals[i];\r
+ return newVals;\r
+ }\r
+\r
+ private static void splitByConstructors(CodeWriter w, final Environment env, IVal[] scrutinee, ICont failure, List<Row2> rows, int columnId) {\r
+ THashMap<Object, ExpressionMatrix> matrixMap = new THashMap<Object, ExpressionMatrix>();\r
+ ArrayList<Branch> branches = new ArrayList<Branch>();\r
+ ArrayList<ExpressionMatrix> matrices = new ArrayList<ExpressionMatrix>();\r
+ \r
+ /*System.out.println("---");\r
+ for(Row row : rows) {\r
+ for(Expression e : row.patterns)\r
+ System.out.print(e + " ");\r
+ System.out.println();\r
+ }*/\r
+\r
+ int i;\r
+ for(i=0;i<rows.size();++i) {\r
+ Row2 row = rows.get(i);\r
+ Expression pattern = row.patterns[columnId];\r
+ while(true) {\r
+ if(pattern instanceof EApplyType)\r
+ pattern = ((EApplyType)pattern).getExpression();\r
+ else if(pattern instanceof EAsPattern) {\r
+ EAsPattern asPattern = (EAsPattern)pattern;\r
+ pattern = asPattern.getPattern();\r
+ asPattern.getVariable().setVal(scrutinee[columnId]);\r
+ }\r
+ else\r
+ break;\r
+ row.patterns[columnId] = pattern;\r
+ }\r
+ if(pattern instanceof EVariable)\r
+ break;\r
+ else if(pattern instanceof EApply) {\r
+ EApply applyConstructor = (EApply)pattern;\r
+ Expression constructor_ = applyConstructor.getFunction();\r
+ while(constructor_ instanceof EApplyType)\r
+ constructor_ = ((EApplyType)constructor_).getExpression();\r
+ Expression[] parameters = applyConstructor.getParameters();\r
+ // TODO How type parameters are handled???\r
+ if(constructor_ instanceof EConstant) {\r
+ SCLValue constructor = ((EConstant)constructor_).getValue();\r
+ \r
+ ExpressionMatrix matrix = matrixMap.get(constructor.getName());\r
+ if(matrix == null) {\r
+ CodeWriter newW = w.createBlock(Types.getTypes(parameters));\r
+ branches.add(new Branch((Constant)constructor.getValue(), newW.getContinuation()));\r
+ matrix = new ExpressionMatrix(newW, replace(scrutinee, columnId, newW.getParameters()));\r
+ matrices.add(matrix);\r
+ matrixMap.put(constructor.getName(), matrix);\r
+ }\r
+ matrix.rows.add(row.replace(columnId, parameters));\r
+ }\r
+ else if(constructor_ instanceof ELiteral) {\r
+ Constant constructor = ((ELiteral)constructor_).getValue();\r
+ \r
+ ExpressionMatrix matrix = matrixMap.get(constructor);\r
+ if(matrix == null) {\r
+ CodeWriter newW = w.createBlock(Types.getTypes(parameters));\r
+ branches.add(new Branch(constructor, newW.getContinuation()));\r
+ matrix = new ExpressionMatrix(newW, replace(scrutinee, columnId, newW.getParameters()));\r
+ matrices.add(matrix);\r
+ matrixMap.put(constructor, matrix);\r
+ }\r
+ matrix.rows.add(row.replace(columnId, parameters));\r
+ }\r
+ }\r
+ else if(pattern instanceof EConstant) {\r
+ EConstant applyConstructor = (EConstant)pattern;\r
+ SCLValue constructor = applyConstructor.getValue();\r
+\r
+ ExpressionMatrix matrix = matrixMap.get(constructor.getName());\r
+ if(matrix == null) {\r
+ CodeWriter newW = w.createBlock();\r
+ branches.add(new Branch((Constant)constructor.getValue(), newW.getContinuation()));\r
+ matrix = new ExpressionMatrix(newW, replace(scrutinee, columnId, newW.getParameters()));\r
+ matrices.add(matrix);\r
+ matrixMap.put(constructor.getName(), matrix);\r
+ }\r
+ matrix.rows.add(row.replace(columnId, Expression.EMPTY_ARRAY));\r
+ }\r
+ else if(pattern instanceof ELiteral) {\r
+ ELiteral literal = (ELiteral)pattern;\r
+ Constant constructor = literal.getValue();\r
+\r
+ ExpressionMatrix matrix = matrixMap.get(constructor);\r
+ if(matrix == null) {\r
+ CodeWriter newW = w.createBlock();\r
+ branches.add(new Branch(constructor, newW.getContinuation()));\r
+ matrix = new ExpressionMatrix(newW, replace(scrutinee, columnId, newW.getParameters()));\r
+ matrices.add(matrix);\r
+ matrixMap.put(constructor, matrix);\r
+ }\r
+ matrix.rows.add(row.replace(columnId, Expression.EMPTY_ARRAY));\r
+ }\r
+ else if(pattern instanceof EExternalConstant) {\r
+ EExternalConstant constant = (EExternalConstant)pattern;\r
+ Constant constructor = w.getModuleWriter().getExternalConstant(constant.getValue(), constant.getType());\r
+\r
+ ExpressionMatrix matrix = matrixMap.get(constructor);\r
+ if(matrix == null) {\r
+ CodeWriter newW = w.createBlock();\r
+ branches.add(new Branch(constructor, newW.getContinuation()));\r
+ matrix = new ExpressionMatrix(newW, replace(scrutinee, columnId, newW.getParameters()));\r
+ matrices.add(matrix);\r
+ matrixMap.put(constructor, matrix);\r
+ }\r
+ matrix.rows.add(row.replace(columnId, Expression.EMPTY_ARRAY));\r
+ }\r
+ else\r
+ throw new InternalCompilerError("Cannot handle an instance of " + pattern.getClass().getSimpleName() + " in a pattern.");\r
+ }\r
+ if(i < rows.size()) {\r
+ CodeWriter newW = w.createBlock();\r
+ ICont cont = newW.getContinuation();\r
+ branches.add(new Branch(null, cont));\r
+ split(newW, env, scrutinee, failure, rows.subList(i, rows.size()));\r
+ failure = cont;\r
+ }\r
+ else {\r
+ TCon con;\r
+ try {\r
+ con = Types.getConstructor(scrutinee[columnId].getType());\r
+ } catch (MatchException e) {\r
+ throw new InternalCompilerError(e);\r
+ }\r
+ TypeConstructor cons = (TypeConstructor)env.getTypeDescriptor(con);\r
+ int maxBranchCount = cons.isOpen ? Integer.MAX_VALUE \r
+ : cons.constructors.length;\r
+ if(branches.size() < maxBranchCount)\r
+ branches.add(new Branch(null, failure));\r
+ }\r
+\r
+ for(ExpressionMatrix mx : matrices)\r
+ split(mx.w, env, mx.scrutinee, failure, mx.rows);\r
+ w.switch_(scrutinee[columnId], branches.toArray(new Branch[branches.size()]));\r
+ }\r
+\r
+ private static void splitByViewPattern(CodeWriter w, Environment env, IVal[] scrutinee, ICont failure, List<Row2> rows, int viewPatternColumn) {\r
+ Row2 firstRow = rows.get(0);\r
+ EViewPattern firstViewPattern = (EViewPattern)firstRow.patterns[viewPatternColumn];\r
+ firstRow.patterns[viewPatternColumn] = firstViewPattern.pattern;\r
+ int i;\r
+ for(i=1;i<rows.size();++i) {\r
+ Row2 row = rows.get(i);\r
+ Expression pattern = row.patterns[viewPatternColumn];\r
+ while(true) {\r
+ if(pattern instanceof EApplyType)\r
+ pattern = ((EApplyType)pattern).getExpression();\r
+ else if(pattern instanceof EAsPattern) {\r
+ EAsPattern asPattern = (EAsPattern)pattern;\r
+ pattern = asPattern.getPattern();\r
+ asPattern.getVariable().setVal(scrutinee[viewPatternColumn]);\r
+ }\r
+ else\r
+ break;\r
+ row.patterns[viewPatternColumn] = pattern;\r
+ }\r
+ if(!(pattern instanceof EViewPattern))\r
+ break;\r
+ EViewPattern otherViewPattern = (EViewPattern)pattern;\r
+ if(!otherViewPattern.expression.equalsExpression(firstViewPattern.expression))\r
+ break;\r
+ row.patterns[viewPatternColumn] = otherViewPattern.pattern;\r
+ }\r
+ \r
+ IVal[] newScrutinee = Arrays.copyOf(scrutinee, scrutinee.length);\r
+ newScrutinee[viewPatternColumn] =\r
+ w.apply(firstViewPattern.location,\r
+ firstViewPattern.expression.toVal(env, w),\r
+ scrutinee[viewPatternColumn]);\r
+ if(i == rows.size()) {\r
+ split(w, env, newScrutinee, failure, rows);\r
+ }\r
+ else {\r
+ CodeWriter cont = w.createBlock();\r
+ split(w, env, newScrutinee, cont.getContinuation(), rows.subList(0, i));\r
+ split(cont, env, scrutinee, failure, rows.subList(i, rows.size()));\r
+ }\r
+ }\r
+\r
+ public static void split(CodeWriter w, Environment env, IVal[] scrutinee, ICont failure, List<Row2> rows) {\r
+ Row2 firstRow = rows.get(0);\r
+ Expression[] patterns = firstRow.patterns;\r
+ if(scrutinee.length != patterns.length)\r
+ throw new InternalCompilerError("Scrutinee and patterns have a different length");\r
+ \r
+ // Find a non-variable pattern and split by it\r
+ int viewPatternColumn = -1;\r
+ for(int i=0;i<patterns.length;++i) {\r
+ Expression pattern = patterns[i];\r
+ if(pattern instanceof EViewPattern) {\r
+ if(viewPatternColumn == -1)\r
+ viewPatternColumn = i;\r
+ }\r
+ else if(!(pattern instanceof EVariable)) {\r
+ splitByConstructors(w, env, scrutinee, failure, rows, i);\r
+ return;\r
+ }\r
+ }\r
+ \r
+ if(viewPatternColumn >= 0) {\r
+ splitByViewPattern(w, env, scrutinee, failure, rows, viewPatternColumn);\r
+ return;\r
+ }\r
+\r
+ // The first row has only variable patterns: no matching needed\r
+ for(int i=0;i<patterns.length;++i)\r
+ ((EVariable)patterns[i]).getVariable().setVal(scrutinee[i]);\r
+ w.jump(firstRow.continuation);\r
+ }\r
+}\r
--- /dev/null
+package org.simantics.scl.compiler.internal.elaboration.matching2;\r
+\r
+\r
+import java.util.Arrays;\r
+\r
+import org.simantics.scl.compiler.elaboration.expressions.Expression;\r
+import org.simantics.scl.compiler.internal.codegen.continuations.ICont;\r
+\r
+public class Row2 {\r
+ Expression[] patterns;\r
+ ICont continuation;\r
+ \r
+ public Row2(Expression[] patterns,ICont continuation) {\r
+ this.patterns = patterns;\r
+ this.continuation = continuation;\r
+ }\r
+ \r
+ public Row2 replace(int columnToReplace, Expression[] substitution) {\r
+ Expression[] newPatterns = new Expression[patterns.length-1+substitution.length];\r
+ int j=0;\r
+ for(int i=0;i<columnToReplace;++i)\r
+ newPatterns[j++] = patterns[i];\r
+ for(int i=0;i<substitution.length;++i)\r
+ newPatterns[j++] = substitution[i];\r
+ for(int i=columnToReplace+1;i<patterns.length;++i)\r
+ newPatterns[j++] = patterns[i];\r
+ return new Row2(newPatterns, continuation);\r
+ }\r
+ \r
+ @Override\r
+ public String toString() {\r
+ return Arrays.toString(patterns);\r
+ }\r
+}\r
import org.simantics.scl.compiler.elaboration.expressions.EBinary;
import org.simantics.scl.compiler.elaboration.expressions.EBind;
import org.simantics.scl.compiler.elaboration.expressions.EBlock;
+import org.simantics.scl.compiler.elaboration.expressions.ECHRRuleset;
import org.simantics.scl.compiler.elaboration.expressions.EConstant;
import org.simantics.scl.compiler.elaboration.expressions.ECoveringBranchPoint;
import org.simantics.scl.compiler.elaboration.expressions.EEnforce;
++codeCounter;
expression.condition = expression.condition.accept(this);
expression.then_ = injectBranchPoint(expression.then_);
- expression.else_ = injectBranchPoint(expression.else_);
+ if(expression.else_ != null)
+ expression.else_ = injectBranchPoint(expression.else_);
return expression;
}
return super.transform(expression);
}
+ @Override
+ public Expression transform(ECHRRuleset expression) {
+ ++codeCounter;
+ return super.transform(expression);
+ }
+
@Override
public Expression transform(EConstant expression) {
++codeCounter;
import java.util.Arrays;
import java.util.List;
-import org.simantics.scl.compiler.common.names.Name;
+import org.simantics.scl.compiler.common.names.Names;
import org.simantics.scl.compiler.constants.Constant;
import org.simantics.scl.compiler.elaboration.contexts.EnvironmentalContext;
import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
import org.simantics.scl.compiler.internal.codegen.references.IVal;
import org.simantics.scl.compiler.internal.elaboration.utils.ForcedClosure;
import org.simantics.scl.compiler.top.SCLCompilerConfiguration;
-import org.simantics.scl.compiler.types.TCon;
import org.simantics.scl.compiler.types.Type;
import org.simantics.scl.compiler.types.Types;
import gnu.trove.set.hash.THashSet;
public class TransformationBuilder {
- private static final TCon UMap = Types.con("Unification", "UMap");
- private static final Name createUMap = Name.create("Unification", "createUMap");
-
- private static final TCon Unifiable = Types.con("Unification", "Unifiable");
- private static final Name uVar = Name.create("Unification", "uVar");
-
private final ErrorLog errorLog;
private final TypingContext context;
private final UnifiableFactory unifiableFactory;
mappingRelation.parameterTypes[0]
});
mapping.umap = new Variable("map_" + mappingRelation.name.name,
- Types.apply(UMap, mappingRelation.parameterTypes)
+ Types.apply(Names.Unifiable_UMap, mappingRelation.parameterTypes)
);
mappings.put(mappingRelation, mapping);
mappingStatements.add(new LetStatement(new EVariable(mapping.umap),
- Expressions.apply(context, Types.PROC, createUMap,
+ Expressions.apply(context.getCompilationContext(), Types.PROC, Names.Unifiable_createUMap,
mappingRelation.parameterTypes[0],
mappingRelation.parameterTypes[1],
Expressions.punit())));
int count = mappedVariableUseCount.get(variable);
if(count > 1) {
Variable uniVariable = new Variable("uvar_" + variable.getName(),
- Types.apply(Unifiable, variable.getType()));
+ Types.apply(Names.Unifiable_Unifiable, variable.getType()));
phase2Actions.add(new LetStatement(new EVariable(uniVariable),
- Expressions.apply(context, Types.PROC,
- uVar,
+ Expressions.apply(context.getCompilationContext(), Types.PROC,
+ Names.Unifiable_uVar,
variable.getType(),
Expressions.tuple())));
uniVariableMap.put(variable, uniVariable);
new QAtom(decomposed.ruleMatchingRelation,
Type.EMPTY_ARRAY,
Expressions.vars(sourceVariables)),
- statementsToExpression(context, phase2Actions),
+ statementsToExpression(context.getCompilationContext(), phase2Actions),
sourceVariables).compile(context)));
// Enforcing statement
for(int phase : phases.keys()) {
ArrayList<Query> targetQuery = phases.get(phase);
Expression enforcing = new EEnforce(new QConjunction(targetQuery.toArray(new Query[targetQuery.size()]))).compile(context);
- enforcing = statementsToExpression(context, phase3Actions, enforcing);
+ enforcing = statementsToExpression(context.getCompilationContext(), phase3Actions, enforcing);
enforcing = new EWhen(
rule.location,
new QAtom(decomposed.ruleMatchingRelation,
for(int phase : phases)
allEnforcingStatements.addAll(enforcingStatements.get(phase));
}
- Expression expression = statementsToExpression(context, allEnforcingStatements);
- expression = statementsToExpression(context, mappingStatements, expression);
+ Expression expression = statementsToExpression(context.getCompilationContext(), allEnforcingStatements);
+ expression = statementsToExpression(context.getCompilationContext(), mappingStatements, expression);
// Matching
Expression result = new ERuleset(
import java.util.ArrayList;
import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
-import org.simantics.scl.compiler.common.names.Name;
+import org.simantics.scl.compiler.common.names.Names;
import org.simantics.scl.compiler.constants.Constant;
import org.simantics.scl.compiler.constants.StringConstant;
import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
import gnu.trove.set.hash.THashSet;
public class UnifiableFactory {
- private static final TCon Unifiable = Types.con("Unification", "Unifiable");
- private static final Name uVar = Name.create("Unification", "uVar");
- private static final Name uCons = Name.create("Unification", "uCons");
- private static final Name uId = Name.create("Unification", "uId");
- private static final Name uPending = Name.create("Unification", "uPending");
- private static final TCon UTag = Types.con("Unification", "UTag");
- private static final Name uTag = Name.create("Unification", "uTag");
- private static final Name extractWithDefault = Name.create("Unification", "extractWithDefault");
-
- private static final Name putUMap = Name.create("Unification", "putUMap");
- private static final Name putUMapC = Name.create("Unification", "putUMapC");
- private static final Name getUMapWithDefault = Name.create("Unification", "getUMapWithDefault");
-
- private static final Name fail = Name.create("Builtin", "fail");
- private static final Name unsafeCoerce = Name.create("JavaBuiltin", "unsafeCoerce");
- private static final Name newResource = Name.create("Simantics/DB", "newResource");
- private static final Name createElement = Name.create("Data/XML", "createElement");
-
- private static final Type XML_ELEMENT = Types.con("Data/XML", "Element");
-
private final TypingContext context;
/**
* The factory generates here the statements initializing the variables needed in unification.
}
@Override
public Expression toExpression() {
- return Expressions.apply(context, Types.NO_EFFECTS, uId,
+ return Expressions.apply(context.getCompilationContext(), Types.NO_EFFECTS, Names.Unifiable_uId,
constant.getType(), constant);
}
}
variable,
extract(variable.getType(), Expressions.var(uniVariableMap.get(variable))),
expression);
- return Expressions.apply(context, Types.NO_EFFECTS, uPending,
+ return Expressions.apply(context.getCompilationContext(), Types.NO_EFFECTS, Names.Unifiable_uPending,
value.getType(), Expressions.computation(Types.PROC, expression));
}
}
if(uniVariable != null)
return new UniRep(new EVariable(uniVariable));
else
- return new UniRep(Expressions.apply(context, Types.PROC, uVar, variable.getType(), Expressions.punit()));
+ return new UniRep(Expressions.apply(context.getCompilationContext(), Types.PROC, Names.Unifiable_uVar, variable.getType(), Expressions.punit()));
}
apply:
if(expression instanceof EApply) {
for(int i=0;i<arity;++i)
tupleParameters[i] = uniParameters[i].toExpression();
Expression tuple = Expressions.tuple(tupleParameters);
- return new UniRep(Expressions.apply(context, Types.NO_EFFECTS, uCons,
+ return new UniRep(Expressions.apply(context.getCompilationContext(), Types.NO_EFFECTS, Names.Unifiable_uCons,
expression.getType(), tuple.getType(),
getTag(function), tuple));
}
Type[] uniParameterTypes = new Type[arity];
for(int i=0;i<arity;++i)
- uniParameterTypes[i] = Types.apply(Unifiable, mfun.parameterTypes[i]);
+ uniParameterTypes[i] = Types.apply(Names.Unifiable_Unifiable, mfun.parameterTypes[i]);
Type tupleType = Types.tuple(uniParameterTypes);
// Destructor
Expression destructor;
if(sclValue.getName().module.equals("Builtin") && sclValue.getName().name.charAt(0)=='(') {
// Tuple constructor is a special case, where we can just cast the value
- destructor = Expressions.constant(context, unsafeCoerce, mfun.returnType, tupleType);
+ destructor = Expressions.constant(context.getCompilationContext(), Names.JavaBuiltin_unsafeCoerce, mfun.returnType, tupleType);
}
else {
Variable[] parameters = new Variable[arity];
Expression pattern = new EApply(constructorExpr.copy(context), Expressions.vars(parameters));
Expression[] tupleParameters = new Expression[arity];
for(int i=0;i<arity;++i)
- tupleParameters[i] = Expressions.apply(context, Types.NO_EFFECTS, uId,
+ tupleParameters[i] = Expressions.apply(context.getCompilationContext(), Types.NO_EFFECTS, Names.Unifiable_uId,
parameters[i].getType(), Expressions.var(parameters[i]));
Expression value = Expressions.tuple(tupleParameters);
destructor = new ELambda(Locations.NO_LOCATION, pattern, value);
constructor = new ELambda(Locations.NO_LOCATION, pattern, value);
}
- tag = new Variable("tag", Types.apply(UTag, mfun.returnType, tupleType));
+ tag = new Variable("tag", Types.apply(Names.Unifiable_UTag, mfun.returnType, tupleType));
mappingStatements.add(new LetStatement(new EVariable(tag),
- Expressions.apply(context, Types.NO_EFFECTS, uTag, tupleType, mfun.returnType,
+ Expressions.apply(context.getCompilationContext(), Types.NO_EFFECTS, Names.Unifiable_uTag, tupleType, mfun.returnType,
Expressions.integer(constructorTag), constructor, destructor)));
constructorTags.put(key, tag);
}
}
private Expression extract(Type type, Expression uni) {
- return Expressions.apply(context, Types.PROC, extractWithDefault,
+ return Expressions.apply(context.getCompilationContext(), Types.PROC, Names.Unifiable_extractWithDefault,
type, getDefaultGenerator(type), uni);
}
//System.out.println("createGenerationExpression(" + type.toString(tuc) + ")");
if(apply.constructor instanceof TCon) {
if(apply.constructor.equals(Types.RESOURCE))
- return Expressions.apply(context, Types.PROC, newResource, Expressions.tuple());
+ return Expressions.apply(context.getCompilationContext(), Types.PROC, Names.Simantics_DB_newResource, Expressions.tuple());
if(apply.constructor.equals(Types.STRING))
return new ELiteral(new StringConstant("")); // FIXME
- if(apply.constructor.equals(XML_ELEMENT))
- return Expressions.apply(context, Types.PROC, createElement, Expressions.string("NO-NAME"));
+ if(apply.constructor.equals(Names.Data_XML_Element))
+ return Expressions.apply(context.getCompilationContext(), Types.PROC, Names.Data_XML_createElement, Expressions.string("NO-NAME"));
TCon con = (TCon)apply.constructor;
if(con.name.charAt(0) == '(') { // (), (,), (,,),...
return Expressions.tuple(parameters);
}
}
- return Expressions.apply(context, Types.NO_EFFECTS, fail,
+ return Expressions.apply(context.getCompilationContext(), Types.NO_EFFECTS, Names.Builtin_fail,
new ELiteral(new StringConstant("Cannot generated default instance for type " + type + ".")));
}
}
public Expression getFromUMap(Expression umap, Expression key, Type valueType) {
- return Expressions.apply(context, Types.PROC,
- getUMapWithDefault,
+ return Expressions.apply(context.getCompilationContext(), Types.PROC,
+ Names.Unifiable_getUMapWithDefault,
valueType,
key.getType(),
getDefaultGenerator(valueType),
public Expression putToUMapUnifiable(
THashSet<Variable> variableSet, THashMap<Variable, Variable> uniVariableMap,
Expression umap, Expression key, Expression value) {
- return Expressions.apply(context, Types.PROC,
- putUMap,
+ return Expressions.apply(context.getCompilationContext(), Types.PROC,
+ Names.Unifiable_putUMap,
key.getType(),
value.getType(),
umap,
}
public Expression putToUMapConstant(Variable umap, Expression key, Expression value) {
- return Expressions.apply(context, Types.PROC,
- putUMapC,
+ return Expressions.apply(context.getCompilationContext(), Types.PROC,
+ Names.Unifiable_putUMapC,
key.getType(), value.getType(),
Expressions.var(umap),
key, value);
;
lexp
- = faexp+ # Apply, shift ID, shift LAMBDA,
+ = faexp+ # Apply, shift ID, shift LAMBDA, shift LAMBDA_MATCH,
shift LET, shift INTEGER, shift BEGIN_STRING,
shift IF, shift MATCH, shift DO,
shift MDO, shift ENFORCE, shift BLANK,
aexp
= LAMBDA aexp+ ARROW exp # Lambda, shift HASTYPE
+ | LAMBDA_MATCH LBRACE case (SEMICOLON case)* RBRACE # LambdaMatch, shift HASTYPE
| LET statements IN exp # Let, shift HASTYPE
- | IF exp THEN exp ELSE exp # If, shift HASTYPE
+ | IF exp THEN exp (ELSE exp)? # If, shift HASTYPE, shift ELSE
| MATCH exp WITH
LBRACE case (SEMICOLON case)* RBRACE # Match
| (DO | MDO) statements # Do
| (SELECT | SELECT_FIRST | SELECT_DISTINCT)
exp WHERE queryBlock # Select
| ENFORCE queryBlock # Enforce
- | WHEN queryBlock SEMICOLON exp # When
+ //| WHEN queryBlock SEMICOLON exp # When
| var # Var
| ATTACHED_HASH ID # HashedId
| BLANK # Blank
| stringLiteral # String
| CHAR # Char
| LPAREN (exp (COMMA exp)*)? RPAREN # Tuple
+ | LPAREN exp ARROW exp RPAREN # ViewPattern
| LPAREN symbolWithoutMinus lexp RPAREN # RightSection
| LPAREN lexp symbol RPAREN # LeftSection
| LBRACKET (exp (COMMA exp)*)? RBRACKET # ListLiteral
| exp rhs # LetStatement
| exp BINDS exp # BindStatement
| exp FOLLOWS queryBlock # RuleStatement
+ | chrQuery IMPLIES chrQuery # CHRStatement
+ | WHEN verboseChrQuery THEN_AFTER_WHEN verboseChrQuery # VerboseCHRStatement
+ | CONSTRAINT ID atype* # ConstraintStatement
+ ;
+
+chrQuery
+ = listQualifier (COMMA listQualifier)* # CHRQuery
+ ;
+
+verboseChrQuery
+ = LBRACE listQualifier (SEMICOLON listQualifier)* RBRACE # VerboseCHRQuery
;
listQualifier
digit = [0-9]
hexDigit = [0-9a-fA-F]
id_char = {letter} | {digit} | "'"
-ord_symbol_char = [!$%&*+\/<=>?@\\\^|\-:~]
+ord_symbol_char = [!$%&*+\/<=>@\\\^|\-:~]
symbol_char = {ord_symbol_char} | "#"
prefix = {letter} {id_char}* "."
// relation { return sym(SCLTerminals.RELATION); }
as { return sym(SCLTerminals.AS); }
by { return sym(SCLTerminals.BY); }
+ constraint { return sym(SCLTerminals.CONSTRAINT); }
{queryOp} { return sym(SCLTerminals.QUERY_OP); }
"@" { return sym(SCLTerminals.AT); }
"{" { return sym(SCLTerminals.LBRACE); }
{separatedDot} { return sym(SCLTerminals.SEPARATED_DOT, "."); }
"." { return sym(SCLTerminals.ATTACHED_DOT, "."); }
"-" { return sym(SCLTerminals.MINUS, "-"); }
-// "<" existentialVar ">" { yybegin(XML); return sym(SCLTerminals.XML_BEGIN); }
+// "<" {existentialVar} ">" { yybegin(XML); return sym(SCLTerminals.XML_BEGIN); }
"<" { return sym(SCLTerminals.LESS, "<"); }
">" { return sym(SCLTerminals.GREATER, ">"); }
";" { return sym(SCLTerminals.SEMICOLON); }
"=" { return sym(SCLTerminals.EQUALS); }
"::" { return sym(SCLTerminals.HASTYPE); }
":" { return sym(SCLTerminals.COLON); }
+ "\\" " "* match { return sym(SCLTerminals.LAMBDA_MATCH); }
"\\" { return sym(SCLTerminals.LAMBDA); }
"\"\"\"" { string.setLength(0); stringStart=yychar; yybegin(LONG_STRING); return sym(SCLTerminals.BEGIN_STRING); }
"\"" { string.setLength(0); stringStart=yychar; yybegin(STRING); return sym(SCLTerminals.BEGIN_STRING); }
/* The following code was generated by JFlex 1.6.1 */\r
\r
-package org.simantics.scl.compiler.internal.parsing.parser;\r
-\r
-import org.simantics.scl.compiler.internal.parsing.Token;\r
-import org.simantics.scl.compiler.errors.Locations;\r
-import org.simantics.scl.compiler.internal.parsing.exceptions.SCLSyntaxErrorException;\r
-import gnu.trove.list.array.TIntArrayList;\r
-\r
+package org.simantics.scl.compiler.internal.parsing.parser;
+
+import org.simantics.scl.compiler.internal.parsing.Token;
+import org.simantics.scl.compiler.errors.Locations;
+import org.simantics.scl.compiler.internal.parsing.exceptions.SCLSyntaxErrorException;
+import gnu.trove.list.array.TIntArrayList;
+
\r
/**\r
* This class is a scanner generated by \r
\r
private static final String ZZ_ACTION_PACKED_0 =\r
"\4\0\1\1\1\2\1\3\1\1\1\4\1\5\1\6"+\r
- "\1\7\1\10\1\11\1\12\1\4\1\13\1\1\1\14"+\r
+ "\1\7\1\10\1\11\1\12\1\1\1\13\1\1\1\14"+\r
"\1\15\1\16\1\17\1\4\1\20\1\21\16\2\1\22"+\r
"\1\23\1\24\1\25\1\26\1\27\1\30\1\31\1\32"+\r
"\1\33\1\13\1\34\1\35\1\36\1\0\1\37\1\36"+\r
"\1\40\2\35\2\40\5\0\1\4\1\41\1\42\1\43"+\r
- "\3\0\1\2\3\0\1\4\1\44\1\45\1\46\1\4"+\r
- "\2\2\1\47\2\2\1\50\1\51\11\2\1\52\3\2"+\r
- "\1\53\1\2\1\54\4\2\1\55\1\56\1\57\1\0"+\r
- "\1\60\1\61\1\62\1\63\1\64\1\60\1\65\2\0"+\r
- "\2\66\1\0\1\67\1\70\1\2\1\0\1\71\2\0"+\r
- "\1\72\1\0\1\4\3\2\1\73\24\2\1\74\1\75"+\r
- "\1\0\1\76\2\0\1\46\1\2\1\77\6\2\1\100"+\r
- "\1\101\2\2\1\102\3\2\1\103\1\2\1\104\1\2"+\r
- "\1\105\3\2\1\0\1\46\2\2\1\106\11\2\1\107"+\r
- "\1\110\1\2\1\111\1\2\1\0\1\112\1\2\1\113"+\r
- "\1\114\2\2\1\115\1\2\1\116\1\117\2\2\1\120"+\r
- "\2\2\1\121\2\2\1\122\2\2\1\123\1\124\1\0"+\r
- "\3\2\1\125\2\2\2\0\1\126\2\0\2\2\4\0"+\r
- "\1\127\1\2\4\0\1\2\4\0\1\2\1\130\2\0"+\r
- "\1\131\1\2\2\0\1\132\2\0\1\133\1\0\1\134";\r
+ "\3\0\1\2\4\0\1\4\1\44\1\45\1\46\1\4"+\r
+ "\2\0\2\2\1\47\2\2\1\50\1\51\11\2\1\52"+\r
+ "\3\2\1\53\2\2\1\54\4\2\1\55\1\56\1\57"+\r
+ "\1\0\1\60\1\61\1\62\1\63\1\64\1\60\1\65"+\r
+ "\2\0\2\66\1\0\1\67\1\70\1\2\1\0\1\71"+\r
+ "\2\0\2\72\1\0\1\4\1\0\3\2\1\73\25\2"+\r
+ "\1\74\1\75\1\0\1\76\2\0\1\46\1\0\1\2"+\r
+ "\1\77\6\2\1\100\1\101\2\2\1\102\3\2\1\103"+\r
+ "\1\2\1\104\2\2\1\105\3\2\1\0\1\46\1\0"+\r
+ "\2\2\1\106\11\2\1\107\1\2\1\110\1\2\1\111"+\r
+ "\1\2\1\0\1\112\1\113\1\2\1\114\1\115\2\2"+\r
+ "\1\116\1\2\1\117\1\120\2\2\1\121\3\2\1\122"+\r
+ "\2\2\1\123\2\2\1\124\1\125\1\0\4\2\1\126"+\r
+ "\2\2\2\0\1\2\1\127\2\0\2\2\2\0\1\2"+\r
+ "\2\0\1\130\1\2\2\0\1\131\2\0\1\2\4\0"+\r
+ "\1\2\1\132\2\0\1\133\1\2\2\0\1\134\2\0"+\r
+ "\1\135\1\0\1\136";\r
\r
private static int [] zzUnpackAction() {\r
- int [] result = new int[276];\r
+ int [] result = new int[293];\r
int offset = 0;\r
offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result);\r
return result;\r
"\0\0\0\76\0\174\0\272\0\272\0\370\0\u0136\0\u0174"+\r
"\0\u01b2\0\u01f0\0\u022e\0\u026c\0\u02aa\0\272\0\272\0\u02e8"+\r
"\0\u0326\0\u0364\0\u03a2\0\u01b2\0\u03e0\0\u041e\0\u045c\0\272"+\r
- "\0\u01b2\0\u049a\0\u04d8\0\u0516\0\u0554\0\u0592\0\u05d0\0\u060e"+\r
- "\0\u064c\0\u068a\0\u06c8\0\u0706\0\u0744\0\u0782\0\u07c0\0\272"+\r
- "\0\272\0\272\0\272\0\u07fe\0\u083c\0\272\0\u01b2\0\u087a"+\r
- "\0\370\0\272\0\272\0\u08b8\0\u08f6\0\u0934\0\272\0\272"+\r
- "\0\u0972\0\u09b0\0\u09ee\0\u08b8\0\272\0\u0a2c\0\u0a6a\0\u0aa8"+\r
- "\0\u0ae6\0\u0b24\0\u0b62\0\272\0\u0ba0\0\u0bde\0\u0c1c\0\u0c5a"+\r
- "\0\u0c98\0\u0cd6\0\u0d14\0\u0d52\0\u0d90\0\u0dce\0\u01b2\0\u01b2"+\r
- "\0\u0e0c\0\u0e4a\0\u0e88\0\u0ec6\0\370\0\u0f04\0\u0f42\0\370"+\r
- "\0\u0f80\0\u0fbe\0\u0ffc\0\u103a\0\u1078\0\u10b6\0\u10f4\0\u1132"+\r
- "\0\u1170\0\u11ae\0\370\0\u11ec\0\u122a\0\u1268\0\370\0\u12a6"+\r
- "\0\370\0\u12e4\0\u1322\0\u1360\0\u139e\0\u01b2\0\u01b2\0\u01b2"+\r
- "\0\u13dc\0\272\0\272\0\272\0\272\0\272\0\u141a\0\272"+\r
- "\0\u1458\0\u1496\0\u14d4\0\u1512\0\u1512\0\272\0\272\0\272"+\r
- "\0\u1550\0\272\0\u158e\0\u15cc\0\u01b2\0\u160a\0\u1648\0\u1686"+\r
- "\0\u16c4\0\u1702\0\370\0\u1740\0\u177e\0\u17bc\0\u17fa\0\u1838"+\r
- "\0\u1876\0\u18b4\0\u18f2\0\u1930\0\u196e\0\u19ac\0\u19ea\0\u1a28"+\r
- "\0\u1a66\0\u1aa4\0\u1ae2\0\u1b20\0\u1b5e\0\u1b9c\0\u1bda\0\370"+\r
- "\0\272\0\u1c18\0\272\0\u1c56\0\u1c94\0\u01b2\0\u1cd2\0\370"+\r
- "\0\u1d10\0\u1d4e\0\u1d8c\0\u1dca\0\u1e08\0\u1e46\0\370\0\370"+\r
- "\0\u1e84\0\u1ec2\0\370\0\u1f00\0\u1f3e\0\u1f7c\0\370\0\u1fba"+\r
- "\0\370\0\u1ff8\0\370\0\u2036\0\u2074\0\u20b2\0\u20f0\0\272"+\r
- "\0\u212e\0\u216c\0\u21aa\0\u21e8\0\u2226\0\u2264\0\u22a2\0\u22e0"+\r
- "\0\u231e\0\u235c\0\u239a\0\u23d8\0\370\0\370\0\u2416\0\370"+\r
- "\0\u2454\0\u2492\0\370\0\u24d0\0\370\0\370\0\u250e\0\u254c"+\r
- "\0\u258a\0\u25c8\0\370\0\370\0\u2606\0\u2644\0\u2682\0\u26c0"+\r
- "\0\u26fe\0\272\0\u273c\0\u277a\0\370\0\u27b8\0\u27f6\0\370"+\r
- "\0\370\0\u2834\0\u2872\0\u28b0\0\u28ee\0\370\0\u292c\0\u296a"+\r
- "\0\u29a8\0\u29e6\0\370\0\u2a24\0\u2a62\0\u2aa0\0\u2ade\0\u2b1c"+\r
+ "\0\u049a\0\u04d8\0\u0516\0\u0554\0\u0592\0\u05d0\0\u060e\0\u064c"+\r
+ "\0\u068a\0\u06c8\0\u0706\0\u0744\0\u0782\0\u07c0\0\u07fe\0\272"+\r
+ "\0\272\0\272\0\272\0\u083c\0\u087a\0\272\0\u01b2\0\u08b8"+\r
+ "\0\370\0\272\0\272\0\u08f6\0\u0934\0\u0972\0\272\0\272"+\r
+ "\0\u09b0\0\u09ee\0\u0a2c\0\u08f6\0\272\0\u0a6a\0\u0aa8\0\u0ae6"+\r
+ "\0\u0b24\0\u0b62\0\u0ba0\0\272\0\u0bde\0\u0c1c\0\u0c5a\0\u0c98"+\r
+ "\0\u0cd6\0\u0d14\0\u0d52\0\u0d90\0\u0dce\0\u0e0c\0\u0e4a\0\u01b2"+\r
+ "\0\u01b2\0\u0e88\0\u0ec6\0\u0f04\0\u0f42\0\u0f80\0\u0fbe\0\370"+\r
+ "\0\u0ffc\0\u103a\0\370\0\u1078\0\u10b6\0\u10f4\0\u1132\0\u1170"+\r
+ "\0\u11ae\0\u11ec\0\u122a\0\u1268\0\u12a6\0\370\0\u12e4\0\u1322"+\r
+ "\0\u1360\0\370\0\u139e\0\u13dc\0\370\0\u141a\0\u1458\0\u1496"+\r
+ "\0\u14d4\0\u01b2\0\u01b2\0\u01b2\0\u1512\0\272\0\272\0\272"+\r
+ "\0\272\0\272\0\u1550\0\272\0\u158e\0\u02e8\0\u15cc\0\u160a"+\r
+ "\0\u160a\0\272\0\272\0\272\0\u1648\0\272\0\u1686\0\u16c4"+\r
+ "\0\272\0\u01b2\0\u1702\0\u1740\0\u177e\0\u17bc\0\u17fa\0\u1838"+\r
+ "\0\370\0\u1876\0\u18b4\0\u18f2\0\u1930\0\u196e\0\u19ac\0\u19ea"+\r
+ "\0\u1a28\0\u1a66\0\u1aa4\0\u1ae2\0\u1b20\0\u1b5e\0\u1b9c\0\u1bda"+\r
+ "\0\u1c18\0\u1c56\0\u1c94\0\u1cd2\0\u1d10\0\u1d4e\0\370\0\272"+\r
+ "\0\u1d8c\0\272\0\u1dca\0\u1e08\0\u01b2\0\u1e46\0\u1e84\0\370"+\r
+ "\0\u1ec2\0\u1f00\0\u1f3e\0\u1f7c\0\u1fba\0\u1ff8\0\370\0\370"+\r
+ "\0\u2036\0\u2074\0\370\0\u20b2\0\u20f0\0\u212e\0\370\0\u216c"+\r
+ "\0\370\0\u21aa\0\u21e8\0\370\0\u2226\0\u2264\0\u22a2\0\u22e0"+\r
+ "\0\272\0\u231e\0\u235c\0\u239a\0\u23d8\0\u2416\0\u2454\0\u2492"+\r
+ "\0\u24d0\0\u250e\0\u254c\0\u258a\0\u25c8\0\u2606\0\370\0\u2644"+\r
+ "\0\370\0\u2682\0\370\0\u26c0\0\u26fe\0\272\0\370\0\u273c"+\r
+ "\0\370\0\370\0\u277a\0\u27b8\0\u27f6\0\u2834\0\370\0\370"+\r
+ "\0\u2872\0\u28b0\0\u28ee\0\u292c\0\u296a\0\u29a8\0\272\0\u29e6"+\r
+ "\0\u2a24\0\370\0\u2a62\0\u2aa0\0\370\0\370\0\u2ade\0\u2b1c"+\r
"\0\u2b5a\0\u2b98\0\u2bd6\0\370\0\u2c14\0\u2c52\0\u2c90\0\u2cce"+\r
- "\0\u2d0c\0\u2d4a\0\u2d88\0\u2dc6\0\u2e04\0\u2e42\0\u2e80\0\272"+\r
- "\0\u2ebe\0\u2efc\0\272\0\u2f3a\0\u2f78\0\u2fb6\0\370\0\u2ff4"+\r
- "\0\u3032\0\272\0\u3070\0\272";\r
+ "\0\u2d0c\0\370\0\u2d4a\0\u2d88\0\u2dc6\0\u2e04\0\u2e42\0\u2e80"+\r
+ "\0\u2ebe\0\u2efc\0\u2f3a\0\370\0\u2f78\0\u2fb6\0\u2ff4\0\370"+\r
+ "\0\u3032\0\u3070\0\u30ae\0\u30ec\0\u312a\0\u3168\0\u31a6\0\u31e4"+\r
+ "\0\272\0\u3222\0\u3260\0\272\0\u329e\0\u32dc\0\u331a\0\370"+\r
+ "\0\u3358\0\u3396\0\272\0\u33d4\0\272";\r
\r
private static int [] zzUnpackRowMap() {\r
- int [] result = new int[276];\r
+ int [] result = new int[293];\r
int offset = 0;\r
offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result);\r
return result;\r
"\12\0\1\6\6\0\30\6\11\0\1\6\5\0\1\7"+\r
"\4\0\1\77\12\0\1\100\16\0\1\100\34\0\4\101"+\r
"\1\0\22\101\1\0\1\102\45\101\5\0\2\11\1\0"+\r
- "\1\11\3\0\1\11\2\0\3\11\1\0\1\11\1\0"+\r
- "\2\11\1\0\1\11\34\0\2\11\1\0\1\11\12\0"+\r
- "\2\11\1\0\1\11\3\0\1\11\1\103\1\0\3\11"+\r
- "\1\0\1\11\1\103\2\11\1\0\1\11\34\0\2\11"+\r
- "\1\0\1\11\3\0\1\103\10\0\1\104\5\0\1\105"+\r
- "\6\0\1\105\47\0\1\105\2\0\1\106\1\0\1\106"+\r
- "\1\0\2\11\1\0\1\11\3\0\1\11\2\0\3\11"+\r
- "\1\106\1\11\1\0\2\11\1\0\1\11\30\106\4\0"+\r
- "\2\11\1\0\1\11\1\0\1\106\10\0\2\107\1\110"+\r
- "\1\107\1\0\1\111\1\0\1\107\2\0\3\107\1\0"+\r
- "\1\107\1\0\2\107\1\0\1\107\34\0\2\107\1\0"+\r
- "\1\107\6\0\1\112\1\0\1\112\1\0\2\11\1\0"+\r
- "\1\11\3\0\1\11\2\0\3\11\1\112\1\11\1\0"+\r
- "\2\11\1\0\1\11\30\112\4\0\2\11\1\0\1\11"+\r
- "\1\0\1\112\77\0\1\62\2\0\1\113\1\0\1\113"+\r
- "\5\0\1\114\2\0\1\115\5\0\1\113\6\0\30\113"+\r
- "\11\0\1\113\10\0\2\11\1\0\1\11\3\0\1\116"+\r
- "\2\0\1\11\1\116\1\11\1\0\1\117\1\0\2\11"+\r
- "\1\0\1\11\34\0\2\11\1\0\1\116\12\0\2\11"+\r
- "\1\0\1\11\3\0\1\11\2\0\2\11\1\120\1\0"+\r
+ "\1\11\6\0\3\11\1\0\1\11\1\0\2\11\1\0"+\r
+ "\1\11\34\0\2\11\1\0\1\11\12\0\2\11\1\0"+\r
+ "\1\11\4\0\1\103\1\0\3\11\1\0\1\11\1\103"+\r
+ "\2\11\1\0\1\11\34\0\2\11\1\0\1\11\3\0"+\r
+ "\1\103\10\0\1\104\5\0\1\105\6\0\1\105\47\0"+\r
+ "\1\105\2\0\1\106\1\0\1\106\1\0\2\11\1\0"+\r
+ "\1\11\6\0\3\11\1\106\1\11\1\0\2\11\1\0"+\r
+ "\1\11\30\106\4\0\2\11\1\0\1\11\1\0\1\106"+\r
+ "\10\0\2\107\1\110\1\107\1\0\1\111\4\0\3\107"+\r
+ "\1\0\1\107\1\0\2\107\1\0\1\107\34\0\2\107"+\r
+ "\1\0\1\107\6\0\1\112\1\0\1\112\16\0\1\112"+\r
+ "\6\0\30\112\11\0\1\112\77\0\1\62\2\0\1\113"+\r
+ "\1\0\1\113\5\0\1\114\2\0\1\115\5\0\1\113"+\r
+ "\6\0\30\113\11\0\1\113\10\0\2\11\1\0\1\11"+\r
+ "\3\0\1\116\2\0\1\11\1\117\1\11\1\0\1\120"+\r
+ "\1\0\2\11\1\0\1\11\34\0\2\11\1\0\1\117"+\r
+ "\12\0\2\11\1\0\1\11\6\0\2\11\1\121\1\0"+\r
"\1\11\1\0\2\11\1\0\1\11\34\0\2\11\1\0"+\r
- "\1\11\31\0\1\26\56\0\2\11\1\0\1\11\3\0"+\r
- "\1\11\2\0\3\11\1\0\1\11\1\0\1\121\1\122"+\r
- "\1\0\1\11\34\0\2\11\1\0\1\11\6\0\4\6"+\r
- "\2\0\1\76\12\0\1\6\6\0\1\6\1\123\26\6"+\r
+ "\1\11\31\0\1\26\56\0\2\11\1\0\1\11\6\0"+\r
+ "\3\11\1\0\1\11\1\0\1\122\1\123\1\0\1\11"+\r
+ "\34\0\2\11\1\0\1\11\12\0\2\11\1\0\1\11"+\r
+ "\6\0\3\11\1\0\1\11\1\124\2\11\1\0\1\11"+\r
+ "\21\0\1\125\12\0\2\11\1\0\1\11\6\0\4\6"+\r
+ "\2\0\1\76\12\0\1\6\6\0\1\6\1\126\26\6"+\r
"\11\0\1\6\4\0\4\6\2\0\1\76\12\0\1\6"+\r
- "\6\0\14\6\1\124\13\6\11\0\1\6\4\0\4\6"+\r
- "\2\0\1\76\12\0\1\6\6\0\12\6\1\125\2\6"+\r
- "\1\126\12\6\11\0\1\6\4\0\4\6\2\0\1\76"+\r
- "\12\0\1\6\6\0\10\6\1\127\17\6\11\0\1\6"+\r
- "\4\0\4\6\2\0\1\76\12\0\1\6\6\0\1\130"+\r
- "\10\6\1\131\7\6\1\132\6\6\11\0\1\6\4\0"+\r
- "\4\6\2\0\1\76\12\0\1\6\6\0\2\6\1\133"+\r
- "\4\6\1\134\16\6\1\135\1\6\11\0\1\6\4\0"+\r
- "\4\6\2\0\1\76\12\0\1\6\6\0\5\6\1\136"+\r
+ "\6\0\14\6\1\127\13\6\11\0\1\6\4\0\4\6"+\r
+ "\2\0\1\76\12\0\1\6\6\0\12\6\1\130\2\6"+\r
+ "\1\131\12\6\11\0\1\6\4\0\4\6\2\0\1\76"+\r
+ "\12\0\1\6\6\0\10\6\1\132\17\6\11\0\1\6"+\r
+ "\4\0\4\6\2\0\1\76\12\0\1\6\6\0\1\133"+\r
+ "\10\6\1\134\7\6\1\135\6\6\11\0\1\6\4\0"+\r
+ "\4\6\2\0\1\76\12\0\1\6\6\0\2\6\1\136"+\r
+ "\4\6\1\137\16\6\1\140\1\6\11\0\1\6\4\0"+\r
+ "\4\6\2\0\1\76\12\0\1\6\6\0\5\6\1\141"+\r
"\22\6\11\0\1\6\4\0\4\6\2\0\1\76\12\0"+\r
- "\1\6\6\0\1\137\3\6\1\140\4\6\1\141\5\6"+\r
- "\1\142\4\6\1\143\3\6\11\0\1\6\4\0\4\6"+\r
- "\2\0\1\76\12\0\1\6\6\0\10\6\1\144\17\6"+\r
+ "\1\6\6\0\1\142\3\6\1\143\4\6\1\144\5\6"+\r
+ "\1\145\4\6\1\146\3\6\11\0\1\6\4\0\4\6"+\r
+ "\2\0\1\76\12\0\1\6\6\0\10\6\1\147\17\6"+\r
"\11\0\1\6\4\0\4\6\2\0\1\76\12\0\1\6"+\r
- "\6\0\5\6\1\145\1\6\1\146\20\6\11\0\1\6"+\r
+ "\6\0\5\6\1\150\1\6\1\151\20\6\11\0\1\6"+\r
"\4\0\4\6\2\0\1\76\12\0\1\6\6\0\26\6"+\r
- "\1\147\1\6\11\0\1\6\4\0\4\6\2\0\1\76"+\r
- "\12\0\1\6\6\0\4\6\1\150\23\6\11\0\1\6"+\r
- "\4\0\4\6\2\0\1\76\12\0\1\6\6\0\1\6"+\r
- "\1\151\1\6\1\152\4\6\1\153\17\6\11\0\1\6"+\r
- "\4\0\4\6\2\0\1\76\12\0\1\6\6\0\3\6"+\r
- "\1\154\14\6\1\155\7\6\11\0\1\6\10\0\2\11"+\r
- "\1\0\1\11\3\0\1\11\2\0\2\11\1\156\1\0"+\r
- "\1\11\1\0\2\11\1\0\1\11\34\0\2\11\1\0"+\r
- "\1\11\12\0\2\11\1\0\1\11\3\0\1\11\2\0"+\r
- "\3\11\1\0\1\157\1\0\2\11\1\0\1\11\34\0"+\r
- "\1\11\1\160\1\0\1\11\76\0\1\161\4\0\15\64"+\r
- "\1\0\11\64\2\0\40\64\1\0\2\64\1\0\1\64"+\r
- "\74\0\1\70\1\0\4\162\1\163\4\162\1\164\3\162"+\r
- "\1\0\12\162\1\163\2\162\1\165\3\162\1\166\2\162"+\r
- "\1\75\2\162\1\167\23\162\1\163\1\162\2\0\1\162"+\r
- "\74\0\1\75\12\0\1\170\155\0\1\171\5\0\1\6"+\r
- "\1\0\1\6\10\0\1\172\5\0\1\6\6\0\30\6"+\r
- "\11\0\1\6\5\0\1\173\75\0\1\174\20\0\1\175"+\r
- "\56\0\1\176\71\0\27\101\1\0\46\101\15\0\1\103"+\r
- "\6\0\1\103\47\0\1\103\16\0\1\105\6\0\1\105"+\r
- "\47\0\1\105\2\0\4\106\15\0\1\106\6\0\30\106"+\r
- "\11\0\1\106\10\0\2\107\1\0\1\107\2\0\1\177"+\r
- "\1\107\2\0\3\107\1\0\1\107\1\0\2\107\1\0"+\r
- "\1\107\34\0\2\107\1\0\1\107\20\0\1\177\74\0"+\r
- "\1\111\1\200\63\0\4\112\15\0\1\112\6\0\30\112"+\r
- "\11\0\1\112\4\0\4\113\2\0\1\201\6\0\1\202"+\r
- "\3\0\1\113\6\0\30\113\11\0\1\113\15\0\1\203"+\r
- "\64\0\1\204\1\0\1\204\16\0\1\204\6\0\30\204"+\r
- "\11\0\1\204\10\0\2\11\1\0\1\11\3\0\1\11"+\r
- "\2\0\2\11\1\205\1\0\1\11\1\0\2\11\1\0"+\r
- "\1\11\34\0\2\11\1\0\1\11\5\0\15\121\1\0"+\r
- "\56\121\1\0\1\121\5\206\2\122\1\206\1\122\3\206"+\r
- "\1\122\2\206\3\122\1\206\1\122\1\206\1\122\1\207"+\r
- "\1\206\1\122\34\206\2\122\1\206\1\122\5\206\1\0"+\r
- "\4\6\2\0\1\76\12\0\1\6\6\0\2\6\1\210"+\r
- "\25\6\11\0\1\6\4\0\4\6\2\0\1\76\12\0"+\r
- "\1\6\6\0\4\6\1\211\23\6\11\0\1\6\4\0"+\r
- "\4\6\2\0\1\76\12\0\1\6\6\0\12\6\1\212"+\r
- "\15\6\11\0\1\6\4\0\4\6\2\0\1\76\12\0"+\r
- "\1\6\6\0\6\6\1\213\21\6\11\0\1\6\4\0"+\r
- "\4\6\2\0\1\76\12\0\1\6\6\0\1\214\11\6"+\r
- "\1\215\3\6\1\216\11\6\11\0\1\6\4\0\4\6"+\r
- "\2\0\1\76\12\0\1\6\6\0\22\6\1\217\5\6"+\r
- "\11\0\1\6\4\0\4\6\2\0\1\76\12\0\1\6"+\r
- "\6\0\3\6\1\220\24\6\11\0\1\6\4\0\4\6"+\r
- "\2\0\1\76\12\0\1\6\6\0\10\6\1\221\17\6"+\r
- "\11\0\1\6\4\0\4\6\2\0\1\76\12\0\1\6"+\r
- "\6\0\22\6\1\222\5\6\11\0\1\6\4\0\4\6"+\r
- "\2\0\1\76\12\0\1\6\6\0\20\6\1\223\7\6"+\r
- "\11\0\1\6\4\0\4\6\2\0\1\76\12\0\1\6"+\r
- "\6\0\1\224\27\6\11\0\1\6\4\0\4\6\2\0"+\r
- "\1\76\12\0\1\6\6\0\12\6\1\225\15\6\11\0"+\r
- "\1\6\4\0\4\6\2\0\1\76\12\0\1\6\6\0"+\r
- "\1\226\27\6\11\0\1\6\4\0\4\6\2\0\1\76"+\r
- "\12\0\1\6\6\0\6\6\1\227\21\6\11\0\1\6"+\r
- "\4\0\4\6\2\0\1\76\12\0\1\6\6\0\4\6"+\r
- "\1\230\23\6\11\0\1\6\4\0\4\6\2\0\1\76"+\r
- "\12\0\1\6\6\0\6\6\1\231\21\6\11\0\1\6"+\r
- "\4\0\4\6\2\0\1\76\12\0\1\6\6\0\10\6"+\r
- "\1\232\17\6\11\0\1\6\4\0\4\6\2\0\1\76"+\r
- "\12\0\1\6\6\0\3\6\1\233\24\6\11\0\1\6"+\r
- "\4\0\4\6\2\0\1\76\12\0\1\6\6\0\6\6"+\r
- "\1\234\21\6\11\0\1\6\4\0\4\6\2\0\1\76"+\r
- "\12\0\1\6\6\0\2\6\1\235\25\6\11\0\1\6"+\r
- "\4\0\4\6\2\0\1\76\12\0\1\6\6\0\6\6"+\r
- "\1\236\13\6\1\237\5\6\11\0\1\6\4\0\4\6"+\r
- "\2\0\1\76\12\0\1\6\6\0\1\6\1\240\26\6"+\r
- "\11\0\1\6\74\0\1\241\6\0\2\242\16\0\1\242"+\r
- "\6\0\1\242\2\0\1\242\4\0\1\242\4\0\2\242"+\r
- "\1\0\1\242\115\0\1\243\5\0\1\112\1\0\1\112"+\r
- "\16\0\1\112\6\0\30\112\11\0\1\112\5\0\1\173"+\r
- "\17\0\1\100\16\0\1\100\36\0\1\174\74\0\1\113"+\r
- "\1\0\1\113\10\0\1\115\5\0\1\113\6\0\30\113"+\r
- "\11\0\1\113\15\0\1\203\1\244\63\0\4\204\11\0"+\r
- "\1\202\3\0\1\204\6\0\30\204\11\0\1\204\3\0"+\r
- "\26\206\1\245\54\206\2\122\1\206\1\122\3\206\1\122"+\r
- "\2\206\3\122\1\206\1\122\1\206\1\246\1\207\1\206"+\r
- "\1\122\34\206\2\122\1\206\1\122\5\206\1\0\4\6"+\r
- "\2\0\1\76\12\0\1\6\6\0\3\6\1\247\24\6"+\r
- "\11\0\1\6\4\0\4\6\2\0\1\76\12\0\1\6"+\r
- "\6\0\10\6\1\250\17\6\11\0\1\6\4\0\4\6"+\r
- "\2\0\1\76\12\0\1\6\6\0\6\6\1\251\21\6"+\r
- "\11\0\1\6\4\0\4\6\2\0\1\76\12\0\1\6"+\r
- "\6\0\5\6\1\252\22\6\11\0\1\6\4\0\4\6"+\r
- "\2\0\1\76\12\0\1\6\6\0\6\6\1\253\21\6"+\r
- "\11\0\1\6\4\0\4\6\2\0\1\76\12\0\1\6"+\r
- "\6\0\4\6\1\254\23\6\11\0\1\6\4\0\4\6"+\r
- "\2\0\1\76\12\0\1\6\6\0\1\6\1\255\26\6"+\r
- "\11\0\1\6\4\0\4\6\2\0\1\76\12\0\1\6"+\r
- "\6\0\11\6\1\256\16\6\11\0\1\6\4\0\4\6"+\r
- "\2\0\1\76\12\0\1\6\6\0\11\6\1\257\16\6"+\r
- "\11\0\1\6\4\0\4\6\2\0\1\76\12\0\1\6"+\r
- "\6\0\10\6\1\260\17\6\11\0\1\6\4\0\4\6"+\r
- "\2\0\1\76\12\0\1\6\6\0\5\6\1\261\22\6"+\r
+ "\1\152\1\6\11\0\1\6\4\0\4\6\2\0\1\76"+\r
+ "\12\0\1\6\6\0\1\6\1\153\2\6\1\154\23\6"+\r
"\11\0\1\6\4\0\4\6\2\0\1\76\12\0\1\6"+\r
- "\6\0\10\6\1\262\17\6\11\0\1\6\4\0\4\6"+\r
- "\2\0\1\76\12\0\1\6\6\0\10\6\1\263\17\6"+\r
+ "\6\0\1\6\1\155\1\6\1\156\4\6\1\157\17\6"+\r
"\11\0\1\6\4\0\4\6\2\0\1\76\12\0\1\6"+\r
- "\6\0\1\6\1\264\26\6\11\0\1\6\4\0\4\6"+\r
- "\2\0\1\76\12\0\1\6\6\0\10\6\1\265\17\6"+\r
- "\11\0\1\6\4\0\4\6\2\0\1\76\12\0\1\6"+\r
- "\6\0\10\6\1\266\17\6\11\0\1\6\4\0\4\6"+\r
- "\2\0\1\76\12\0\1\6\6\0\7\6\1\267\20\6"+\r
- "\11\0\1\6\4\0\4\6\2\0\1\76\12\0\1\6"+\r
- "\6\0\2\6\1\270\6\6\1\271\16\6\11\0\1\6"+\r
+ "\6\0\3\6\1\160\14\6\1\161\7\6\11\0\1\6"+\r
+ "\10\0\2\11\1\0\1\11\6\0\2\11\1\162\1\0"+\r
+ "\1\11\1\0\2\11\1\0\1\11\34\0\2\11\1\0"+\r
+ "\1\11\12\0\2\11\1\0\1\11\6\0\3\11\1\0"+\r
+ "\1\163\1\0\2\11\1\0\1\11\34\0\1\11\1\164"+\r
+ "\1\0\1\11\76\0\1\165\4\0\15\64\1\0\11\64"+\r
+ "\2\0\40\64\1\0\2\64\1\0\1\64\74\0\1\70"+\r
+ "\1\0\4\166\1\167\4\166\1\170\3\166\1\0\12\166"+\r
+ "\1\167\2\166\1\171\3\166\1\172\2\166\1\75\2\166"+\r
+ "\1\173\23\166\1\167\1\166\2\0\1\166\74\0\1\75"+\r
+ "\12\0\1\174\155\0\1\175\5\0\1\6\1\0\1\6"+\r
+ "\10\0\1\176\5\0\1\6\6\0\30\6\11\0\1\6"+\r
+ "\5\0\1\177\75\0\1\200\20\0\1\201\56\0\1\202"+\r
+ "\71\0\27\101\1\0\46\101\15\0\1\103\6\0\1\103"+\r
+ "\47\0\1\103\16\0\1\105\6\0\1\105\47\0\1\105"+\r
+ "\2\0\4\106\15\0\1\106\6\0\30\106\11\0\1\106"+\r
+ "\10\0\2\107\1\0\1\107\2\0\1\203\3\0\3\107"+\r
+ "\1\0\1\107\1\0\2\107\1\0\1\107\34\0\2\107"+\r
+ "\1\0\1\107\20\0\1\203\74\0\1\111\1\204\63\0"+\r
+ "\4\112\15\0\1\112\6\0\30\112\11\0\1\112\4\0"+\r
+ "\4\113\2\0\1\205\6\0\1\206\3\0\1\113\6\0"+\r
+ "\30\113\11\0\1\113\15\0\1\207\64\0\1\210\1\0"+\r
+ "\1\210\16\0\1\210\6\0\30\210\11\0\1\210\24\0"+\r
+ "\1\211\61\0\2\11\1\0\1\11\6\0\2\11\1\212"+\r
+ "\1\0\1\11\1\0\2\11\1\0\1\11\34\0\2\11"+\r
+ "\1\0\1\11\5\0\15\122\1\0\56\122\1\0\1\122"+\r
+ "\5\213\2\123\1\213\1\123\6\213\3\123\1\213\1\123"+\r
+ "\1\213\1\123\1\214\1\213\1\123\34\213\2\123\1\213"+\r
+ "\1\123\5\213\24\0\1\124\25\0\1\125\57\0\1\215"+\r
+ "\42\0\4\6\2\0\1\76\12\0\1\6\6\0\2\6"+\r
+ "\1\216\25\6\11\0\1\6\4\0\4\6\2\0\1\76"+\r
+ "\12\0\1\6\6\0\4\6\1\217\23\6\11\0\1\6"+\r
"\4\0\4\6\2\0\1\76\12\0\1\6\6\0\12\6"+\r
- "\1\272\15\6\11\0\1\6\4\0\4\6\2\0\1\76"+\r
- "\12\0\1\6\6\0\3\6\1\273\24\6\11\0\1\6"+\r
- "\4\0\4\6\2\0\1\76\12\0\1\6\6\0\5\6"+\r
- "\1\274\22\6\11\0\1\6\4\0\4\6\2\0\1\76"+\r
- "\12\0\1\6\6\0\16\6\1\275\11\6\11\0\1\6"+\r
- "\4\0\4\6\2\0\1\76\12\0\1\6\6\0\22\6"+\r
- "\1\276\5\6\11\0\1\6\5\0\2\277\16\0\1\277"+\r
- "\6\0\1\277\2\0\1\277\4\0\1\277\4\0\2\277"+\r
- "\1\0\1\277\42\0\1\202\57\0\25\206\1\300\1\245"+\r
- "\47\206\1\0\4\6\2\0\1\76\12\0\1\6\6\0"+\r
- "\4\6\1\301\23\6\11\0\1\6\4\0\4\6\2\0"+\r
- "\1\76\12\0\1\6\6\0\2\6\1\302\25\6\11\0"+\r
+ "\1\220\15\6\11\0\1\6\4\0\4\6\2\0\1\76"+\r
+ "\12\0\1\6\6\0\6\6\1\221\21\6\11\0\1\6"+\r
+ "\4\0\4\6\2\0\1\76\12\0\1\6\6\0\1\222"+\r
+ "\11\6\1\223\3\6\1\224\11\6\11\0\1\6\4\0"+\r
+ "\4\6\2\0\1\76\12\0\1\6\6\0\22\6\1\225"+\r
+ "\5\6\11\0\1\6\4\0\4\6\2\0\1\76\12\0"+\r
+ "\1\6\6\0\3\6\1\226\24\6\11\0\1\6\4\0"+\r
+ "\4\6\2\0\1\76\12\0\1\6\6\0\10\6\1\227"+\r
+ "\17\6\11\0\1\6\4\0\4\6\2\0\1\76\12\0"+\r
+ "\1\6\6\0\22\6\1\230\5\6\11\0\1\6\4\0"+\r
+ "\4\6\2\0\1\76\12\0\1\6\6\0\20\6\1\231"+\r
+ "\7\6\11\0\1\6\4\0\4\6\2\0\1\76\12\0"+\r
+ "\1\6\6\0\1\232\27\6\11\0\1\6\4\0\4\6"+\r
+ "\2\0\1\76\12\0\1\6\6\0\12\6\1\233\15\6"+\r
+ "\11\0\1\6\4\0\4\6\2\0\1\76\12\0\1\6"+\r
+ "\6\0\1\234\27\6\11\0\1\6\4\0\4\6\2\0"+\r
+ "\1\76\12\0\1\6\6\0\6\6\1\235\21\6\11\0"+\r
"\1\6\4\0\4\6\2\0\1\76\12\0\1\6\6\0"+\r
- "\17\6\1\303\10\6\11\0\1\6\4\0\4\6\2\0"+\r
- "\1\76\12\0\1\6\6\0\3\6\1\304\24\6\11\0"+\r
+ "\4\6\1\236\23\6\11\0\1\6\4\0\4\6\2\0"+\r
+ "\1\76\12\0\1\6\6\0\6\6\1\237\21\6\11\0"+\r
"\1\6\4\0\4\6\2\0\1\76\12\0\1\6\6\0"+\r
- "\14\6\1\305\13\6\11\0\1\6\4\0\4\6\2\0"+\r
- "\1\76\12\0\1\6\6\0\2\6\1\306\25\6\11\0"+\r
+ "\10\6\1\240\17\6\11\0\1\6\4\0\4\6\2\0"+\r
+ "\1\76\12\0\1\6\6\0\11\6\1\241\16\6\11\0"+\r
"\1\6\4\0\4\6\2\0\1\76\12\0\1\6\6\0"+\r
- "\12\6\1\307\15\6\11\0\1\6\4\0\4\6\2\0"+\r
- "\1\76\12\0\1\6\6\0\11\6\1\310\16\6\11\0"+\r
+ "\3\6\1\242\24\6\11\0\1\6\4\0\4\6\2\0"+\r
+ "\1\76\12\0\1\6\6\0\6\6\1\243\21\6\11\0"+\r
"\1\6\4\0\4\6\2\0\1\76\12\0\1\6\6\0"+\r
- "\16\6\1\311\11\6\11\0\1\6\4\0\4\6\2\0"+\r
- "\1\76\12\0\1\6\6\0\2\6\1\312\25\6\11\0"+\r
+ "\2\6\1\244\25\6\11\0\1\6\4\0\4\6\2\0"+\r
+ "\1\76\12\0\1\6\6\0\6\6\1\245\13\6\1\246"+\r
+ "\5\6\11\0\1\6\4\0\4\6\2\0\1\76\12\0"+\r
+ "\1\6\6\0\1\6\1\247\26\6\11\0\1\6\74\0"+\r
+ "\1\250\6\0\2\251\16\0\1\251\6\0\1\251\2\0"+\r
+ "\1\251\4\0\1\251\4\0\2\251\1\0\1\251\115\0"+\r
+ "\1\252\6\0\1\177\17\0\1\100\16\0\1\100\36\0"+\r
+ "\1\200\74\0\1\113\1\0\1\113\10\0\1\115\5\0"+\r
+ "\1\113\6\0\30\113\11\0\1\113\15\0\1\207\1\253"+\r
+ "\63\0\4\210\11\0\1\206\3\0\1\210\6\0\30\210"+\r
+ "\11\0\1\210\3\0\26\213\1\254\54\213\2\123\1\213"+\r
+ "\1\123\6\213\3\123\1\213\1\123\1\213\1\255\1\214"+\r
+ "\1\213\1\123\34\213\2\123\1\213\1\123\5\213\37\0"+\r
+ "\1\256\37\0\4\6\2\0\1\76\12\0\1\6\6\0"+\r
+ "\3\6\1\257\24\6\11\0\1\6\4\0\4\6\2\0"+\r
+ "\1\76\12\0\1\6\6\0\10\6\1\260\17\6\11\0"+\r
"\1\6\4\0\4\6\2\0\1\76\12\0\1\6\6\0"+\r
- "\11\6\1\313\16\6\11\0\1\6\4\0\4\6\2\0"+\r
- "\1\76\12\0\1\6\6\0\16\6\1\314\11\6\11\0"+\r
+ "\6\6\1\261\21\6\11\0\1\6\4\0\4\6\2\0"+\r
+ "\1\76\12\0\1\6\6\0\5\6\1\262\22\6\11\0"+\r
"\1\6\4\0\4\6\2\0\1\76\12\0\1\6\6\0"+\r
- "\10\6\1\315\17\6\11\0\1\6\4\0\4\6\2\0"+\r
- "\1\76\12\0\1\6\6\0\12\6\1\316\15\6\11\0"+\r
+ "\6\6\1\263\21\6\11\0\1\6\4\0\4\6\2\0"+\r
+ "\1\76\12\0\1\6\6\0\4\6\1\264\23\6\11\0"+\r
"\1\6\4\0\4\6\2\0\1\76\12\0\1\6\6\0"+\r
- "\25\6\1\317\2\6\11\0\1\6\4\0\4\6\2\0"+\r
- "\1\76\12\0\1\6\6\0\7\6\1\320\20\6\11\0"+\r
+ "\1\6\1\265\26\6\11\0\1\6\4\0\4\6\2\0"+\r
+ "\1\76\12\0\1\6\6\0\11\6\1\266\16\6\11\0"+\r
"\1\6\4\0\4\6\2\0\1\76\12\0\1\6\6\0"+\r
- "\5\6\1\321\22\6\11\0\1\6\5\0\2\322\16\0"+\r
- "\1\322\6\0\1\322\2\0\1\322\4\0\1\322\4\0"+\r
- "\2\322\1\0\1\322\25\0\4\6\2\0\1\76\12\0"+\r
- "\1\6\6\0\4\6\1\323\23\6\11\0\1\6\4\0"+\r
- "\4\6\2\0\1\76\12\0\1\6\6\0\3\6\1\324"+\r
- "\24\6\11\0\1\6\4\0\4\6\2\0\1\76\12\0"+\r
- "\1\6\6\0\2\6\1\325\1\6\1\326\23\6\11\0"+\r
+ "\11\6\1\267\16\6\11\0\1\6\4\0\4\6\2\0"+\r
+ "\1\76\12\0\1\6\6\0\10\6\1\270\17\6\11\0"+\r
"\1\6\4\0\4\6\2\0\1\76\12\0\1\6\6\0"+\r
- "\11\6\1\327\16\6\11\0\1\6\4\0\4\6\2\0"+\r
- "\1\76\12\0\1\6\6\0\20\6\1\330\7\6\11\0"+\r
+ "\5\6\1\271\22\6\11\0\1\6\4\0\4\6\2\0"+\r
+ "\1\76\12\0\1\6\6\0\10\6\1\272\17\6\11\0"+\r
"\1\6\4\0\4\6\2\0\1\76\12\0\1\6\6\0"+\r
- "\6\6\1\331\21\6\11\0\1\6\4\0\4\6\2\0"+\r
- "\1\76\12\0\1\6\6\0\1\332\27\6\11\0\1\6"+\r
- "\4\0\4\6\2\0\1\76\12\0\1\6\6\0\23\6"+\r
- "\1\333\4\6\11\0\1\6\4\0\4\6\2\0\1\76"+\r
- "\12\0\1\6\6\0\6\6\1\334\21\6\11\0\1\6"+\r
- "\4\0\4\6\2\0\1\76\12\0\1\6\6\0\16\6"+\r
- "\1\335\11\6\11\0\1\6\4\0\4\6\2\0\1\76"+\r
- "\12\0\1\6\6\0\20\6\1\336\7\6\11\0\1\6"+\r
- "\4\0\4\6\2\0\1\76\12\0\1\6\6\0\6\6"+\r
- "\1\337\21\6\11\0\1\6\4\0\4\6\2\0\1\76"+\r
- "\12\0\1\6\6\0\5\6\1\340\22\6\11\0\1\6"+\r
- "\4\0\4\6\2\0\1\76\12\0\1\6\6\0\11\6"+\r
- "\1\341\16\6\11\0\1\6\5\0\2\342\16\0\1\342"+\r
- "\6\0\1\342\2\0\1\342\4\0\1\342\4\0\2\342"+\r
- "\1\0\1\342\25\0\4\6\2\0\1\76\12\0\1\6"+\r
- "\6\0\16\6\1\343\11\6\11\0\1\6\4\0\4\6"+\r
- "\2\0\1\76\12\0\1\6\6\0\16\6\1\344\11\6"+\r
- "\11\0\1\6\4\0\4\6\2\0\1\76\12\0\1\6"+\r
- "\6\0\10\6\1\345\17\6\11\0\1\6\4\0\4\6"+\r
- "\2\0\1\76\12\0\1\6\6\0\27\6\1\346\11\0"+\r
+ "\10\6\1\273\17\6\11\0\1\6\4\0\4\6\2\0"+\r
+ "\1\76\12\0\1\6\6\0\1\6\1\274\26\6\11\0"+\r
"\1\6\4\0\4\6\2\0\1\76\12\0\1\6\6\0"+\r
- "\1\6\1\347\26\6\11\0\1\6\4\0\4\6\2\0"+\r
- "\1\76\12\0\1\6\6\0\10\6\1\350\17\6\11\0"+\r
+ "\10\6\1\275\17\6\11\0\1\6\4\0\4\6\2\0"+\r
+ "\1\76\12\0\1\6\6\0\10\6\1\276\17\6\11\0"+\r
"\1\6\4\0\4\6\2\0\1\76\12\0\1\6\6\0"+\r
- "\12\6\1\351\15\6\11\0\1\6\4\0\4\6\2\0"+\r
- "\1\76\12\0\1\6\1\0\1\352\4\0\30\6\11\0"+\r
- "\1\6\4\0\4\6\2\0\1\76\12\0\1\6\6\0"+\r
- "\11\6\1\353\16\6\11\0\1\6\4\0\4\6\2\0"+\r
- "\1\76\12\0\1\6\6\0\23\6\1\354\4\6\11\0"+\r
+ "\7\6\1\277\20\6\11\0\1\6\4\0\4\6\2\0"+\r
+ "\1\76\12\0\1\6\6\0\2\6\1\300\6\6\1\301"+\r
+ "\16\6\11\0\1\6\4\0\4\6\2\0\1\76\12\0"+\r
+ "\1\6\6\0\12\6\1\302\15\6\11\0\1\6\4\0"+\r
+ "\4\6\2\0\1\76\12\0\1\6\6\0\12\6\1\303"+\r
+ "\15\6\11\0\1\6\4\0\4\6\2\0\1\76\12\0"+\r
+ "\1\6\6\0\3\6\1\304\24\6\11\0\1\6\4\0"+\r
+ "\4\6\2\0\1\76\12\0\1\6\6\0\5\6\1\305"+\r
+ "\22\6\11\0\1\6\4\0\4\6\2\0\1\76\12\0"+\r
+ "\1\6\6\0\16\6\1\306\11\6\11\0\1\6\4\0"+\r
+ "\4\6\2\0\1\76\12\0\1\6\6\0\22\6\1\307"+\r
+ "\5\6\11\0\1\6\5\0\2\310\16\0\1\310\6\0"+\r
+ "\1\310\2\0\1\310\4\0\1\310\4\0\2\310\1\0"+\r
+ "\1\310\42\0\1\206\57\0\25\213\1\311\1\254\47\213"+\r
+ "\47\0\1\312\27\0\4\6\2\0\1\76\12\0\1\6"+\r
+ "\6\0\4\6\1\313\23\6\11\0\1\6\4\0\4\6"+\r
+ "\2\0\1\76\12\0\1\6\6\0\2\6\1\314\25\6"+\r
+ "\11\0\1\6\4\0\4\6\2\0\1\76\12\0\1\6"+\r
+ "\6\0\17\6\1\315\10\6\11\0\1\6\4\0\4\6"+\r
+ "\2\0\1\76\12\0\1\6\6\0\3\6\1\316\24\6"+\r
+ "\11\0\1\6\4\0\4\6\2\0\1\76\12\0\1\6"+\r
+ "\6\0\14\6\1\317\13\6\11\0\1\6\4\0\4\6"+\r
+ "\2\0\1\76\12\0\1\6\6\0\2\6\1\320\25\6"+\r
+ "\11\0\1\6\4\0\4\6\2\0\1\76\12\0\1\6"+\r
+ "\6\0\12\6\1\321\15\6\11\0\1\6\4\0\4\6"+\r
+ "\2\0\1\76\12\0\1\6\6\0\11\6\1\322\16\6"+\r
+ "\11\0\1\6\4\0\4\6\2\0\1\76\12\0\1\6"+\r
+ "\6\0\16\6\1\323\11\6\11\0\1\6\4\0\4\6"+\r
+ "\2\0\1\76\12\0\1\6\6\0\2\6\1\324\25\6"+\r
+ "\11\0\1\6\4\0\4\6\2\0\1\76\12\0\1\6"+\r
+ "\6\0\11\6\1\325\16\6\11\0\1\6\4\0\4\6"+\r
+ "\2\0\1\76\12\0\1\6\6\0\16\6\1\326\11\6"+\r
+ "\11\0\1\6\4\0\4\6\2\0\1\76\12\0\1\6"+\r
+ "\6\0\10\6\1\327\17\6\11\0\1\6\4\0\4\6"+\r
+ "\2\0\1\76\12\0\1\6\6\0\6\6\1\330\21\6"+\r
+ "\11\0\1\6\4\0\4\6\2\0\1\76\12\0\1\6"+\r
+ "\6\0\12\6\1\331\15\6\11\0\1\6\4\0\4\6"+\r
+ "\2\0\1\76\12\0\1\6\6\0\25\6\1\332\2\6"+\r
+ "\11\0\1\6\4\0\4\6\2\0\1\76\12\0\1\6"+\r
+ "\6\0\7\6\1\333\20\6\11\0\1\6\4\0\4\6"+\r
+ "\2\0\1\76\12\0\1\6\6\0\5\6\1\334\22\6"+\r
+ "\11\0\1\6\5\0\2\335\16\0\1\335\6\0\1\335"+\r
+ "\2\0\1\335\4\0\1\335\4\0\2\335\1\0\1\335"+\r
+ "\64\0\1\336\36\0\4\6\2\0\1\76\12\0\1\6"+\r
+ "\6\0\4\6\1\337\23\6\11\0\1\6\4\0\4\6"+\r
+ "\2\0\1\76\12\0\1\6\6\0\3\6\1\340\24\6"+\r
+ "\11\0\1\6\4\0\4\6\2\0\1\76\12\0\1\6"+\r
+ "\6\0\2\6\1\341\1\6\1\342\23\6\11\0\1\6"+\r
+ "\4\0\4\6\2\0\1\76\12\0\1\6\6\0\11\6"+\r
+ "\1\343\16\6\11\0\1\6\4\0\4\6\2\0\1\76"+\r
+ "\12\0\1\6\6\0\20\6\1\344\7\6\11\0\1\6"+\r
+ "\4\0\4\6\2\0\1\76\12\0\1\6\6\0\6\6"+\r
+ "\1\345\21\6\11\0\1\6\4\0\4\6\2\0\1\76"+\r
+ "\12\0\1\6\6\0\1\346\27\6\11\0\1\6\4\0"+\r
+ "\4\6\2\0\1\76\12\0\1\6\6\0\23\6\1\347"+\r
+ "\4\6\11\0\1\6\4\0\4\6\2\0\1\76\12\0"+\r
+ "\1\6\6\0\6\6\1\350\21\6\11\0\1\6\4\0"+\r
+ "\4\6\2\0\1\76\12\0\1\6\6\0\16\6\1\351"+\r
+ "\11\6\11\0\1\6\4\0\4\6\2\0\1\76\12\0"+\r
+ "\1\6\6\0\20\6\1\352\7\6\11\0\1\6\4\0"+\r
+ "\4\6\2\0\1\76\12\0\1\6\6\0\6\6\1\353"+\r
+ "\21\6\11\0\1\6\4\0\4\6\2\0\1\76\12\0"+\r
+ "\1\6\6\0\2\6\1\354\25\6\11\0\1\6\4\0"+\r
+ "\4\6\2\0\1\76\12\0\1\6\6\0\5\6\1\355"+\r
+ "\22\6\11\0\1\6\4\0\4\6\2\0\1\76\12\0"+\r
+ "\1\6\6\0\11\6\1\356\16\6\11\0\1\6\5\0"+\r
+ "\2\357\16\0\1\357\6\0\1\357\2\0\1\357\4\0"+\r
+ "\1\357\4\0\2\357\1\0\1\357\25\0\4\6\2\0"+\r
+ "\1\76\12\0\1\6\6\0\16\6\1\360\11\6\11\0"+\r
"\1\6\4\0\4\6\2\0\1\76\12\0\1\6\6\0"+\r
- "\6\6\1\355\21\6\11\0\1\6\4\0\4\6\2\0"+\r
- "\1\76\12\0\1\6\6\0\10\6\1\356\17\6\11\0"+\r
+ "\16\6\1\361\11\6\11\0\1\6\4\0\4\6\2\0"+\r
+ "\1\76\12\0\1\6\6\0\10\6\1\362\17\6\11\0"+\r
"\1\6\4\0\4\6\2\0\1\76\12\0\1\6\6\0"+\r
- "\3\6\1\357\24\6\11\0\1\6\4\0\4\6\2\0"+\r
- "\1\76\12\0\1\6\6\0\2\6\1\360\25\6\11\0"+\r
- "\1\6\27\0\1\352\4\0\1\361\17\0\1\362\25\0"+\r
- "\4\6\2\0\1\76\12\0\1\6\6\0\23\6\1\363"+\r
- "\4\6\11\0\1\6\4\0\4\6\2\0\1\76\12\0"+\r
- "\1\6\1\0\1\364\4\0\30\6\11\0\1\6\4\0"+\r
- "\4\6\2\0\1\76\12\0\1\6\1\0\1\365\4\0"+\r
- "\30\6\11\0\1\6\4\0\4\6\2\0\1\76\12\0"+\r
- "\1\6\6\0\25\6\1\366\2\6\11\0\1\6\4\0"+\r
- "\4\6\2\0\1\76\12\0\1\6\6\0\21\6\1\367"+\r
- "\6\6\11\0\1\6\41\0\1\370\75\0\1\371\63\0"+\r
- "\1\364\6\0\1\372\66\0\1\365\6\0\1\373\43\0"+\r
- "\4\6\2\0\1\76\12\0\1\6\6\0\3\6\1\374"+\r
- "\24\6\11\0\1\6\4\0\4\6\2\0\1\76\12\0"+\r
- "\1\6\6\0\3\6\1\375\24\6\11\0\1\6\36\0"+\r
- "\1\376\105\0\1\377\73\0\1\u0100\101\0\1\u0101\31\0"+\r
- "\4\6\2\0\1\76\12\0\1\6\6\0\6\6\1\u0102"+\r
- "\21\6\11\0\1\6\46\0\1\u0103\71\0\1\u0104\73\0"+\r
- "\1\u0105\75\0\1\u0106\41\0\4\6\2\0\1\76\12\0"+\r
- "\1\6\6\0\5\6\1\u0107\22\6\11\0\1\6\42\0"+\r
- "\1\u0108\74\0\1\u0109\73\0\1\u010a\102\0\1\u010b\35\0"+\r
- "\4\6\2\0\1\76\12\0\1\6\6\0\1\6\1\u010c"+\r
- "\26\6\11\0\1\6\45\0\1\u010d\72\0\1\u010e\37\0"+\r
- "\4\6\2\0\1\76\12\0\1\6\6\0\11\6\1\u010f"+\r
- "\16\6\11\0\1\6\52\0\1\u0110\64\0\1\u0111\76\0"+\r
- "\1\u0112\70\0\1\u0113\105\0\1\u0114\33\0";\r
+ "\27\6\1\363\11\0\1\6\4\0\4\6\2\0\1\76"+\r
+ "\12\0\1\6\6\0\1\6\1\364\26\6\11\0\1\6"+\r
+ "\4\0\4\6\2\0\1\76\12\0\1\6\6\0\10\6"+\r
+ "\1\365\17\6\11\0\1\6\4\0\4\6\2\0\1\76"+\r
+ "\12\0\1\6\6\0\12\6\1\366\15\6\11\0\1\6"+\r
+ "\4\0\4\6\2\0\1\76\12\0\1\6\1\0\1\367"+\r
+ "\4\0\30\6\11\0\1\6\4\0\4\6\2\0\1\76"+\r
+ "\12\0\1\6\6\0\3\6\1\370\24\6\11\0\1\6"+\r
+ "\4\0\4\6\2\0\1\76\12\0\1\6\6\0\11\6"+\r
+ "\1\371\16\6\11\0\1\6\4\0\4\6\2\0\1\76"+\r
+ "\12\0\1\6\6\0\23\6\1\372\4\6\11\0\1\6"+\r
+ "\4\0\4\6\2\0\1\76\12\0\1\6\6\0\6\6"+\r
+ "\1\373\21\6\11\0\1\6\4\0\4\6\2\0\1\76"+\r
+ "\12\0\1\6\6\0\10\6\1\374\17\6\11\0\1\6"+\r
+ "\4\0\4\6\2\0\1\76\12\0\1\6\6\0\3\6"+\r
+ "\1\375\24\6\11\0\1\6\4\0\4\6\2\0\1\76"+\r
+ "\12\0\1\6\6\0\2\6\1\376\25\6\11\0\1\6"+\r
+ "\27\0\1\367\4\0\1\377\17\0\1\u0100\25\0\4\6"+\r
+ "\2\0\1\76\12\0\1\6\6\0\5\6\1\u0101\22\6"+\r
+ "\11\0\1\6\4\0\4\6\2\0\1\76\12\0\1\6"+\r
+ "\6\0\23\6\1\u0102\4\6\11\0\1\6\4\0\4\6"+\r
+ "\2\0\1\76\12\0\1\6\1\0\1\u0103\4\0\30\6"+\r
+ "\11\0\1\6\4\0\4\6\2\0\1\76\12\0\1\6"+\r
+ "\1\0\1\u0104\4\0\30\6\11\0\1\6\4\0\4\6"+\r
+ "\2\0\1\76\12\0\1\6\6\0\25\6\1\u0105\2\6"+\r
+ "\11\0\1\6\4\0\4\6\2\0\1\76\12\0\1\6"+\r
+ "\6\0\21\6\1\u0106\6\6\11\0\1\6\41\0\1\u0107"+\r
+ "\75\0\1\u0108\40\0\4\6\2\0\1\76\12\0\1\6"+\r
+ "\6\0\11\6\1\u0109\16\6\11\0\1\6\27\0\1\u0103"+\r
+ "\6\0\1\u010a\66\0\1\u0104\6\0\1\u010b\43\0\4\6"+\r
+ "\2\0\1\76\12\0\1\6\6\0\3\6\1\u010c\24\6"+\r
+ "\11\0\1\6\4\0\4\6\2\0\1\76\12\0\1\6"+\r
+ "\6\0\3\6\1\u010d\24\6\11\0\1\6\36\0\1\u010e"+\r
+ "\105\0\1\u010f\33\0\4\6\2\0\1\76\12\0\1\6"+\r
+ "\6\0\6\6\1\u0110\21\6\11\0\1\6\44\0\1\u0111"+\r
+ "\101\0\1\u0112\31\0\4\6\2\0\1\76\12\0\1\6"+\r
+ "\6\0\6\6\1\u0113\21\6\11\0\1\6\46\0\1\u0114"+\r
+ "\71\0\1\u0115\73\0\1\u0116\75\0\1\u0117\41\0\4\6"+\r
+ "\2\0\1\76\12\0\1\6\6\0\5\6\1\u0118\22\6"+\r
+ "\11\0\1\6\42\0\1\u0119\74\0\1\u011a\73\0\1\u011b"+\r
+ "\102\0\1\u011c\35\0\4\6\2\0\1\76\12\0\1\6"+\r
+ "\6\0\1\6\1\u011d\26\6\11\0\1\6\45\0\1\u011e"+\r
+ "\72\0\1\u011f\37\0\4\6\2\0\1\76\12\0\1\6"+\r
+ "\6\0\11\6\1\u0120\16\6\11\0\1\6\52\0\1\u0121"+\r
+ "\64\0\1\u0122\76\0\1\u0123\70\0\1\u0124\105\0\1\u0125"+\r
+ "\33\0";\r
\r
private static int [] zzUnpackTrans() {\r
- int [] result = new int[12462];\r
+ int [] result = new int[13330];\r
int offset = 0;\r
offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result);\r
return result;\r
"\3\0\1\10\1\11\10\1\2\11\10\1\1\11\17\1"+\r
"\4\11\2\1\1\11\3\1\2\11\2\1\1\0\2\11"+\r
"\4\1\1\11\5\0\1\1\1\11\2\1\3\0\1\1"+\r
- "\3\0\43\1\1\0\5\11\1\1\1\11\2\0\2\1"+\r
- "\1\0\3\11\1\0\1\11\2\0\1\1\1\0\32\1"+\r
- "\1\11\1\0\1\11\2\0\31\1\1\0\1\11\21\1"+\r
- "\1\0\17\1\1\11\7\1\1\0\6\1\2\0\1\1"+\r
- "\2\0\2\1\4\0\2\1\4\0\1\1\4\0\1\1"+\r
- "\1\11\2\0\1\11\1\1\2\0\1\1\2\0\1\11"+\r
- "\1\0\1\11";\r
+ "\4\0\5\1\2\0\37\1\1\0\5\11\1\1\1\11"+\r
+ "\2\0\2\1\1\0\3\11\1\0\1\11\2\0\1\11"+\r
+ "\1\1\1\0\1\1\1\0\32\1\1\11\1\0\1\11"+\r
+ "\2\0\1\1\1\0\31\1\1\0\1\11\1\0\22\1"+\r
+ "\1\0\1\11\20\1\1\11\7\1\1\0\7\1\2\0"+\r
+ "\2\1\2\0\2\1\2\0\1\1\2\0\2\1\2\0"+\r
+ "\1\1\2\0\1\1\4\0\1\1\1\11\2\0\1\11"+\r
+ "\1\1\2\0\1\1\2\0\1\11\1\0\1\11";\r
\r
private static int [] zzUnpackAttribute() {\r
- int [] result = new int[276];\r
+ int [] result = new int[293];\r
int offset = 0;\r
offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result);\r
return result;\r
private int zzFinalHighSurrogate = 0;\r
\r
/* user code: */\r
- public SCLParserOptions options = SCLParserOptions.DEFAULT;\r
- int stringStart;\r
- TIntArrayList parenCountStack = new TIntArrayList(2);\r
- int parenCount = 0;\r
- TIntArrayList stateStack = new TIntArrayList(2);\r
-\r
- StringBuffer string = new StringBuffer();\r
- \r
- private Token sym(int id) {\r
- return new Token(id, yychar, yychar+yylength(), yytext());\r
- }\r
- private Token sym(int id, String text) {\r
- return new Token(id, yychar, yychar+yylength(), text);\r
- }\r
+ public SCLParserOptions options = SCLParserOptions.DEFAULT;
+ int stringStart;
+ TIntArrayList parenCountStack = new TIntArrayList(2);
+ int parenCount = 0;
+ TIntArrayList stateStack = new TIntArrayList(2);
+
+ StringBuffer string = new StringBuffer();
+
+ private Token sym(int id) {
+ return new Token(id, yychar, yychar+yylength(), yytext());
+ }
+ private Token sym(int id, String text) {
+ return new Token(id, yychar, yychar+yylength(), text);
+ }
\r
\r
/**\r
case STRING: {\r
throw new SCLSyntaxErrorException(Locations.location(stringStart, yychar), "Unclosed string literal.");\r
}\r
- case 277: break;\r
+ case 294: break;\r
case LONG_STRING: {\r
throw new SCLSyntaxErrorException(Locations.location(stringStart, yychar), "Unclosed string literal.");\r
}\r
- case 278: break;\r
+ case 295: break;\r
default:\r
- { return sym(SCLTerminals.EOF);\r
+ { return sym(SCLTerminals.EOF);
}\r
}\r
}\r
case 1: \r
{ throw new SCLSyntaxErrorException(Locations.location(yychar, yychar+1), "Illegal character '" + yytext() + "'.");\r
}\r
- case 93: break;\r
+ case 95: break;\r
case 2: \r
{ return sym(SCLTerminals.ID);\r
}\r
- case 94: break;\r
+ case 96: break;\r
case 3: \r
{ return sym(SCLTerminals.INTEGER);\r
}\r
- case 95: break;\r
+ case 97: break;\r
case 4: \r
{ return sym(SCLTerminals.SYMBOL, yytext().trim());\r
}\r
- case 96: break;\r
+ case 98: break;\r
case 5: \r
{ return sym(SCLTerminals.ATTACHED_HASH, "#");\r
}\r
- case 97: break;\r
+ case 99: break;\r
case 6: \r
{ return sym(SCLTerminals.ATTACHED_DOT, ".");\r
}\r
- case 98: break;\r
+ case 100: break;\r
case 7: \r
{ return sym(SCLTerminals.AT);\r
}\r
- case 99: break;\r
+ case 101: break;\r
case 8: \r
{ ++parenCount; return sym(SCLTerminals.LPAREN);\r
}\r
- case 100: break;\r
+ case 102: break;\r
case 9: \r
{ return sym(SCLTerminals.COMMA);\r
}\r
- case 101: break;\r
+ case 103: break;\r
case 10: \r
- { --parenCount;\r
- if(parenCount == 0 && !parenCountStack.isEmpty()) { \r
- parenCount = parenCountStack.removeAt(parenCountStack.size()-1);\r
- string.setLength(0);\r
- stringStart=yychar;\r
- yybegin(stateStack.removeAt(stateStack.size()-1));\r
- return sym(SCLTerminals.CONTINUE_STRING);\r
- }\r
- else\r
+ { --parenCount;
+ if(parenCount == 0 && !parenCountStack.isEmpty()) {
+ parenCount = parenCountStack.removeAt(parenCountStack.size()-1);
+ string.setLength(0);
+ stringStart=yychar;
+ yybegin(stateStack.removeAt(stateStack.size()-1));
+ return sym(SCLTerminals.CONTINUE_STRING);
+ }
+ else
return sym(SCLTerminals.RPAREN);\r
}\r
- case 102: break;\r
+ case 104: break;\r
case 11: \r
{ return new Token(SCLTerminals.EOL, yychar, yychar+yylength(), "");\r
}\r
- case 103: break;\r
+ case 105: break;\r
case 12: \r
{ return sym(SCLTerminals.LESS, "<");\r
}\r
- case 104: break;\r
+ case 106: break;\r
case 13: \r
{ return sym(SCLTerminals.GREATER, ">");\r
}\r
- case 105: break;\r
+ case 107: break;\r
case 14: \r
{ return sym(SCLTerminals.MINUS, "-");\r
}\r
- case 106: break;\r
+ case 108: break;\r
case 15: \r
{ \r
}\r
- case 107: break;\r
+ case 109: break;\r
case 16: \r
{ throw new SCLSyntaxErrorException(Locations.location(yychar, yychar+1), "Character does not conform to UTF-8 encoding.");\r
}\r
- case 108: break;\r
+ case 110: break;\r
case 17: \r
{ return sym(SCLTerminals.LAMBDA);\r
}\r
- case 109: break;\r
+ case 111: break;\r
case 18: \r
{ return sym(SCLTerminals.LBRACE);\r
}\r
- case 110: break;\r
+ case 112: break;\r
case 19: \r
{ return sym(SCLTerminals.RBRACE);\r
}\r
- case 111: break;\r
+ case 113: break;\r
case 20: \r
{ return sym(SCLTerminals.LBRACKET);\r
}\r
- case 112: break;\r
+ case 114: break;\r
case 21: \r
{ return sym(SCLTerminals.RBRACKET);\r
}\r
- case 113: break;\r
+ case 115: break;\r
case 22: \r
{ return sym(SCLTerminals.EQUALS);\r
}\r
- case 114: break;\r
+ case 116: break;\r
case 23: \r
{ return sym(SCLTerminals.COLON);\r
}\r
- case 115: break;\r
+ case 117: break;\r
case 24: \r
{ return sym(SCLTerminals.SEMICOLON);\r
}\r
- case 116: break;\r
+ case 118: break;\r
case 25: \r
{ return sym(SCLTerminals.BAR);\r
}\r
- case 117: break;\r
+ case 119: break;\r
case 26: \r
{ string.setLength(0); stringStart=yychar; yybegin(STRING); return sym(SCLTerminals.BEGIN_STRING);\r
}\r
- case 118: break;\r
+ case 120: break;\r
case 27: \r
{ return sym(SCLTerminals.BLANK);\r
}\r
- case 119: break;\r
+ case 121: break;\r
case 28: \r
{ throw new SCLSyntaxErrorException(Locations.location(yychar, yychar+1), "Tabulator is not allowed except inside string literals.");\r
}\r
- case 120: break;\r
+ case 122: break;\r
case 29: \r
{ string.append( yytext() );\r
}\r
- case 121: break;\r
+ case 123: break;\r
case 30: \r
{ throw new SCLSyntaxErrorException(Locations.location(stringStart, yychar), "Unclosed string literal.");\r
}\r
- case 122: break;\r
+ case 124: break;\r
case 31: \r
- { yybegin(YYINITIAL); \r
+ { yybegin(YYINITIAL);
return new Token(SCLTerminals.END_STRING, stringStart, yychar+1, string.toString());\r
}\r
- case 123: break;\r
+ case 125: break;\r
case 32: \r
{ string.append('\n');\r
}\r
- case 124: break;\r
+ case 126: break;\r
case 33: \r
{ return sym(SCLTerminals.DOTDOT, ".");\r
}\r
- case 125: break;\r
+ case 127: break;\r
case 34: \r
{ return sym(SCLTerminals.SEPARATED_DOT, ".");\r
}\r
- case 126: break;\r
+ case 128: break;\r
case 35: \r
{ return sym(SCLTerminals.ANNOTATION_ID);\r
}\r
- case 127: break;\r
+ case 129: break;\r
case 36: \r
{ return sym(SCLTerminals.BINDS);\r
}\r
- case 128: break;\r
+ case 130: break;\r
case 37: \r
{ return sym(SCLTerminals.ARROW);\r
}\r
- case 129: break;\r
+ case 131: break;\r
case 38: \r
{ return sym(SCLTerminals.COMMENT);\r
}\r
- case 130: break;\r
+ case 132: break;\r
case 39: \r
{ return sym(SCLTerminals.AS);\r
}\r
- case 131: break;\r
+ case 133: break;\r
case 40: \r
{ return sym(SCLTerminals.IF);\r
}\r
- case 132: break;\r
+ case 134: break;\r
case 41: \r
{ return sym(SCLTerminals.IN);\r
}\r
- case 133: break;\r
+ case 135: break;\r
case 42: \r
{ return sym(options.supportEq ? SCLTerminals.EQ : SCLTerminals.ID);\r
}\r
- case 134: break;\r
+ case 136: break;\r
case 43: \r
{ return sym(SCLTerminals.BY);\r
}\r
- case 135: break;\r
+ case 137: break;\r
case 44: \r
{ return sym(SCLTerminals.DO);\r
}\r
- case 136: break;\r
+ case 138: break;\r
case 45: \r
{ return sym(SCLTerminals.IMPLIES);\r
}\r
- case 137: break;\r
+ case 139: break;\r
case 46: \r
{ return sym(SCLTerminals.FOLLOWS);\r
}\r
- case 138: break;\r
+ case 140: break;\r
case 47: \r
{ return sym(SCLTerminals.HASTYPE);\r
}\r
- case 139: break;\r
+ case 141: break;\r
case 48: \r
{ throw new SCLSyntaxErrorException(Locations.location(stringStart, yychar), "Illegal string escape character.");\r
}\r
- case 140: break;\r
+ case 142: break;\r
case 49: \r
{ string.append(yytext().substring(1));\r
}\r
- case 141: break;\r
+ case 143: break;\r
case 50: \r
- { parenCountStack.add(parenCount);\r
- parenCount = 1;\r
- stateStack.add(STRING);\r
- yybegin(YYINITIAL); \r
+ { parenCountStack.add(parenCount);
+ parenCount = 1;
+ stateStack.add(STRING);
+ yybegin(YYINITIAL);
return new Token(SCLTerminals.SUSPEND_STRING, stringStart, yychar+1, string.toString());\r
}\r
- case 142: break;\r
+ case 144: break;\r
case 51: \r
{ string.append('\r');\r
}\r
- case 143: break;\r
+ case 145: break;\r
case 52: \r
{ string.append('\t');\r
}\r
- case 144: break;\r
+ case 146: break;\r
case 53: \r
- { parenCountStack.add(parenCount);\r
- parenCount = 1;\r
- stateStack.add(LONG_STRING);\r
- yybegin(YYINITIAL); \r
+ { parenCountStack.add(parenCount);
+ parenCount = 1;
+ stateStack.add(LONG_STRING);
+ yybegin(YYINITIAL);
return new Token(SCLTerminals.SUSPEND_STRING, stringStart, yychar+1, string.toString());\r
}\r
- case 145: break;\r
+ case 147: break;\r
case 54: \r
{ return sym(SCLTerminals.FLOAT);\r
}\r
- case 146: break;\r
+ case 148: break;\r
case 55: \r
{ return sym(SCLTerminals.CHAR);\r
}\r
- case 147: break;\r
+ case 149: break;\r
case 56: \r
- { String text = yytext();\r
+ { String text = yytext();
return sym(SCLTerminals.ID, text.substring(1, text.length()-1));\r
}\r
- case 148: break;\r
+ case 150: break;\r
case 57: \r
- { String text = yytext();\r
+ { String text = yytext();
return sym(SCLTerminals.SYMBOL, text.substring(1, text.length()-1));\r
}\r
- case 149: break;\r
+ case 151: break;\r
case 58: \r
{ return sym(SCLTerminals.QUERY_OP);\r
}\r
- case 150: break;\r
+ case 152: break;\r
case 59: \r
{ return sym(SCLTerminals.LET);\r
}\r
- case 151: break;\r
+ case 153: break;\r
case 60: \r
{ return sym(SCLTerminals.MDO);\r
}\r
- case 152: break;\r
+ case 154: break;\r
case 61: \r
{ string.setLength(0); stringStart=yychar; yybegin(LONG_STRING); return sym(SCLTerminals.BEGIN_STRING);\r
}\r
- case 153: break;\r
+ case 155: break;\r
case 62: \r
- { yybegin(YYINITIAL); \r
+ { yybegin(YYINITIAL);
return new Token(SCLTerminals.END_STRING, stringStart, yychar+3, string.toString());\r
}\r
- case 154: break;\r
+ case 156: break;\r
case 63: \r
{ return sym(SCLTerminals.RULE);\r
}\r
- case 155: break;\r
+ case 157: break;\r
case 64: \r
{ return sym(SCLTerminals.THEN);\r
}\r
- case 156: break;\r
+ case 158: break;\r
case 65: \r
{ return sym(SCLTerminals.TYPE);\r
}\r
- case 157: break;\r
+ case 159: break;\r
case 66: \r
{ return sym(SCLTerminals.ELSE);\r
}\r
- case 158: break;\r
+ case 160: break;\r
case 67: \r
{ return sym(SCLTerminals.WITH);\r
}\r
- case 159: break;\r
+ case 161: break;\r
case 68: \r
{ return sym(SCLTerminals.WHEN);\r
}\r
- case 160: break;\r
+ case 162: break;\r
case 69: \r
{ return sym(SCLTerminals.DATA);\r
}\r
- case 161: break;\r
+ case 163: break;\r
case 70: \r
{ return sym(SCLTerminals.INFIX);\r
}\r
- case 162: break;\r
+ case 164: break;\r
case 71: \r
{ return sym(SCLTerminals.WHERE);\r
}\r
- case 163: break;\r
+ case 165: break;\r
case 72: \r
{ return sym(SCLTerminals.CLASS);\r
}\r
- case 164: break;\r
+ case 166: break;\r
case 73: \r
{ return sym(SCLTerminals.MATCH);\r
}\r
- case 165: break;\r
+ case 167: break;\r
case 74: \r
- { return sym(SCLTerminals.FORALL);\r
+ { return sym(SCLTerminals.LAMBDA_MATCH);\r
}\r
- case 166: break;\r
+ case 168: break;\r
case 75: \r
- { return sym(SCLTerminals.INFIXR);\r
+ { return sym(SCLTerminals.FORALL);\r
}\r
- case 167: break;\r
+ case 169: break;\r
case 76: \r
- { return sym(SCLTerminals.INFIXL);\r
+ { return sym(SCLTerminals.INFIXR);\r
}\r
- case 168: break;\r
+ case 170: break;\r
case 77: \r
- { return sym(SCLTerminals.IMPORT);\r
+ { return sym(SCLTerminals.INFIXL);\r
}\r
- case 169: break;\r
+ case 171: break;\r
case 78: \r
- { return sym(SCLTerminals.HIDING);\r
+ { return sym(SCLTerminals.IMPORT);\r
}\r
- case 170: break;\r
+ case 172: break;\r
case 79: \r
- { return sym(SCLTerminals.EFFECT);\r
+ { return sym(SCLTerminals.HIDING);\r
}\r
- case 171: break;\r
+ case 173: break;\r
case 80: \r
- { return sym(SCLTerminals.SELECT);\r
+ { return sym(SCLTerminals.EFFECT);\r
}\r
- case 172: break;\r
+ case 174: break;\r
case 81: \r
- { string.append((char)Integer.parseInt(yytext().substring(2), 16));\r
+ { return sym(SCLTerminals.SELECT);\r
}\r
- case 173: break;\r
+ case 175: break;\r
case 82: \r
- { return sym(SCLTerminals.INCLUDE);\r
+ { string.append((char)Integer.parseInt(yytext().substring(2), 16));\r
}\r
- case 174: break;\r
+ case 176: break;\r
case 83: \r
- { return sym(SCLTerminals.ENFORCE);\r
+ { return sym(SCLTerminals.INCLUDE);\r
}\r
- case 175: break;\r
+ case 177: break;\r
case 84: \r
- { return sym(SCLTerminals.EXTENDS);\r
+ { return sym(SCLTerminals.ENFORCE);\r
}\r
- case 176: break;\r
+ case 178: break;\r
case 85: \r
- { return sym(SCLTerminals.INSTANCE);\r
+ { return sym(SCLTerminals.EXTENDS);\r
}\r
- case 177: break;\r
+ case 179: break;\r
case 86: \r
- { return sym(SCLTerminals.DERIVING);\r
+ { return sym(SCLTerminals.INSTANCE);\r
}\r
- case 178: break;\r
+ case 180: break;\r
case 87: \r
- { return sym(SCLTerminals.IMPORTJAVA);\r
+ { return sym(SCLTerminals.DERIVING);\r
}\r
- case 179: break;\r
+ case 181: break;\r
case 88: \r
- { return sym(SCLTerminals.SELECT_FIRST);\r
+ { return sym(SCLTerminals.IMPORTJAVA);\r
}\r
- case 180: break;\r
+ case 182: break;\r
case 89: \r
- { return sym(SCLTerminals.ABSTRACT_RULE);\r
+ { return sym(SCLTerminals.CONSTRAINT);\r
}\r
- case 181: break;\r
+ case 183: break;\r
case 90: \r
- { return sym(SCLTerminals.TRANSFORMATION);\r
+ { return sym(SCLTerminals.SELECT_FIRST);\r
}\r
- case 182: break;\r
+ case 184: break;\r
case 91: \r
- { return sym(SCLTerminals.SELECT_DISTINCT);\r
+ { return sym(SCLTerminals.ABSTRACT_RULE);\r
}\r
- case 183: break;\r
+ case 185: break;\r
case 92: \r
+ { return sym(SCLTerminals.TRANSFORMATION);\r
+ }\r
+ case 186: break;\r
+ case 93: \r
+ { return sym(SCLTerminals.SELECT_DISTINCT);\r
+ }\r
+ case 187: break;\r
+ case 94: \r
{ return sym(SCLTerminals.MAPPING_RELATION);\r
}\r
- case 184: break;\r
+ case 188: break;\r
default:\r
zzScanError(ZZ_NO_MATCH);\r
}\r
public static final boolean TRACE = false;\r
\r
private static final int INITIAL_CAPACITY = 16;\r
- private static final int STATE_COUNT = 324;\r
- private static final int TERMINAL_COUNT = 79;\r
- private static final int NONTERMINAL_COUNT = 49;\r
- private static final int PRODUCT_COUNT = 126;\r
+ private static final int STATE_COUNT = 344;\r
+ private static final int TERMINAL_COUNT = 82;\r
+ private static final int NONTERMINAL_COUNT = 51;\r
+ private static final int PRODUCT_COUNT = 132;\r
\r
private static final int[] ACTION_ROW_ID = new int[STATE_COUNT];\r
private static final int[] ACTION_COLUMN_ID = new int[TERMINAL_COUNT];\r
- private static final short[] ACTION_TABLE = new short[5508];\r
- private static final int[] ERROR_TABLE = new int[800];\r
+ private static final short[] ACTION_TABLE = new short[6120];\r
+ private static final int[] ERROR_TABLE = new int[882];\r
private static final int[] GOTO_ROW_ID = new int[STATE_COUNT];\r
private static final int[] GOTO_COLUMN_ID = new int[NONTERMINAL_COUNT];\r
- private static final short[] GOTO_TABLE = new short[1620];\r
+ private static final short[] GOTO_TABLE = new short[1829];\r
private static final int[] PRODUCT_LHS = new int[PRODUCT_COUNT];\r
\r
private static final short STATE_MASK = (short)0x0fff;\r
"SEPARATED_DOT",\r
"ESCAPED_ID",\r
"LAMBDA",\r
+ "LAMBDA_MATCH",\r
"LET",\r
"IF",\r
"MATCH",\r
"SUSPEND_STRING",\r
"CONTINUE_STRING",\r
"BINDS",\r
+ "IMPLIES",\r
+ "THEN_AFTER_WHEN",\r
+ "CONSTRAINT",\r
"BY",\r
"QUERY_OP",\r
- "IMPLIES",\r
"FORALL",\r
"COMMENT",\r
"EOL",\r
"symbolWithoutMinus",\r
"listQualifier",\r
"field",\r
+ "chrQuery",\r
+ "verboseChrQuery",\r
"caseRhs",\r
"guardedExpArrow",\r
"equation",\r
return parse(0);\r
}\r
public Object parseCommands() {\r
- return parse(309);\r
+ return parse(329);\r
}\r
public Object parseImport() {\r
- return parse(316);\r
+ return parse(336);\r
}\r
public Object parseType() {\r
- return parse(318);\r
+ return parse(338);\r
}\r
public Object parseExp() {\r
- return parse(320);\r
+ return parse(340);\r
}\r
public Object parseEquationBlock() {\r
- return parse(322);\r
+ return parse(342);\r
}\r
\r
\r
case 29:\r
return reduceRuleStatement();\r
case 30:\r
- return reduceDeclarations();\r
+ return reduceCHRStatement();\r
case 31:\r
- return reduceVarId();\r
+ return reduceVerboseCHRStatement();\r
case 32:\r
- return reduceEscapedSymbol();\r
+ return reduceConstraintStatement();\r
case 33:\r
- return reduceTupleConstructor();\r
+ return reduceDeclarations();\r
case 34:\r
- return reduceBinary();\r
+ return reduceVarId();\r
case 35:\r
- return reduceSimpleRhs();\r
+ return reduceEscapedSymbol();\r
case 36:\r
- return reduceGuardedRhs();\r
+ return reduceTupleConstructor();\r
case 37:\r
- return reduceConstructor();\r
+ return reduceBinary();\r
case 38:\r
- return reduceRecordConstructor();\r
+ return reduceSimpleRhs();\r
case 39:\r
- return reduceContext();\r
+ return reduceGuardedRhs();\r
case 40:\r
- return reduceFundeps();\r
+ return reduceConstructor();\r
case 41:\r
- return reduceTypeVar();\r
+ return reduceRecordConstructor();\r
case 42:\r
- return reduceTupleType();\r
+ return reduceContext();\r
case 43:\r
- return reduceListType();\r
+ return reduceFundeps();\r
case 44:\r
- return reduceListTypeConstructor();\r
+ return reduceTypeVar();\r
case 45:\r
- return reduceTupleTypeConstructor();\r
+ return reduceTupleType();\r
case 46:\r
- return reduceLambda();\r
+ return reduceListType();\r
case 47:\r
- return reduceLet();\r
+ return reduceListTypeConstructor();\r
case 48:\r
- return reduceIf();\r
+ return reduceTupleTypeConstructor();\r
case 49:\r
- return reduceMatch();\r
+ return reduceLambda();\r
case 50:\r
- return reduceDo();\r
+ return reduceLambdaMatch();\r
case 51:\r
- return reduceSelect();\r
+ return reduceLet();\r
case 52:\r
- return reduceEnforce();\r
+ return reduceIf();\r
case 53:\r
- return reduceWhen();\r
+ return reduceMatch();\r
case 54:\r
- return reduceVar();\r
+ return reduceDo();\r
case 55:\r
- return reduceHashedId();\r
+ return reduceSelect();\r
case 56:\r
- return reduceBlank();\r
+ return reduceEnforce();\r
case 57:\r
- return reduceInteger();\r
+ return reduceVar();\r
case 58:\r
- return reduceFloat();\r
+ return reduceHashedId();\r
case 59:\r
- return reduceString();\r
+ return reduceBlank();\r
case 60:\r
- return reduceChar();\r
+ return reduceInteger();\r
case 61:\r
- return reduceTuple();\r
+ return reduceFloat();\r
case 62:\r
- return reduceRightSection();\r
+ return reduceString();\r
case 63:\r
- return reduceLeftSection();\r
+ return reduceChar();\r
case 64:\r
- return reduceListLiteral();\r
+ return reduceTuple();\r
case 65:\r
- return reduceRange();\r
+ return reduceViewPattern();\r
case 66:\r
- return reduceListComprehension();\r
+ return reduceRightSection();\r
case 67:\r
- return reduceAs();\r
+ return reduceLeftSection();\r
case 68:\r
- return reduceRecord();\r
+ return reduceListLiteral();\r
case 69:\r
- return reduceTransformation();\r
+ return reduceRange();\r
case 70:\r
- return reduceEq();\r
+ return reduceListComprehension();\r
case 71:\r
- return reduceRuleDeclarations();\r
+ return reduceAs();\r
case 72:\r
- return reduceImportShowing();\r
+ return reduceRecord();\r
case 73:\r
- return reduceImportHiding();\r
+ return reduceTransformation();\r
case 74:\r
- return reduceImportValueItem();\r
+ return reduceEq();\r
case 75:\r
- return reduceFieldDescription();\r
+ return reduceRuleDeclarations();\r
case 76:\r
- return reduceStatements();\r
+ return reduceImportShowing();\r
case 77:\r
- return reduceGuardedExpEq();\r
+ return reduceImportHiding();\r
case 78:\r
- return reduceFundep();\r
+ return reduceImportValueItem();\r
case 79:\r
- return reduceQueryRuleDeclaration();\r
+ return reduceFieldDescription();\r
case 80:\r
- return reduceAnnotation();\r
+ return reduceStatements();\r
case 81:\r
- return reduceGuardQuery();\r
+ return reduceGuardedExpEq();\r
case 82:\r
- return reduceEqualsQuery();\r
+ return reduceFundep();\r
case 83:\r
- return reduceBindQuery();\r
+ return reduceQueryRuleDeclaration();\r
case 84:\r
- return reduceCompositeQuery();\r
+ return reduceAnnotation();\r
case 85:\r
- return reduceQueryBlock();\r
+ return reduceGuardQuery();\r
case 86:\r
- return reduceApply();\r
+ return reduceEqualsQuery();\r
case 87:\r
- return reduceSymbol();\r
+ return reduceBindQuery();\r
case 88:\r
- return reduceEscapedId();\r
+ return reduceCompositeQuery();\r
case 89:\r
- return reduceMinus();\r
+ return reduceQueryBlock();\r
case 90:\r
- return reduceLess();\r
+ return reduceApply();\r
case 91:\r
- return reduceGreater();\r
+ return reduceSymbol();\r
case 92:\r
- return reduceDot();\r
+ return reduceEscapedId();\r
case 93:\r
- return reduceFieldAccess();\r
+ return reduceMinus();\r
case 94:\r
- return reduceIdAccessor();\r
+ return reduceLess();\r
case 95:\r
- return reduceStringAccessor();\r
+ return reduceGreater();\r
case 96:\r
- return reduceExpAccessor();\r
+ return reduceDot();\r
case 97:\r
- return reduceCase();\r
+ return reduceFieldAccess();\r
case 98:\r
- return reduceStringLiteral();\r
+ return reduceIdAccessor();\r
case 99:\r
- return reduceSymbol();\r
+ return reduceStringAccessor();\r
case 100:\r
- return reduceEscapedId();\r
+ return reduceExpAccessor();\r
case 101:\r
- return reduceLess();\r
+ return reduceCase();\r
case 102:\r
- return reduceGreater();\r
+ return reduceStringLiteral();\r
case 103:\r
- return reduceDot();\r
+ return reduceSymbol();\r
case 104:\r
- return reduceGuardQualifier();\r
+ return reduceEscapedId();\r
case 105:\r
- return reduceLetQualifier();\r
+ return reduceLess();\r
case 106:\r
- return reduceBindQualifier();\r
+ return reduceGreater();\r
case 107:\r
- return reduceThenQualifier();\r
+ return reduceDot();\r
case 108:\r
- return reduceField();\r
+ return reduceGuardQualifier();\r
case 109:\r
- return reduceFieldShorthand();\r
+ return reduceLetQualifier();\r
case 110:\r
- return reduceSimpleCaseRhs();\r
+ return reduceBindQualifier();\r
case 111:\r
- return reduceGuardedCaseRhs();\r
+ return reduceThenQualifier();\r
case 112:\r
- return reduceGuardedExpArrow();\r
+ return reduceField();\r
case 113:\r
- return reduceGuardEquation();\r
+ return reduceFieldShorthand();\r
case 114:\r
- return reduceBasicEquation();\r
+ return reduceCHRQuery();\r
case 115:\r
- return reduceEffect();\r
+ return reduceVerboseCHRQuery();\r
case 116:\r
- return reduceJustEtype();\r
+ return reduceSimpleCaseRhs();\r
case 117:\r
- return reduceForAll();\r
+ return reduceGuardedCaseRhs();\r
case 118:\r
- return reduceApplyType();\r
+ return reduceGuardedExpArrow();\r
case 119:\r
+ return reduceGuardEquation();\r
+ case 120:\r
+ return reduceBasicEquation();\r
+ case 121:\r
+ return reduceEffect();\r
+ case 122:\r
+ return reduceJustEtype();\r
+ case 123:\r
+ return reduceForAll();\r
+ case 124:\r
+ return reduceApplyType();\r
+ case 125:\r
return reduceDummy1();\r
\r
default:\r
* statement ::= exp FOLLOWS queryBlock\r
*/\r
protected abstract Object reduceRuleStatement();\r
+ /**\r
+ * statement ::= chrQuery IMPLIES chrQuery\r
+ */\r
+ protected abstract Object reduceCHRStatement();\r
+ /**\r
+ * statement ::= WHEN verboseChrQuery THEN_AFTER_WHEN verboseChrQuery\r
+ */\r
+ protected abstract Object reduceVerboseCHRStatement();\r
+ /**\r
+ * statement ::= CONSTRAINT ID atype*\r
+ */\r
+ protected abstract Object reduceConstraintStatement();\r
/**\r
* declarations ::= LBRACE (declaration (SEMICOLON (declaration SEMICOLON)* declaration)?)? RBRACE\r
*/\r
* aexp ::= LAMBDA aexp aexp* ARROW exp\r
*/\r
protected abstract Object reduceLambda();\r
+ /**\r
+ * aexp ::= LAMBDA_MATCH LBRACE case (SEMICOLON case)* RBRACE\r
+ */\r
+ protected abstract Object reduceLambdaMatch();\r
/**\r
* aexp ::= LET statements IN exp\r
*/\r
protected abstract Object reduceLet();\r
/**\r
- * aexp ::= IF exp THEN exp ELSE exp\r
+ * aexp ::= IF exp THEN exp (ELSE exp)?\r
*/\r
protected abstract Object reduceIf();\r
/**\r
* aexp ::= ENFORCE queryBlock\r
*/\r
protected abstract Object reduceEnforce();\r
- /**\r
- * aexp ::= WHEN queryBlock SEMICOLON exp\r
- */\r
- protected abstract Object reduceWhen();\r
/**\r
* aexp ::= var\r
*/\r
* aexp ::= LPAREN (exp (COMMA (exp COMMA)* exp)?)? RPAREN\r
*/\r
protected abstract Object reduceTuple();\r
+ /**\r
+ * aexp ::= LPAREN exp ARROW exp RPAREN\r
+ */\r
+ protected abstract Object reduceViewPattern();\r
/**\r
* aexp ::= LPAREN symbolWithoutMinus lexp RPAREN\r
*/\r
* field ::= ID\r
*/\r
protected abstract Object reduceFieldShorthand();\r
+ /**\r
+ * chrQuery ::= (listQualifier COMMA)* listQualifier\r
+ */\r
+ protected abstract Object reduceCHRQuery();\r
+ /**\r
+ * verboseChrQuery ::= LBRACE listQualifier (SEMICOLON listQualifier)* RBRACE\r
+ */\r
+ protected abstract Object reduceVerboseCHRQuery();\r
/**\r
* caseRhs ::= ARROW exp (WHERE statements)?\r
*/\r
import org.simantics.scl.compiler.elaboration.expressions.ETypeAnnotation;
import org.simantics.scl.compiler.elaboration.expressions.EVar;
import org.simantics.scl.compiler.elaboration.expressions.EVariable;
-import org.simantics.scl.compiler.elaboration.expressions.EWhen;
+import org.simantics.scl.compiler.elaboration.expressions.EViewPattern;
import org.simantics.scl.compiler.elaboration.expressions.Expression;
import org.simantics.scl.compiler.elaboration.expressions.GuardedExpression;
import org.simantics.scl.compiler.elaboration.expressions.GuardedExpressionGroup;
import org.simantics.scl.compiler.elaboration.expressions.accessor.IdAccessor;
import org.simantics.scl.compiler.elaboration.expressions.accessor.StringAccessor;
import org.simantics.scl.compiler.elaboration.expressions.block.BindStatement;
+import org.simantics.scl.compiler.elaboration.expressions.block.CHRStatement;
+import org.simantics.scl.compiler.elaboration.expressions.block.ConstraintStatement;
import org.simantics.scl.compiler.elaboration.expressions.block.GuardStatement;
import org.simantics.scl.compiler.elaboration.expressions.block.LetStatement;
import org.simantics.scl.compiler.elaboration.expressions.block.RuleStatement;
);
}
+ @SuppressWarnings("unchecked")
@Override
protected Object reduceClassDefinition() {
int i=1;
return fundeps;
}
+ @SuppressWarnings("unchecked")
@Override
protected Object reduceInstanceDefinition() {
int i=1;
declarations);
}
+ @SuppressWarnings("unchecked")
@Override
protected Object reduceDerivingInstanceDefinition() {
int i=2;
return get(0);
}
+ @SuppressWarnings("unchecked")
@Override
protected Object reduceImportJava() {
return new DImportJavaAst(((Token)get(2)).text, (ArrayList<DeclarationAst>)get(4));
case_.setLhs(Locations.combine(patterns[0].location, patterns[patterns.length-1].location));
return new ELambda(case_);
}
+
+ @Override
+ protected Object reduceLambdaMatch() {
+ Case[] cases = new Case[length()/2-1];
+ for(int i=0;i<cases.length;++i)
+ cases[i] = (Case)get(i*2+2);
+ return new ELambda(cases);
+ }
@Override
protected Object reduceLet() {
return new EIf(
(Expression)get(1),
(Expression)get(3),
- (Expression)get(5));
+ length() == 6 ? (Expression)get(5) : null);
}
@Override
protected Object reduceSelect() {
return new ESelect(((Token)get(0)).id, (Expression)get(1), new QConjunction((Query[])get(3)));
}
-
- @Override
- protected Object reduceWhen() {
- return new EWhen(
- new QConjunction((Query[])get(1)),
- (Expression)get(3));
- }
-
+
@Override
protected Object reduceEnforce() {
return new EEnforce(new QConjunction((Query[])get(1)));
throw new UnsupportedOperationException();
}
+ @SuppressWarnings("unchecked")
@Override
protected void postReduce(Object reduced) {
if(!(reduced instanceof Symbol))
Symbol sym = (Symbol)reduced;
if(sym.location != Locations.NO_LOCATION || length() == 0)
return;
+ Object first = get(0);
+ if(!(first instanceof Symbol)) {
+ if(first instanceof List) {
+ List<Object> ll = (List<Object>)first;
+ first = ll.get(0);
+ }
+ else {
+ Object[] ll = (Object[])first;
+ if(ll.length > 0)
+ first = ll[0];
+ else
+ first = get(1);
+ }
+ }
Object last = get(length()-1);
if(!(last instanceof Symbol)) {
if(last instanceof List) {
last = get(length()-2);
}
}
- sym.location = (((Symbol)get(0)).location & 0xffffffff00000000L)
+ sym.location = (((Symbol)first).location & 0xffffffff00000000L)
| (((Symbol)last).location & 0xffffffffL);
/*for(int i=0;i<length();++i) {
Object obj = get(i);
private static final String[] EMPTY_STRING_ARRAY = new String[0];
+ @SuppressWarnings("unchecked")
@Override
protected Object reduceRuleDefinition() {
String[] extendsNames = EMPTY_STRING_ARRAY;
);
}
+ @SuppressWarnings("unchecked")
@Override
protected Object reduceRelationDefinition() {
return new DRelationAst((Expression)get(0),
protected Object reduceBasicEquation() {
return new EqBasic((Expression)get(0), (Expression)get(2));
}
+
+ @Override
+ protected Object reduceViewPattern() {
+ return new EViewPattern((Expression)get(1), (Expression)get(3));
+ }
+
+ @Override
+ protected Object reduceCHRStatement() {
+ return new CHRStatement((ListQualifier[])get(0), (ListQualifier[])get(2));
+ }
+
+ @Override
+ protected Object reduceConstraintStatement() {
+ TypeAst[] parameterTypes = new TypeAst[length()-2];
+ for(int i=0;i<parameterTypes.length;++i)
+ parameterTypes[i] = (TypeAst)get(2+i);
+ return new ConstraintStatement((Token)get(1), parameterTypes);
+ }
+
+ @Override
+ protected Object reduceCHRQuery() {
+ ListQualifier[] query = new ListQualifier[(length()+1)/2];
+ for(int i=0;i<query.length;++i)
+ query[i] = (ListQualifier)get(i*2);
+ return query;
+ }
+
+ /*
+ @Override
+ protected Object reduceWhen() {
+ return new EWhen(
+ new QConjunction((Query[])get(1)),
+ (Expression)get(3));
+ }*/
+
+ @Override
+ protected Object reduceVerboseCHRQuery() {
+ ListQualifier[] query = new ListQualifier[(length()-1)/2];
+ for(int i=0;i<query.length;++i)
+ query[i] = (ListQualifier)get(i*2+1);
+ return query;
+ }
+
+ @Override
+ protected Object reduceVerboseCHRStatement() {
+ return new CHRStatement((ListQualifier[])get(1), (ListQualifier[])get(3));
+ }
+
}
INDENTABLE.add(SCLTerminals.WHEN);
INDENTABLE.add(SCLTerminals.FOLLOWS);
INDENTABLE.add(SCLTerminals.EQ);
+ INDENTABLE.add(SCLTerminals.LAMBDA_MATCH);
+ INDENTABLE.add(SCLTerminals.THEN_AFTER_WHEN);
NO_SEMICOLON_BEFORE.add(SCLTerminals.EOF);
NO_SEMICOLON_BEFORE.add(SCLTerminals.SYMBOL);
NO_SEMICOLON_BEFORE.add(SCLTerminals.RBRACE);
NO_SEMICOLON_BEFORE.add(SCLTerminals.RBRACKET);
NO_SEMICOLON_BEFORE.add(SCLTerminals.RPAREN);
+ NO_SEMICOLON_BEFORE.add(SCLTerminals.SEMICOLON);
NO_SEMICOLON_AFTER.add(SCLTerminals.EOF);
NO_SEMICOLON_AFTER.add(SCLTerminals.SYMBOL);
Token[] queue = new Token[16];
int queuePos=0, queueSize=0;
TIntArrayList indentations = new TIntArrayList();
+ TIntArrayList indentationTokens = new TIntArrayList();
Token curToken = null;
int lineStart = 0;
boolean firstTokenOfLine = true;
{
indentations.add(0);
+ indentationTokens.add(SCLTerminals.EOF);
}
public SCLPostLexer(SCLLexer lexer) {
int symbolIndentation = symbolStart-lineStart;
//System.out.println("symbolIndentation = " + symbolIndentation);
indentations.add(symbolIndentation);
+ indentationTokens.add(prevTokenId);
firstTokenOfLine = false;
}
else if(firstTokenOfLine) {
//System.out.println("level = " + level);
if(indentations.get(indentations.size()-1) >= level) {
while(indentations.get(indentations.size()-1) > level) {
+ indentationTokens.removeAt(indentations.size()-1);
indentations.removeAt(indentations.size()-1);
int loc = Locations.endOf(prevToken.location);
push(new Token(SCLTerminals.RBRACE, loc, loc, "implicit }"));
case SCLTerminals.LPAREN:
case SCLTerminals.LBRACKET:
case SCLTerminals.IF:
+ case SCLTerminals.WHEN:
case SCLTerminals.LET:
indentations.add(-1);
+ indentationTokens.add(symbolId);
push(symbol);
return;
+ case SCLTerminals.THEN:
+ /*for(int tt : indentationTokens.toArray())
+ System.out.print(SCLParser.TERMINAL_NAMES[tt] + " ");
+ System.out.println();*/
+ if(prevTokenId == SCLTerminals.COMMA) {
+ // for list comprehension syntax
+ push(symbol);
+ break;
+ }
case SCLTerminals.RBRACE:
case SCLTerminals.RPAREN:
case SCLTerminals.RBRACKET:
case SCLTerminals.ELSE:
case SCLTerminals.IN:
- while(!indentations.isEmpty() && indentations.removeAt(indentations.size()-1) >= 0) {
- int loc = Locations.endOf(prevToken.location);
- push(new Token(SCLTerminals.RBRACE, loc, loc, "implicit }"));
- }
- if(indentations.isEmpty())
- throw error(symbolStart, symbolEnd, "No corresponding opening parenthesis for '" + symbol.text + "'.");
- push(symbol);
- return;
- case SCLTerminals.THEN: // 'then' both closes and opens a block
- while(!indentations.isEmpty() && indentations.removeAt(indentations.size()-1) >= 0) {
- int loc = Locations.endOf(prevToken.location);
- push(new Token(SCLTerminals.RBRACE, loc, loc, "implicit }"));
+ int removedToken = SCLTerminals.EOF;
+ while(!indentations.isEmpty()) {
+ removedToken = indentationTokens.removeAt(indentations.size()-1);
+ //System.out.println(" removed " + SCLParser.TERMINAL_NAMES[removedToken]);
+ if(indentations.removeAt(indentations.size()-1) < 0)
+ break;
+ long loc = prevToken != null ? Locations.location(Locations.endOf(prevToken.location), Locations.endOf(prevToken.location)) : symbol.location;
+ push(new Token(SCLTerminals.RBRACE, loc, "implicit }"));
}
if(indentations.isEmpty())
throw error(symbolStart, symbolEnd, "No corresponding opening parenthesis for '" + symbol.text + "'.");
+ if(symbolId == SCLTerminals.THEN) {
+ if(removedToken == SCLTerminals.WHEN)
+ curToken = symbol = new Token(SCLTerminals.THEN_AFTER_WHEN, symbol.location, symbol.text);
+ else {
+ indentations.add(-1);
+ indentationTokens.add(SCLTerminals.THEN);
+ }
+ }
push(symbol);
- indentations.add(-1);
return;
case SCLTerminals.EOF:
while(indentations.size() > 1 && indentations.get(indentations.size()-1) >= 0) {
- int loc = Locations.endOf(prevToken.location);
- push(new Token(SCLTerminals.RBRACE, loc, loc, "implicit }"));
+ long loc = prevToken != null ? Locations.location(Locations.endOf(prevToken.location), Locations.endOf(prevToken.location)) : symbol.location;
+ push(new Token(SCLTerminals.RBRACE, loc, "implicit }"));
+ indentationTokens.removeAt(indentations.size()-1);
indentations.removeAt(indentations.size()-1);
}
if(indentations.size() > 1)
public static final int SEPARATED_DOT = 41;\r
public static final int ESCAPED_ID = 42;\r
public static final int LAMBDA = 43;\r
- public static final int LET = 44;\r
- public static final int IF = 45;\r
- public static final int MATCH = 46;\r
- public static final int DO = 47;\r
- public static final int MDO = 48;\r
- public static final int ENFORCE = 49;\r
- public static final int BLANK = 50;\r
- public static final int FLOAT = 51;\r
- public static final int LBRACKET = 52;\r
- public static final int ESCAPED_SYMBOL = 53;\r
- public static final int CHAR = 54;\r
- public static final int WHEN = 55;\r
- public static final int ATTACHED_HASH = 56;\r
- public static final int SELECT = 57;\r
- public static final int SELECT_FIRST = 58;\r
- public static final int SELECT_DISTINCT = 59;\r
- public static final int TRANSFORMATION = 60;\r
- public static final int EQ = 61;\r
- public static final int ATTACHED_DOT = 62;\r
- public static final int IN = 63;\r
- public static final int THEN = 64;\r
- public static final int ELSE = 65;\r
- public static final int RBRACKET = 66;\r
- public static final int DOTDOT = 67;\r
- public static final int AT = 68;\r
- public static final int SUSPEND_STRING = 69;\r
- public static final int CONTINUE_STRING = 70;\r
- public static final int BINDS = 71;\r
- public static final int BY = 72;\r
- public static final int QUERY_OP = 73;\r
- public static final int IMPLIES = 74;\r
- public static final int FORALL = 75;\r
- public static final int COMMENT = 76;\r
- public static final int EOL = 77;\r
- public static final int EOF = 78;\r
+ public static final int LAMBDA_MATCH = 44;\r
+ public static final int LET = 45;\r
+ public static final int IF = 46;\r
+ public static final int MATCH = 47;\r
+ public static final int DO = 48;\r
+ public static final int MDO = 49;\r
+ public static final int ENFORCE = 50;\r
+ public static final int BLANK = 51;\r
+ public static final int FLOAT = 52;\r
+ public static final int LBRACKET = 53;\r
+ public static final int ESCAPED_SYMBOL = 54;\r
+ public static final int CHAR = 55;\r
+ public static final int WHEN = 56;\r
+ public static final int ATTACHED_HASH = 57;\r
+ public static final int SELECT = 58;\r
+ public static final int SELECT_FIRST = 59;\r
+ public static final int SELECT_DISTINCT = 60;\r
+ public static final int TRANSFORMATION = 61;\r
+ public static final int EQ = 62;\r
+ public static final int ATTACHED_DOT = 63;\r
+ public static final int IN = 64;\r
+ public static final int THEN = 65;\r
+ public static final int ELSE = 66;\r
+ public static final int RBRACKET = 67;\r
+ public static final int DOTDOT = 68;\r
+ public static final int AT = 69;\r
+ public static final int SUSPEND_STRING = 70;\r
+ public static final int CONTINUE_STRING = 71;\r
+ public static final int BINDS = 72;\r
+ public static final int IMPLIES = 73;\r
+ public static final int THEN_AFTER_WHEN = 74;\r
+ public static final int CONSTRAINT = 75;\r
+ public static final int BY = 76;\r
+ public static final int QUERY_OP = 77;\r
+ public static final int FORALL = 78;\r
+ public static final int COMMENT = 79;\r
+ public static final int EOL = 80;\r
+ public static final int EOF = 81;\r
}\r
import org.simantics.scl.compiler.elaboration.contexts.TypeTranslationContext;
import org.simantics.scl.compiler.elaboration.modules.TypeAlias;
+import org.simantics.scl.compiler.elaboration.modules.TypeDescriptor;
import org.simantics.scl.compiler.environment.AmbiguousNameException;
import org.simantics.scl.compiler.environment.Environments;
import org.simantics.scl.compiler.internal.types.TypeElaborationContext;
public Type toType(TypeTranslationContext context, Kind expectedKind) {
if(function instanceof TVarAst) {
String name = ((TVarAst)function).name;
- TypeAlias alias;
+ TypeAlias alias = null;
try {
- alias = Environments.getTypeAlias(context.getEnvironment(), name);
+ TypeDescriptor tdesc = Environments.getTypeDescriptor(context.getEnvironment(), name);
+ if(tdesc instanceof TypeAlias)
+ alias = (TypeAlias)tdesc;
} catch (AmbiguousNameException e) {
context.getErrorLog().log(location, e.getMessage());
return Types.metaVar(Kinds.STAR);
import org.simantics.scl.compiler.elaboration.contexts.TypeTranslationContext;
import org.simantics.scl.compiler.elaboration.modules.TypeAlias;
+import org.simantics.scl.compiler.elaboration.modules.TypeDescriptor;
import org.simantics.scl.compiler.environment.AmbiguousNameException;
import org.simantics.scl.compiler.environment.Environments;
import org.simantics.scl.compiler.internal.types.TypeElaborationContext;
for(int i=1;i<name.length()-1;++i)
if(name.charAt(i) != ',') {
try {
- con = Environments.getTypeConstructorName(context.getEnvironment(), name.substring(1, name.length()-1));
+ con = Environments.getTypeDescriptorName(context.getEnvironment(), name.substring(1, name.length()-1));
} catch(AmbiguousNameException e) {
context.getErrorLog().log(location, e.getMessage());
return Types.metaVar(Kinds.STAR);
else if(Character.isLowerCase(c))
return context.resolveTypeVariable(location, name, expectedKind);
else {
- TypeAlias alias;
+ TypeDescriptor tdesc;
try {
- alias = Environments.getTypeAlias(context.getEnvironment(), name);
- } catch (AmbiguousNameException e1) {
- context.getErrorLog().log(location, e1.getMessage());
+ tdesc = Environments.getTypeDescriptor(context.getEnvironment(), name);
+ } catch (AmbiguousNameException e) {
+ context.getErrorLog().log(location, e.getMessage());
+ return Types.metaVar(Kinds.STAR);
+ }
+ if(tdesc == null) {
+ context.getErrorLog().log(location, "Didn't find type constructor " + name + ".");
return Types.metaVar(Kinds.STAR);
}
- if(alias != null) {
+ if(tdesc instanceof TypeAlias) {
+ TypeAlias alias = (TypeAlias)tdesc;
if(alias.getArity() > 0) {
context.getErrorLog().log(location, "The alias expects " +
alias.getArity() + " parameters, but none are given.");
}
return alias.body;
}
- try {
- con = Environments.getTypeConstructorName(context.getEnvironment(), name);
- } catch(AmbiguousNameException e) {
- context.getErrorLog().log(location, e.getMessage());
- return Types.metaVar(Kinds.STAR);
- }
- if(con == null) {
- context.getErrorLog().log(location, "Didn't find type constructor " + name + ".");
- return Types.metaVar(Kinds.STAR);
- }
+ con = tdesc.name;
}
}
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.environment.filter.AcceptAllNamespaceFilter;
import org.simantics.scl.compiler.errors.Failable;
import org.simantics.scl.compiler.markdown.internal.ExtensionNodeHandler;
}
private void generateDataDocumentation(Node container, Module module, String name) {
- TypeConstructor typeConstructor = module.getTypeConstructor(name);
- if(typeConstructor == null) {
+ TypeDescriptor typeDescriptor = module.getTypeDescriptor(name);
+ if(typeDescriptor == null) {
StringBuilder error = new StringBuilder();
- error.append("Didn't find the type constructor '" + name + "'.");
- System.err.println(error);
+ error.append("Didn't find the type " + name + ".");
container.addChild(new CodeBlockNode(error));
return;
}
StringBuilder signature = new StringBuilder();
signature.append("<div class=\"code-doc-box\"><div class=\"code\">");
signature.append("data ");
- signature.append(typeConstructor.name.name);
- for(TVar p : typeConstructor.parameters) {
- signature.append(' ');
- p.toName(tuc, signature);
+ signature.append(typeDescriptor.name.name);
+ if(typeDescriptor instanceof TypeConstructor) {
+ for(TVar p : ((TypeConstructor)typeDescriptor).parameters) {
+ signature.append(' ');
+ p.toName(tuc, signature);
+ }
}
String moduleName = module.getName();
if(!moduleName.equals(documentationName)) {
signature.append("</div><div class=\"doc\">");
container.addChild(new HtmlNode(signature));
- if(typeConstructor.documentation != null) {
+ if(typeDescriptor.getDocumentation() != null) {
MarkdownParser parser = new MarkdownParser();
- container.addChild(parser.parseDocument(typeConstructor.documentation));
+ container.addChild(parser.parseDocument(typeDescriptor.getDocumentation()));
}
else
System.out.println(name);
- for(Constructor constructor : typeConstructor.constructors) {
- if(!documentedValues.add(constructor.name.name))
- System.err.println("Method '" + constructor.name.name + "' has already been documented in " + documentationName + ".");
- generateValueDocumentation(container, module, constructor.name.name, new TypeUnparsingContext(tuc));
+ if(typeDescriptor instanceof TypeConstructor) {
+ for(Constructor constructor : ((TypeConstructor)typeDescriptor).constructors) {
+ if(!documentedValues.add(constructor.name.name))
+ System.err.println("Method '" + constructor.name.name + "' has already been documented in " + documentationName + ".");
+ generateValueDocumentation(container, module, constructor.name.name, new TypeUnparsingContext(tuc));
+ }
}
container.addChild(new HtmlNode("</div></div>"));
}
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.TypeAlias;
import org.simantics.scl.compiler.elaboration.modules.TypeClass;
import org.simantics.scl.compiler.elaboration.modules.TypeClassInstance;
-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;
import org.simantics.scl.compiler.elaboration.rules.MappingRelation;
public class ConcreteModule implements Module {
String moduleName;
- THashMap<String, TypeConstructor> typeConstructors = new THashMap<String, TypeConstructor>();
- THashMap<String, TypeAlias> typeAliases = new THashMap<String, TypeAlias>();
+ THashMap<String, TypeDescriptor> typeDescriptors = new THashMap<String, TypeDescriptor>();
THashMap<String, EffectConstructor> effectConstructors = new THashMap<String, EffectConstructor>();
THashMap<String, TypeClass> typeClasses = new THashMap<String, TypeClass>();
THashMap<TCon, ArrayList<TypeClassInstance>> typeClassInstances = new THashMap<TCon, ArrayList<TypeClassInstance>>();
this.moduleName = moduleName;
}
- public boolean addTypeConstructor(String name, TypeConstructor typeConstructor) {
- return typeConstructors.put(name, typeConstructor) != null;
- }
-
- public boolean addTypeAlias(String name, TypeAlias alias) {
- return typeAliases.put(name, alias) != null;
+ public boolean addTypeDescriptor(String name, TypeDescriptor typeConstructor) {
+ return typeDescriptors.put(name, typeConstructor) != null;
}
public boolean addEffectConstructor(String name, EffectConstructor effectConstructor) {
}
@Override
- public TypeConstructor getTypeConstructor(String name) {
- return typeConstructors.get(name);
+ public TypeDescriptor getTypeDescriptor(String name) {
+ return typeDescriptors.get(name);
}
@Override
return documentation;
}
- @Override
- public TypeAlias getTypeAlias(String name) {
- return typeAliases.get(name);
- }
-
public void setClasses(Map<String, byte[]> classes) {
this.classes = classes;
}
@Override
public void findTypesForPrefix(String prefix, NamespaceFilter filter, Consumer<TCon> consumer) {
- typeConstructors.values().forEach(type -> {
+ typeDescriptors.values().forEach(type -> {
TCon tcon = type.name;
if (tcon.name.toLowerCase().startsWith(prefix.toLowerCase()) && filter.isValueIncluded(tcon.name))
consumer.accept(tcon);
});
- typeAliases.values().forEach(type -> {
- TCon tcon = type.getCon();
- if (tcon.name.toLowerCase().startsWith(prefix.toLowerCase()) && filter.isValueIncluded(tcon.name))
- consumer.accept(tcon);
- });
}
public void setBranchPoints(THashMap<String, BranchPoint[]> branchPoints) {
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.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;
import org.simantics.scl.compiler.elaboration.rules.MappingRelation;
}
@Override
- public TypeConstructor getTypeConstructor(String name) {
+ public TypeDescriptor getTypeDescriptor(String name) {
return null;
}
return null;
}
- @Override
- public TypeAlias getTypeAlias(String name) {
- return null;
- }
-
@Override
public Collection<TransformationRule> getRules() {
return Collections.emptyList();
import org.simantics.scl.compiler.elaboration.modules.Documentation;
import org.simantics.scl.compiler.elaboration.modules.SCLValue;
-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.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;
import org.simantics.scl.compiler.elaboration.rules.MappingRelation;
SCLValue getValue(String name);
SCLRelation getRelation(String name);
SCLEntityType getEntityType(String name);
- TypeConstructor getTypeConstructor(String name);
+
+ TypeDescriptor getTypeDescriptor(String name);
+
EffectConstructor getEffectConstructor(String name);
TypeClass getTypeClass(String name);
Collection<TypeClassInstance> getInstances(TCon typeClass);
- TypeAlias getTypeAlias(String name);
MappingRelation getMappingRelation(String name);
TransformationRule getRule(String name);
Collection<TransformationRule> getRules();
-package org.simantics.scl.compiler.module.repository;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.WeakHashMap;
-import java.util.concurrent.ConcurrentHashMap;
-
-import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
-import org.simantics.scl.compiler.elaboration.modules.SCLValue;
-import org.simantics.scl.compiler.environment.ConcreteEnvironment;
-import org.simantics.scl.compiler.environment.Environment;
-import org.simantics.scl.compiler.environment.NamespaceImpl.ModuleImport;
-import org.simantics.scl.compiler.environment.NamespaceSpec;
-import org.simantics.scl.compiler.environment.filter.NamespaceFilter;
-import org.simantics.scl.compiler.environment.filter.NamespaceFilters;
-import org.simantics.scl.compiler.environment.specification.EnvironmentSpecification;
-import org.simantics.scl.compiler.errors.CompilationError;
-import org.simantics.scl.compiler.errors.DoesNotExist;
-import org.simantics.scl.compiler.errors.Failable;
-import org.simantics.scl.compiler.errors.Failure;
-import org.simantics.scl.compiler.errors.Success;
-import org.simantics.scl.compiler.module.ImportDeclaration;
-import org.simantics.scl.compiler.module.Module;
-import org.simantics.scl.compiler.module.options.ModuleCompilationOptionsAdvisor;
-import org.simantics.scl.compiler.runtime.RuntimeEnvironment;
-import org.simantics.scl.compiler.runtime.RuntimeEnvironmentImpl;
-import org.simantics.scl.compiler.runtime.RuntimeModule;
-import org.simantics.scl.compiler.runtime.RuntimeModuleMap;
-import org.simantics.scl.compiler.source.ModuleSource;
-import org.simantics.scl.compiler.source.repository.ModuleSourceRepository;
-import org.simantics.scl.compiler.top.ModuleInitializer;
-import org.simantics.scl.compiler.top.SCLCompilerConfiguration;
-import org.simantics.scl.compiler.top.ValueNotFound;
-import org.simantics.scl.compiler.types.Types;
-
-import gnu.trove.map.hash.THashMap;
-import gnu.trove.procedure.TObjectObjectProcedure;
-import gnu.trove.set.hash.THashSet;
-
-/**
- * Manages compilation and caching of SCL modules.
- *
- * @author Hannu Niemistö
- */
-public class ModuleRepository {
- private final ModuleRepository parentRepository;
- private final ModuleSourceRepository sourceRepository;
- private ConcurrentHashMap<String, ModuleEntry> moduleCache = new ConcurrentHashMap<String, ModuleEntry>();
-
- private static final ThreadLocal<THashSet<String>> PENDING_MODULES = new ThreadLocal<THashSet<String>>();
-
- private ModuleCompilationOptionsAdvisor advisor = null;
-
- private static void beginModuleCompilation(String moduleName) {
- THashSet<String> set = PENDING_MODULES.get();
- if(set == null) {
- set = new THashSet<String>();
- PENDING_MODULES.set(set);
- }
- if(!set.add(moduleName))
- throw new IllegalArgumentException("Cyclic module dependency detected at " + moduleName + ".");
- }
-
- private static void finishModuleCompilation(String moduleName) {
- PENDING_MODULES.get().remove(moduleName);
- }
-
- private class ModuleEntry implements UpdateListener {
- final String moduleName;
- WeakHashMap<UpdateListener,Object> listeners = new WeakHashMap<UpdateListener,Object>();
-
- ModuleSource source;
- Failable<Module> compilationResult;
- Failable<RuntimeModule> runtimeModule; // created lazily
-
- public ModuleEntry(String moduleName) {
- this.moduleName = moduleName;
- }
-
- synchronized void addListener(UpdateListener listener) {
- if(listener != null)
- listeners.put(listener, null);
- }
-
- @Override
- public void notifyAboutUpdate() {
- if (listeners == null)
- return;
- ArrayList<UpdateListener> externalListeners = new ArrayList<UpdateListener>();
- notifyAboutUpdate(externalListeners);
- for(UpdateListener listener : externalListeners)
- listener.notifyAboutUpdate();
- }
-
- synchronized void notifyAboutUpdate(ArrayList<UpdateListener> externalListeners) {
- if(moduleCache.get(moduleName) == this) {
- moduleCache.remove(moduleName);
- if(SCLCompilerConfiguration.TRACE_MODULE_UPDATE) {
- System.out.println("Invalidate " + moduleName);
- for(UpdateListener l : listeners.keySet())
- System.out.println(" " + l);
- }
- for(UpdateListener l : listeners.keySet())
- if(l instanceof ModuleEntry)
- ((ModuleEntry)l).notifyAboutUpdate(externalListeners);
- else
- externalListeners.add(l);
- }
- }
-
- private ModuleEntry initModuleEntryAndAddListener(UpdateListener listener) {
- source = sourceRepository.getModuleSource(moduleName, this);
-
- if(source == null)
- compilationResult = DoesNotExist.getInstance();
- else {
- if(SCLCompilerConfiguration.TRACE_MODULE_UPDATE)
- System.out.println("Compile " + source);
- beginModuleCompilation(moduleName);
- compilationResult = source.compileModule(ModuleRepository.this, this, advisor == null ? null : advisor.getOptions(moduleName));
- finishModuleCompilation(moduleName);
- }
-
- ModuleEntry oldEntry = moduleCache.putIfAbsent(moduleName, this);
- if(oldEntry != null) {
- oldEntry.addListener(listener);
- return oldEntry;
- }
-
- addListener(listener);
- return this;
- }
-
- @SuppressWarnings({ "rawtypes", "unchecked" })
- public synchronized Failable<RuntimeModule> getRuntimeModule() {
- if(runtimeModule == null) {
- if(compilationResult.didSucceed()) {
- Module module = compilationResult.getResult();
- RuntimeModuleMap parentModules = new RuntimeModuleMap();
- if(!moduleName.equals(Types.BUILTIN)) {
- parentModules.add(ModuleRepository.this.getRuntimeModule(Types.BUILTIN)
- .getResult());
- Collection<ImportDeclaration> dependencies = module.getDependencies();
- THashMap<String, ModuleEntry> moduleEntries;
- try {
- moduleEntries = getModuleEntries(dependencies.toArray(new ImportDeclaration[dependencies.size()]), null);
- } catch (ImportFailureException e) {
- throw new InternalCompilerError(e);
- }
- for(RuntimeModule m : mapEntriesToRuntimeModules(moduleEntries).values())
- parentModules.add(m);
- }
- /*for(ImportDeclaration importAst : module.getDependencies()) {
- RuntimeModule parentModule =
- ModuleRepository.this.getRuntimeModule(importAst.moduleName)
- .getResult();
- if(parentModule != null)
- parentModules.add(parentModule);
- }*/
- RuntimeModule rm = new RuntimeModule(module, parentModules, source.getClassLoader());
- ModuleInitializer initializer = module.getModuleInitializer();
- if(initializer != null)
- try {
- initializer.initializeModule(rm.getMutableClassLoader().getClassLoader());
- } catch (Exception e) {
- compilationResult = new Failure(new CompilationError[] {new CompilationError("Initialization of module " + moduleName + " failed: " + e.getMessage())});
- e.printStackTrace();
- }
- runtimeModule = new Success<RuntimeModule>(rm);
- }
- else
- runtimeModule = (Failable<RuntimeModule>)(Failable)compilationResult;
- }
- return runtimeModule;
- }
-
- public void dispose() {
- if (listeners != null)
- listeners.clear();
- listeners = null;
- source = null;
- compilationResult = null;
- if (runtimeModule != null) {
- if (runtimeModule.didSucceed())
- runtimeModule.getResult().dispose();
- }
- runtimeModule = null;
- }
-
- @Override
- public String toString() {
- return "ModuleEntry@" + moduleName + "@" + hashCode();
- }
- }
-
- public ModuleRepository(ModuleRepository parentRepository, ModuleSourceRepository sourceRepository) {
- this.parentRepository = parentRepository;
- this.sourceRepository = sourceRepository;
- }
-
- public ModuleRepository(ModuleSourceRepository sourceRepository) {
- this(null, sourceRepository);
- }
-
- public Failable<Module> getModule(String moduleName, UpdateListener listener) {
- return getModuleEntry(moduleName, listener).compilationResult;
- }
-
- public Failable<Module> getModule(String moduleName) {
- return getModule(moduleName, null);
- }
-
- public Failable<RuntimeModule> getRuntimeModule(String moduleName, UpdateListener listener) {
- return getModuleEntry(moduleName, listener).getRuntimeModule();
- }
-
- public Failable<RuntimeModule> getRuntimeModule(String moduleName) {
- return getRuntimeModule(moduleName, null);
- }
-
- private ModuleEntry getModuleEntry(String moduleName, UpdateListener listener) {
- /* It is deliberate that the following code does not try to prevent
- * simultaneous compilation of the same module. This is because in
- * some situations only certain thread trying compilation can succeed
- * in it.
- */
- ModuleEntry entry = moduleCache.get(moduleName);
- if(entry == null)
- entry = new ModuleEntry(moduleName).initModuleEntryAndAddListener(listener);
- else
- entry.addListener(listener);
-
- if(entry.compilationResult == DoesNotExist.INSTANCE && parentRepository != null)
- return parentRepository.getModuleEntry(moduleName, listener);
- else
- return entry;
- }
-
- private THashMap<String, ModuleEntry> getModuleEntries(
- ImportDeclaration[] imports,
- UpdateListener listener) throws ImportFailureException {
- THashMap<String, ModuleEntry> result = new THashMap<String, ModuleEntry>();
- Collection<ImportFailure> failures = null;
-
- ArrayList<ImportDeclaration> stack = new ArrayList<ImportDeclaration>(imports.length);
- for(ImportDeclaration import_ : imports)
- stack.add(import_);
- while(!stack.isEmpty()) {
- ImportDeclaration import_ = stack.remove(stack.size()-1);
- if(!result.containsKey(import_.moduleName)) {
- ModuleEntry entry = getModuleEntry(import_.moduleName, listener);
- Failable<Module> compilationResult = entry.compilationResult;
- if(compilationResult.didSucceed()) {
- result.put(import_.moduleName, entry);
- stack.addAll(compilationResult.getResult().getDependencies());
- }
- else {
- if(failures == null)
- failures = new ArrayList<ImportFailure>(2);
- failures.add(new ImportFailure(import_.location, import_.moduleName,
- compilationResult == DoesNotExist.INSTANCE
- ? ImportFailure.MODULE_DOES_NOT_EXIST_REASON
- : ((Failure)compilationResult).errors));
- }
- }
- }
-
- if(failures != null)
- throw new ImportFailureException(failures);
-
- return result;
- }
-
- private static THashMap<String, Module> mapEntriesToModules(THashMap<String, ModuleEntry> entries) {
- final THashMap<String, Module> result = new THashMap<String, Module>(entries.size());
- entries.forEachEntry(new TObjectObjectProcedure<String, ModuleEntry>() {
- @Override
- public boolean execute(String a, ModuleEntry b) {
- result.put(a, b.compilationResult.getResult());
- return true;
- }
- });
- return result;
- }
-
- private static THashMap<String, RuntimeModule> mapEntriesToRuntimeModules(THashMap<String, ModuleEntry> entries) {
- final THashMap<String, RuntimeModule> result = new THashMap<String, RuntimeModule>(entries.size());
- entries.forEachEntry(new TObjectObjectProcedure<String, ModuleEntry>() {
- @Override
- public boolean execute(String a, ModuleEntry b) {
- result.put(a, b.getRuntimeModule().getResult());
- return true;
- }
- });
- return result;
- }
-
- public Environment createEnvironment(
- ImportDeclaration[] imports,
- UpdateListener listener) throws ImportFailureException {
- THashMap<String, ModuleEntry> entries = getModuleEntries(imports, listener);
- THashMap<String, Module> moduleMap = mapEntriesToModules(entries);
- return createEnvironment(moduleMap, imports);
- }
-
- public Environment createEnvironment(
- EnvironmentSpecification specification,
- UpdateListener listener) throws ImportFailureException {
- return createEnvironment(specification.imports.toArray(new ImportDeclaration[specification.imports.size()]), listener);
- }
-
- public RuntimeEnvironment createRuntimeEnvironment(
- EnvironmentSpecification environmentSpecification, ClassLoader parentClassLoader) throws ImportFailureException {
- return createRuntimeEnvironment(environmentSpecification, parentClassLoader, null);
- }
-
- public RuntimeEnvironment createRuntimeEnvironment(
- EnvironmentSpecification environmentSpecification,
- ClassLoader parentClassLoader,
- UpdateListener listener) throws ImportFailureException {
- return createRuntimeEnvironment(
- environmentSpecification.imports.toArray(new ImportDeclaration[environmentSpecification.imports.size()]),
- parentClassLoader,
- listener);
- }
-
- public RuntimeEnvironment createRuntimeEnvironment(
- ImportDeclaration[] imports,
- ClassLoader parentClassLoader,
- UpdateListener listener) throws ImportFailureException {
- THashMap<String, ModuleEntry> entries = getModuleEntries(imports, listener);
- THashMap<String, Module> moduleMap = mapEntriesToModules(entries);
- Environment environment = createEnvironment(moduleMap, imports);
- THashMap<String, RuntimeModule> runtimeModuleMap = mapEntriesToRuntimeModules(entries);
- return new RuntimeEnvironmentImpl(environment, parentClassLoader, runtimeModuleMap);
- }
-
- private static Environment createEnvironment(THashMap<String, Module> moduleMap,
- ImportDeclaration[] imports) {
- NamespaceSpec spec = new NamespaceSpec();
- for(ImportDeclaration import_ : imports)
- if(import_.localName != null)
- addToNamespace(moduleMap, spec, import_.moduleName, import_.localName,
- NamespaceFilters.createFromSpec(import_.spec));
-
- return new ConcreteEnvironment(moduleMap, spec.toNamespace());
- }
-
- private static void addToNamespace(THashMap<String, Module> moduleMap,
- NamespaceSpec namespace, String moduleName, String localName,
- NamespaceFilter filter) {
- if(localName.isEmpty())
- addToNamespace(moduleMap, namespace, moduleName, filter);
- else
- addToNamespace(moduleMap, namespace.getNamespace(localName), moduleName, filter);
- }
-
- private static void addToNamespace(THashMap<String, Module> moduleMap,
- NamespaceSpec namespace, String moduleName, NamespaceFilter filter) {
- ModuleImport moduleImport = namespace.moduleMap.get(moduleName);
- if(moduleImport == null) {
- Module module = moduleMap.get(moduleName);
- namespace.moduleMap.put(moduleName, new ModuleImport(module, filter));
- for(ImportDeclaration import_ : module.getDependencies())
- if(import_.localName != null) {
- NamespaceFilter localFilter = NamespaceFilters.createFromSpec(import_.spec);
- if(import_.localName.equals(""))
- localFilter = NamespaceFilters.intersection(filter, localFilter);
- addToNamespace(moduleMap, namespace, import_.moduleName, import_.localName, localFilter);
- }
- }
- else if(!filter.isSubsetOf(moduleImport.filter)) {
- moduleImport.filter = NamespaceFilters.union(moduleImport.filter, filter);
- for(ImportDeclaration import_ : moduleImport.module.getDependencies())
- // We have to recheck only modules imported to this namespace
- if("".equals(import_.localName)) {
- NamespaceFilter localFilter = NamespaceFilters.createFromSpec(import_.spec);
- localFilter = NamespaceFilters.intersection(filter, localFilter);
- addToNamespace(moduleMap, namespace, import_.moduleName, import_.localName, localFilter);
- }
- }
- }
-
- public Object getValue(String moduleName, String valueName) throws ValueNotFound {
- Failable<RuntimeModule> module = getRuntimeModule(moduleName);
- if(module.didSucceed())
- return module.getResult().getValue(valueName);
- else if(module == DoesNotExist.INSTANCE)
- throw new ValueNotFound("Didn't find module " + moduleName);
- else
- throw new ValueNotFound(((Failure)module).toString());
- }
-
- public Object getValue(String fullValueName) throws ValueNotFound {
- int p = fullValueName.lastIndexOf('/');
- if(p < 0)
- throw new ValueNotFound(fullValueName + " is not a valid full value name.");
- return getValue(fullValueName.substring(0, p), fullValueName.substring(p+1));
- }
-
- public SCLValue getValueRef(String moduleName, String valueName) throws ValueNotFound {
- Failable<Module> module = getModule(moduleName);
- if(module.didSucceed()) {
- SCLValue value = module.getResult().getValue(valueName);
- if(value == null)
- throw new ValueNotFound("Module " + moduleName + " does not contain value " + valueName + ".");
- return value;
- }
- else if(module == DoesNotExist.INSTANCE)
- throw new ValueNotFound("Didn't find module " + moduleName);
- else
- throw new ValueNotFound(((Failure)module).toString());
- }
-
- public SCLValue getValueRef(String fullValueName) throws ValueNotFound {
- int p = fullValueName.lastIndexOf('/');
- if(p < 0)
- throw new ValueNotFound(fullValueName + " is not a valid full value name.");
- return getValueRef(fullValueName.substring(0, p), fullValueName.substring(p+1));
- }
-
- public ModuleSourceRepository getSourceRepository() {
- return sourceRepository;
- }
-
- public String getDocumentation(String documentationName) {
- String documentation = sourceRepository.getDocumentation(documentationName);
- if(documentation == null && parentRepository != null)
- return parentRepository.getDocumentation(documentationName);
- return documentation;
- }
-
- public void flush() {
- if (parentRepository != null)
- parentRepository.flush();
- if (moduleCache != null) {
- for (ModuleEntry entry : moduleCache.values()) {
- entry.dispose();
- }
- moduleCache.clear();
- }
- moduleCache = null;
- }
-
- public Map<String, Module> getModules() {
- Map<String, Module> result = new HashMap<>(moduleCache.size());
- for (Map.Entry<String, ModuleEntry> entry : moduleCache.entrySet()) {
- ModuleEntry moduleEntry = entry.getValue();
- if (moduleEntry.compilationResult.didSucceed()) {
- result.put(entry.getKey(), moduleEntry.compilationResult.getResult());
- }
- }
- return result;
- }
-
- public ModuleCompilationOptionsAdvisor getAdvisor() {
- return advisor;
- }
-
- public void setAdvisor(ModuleCompilationOptionsAdvisor advisor) {
- this.advisor = advisor;
- }
+package org.simantics.scl.compiler.module.repository;\r
\r
-}
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+import java.util.WeakHashMap;\r
+import java.util.concurrent.ConcurrentHashMap;\r
+\r
+import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
+import org.simantics.scl.compiler.elaboration.modules.SCLValue;\r
+import org.simantics.scl.compiler.environment.ConcreteEnvironment;\r
+import org.simantics.scl.compiler.environment.Environment;\r
+import org.simantics.scl.compiler.environment.NamespaceImpl.ModuleImport;\r
+import org.simantics.scl.compiler.environment.NamespaceSpec;\r
+import org.simantics.scl.compiler.environment.filter.NamespaceFilter;\r
+import org.simantics.scl.compiler.environment.filter.NamespaceFilters;\r
+import org.simantics.scl.compiler.environment.specification.EnvironmentSpecification;\r
+import org.simantics.scl.compiler.errors.CompilationError;\r
+import org.simantics.scl.compiler.errors.DoesNotExist;\r
+import org.simantics.scl.compiler.errors.Failable;\r
+import org.simantics.scl.compiler.errors.Failure;\r
+import org.simantics.scl.compiler.errors.Success;\r
+import org.simantics.scl.compiler.module.ImportDeclaration;\r
+import org.simantics.scl.compiler.module.Module;\r
+import org.simantics.scl.compiler.module.options.ModuleCompilationOptionsAdvisor;\r
+import org.simantics.scl.compiler.runtime.RuntimeEnvironment;\r
+import org.simantics.scl.compiler.runtime.RuntimeEnvironmentImpl;\r
+import org.simantics.scl.compiler.runtime.RuntimeModule;\r
+import org.simantics.scl.compiler.runtime.RuntimeModuleMap;\r
+import org.simantics.scl.compiler.source.ModuleSource;\r
+import org.simantics.scl.compiler.source.repository.ModuleSourceRepository;\r
+import org.simantics.scl.compiler.top.ModuleInitializer;\r
+import org.simantics.scl.compiler.top.SCLCompilerConfiguration;\r
+import org.simantics.scl.compiler.top.ValueNotFound;\r
+import org.simantics.scl.compiler.types.Types;\r
+\r
+import gnu.trove.map.hash.THashMap;\r
+import gnu.trove.procedure.TObjectObjectProcedure;\r
+import gnu.trove.set.hash.THashSet;\r
+\r
+/**\r
+ * Manages compilation and caching of SCL modules.\r
+ * \r
+ * @author Hannu Niemistö\r
+ */\r
+public class ModuleRepository {\r
+ private final ModuleRepository parentRepository;\r
+ private final ModuleSourceRepository sourceRepository;\r
+ private ConcurrentHashMap<String, ModuleEntry> moduleCache = new ConcurrentHashMap<String, ModuleEntry>();\r
+ \r
+ private static final ThreadLocal<THashSet<String>> PENDING_MODULES = new ThreadLocal<THashSet<String>>();\r
+ \r
+ private ModuleCompilationOptionsAdvisor advisor = null;\r
+ \r
+ private static void beginModuleCompilation(String moduleName) {\r
+ THashSet<String> set = PENDING_MODULES.get();\r
+ if(set == null) {\r
+ set = new THashSet<String>();\r
+ PENDING_MODULES.set(set);\r
+ }\r
+ if(!set.add(moduleName))\r
+ throw new IllegalArgumentException("Cyclic module dependency detected at " + moduleName + ".");\r
+ }\r
+ \r
+ private static void finishModuleCompilation(String moduleName) {\r
+ PENDING_MODULES.get().remove(moduleName);\r
+ }\r
+ \r
+ private class ModuleEntry implements UpdateListener {\r
+ final String moduleName;\r
+ WeakHashMap<UpdateListener,Object> listeners = new WeakHashMap<UpdateListener,Object>();\r
+ \r
+ ModuleSource source;\r
+ Failable<Module> compilationResult;\r
+ Failable<RuntimeModule> runtimeModule; // created lazily\r
+\r
+ public ModuleEntry(String moduleName) {\r
+ this.moduleName = moduleName;\r
+ }\r
+ \r
+ synchronized void addListener(UpdateListener listener) {\r
+ if(listener != null)\r
+ listeners.put(listener, null);\r
+ }\r
+ \r
+ @Override\r
+ public void notifyAboutUpdate() {\r
+ if (listeners == null)\r
+ return;\r
+ ArrayList<UpdateListener> externalListeners = new ArrayList<UpdateListener>();\r
+ notifyAboutUpdate(externalListeners);\r
+ for(UpdateListener listener : externalListeners)\r
+ listener.notifyAboutUpdate();\r
+ }\r
+\r
+ synchronized void notifyAboutUpdate(ArrayList<UpdateListener> externalListeners) {\r
+ if(moduleCache.get(moduleName) == this) {\r
+ moduleCache.remove(moduleName);\r
+ if(SCLCompilerConfiguration.TRACE_MODULE_UPDATE) {\r
+ System.out.println("Invalidate " + moduleName);\r
+ for(UpdateListener l : listeners.keySet())\r
+ System.out.println(" " + l);\r
+ }\r
+ for(UpdateListener l : listeners.keySet())\r
+ if(l instanceof ModuleEntry)\r
+ ((ModuleEntry)l).notifyAboutUpdate(externalListeners);\r
+ else\r
+ externalListeners.add(l);\r
+ }\r
+ }\r
+\r
+ private ModuleEntry initModuleEntryAndAddListener(UpdateListener listener) {\r
+ source = sourceRepository.getModuleSource(moduleName, this);\r
+ \r
+ if(source == null)\r
+ compilationResult = DoesNotExist.getInstance();\r
+ else {\r
+ if(SCLCompilerConfiguration.TRACE_MODULE_UPDATE)\r
+ System.out.println("Compile " + source);\r
+ beginModuleCompilation(moduleName);\r
+ compilationResult = source.compileModule(ModuleRepository.this, this, advisor == null ? null : advisor.getOptions(moduleName));\r
+ finishModuleCompilation(moduleName);\r
+ }\r
+ \r
+ ModuleEntry oldEntry = moduleCache.putIfAbsent(moduleName, this);\r
+ if(oldEntry != null) {\r
+ oldEntry.addListener(listener);\r
+ return oldEntry;\r
+ }\r
+ \r
+ addListener(listener);\r
+ return this;\r
+ }\r
+ \r
+ @SuppressWarnings({ "rawtypes", "unchecked" })\r
+ public synchronized Failable<RuntimeModule> getRuntimeModule() {\r
+ if(runtimeModule == null) {\r
+ if(compilationResult.didSucceed()) {\r
+ Module module = compilationResult.getResult();\r
+ RuntimeModuleMap parentModules = new RuntimeModuleMap();\r
+ if(!moduleName.equals(Types.BUILTIN)) {\r
+ parentModules.add(ModuleRepository.this.getRuntimeModule(Types.BUILTIN)\r
+ .getResult());\r
+ Collection<ImportDeclaration> dependencies = module.getDependencies();\r
+ THashMap<String, ModuleEntry> moduleEntries;\r
+ try {\r
+ moduleEntries = getModuleEntries(dependencies.toArray(new ImportDeclaration[dependencies.size()]), null);\r
+ } catch (ImportFailureException e) {\r
+ throw new InternalCompilerError(e);\r
+ }\r
+ for(RuntimeModule m : mapEntriesToRuntimeModules(moduleEntries).values())\r
+ parentModules.add(m);\r
+ }\r
+ /*for(ImportDeclaration importAst : module.getDependencies()) {\r
+ RuntimeModule parentModule =\r
+ ModuleRepository.this.getRuntimeModule(importAst.moduleName)\r
+ .getResult();\r
+ if(parentModule != null)\r
+ parentModules.add(parentModule);\r
+ }*/\r
+ RuntimeModule rm = new RuntimeModule(module, parentModules, source.getClassLoader());\r
+ ModuleInitializer initializer = module.getModuleInitializer();\r
+ if(initializer != null)\r
+ try {\r
+ initializer.initializeModule(rm.getMutableClassLoader().getClassLoader());\r
+ } catch (Exception e) {\r
+ compilationResult = new Failure(new CompilationError[] {new CompilationError("Initialization of module " + moduleName + " failed: " + e.getMessage())});\r
+ e.printStackTrace();\r
+ }\r
+ runtimeModule = new Success<RuntimeModule>(rm); \r
+ }\r
+ else\r
+ runtimeModule = (Failable<RuntimeModule>)(Failable)compilationResult;\r
+ }\r
+ return runtimeModule;\r
+ }\r
+\r
+ public void dispose() {\r
+ if (listeners != null)\r
+ listeners.clear();\r
+ listeners = null;\r
+ source = null;\r
+ compilationResult = null;\r
+ if (runtimeModule != null) {\r
+ if (runtimeModule.didSucceed())\r
+ runtimeModule.getResult().dispose();\r
+ }\r
+ runtimeModule = null;\r
+ }\r
+ \r
+ @Override\r
+ public String toString() {\r
+ return "ModuleEntry@" + moduleName + "@" + hashCode();\r
+ }\r
+ }\r
+ \r
+ public ModuleRepository(ModuleRepository parentRepository, ModuleSourceRepository sourceRepository) {\r
+ this.parentRepository = parentRepository;\r
+ this.sourceRepository = sourceRepository;\r
+ }\r
+\r
+ public ModuleRepository(ModuleSourceRepository sourceRepository) {\r
+ this(null, sourceRepository);\r
+ }\r
+ \r
+ public Failable<Module> getModule(String moduleName, UpdateListener listener) {\r
+ return getModuleEntry(moduleName, listener).compilationResult;\r
+ }\r
+ \r
+ public Failable<Module> getModule(String moduleName) {\r
+ return getModule(moduleName, null);\r
+ }\r
+ \r
+ public Failable<RuntimeModule> getRuntimeModule(String moduleName, UpdateListener listener) {\r
+ return getModuleEntry(moduleName, listener).getRuntimeModule();\r
+ }\r
+ \r
+ public Failable<RuntimeModule> getRuntimeModule(String moduleName) {\r
+ return getRuntimeModule(moduleName, null);\r
+ }\r
+ \r
+ private ModuleEntry getModuleEntry(String moduleName, UpdateListener listener) {\r
+ /* It is deliberate that the following code does not try to prevent\r
+ * simultaneous compilation of the same module. This is because in\r
+ * some situations only certain thread trying compilation can succeed\r
+ * in it.\r
+ */\r
+ ModuleEntry entry = moduleCache.get(moduleName);\r
+ if(entry == null)\r
+ entry = new ModuleEntry(moduleName).initModuleEntryAndAddListener(listener);\r
+ else\r
+ entry.addListener(listener);\r
+\r
+ if(entry.compilationResult == DoesNotExist.INSTANCE && parentRepository != null)\r
+ return parentRepository.getModuleEntry(moduleName, listener);\r
+ else\r
+ return entry;\r
+ }\r
+ \r
+ private THashMap<String, ModuleEntry> getModuleEntries(\r
+ ImportDeclaration[] imports,\r
+ UpdateListener listener) throws ImportFailureException {\r
+ THashMap<String, ModuleEntry> result = new THashMap<String, ModuleEntry>();\r
+ Collection<ImportFailure> failures = null;\r
+ \r
+ ArrayList<ImportDeclaration> stack = new ArrayList<ImportDeclaration>(imports.length);\r
+ for(ImportDeclaration import_ : imports)\r
+ stack.add(import_);\r
+ while(!stack.isEmpty()) {\r
+ ImportDeclaration import_ = stack.remove(stack.size()-1);\r
+ if(!result.containsKey(import_.moduleName)) {\r
+ ModuleEntry entry = getModuleEntry(import_.moduleName, listener);\r
+ Failable<Module> compilationResult = entry.compilationResult;\r
+ if(compilationResult.didSucceed()) {\r
+ result.put(import_.moduleName, entry);\r
+ stack.addAll(compilationResult.getResult().getDependencies());\r
+ }\r
+ else {\r
+ if(failures == null)\r
+ failures = new ArrayList<ImportFailure>(2);\r
+ failures.add(new ImportFailure(import_.location, import_.moduleName,\r
+ compilationResult == DoesNotExist.INSTANCE\r
+ ? ImportFailure.MODULE_DOES_NOT_EXIST_REASON\r
+ : ((Failure)compilationResult).errors));\r
+ }\r
+ }\r
+ }\r
+ \r
+ if(failures != null)\r
+ throw new ImportFailureException(failures);\r
+ \r
+ return result;\r
+ }\r
+\r
+ private static THashMap<String, Module> mapEntriesToModules(THashMap<String, ModuleEntry> entries) {\r
+ final THashMap<String, Module> result = new THashMap<String, Module>(entries.size());\r
+ entries.forEachEntry(new TObjectObjectProcedure<String, ModuleEntry>() {\r
+ @Override\r
+ public boolean execute(String a, ModuleEntry b) {\r
+ result.put(a, b.compilationResult.getResult());\r
+ return true;\r
+ }\r
+ });\r
+ return result;\r
+ }\r
+ \r
+ private static THashMap<String, RuntimeModule> mapEntriesToRuntimeModules(THashMap<String, ModuleEntry> entries) {\r
+ final THashMap<String, RuntimeModule> result = new THashMap<String, RuntimeModule>(entries.size());\r
+ entries.forEachEntry(new TObjectObjectProcedure<String, ModuleEntry>() {\r
+ @Override\r
+ public boolean execute(String a, ModuleEntry b) {\r
+ result.put(a, b.getRuntimeModule().getResult());\r
+ return true;\r
+ }\r
+ });\r
+ return result;\r
+ }\r
+ \r
+ public Environment createEnvironment(\r
+ ImportDeclaration[] imports,\r
+ UpdateListener listener) throws ImportFailureException {\r
+ THashMap<String, ModuleEntry> entries = getModuleEntries(imports, listener);\r
+ THashMap<String, Module> moduleMap = mapEntriesToModules(entries);\r
+ return createEnvironment(moduleMap, imports);\r
+ }\r
+ \r
+ public Environment createEnvironment(\r
+ EnvironmentSpecification specification,\r
+ UpdateListener listener) throws ImportFailureException {\r
+ return createEnvironment(specification.imports.toArray(new ImportDeclaration[specification.imports.size()]), listener);\r
+ }\r
+ \r
+ public RuntimeEnvironment createRuntimeEnvironment(\r
+ EnvironmentSpecification environmentSpecification, ClassLoader parentClassLoader) throws ImportFailureException {\r
+ return createRuntimeEnvironment(environmentSpecification, parentClassLoader, null);\r
+ }\r
+ \r
+ public RuntimeEnvironment createRuntimeEnvironment(\r
+ EnvironmentSpecification environmentSpecification,\r
+ ClassLoader parentClassLoader,\r
+ UpdateListener listener) throws ImportFailureException {\r
+ return createRuntimeEnvironment(\r
+ environmentSpecification.imports.toArray(new ImportDeclaration[environmentSpecification.imports.size()]),\r
+ parentClassLoader,\r
+ listener);\r
+ }\r
+ \r
+ public RuntimeEnvironment createRuntimeEnvironment(\r
+ ImportDeclaration[] imports,\r
+ ClassLoader parentClassLoader,\r
+ UpdateListener listener) throws ImportFailureException {\r
+ THashMap<String, ModuleEntry> entries = getModuleEntries(imports, listener);\r
+ THashMap<String, Module> moduleMap = mapEntriesToModules(entries);\r
+ Environment environment = createEnvironment(moduleMap, imports);\r
+ THashMap<String, RuntimeModule> runtimeModuleMap = mapEntriesToRuntimeModules(entries);\r
+ return new RuntimeEnvironmentImpl(environment, parentClassLoader, runtimeModuleMap);\r
+ }\r
+ \r
+ private static Environment createEnvironment(THashMap<String, Module> moduleMap, \r
+ ImportDeclaration[] imports) {\r
+ NamespaceSpec spec = new NamespaceSpec();\r
+ for(ImportDeclaration import_ : imports)\r
+ if(import_.localName != null)\r
+ addToNamespace(moduleMap, spec, import_.moduleName, import_.localName,\r
+ NamespaceFilters.createFromSpec(import_.spec));\r
+ \r
+ return new ConcreteEnvironment(moduleMap, spec.toNamespace());\r
+ }\r
+ \r
+ private static void addToNamespace(THashMap<String, Module> moduleMap, \r
+ NamespaceSpec namespace, String moduleName, String localName,\r
+ NamespaceFilter filter) {\r
+ if(localName.isEmpty())\r
+ addToNamespace(moduleMap, namespace, moduleName, filter);\r
+ else\r
+ addToNamespace(moduleMap, namespace.getNamespace(localName), moduleName, filter);\r
+ }\r
+ \r
+ private static void addToNamespace(THashMap<String, Module> moduleMap, \r
+ NamespaceSpec namespace, String moduleName, NamespaceFilter filter) {\r
+ ModuleImport moduleImport = namespace.moduleMap.get(moduleName);\r
+ if(moduleImport == null) {\r
+ Module module = moduleMap.get(moduleName);\r
+ namespace.moduleMap.put(moduleName, new ModuleImport(module, filter));\r
+ for(ImportDeclaration import_ : module.getDependencies())\r
+ if(import_.localName != null) {\r
+ NamespaceFilter localFilter = NamespaceFilters.createFromSpec(import_.spec);\r
+ if(import_.localName.equals(""))\r
+ localFilter = NamespaceFilters.intersection(filter, localFilter);\r
+ addToNamespace(moduleMap, namespace, import_.moduleName, import_.localName, localFilter);\r
+ }\r
+ }\r
+ else if(!filter.isSubsetOf(moduleImport.filter)) {\r
+ moduleImport.filter = NamespaceFilters.union(moduleImport.filter, filter);\r
+ for(ImportDeclaration import_ : moduleImport.module.getDependencies())\r
+ // We have to recheck only modules imported to this namespace\r
+ if("".equals(import_.localName)) {\r
+ NamespaceFilter localFilter = NamespaceFilters.createFromSpec(import_.spec);\r
+ localFilter = NamespaceFilters.intersection(filter, localFilter);\r
+ addToNamespace(moduleMap, namespace, import_.moduleName, import_.localName, localFilter);\r
+ }\r
+ }\r
+ }\r
+\r
+ public Object getValue(String moduleName, String valueName) throws ValueNotFound {\r
+ Failable<RuntimeModule> module = getRuntimeModule(moduleName);\r
+ if(module.didSucceed())\r
+ return module.getResult().getValue(valueName);\r
+ else if(module == DoesNotExist.INSTANCE)\r
+ throw new ValueNotFound("Didn't find module " + moduleName);\r
+ else\r
+ throw new ValueNotFound(((Failure)module).toString());\r
+ }\r
+\r
+ public Object getValue(String fullValueName) throws ValueNotFound {\r
+ int p = fullValueName.lastIndexOf('/');\r
+ if(p < 0)\r
+ throw new ValueNotFound(fullValueName + " is not a valid full value name.");\r
+ return getValue(fullValueName.substring(0, p), fullValueName.substring(p+1));\r
+ }\r
+\r
+ public SCLValue getValueRef(String moduleName, String valueName) throws ValueNotFound {\r
+ Failable<Module> module = getModule(moduleName);\r
+ if(module.didSucceed()) {\r
+ SCLValue value = module.getResult().getValue(valueName);\r
+ if(value == null)\r
+ throw new ValueNotFound("Module " + moduleName + " does not contain value " + valueName + ".");\r
+ return value;\r
+ }\r
+ else if(module == DoesNotExist.INSTANCE)\r
+ throw new ValueNotFound("Didn't find module " + moduleName);\r
+ else\r
+ throw new ValueNotFound(((Failure)module).toString());\r
+ }\r
+ \r
+ public SCLValue getValueRef(String fullValueName) throws ValueNotFound {\r
+ int p = fullValueName.lastIndexOf('/');\r
+ if(p < 0)\r
+ throw new ValueNotFound(fullValueName + " is not a valid full value name.");\r
+ return getValueRef(fullValueName.substring(0, p), fullValueName.substring(p+1));\r
+ }\r
+ \r
+ public ModuleSourceRepository getSourceRepository() {\r
+ return sourceRepository;\r
+ }\r
+ \r
+ public String getDocumentation(String documentationName) {\r
+ String documentation = sourceRepository.getDocumentation(documentationName);\r
+ if(documentation == null && parentRepository != null)\r
+ return parentRepository.getDocumentation(documentationName);\r
+ return documentation;\r
+ }\r
+ \r
+ public void flush() {\r
+ if (parentRepository != null)\r
+ parentRepository.flush();\r
+ if (moduleCache != null) {\r
+ for (ModuleEntry entry : moduleCache.values()) {\r
+ entry.dispose();\r
+ }\r
+ moduleCache.clear();\r
+ }\r
+ moduleCache = null;\r
+ }\r
+\r
+ public Map<String, Module> getModules() {\r
+ Map<String, Module> result = new HashMap<>(moduleCache.size()); \r
+ for (Map.Entry<String, ModuleEntry> entry : moduleCache.entrySet()) {\r
+ ModuleEntry moduleEntry = entry.getValue();\r
+ if (moduleEntry.compilationResult.didSucceed()) {\r
+ result.put(entry.getKey(), moduleEntry.compilationResult.getResult());\r
+ }\r
+ }\r
+ return result;\r
+ }\r
+\r
+ public ModuleCompilationOptionsAdvisor getAdvisor() {\r
+ return advisor;\r
+ }\r
+\r
+ public void setAdvisor(ModuleCompilationOptionsAdvisor advisor) {\r
+ this.advisor = advisor;\r
+ }\r
+\r
+}\r
\ No newline at end of file
return defineClass(name, bytes, 0, bytes.length);
}
+ public byte[] getBytes(String name) {
+ // Non-SCL classes are not handled here
+ if(!name.startsWith(SCL_PACKAGE_PREFIX))
+ return null;
+
+ // Determine the id of the class loader which is responsible of the class
+ String requestedModuleName = RuntimeModule.extractClassLoaderId(name);
+
+ // Is class defined locally in this class loader?
+ if(requestedModuleName.equals(basePackageName)) {
+ String internalName = name.replace('.', '/');
+ byte[] bytes = localClasses.get(internalName);
+ if(bytes != null)
+ return bytes;
+ return localClasses.get(internalName);
+ }
+
+ // Find suitable class loader that has this class locally
+ {
+ RuntimeModule parentModule = runtimeModuleMap.get(requestedModuleName);
+ if(parentModule == null)
+ return null;
+
+ // Find the class from the ancestor class loader
+ return parentModule.classLoader.getBytes(name);
+ }
+ }
+
private Class<?> getClass(String name) throws ClassNotFoundException {
//System.out.println("getClass " + name);
package org.simantics.scl.compiler.runtime;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
import org.simantics.scl.compiler.internal.codegen.utils.JavaNamingPolicy;
import org.simantics.scl.compiler.internal.codegen.utils.TransientClassBuilder;
import org.simantics.scl.compiler.module.Module;
-import org.simantics.scl.compiler.top.SCLCompilerConfiguration;
import org.simantics.scl.compiler.top.ValueNotFound;
-import com.strobel.assembler.metadata.Buffer;
-import com.strobel.assembler.metadata.ClasspathTypeLoader;
-import com.strobel.assembler.metadata.CompositeTypeLoader;
-import com.strobel.assembler.metadata.ITypeLoader;
-import com.strobel.decompiler.Decompiler;
-import com.strobel.decompiler.DecompilerSettings;
-import com.strobel.decompiler.PlainTextOutput;
-
import gnu.trove.map.hash.THashMap;
public class RuntimeModule {
bytes = localClasses.get(internalName);
if(bytes == null)
throw new ClassNotFoundException(name);
- }
- if(SCLCompilerConfiguration.SHOW_LOADED_CLASSES_DISASSEMBLED) {
- DecompilerSettings settings = DecompilerSettings.javaDefaults();
- ITypeLoader typeLoader = new ITypeLoader() {
- @Override
- public boolean tryLoadType(String internalName, Buffer buffer) {
- byte[] bytes = getBytes(internalName);
- if(bytes != null) {
- buffer.reset(bytes.length);
- buffer.putByteArray(bytes, 0, bytes.length);
- buffer.position(0);
- return true;
- }
- else
- return false;
- }
- };
- settings.setTypeLoader(new CompositeTypeLoader(typeLoader, new ClasspathTypeLoader()));
- OutputStreamWriter writer = new OutputStreamWriter(System.out);
- PlainTextOutput output = new PlainTextOutput(writer);
- Decompiler.decompile(name, output, settings);
- try {
- writer.flush();
- } catch (IOException e) {
- }
- }
+ }
return defineClass(name, bytes, 0, bytes.length);
}
import org.simantics.scl.compiler.module.options.ModuleCompilationOptions;
import org.simantics.scl.compiler.module.repository.ModuleRepository;
import org.simantics.scl.compiler.module.repository.UpdateListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public abstract class TextualModuleSource implements ModuleSource {
+ private static final Logger LOGGER = LoggerFactory.getLogger(TextualModuleSource.class);
+
public static final ImportDeclaration[] DEFAULT_IMPORTS = new ImportDeclaration[] {
new ImportDeclaration("Builtin", ""),
new ImportDeclaration("Prelude", "")
if(compiler.getErrorLog().isEmpty())
return new Success<Module>(compiler.getModule());
else {
- System.err.println("While compiling " + getModuleName() + ":");
- System.err.println(CompilationErrorFormatter.toString(getSourceReader(null), compiler.getErrorLog().getErrors()));
+ LOGGER.error("While compiling " + getModuleName() + ":");
+ LOGGER.error(CompilationErrorFormatter.toString(getSourceReader(null), compiler.getErrorLog().getErrors()));
return new Failure(compiler.getErrorLog().getErrors());
}
} catch (IOException e) {
+++ /dev/null
-package org.simantics.scl.compiler.source.repository;
-
-import gnu.trove.procedure.TObjectProcedure;
-
-
-public abstract class AbstractModuleSourceRepository implements ModuleSourceRepository {
- @Override
- public String getDocumentation(String documentationName) {
- return null;
- }
-
- @Override
- public void forAllDocumentations(TObjectProcedure<String> procedure) {
- }
-
- @Override
- public void checkUpdates() {
- }
-}
import java.io.IOException;
import java.net.URL;
+import java.util.Collection;
import org.simantics.scl.compiler.module.ImportDeclaration;
import org.simantics.scl.compiler.module.repository.UpdateListener;
import gnu.trove.procedure.TObjectProcedure;
import gnu.trove.set.hash.THashSet;
-public class ClassModuleSourceRepository extends AbstractModuleSourceRepository {
+public class ClassModuleSourceRepository implements ModuleSourceRepository {
private final Class<?> clazz;
private final String path;
return new ClassModuleSource(moduleName, clazz, classLoader, path + "/" + moduleName + ".scl", getBuiltinImports());
}
+ @Override
+ public Collection<String> getModuleNames() {
+ return modules;
+ }
+
@Override
public void forAllModules(TObjectProcedure<String> procedure) {
modules.forEach(procedure);
protected ImportDeclaration[] getBuiltinImports() {
return ClassModuleSource.DEFAULT_IMPORTS;
}
-
- @Override
- public void clear() {
-
- }
}
package org.simantics.scl.compiler.source.repository;
+import java.util.ArrayList;
+import java.util.Collection;
+
import org.simantics.scl.compiler.module.repository.UpdateListener;
import org.simantics.scl.compiler.source.ModuleSource;
sourceRepository.forAllModules(procedure);
}
+ @Override
+ public Collection<String> getModuleNames() {
+ ArrayList<String> result = new ArrayList<>();
+ forAllModules((String name) -> {
+ result.add(name);
+ return true;
+ });
+ return result;
+ }
+
@Override
public void forAllDocumentations(TObjectProcedure<String> procedure) {
for(ModuleSourceRepository sourceRepository : children)
sourceRepository.forAllDocumentations(procedure);
}
+
+ @Override
+ public Collection<String> getDocumentationNames() {
+ ArrayList<String> result = new ArrayList<>();
+ forAllDocumentations((String name) -> {
+ result.add(name);
+ return true;
+ });
+ return result;
+ }
@Override
public void checkUpdates() {
+ for (ModuleSourceRepository child : children)
+ child.checkUpdates();
}
@Override
import java.io.File;
import java.io.IOException;
+import java.util.Collection;
import org.simantics.scl.compiler.module.ImportDeclaration;
import org.simantics.scl.compiler.module.repository.UpdateListener;
import gnu.trove.procedure.TObjectProcedure;
import gnu.trove.set.hash.THashSet;
-public class FileModuleSourceRepository extends AbstractModuleSourceRepository {
+public class FileModuleSourceRepository implements ModuleSourceRepository {
private final File path;
private final ClassLoader classLoader;
modules.forEach(procedure);
}
+ @Override
+ public Collection<String> getModuleNames() {
+ return modules;
+ }
+
protected ImportDeclaration[] getBuiltinImports() {
return ClassModuleSource.DEFAULT_IMPORTS;
}
-
- @Override
- public void clear() {
-
- }
}
package org.simantics.scl.compiler.source.repository;
+import java.util.Collection;
+
import org.simantics.scl.compiler.module.Module;
import org.simantics.scl.compiler.module.repository.UpdateListener;
import org.simantics.scl.compiler.source.ModuleSource;
return modules.get(moduleName);
}
+ @Override
+ public Collection<String> getModuleNames() {
+ return modules.keySet();
+ }
+
@Override
public void forAllModules(TObjectProcedure<String> procedure) {
modules.forEachKey(procedure);
}
@Override
- public void forAllDocumentations(TObjectProcedure<String> procedure) {
- for(String documentationName : documentations.keySet())
- procedure.execute(documentationName);
- }
-
- @Override
- public void checkUpdates() {
- }
-
- @Override
- public void clear() {
+ public Collection<String> getDocumentationNames() {
+ return documentations.keySet();
}
}
package org.simantics.scl.compiler.source.repository;
+import java.util.Collection;
+import java.util.Collections;
+
import org.simantics.scl.compiler.module.repository.ModuleRepository;
import org.simantics.scl.compiler.module.repository.UpdateListener;
import org.simantics.scl.compiler.source.ModuleSource;
* @author Hannu Niemistö
*/
public interface ModuleSourceRepository {
+ /**
+ * Returns all module names governed by this repository. Some implementations
+ * may return empty collection, even if the contain modules, if it is hard
+ * to discover all modules (for example file system based module repository
+ * works like this).
+ */
+ Collection<String> getModuleNames();
+
+ /**
+ * Calls the given procedure with all module names returned by {@link #getModuleNames}
+ */
+ default void forAllModules(TObjectProcedure<String> procedure) {
+ for(String module : getModuleNames())
+ if(!procedure.execute(module))
+ return;
+ }
+
+ /**
+ * Returns the module source of the given module name or null, if the module does not exists.
+ * If {@code listener} is not null, it is called when the module contents change.
+ */
ModuleSource getModuleSource(String moduleName, UpdateListener listener);
- void forAllModules(TObjectProcedure<String> procedure);
- String getDocumentation(String documentationName);
- void forAllDocumentations(TObjectProcedure<String> procedure);
- void checkUpdates();
- void clear();
+
+ /**
+ * Returns all documentation names governed by this repository. Some implementations
+ * may return empty collection, even if the contain documentation.
+ */
+ default Collection<String> getDocumentationNames() {
+ return Collections.emptyList();
+ }
+
+ /**
+ * Calls the given procedure with all documentation names eturned by {@link #getDocumentationNames}
+ */
+ default void forAllDocumentations(TObjectProcedure<String> procedure) {
+ for(String module : getDocumentationNames())
+ if(!procedure.execute(module))
+ return;
+ }
+
+ /**
+ * Returns original markdown text for the given documentation name or null
+ * if the documentation does not exist.
+ */
+ default String getDocumentation(String documentationName) {
+ return null;
+ }
+
+ /**
+ * Triggers repository to check if module contents have been changed. Some repositories listen
+ * changes and report them to update listeners even without manual triggering.
+ */
+ default void checkUpdates() {
+ }
+
+ /**
+ * Resets the repository and removes listeners. This is only used during regression testing and shouldn't be called during normal operation.
+ */
+ default void clear() {
+ }
}
import org.simantics.scl.compiler.common.names.Name;
import org.simantics.scl.compiler.compilation.CodeGeneration;
+import org.simantics.scl.compiler.compilation.CompilationContext;
import org.simantics.scl.compiler.constants.JavaStaticMethod;
import org.simantics.scl.compiler.constants.SCLConstant;
import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;
public Object eval() throws SCLExpressionCompilationException {
fillDefaults();
- final ErrorLog errorLog = new ErrorLog();
+ final CompilationContext compilationContext = new CompilationContext();
+ final ErrorLog errorLog = compilationContext.errorLog;
final Environment environment = runtimeEnvironment.getEnvironment();
+ compilationContext.environment = environment;
// Parse expression
- if(expressionText != null && !expressionText.trim().isEmpty()) {
+ if(expressionText != null) {
try {
switch(parseMode) {
case BLOCK: {
// Elaboration
{
- TranslationContext context = new TranslationContext(errorLog,
- environment, localEnvironment);
+ TranslationContext context = new TranslationContext(compilationContext, localEnvironment);
expression = expression.resolve(context);
if(!errorLog.isEmpty())
throw new SCLExpressionCompilationException(errorLog.getErrors());
// Type checking
{
- TypingContext context = new TypingContext(errorLog, environment);
+ TypingContext context = new TypingContext(compilationContext);
context.pushEffectUpperBound(expression.location, expectedEffect);
expression = expression.checkType(context, expectedType);
MutableClassLoader classLoader = runtimeEnvironment.getMutableClassLoader();
String moduleName = classLoader.getFreshPackageName();
JavaTypeTranslator javaTypeTranslator = new JavaTypeTranslator(environment);
+ compilationContext.javaTypeTranslator = javaTypeTranslator;
JavaNamingPolicy namingPolicy = new JavaNamingPolicy(moduleName);
+ compilationContext.namingPolicy = namingPolicy;
ModuleBuilder moduleBuilder = new ModuleBuilder(namingPolicy, javaTypeTranslator);
// Simplify
SimplificationContext context =
- new SimplificationContext(environment, errorLog,
- javaTypeTranslator, DummyJavaReferenceValidator.INSTANCE);
+ new SimplificationContext(compilationContext, DummyJavaReferenceValidator.INSTANCE);
expression = expression.simplify(context);
if(!errorLog.isEmpty())
public static final boolean SHOW_SSA_BEFORE_LAMBDA_LIFTING = false;
public static final boolean SHOW_FINAL_SSA = false;
public static final boolean SHOW_COMPILED_BYTECODE = false;
- public static final boolean SHOW_LOADED_CLASSES_DISASSEMBLED = false;
public static final boolean SHOW_EXPRESSION_BEFORE_EVALUATION = false;
public static final boolean SHOW_INTERPRETED_EXPRESSION = false;
public static final boolean EVERY_RULE_ENFORCEMENT_IN_SEPARATE_METHOD = true;
public static final boolean EVERY_DATALOG_STRATUM_IN_SEPARATE_METHOD = true;
- public static final boolean ALLOW_OVERLOADING = false;
+ public static final boolean ALLOW_OVERLOADING = true;
}
import java.util.ArrayList;
import org.simantics.scl.compiler.common.names.Name;
+import org.simantics.scl.compiler.common.names.Names;
import org.simantics.scl.compiler.elaboration.expressions.EApply;
import org.simantics.scl.compiler.elaboration.expressions.EConstant;
import org.simantics.scl.compiler.elaboration.expressions.EEnforce;
ArrayList<TCon> concreteEffects = new ArrayList<TCon>();
effect.collectConcreteEffects(concreteEffects);
if(concreteEffects.contains(Types.WRITE_GRAPH)) {
- Name name = Name.create("Simantics/DB", "syncWrite");
+ Name name = Names.Simantics_DB_syncWrite;
SCLValue transactionFunction = environment.getValue(name);
if(transactionFunction == null) {
errorLog.log(expression.location, "Cannot locate " + name);
expression = decorate(transactionFunction, Types.WRITE_GRAPH, expression);
}
else if(concreteEffects.contains(Types.READ_GRAPH)) {
- Name name = Name.create("Simantics/DB", "syncRead");
+ Name name = Names.Simantics_DB_syncRead;
SCLValue transactionFunction = environment.getValue(name);
if(transactionFunction == null) {
errorLog.log(expression.location, "Cannot locate " + name);
expression = decorate(transactionFunction, Types.READ_GRAPH, expression);
}
if(concreteEffects.contains(R)) {
- Name name = Name.create("R/R", "runR");
+ Name name = Names.R_R_runR;
SCLValue transactionFunction = environment.getValue(name);
if(transactionFunction == null) {
errorLog.log(expression.location, "Cannot locate " + name);
expression = decorate(transactionFunction, R, expression);
}
if(concreteEffects.contains(Types.RANDOM)) {
- Name name = Name.create("Random", "runRandom");
+ Name name = Names.Random_runRandom;
SCLValue transactionFunction = environment.getValue(name);
if(transactionFunction == null) {
errorLog.log(expression.location, "Cannot locate " + name);
import org.simantics.scl.compiler.internal.types.HashCodeUtils;
import org.simantics.scl.compiler.types.exceptions.KindUnificationException;
import org.simantics.scl.compiler.types.exceptions.UnificationException;
+import org.simantics.scl.compiler.types.kinds.Kind;
import org.simantics.scl.compiler.types.kinds.Kinds;
import gnu.trove.map.hash.THashMap;
return Types.metaVar(Kinds.EFFECT);
return first;
}
+
+ public static boolean equalSkeletons(TApply a, TApply b) {
+ return equalSkeletons(a.parameter, b.parameter)
+ && equalSkeletons(a.function , b.function );
+ }
+
+ public static boolean equalSkeletons(TFun a, TFun b) {
+ return equalSkeletons(a.domain, b.domain)
+ && equalSkeletons(a.range, b.range);
+ }
+
+ public static boolean equalSkeletons(TForAll a, TForAll b) {
+ Kind aKind = a.var.getKind();
+ if(!Kinds.equalsCanonical(aKind, b.var.getKind()))
+ return false;
+ TVar newVar = Types.var(aKind);
+ return equalSkeletons(a.type.replace(a.var, newVar), b.type.replace(b.var, newVar));
+ }
+
+ public static boolean equalSkeletons(TPred a, TPred b) {
+ if(a.typeClass != b.typeClass
+ || a.parameters.length != b.parameters.length)
+ return false;
+ Type[] aParameters = a.parameters;
+ Type[] bParameters = b.parameters;
+ for(int i=0;i<aParameters.length;++i)
+ if(!equalSkeletons(aParameters[i], bParameters[i]))
+ return false;
+ return true;
+ }
+
+ /**
+ * Tests equality of two types. Unbound TVars
+ * are equal only if they are the same variable.
+ * Bound TMetaVar is equal to the type it is bound to.
+ * Unbound TMetaVars are equal only if they are the same metavariable.
+ * Order of predicates and forall quantifiers matters.
+ */
+ public static boolean equalSkeletons(Type a, Type b) {
+ a = canonicalSkeleton(a);
+ b = canonicalSkeleton(b);
+ if(a == b)
+ return true;
+ Class<?> ca = a.getClass();
+ Class<?> cb = b.getClass();
+ if(ca != cb)
+ return false;
+ if(ca == TApply.class)
+ return equalSkeletons((TApply)a, (TApply)b);
+ else if(ca == TFun.class)
+ return equalSkeletons((TFun)a, (TFun)b);
+ else if(ca == TForAll.class)
+ return equalSkeletons((TForAll)a, (TForAll)b);
+ else if(ca == TPred.class)
+ return equalSkeletons((TPred)a, (TPred)b);
+ else // ca == TCon.class
+ // || (ca == TMetaVar.class && a.ref == null && b.ref == null)
+ // || ca = TVar.class
+ return false; // Equals only if a == b, that was already tested
+ }
}
return hash;
}
+ @Override
+ public int skeletonHashCode(int hash) {
+ hash = HashCodeUtils.updateWithPreprocessedValue(hash, APPLY_HASH);
+ hash = function.skeletonHashCode(hash);
+ hash = parameter.skeletonHashCode(hash);
+ return hash;
+ }
+
+ @Override
+ public int skeletonHashCode(int hash, TVar[] boundVars) {
+ hash = HashCodeUtils.updateWithPreprocessedValue(hash, APPLY_HASH);
+ hash = function.skeletonHashCode(hash, boundVars);
+ hash = parameter.skeletonHashCode(hash, boundVars);
+ return hash;
+ }
+
public Type getCanonicalFunction() {
if(function instanceof TMetaVar)
function = function.canonical();
return getCanonicalFunction().equalsCanonical(apply.getCanonicalFunction())
&& getCanonicalParameter().equalsCanonical(apply.getCanonicalParameter());
}
+
+ @Override
+ public Type[] skeletonCanonicalChildren() {
+ return new Type[] {Skeletons.canonicalSkeleton(function), Skeletons.canonicalSkeleton(parameter)};
+ }
}
return this == obj;
}
- @Override
- public int hashCode() {
- return System.identityHashCode(this);
- }
-
@Override
public void updateHashCode(TypeHashCodeContext context) {
context.append(System.identityHashCode(this));
}
public Kind inferKind(Environment context) throws KindUnificationException {
- return context.getTypeConstructor(this).kind;
+ return context.getTypeDescriptor(this).getKind();
}
public Kind getKind(Environment context) {
- return context.getTypeConstructor(this).kind;
+ return context.getTypeDescriptor(this).getKind();
}
@Override
public Type copySkeleton(THashMap<TMetaVar, TMetaVar> metaVarMap) {
return this;
}
+
+ @Override
+ public int hashCode() {
+ return System.identityHashCode(this);
+ }
@Override
public int hashCode(int hash) {
return HashCodeUtils.update(hash, System.identityHashCode(this));
}
+ @Override
+ public int skeletonHashCode() {
+ return System.identityHashCode(this);
+ }
+
+ @Override
+ public int skeletonHashCode(int hash) {
+ return HashCodeUtils.update(hash, System.identityHashCode(this));
+ }
+
+ @Override
+ public int skeletonHashCode(int hash, TVar[] boundVars) {
+ return HashCodeUtils.update(hash, System.identityHashCode(this));
+ }
+
@Override
public boolean equalsCanonical(Type other) {
return this == other;
}
+
+ @Override
+ public Type[] skeletonCanonicalChildren() {
+ return EMPTY_ARRAY;
+ }
}
return t.type.hashCode(hash, boundVars);
}
+ @Override
+ public int skeletonHashCode(int hash) {
+ int count=1;
+ {
+ Type t = Types.canonical(type);
+ while(t instanceof TForAll) {
+ t = Types.canonical( ((TForAll)t).type );
+ ++count;
+ }
+ }
+ TVar[] boundVars = new TVar[count];
+ boundVars[0] = var;
+ TForAll t = this;
+ {
+ for(int i=1;i<count;++i) {
+ t = (TForAll)Types.canonical(t.type);
+ boundVars[i] = t.var;
+ }
+ }
+
+ for(int i=0;i<count;++i)
+ hash = HashCodeUtils.updateWithPreprocessedValue(hash, FORALL_HASH);
+ return t.type.skeletonHashCode(hash, boundVars);
+ }
+
+ @Override
+ public int skeletonHashCode(int hash, TVar[] oldBoundVars) {
+ int count=1;
+ {
+ Type t = Types.canonical(type);
+ while(t instanceof TForAll) {
+ t = Types.canonical( ((TForAll)t).type );
+ ++count;
+ }
+ }
+ TVar[] boundVars = Arrays.copyOf(oldBoundVars, oldBoundVars.length + count);
+ boundVars[oldBoundVars.length] = var;
+ TForAll t = this;
+ {
+ for(int i=1;i<count;++i) {
+ t = (TForAll)Types.canonical(t.type);
+ boundVars[oldBoundVars.length + i] = t.var;
+ }
+ }
+
+ for(int i=0;i<count;++i)
+ hash = HashCodeUtils.updateWithPreprocessedValue(hash, FORALL_HASH);
+ return t.type.skeletonHashCode(hash, boundVars);
+ }
+
public Type getCanonicalType() {
if(type instanceof TMetaVar)
type = type.canonical();
@Override
public Kind getKind(Environment context) {
return Kinds.STAR;
+ }
+
+ @Override
+ public Type[] skeletonCanonicalChildren() {
+ return new Type[] { Skeletons.canonicalSkeleton(type) };
}
}
return hash;
}
+ @Override
+ public int skeletonHashCode(int hash) {
+ hash = HashCodeUtils.updateWithPreprocessedValue(hash, FUN_HASH);
+ hash = domain.skeletonHashCode(hash);
+ hash = range.skeletonHashCode(hash);
+ return hash;
+ }
+
+ @Override
+ public int skeletonHashCode(int hash, TVar[] boundVars) {
+ hash = HashCodeUtils.updateWithPreprocessedValue(hash, FUN_HASH);
+ hash = domain.skeletonHashCode(hash, boundVars);
+ hash = range.skeletonHashCode(hash, boundVars);
+ return hash;
+ }
+
public Type getCanonicalDomain() {
if(domain instanceof TMetaVar)
domain = domain.canonical();
public Kind getKind(Environment context) {
return Kinds.STAR;
}
+
+ @Override
+ public Type[] skeletonCanonicalChildren() {
+ return new Type[] {Skeletons.canonicalSkeleton(domain), Skeletons.canonicalSkeleton(range)};
+ }
}
return ref.toTypeAst(context);
}
- @Override
- public int hashCode() {
- if(ref == null)
- return System.identityHashCode(this);
- else
- return ref.hashCode();
- }
-
@Override
public void updateHashCode(TypeHashCodeContext context) {
if(ref == null)
}
public void setRef(Type type) throws UnificationException {
+ if(type instanceof TMetaVar && ((TMetaVar)type).ref != null)
+ throw new InternalCompilerError("Not canonical!");
+ if(type == this)
+ throw new InternalCompilerError("Illegal setRef");
if(DEBUG)
System.out.println("setRef " + System.identityHashCode(this) + " -> " + type);
if(ref != null)
fireNotifyAboutChange();
}
+ @Override
+ public int hashCode() {
+ if(ref == null)
+ return System.identityHashCode(this);
+ else
+ return ref.hashCode();
+ }
+
@Override
public int hashCode(int hash) {
if(ref == null)
return ref.hashCode(hash, boundVars);
}
+ @Override
+ public int skeletonHashCode() {
+ if(ref != null)
+ return ref.skeletonHashCode();
+ else if(skeletonRef != null)
+ return skeletonRef.skeletonHashCode();
+ else
+ return System.identityHashCode(this);
+ }
+
+ @Override
+ public int skeletonHashCode(int hash) {
+ if(ref != null)
+ return ref.skeletonHashCode(hash);
+ else if(skeletonRef != null)
+ return skeletonRef.skeletonHashCode(hash);
+ else
+ return HashCodeUtils.update(hash, System.identityHashCode(this));
+ }
+
+ @Override
+ public int skeletonHashCode(int hash, TVar[] boundVars) {
+ if(ref != null)
+ return ref.skeletonHashCode(hash, boundVars);
+ else if(skeletonRef != null)
+ return skeletonRef.skeletonHashCode(hash, boundVars);
+ else
+ return HashCodeUtils.update(hash, System.identityHashCode(this));
+ }
+
@Override
public boolean equalsCanonical(Type other) {
return this == other;
public Kind getKind(Environment context) {
return kind;
}
+
+ @Override
+ public Type[] skeletonCanonicalChildren() {
+ // Assumes that this is already canonical skeleton
+ return EMPTY_ARRAY;
+ }
}
hash = parameter.hashCode(hash, boundVars);
return hash;
}
+
+ @Override
+ public int skeletonHashCode(int hash) {
+ hash = HashCodeUtils.updateWithPreprocessedValue(hash, PRED_HASH);
+ hash = typeClass.skeletonHashCode(hash);
+ for(Type parameter : parameters)
+ hash = parameter.skeletonHashCode(hash);
+ return hash;
+ }
+
+ @Override
+ public int skeletonHashCode(int hash, TVar[] boundVars) {
+ hash = HashCodeUtils.updateWithPreprocessedValue(hash, PRED_HASH);
+ hash = typeClass.skeletonHashCode(hash, boundVars);
+ for(Type parameter : parameters)
+ hash = parameter.skeletonHashCode(hash, boundVars);
+ return hash;
+ }
@Override
public boolean equalsCanonical(Type other) {
public Kind getKind(Environment context) {
return Kinds.STAR;
}
+
+ @Override
+ public Type[] skeletonCanonicalChildren() {
+ Type[] result = new Type[parameters.length];
+ for(int i=0;i<parameters.length;++i)
+ result[i] = Skeletons.canonicalSkeleton(parameters[i]);
+ return result;
+ }
}
return HashCodeUtils.updateWithPreprocessedValue(hash, sum);
}
+ @Override
+ public int skeletonHashCode(int hash) {
+ int sum = UNION_HASH;
+ for(Type effect : effects)
+ sum += effect.skeletonHashCode(HashCodeUtils.SEED);
+ return HashCodeUtils.updateWithPreprocessedValue(hash, sum);
+ }
+
+ @Override
+ public int skeletonHashCode(int hash, TVar[] boundVars) {
+ int sum = UNION_HASH;
+ for(Type effect : effects)
+ sum += effect.skeletonHashCode(HashCodeUtils.SEED, boundVars);
+ return HashCodeUtils.updateWithPreprocessedValue(hash, sum);
+ }
+
@Override
public boolean equalsCanonical(Type other) {
if(this == other)
public Kind getKind(Environment context) {
return Kinds.EFFECT;
}
+
+ @Override
+ public Type[] skeletonCanonicalChildren() {
+ return EMPTY_ARRAY;
+ }
}
return this == obj;
}
- @Override
- public int hashCode() {
- return System.identityHashCode(this);
- }
-
@Override
public void updateHashCode(TypeHashCodeContext context) {
TObjectIntHashMap<TVar> varHashCode = context.getVarHashCode();
return this;
}
+ @Override
+ public int hashCode() {
+ return System.identityHashCode(this);
+ }
+
@Override
public int hashCode(int hash) {
return HashCodeUtils.update(hash, System.identityHashCode(this));
return HashCodeUtils.update(hash, System.identityHashCode(this));
}
+ @Override
+ public int skeletonHashCode() {
+ return System.identityHashCode(this);
+ }
+
+ @Override
+ public int skeletonHashCode(int hash) {
+ return HashCodeUtils.update(hash, System.identityHashCode(this));
+ }
+
+ @Override
+ public int skeletonHashCode(int hash, TVar[] boundVars) {
+ for(int i=0;i<boundVars.length;++i)
+ if(boundVars[i] == this) {
+ hash = HashCodeUtils.updateWithPreprocessedValue(hash, BOUND_VAR_HASH);
+ return HashCodeUtils.update(hash, i);
+ }
+ return HashCodeUtils.update(hash, System.identityHashCode(this));
+ }
+
@Override
public boolean equalsCanonical(Type other) {
return this == other;
public Kind getKind(Environment context) {
return kind;
}
+
+ @Override
+ public Type[] skeletonCanonicalChildren() {
+ return EMPTY_ARRAY;
+ }
}
public abstract void updateHashCode(TypeHashCodeContext context);
public abstract int hashCode(int hash);
public abstract int hashCode(int hash, TVar[] boundVars);
+
+ public int skeletonHashCode() {
+ return skeletonHashCode(HashCodeUtils.SEED);
+ }
+
+ public abstract int skeletonHashCode(int hash);
+ public abstract int skeletonHashCode(int hash, TVar[] boundVars);
public abstract void collectFreeVars(ArrayList<TVar> vars);
public abstract Kind getKind(Environment context);
+ public abstract Type[] skeletonCanonicalChildren();
+
}
\ No newline at end of file
public static final TCon ORDERED_RING = con("Prelude", "OrderedRing");
public static final TCon REAL = con("Prelude", "Real");
public static final TCon SHOW = con("Prelude", "Show");
- public static final TCon EQ = con("Prelude", "Eq");
public static final TCon ORD = con("Prelude", "Ord");
- public static final TCon HASHABLE = con("Prelude", "Hashable");
public static final TCon IO = con("Serialization", "IO");
public static final Type REF = con("Prelude", "Ref");
else
return new TUnion(effects);
}
+
+ public static Type union(Type effect1, Type effect2) {
+ return new TUnion(effect1, effect2);
+ }
public static Type union(List<Type> effects) {
if(effects.size() == 0)
--- /dev/null
+package org.simantics.scl.compiler.types.util;\r
+\r
+import org.simantics.scl.compiler.types.Skeletons;\r
+import org.simantics.scl.compiler.types.Type;\r
+\r
+import gnu.trove.map.hash.THashMap;\r
+\r
+public class SkeletonKeyMap<T> extends THashMap<Type,T> {\r
+ @Override\r
+ protected int hash(Object notnull) {\r
+ return ((Type)notnull).hashCode();\r
+ }\r
+ \r
+ @Override\r
+ protected boolean equals(Object notnull, Object two) {\r
+ return Skeletons.equalSkeletons((Type)notnull, (Type)two);\r
+ }\r
+}\r
+++ /dev/null
-package org.simantics.scl.compiler.tests;
-
-import org.junit.Ignore;
-import org.junit.Test;
-
-public class ActiveTests extends TestBase {
-
- public ActiveTests() { super("scl"); }
-/*
- @Test public void Equations1() { test(); }
- @Test public void MarketModel2() { test(); }
- @Test public void Overloading2() { test(); }
- @Test public void Overloading3() { test(); }
- //@Ignore
- @Test public void PatternError() { test(); }
- @Test public void Serialization() { test(); }
- @Ignore
- @Test public void TypeClass2() { test(); }
- @Test public void TypeClassBug2() { test(); }
- */
-
- //@Test public void CityoptSetup() { test(); }
- @Test public void EmptyLet() { test(); }
-}
+++ /dev/null
-package org.simantics.scl.compiler.tests;\r
-\r
-import java.lang.reflect.Method;\r
-\r
-import org.objectweb.asm.ClassWriter;\r
-import org.objectweb.asm.MethodVisitor;\r
-import org.objectweb.asm.Opcodes;\r
-\r
-public class FindAllowedChars {\r
- public static class MyClassLoader extends ClassLoader {\r
- final String className;\r
- final byte[] classBytes;\r
- \r
- public MyClassLoader(ClassLoader parent, String className, byte[] classBytes) {\r
- super(parent);\r
- this.className = className;\r
- this.classBytes = classBytes;\r
- }\r
- \r
- public MyClassLoader(String className, byte[] classBytes) {\r
- this.className = className;\r
- this.classBytes = classBytes;\r
- }\r
-\r
- @Override\r
- protected Class<?> findClass(String name) throws ClassNotFoundException {\r
- if(name.equals(name))\r
- return defineClass(name, classBytes, 0, classBytes.length);\r
- else\r
- return super.findClass(name);\r
- }\r
- }\r
- \r
- public static void test(String className, String methodName) throws Exception {\r
- ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS);\r
- classWriter.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, className, null, "java/lang/Object", null);\r
- \r
- MethodVisitor methodVisitor = classWriter.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, methodName, "()V", null, null);\r
- /*methodVisitor.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");\r
- methodVisitor.visitLdcInsn("Hello world!");\r
- methodVisitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);*/\r
- methodVisitor.visitInsn(Opcodes.RETURN);\r
- methodVisitor.visitMaxs(0, 0);\r
- methodVisitor.visitEnd();\r
- classWriter.visitEnd();\r
- \r
- ClassLoader loader = new MyClassLoader(className, classWriter.toByteArray());\r
- Class<?> clazz = loader.loadClass(className);\r
- Method method = clazz.getMethod(methodName);\r
- method.invoke(null);\r
- }\r
- \r
- public static void main(String[] args) throws Exception {\r
- for(int a=Character.MIN_VALUE;a<Character.MAX_VALUE;++a) {\r
- //for(char b=0;b<256;++b) {\r
- String name = new String(new char[] {(char)a});\r
- try {\r
- test(name, "test");\r
- } catch(Throwable e) {\r
- System.out.println(name + " (" + a + ")");\r
- }\r
- //} \r
- }\r
- System.out.println((int)Character.MAX_VALUE);\r
- }\r
-}\r
+++ /dev/null
-package org.simantics.scl.compiler.tests;
-
-import org.junit.AfterClass;
-import org.junit.Test;
-import org.simantics.scl.compiler.errors.Failable;
-import org.simantics.scl.compiler.module.Module;
-import org.simantics.scl.compiler.module.coverage.CoverageUtils;
-import org.simantics.scl.compiler.module.coverage.ModuleCoverage;
-import org.simantics.scl.compiler.top.ValueNotFound;
-import org.simantics.scl.runtime.profiling.BranchPoint;
-
-public class ModuleRegressionTests extends TestBase {
-
- public ModuleRegressionTests() { super("scl"); }
-
- @Test public void AmbiguousType() { test(); }
- @Test public void ApplicationOfNunfunction() { test(); }
- @Test public void Arity1() { test(); }
- @Test public void AsPattern() { test(); }
- @Test public void BigContext() { test(); }
- @Test public void BigFunction() { test(); }
- @Test public void BinaryOperators1() { test(); }
- @Test public void BooleanId() { test(); }
- @Test public void Bug4450() { test(); }
- @Test public void Character1() { test(); }
- @Test public void ClashingClass() { test(); }
- @Test public void ClashingData() { test(); }
- @Test public void ClashingInstance() { test(); }
- @Test public void ClashingValueType() { test(); }
- @Test public void Collaz() { test(); }
- @Test public void Compose() { test(); }
- @Test public void Composition() { test(); }
- @Test public void ConjunctionMacro() { test(); }
- @Test public void Constant() { test(); }
- @Test public void ConstructorNameClash() { test(); }
- @Test public void DefaultMethods1() { test(); }
- @Test public void Deriving3() { test(); }
- @Test public void Deriving4() { test(); }
- @Test public void DifferentBranchTypes() { test(); }
- @Test public void Div() { test(); }
- @Test public void DoubleConversion() { test(); }
- @Test public void DoubleEffect() { test(); }
- @Test public void Effects1() { test(); }
- @Test public void Effects2() { test(); }
- @Test public void Effects3() { test(); }
- @Test public void Effects4() { test(); }
- @Test public void Effects5() { test(); }
- @Test public void Effects6() { test(); }
- @Test(expected=ValueNotFound.class)
- public void EmptyModule() throws ValueNotFound {
- test(new String[]{"EmptyModule"}, new String[]{""});
- }
- @Test public void Equality() { test(); }
- @Test public void ExistentialData() { test(); }
- @Test public void ExistentialData2() { test(); }
- @Test public void ExpressionParsing() { test(); }
- @Test public void FaultyRecursion() { test(); }
- @Test public void Fibonacci() { test(); }
- @Test public void Fibonacci2() { test(); }
- @Test public void Fibonacci3() { test(); }
- @Test public void FingerTree() { test(); }
- @Test public void FoldMissingInitialValue() { test(); }
- @Test public void FoldlBuild1() { test(); }
- @Test public void FoldlBuild2() { test(); }
- @Test public void Forall1() { test(); }
- @Test public void Forall2() { test(); }
- @Test public void Forall3() { test(); }
- @Test public void Formula() { test(); }
- @Test public void FromDynamic() { test(); }
- @Test public void FromDynamic2() { test(); }
- @Test public void FromDynamic3() { test(); }
- @Test public void FromDynamic4() { test(); }
- @Test public void FromDynamic5() { test(); }
- @Test public void FunctionFunctor() { test(); }
- @Test public void Functor() { test(); }
- @Test public void FunctorM1() { test(); }
- @Test public void Generalization() { test(); }
- @Test public void GenericMutualRecursion() { test(); }
- @Test public void GlobalVariables() { test(); }
- @Test public void GuardedExpressionBug() { test(); }
- @Test public void Guards1() { test(); }
- @Test public void Guards2() { test(); }
- @Test public void IdAsOperator() { test(); }
- @Test public void IllegalChar() { test(); }
- @Test public void ImportJavaConstructor() { test(); }
- @Test public void ImportRef() { test(); }
- @Test public void InconsistentArity() { test(); }
- @Test public void InconsistentIndentation() { test(); }
- @Test public void IndentationAndParenthesis() { test(); }
- @Test public void Index() { test(); }
- @Test public void Inline1() { test(); }
- @Test public void InstanceHierarchy() { test(); }
- @Test public void InstanceIsTypoedAsClass() { test(); }
- @Test public void InvalidClass1() { test(); }
- @Test public void InvalidEncoding() { test(); }
- @Test public void InvalidInstance1() { test(); }
- @Test public void InvalidJavaTypeAnnotation() { test(); }
- @Test public void InvalidKinds() { test(); }
- @Test public void InvalidKinds2() { test(); }
- @Test public void InvalidKinds3() { test(); }
- @Test public void InvalidLambda() { test(); }
- @Test public void InvalidModule() { test(); }
- @Test public void InvalidPattern1() { test(); }
- @Test public void InvalidPattern2() { test(); }
- @Test public void InvalidPattern3() { test(); }
- @Test public void InvalidPattern4() { test(); }
- @Test public void InvalidTypeClassInstance1() { test(); }
- @Test public void JavaAccess1() { test(); }
- @Test public void JavaConstructors() { test(); }
- @Test public void JavaMethods() { test(); }
- @Test public void JavaTypes() { test(); }
- @Test public void Kinds1() { test(); }
- @Test public void Lambda() { test(); }
- @Test public void Layout1() { test(); }
- @Test public void List() { test(); }
- @Test public void ListError1() { test(); }
- @Test public void ListError2() { test(); }
- @Test public void ListSyntax() { test(); }
- @Test public void ListSyntax10() { test(); }
- @Test public void ListSyntax11() { test(); }
- @Test public void ListSyntax12() { test(); }
- @Test public void ListSyntax2() { test(); }
- @Test public void ListSyntax3() { test(); }
- @Test public void ListSyntax4() { test(); }
- @Test public void ListSyntax5() { test(); }
- @Test public void ListSyntax6() { test(); }
- @Test public void ListSyntax7() { test(); }
- @Test public void ListSyntax8() { test(); }
- @Test public void ListSyntax9() { test(); }
- @Test public void ListSyntaxWithoutPrelude() { test(); }
- @Test public void LocalDefinitions() { test(); }
- @Test public void LocalDefinitions2() { test(); }
- @Test public void LocalDefinitions3() { test(); }
- @Test public void LocalDefinitions4() { test(); }
- @Test public void LocalDefinitions5() { test(); }
- @Test public void Macros1() { test(); }
- @Test public void Macros2() { test(); }
- @Test public void Macros4() { test(); }
- @Test public void Map1() { test(); }
- @Test public void MarketModel() { test(); }
- @Test public void Matching() { test(); }
- @Test public void Matching2() { test(); }
- @Test public void Matching4() { test(); }
- @Test public void Matching5() { test(); }
- @Test public void MatchingWithMissingParameter() { test(); }
- @Test public void MatchingWithoutTypeAnnotations() { test(); }
- @Test public void MaximumBy() { test(); }
- @Test public void Maybe1() { test(); }
- @Test public void Maybe2() { test(); }
- @Test public void Maybe3() { test(); }
- @Test public void Maybe4() { test(); }
- @Test public void MissingEffect() { test(); }
- @Test public void MissingMethod() { test(); }
- @Test public void ModuleInitialization() { test(); }
- @Test public void MonadBug1() { test(); }
- @Test public void MonadSyntax1() { test(); }
- @Test public void Monads1() { test(); }
- @Test public void NoDefinitionErrorMessage() { test(); }
- @Test public void NoInstance() { test(); }
- @Test public void NoInstance2() { test(); }
- @Test public void NonassociativeOperator() { test(); }
- @Test public void NonexistentTypeClassInAnnotation() { test(); }
- @Test public void NonexistingEffect() { test(); }
- @Test public void OneLineMatch() { test(); }
- @Test public void OpenString1() { test(); }
- @Test public void OpenString2() { test(); }
- @Test public void OverloadedArithmetic1() { test(); }
- @Test public void OverloadedArithmetic2() { test(); }
- @Test public void OverloadedArithmetic3() { test(); }
- @Test public void OverloadedLiterals2() { test(); }
- @Test public void Overloading1() { test(); }
- @Test public void Parsing() { test(); }
- @Test public void PolymorphicRecursion() { test(); }
- @Test public void PolymorphicRecursion2() { test(); }
- @Test public void Polynomials() { test(); }
- @Test public void PrecedenceOfNonoperators() { test(); }
- @Test public void Primes() { test(); }
- @Test public void Proc1() { test(); }
- @Test public void Proc2() { test(); }
- @Test public void Proc3() { test(); }
- @Test public void Pythagoras() { test(); }
- @Test public void Random1() { test(); }
- @Test public void RangeSyntax() { test(); }
- @Test public void Record1() { test(); }
- @Test public void RecordShorthand() { test(); }
- @Test public void RecursiveContext() { test(); }
- @Test public void RecursiveValues2() { test(); }
- @Test public void RecursiveValues3() { test(); }
- @Test public void RecursiveValues4() { test(); }
- @Test public void RedBlackTrees() { test(); }
- @Test public void Relations1() { test(); }
- @Test public void Relations2() { test(); }
- @Test public void RepeatedVariableInPattern() { test(); }
- @Test public void SSATypingBug() { test(); }
- @Test public void Scanl() { test(); }
- @Test public void Search() { 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(); }
- @Test public void Select7() { test(); }
- @Test public void Select8() { test(); }
- @Test public void Select9() { test(); }
- @Test public void SelfReferringContextInTypeClass() { test(); }
- @Test public void Serialization2() { test(); }
- @Test public void Serialization3() { test(); }
- @Test public void SharedTypeVariable() { test(); }
- @Test public void ShortcutFusion() { test(); }
- @Test public void Show1() { test(); }
- @Test public void SinConst1() { test(); }
- @Test public void Sort() { test(); }
- @Test public void Sort2() { test(); }
- @Test public void StreamFusion() { test(); }
- @Test public void StringEscape() { test(); }
- @Test public void StringInterpolation1() { test(); }
- @Test public void StringMatching1() { test(); }
- @Test public void SumOfInverses2() { test(); }
- @Test public void TooManyParametersToSin() { test(); }
- @Test public void Transformation1() { test(); }
- @Test public void Transformation2() { test(); }
- @Test public void Transformation3() { test(); }
- @Test public void Transformation4() { test(); }
- @Test public void Transformation5() { test(); }
- @Test public void Transformation6() { test(); }
- @Test public void Transformation7() { test(); }
- @Test public void TransformationOrder() { test(); }
- @Test public void Tuples() { test(); }
- @Test public void Tuples2() { test(); }
- @Test public void TypeAlias1() { test(); }
- @Test public void TypeAlias2() { test(); }
- @Test public void TypeAlias3() { test(); }
- @Test public void TypeAliasRefsToTypeAlias() { test(); }
- @Test public void TypeAnnotation1() { test(); }
- @Test public void TypeAnnotation2() { test(); }
- @Test public void TypeClass() { test(); }
- @Test public void TypeClassBug1() { test(); }
- @Test(timeout=1000L) public void TypeInferenceBug2() { test(); }
- @Test public void TypeOf1() { test(); }
- @Test public void TypingBug1() { test(); }
- @Test public void TypingError1() { test(); }
- @Test public void TypingError2() { test(); }
- @Test public void UnaryMinus() { test(); }
- @Test public void UndefinedValue() { test(); }
- @Test public void UnexpectedToken() { test(); }
- @Test public void Unification1() { test(); }
- @Test public void UnknownAnnotation() { test(); }
- @Test public void UnresolvedClass() { test(); }
- @Test public void UnresolvedTypeInAnnotation() { test(); }
- @Test public void UnresolvedTypeInInstance() { test(); }
- @Test public void UnresolvedVariable() { test(); }
- @Test public void UnresolvedVariable2() { test(); }
- @Test public void ValueAsOperator() { test(); }
- @Test public void ValueConversion() { test(); }
- @Test public void Vector1() { test(); }
- @Test public void Vector2() { test(); }
- @Test public void Void1() { test(); }
- @Test public void Void2() { test(); }
- @Test public void Void3() { test(); }
- @Test public void While() { test(); }
- @Test public void While2() { test(); }
- @Test public void While3() { test(); }
- @Test public void WrongDefaultMethod() { test(); }
- @Test public void WrongInstanceMethod() { test(); }
-
- @AfterClass
- public static void checkCoverage() {
- Failable<Module> maybeModule = PRELUDE_MODULE_REPOSITORY.getModule("Prelude");
- if(!maybeModule.didSucceed())
- return;
- Module module = maybeModule.getResult();
- ModuleCoverage coverage = CoverageUtils.getCoverage(module);
- if(coverage == null)
- return;
- coverage.print(System.out);
- printCoverageTree(module.getBranchPoints().get("lookup"), 0);
- }
-
- private static void printCoverageTree(BranchPoint[] branchPoints, int ind) {
- for(BranchPoint bp : branchPoints) {
- for(int i=0;i<ind;++i)
- System.out.print(" ");
- System.out.println(bp.getCodeSize());
- printCoverageTree(bp.getChildren(), ind+1);
- }
- }
-
-}
+++ /dev/null
-package org.simantics.scl.compiler.tests;
-
-import org.junit.runner.RunWith;
-import org.junit.runners.Suite;
-import org.junit.runners.Suite.SuiteClasses;
-
-@RunWith(Suite.class)
-@SuiteClasses({
- ModuleRegressionTests.class,
- TestExpressionEvaluator.class,
- TestCommandSession.class
-})
-public class RegressionTests {
-}
+++ /dev/null
-package org.simantics.scl.compiler.tests;
-
-import java.io.BufferedReader;
-import java.io.InputStreamReader;
-import java.nio.charset.Charset;
-
-import org.junit.Before;
-import org.simantics.scl.compiler.commands.CommandSession;
-import org.simantics.scl.compiler.commands.TestScriptExecutor;
-import org.simantics.scl.compiler.module.repository.ModuleRepository;
-import org.simantics.scl.compiler.source.repository.CompositeModuleSourceRepository;
-import org.simantics.scl.compiler.source.repository.SourceRepositories;
-
-public class ScriptTestBase {
-
- private final String path;
-
- ModuleRepository moduleRepository;
-
- public ScriptTestBase(String path) {
- this.path = path;
- }
-
- @Before
- public void initialize() throws Exception {
- moduleRepository = new ModuleRepository(
- new CompositeModuleSourceRepository(
- SourceRepositories.BUILTIN_SOURCE_REPOSITORY,
- SourceRepositories.PRELUDE_SOURCE_REPOSITORY
- ));
- }
-
- protected void test() throws Exception {
- String testScriptName = Thread.currentThread().getStackTrace()[2].getMethodName();
- String testPath = "scripts/" + testScriptName + ".sts";
-
- CommandSession session = new CommandSession(moduleRepository, null);
- new TestScriptExecutor(session,
- new BufferedReader(
- new InputStreamReader(getClass().getResourceAsStream(testPath), Charset.forName("UTF-8"))),
- null)
- .execute();
- }
-
-}
+++ /dev/null
-package org.simantics.scl.compiler.tests;
-
-import org.junit.Test;
-
-public class ScriptTests extends ScriptTestBase {
-
- public ScriptTests() {
- super("scripts");
- }
-
- @Test public void Arithmetic() throws Exception { test(); }
- @Test public void Functions() throws Exception { test(); }
- @Test public void Functions2() throws Exception { test(); }
- @Test public void Lists() throws Exception { test(); }
-
-}
+++ /dev/null
-package org.simantics.scl.compiler.tests;
-
-import org.junit.runner.RunWith;
-import org.junit.runners.Suite;
-import org.junit.runners.Suite.SuiteClasses;
-import org.simantics.scl.compiler.tests.unit.TestSubSolver;
-
-@RunWith(Suite.class)
-@SuiteClasses({
- RegressionTests.class,
-
- ActiveTests.class,
- UnimplementedTests.class,
- ScriptTests.class,
-
- TestSubSolver.class
-})
-public class TestAll {
-}
+++ /dev/null
-package org.simantics.scl.compiler.tests;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.regex.Pattern;
-
-import org.junit.Assert;
-import org.simantics.scl.compiler.errors.Failable;
-import org.simantics.scl.compiler.errors.Failure;
-import org.simantics.scl.compiler.module.ImportDeclaration;
-import org.simantics.scl.compiler.module.Module;
-import org.simantics.scl.compiler.module.repository.ModuleRepository;
-import org.simantics.scl.compiler.module.repository.UpdateListener;
-import org.simantics.scl.compiler.source.ModuleSource;
-import org.simantics.scl.compiler.source.StringModuleSource;
-import org.simantics.scl.compiler.source.repository.CompositeModuleSourceRepository;
-import org.simantics.scl.compiler.source.repository.MapModuleSourceRepository;
-import org.simantics.scl.compiler.source.repository.SourceRepositories;
-import org.simantics.scl.compiler.top.ValueNotFound;
-
-public class TestBase {
-
- public static final ModuleRepository PRELUDE_MODULE_REPOSITORY = new ModuleRepository(
- new CompositeModuleSourceRepository(
- SourceRepositories.BUILTIN_SOURCE_REPOSITORY,
- SourceRepositories.PRELUDE_SOURCE_REPOSITORY
- ));
- private static final Pattern TEST_SEPARATOR = Pattern.compile("^--+ *$", Pattern.MULTILINE);
- private static final Charset UTF8 = Charset.forName("UTF-8");
-
- String path;
-
- public TestBase(String path) {
- this.path = path;
- }
-
- protected void test() {
- String testModuleName = Thread.currentThread().getStackTrace()[2].getMethodName();
- String testPath = path + "/" + testModuleName + ".scl";
-
- try {
- String[] testParts = readTestParts(testPath);
-
- int j=0;
- ArrayList<String> auxModuleNameList = new ArrayList<String>();
- while(j < testParts.length) {
- String part = testParts[j];
- if(part.startsWith("// module "))
- auxModuleNameList.add(part.substring(10).split("\\n", 2)[0].trim());
- else
- break;
- ++j;
- }
- int mainId = j;
- String[] moduleNames = new String[mainId+1];
- String[] moduleTexts = new String[mainId+1];
- for(int i=0;i<mainId;++i) {
- moduleNames[i] = auxModuleNameList.get(i);
- moduleTexts[i] = testParts[i];
- }
- moduleNames[mainId] = testModuleName;
-
- for(;j<testParts.length;j+=2) {
- moduleTexts[mainId] = testParts[j];
- String expectedOutput = j+1<testParts.length ? testParts[j+1] : "";
- String actualOutput = test(moduleNames, moduleTexts);
- Assert.assertEquals(
- canonicalizeOutput(expectedOutput),
- canonicalizeOutput(actualOutput));
- }
- } catch(IOException e) {
- throw new RuntimeException(e);
- } catch (ValueNotFound e) {
- throw new RuntimeException(e);
- }
- }
-
- private static String canonicalizeOutput(String text) {
- return text.trim().replace("\r\n", "\n");
- }
-
- protected String test(String[] moduleNames, String[] moduleTexts) throws ValueNotFound {
- if(moduleNames.length != moduleTexts.length)
- throw new IllegalArgumentException();
- /*for(int i=0;i<moduleNames.length;++i) {
- System.out.println("-- " + moduleNames[i] + " --");
- System.out.println(moduleTexts[i]);
- }*/
-
- ModuleSource[] moduleSources = new ModuleSource[moduleNames.length];
- for(int i=0;i<moduleNames.length;++i)
- moduleSources[i] = new StringModuleSource(
- moduleNames[i], getClass().getClassLoader(), moduleTexts[i]) {
- @Override
- protected ImportDeclaration[] getBuiltinImports(UpdateListener listener) {
- return ImportDeclaration.ONLY_BUILTINS;
- }
- };
- ModuleRepository testEnvironment = new ModuleRepository(
- PRELUDE_MODULE_REPOSITORY,
- new MapModuleSourceRepository(moduleSources));
- int lastId = moduleNames.length-1;
- Failable<Module> result = testEnvironment.getModule(moduleNames[lastId]);
- if(!result.didSucceed())
- return ((Failure)result).toString(moduleTexts[lastId]);
- else {
- Object main = testEnvironment.getRuntimeModule(moduleNames[lastId]).getResult().getValue("main");
- return String.valueOf(main);
- }
- }
-
- private String[] readTestParts(String testPath) throws IOException {
- InputStream stream = getClass().getResourceAsStream(testPath);
- try {
- byte[] buffer = new byte[1024];
- int pos = 0;
- while(true) {
- int c = stream.read(buffer, pos, buffer.length-pos);
- if(c <= 0)
- break;
- pos += c;
- if(pos < buffer.length)
- break;
- buffer = Arrays.copyOf(buffer, pos*2);
- }
- String text = new String(buffer, 0, pos, UTF8);
- String[] result = TEST_SEPARATOR.split(text);
- for(int i=1;i<result.length;++i) {
- if(result[i].startsWith("\r\n"))
- result[i] = result[i].substring(2);
- if(result[i].startsWith("\n") || result[i].startsWith("\r"))
- result[i] = result[i].substring(1);
- }
- return result;
- } finally {
- stream.close();
- }
- }
-}
+++ /dev/null
-package org.simantics.scl.compiler.tests;\r
-\r
-import org.junit.Test;\r
-import org.simantics.scl.compiler.elaboration.java.Builtins;\r
-import org.simantics.scl.compiler.environment.specification.EnvironmentSpecification;\r
-import org.simantics.scl.compiler.module.ImportDeclaration;\r
-import org.simantics.scl.compiler.module.repository.ModuleRepository;\r
-import org.simantics.scl.compiler.module.repository.UpdateListener;\r
-import org.simantics.scl.compiler.runtime.RuntimeEnvironment;\r
-import org.simantics.scl.compiler.source.PrecompiledModuleSource;\r
-import org.simantics.scl.compiler.source.StringModuleSource;\r
-import org.simantics.scl.compiler.source.repository.MapModuleSourceRepository;\r
-import org.simantics.scl.compiler.source.repository.ModuleSourceRepository;\r
-import org.simantics.scl.compiler.top.ExpressionEvaluator;\r
-\r
-import junit.framework.Assert;\r
-\r
-public class TestClassNaming {\r
-\r
- private static class SimpleModuleSource extends StringModuleSource {\r
- public SimpleModuleSource(String moduleName, String moduleText) {\r
- super(moduleName, moduleText);\r
- }\r
- \r
- @Override\r
- protected ImportDeclaration[] getBuiltinImports(UpdateListener listener) {\r
- return new ImportDeclaration[] {new ImportDeclaration("Builtin", "")};\r
- }\r
- }\r
- \r
- @Test\r
- public void testClassNaming() throws Exception {\r
- ModuleSourceRepository sourceRepository = new MapModuleSourceRepository(\r
- new PrecompiledModuleSource(Builtins.INSTANCE),\r
- new SimpleModuleSource("http://ProjectGame@A/SCLConstants",\r
- "locale = \"fi-FI\"")\r
- );\r
- ModuleRepository moduleRepository = new ModuleRepository(sourceRepository);\r
- RuntimeEnvironment runtimeEnvironment = moduleRepository.createRuntimeEnvironment(\r
- EnvironmentSpecification.of(\r
- "http://ProjectGame@A/SCLConstants", ""),\r
- getClass().getClassLoader());\r
- Assert.assertEquals("fi-FI", new ExpressionEvaluator(runtimeEnvironment, "locale").eval());\r
- }\r
- \r
-}\r
+++ /dev/null
-package org.simantics.scl.compiler.tests;\r
-\r
-import java.io.Reader;\r
-import java.io.StringReader;\r
-\r
-import org.junit.Test;\r
-import org.simantics.scl.compiler.internal.parsing.parser.SCLParser;\r
-import org.simantics.scl.compiler.internal.parsing.parser.SCLParserImpl;\r
-\r
-public class TestCommandParsing {\r
- @Test\r
- public void testCommandParsing() throws Exception {\r
- Reader reader = new StringReader("import \"asdasd\";a = 1\nb = 2");\r
- SCLParser parser = new SCLParserImpl(reader) {\r
- @Override\r
- protected Object reduceStatementCommand() {\r
- System.out.println("statement " + get(0));\r
- return null;\r
- }\r
- \r
- @Override\r
- protected Object reduceImport() {\r
- System.out.println("import " + get(0));\r
- return null;\r
- }\r
- };\r
- parser.parseCommands();\r
- }\r
-}\r
+++ /dev/null
-package org.simantics.scl.compiler.tests;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.simantics.scl.compiler.commands.CommandSession;
-import org.simantics.scl.compiler.module.repository.ModuleRepository;
-import org.simantics.scl.compiler.source.repository.CompositeModuleSourceRepository;
-import org.simantics.scl.compiler.source.repository.SourceRepositories;
-import org.simantics.scl.runtime.reporting.AbstractSCLReportingHandler;
-import org.simantics.scl.runtime.reporting.SCLReportingHandler;
-
-public class TestCommandSession {
-
- ModuleRepository moduleRepository;
-
- @Before
- public void initialize() throws Exception {
- moduleRepository = new ModuleRepository(
- new CompositeModuleSourceRepository(
- SourceRepositories.BUILTIN_SOURCE_REPOSITORY,
- SourceRepositories.PRELUDE_SOURCE_REPOSITORY
- ));
- }
-
- private static class SCLErrorMessageException extends RuntimeException {
- private static final long serialVersionUID = 418954639267697065L;
- public SCLErrorMessageException(String message) {
- super(message);
- }
- }
-
- private static final SCLReportingHandler TEST_HANDLER = new AbstractSCLReportingHandler() {
- @Override
- public void print(String text) {
- System.out.println(text);
- }
-
- public void printError(String error) {
- System.err.println(error);
- throw new SCLErrorMessageException(error);
- }
- };
-
- @Test
- public void testCommandSession() {
- CommandSession session = new CommandSession(moduleRepository, TEST_HANDLER);
-
- session.execute("a = 1");
- session.execute("b = 2");
- session.execute("a + b");
-
- session.execute("x = 1\ny = 2");
- session.execute("x + y");
- }
-
- @Test
- public void testCommandSession2() {
- CommandSession session = new CommandSession(moduleRepository, TEST_HANDLER);
-
- session.execute("f name coords = print \"\\(name :: String) \\(coords :: (Double, Double))\"");
- session.execute("g name (x,y) = f name (x,y)");
- }
-
- @Test
- public void testTyping1() {
- CommandSession session = new CommandSession(moduleRepository, TEST_HANDLER);
-
- session.execute("apply f = f ()");
- session.execute("printHello () = print \"Hello\"");
- session.execute("apply printHello");
- }
-
- @Test
- public void testTyping2() {
- CommandSession session = new CommandSession(moduleRepository, TEST_HANDLER);
-
- session.execute("iter f (list :: [a]) = loop 0 where { len = length list ; loop i | i == len = 0 | otherwise = do f (list!i) ; loop (i+1) }");
- session.execute("iter (\\i -> print i) [1,2,3]");
- session.execute("iter (\\i -> print i) [(),(),()]");
- }
-
-}
+++ /dev/null
-package org.simantics.scl.compiler.tests;
-
-import java.util.Arrays;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.simantics.scl.compiler.elaboration.expressions.EVariable;
-import org.simantics.scl.compiler.elaboration.expressions.Expression;
-import org.simantics.scl.compiler.elaboration.expressions.Variable;
-import org.simantics.scl.compiler.environment.AbstractLocalEnvironment;
-import org.simantics.scl.compiler.environment.Environment;
-import org.simantics.scl.compiler.environment.LocalEnvironment;
-import org.simantics.scl.compiler.environment.specification.EnvironmentSpecification;
-import org.simantics.scl.compiler.errors.CompilationErrorFormatter;
-import org.simantics.scl.compiler.module.repository.ImportFailure;
-import org.simantics.scl.compiler.module.repository.ImportFailureException;
-import org.simantics.scl.compiler.module.repository.ModuleRepository;
-import org.simantics.scl.compiler.runtime.RuntimeEnvironment;
-import org.simantics.scl.compiler.source.repository.CompositeModuleSourceRepository;
-import org.simantics.scl.compiler.source.repository.SourceRepositories;
-import org.simantics.scl.compiler.top.ExpressionEvaluator;
-import org.simantics.scl.compiler.top.SCLExpressionCompilationException;
-import org.simantics.scl.compiler.types.Type;
-import org.simantics.scl.compiler.types.Types;
-import org.simantics.scl.runtime.function.Function;
-import org.simantics.scl.runtime.tuple.Tuple0;
-
-import junit.framework.Assert;
-
-public class TestExpressionEvaluator {
-
- public static final boolean TIMING = false;
- public static final int COUNT = 10000;
-
- ModuleRepository moduleRepository;
-
- RuntimeEnvironment runtimeEnvironment;
-
- @Before
- public void initialize() throws Exception {
- moduleRepository = new ModuleRepository(
- new CompositeModuleSourceRepository(
- SourceRepositories.BUILTIN_SOURCE_REPOSITORY,
- SourceRepositories.PRELUDE_SOURCE_REPOSITORY
- ));
-
- // Environment for compiling expressions
- EnvironmentSpecification environmentSpecification = new EnvironmentSpecification();
- environmentSpecification.importModule("Builtin", "");
- environmentSpecification.importModule("Prelude", "");
-
- try {
- runtimeEnvironment = moduleRepository.createRuntimeEnvironment(environmentSpecification,
- getClass().getClassLoader());
- } catch(ImportFailureException e) {
- for(ImportFailure failure : e.failures)
- System.err.println("Failed to import " + failure.moduleName);
- throw e;
- }
- }
-
- private void testExpression0(String expressionText,
- Object expectedValue,
- Type expectedType) throws Exception {
- // Compiling and running expression
- try {
- Object result = new ExpressionEvaluator(runtimeEnvironment, expressionText)
- .expectedType(expectedType)
- .eval();
- if(expectedValue != null)
- Assert.assertEquals(expectedValue, result);
- } catch(SCLExpressionCompilationException e) {
- System.out.println(CompilationErrorFormatter.toString(expressionText, e.getErrors()));
- throw e;
- }
- }
-
- private void testExpression(String expressionText,
- Object expectedValue,
- Type expectedType) throws Exception {
- if(TIMING) {
- System.out.println(expressionText);
- long beginTime = System.nanoTime();
- for(int i=0;i<COUNT;++i)
- testExpression0(expressionText, expectedValue, expectedType);
- long endTime = System.nanoTime();
- System.out.println( " " + (endTime-beginTime)*1e-6/COUNT + " ms");
- }
- else
- testExpression0(expressionText, expectedValue, expectedType);
- }
-
- @Test
- public void testExpressionCompiler() throws Exception {
- testExpression("1",
- Integer.valueOf(1),
- Types.INTEGER);
- testExpression("1+2",
- Integer.valueOf(3),
- Types.INTEGER);
- testExpression("map (\\(_,x) -> x) [(1,2),(2,3)]",
- Arrays.asList(2.0, 3.0),
- Types.list(Types.DOUBLE));
- testExpression("map (\\x -> snd x) [(1,2),(2,3)]",
- Arrays.asList(2.0, 3.0),
- Types.list(Types.DOUBLE));
- testExpression("let f x = x+1 in (f . f . f) 3",
- Double.valueOf(6.0),
- Types.DOUBLE);
- if(!TIMING)
- testExpression("print \"Hello world!\"",
- Tuple0.INSTANCE,
- Types.UNIT);
- testExpression("[1,2+3,4+5]",
- Arrays.asList(1,5,9),
- Types.list(Types.INTEGER));
- testExpression("let a = 5.3 in let f x = x+a in f 3",
- Double.valueOf(8.3),
- Types.DOUBLE);
- testExpression("let mm x y = if x < y then x else y in mm 2 (mm 1 3)",
- Double.valueOf(1.0),
- Types.DOUBLE);
- }
-
- @Test
- public void testLocalEnvironment() throws Exception {
- String expressionText = "a + b";
- LocalEnvironment localEnvironment = new AbstractLocalEnvironment() {
- Variable[] localParameters = new Variable[] {
- new Variable("a", Types.DOUBLE),
- new Variable("b", Types.DOUBLE),
- };
-
- @Override
- public Expression resolve(Environment environment, String localName) {
- if(localName.equals("a"))
- return new EVariable(localParameters[0]);
- else if(localName.equals("b"))
- return new EVariable(localParameters[1]);
- else
- return null;
- }
-
- @Override
- protected Variable[] getContextVariables() {
- return localParameters;
- }
- };
- try {
- Object result = new ExpressionEvaluator(runtimeEnvironment, expressionText)
- .localEnvironment(localEnvironment)
- .expectedType(Types.DOUBLE)
- .eval();
- Assert.assertEquals(
- Double.valueOf(15.0),
- ((Function)result).apply(7.0, 8.0));
- } catch(SCLExpressionCompilationException e) {
- System.out.println(CompilationErrorFormatter.toString(expressionText, e.getErrors()));
- throw e;
- }
- }
-
- @Test
- public void testArities() throws Exception {
- for(int arity=1;arity<50;++arity) {
- // Build expressions
- StringBuilder b = new StringBuilder();
- b.append('\\');
- for(int i=0;i<arity;++i)
- b.append("v" + i + " ");
- b.append("-> ");
- for(int i=0;i<arity;++i) {
- if(i > 0)
- b.append(" + ");
- b.append("v" + i);
- }
- //System.out.println(b.toString());
-
- // Compile
- Type expectedType = Types.INTEGER;
- for(int i=0;i<arity;++i)
- expectedType = Types.function(Types.INTEGER, expectedType);
-
- Function function = (Function)new ExpressionEvaluator(runtimeEnvironment, b.toString())
- .expectedType(expectedType)
- .interpretIfPossible(false)
- .eval();
-
- // Evaluate
- Object[] parameters = new Object[arity];
- int sum = 0;
- for(int i=0;i<arity;++i) {
- int value = i+1;
- parameters[i] = value;
- sum += value;
- }
- Object result = function.applyArray(parameters);
- Assert.assertEquals(sum, result);
- }
- }
-}
+++ /dev/null
-package org.simantics.scl.compiler.tests;
-
-import org.cojen.classfile.TypeDesc;
-
-public class TestTypeDesc {
- public static void main(String[] args) {
- System.out.println(TypeDesc.forClass(String.class).getFullName());
- System.out.println(TypeDesc.forClass(String.class).getDescriptor());
- System.out.println(TypeDesc.forClass(String.class).getRootName());
-
- }
-}
+++ /dev/null
-package org.simantics.scl.compiler.tests;
-
-import org.junit.Test;
-
-public class UnimplementedTests extends TestBase {
-
- public UnimplementedTests() { super("scl"); }
-
- @Test public void BigInstances() { test(); }
- @Test public void BlankExpression() { test(); }
- @Test public void ClashingValueDefinition() { test(); }
- @Test public void FunctionalDependencies1() { test(); }
- @Test public void FunctionalDependencies2() { test(); }
- @Test public void InlineLoop() { test(); }
- @Test public void InstanceTypeVariables() { test(); }
- @Test public void LP() { test(); }
- @Test public void Macros3() { test(); }
- @Test public void MissingTypeParameter() { test(); }
- @Test(timeout=100L) public void RecursiveValues() { test(); }
-
- @Test public void Set1() { test(); }
- @Test public void Signals() { test(); }
- @Test public void SpecConstr1() { test(); }
- @Test public void StackTrace() { test(); }
- @Test public void StringInterpolation2() { test(); }
- @Test public void Timing() { test(); }
-
-}
-
+++ /dev/null
-package org.simantics.scl.compiler.tests.experimentation;\r
-\r
-import java.io.PrintWriter;\r
-import java.lang.reflect.Method;\r
-import java.util.concurrent.atomic.AtomicReference;\r
-\r
-import org.objectweb.asm.ClassVisitor;\r
-import org.objectweb.asm.ClassWriter;\r
-import org.objectweb.asm.MethodVisitor;\r
-import org.objectweb.asm.Opcodes;\r
-import org.objectweb.asm.util.TraceClassVisitor;\r
-\r
-public class RecursiveInitialization {\r
-\r
- public static void main(String[] args) throws Exception {\r
- ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS);\r
- ClassVisitor classVisitor = new TraceClassVisitor(classWriter, new PrintWriter(System.out));\r
- classVisitor.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, "test/Test", null, "java/lang/Object", new String[0]);\r
- MethodVisitor methodWriter = classVisitor.visitMethod(\r
- Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC,\r
- "main", "()Ljava/lang/Object;", null, null);\r
- \r
- methodWriter.visitCode(); \r
- methodWriter.visitTypeInsn(Opcodes.NEW, "java/util/concurrent/atomic/AtomicReference");\r
- methodWriter.visitVarInsn(Opcodes.ASTORE, 2);\r
-\r
- methodWriter.visitTypeInsn(Opcodes.NEW, "java/util/concurrent/atomic/AtomicReference");\r
- methodWriter.visitVarInsn(Opcodes.ASTORE, 1);\r
- \r
- methodWriter.visitVarInsn(Opcodes.ALOAD, 2);\r
- methodWriter.visitVarInsn(Opcodes.ALOAD, 1);\r
- //methodWriter.visitInsn(Opcodes.ACONST_NULL);\r
- methodWriter.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/util/concurrent/atomic/AtomicReference", "<init>", "(Ljava/lang/Object;)V", false);\r
- \r
- methodWriter.visitVarInsn(Opcodes.ALOAD, 1);\r
- methodWriter.visitVarInsn(Opcodes.ALOAD, 2);\r
- methodWriter.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/util/concurrent/atomic/AtomicReference", "<init>", "(Ljava/lang/Object;)V", false);\r
-\r
- methodWriter.visitVarInsn(Opcodes.ALOAD, 2);\r
- methodWriter.visitInsn(Opcodes.ARETURN);\r
- methodWriter.visitMaxs(0, 0);\r
- methodWriter.visitEnd();\r
- \r
- byte[] bytes = classWriter.toByteArray();\r
- ClassLoader classLoader = new ClassLoader() {\r
- @Override\r
- protected Class<?> findClass(String name) throws ClassNotFoundException {\r
- if(!name.equals("test.Test"))\r
- throw new ClassNotFoundException();\r
- return defineClass("test.Test", bytes, 0, bytes.length);\r
- }\r
- };\r
- Class<?> clazz = classLoader.loadClass("test.Test");\r
- Method method = clazz.getMethod("main");\r
- AtomicReference<Object> result = (AtomicReference<Object>)method.invoke(null);\r
- System.out.println(result.hashCode());\r
- //System.out.println(result.get().hashCode());\r
- }\r
- \r
-}\r
+++ /dev/null
-package org.simantics.scl.compiler.tests.experimentation;\r
-\r
-public class TestEquals {\r
- public static boolean eqInt(int a, int b) {\r
- return a==b;\r
- }\r
- \r
- public static boolean eqDouble(double a, double b) {\r
- return a==b;\r
- }\r
- \r
- public static boolean eqObject(Object a, Object b) {\r
- return a.equals(b);\r
- }\r
-}\r
+++ /dev/null
-package org.simantics.scl.compiler.tests.experimentation;
-
-import org.cojen.classfile.TypeDesc;
-
-public class TestTypeDesc {
- public static void main(String[] args) {
- System.out.println(TypeDesc.forClass(String.class).getFullName());
- System.out.println(TypeDesc.forClass(String.class).getDescriptor());
- System.out.println(TypeDesc.forClass(String.class).getRootName());
-
- }
-}
+++ /dev/null
-package org.simantics.scl.compiler.tests.imports;\r
-\r
-import java.util.Random;\r
-\r
-public class Maybe4Imports {\r
-\r
- public static Object toMaybeDouble(Random r, String s) {\r
- try {\r
- return new Double(s);\r
- } catch(Exception e) {\r
- return null;\r
- }\r
- }\r
- \r
-}\r
+++ /dev/null
----
-title: CommonMark Spec
-author: John MacFarlane
-version: 0.25
-date: '2016-03-24'
-license: '[CC-BY-SA 4.0](http://creativecommons.org/licenses/by-sa/4.0/)'
-...
-
-# Introduction
-
-## What is Markdown?
-
-Markdown is a plain text format for writing structured documents,
-based on conventions used for indicating formatting in email and
-usenet posts. It was developed in 2004 by John Gruber, who wrote
-the first Markdown-to-HTML converter in perl, and it soon became
-widely used in websites. By 2014 there were dozens of
-implementations in many languages. Some of them extended basic
-Markdown syntax with conventions for footnotes, definition lists,
-tables, and other constructs, and some allowed output not just in
-HTML but in LaTeX and many other formats.
-
-## Why is a spec needed?
-
-John Gruber's [canonical description of Markdown's
-syntax](http://daringfireball.net/projects/markdown/syntax)
-does not specify the syntax unambiguously. Here are some examples of
-questions it does not answer:
-
-1. How much indentation is needed for a sublist? The spec says that
- continuation paragraphs need to be indented four spaces, but is
- not fully explicit about sublists. It is natural to think that
- they, too, must be indented four spaces, but `Markdown.pl` does
- not require that. This is hardly a "corner case," and divergences
- between implementations on this issue often lead to surprises for
- users in real documents. (See [this comment by John
- Gruber](http://article.gmane.org/gmane.text.markdown.general/1997).)
-
-2. Is a blank line needed before a block quote or heading?
- Most implementations do not require the blank line. However,
- this can lead to unexpected results in hard-wrapped text, and
- also to ambiguities in parsing (note that some implementations
- put the heading inside the blockquote, while others do not).
- (John Gruber has also spoken [in favor of requiring the blank
- lines](http://article.gmane.org/gmane.text.markdown.general/2146).)
-
-3. Is a blank line needed before an indented code block?
- (`Markdown.pl` requires it, but this is not mentioned in the
- documentation, and some implementations do not require it.)
-
- ``` markdown
- paragraph
- code?
- ```
-
-4. What is the exact rule for determining when list items get
- wrapped in `<p>` tags? Can a list be partially "loose" and partially
- "tight"? What should we do with a list like this?
-
- ``` markdown
- 1. one
-
- 2. two
- 3. three
- ```
-
- Or this?
-
- ``` markdown
- 1. one
- - a
-
- - b
- 2. two
- ```
-
- (There are some relevant comments by John Gruber
- [here](http://article.gmane.org/gmane.text.markdown.general/2554).)
-
-5. Can list markers be indented? Can ordered list markers be right-aligned?
-
- ``` markdown
- 8. item 1
- 9. item 2
- 10. item 2a
- ```
-
-6. Is this one list with a thematic break in its second item,
- or two lists separated by a thematic break?
-
- ``` markdown
- * a
- * * * * *
- * b
- ```
-
-7. When list markers change from numbers to bullets, do we have
- two lists or one? (The Markdown syntax description suggests two,
- but the perl scripts and many other implementations produce one.)
-
- ``` markdown
- 1. fee
- 2. fie
- - foe
- - fum
- ```
-
-8. What are the precedence rules for the markers of inline structure?
- For example, is the following a valid link, or does the code span
- take precedence ?
-
- ``` markdown
- [a backtick (`)](/url) and [another backtick (`)](/url).
- ```
-
-9. What are the precedence rules for markers of emphasis and strong
- emphasis? For example, how should the following be parsed?
-
- ``` markdown
- *foo *bar* baz*
- ```
-
-10. What are the precedence rules between block-level and inline-level
- structure? For example, how should the following be parsed?
-
- ``` markdown
- - `a long code span can contain a hyphen like this
- - and it can screw things up`
- ```
-
-11. Can list items include section headings? (`Markdown.pl` does not
- allow this, but does allow blockquotes to include headings.)
-
- ``` markdown
- - # Heading
- ```
-
-12. Can list items be empty?
-
- ``` markdown
- * a
- *
- * b
- ```
-
-13. Can link references be defined inside block quotes or list items?
-
- ``` markdown
- > Blockquote [foo].
- >
- > [foo]: /url
- ```
-
-14. If there are multiple definitions for the same reference, which takes
- precedence?
-
- ``` markdown
- [foo]: /url1
- [foo]: /url2
-
- [foo][]
- ```
-
-In the absence of a spec, early implementers consulted `Markdown.pl`
-to resolve these ambiguities. But `Markdown.pl` was quite buggy, and
-gave manifestly bad results in many cases, so it was not a
-satisfactory replacement for a spec.
-
-Because there is no unambiguous spec, implementations have diverged
-considerably. As a result, users are often surprised to find that
-a document that renders one way on one system (say, a github wiki)
-renders differently on another (say, converting to docbook using
-pandoc). To make matters worse, because nothing in Markdown counts
-as a "syntax error," the divergence often isn't discovered right away.
-
-## About this document
-
-This document attempts to specify Markdown syntax unambiguously.
-It contains many examples with side-by-side Markdown and
-HTML. These are intended to double as conformance tests. An
-accompanying script `spec_tests.py` can be used to run the tests
-against any Markdown program:
-
- python test/spec_tests.py --spec spec.txt --program PROGRAM
-
-Since this document describes how Markdown is to be parsed into
-an abstract syntax tree, it would have made sense to use an abstract
-representation of the syntax tree instead of HTML. But HTML is capable
-of representing the structural distinctions we need to make, and the
-choice of HTML for the tests makes it possible to run the tests against
-an implementation without writing an abstract syntax tree renderer.
-
-This document is generated from a text file, `spec.txt`, written
-in Markdown with a small extension for the side-by-side tests.
-The script `tools/makespec.py` can be used to convert `spec.txt` into
-HTML or CommonMark (which can then be converted into other formats).
-
-In the examples, the `→` character is used to represent tabs.
-
-# Preliminaries
-
-## Characters and lines
-
-Any sequence of [characters] is a valid CommonMark
-document.
-
-A [character](@) is a Unicode code point. Although some
-code points (for example, combining accents) do not correspond to
-characters in an intuitive sense, all code points count as characters
-for purposes of this spec.
-
-This spec does not specify an encoding; it thinks of lines as composed
-of [characters] rather than bytes. A conforming parser may be limited
-to a certain encoding.
-
-A [line](@) is a sequence of zero or more [characters]
-other than newline (`U+000A`) or carriage return (`U+000D`),
-followed by a [line ending] or by the end of file.
-
-A [line ending](@) is a newline (`U+000A`), a carriage return
-(`U+000D`) not followed by a newline, or a carriage return and a
-following newline.
-
-A line containing no characters, or a line containing only spaces
-(`U+0020`) or tabs (`U+0009`), is called a [blank line](@).
-
-The following definitions of character classes will be used in this spec:
-
-A [whitespace character](@) is a space
-(`U+0020`), tab (`U+0009`), newline (`U+000A`), line tabulation (`U+000B`),
-form feed (`U+000C`), or carriage return (`U+000D`).
-
-[Whitespace](@) is a sequence of one or more [whitespace
-characters].
-
-A [Unicode whitespace character](@) is
-any code point in the Unicode `Zs` class, or a tab (`U+0009`),
-carriage return (`U+000D`), newline (`U+000A`), or form feed
-(`U+000C`).
-
-[Unicode whitespace](@) is a sequence of one
-or more [Unicode whitespace characters].
-
-A [space](@) is `U+0020`.
-
-A [non-whitespace character](@) is any character
-that is not a [whitespace character].
-
-An [ASCII punctuation character](@)
-is `!`, `"`, `#`, `$`, `%`, `&`, `'`, `(`, `)`,
-`*`, `+`, `,`, `-`, `.`, `/`, `:`, `;`, `<`, `=`, `>`, `?`, `@`,
-`[`, `\`, `]`, `^`, `_`, `` ` ``, `{`, `|`, `}`, or `~`.
-
-A [punctuation character](@) is an [ASCII
-punctuation character] or anything in
-the Unicode classes `Pc`, `Pd`, `Pe`, `Pf`, `Pi`, `Po`, or `Ps`.
-
-## Tabs
-
-Tabs in lines are not expanded to [spaces]. However,
-in contexts where indentation is significant for the
-document's structure, tabs behave as if they were replaced
-by spaces with a tab stop of 4 characters.
-
-```````````````````````````````` example
-→foo→baz→→bim
-.
-<pre><code>foo→baz→→bim
-</code></pre>
-````````````````````````````````
-
-
-```````````````````````````````` example
- →foo→baz→→bim
-.
-<pre><code>foo→baz→→bim
-</code></pre>
-````````````````````````````````
-
-
-```````````````````````````````` example
- a→a
- ὐ→a
-.
-<pre><code>a→a
-ὐ→a
-</code></pre>
-````````````````````````````````
-
-
-```````````````````````````````` example
- - foo
-
-→bar
-.
-<ul>
-<li>
-<p>foo</p>
-<p>bar</p>
-</li>
-</ul>
-````````````````````````````````
-
-```````````````````````````````` example
-- foo
-
-→→bar
-.
-<ul>
-<li>
-<p>foo</p>
-<pre><code> bar
-</code></pre>
-</li>
-</ul>
-````````````````````````````````
-
-```````````````````````````````` example
->→→foo
-.
-<blockquote>
-<pre><code> foo
-</code></pre>
-</blockquote>
-````````````````````````````````
-
-```````````````````````````````` example
--→→foo
-.
-<ul>
-<li>
-<pre><code> foo
-</code></pre>
-</li>
-</ul>
-````````````````````````````````
-
-
-```````````````````````````````` example
- foo
-→bar
-.
-<pre><code>foo
-bar
-</code></pre>
-````````````````````````````````
-
-```````````````````````````````` example
- - foo
- - bar
-→ - baz
-.
-<ul>
-<li>foo
-<ul>
-<li>bar
-<ul>
-<li>baz</li>
-</ul>
-</li>
-</ul>
-</li>
-</ul>
-````````````````````````````````
-
-
-
-## Insecure characters
-
-For security reasons, the Unicode character `U+0000` must be replaced
-with the REPLACEMENT CHARACTER (`U+FFFD`).
-
-# Blocks and inlines
-
-We can think of a document as a sequence of
-[blocks](@)---structural elements like paragraphs, block
-quotations, lists, headings, rules, and code blocks. Some blocks (like
-block quotes and list items) contain other blocks; others (like
-headings and paragraphs) contain [inline](@) content---text,
-links, emphasized text, images, code, and so on.
-
-## Precedence
-
-Indicators of block structure always take precedence over indicators
-of inline structure. So, for example, the following is a list with
-two items, not a list with one item containing a code span:
-
-```````````````````````````````` example
-- `one
-- two`
-.
-<ul>
-<li>`one</li>
-<li>two`</li>
-</ul>
-````````````````````````````````
-
-
-This means that parsing can proceed in two steps: first, the block
-structure of the document can be discerned; second, text lines inside
-paragraphs, headings, and other block constructs can be parsed for inline
-structure. The second step requires information about link reference
-definitions that will be available only at the end of the first
-step. Note that the first step requires processing lines in sequence,
-but the second can be parallelized, since the inline parsing of
-one block element does not affect the inline parsing of any other.
-
-## Container blocks and leaf blocks
-
-We can divide blocks into two types:
-[container block](@)s,
-which can contain other blocks, and [leaf block](@)s,
-which cannot.
-
-# Leaf blocks
-
-This section describes the different kinds of leaf block that make up a
-Markdown document.
-
-## Thematic breaks
-
-A line consisting of 0-3 spaces of indentation, followed by a sequence
-of three or more matching `-`, `_`, or `*` characters, each followed
-optionally by any number of spaces, forms a
-[thematic break](@).
-
-```````````````````````````````` example
-***
----
-___
-.
-<hr />
-<hr />
-<hr />
-````````````````````````````````
-
-
-Wrong characters:
-
-```````````````````````````````` example
-+++
-.
-<p>+++</p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-===
-.
-<p>===</p>
-````````````````````````````````
-
-
-Not enough characters:
-
-```````````````````````````````` example
---
-**
-__
-.
-<p>--
-**
-__</p>
-````````````````````````````````
-
-
-One to three spaces indent are allowed:
-
-```````````````````````````````` example
- ***
- ***
- ***
-.
-<hr />
-<hr />
-<hr />
-````````````````````````````````
-
-
-Four spaces is too many:
-
-```````````````````````````````` example
- ***
-.
-<pre><code>***
-</code></pre>
-````````````````````````````````
-
-
-```````````````````````````````` example
-Foo
- ***
-.
-<p>Foo
-***</p>
-````````````````````````````````
-
-
-More than three characters may be used:
-
-```````````````````````````````` example
-_____________________________________
-.
-<hr />
-````````````````````````````````
-
-
-Spaces are allowed between the characters:
-
-```````````````````````````````` example
- - - -
-.
-<hr />
-````````````````````````````````
-
-
-```````````````````````````````` example
- ** * ** * ** * **
-.
-<hr />
-````````````````````````````````
-
-
-```````````````````````````````` example
-- - - -
-.
-<hr />
-````````````````````````````````
-
-
-Spaces are allowed at the end:
-
-```````````````````````````````` example
-- - - -
-.
-<hr />
-````````````````````````````````
-
-
-However, no other characters may occur in the line:
-
-```````````````````````````````` example
-_ _ _ _ a
-
-a------
-
----a---
-.
-<p>_ _ _ _ a</p>
-<p>a------</p>
-<p>---a---</p>
-````````````````````````````````
-
-
-It is required that all of the [non-whitespace characters] be the same.
-So, this is not a thematic break:
-
-```````````````````````````````` example
- *-*
-.
-<p><em>-</em></p>
-````````````````````````````````
-
-
-Thematic breaks do not need blank lines before or after:
-
-```````````````````````````````` example
-- foo
-***
-- bar
-.
-<ul>
-<li>foo</li>
-</ul>
-<hr />
-<ul>
-<li>bar</li>
-</ul>
-````````````````````````````````
-
-
-Thematic breaks can interrupt a paragraph:
-
-```````````````````````````````` example
-Foo
-***
-bar
-.
-<p>Foo</p>
-<hr />
-<p>bar</p>
-````````````````````````````````
-
-
-If a line of dashes that meets the above conditions for being a
-thematic break could also be interpreted as the underline of a [setext
-heading], the interpretation as a
-[setext heading] takes precedence. Thus, for example,
-this is a setext heading, not a paragraph followed by a thematic break:
-
-```````````````````````````````` example
-Foo
----
-bar
-.
-<h2>Foo</h2>
-<p>bar</p>
-````````````````````````````````
-
-
-When both a thematic break and a list item are possible
-interpretations of a line, the thematic break takes precedence:
-
-```````````````````````````````` example
-* Foo
-* * *
-* Bar
-.
-<ul>
-<li>Foo</li>
-</ul>
-<hr />
-<ul>
-<li>Bar</li>
-</ul>
-````````````````````````````````
-
-
-If you want a thematic break in a list item, use a different bullet:
-
-```````````````````````````````` example
-- Foo
-- * * *
-.
-<ul>
-<li>Foo</li>
-<li>
-<hr />
-</li>
-</ul>
-````````````````````````````````
-
-
-## ATX headings
-
-An [ATX heading](@)
-consists of a string of characters, parsed as inline content, between an
-opening sequence of 1--6 unescaped `#` characters and an optional
-closing sequence of any number of unescaped `#` characters.
-The opening sequence of `#` characters must be followed by a
-[space] or by the end of line. The optional closing sequence of `#`s must be
-preceded by a [space] and may be followed by spaces only. The opening
-`#` character may be indented 0-3 spaces. The raw contents of the
-heading are stripped of leading and trailing spaces before being parsed
-as inline content. The heading level is equal to the number of `#`
-characters in the opening sequence.
-
-Simple headings:
-
-```````````````````````````````` example
-# foo
-## foo
-### foo
-#### foo
-##### foo
-###### foo
-.
-<h1>foo</h1>
-<h2>foo</h2>
-<h3>foo</h3>
-<h4>foo</h4>
-<h5>foo</h5>
-<h6>foo</h6>
-````````````````````````````````
-
-
-More than six `#` characters is not a heading:
-
-```````````````````````````````` example
-####### foo
-.
-<p>####### foo</p>
-````````````````````````````````
-
-
-At least one space is required between the `#` characters and the
-heading's contents, unless the heading is empty. Note that many
-implementations currently do not require the space. However, the
-space was required by the
-[original ATX implementation](http://www.aaronsw.com/2002/atx/atx.py),
-and it helps prevent things like the following from being parsed as
-headings:
-
-```````````````````````````````` example
-#5 bolt
-
-#hashtag
-.
-<p>#5 bolt</p>
-<p>#hashtag</p>
-````````````````````````````````
-
-
-A tab will not work:
-
-```````````````````````````````` example
-#→foo
-.
-<p>#→foo</p>
-````````````````````````````````
-
-
-This is not a heading, because the first `#` is escaped:
-
-```````````````````````````````` example
-\## foo
-.
-<p>## foo</p>
-````````````````````````````````
-
-
-Contents are parsed as inlines:
-
-```````````````````````````````` example
-# foo *bar* \*baz\*
-.
-<h1>foo <em>bar</em> *baz*</h1>
-````````````````````````````````
-
-
-Leading and trailing blanks are ignored in parsing inline content:
-
-```````````````````````````````` example
-# foo
-.
-<h1>foo</h1>
-````````````````````````````````
-
-
-One to three spaces indentation are allowed:
-
-```````````````````````````````` example
- ### foo
- ## foo
- # foo
-.
-<h3>foo</h3>
-<h2>foo</h2>
-<h1>foo</h1>
-````````````````````````````````
-
-
-Four spaces are too much:
-
-```````````````````````````````` example
- # foo
-.
-<pre><code># foo
-</code></pre>
-````````````````````````````````
-
-
-```````````````````````````````` example
-foo
- # bar
-.
-<p>foo
-# bar</p>
-````````````````````````````````
-
-
-A closing sequence of `#` characters is optional:
-
-```````````````````````````````` example
-## foo ##
- ### bar ###
-.
-<h2>foo</h2>
-<h3>bar</h3>
-````````````````````````````````
-
-
-It need not be the same length as the opening sequence:
-
-```````````````````````````````` example
-# foo ##################################
-##### foo ##
-.
-<h1>foo</h1>
-<h5>foo</h5>
-````````````````````````````````
-
-
-Spaces are allowed after the closing sequence:
-
-```````````````````````````````` example
-### foo ###
-.
-<h3>foo</h3>
-````````````````````````````````
-
-
-A sequence of `#` characters with anything but [spaces] following it
-is not a closing sequence, but counts as part of the contents of the
-heading:
-
-```````````````````````````````` example
-### foo ### b
-.
-<h3>foo ### b</h3>
-````````````````````````````````
-
-
-The closing sequence must be preceded by a space:
-
-```````````````````````````````` example
-# foo#
-.
-<h1>foo#</h1>
-````````````````````````````````
-
-
-Backslash-escaped `#` characters do not count as part
-of the closing sequence:
-
-```````````````````````````````` example
-### foo \###
-## foo #\##
-# foo \#
-.
-<h3>foo ###</h3>
-<h2>foo ###</h2>
-<h1>foo #</h1>
-````````````````````````````````
-
-
-ATX headings need not be separated from surrounding content by blank
-lines, and they can interrupt paragraphs:
-
-```````````````````````````````` example
-****
-## foo
-****
-.
-<hr />
-<h2>foo</h2>
-<hr />
-````````````````````````````````
-
-
-```````````````````````````````` example
-Foo bar
-# baz
-Bar foo
-.
-<p>Foo bar</p>
-<h1>baz</h1>
-<p>Bar foo</p>
-````````````````````````````````
-
-
-ATX headings can be empty:
-
-```````````````````````````````` example
-##
-#
-### ###
-.
-<h2></h2>
-<h1></h1>
-<h3></h3>
-````````````````````````````````
-
-
-## Setext headings
-
-A [setext heading](@) consists of one or more
-lines of text, each containing at least one [non-whitespace
-character], with no more than 3 spaces indentation, followed by
-a [setext heading underline]. The lines of text must be such
-that, were they not followed by the setext heading underline,
-they would be interpreted as a paragraph: they cannot be
-interpretable as a [code fence], [ATX heading][ATX headings],
-[block quote][block quotes], [thematic break][thematic breaks],
-[list item][list items], or [HTML block][HTML blocks].
-
-A [setext heading underline](@) is a sequence of
-`=` characters or a sequence of `-` characters, with no more than 3
-spaces indentation and any number of trailing spaces. If a line
-containing a single `-` can be interpreted as an
-empty [list items], it should be interpreted this way
-and not as a [setext heading underline].
-
-The heading is a level 1 heading if `=` characters are used in
-the [setext heading underline], and a level 2 heading if `-`
-characters are used. The contents of the heading are the result
-of parsing the preceding lines of text as CommonMark inline
-content.
-
-In general, a setext heading need not be preceded or followed by a
-blank line. However, it cannot interrupt a paragraph, so when a
-setext heading comes after a paragraph, a blank line is needed between
-them.
-
-Simple examples:
-
-```````````````````````````````` example
-Foo *bar*
-=========
-
-Foo *bar*
----------
-.
-<h1>Foo <em>bar</em></h1>
-<h2>Foo <em>bar</em></h2>
-````````````````````````````````
-
-
-The content of the header may span more than one line:
-
-```````````````````````````````` example
-Foo *bar
-baz*
-====
-.
-<h1>Foo <em>bar
-baz</em></h1>
-````````````````````````````````
-
-
-The underlining can be any length:
-
-```````````````````````````````` example
-Foo
--------------------------
-
-Foo
-=
-.
-<h2>Foo</h2>
-<h1>Foo</h1>
-````````````````````````````````
-
-
-The heading content can be indented up to three spaces, and need
-not line up with the underlining:
-
-```````````````````````````````` example
- Foo
----
-
- Foo
------
-
- Foo
- ===
-.
-<h2>Foo</h2>
-<h2>Foo</h2>
-<h1>Foo</h1>
-````````````````````````````````
-
-
-Four spaces indent is too much:
-
-```````````````````````````````` example
- Foo
- ---
-
- Foo
----
-.
-<pre><code>Foo
----
-
-Foo
-</code></pre>
-<hr />
-````````````````````````````````
-
-
-The setext heading underline can be indented up to three spaces, and
-may have trailing spaces:
-
-```````````````````````````````` example
-Foo
- ----
-.
-<h2>Foo</h2>
-````````````````````````````````
-
-
-Four spaces is too much:
-
-```````````````````````````````` example
-Foo
- ---
-.
-<p>Foo
----</p>
-````````````````````````````````
-
-
-The setext heading underline cannot contain internal spaces:
-
-```````````````````````````````` example
-Foo
-= =
-
-Foo
---- -
-.
-<p>Foo
-= =</p>
-<p>Foo</p>
-<hr />
-````````````````````````````````
-
-
-Trailing spaces in the content line do not cause a line break:
-
-```````````````````````````````` example
-Foo
------
-.
-<h2>Foo</h2>
-````````````````````````````````
-
-
-Nor does a backslash at the end:
-
-```````````````````````````````` example
-Foo\
-----
-.
-<h2>Foo\</h2>
-````````````````````````````````
-
-
-Since indicators of block structure take precedence over
-indicators of inline structure, the following are setext headings:
-
-```````````````````````````````` example
-`Foo
-----
-`
-
-<a title="a lot
----
-of dashes"/>
-.
-<h2>`Foo</h2>
-<p>`</p>
-<h2><a title="a lot</h2>
-<p>of dashes"/></p>
-````````````````````````````````
-
-
-The setext heading underline cannot be a [lazy continuation
-line] in a list item or block quote:
-
-```````````````````````````````` example
-> Foo
----
-.
-<blockquote>
-<p>Foo</p>
-</blockquote>
-<hr />
-````````````````````````````````
-
-
-```````````````````````````````` example
-> foo
-bar
-===
-.
-<blockquote>
-<p>foo
-bar
-===</p>
-</blockquote>
-````````````````````````````````
-
-
-```````````````````````````````` example
-- Foo
----
-.
-<ul>
-<li>Foo</li>
-</ul>
-<hr />
-````````````````````````````````
-
-
-A blank line is needed between a paragraph and a following
-setext heading, since otherwise the paragraph becomes part
-of the heading's content:
-
-```````````````````````````````` example
-Foo
-Bar
----
-.
-<h2>Foo
-Bar</h2>
-````````````````````````````````
-
-
-But in general a blank line is not required before or after
-setext headings:
-
-```````````````````````````````` example
----
-Foo
----
-Bar
----
-Baz
-.
-<hr />
-<h2>Foo</h2>
-<h2>Bar</h2>
-<p>Baz</p>
-````````````````````````````````
-
-
-Setext headings cannot be empty:
-
-```````````````````````````````` example
-
-====
-.
-<p>====</p>
-````````````````````````````````
-
-
-Setext heading text lines must not be interpretable as block
-constructs other than paragraphs. So, the line of dashes
-in these examples gets interpreted as a thematic break:
-
-```````````````````````````````` example
----
----
-.
-<hr />
-<hr />
-````````````````````````````````
-
-
-```````````````````````````````` example
-- foo
------
-.
-<ul>
-<li>foo</li>
-</ul>
-<hr />
-````````````````````````````````
-
-
-```````````````````````````````` example
- foo
----
-.
-<pre><code>foo
-</code></pre>
-<hr />
-````````````````````````````````
-
-
-```````````````````````````````` example
-> foo
------
-.
-<blockquote>
-<p>foo</p>
-</blockquote>
-<hr />
-````````````````````````````````
-
-
-If you want a heading with `> foo` as its literal text, you can
-use backslash escapes:
-
-```````````````````````````````` example
-\> foo
-------
-.
-<h2>> foo</h2>
-````````````````````````````````
-
-
-**Compatibility note:** Most existing Markdown implementations
-do not allow the text of setext headings to span multiple lines.
-But there is no consensus about how to interpret
-
-``` markdown
-Foo
-bar
----
-baz
-```
-
-One can find four different interpretations:
-
-1. paragraph "Foo", heading "bar", paragraph "baz"
-2. paragraph "Foo bar", thematic break, paragraph "baz"
-3. paragraph "Foo bar --- baz"
-4. heading "Foo bar", paragraph "baz"
-
-We find interpretation 4 most natural, and interpretation 4
-increases the expressive power of CommonMark, by allowing
-multiline headings. Authors who want interpretation 1 can
-put a blank line after the first paragraph:
-
-```````````````````````````````` example
-Foo
-
-bar
----
-baz
-.
-<p>Foo</p>
-<h2>bar</h2>
-<p>baz</p>
-````````````````````````````````
-
-
-Authors who want interpretation 2 can put blank lines around
-the thematic break,
-
-```````````````````````````````` example
-Foo
-bar
-
----
-
-baz
-.
-<p>Foo
-bar</p>
-<hr />
-<p>baz</p>
-````````````````````````````````
-
-
-or use a thematic break that cannot count as a [setext heading
-underline], such as
-
-```````````````````````````````` example
-Foo
-bar
-* * *
-baz
-.
-<p>Foo
-bar</p>
-<hr />
-<p>baz</p>
-````````````````````````````````
-
-
-Authors who want interpretation 3 can use backslash escapes:
-
-```````````````````````````````` example
-Foo
-bar
-\---
-baz
-.
-<p>Foo
-bar
----
-baz</p>
-````````````````````````````````
-
-
-## Indented code blocks
-
-An [indented code block](@) is composed of one or more
-[indented chunks] separated by blank lines.
-An [indented chunk](@) is a sequence of non-blank lines,
-each indented four or more spaces. The contents of the code block are
-the literal contents of the lines, including trailing
-[line endings], minus four spaces of indentation.
-An indented code block has no [info string].
-
-An indented code block cannot interrupt a paragraph, so there must be
-a blank line between a paragraph and a following indented code block.
-(A blank line is not needed, however, between a code block and a following
-paragraph.)
-
-```````````````````````````````` example
- a simple
- indented code block
-.
-<pre><code>a simple
- indented code block
-</code></pre>
-````````````````````````````````
-
-
-If there is any ambiguity between an interpretation of indentation
-as a code block and as indicating that material belongs to a [list
-item][list items], the list item interpretation takes precedence:
-
-```````````````````````````````` example
- - foo
-
- bar
-.
-<ul>
-<li>
-<p>foo</p>
-<p>bar</p>
-</li>
-</ul>
-````````````````````````````````
-
-
-```````````````````````````````` example
-1. foo
-
- - bar
-.
-<ol>
-<li>
-<p>foo</p>
-<ul>
-<li>bar</li>
-</ul>
-</li>
-</ol>
-````````````````````````````````
-
-
-
-The contents of a code block are literal text, and do not get parsed
-as Markdown:
-
-```````````````````````````````` example
- <a/>
- *hi*
-
- - one
-.
-<pre><code><a/>
-*hi*
-
-- one
-</code></pre>
-````````````````````````````````
-
-
-Here we have three chunks separated by blank lines:
-
-```````````````````````````````` example
- chunk1
-
- chunk2
-
-
-
- chunk3
-.
-<pre><code>chunk1
-
-chunk2
-
-
-
-chunk3
-</code></pre>
-````````````````````````````````
-
-
-Any initial spaces beyond four will be included in the content, even
-in interior blank lines:
-
-```````````````````````````````` example
- chunk1
-
- chunk2
-.
-<pre><code>chunk1
-
- chunk2
-</code></pre>
-````````````````````````````````
-
-
-An indented code block cannot interrupt a paragraph. (This
-allows hanging indents and the like.)
-
-```````````````````````````````` example
-Foo
- bar
-
-.
-<p>Foo
-bar</p>
-````````````````````````````````
-
-
-However, any non-blank line with fewer than four leading spaces ends
-the code block immediately. So a paragraph may occur immediately
-after indented code:
-
-```````````````````````````````` example
- foo
-bar
-.
-<pre><code>foo
-</code></pre>
-<p>bar</p>
-````````````````````````````````
-
-
-And indented code can occur immediately before and after other kinds of
-blocks:
-
-```````````````````````````````` example
-# Heading
- foo
-Heading
-------
- foo
-----
-.
-<h1>Heading</h1>
-<pre><code>foo
-</code></pre>
-<h2>Heading</h2>
-<pre><code>foo
-</code></pre>
-<hr />
-````````````````````````````````
-
-
-The first line can be indented more than four spaces:
-
-```````````````````````````````` example
- foo
- bar
-.
-<pre><code> foo
-bar
-</code></pre>
-````````````````````````````````
-
-
-Blank lines preceding or following an indented code block
-are not included in it:
-
-```````````````````````````````` example
-
-
- foo
-
-
-.
-<pre><code>foo
-</code></pre>
-````````````````````````````````
-
-
-Trailing spaces are included in the code block's content:
-
-```````````````````````````````` example
- foo
-.
-<pre><code>foo
-</code></pre>
-````````````````````````````````
-
-
-
-## Fenced code blocks
-
-A [code fence](@) is a sequence
-of at least three consecutive backtick characters (`` ` ``) or
-tildes (`~`). (Tildes and backticks cannot be mixed.)
-A [fenced code block](@)
-begins with a code fence, indented no more than three spaces.
-
-The line with the opening code fence may optionally contain some text
-following the code fence; this is trimmed of leading and trailing
-spaces and called the [info string](@).
-The [info string] may not contain any backtick
-characters. (The reason for this restriction is that otherwise
-some inline code would be incorrectly interpreted as the
-beginning of a fenced code block.)
-
-The content of the code block consists of all subsequent lines, until
-a closing [code fence] of the same type as the code block
-began with (backticks or tildes), and with at least as many backticks
-or tildes as the opening code fence. If the leading code fence is
-indented N spaces, then up to N spaces of indentation are removed from
-each line of the content (if present). (If a content line is not
-indented, it is preserved unchanged. If it is indented less than N
-spaces, all of the indentation is removed.)
-
-The closing code fence may be indented up to three spaces, and may be
-followed only by spaces, which are ignored. If the end of the
-containing block (or document) is reached and no closing code fence
-has been found, the code block contains all of the lines after the
-opening code fence until the end of the containing block (or
-document). (An alternative spec would require backtracking in the
-event that a closing code fence is not found. But this makes parsing
-much less efficient, and there seems to be no real down side to the
-behavior described here.)
-
-A fenced code block may interrupt a paragraph, and does not require
-a blank line either before or after.
-
-The content of a code fence is treated as literal text, not parsed
-as inlines. The first word of the [info string] is typically used to
-specify the language of the code sample, and rendered in the `class`
-attribute of the `code` tag. However, this spec does not mandate any
-particular treatment of the [info string].
-
-Here is a simple example with backticks:
-
-```````````````````````````````` example
-```
-<
- >
-```
-.
-<pre><code><
- >
-</code></pre>
-````````````````````````````````
-
-
-With tildes:
-
-```````````````````````````````` example
-~~~
-<
- >
-~~~
-.
-<pre><code><
- >
-</code></pre>
-````````````````````````````````
-
-
-The closing code fence must use the same character as the opening
-fence:
-
-```````````````````````````````` example
-```
-aaa
-~~~
-```
-.
-<pre><code>aaa
-~~~
-</code></pre>
-````````````````````````````````
-
-
-```````````````````````````````` example
-~~~
-aaa
-```
-~~~
-.
-<pre><code>aaa
-```
-</code></pre>
-````````````````````````````````
-
-
-The closing code fence must be at least as long as the opening fence:
-
-```````````````````````````````` example
-````
-aaa
-```
-``````
-.
-<pre><code>aaa
-```
-</code></pre>
-````````````````````````````````
-
-
-```````````````````````````````` example
-~~~~
-aaa
-~~~
-~~~~
-.
-<pre><code>aaa
-~~~
-</code></pre>
-````````````````````````````````
-
-
-Unclosed code blocks are closed by the end of the document
-(or the enclosing [block quote][block quotes] or [list item][list items]):
-
-```````````````````````````````` example
-```
-.
-<pre><code></code></pre>
-````````````````````````````````
-
-
-```````````````````````````````` example
-`````
-
-```
-aaa
-.
-<pre><code>
-```
-aaa
-</code></pre>
-````````````````````````````````
-
-
-```````````````````````````````` example
-> ```
-> aaa
-
-bbb
-.
-<blockquote>
-<pre><code>aaa
-</code></pre>
-</blockquote>
-<p>bbb</p>
-````````````````````````````````
-
-
-A code block can have all empty lines as its content:
-
-```````````````````````````````` example
-```
-
-
-```
-.
-<pre><code>
-
-</code></pre>
-````````````````````````````````
-
-
-A code block can be empty:
-
-```````````````````````````````` example
-```
-```
-.
-<pre><code></code></pre>
-````````````````````````````````
-
-
-Fences can be indented. If the opening fence is indented,
-content lines will have equivalent opening indentation removed,
-if present:
-
-```````````````````````````````` example
- ```
- aaa
-aaa
-```
-.
-<pre><code>aaa
-aaa
-</code></pre>
-````````````````````````````````
-
-
-```````````````````````````````` example
- ```
-aaa
- aaa
-aaa
- ```
-.
-<pre><code>aaa
-aaa
-aaa
-</code></pre>
-````````````````````````````````
-
-
-```````````````````````````````` example
- ```
- aaa
- aaa
- aaa
- ```
-.
-<pre><code>aaa
- aaa
-aaa
-</code></pre>
-````````````````````````````````
-
-
-Four spaces indentation produces an indented code block:
-
-```````````````````````````````` example
- ```
- aaa
- ```
-.
-<pre><code>```
-aaa
-```
-</code></pre>
-````````````````````````````````
-
-
-Closing fences may be indented by 0-3 spaces, and their indentation
-need not match that of the opening fence:
-
-```````````````````````````````` example
-```
-aaa
- ```
-.
-<pre><code>aaa
-</code></pre>
-````````````````````````````````
-
-
-```````````````````````````````` example
- ```
-aaa
- ```
-.
-<pre><code>aaa
-</code></pre>
-````````````````````````````````
-
-
-This is not a closing fence, because it is indented 4 spaces:
-
-```````````````````````````````` example
-```
-aaa
- ```
-.
-<pre><code>aaa
- ```
-</code></pre>
-````````````````````````````````
-
-
-
-Code fences (opening and closing) cannot contain internal spaces:
-
-```````````````````````````````` example
-``` ```
-aaa
-.
-<p><code></code>
-aaa</p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-~~~~~~
-aaa
-~~~ ~~
-.
-<pre><code>aaa
-~~~ ~~
-</code></pre>
-````````````````````````````````
-
-
-Fenced code blocks can interrupt paragraphs, and can be followed
-directly by paragraphs, without a blank line between:
-
-```````````````````````````````` example
-foo
-```
-bar
-```
-baz
-.
-<p>foo</p>
-<pre><code>bar
-</code></pre>
-<p>baz</p>
-````````````````````````````````
-
-
-Other blocks can also occur before and after fenced code blocks
-without an intervening blank line:
-
-```````````````````````````````` example
-foo
----
-~~~
-bar
-~~~
-# baz
-.
-<h2>foo</h2>
-<pre><code>bar
-</code></pre>
-<h1>baz</h1>
-````````````````````````````````
-
-
-An [info string] can be provided after the opening code fence.
-Opening and closing spaces will be stripped, and the first word, prefixed
-with `language-`, is used as the value for the `class` attribute of the
-`code` element within the enclosing `pre` element.
-
-```````````````````````````````` example
-```ruby
-def foo(x)
- return 3
-end
-```
-.
-<pre><code class="language-ruby">def foo(x)
- return 3
-end
-</code></pre>
-````````````````````````````````
-
-
-```````````````````````````````` example
-~~~~ ruby startline=3 $%@#$
-def foo(x)
- return 3
-end
-~~~~~~~
-.
-<pre><code class="language-ruby">def foo(x)
- return 3
-end
-</code></pre>
-````````````````````````````````
-
-
-```````````````````````````````` example
-````;
-````
-.
-<pre><code class="language-;"></code></pre>
-````````````````````````````````
-
-
-[Info strings] for backtick code blocks cannot contain backticks:
-
-```````````````````````````````` example
-``` aa ```
-foo
-.
-<p><code>aa</code>
-foo</p>
-````````````````````````````````
-
-
-Closing code fences cannot have [info strings]:
-
-```````````````````````````````` example
-```
-``` aaa
-```
-.
-<pre><code>``` aaa
-</code></pre>
-````````````````````````````````
-
-
-
-## HTML blocks
-
-An [HTML block](@) is a group of lines that is treated
-as raw HTML (and will not be escaped in HTML output).
-
-There are seven kinds of [HTML block], which can be defined
-by their start and end conditions. The block begins with a line that
-meets a [start condition](@) (after up to three spaces
-optional indentation). It ends with the first subsequent line that
-meets a matching [end condition](@), or the last line of
-the document, if no line is encountered that meets the
-[end condition]. If the first line meets both the [start condition]
-and the [end condition], the block will contain just that line.
-
-1. **Start condition:** line begins with the string `<script`,
-`<pre`, or `<style` (case-insensitive), followed by whitespace,
-the string `>`, or the end of the line.\
-**End condition:** line contains an end tag
-`</script>`, `</pre>`, or `</style>` (case-insensitive; it
-need not match the start tag).
-
-2. **Start condition:** line begins with the string `<!--`.\
-**End condition:** line contains the string `-->`.
-
-3. **Start condition:** line begins with the string `<?`.\
-**End condition:** line contains the string `?>`.
-
-4. **Start condition:** line begins with the string `<!`
-followed by an uppercase ASCII letter.\
-**End condition:** line contains the character `>`.
-
-5. **Start condition:** line begins with the string
-`<![CDATA[`.\
-**End condition:** line contains the string `]]>`.
-
-6. **Start condition:** line begins the string `<` or `</`
-followed by one of the strings (case-insensitive) `address`,
-`article`, `aside`, `base`, `basefont`, `blockquote`, `body`,
-`caption`, `center`, `col`, `colgroup`, `dd`, `details`, `dialog`,
-`dir`, `div`, `dl`, `dt`, `fieldset`, `figcaption`, `figure`,
-`footer`, `form`, `frame`, `frameset`, `h1`, `head`, `header`, `hr`,
-`html`, `iframe`, `legend`, `li`, `link`, `main`, `menu`, `menuitem`,
-`meta`, `nav`, `noframes`, `ol`, `optgroup`, `option`, `p`, `param`,
-`section`, `source`, `summary`, `table`, `tbody`, `td`,
-`tfoot`, `th`, `thead`, `title`, `tr`, `track`, `ul`, followed
-by [whitespace], the end of the line, the string `>`, or
-the string `/>`.\
-**End condition:** line is followed by a [blank line].
-
-7. **Start condition:** line begins with a complete [open tag]
-or [closing tag] (with any [tag name] other than `script`,
-`style`, or `pre`) followed only by [whitespace]
-or the end of the line.\
-**End condition:** line is followed by a [blank line].
-
-All types of [HTML blocks] except type 7 may interrupt
-a paragraph. Blocks of type 7 may not interrupt a paragraph.
-(This restriction is intended to prevent unwanted interpretation
-of long tags inside a wrapped paragraph as starting HTML blocks.)
-
-Some simple examples follow. Here are some basic HTML blocks
-of type 6:
-
-```````````````````````````````` example
-<table>
- <tr>
- <td>
- hi
- </td>
- </tr>
-</table>
-
-okay.
-.
-<table>
- <tr>
- <td>
- hi
- </td>
- </tr>
-</table>
-<p>okay.</p>
-````````````````````````````````
-
-
-```````````````````````````````` example
- <div>
- *hello*
- <foo><a>
-.
- <div>
- *hello*
- <foo><a>
-````````````````````````````````
-
-
-A block can also start with a closing tag:
-
-```````````````````````````````` example
-</div>
-*foo*
-.
-</div>
-*foo*
-````````````````````````````````
-
-
-Here we have two HTML blocks with a Markdown paragraph between them:
-
-```````````````````````````````` example
-<DIV CLASS="foo">
-
-*Markdown*
-
-</DIV>
-.
-<DIV CLASS="foo">
-<p><em>Markdown</em></p>
-</DIV>
-````````````````````````````````
-
-
-The tag on the first line can be partial, as long
-as it is split where there would be whitespace:
-
-```````````````````````````````` example
-<div id="foo"
- class="bar">
-</div>
-.
-<div id="foo"
- class="bar">
-</div>
-````````````````````````````````
-
-
-```````````````````````````````` example
-<div id="foo" class="bar
- baz">
-</div>
-.
-<div id="foo" class="bar
- baz">
-</div>
-````````````````````````````````
-
-
-An open tag need not be closed:
-```````````````````````````````` example
-<div>
-*foo*
-
-*bar*
-.
-<div>
-*foo*
-<p><em>bar</em></p>
-````````````````````````````````
-
-
-
-A partial tag need not even be completed (garbage
-in, garbage out):
-
-```````````````````````````````` example
-<div id="foo"
-*hi*
-.
-<div id="foo"
-*hi*
-````````````````````````````````
-
-
-```````````````````````````````` example
-<div class
-foo
-.
-<div class
-foo
-````````````````````````````````
-
-
-The initial tag doesn't even need to be a valid
-tag, as long as it starts like one:
-
-```````````````````````````````` example
-<div *???-&&&-<---
-*foo*
-.
-<div *???-&&&-<---
-*foo*
-````````````````````````````````
-
-
-In type 6 blocks, the initial tag need not be on a line by
-itself:
-
-```````````````````````````````` example
-<div><a href="bar">*foo*</a></div>
-.
-<div><a href="bar">*foo*</a></div>
-````````````````````````````````
-
-
-```````````````````````````````` example
-<table><tr><td>
-foo
-</td></tr></table>
-.
-<table><tr><td>
-foo
-</td></tr></table>
-````````````````````````````````
-
-
-Everything until the next blank line or end of document
-gets included in the HTML block. So, in the following
-example, what looks like a Markdown code block
-is actually part of the HTML block, which continues until a blank
-line or the end of the document is reached:
-
-```````````````````````````````` example
-<div></div>
-``` c
-int x = 33;
-```
-.
-<div></div>
-``` c
-int x = 33;
-```
-````````````````````````````````
-
-
-To start an [HTML block] with a tag that is *not* in the
-list of block-level tags in (6), you must put the tag by
-itself on the first line (and it must be complete):
-
-```````````````````````````````` example
-<a href="foo">
-*bar*
-</a>
-.
-<a href="foo">
-*bar*
-</a>
-````````````````````````````````
-
-
-In type 7 blocks, the [tag name] can be anything:
-
-```````````````````````````````` example
-<Warning>
-*bar*
-</Warning>
-.
-<Warning>
-*bar*
-</Warning>
-````````````````````````````````
-
-
-```````````````````````````````` example
-<i class="foo">
-*bar*
-</i>
-.
-<i class="foo">
-*bar*
-</i>
-````````````````````````````````
-
-
-```````````````````````````````` example
-</ins>
-*bar*
-.
-</ins>
-*bar*
-````````````````````````````````
-
-
-These rules are designed to allow us to work with tags that
-can function as either block-level or inline-level tags.
-The `<del>` tag is a nice example. We can surround content with
-`<del>` tags in three different ways. In this case, we get a raw
-HTML block, because the `<del>` tag is on a line by itself:
-
-```````````````````````````````` example
-<del>
-*foo*
-</del>
-.
-<del>
-*foo*
-</del>
-````````````````````````````````
-
-
-In this case, we get a raw HTML block that just includes
-the `<del>` tag (because it ends with the following blank
-line). So the contents get interpreted as CommonMark:
-
-```````````````````````````````` example
-<del>
-
-*foo*
-
-</del>
-.
-<del>
-<p><em>foo</em></p>
-</del>
-````````````````````````````````
-
-
-Finally, in this case, the `<del>` tags are interpreted
-as [raw HTML] *inside* the CommonMark paragraph. (Because
-the tag is not on a line by itself, we get inline HTML
-rather than an [HTML block].)
-
-```````````````````````````````` example
-<del>*foo*</del>
-.
-<p><del><em>foo</em></del></p>
-````````````````````````````````
-
-
-HTML tags designed to contain literal content
-(`script`, `style`, `pre`), comments, processing instructions,
-and declarations are treated somewhat differently.
-Instead of ending at the first blank line, these blocks
-end at the first line containing a corresponding end tag.
-As a result, these blocks can contain blank lines:
-
-A pre tag (type 1):
-
-```````````````````````````````` example
-<pre language="haskell"><code>
-import Text.HTML.TagSoup
-
-main :: IO ()
-main = print $ parseTags tags
-</code></pre>
-.
-<pre language="haskell"><code>
-import Text.HTML.TagSoup
-
-main :: IO ()
-main = print $ parseTags tags
-</code></pre>
-````````````````````````````````
-
-
-A script tag (type 1):
-
-```````````````````````````````` example
-<script type="text/javascript">
-// JavaScript example
-
-document.getElementById("demo").innerHTML = "Hello JavaScript!";
-</script>
-.
-<script type="text/javascript">
-// JavaScript example
-
-document.getElementById("demo").innerHTML = "Hello JavaScript!";
-</script>
-````````````````````````````````
-
-
-A style tag (type 1):
-
-```````````````````````````````` example
-<style
- type="text/css">
-h1 {color:red;}
-
-p {color:blue;}
-</style>
-.
-<style
- type="text/css">
-h1 {color:red;}
-
-p {color:blue;}
-</style>
-````````````````````````````````
-
-
-If there is no matching end tag, the block will end at the
-end of the document (or the enclosing [block quote][block quotes]
-or [list item][list items]):
-
-```````````````````````````````` example
-<style
- type="text/css">
-
-foo
-.
-<style
- type="text/css">
-
-foo
-````````````````````````````````
-
-
-```````````````````````````````` example
-> <div>
-> foo
-
-bar
-.
-<blockquote>
-<div>
-foo
-</blockquote>
-<p>bar</p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-- <div>
-- foo
-.
-<ul>
-<li>
-<div>
-</li>
-<li>foo</li>
-</ul>
-````````````````````````````````
-
-
-The end tag can occur on the same line as the start tag:
-
-```````````````````````````````` example
-<style>p{color:red;}</style>
-*foo*
-.
-<style>p{color:red;}</style>
-<p><em>foo</em></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-<!-- foo -->*bar*
-*baz*
-.
-<!-- foo -->*bar*
-<p><em>baz</em></p>
-````````````````````````````````
-
-
-Note that anything on the last line after the
-end tag will be included in the [HTML block]:
-
-```````````````````````````````` example
-<script>
-foo
-</script>1. *bar*
-.
-<script>
-foo
-</script>1. *bar*
-````````````````````````````````
-
-
-A comment (type 2):
-
-```````````````````````````````` example
-<!-- Foo
-
-bar
- baz -->
-.
-<!-- Foo
-
-bar
- baz -->
-````````````````````````````````
-
-
-
-A processing instruction (type 3):
-
-```````````````````````````````` example
-<?php
-
- echo '>';
-
-?>
-.
-<?php
-
- echo '>';
-
-?>
-````````````````````````````````
-
-
-A declaration (type 4):
-
-```````````````````````````````` example
-<!DOCTYPE html>
-.
-<!DOCTYPE html>
-````````````````````````````````
-
-
-CDATA (type 5):
-
-```````````````````````````````` example
-<![CDATA[
-function matchwo(a,b)
-{
- if (a < b && a < 0) then {
- return 1;
-
- } else {
-
- return 0;
- }
-}
-]]>
-.
-<![CDATA[
-function matchwo(a,b)
-{
- if (a < b && a < 0) then {
- return 1;
-
- } else {
-
- return 0;
- }
-}
-]]>
-````````````````````````````````
-
-
-The opening tag can be indented 1-3 spaces, but not 4:
-
-```````````````````````````````` example
- <!-- foo -->
-
- <!-- foo -->
-.
- <!-- foo -->
-<pre><code><!-- foo -->
-</code></pre>
-````````````````````````````````
-
-
-```````````````````````````````` example
- <div>
-
- <div>
-.
- <div>
-<pre><code><div>
-</code></pre>
-````````````````````````````````
-
-
-An HTML block of types 1--6 can interrupt a paragraph, and need not be
-preceded by a blank line.
-
-```````````````````````````````` example
-Foo
-<div>
-bar
-</div>
-.
-<p>Foo</p>
-<div>
-bar
-</div>
-````````````````````````````````
-
-
-However, a following blank line is needed, except at the end of
-a document, and except for blocks of types 1--5, above:
-
-```````````````````````````````` example
-<div>
-bar
-</div>
-*foo*
-.
-<div>
-bar
-</div>
-*foo*
-````````````````````````````````
-
-
-HTML blocks of type 7 cannot interrupt a paragraph:
-
-```````````````````````````````` example
-Foo
-<a href="bar">
-baz
-.
-<p>Foo
-<a href="bar">
-baz</p>
-````````````````````````````````
-
-
-This rule differs from John Gruber's original Markdown syntax
-specification, which says:
-
-> The only restrictions are that block-level HTML elements —
-> e.g. `<div>`, `<table>`, `<pre>`, `<p>`, etc. — must be separated from
-> surrounding content by blank lines, and the start and end tags of the
-> block should not be indented with tabs or spaces.
-
-In some ways Gruber's rule is more restrictive than the one given
-here:
-
-- It requires that an HTML block be preceded by a blank line.
-- It does not allow the start tag to be indented.
-- It requires a matching end tag, which it also does not allow to
- be indented.
-
-Most Markdown implementations (including some of Gruber's own) do not
-respect all of these restrictions.
-
-There is one respect, however, in which Gruber's rule is more liberal
-than the one given here, since it allows blank lines to occur inside
-an HTML block. There are two reasons for disallowing them here.
-First, it removes the need to parse balanced tags, which is
-expensive and can require backtracking from the end of the document
-if no matching end tag is found. Second, it provides a very simple
-and flexible way of including Markdown content inside HTML tags:
-simply separate the Markdown from the HTML using blank lines:
-
-Compare:
-
-```````````````````````````````` example
-<div>
-
-*Emphasized* text.
-
-</div>
-.
-<div>
-<p><em>Emphasized</em> text.</p>
-</div>
-````````````````````````````````
-
-
-```````````````````````````````` example
-<div>
-*Emphasized* text.
-</div>
-.
-<div>
-*Emphasized* text.
-</div>
-````````````````````````````````
-
-
-Some Markdown implementations have adopted a convention of
-interpreting content inside tags as text if the open tag has
-the attribute `markdown=1`. The rule given above seems a simpler and
-more elegant way of achieving the same expressive power, which is also
-much simpler to parse.
-
-The main potential drawback is that one can no longer paste HTML
-blocks into Markdown documents with 100% reliability. However,
-*in most cases* this will work fine, because the blank lines in
-HTML are usually followed by HTML block tags. For example:
-
-```````````````````````````````` example
-<table>
-
-<tr>
-
-<td>
-Hi
-</td>
-
-</tr>
-
-</table>
-.
-<table>
-<tr>
-<td>
-Hi
-</td>
-</tr>
-</table>
-````````````````````````````````
-
-
-There are problems, however, if the inner tags are indented
-*and* separated by spaces, as then they will be interpreted as
-an indented code block:
-
-```````````````````````````````` example
-<table>
-
- <tr>
-
- <td>
- Hi
- </td>
-
- </tr>
-
-</table>
-.
-<table>
- <tr>
-<pre><code><td>
- Hi
-</td>
-</code></pre>
- </tr>
-</table>
-````````````````````````````````
-
-
-Fortunately, blank lines are usually not necessary and can be
-deleted. The exception is inside `<pre>` tags, but as described
-above, raw HTML blocks starting with `<pre>` *can* contain blank
-lines.
-
-## Link reference definitions
-
-A [link reference definition](@)
-consists of a [link label], indented up to three spaces, followed
-by a colon (`:`), optional [whitespace] (including up to one
-[line ending]), a [link destination],
-optional [whitespace] (including up to one
-[line ending]), and an optional [link
-title], which if it is present must be separated
-from the [link destination] by [whitespace].
-No further [non-whitespace characters] may occur on the line.
-
-A [link reference definition]
-does not correspond to a structural element of a document. Instead, it
-defines a label which can be used in [reference links]
-and reference-style [images] elsewhere in the document. [Link
-reference definitions] can come either before or after the links that use
-them.
-
-```````````````````````````````` example
-[foo]: /url "title"
-
-[foo]
-.
-<p><a href="/url" title="title">foo</a></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
- [foo]:
- /url
- 'the title'
-
-[foo]
-.
-<p><a href="/url" title="the title">foo</a></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-[Foo*bar\]]:my_(url) 'title (with parens)'
-
-[Foo*bar\]]
-.
-<p><a href="my_(url)" title="title (with parens)">Foo*bar]</a></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-[Foo bar]:
-<my%20url>
-'title'
-
-[Foo bar]
-.
-<p><a href="my%20url" title="title">Foo bar</a></p>
-````````````````````````````````
-
-
-The title may extend over multiple lines:
-
-```````````````````````````````` example
-[foo]: /url '
-title
-line1
-line2
-'
-
-[foo]
-.
-<p><a href="/url" title="
-title
-line1
-line2
-">foo</a></p>
-````````````````````````````````
-
-
-However, it may not contain a [blank line]:
-
-```````````````````````````````` example
-[foo]: /url 'title
-
-with blank line'
-
-[foo]
-.
-<p>[foo]: /url 'title</p>
-<p>with blank line'</p>
-<p>[foo]</p>
-````````````````````````````````
-
-
-The title may be omitted:
-
-```````````````````````````````` example
-[foo]:
-/url
-
-[foo]
-.
-<p><a href="/url">foo</a></p>
-````````````````````````````````
-
-
-The link destination may not be omitted:
-
-```````````````````````````````` example
-[foo]:
-
-[foo]
-.
-<p>[foo]:</p>
-<p>[foo]</p>
-````````````````````````````````
-
-
-Both title and destination can contain backslash escapes
-and literal backslashes:
-
-```````````````````````````````` example
-[foo]: /url\bar\*baz "foo\"bar\baz"
-
-[foo]
-.
-<p><a href="/url%5Cbar*baz" title="foo"bar\baz">foo</a></p>
-````````````````````````````````
-
-
-A link can come before its corresponding definition:
-
-```````````````````````````````` example
-[foo]
-
-[foo]: url
-.
-<p><a href="url">foo</a></p>
-````````````````````````````````
-
-
-If there are several matching definitions, the first one takes
-precedence:
-
-```````````````````````````````` example
-[foo]
-
-[foo]: first
-[foo]: second
-.
-<p><a href="first">foo</a></p>
-````````````````````````````````
-
-
-As noted in the section on [Links], matching of labels is
-case-insensitive (see [matches]).
-
-```````````````````````````````` example
-[FOO]: /url
-
-[Foo]
-.
-<p><a href="/url">Foo</a></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-[ΑΓΩ]: /φου
-
-[αγω]
-.
-<p><a href="/%CF%86%CE%BF%CF%85">αγω</a></p>
-````````````````````````````````
-
-
-Here is a link reference definition with no corresponding link.
-It contributes nothing to the document.
-
-```````````````````````````````` example
-[foo]: /url
-.
-````````````````````````````````
-
-
-Here is another one:
-
-```````````````````````````````` example
-[
-foo
-]: /url
-bar
-.
-<p>bar</p>
-````````````````````````````````
-
-
-This is not a link reference definition, because there are
-[non-whitespace characters] after the title:
-
-```````````````````````````````` example
-[foo]: /url "title" ok
-.
-<p>[foo]: /url "title" ok</p>
-````````````````````````````````
-
-
-This is a link reference definition, but it has no title:
-
-```````````````````````````````` example
-[foo]: /url
-"title" ok
-.
-<p>"title" ok</p>
-````````````````````````````````
-
-
-This is not a link reference definition, because it is indented
-four spaces:
-
-```````````````````````````````` example
- [foo]: /url "title"
-
-[foo]
-.
-<pre><code>[foo]: /url "title"
-</code></pre>
-<p>[foo]</p>
-````````````````````````````````
-
-
-This is not a link reference definition, because it occurs inside
-a code block:
-
-```````````````````````````````` example
-```
-[foo]: /url
-```
-
-[foo]
-.
-<pre><code>[foo]: /url
-</code></pre>
-<p>[foo]</p>
-````````````````````````````````
-
-
-A [link reference definition] cannot interrupt a paragraph.
-
-```````````````````````````````` example
-Foo
-[bar]: /baz
-
-[bar]
-.
-<p>Foo
-[bar]: /baz</p>
-<p>[bar]</p>
-````````````````````````````````
-
-
-However, it can directly follow other block elements, such as headings
-and thematic breaks, and it need not be followed by a blank line.
-
-```````````````````````````````` example
-# [Foo]
-[foo]: /url
-> bar
-.
-<h1><a href="/url">Foo</a></h1>
-<blockquote>
-<p>bar</p>
-</blockquote>
-````````````````````````````````
-
-
-Several [link reference definitions]
-can occur one after another, without intervening blank lines.
-
-```````````````````````````````` example
-[foo]: /foo-url "foo"
-[bar]: /bar-url
- "bar"
-[baz]: /baz-url
-
-[foo],
-[bar],
-[baz]
-.
-<p><a href="/foo-url" title="foo">foo</a>,
-<a href="/bar-url" title="bar">bar</a>,
-<a href="/baz-url">baz</a></p>
-````````````````````````````````
-
-
-[Link reference definitions] can occur
-inside block containers, like lists and block quotations. They
-affect the entire document, not just the container in which they
-are defined:
-
-```````````````````````````````` example
-[foo]
-
-> [foo]: /url
-.
-<p><a href="/url">foo</a></p>
-<blockquote>
-</blockquote>
-````````````````````````````````
-
-
-
-## Paragraphs
-
-A sequence of non-blank lines that cannot be interpreted as other
-kinds of blocks forms a [paragraph](@).
-The contents of the paragraph are the result of parsing the
-paragraph's raw content as inlines. The paragraph's raw content
-is formed by concatenating the lines and removing initial and final
-[whitespace].
-
-A simple example with two paragraphs:
-
-```````````````````````````````` example
-aaa
-
-bbb
-.
-<p>aaa</p>
-<p>bbb</p>
-````````````````````````````````
-
-
-Paragraphs can contain multiple lines, but no blank lines:
-
-```````````````````````````````` example
-aaa
-bbb
-
-ccc
-ddd
-.
-<p>aaa
-bbb</p>
-<p>ccc
-ddd</p>
-````````````````````````````````
-
-
-Multiple blank lines between paragraph have no effect:
-
-```````````````````````````````` example
-aaa
-
-
-bbb
-.
-<p>aaa</p>
-<p>bbb</p>
-````````````````````````````````
-
-
-Leading spaces are skipped:
-
-```````````````````````````````` example
- aaa
- bbb
-.
-<p>aaa
-bbb</p>
-````````````````````````````````
-
-
-Lines after the first may be indented any amount, since indented
-code blocks cannot interrupt paragraphs.
-
-```````````````````````````````` example
-aaa
- bbb
- ccc
-.
-<p>aaa
-bbb
-ccc</p>
-````````````````````````````````
-
-
-However, the first line may be indented at most three spaces,
-or an indented code block will be triggered:
-
-```````````````````````````````` example
- aaa
-bbb
-.
-<p>aaa
-bbb</p>
-````````````````````````````````
-
-
-```````````````````````````````` example
- aaa
-bbb
-.
-<pre><code>aaa
-</code></pre>
-<p>bbb</p>
-````````````````````````````````
-
-
-Final spaces are stripped before inline parsing, so a paragraph
-that ends with two or more spaces will not end with a [hard line
-break]:
-
-```````````````````````````````` example
-aaa
-bbb
-.
-<p>aaa<br />
-bbb</p>
-````````````````````````````````
-
-
-## Blank lines
-
-[Blank lines] between block-level elements are ignored,
-except for the role they play in determining whether a [list]
-is [tight] or [loose].
-
-Blank lines at the beginning and end of the document are also ignored.
-
-```````````````````````````````` example
-
-
-aaa
-
-
-# aaa
-
-
-.
-<p>aaa</p>
-<h1>aaa</h1>
-````````````````````````````````
-
-
-
-# Container blocks
-
-A [container block] is a block that has other
-blocks as its contents. There are two basic kinds of container blocks:
-[block quotes] and [list items].
-[Lists] are meta-containers for [list items].
-
-We define the syntax for container blocks recursively. The general
-form of the definition is:
-
-> If X is a sequence of blocks, then the result of
-> transforming X in such-and-such a way is a container of type Y
-> with these blocks as its content.
-
-So, we explain what counts as a block quote or list item by explaining
-how these can be *generated* from their contents. This should suffice
-to define the syntax, although it does not give a recipe for *parsing*
-these constructions. (A recipe is provided below in the section entitled
-[A parsing strategy](#appendix-a-parsing-strategy).)
-
-## Block quotes
-
-A [block quote marker](@)
-consists of 0-3 spaces of initial indent, plus (a) the character `>` together
-with a following space, or (b) a single character `>` not followed by a space.
-
-The following rules define [block quotes]:
-
-1. **Basic case.** If a string of lines *Ls* constitute a sequence
- of blocks *Bs*, then the result of prepending a [block quote
- marker] to the beginning of each line in *Ls*
- is a [block quote](#block-quotes) containing *Bs*.
-
-2. **Laziness.** If a string of lines *Ls* constitute a [block
- quote](#block-quotes) with contents *Bs*, then the result of deleting
- the initial [block quote marker] from one or
- more lines in which the next [non-whitespace character] after the [block
- quote marker] is [paragraph continuation
- text] is a block quote with *Bs* as its content.
- [Paragraph continuation text](@) is text
- that will be parsed as part of the content of a paragraph, but does
- not occur at the beginning of the paragraph.
-
-3. **Consecutiveness.** A document cannot contain two [block
- quotes] in a row unless there is a [blank line] between them.
-
-Nothing else counts as a [block quote](#block-quotes).
-
-Here is a simple example:
-
-```````````````````````````````` example
-> # Foo
-> bar
-> baz
-.
-<blockquote>
-<h1>Foo</h1>
-<p>bar
-baz</p>
-</blockquote>
-````````````````````````````````
-
-
-The spaces after the `>` characters can be omitted:
-
-```````````````````````````````` example
-># Foo
->bar
-> baz
-.
-<blockquote>
-<h1>Foo</h1>
-<p>bar
-baz</p>
-</blockquote>
-````````````````````````````````
-
-
-The `>` characters can be indented 1-3 spaces:
-
-```````````````````````````````` example
- > # Foo
- > bar
- > baz
-.
-<blockquote>
-<h1>Foo</h1>
-<p>bar
-baz</p>
-</blockquote>
-````````````````````````````````
-
-
-Four spaces gives us a code block:
-
-```````````````````````````````` example
- > # Foo
- > bar
- > baz
-.
-<pre><code>> # Foo
-> bar
-> baz
-</code></pre>
-````````````````````````````````
-
-
-The Laziness clause allows us to omit the `>` before a
-paragraph continuation line:
-
-```````````````````````````````` example
-> # Foo
-> bar
-baz
-.
-<blockquote>
-<h1>Foo</h1>
-<p>bar
-baz</p>
-</blockquote>
-````````````````````````````````
-
-
-A block quote can contain some lazy and some non-lazy
-continuation lines:
-
-```````````````````````````````` example
-> bar
-baz
-> foo
-.
-<blockquote>
-<p>bar
-baz
-foo</p>
-</blockquote>
-````````````````````````````````
-
-
-Laziness only applies to lines that would have been continuations of
-paragraphs had they been prepended with [block quote markers].
-For example, the `> ` cannot be omitted in the second line of
-
-``` markdown
-> foo
-> ---
-```
-
-without changing the meaning:
-
-```````````````````````````````` example
-> foo
----
-.
-<blockquote>
-<p>foo</p>
-</blockquote>
-<hr />
-````````````````````````````````
-
-
-Similarly, if we omit the `> ` in the second line of
-
-``` markdown
-> - foo
-> - bar
-```
-
-then the block quote ends after the first line:
-
-```````````````````````````````` example
-> - foo
-- bar
-.
-<blockquote>
-<ul>
-<li>foo</li>
-</ul>
-</blockquote>
-<ul>
-<li>bar</li>
-</ul>
-````````````````````````````````
-
-
-For the same reason, we can't omit the `> ` in front of
-subsequent lines of an indented or fenced code block:
-
-```````````````````````````````` example
-> foo
- bar
-.
-<blockquote>
-<pre><code>foo
-</code></pre>
-</blockquote>
-<pre><code>bar
-</code></pre>
-````````````````````````````````
-
-
-```````````````````````````````` example
-> ```
-foo
-```
-.
-<blockquote>
-<pre><code></code></pre>
-</blockquote>
-<p>foo</p>
-<pre><code></code></pre>
-````````````````````````````````
-
-
-Note that in the following case, we have a paragraph
-continuation line:
-
-```````````````````````````````` example
-> foo
- - bar
-.
-<blockquote>
-<p>foo
-- bar</p>
-</blockquote>
-````````````````````````````````
-
-
-To see why, note that in
-
-```markdown
-> foo
-> - bar
-```
-
-the `- bar` is indented too far to start a list, and can't
-be an indented code block because indented code blocks cannot
-interrupt paragraphs, so it is a [paragraph continuation line].
-
-A block quote can be empty:
-
-```````````````````````````````` example
->
-.
-<blockquote>
-</blockquote>
-````````````````````````````````
-
-
-```````````````````````````````` example
->
->
->
-.
-<blockquote>
-</blockquote>
-````````````````````````````````
-
-
-A block quote can have initial or final blank lines:
-
-```````````````````````````````` example
->
-> foo
->
-.
-<blockquote>
-<p>foo</p>
-</blockquote>
-````````````````````````````````
-
-
-A blank line always separates block quotes:
-
-```````````````````````````````` example
-> foo
-
-> bar
-.
-<blockquote>
-<p>foo</p>
-</blockquote>
-<blockquote>
-<p>bar</p>
-</blockquote>
-````````````````````````````````
-
-
-(Most current Markdown implementations, including John Gruber's
-original `Markdown.pl`, will parse this example as a single block quote
-with two paragraphs. But it seems better to allow the author to decide
-whether two block quotes or one are wanted.)
-
-Consecutiveness means that if we put these block quotes together,
-we get a single block quote:
-
-```````````````````````````````` example
-> foo
-> bar
-.
-<blockquote>
-<p>foo
-bar</p>
-</blockquote>
-````````````````````````````````
-
-
-To get a block quote with two paragraphs, use:
-
-```````````````````````````````` example
-> foo
->
-> bar
-.
-<blockquote>
-<p>foo</p>
-<p>bar</p>
-</blockquote>
-````````````````````````````````
-
-
-Block quotes can interrupt paragraphs:
-
-```````````````````````````````` example
-foo
-> bar
-.
-<p>foo</p>
-<blockquote>
-<p>bar</p>
-</blockquote>
-````````````````````````````````
-
-
-In general, blank lines are not needed before or after block
-quotes:
-
-```````````````````````````````` example
-> aaa
-***
-> bbb
-.
-<blockquote>
-<p>aaa</p>
-</blockquote>
-<hr />
-<blockquote>
-<p>bbb</p>
-</blockquote>
-````````````````````````````````
-
-
-However, because of laziness, a blank line is needed between
-a block quote and a following paragraph:
-
-```````````````````````````````` example
-> bar
-baz
-.
-<blockquote>
-<p>bar
-baz</p>
-</blockquote>
-````````````````````````````````
-
-
-```````````````````````````````` example
-> bar
-
-baz
-.
-<blockquote>
-<p>bar</p>
-</blockquote>
-<p>baz</p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-> bar
->
-baz
-.
-<blockquote>
-<p>bar</p>
-</blockquote>
-<p>baz</p>
-````````````````````````````````
-
-
-It is a consequence of the Laziness rule that any number
-of initial `>`s may be omitted on a continuation line of a
-nested block quote:
-
-```````````````````````````````` example
-> > > foo
-bar
-.
-<blockquote>
-<blockquote>
-<blockquote>
-<p>foo
-bar</p>
-</blockquote>
-</blockquote>
-</blockquote>
-````````````````````````````````
-
-
-```````````````````````````````` example
->>> foo
-> bar
->>baz
-.
-<blockquote>
-<blockquote>
-<blockquote>
-<p>foo
-bar
-baz</p>
-</blockquote>
-</blockquote>
-</blockquote>
-````````````````````````````````
-
-
-When including an indented code block in a block quote,
-remember that the [block quote marker] includes
-both the `>` and a following space. So *five spaces* are needed after
-the `>`:
-
-```````````````````````````````` example
-> code
-
-> not code
-.
-<blockquote>
-<pre><code>code
-</code></pre>
-</blockquote>
-<blockquote>
-<p>not code</p>
-</blockquote>
-````````````````````````````````
-
-
-
-## List items
-
-A [list marker](@) is a
-[bullet list marker] or an [ordered list marker].
-
-A [bullet list marker](@)
-is a `-`, `+`, or `*` character.
-
-An [ordered list marker](@)
-is a sequence of 1--9 arabic digits (`0-9`), followed by either a
-`.` character or a `)` character. (The reason for the length
-limit is that with 10 digits we start seeing integer overflows
-in some browsers.)
-
-The following rules define [list items]:
-
-1. **Basic case.** If a sequence of lines *Ls* constitute a sequence of
- blocks *Bs* starting with a [non-whitespace character] and not separated
- from each other by more than one blank line, and *M* is a list
- marker of width *W* followed by 0 < *N* < 5 spaces, then the result
- of prepending *M* and the following spaces to the first line of
- *Ls*, and indenting subsequent lines of *Ls* by *W + N* spaces, is a
- list item with *Bs* as its contents. The type of the list item
- (bullet or ordered) is determined by the type of its list marker.
- If the list item is ordered, then it is also assigned a start
- number, based on the ordered list marker.
-
-For example, let *Ls* be the lines
-
-```````````````````````````````` example
-A paragraph
-with two lines.
-
- indented code
-
-> A block quote.
-.
-<p>A paragraph
-with two lines.</p>
-<pre><code>indented code
-</code></pre>
-<blockquote>
-<p>A block quote.</p>
-</blockquote>
-````````````````````````````````
-
-
-And let *M* be the marker `1.`, and *N* = 2. Then rule #1 says
-that the following is an ordered list item with start number 1,
-and the same contents as *Ls*:
-
-```````````````````````````````` example
-1. A paragraph
- with two lines.
-
- indented code
-
- > A block quote.
-.
-<ol>
-<li>
-<p>A paragraph
-with two lines.</p>
-<pre><code>indented code
-</code></pre>
-<blockquote>
-<p>A block quote.</p>
-</blockquote>
-</li>
-</ol>
-````````````````````````````````
-
-
-The most important thing to notice is that the position of
-the text after the list marker determines how much indentation
-is needed in subsequent blocks in the list item. If the list
-marker takes up two spaces, and there are three spaces between
-the list marker and the next [non-whitespace character], then blocks
-must be indented five spaces in order to fall under the list
-item.
-
-Here are some examples showing how far content must be indented to be
-put under the list item:
-
-```````````````````````````````` example
-- one
-
- two
-.
-<ul>
-<li>one</li>
-</ul>
-<p>two</p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-- one
-
- two
-.
-<ul>
-<li>
-<p>one</p>
-<p>two</p>
-</li>
-</ul>
-````````````````````````````````
-
-
-```````````````````````````````` example
- - one
-
- two
-.
-<ul>
-<li>one</li>
-</ul>
-<pre><code> two
-</code></pre>
-````````````````````````````````
-
-
-```````````````````````````````` example
- - one
-
- two
-.
-<ul>
-<li>
-<p>one</p>
-<p>two</p>
-</li>
-</ul>
-````````````````````````````````
-
-
-It is tempting to think of this in terms of columns: the continuation
-blocks must be indented at least to the column of the first
-[non-whitespace character] after the list marker. However, that is not quite right.
-The spaces after the list marker determine how much relative indentation
-is needed. Which column this indentation reaches will depend on
-how the list item is embedded in other constructions, as shown by
-this example:
-
-```````````````````````````````` example
- > > 1. one
->>
->> two
-.
-<blockquote>
-<blockquote>
-<ol>
-<li>
-<p>one</p>
-<p>two</p>
-</li>
-</ol>
-</blockquote>
-</blockquote>
-````````````````````````````````
-
-
-Here `two` occurs in the same column as the list marker `1.`,
-but is actually contained in the list item, because there is
-sufficient indentation after the last containing blockquote marker.
-
-The converse is also possible. In the following example, the word `two`
-occurs far to the right of the initial text of the list item, `one`, but
-it is not considered part of the list item, because it is not indented
-far enough past the blockquote marker:
-
-```````````````````````````````` example
->>- one
->>
- > > two
-.
-<blockquote>
-<blockquote>
-<ul>
-<li>one</li>
-</ul>
-<p>two</p>
-</blockquote>
-</blockquote>
-````````````````````````````````
-
-
-Note that at least one space is needed between the list marker and
-any following content, so these are not list items:
-
-```````````````````````````````` example
--one
-
-2.two
-.
-<p>-one</p>
-<p>2.two</p>
-````````````````````````````````
-
-
-A list item may not contain blocks that are separated by more than
-one blank line. Thus, two blank lines will end a list, unless the
-two blanks are contained in a [fenced code block].
-
-```````````````````````````````` example
-- foo
-
- bar
-
-- foo
-
-
- bar
-
-- ```
- foo
-
-
- bar
- ```
-
-- baz
-
- + ```
- foo
-
-
- bar
- ```
-.
-<ul>
-<li>
-<p>foo</p>
-<p>bar</p>
-</li>
-<li>
-<p>foo</p>
-</li>
-</ul>
-<p>bar</p>
-<ul>
-<li>
-<pre><code>foo
-
-
-bar
-</code></pre>
-</li>
-<li>
-<p>baz</p>
-<ul>
-<li>
-<pre><code>foo
-
-
-bar
-</code></pre>
-</li>
-</ul>
-</li>
-</ul>
-````````````````````````````````
-
-
-A list item may contain any kind of block:
-
-```````````````````````````````` example
-1. foo
-
- ```
- bar
- ```
-
- baz
-
- > bam
-.
-<ol>
-<li>
-<p>foo</p>
-<pre><code>bar
-</code></pre>
-<p>baz</p>
-<blockquote>
-<p>bam</p>
-</blockquote>
-</li>
-</ol>
-````````````````````````````````
-
-
-A list item that contains an indented code block will preserve
-empty lines within the code block verbatim, unless there are two
-or more empty lines in a row (since as described above, two
-blank lines end the list):
-
-```````````````````````````````` example
-- Foo
-
- bar
-
- baz
-.
-<ul>
-<li>
-<p>Foo</p>
-<pre><code>bar
-
-baz
-</code></pre>
-</li>
-</ul>
-````````````````````````````````
-
-
-```````````````````````````````` example
-- Foo
-
- bar
-
-
- baz
-.
-<ul>
-<li>
-<p>Foo</p>
-<pre><code>bar
-</code></pre>
-</li>
-</ul>
-<pre><code> baz
-</code></pre>
-````````````````````````````````
-
-
-Note that ordered list start numbers must be nine digits or less:
-
-```````````````````````````````` example
-123456789. ok
-.
-<ol start="123456789">
-<li>ok</li>
-</ol>
-````````````````````````````````
-
-
-```````````````````````````````` example
-1234567890. not ok
-.
-<p>1234567890. not ok</p>
-````````````````````````````````
-
-
-A start number may begin with 0s:
-
-```````````````````````````````` example
-0. ok
-.
-<ol start="0">
-<li>ok</li>
-</ol>
-````````````````````````````````
-
-
-```````````````````````````````` example
-003. ok
-.
-<ol start="3">
-<li>ok</li>
-</ol>
-````````````````````````````````
-
-
-A start number may not be negative:
-
-```````````````````````````````` example
--1. not ok
-.
-<p>-1. not ok</p>
-````````````````````````````````
-
-
-
-2. **Item starting with indented code.** If a sequence of lines *Ls*
- constitute a sequence of blocks *Bs* starting with an indented code
- block and not separated from each other by more than one blank line,
- and *M* is a list marker of width *W* followed by
- one space, then the result of prepending *M* and the following
- space to the first line of *Ls*, and indenting subsequent lines of
- *Ls* by *W + 1* spaces, is a list item with *Bs* as its contents.
- If a line is empty, then it need not be indented. The type of the
- list item (bullet or ordered) is determined by the type of its list
- marker. If the list item is ordered, then it is also assigned a
- start number, based on the ordered list marker.
-
-An indented code block will have to be indented four spaces beyond
-the edge of the region where text will be included in the list item.
-In the following case that is 6 spaces:
-
-```````````````````````````````` example
-- foo
-
- bar
-.
-<ul>
-<li>
-<p>foo</p>
-<pre><code>bar
-</code></pre>
-</li>
-</ul>
-````````````````````````````````
-
-
-And in this case it is 11 spaces:
-
-```````````````````````````````` example
- 10. foo
-
- bar
-.
-<ol start="10">
-<li>
-<p>foo</p>
-<pre><code>bar
-</code></pre>
-</li>
-</ol>
-````````````````````````````````
-
-
-If the *first* block in the list item is an indented code block,
-then by rule #2, the contents must be indented *one* space after the
-list marker:
-
-```````````````````````````````` example
- indented code
-
-paragraph
-
- more code
-.
-<pre><code>indented code
-</code></pre>
-<p>paragraph</p>
-<pre><code>more code
-</code></pre>
-````````````````````````````````
-
-
-```````````````````````````````` example
-1. indented code
-
- paragraph
-
- more code
-.
-<ol>
-<li>
-<pre><code>indented code
-</code></pre>
-<p>paragraph</p>
-<pre><code>more code
-</code></pre>
-</li>
-</ol>
-````````````````````````````````
-
-
-Note that an additional space indent is interpreted as space
-inside the code block:
-
-```````````````````````````````` example
-1. indented code
-
- paragraph
-
- more code
-.
-<ol>
-<li>
-<pre><code> indented code
-</code></pre>
-<p>paragraph</p>
-<pre><code>more code
-</code></pre>
-</li>
-</ol>
-````````````````````````````````
-
-
-Note that rules #1 and #2 only apply to two cases: (a) cases
-in which the lines to be included in a list item begin with a
-[non-whitespace character], and (b) cases in which
-they begin with an indented code
-block. In a case like the following, where the first block begins with
-a three-space indent, the rules do not allow us to form a list item by
-indenting the whole thing and prepending a list marker:
-
-```````````````````````````````` example
- foo
-
-bar
-.
-<p>foo</p>
-<p>bar</p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-- foo
-
- bar
-.
-<ul>
-<li>foo</li>
-</ul>
-<p>bar</p>
-````````````````````````````````
-
-
-This is not a significant restriction, because when a block begins
-with 1-3 spaces indent, the indentation can always be removed without
-a change in interpretation, allowing rule #1 to be applied. So, in
-the above case:
-
-```````````````````````````````` example
-- foo
-
- bar
-.
-<ul>
-<li>
-<p>foo</p>
-<p>bar</p>
-</li>
-</ul>
-````````````````````````````````
-
-
-3. **Item starting with a blank line.** If a sequence of lines *Ls*
- starting with a single [blank line] constitute a (possibly empty)
- sequence of blocks *Bs*, not separated from each other by more than
- one blank line, and *M* is a list marker of width *W*,
- then the result of prepending *M* to the first line of *Ls*, and
- indenting subsequent lines of *Ls* by *W + 1* spaces, is a list
- item with *Bs* as its contents.
- If a line is empty, then it need not be indented. The type of the
- list item (bullet or ordered) is determined by the type of its list
- marker. If the list item is ordered, then it is also assigned a
- start number, based on the ordered list marker.
-
-Here are some list items that start with a blank line but are not empty:
-
-```````````````````````````````` example
--
- foo
--
- ```
- bar
- ```
--
- baz
-.
-<ul>
-<li>foo</li>
-<li>
-<pre><code>bar
-</code></pre>
-</li>
-<li>
-<pre><code>baz
-</code></pre>
-</li>
-</ul>
-````````````````````````````````
-
-When the list item starts with a blank line, the number of spaces
-following the list marker doesn't change the required indentation:
-
-```````````````````````````````` example
--
- foo
-.
-<ul>
-<li>foo</li>
-</ul>
-````````````````````````````````
-
-
-A list item can begin with at most one blank line.
-In the following example, `foo` is not part of the list
-item:
-
-```````````````````````````````` example
--
-
- foo
-.
-<ul>
-<li></li>
-</ul>
-<p>foo</p>
-````````````````````````````````
-
-
-Here is an empty bullet list item:
-
-```````````````````````````````` example
-- foo
--
-- bar
-.
-<ul>
-<li>foo</li>
-<li></li>
-<li>bar</li>
-</ul>
-````````````````````````````````
-
-
-It does not matter whether there are spaces following the [list marker]:
-
-```````````````````````````````` example
-- foo
--
-- bar
-.
-<ul>
-<li>foo</li>
-<li></li>
-<li>bar</li>
-</ul>
-````````````````````````````````
-
-
-Here is an empty ordered list item:
-
-```````````````````````````````` example
-1. foo
-2.
-3. bar
-.
-<ol>
-<li>foo</li>
-<li></li>
-<li>bar</li>
-</ol>
-````````````````````````````````
-
-
-A list may start or end with an empty list item:
-
-```````````````````````````````` example
-*
-.
-<ul>
-<li></li>
-</ul>
-````````````````````````````````
-
-
-
-4. **Indentation.** If a sequence of lines *Ls* constitutes a list item
- according to rule #1, #2, or #3, then the result of indenting each line
- of *Ls* by 1-3 spaces (the same for each line) also constitutes a
- list item with the same contents and attributes. If a line is
- empty, then it need not be indented.
-
-Indented one space:
-
-```````````````````````````````` example
- 1. A paragraph
- with two lines.
-
- indented code
-
- > A block quote.
-.
-<ol>
-<li>
-<p>A paragraph
-with two lines.</p>
-<pre><code>indented code
-</code></pre>
-<blockquote>
-<p>A block quote.</p>
-</blockquote>
-</li>
-</ol>
-````````````````````````````````
-
-
-Indented two spaces:
-
-```````````````````````````````` example
- 1. A paragraph
- with two lines.
-
- indented code
-
- > A block quote.
-.
-<ol>
-<li>
-<p>A paragraph
-with two lines.</p>
-<pre><code>indented code
-</code></pre>
-<blockquote>
-<p>A block quote.</p>
-</blockquote>
-</li>
-</ol>
-````````````````````````````````
-
-
-Indented three spaces:
-
-```````````````````````````````` example
- 1. A paragraph
- with two lines.
-
- indented code
-
- > A block quote.
-.
-<ol>
-<li>
-<p>A paragraph
-with two lines.</p>
-<pre><code>indented code
-</code></pre>
-<blockquote>
-<p>A block quote.</p>
-</blockquote>
-</li>
-</ol>
-````````````````````````````````
-
-
-Four spaces indent gives a code block:
-
-```````````````````````````````` example
- 1. A paragraph
- with two lines.
-
- indented code
-
- > A block quote.
-.
-<pre><code>1. A paragraph
- with two lines.
-
- indented code
-
- > A block quote.
-</code></pre>
-````````````````````````````````
-
-
-
-5. **Laziness.** If a string of lines *Ls* constitute a [list
- item](#list-items) with contents *Bs*, then the result of deleting
- some or all of the indentation from one or more lines in which the
- next [non-whitespace character] after the indentation is
- [paragraph continuation text] is a
- list item with the same contents and attributes. The unindented
- lines are called
- [lazy continuation line](@)s.
-
-Here is an example with [lazy continuation lines]:
-
-```````````````````````````````` example
- 1. A paragraph
-with two lines.
-
- indented code
-
- > A block quote.
-.
-<ol>
-<li>
-<p>A paragraph
-with two lines.</p>
-<pre><code>indented code
-</code></pre>
-<blockquote>
-<p>A block quote.</p>
-</blockquote>
-</li>
-</ol>
-````````````````````````````````
-
-
-Indentation can be partially deleted:
-
-```````````````````````````````` example
- 1. A paragraph
- with two lines.
-.
-<ol>
-<li>A paragraph
-with two lines.</li>
-</ol>
-````````````````````````````````
-
-
-These examples show how laziness can work in nested structures:
-
-```````````````````````````````` example
-> 1. > Blockquote
-continued here.
-.
-<blockquote>
-<ol>
-<li>
-<blockquote>
-<p>Blockquote
-continued here.</p>
-</blockquote>
-</li>
-</ol>
-</blockquote>
-````````````````````````````````
-
-
-```````````````````````````````` example
-> 1. > Blockquote
-> continued here.
-.
-<blockquote>
-<ol>
-<li>
-<blockquote>
-<p>Blockquote
-continued here.</p>
-</blockquote>
-</li>
-</ol>
-</blockquote>
-````````````````````````````````
-
-
-
-6. **That's all.** Nothing that is not counted as a list item by rules
- #1--5 counts as a [list item](#list-items).
-
-The rules for sublists follow from the general rules above. A sublist
-must be indented the same number of spaces a paragraph would need to be
-in order to be included in the list item.
-
-So, in this case we need two spaces indent:
-
-```````````````````````````````` example
-- foo
- - bar
- - baz
-.
-<ul>
-<li>foo
-<ul>
-<li>bar
-<ul>
-<li>baz</li>
-</ul>
-</li>
-</ul>
-</li>
-</ul>
-````````````````````````````````
-
-
-One is not enough:
-
-```````````````````````````````` example
-- foo
- - bar
- - baz
-.
-<ul>
-<li>foo</li>
-<li>bar</li>
-<li>baz</li>
-</ul>
-````````````````````````````````
-
-
-Here we need four, because the list marker is wider:
-
-```````````````````````````````` example
-10) foo
- - bar
-.
-<ol start="10">
-<li>foo
-<ul>
-<li>bar</li>
-</ul>
-</li>
-</ol>
-````````````````````````````````
-
-
-Three is not enough:
-
-```````````````````````````````` example
-10) foo
- - bar
-.
-<ol start="10">
-<li>foo</li>
-</ol>
-<ul>
-<li>bar</li>
-</ul>
-````````````````````````````````
-
-
-A list may be the first block in a list item:
-
-```````````````````````````````` example
-- - foo
-.
-<ul>
-<li>
-<ul>
-<li>foo</li>
-</ul>
-</li>
-</ul>
-````````````````````````````````
-
-
-```````````````````````````````` example
-1. - 2. foo
-.
-<ol>
-<li>
-<ul>
-<li>
-<ol start="2">
-<li>foo</li>
-</ol>
-</li>
-</ul>
-</li>
-</ol>
-````````````````````````````````
-
-
-A list item can contain a heading:
-
-```````````````````````````````` example
-- # Foo
-- Bar
- ---
- baz
-.
-<ul>
-<li>
-<h1>Foo</h1>
-</li>
-<li>
-<h2>Bar</h2>
-baz</li>
-</ul>
-````````````````````````````````
-
-
-### Motivation
-
-John Gruber's Markdown spec says the following about list items:
-
-1. "List markers typically start at the left margin, but may be indented
- by up to three spaces. List markers must be followed by one or more
- spaces or a tab."
-
-2. "To make lists look nice, you can wrap items with hanging indents....
- But if you don't want to, you don't have to."
-
-3. "List items may consist of multiple paragraphs. Each subsequent
- paragraph in a list item must be indented by either 4 spaces or one
- tab."
-
-4. "It looks nice if you indent every line of the subsequent paragraphs,
- but here again, Markdown will allow you to be lazy."
-
-5. "To put a blockquote within a list item, the blockquote's `>`
- delimiters need to be indented."
-
-6. "To put a code block within a list item, the code block needs to be
- indented twice — 8 spaces or two tabs."
-
-These rules specify that a paragraph under a list item must be indented
-four spaces (presumably, from the left margin, rather than the start of
-the list marker, but this is not said), and that code under a list item
-must be indented eight spaces instead of the usual four. They also say
-that a block quote must be indented, but not by how much; however, the
-example given has four spaces indentation. Although nothing is said
-about other kinds of block-level content, it is certainly reasonable to
-infer that *all* block elements under a list item, including other
-lists, must be indented four spaces. This principle has been called the
-*four-space rule*.
-
-The four-space rule is clear and principled, and if the reference
-implementation `Markdown.pl` had followed it, it probably would have
-become the standard. However, `Markdown.pl` allowed paragraphs and
-sublists to start with only two spaces indentation, at least on the
-outer level. Worse, its behavior was inconsistent: a sublist of an
-outer-level list needed two spaces indentation, but a sublist of this
-sublist needed three spaces. It is not surprising, then, that different
-implementations of Markdown have developed very different rules for
-determining what comes under a list item. (Pandoc and python-Markdown,
-for example, stuck with Gruber's syntax description and the four-space
-rule, while discount, redcarpet, marked, PHP Markdown, and others
-followed `Markdown.pl`'s behavior more closely.)
-
-Unfortunately, given the divergences between implementations, there
-is no way to give a spec for list items that will be guaranteed not
-to break any existing documents. However, the spec given here should
-correctly handle lists formatted with either the four-space rule or
-the more forgiving `Markdown.pl` behavior, provided they are laid out
-in a way that is natural for a human to read.
-
-The strategy here is to let the width and indentation of the list marker
-determine the indentation necessary for blocks to fall under the list
-item, rather than having a fixed and arbitrary number. The writer can
-think of the body of the list item as a unit which gets indented to the
-right enough to fit the list marker (and any indentation on the list
-marker). (The laziness rule, #5, then allows continuation lines to be
-unindented if needed.)
-
-This rule is superior, we claim, to any rule requiring a fixed level of
-indentation from the margin. The four-space rule is clear but
-unnatural. It is quite unintuitive that
-
-``` markdown
-- foo
-
- bar
-
- - baz
-```
-
-should be parsed as two lists with an intervening paragraph,
-
-``` html
-<ul>
-<li>foo</li>
-</ul>
-<p>bar</p>
-<ul>
-<li>baz</li>
-</ul>
-```
-
-as the four-space rule demands, rather than a single list,
-
-``` html
-<ul>
-<li>
-<p>foo</p>
-<p>bar</p>
-<ul>
-<li>baz</li>
-</ul>
-</li>
-</ul>
-```
-
-The choice of four spaces is arbitrary. It can be learned, but it is
-not likely to be guessed, and it trips up beginners regularly.
-
-Would it help to adopt a two-space rule? The problem is that such
-a rule, together with the rule allowing 1--3 spaces indentation of the
-initial list marker, allows text that is indented *less than* the
-original list marker to be included in the list item. For example,
-`Markdown.pl` parses
-
-``` markdown
- - one
-
- two
-```
-
-as a single list item, with `two` a continuation paragraph:
-
-``` html
-<ul>
-<li>
-<p>one</p>
-<p>two</p>
-</li>
-</ul>
-```
-
-and similarly
-
-``` markdown
-> - one
->
-> two
-```
-
-as
-
-``` html
-<blockquote>
-<ul>
-<li>
-<p>one</p>
-<p>two</p>
-</li>
-</ul>
-</blockquote>
-```
-
-This is extremely unintuitive.
-
-Rather than requiring a fixed indent from the margin, we could require
-a fixed indent (say, two spaces, or even one space) from the list marker (which
-may itself be indented). This proposal would remove the last anomaly
-discussed. Unlike the spec presented above, it would count the following
-as a list item with a subparagraph, even though the paragraph `bar`
-is not indented as far as the first paragraph `foo`:
-
-``` markdown
- 10. foo
-
- bar
-```
-
-Arguably this text does read like a list item with `bar` as a subparagraph,
-which may count in favor of the proposal. However, on this proposal indented
-code would have to be indented six spaces after the list marker. And this
-would break a lot of existing Markdown, which has the pattern:
-
-``` markdown
-1. foo
-
- indented code
-```
-
-where the code is indented eight spaces. The spec above, by contrast, will
-parse this text as expected, since the code block's indentation is measured
-from the beginning of `foo`.
-
-The one case that needs special treatment is a list item that *starts*
-with indented code. How much indentation is required in that case, since
-we don't have a "first paragraph" to measure from? Rule #2 simply stipulates
-that in such cases, we require one space indentation from the list marker
-(and then the normal four spaces for the indented code). This will match the
-four-space rule in cases where the list marker plus its initial indentation
-takes four spaces (a common case), but diverge in other cases.
-
-## Lists
-
-A [list](@) is a sequence of one or more
-list items [of the same type]. The list items
-may be separated by single [blank lines], but two
-blank lines end all containing lists.
-
-Two list items are [of the same type](@)
-if they begin with a [list marker] of the same type.
-Two list markers are of the
-same type if (a) they are bullet list markers using the same character
-(`-`, `+`, or `*`) or (b) they are ordered list numbers with the same
-delimiter (either `.` or `)`).
-
-A list is an [ordered list](@)
-if its constituent list items begin with
-[ordered list markers], and a
-[bullet list](@) if its constituent list
-items begin with [bullet list markers].
-
-The [start number](@)
-of an [ordered list] is determined by the list number of
-its initial list item. The numbers of subsequent list items are
-disregarded.
-
-A list is [loose](@) if any of its constituent
-list items are separated by blank lines, or if any of its constituent
-list items directly contain two block-level elements with a blank line
-between them. Otherwise a list is [tight](@).
-(The difference in HTML output is that paragraphs in a loose list are
-wrapped in `<p>` tags, while paragraphs in a tight list are not.)
-
-Changing the bullet or ordered list delimiter starts a new list:
-
-```````````````````````````````` example
-- foo
-- bar
-+ baz
-.
-<ul>
-<li>foo</li>
-<li>bar</li>
-</ul>
-<ul>
-<li>baz</li>
-</ul>
-````````````````````````````````
-
-
-```````````````````````````````` example
-1. foo
-2. bar
-3) baz
-.
-<ol>
-<li>foo</li>
-<li>bar</li>
-</ol>
-<ol start="3">
-<li>baz</li>
-</ol>
-````````````````````````````````
-
-
-In CommonMark, a list can interrupt a paragraph. That is,
-no blank line is needed to separate a paragraph from a following
-list:
-
-```````````````````````````````` example
-Foo
-- bar
-- baz
-.
-<p>Foo</p>
-<ul>
-<li>bar</li>
-<li>baz</li>
-</ul>
-````````````````````````````````
-
-
-`Markdown.pl` does not allow this, through fear of triggering a list
-via a numeral in a hard-wrapped line:
-
-```````````````````````````````` example
-The number of windows in my house is
-14. The number of doors is 6.
-.
-<p>The number of windows in my house is</p>
-<ol start="14">
-<li>The number of doors is 6.</li>
-</ol>
-````````````````````````````````
-
-
-Oddly, `Markdown.pl` *does* allow a blockquote to interrupt a paragraph,
-even though the same considerations might apply. We think that the two
-cases should be treated the same. Here are two reasons for allowing
-lists to interrupt paragraphs:
-
-First, it is natural and not uncommon for people to start lists without
-blank lines:
-
- I need to buy
- - new shoes
- - a coat
- - a plane ticket
-
-Second, we are attracted to a
-
-> [principle of uniformity](@):
-> if a chunk of text has a certain
-> meaning, it will continue to have the same meaning when put into a
-> container block (such as a list item or blockquote).
-
-(Indeed, the spec for [list items] and [block quotes] presupposes
-this principle.) This principle implies that if
-
- * I need to buy
- - new shoes
- - a coat
- - a plane ticket
-
-is a list item containing a paragraph followed by a nested sublist,
-as all Markdown implementations agree it is (though the paragraph
-may be rendered without `<p>` tags, since the list is "tight"),
-then
-
- I need to buy
- - new shoes
- - a coat
- - a plane ticket
-
-by itself should be a paragraph followed by a nested sublist.
-
-Our adherence to the [principle of uniformity]
-thus inclines us to think that there are two coherent packages:
-
-1. Require blank lines before *all* lists and blockquotes,
- including lists that occur as sublists inside other list items.
-
-2. Require blank lines in none of these places.
-
-[reStructuredText](http://docutils.sourceforge.net/rst.html) takes
-the first approach, for which there is much to be said. But the second
-seems more consistent with established practice with Markdown.
-
-There can be blank lines between items, but two blank lines end
-a list:
-
-```````````````````````````````` example
-- foo
-
-- bar
-
-
-- baz
-.
-<ul>
-<li>
-<p>foo</p>
-</li>
-<li>
-<p>bar</p>
-</li>
-</ul>
-<ul>
-<li>baz</li>
-</ul>
-````````````````````````````````
-
-
-As illustrated above in the section on [list items],
-two blank lines between blocks *within* a list item will also end a
-list:
-
-```````````````````````````````` example
-- foo
-
-
- bar
-- baz
-.
-<ul>
-<li>foo</li>
-</ul>
-<p>bar</p>
-<ul>
-<li>baz</li>
-</ul>
-````````````````````````````````
-
-
-Indeed, two blank lines will end *all* containing lists:
-
-```````````````````````````````` example
-- foo
- - bar
- - baz
-
-
- bim
-.
-<ul>
-<li>foo
-<ul>
-<li>bar
-<ul>
-<li>baz</li>
-</ul>
-</li>
-</ul>
-</li>
-</ul>
-<pre><code> bim
-</code></pre>
-````````````````````````````````
-
-
-Thus, two blank lines can be used to separate consecutive lists of
-the same type, or to separate a list from an indented code block
-that would otherwise be parsed as a subparagraph of the final list
-item:
-
-```````````````````````````````` example
-- foo
-- bar
-
-
-- baz
-- bim
-.
-<ul>
-<li>foo</li>
-<li>bar</li>
-</ul>
-<ul>
-<li>baz</li>
-<li>bim</li>
-</ul>
-````````````````````````````````
-
-
-```````````````````````````````` example
-- foo
-
- notcode
-
-- foo
-
-
- code
-.
-<ul>
-<li>
-<p>foo</p>
-<p>notcode</p>
-</li>
-<li>
-<p>foo</p>
-</li>
-</ul>
-<pre><code>code
-</code></pre>
-````````````````````````````````
-
-
-List items need not be indented to the same level. The following
-list items will be treated as items at the same list level,
-since none is indented enough to belong to the previous list
-item:
-
-```````````````````````````````` example
-- a
- - b
- - c
- - d
- - e
- - f
- - g
- - h
-- i
-.
-<ul>
-<li>a</li>
-<li>b</li>
-<li>c</li>
-<li>d</li>
-<li>e</li>
-<li>f</li>
-<li>g</li>
-<li>h</li>
-<li>i</li>
-</ul>
-````````````````````````````````
-
-
-```````````````````````````````` example
-1. a
-
- 2. b
-
- 3. c
-.
-<ol>
-<li>
-<p>a</p>
-</li>
-<li>
-<p>b</p>
-</li>
-<li>
-<p>c</p>
-</li>
-</ol>
-````````````````````````````````
-
-
-This is a loose list, because there is a blank line between
-two of the list items:
-
-```````````````````````````````` example
-- a
-- b
-
-- c
-.
-<ul>
-<li>
-<p>a</p>
-</li>
-<li>
-<p>b</p>
-</li>
-<li>
-<p>c</p>
-</li>
-</ul>
-````````````````````````````````
-
-
-So is this, with a empty second item:
-
-```````````````````````````````` example
-* a
-*
-
-* c
-.
-<ul>
-<li>
-<p>a</p>
-</li>
-<li></li>
-<li>
-<p>c</p>
-</li>
-</ul>
-````````````````````````````````
-
-
-These are loose lists, even though there is no space between the items,
-because one of the items directly contains two block-level elements
-with a blank line between them:
-
-```````````````````````````````` example
-- a
-- b
-
- c
-- d
-.
-<ul>
-<li>
-<p>a</p>
-</li>
-<li>
-<p>b</p>
-<p>c</p>
-</li>
-<li>
-<p>d</p>
-</li>
-</ul>
-````````````````````````````````
-
-
-```````````````````````````````` example
-- a
-- b
-
- [ref]: /url
-- d
-.
-<ul>
-<li>
-<p>a</p>
-</li>
-<li>
-<p>b</p>
-</li>
-<li>
-<p>d</p>
-</li>
-</ul>
-````````````````````````````````
-
-
-This is a tight list, because the blank lines are in a code block:
-
-```````````````````````````````` example
-- a
-- ```
- b
-
-
- ```
-- c
-.
-<ul>
-<li>a</li>
-<li>
-<pre><code>b
-
-
-</code></pre>
-</li>
-<li>c</li>
-</ul>
-````````````````````````````````
-
-
-This is a tight list, because the blank line is between two
-paragraphs of a sublist. So the sublist is loose while
-the outer list is tight:
-
-```````````````````````````````` example
-- a
- - b
-
- c
-- d
-.
-<ul>
-<li>a
-<ul>
-<li>
-<p>b</p>
-<p>c</p>
-</li>
-</ul>
-</li>
-<li>d</li>
-</ul>
-````````````````````````````````
-
-
-This is a tight list, because the blank line is inside the
-block quote:
-
-```````````````````````````````` example
-* a
- > b
- >
-* c
-.
-<ul>
-<li>a
-<blockquote>
-<p>b</p>
-</blockquote>
-</li>
-<li>c</li>
-</ul>
-````````````````````````````````
-
-
-This list is tight, because the consecutive block elements
-are not separated by blank lines:
-
-```````````````````````````````` example
-- a
- > b
- ```
- c
- ```
-- d
-.
-<ul>
-<li>a
-<blockquote>
-<p>b</p>
-</blockquote>
-<pre><code>c
-</code></pre>
-</li>
-<li>d</li>
-</ul>
-````````````````````````````````
-
-
-A single-paragraph list is tight:
-
-```````````````````````````````` example
-- a
-.
-<ul>
-<li>a</li>
-</ul>
-````````````````````````````````
-
-
-```````````````````````````````` example
-- a
- - b
-.
-<ul>
-<li>a
-<ul>
-<li>b</li>
-</ul>
-</li>
-</ul>
-````````````````````````````````
-
-
-This list is loose, because of the blank line between the
-two block elements in the list item:
-
-```````````````````````````````` example
-1. ```
- foo
- ```
-
- bar
-.
-<ol>
-<li>
-<pre><code>foo
-</code></pre>
-<p>bar</p>
-</li>
-</ol>
-````````````````````````````````
-
-
-Here the outer list is loose, the inner list tight:
-
-```````````````````````````````` example
-* foo
- * bar
-
- baz
-.
-<ul>
-<li>
-<p>foo</p>
-<ul>
-<li>bar</li>
-</ul>
-<p>baz</p>
-</li>
-</ul>
-````````````````````````````````
-
-
-```````````````````````````````` example
-- a
- - b
- - c
-
-- d
- - e
- - f
-.
-<ul>
-<li>
-<p>a</p>
-<ul>
-<li>b</li>
-<li>c</li>
-</ul>
-</li>
-<li>
-<p>d</p>
-<ul>
-<li>e</li>
-<li>f</li>
-</ul>
-</li>
-</ul>
-````````````````````````````````
-
-
-# Inlines
-
-Inlines are parsed sequentially from the beginning of the character
-stream to the end (left to right, in left-to-right languages).
-Thus, for example, in
-
-```````````````````````````````` example
-`hi`lo`
-.
-<p><code>hi</code>lo`</p>
-````````````````````````````````
-
-
-`hi` is parsed as code, leaving the backtick at the end as a literal
-backtick.
-
-## Backslash escapes
-
-Any ASCII punctuation character may be backslash-escaped:
-
-```````````````````````````````` example
-\!\"\#\$\%\&\'\(\)\*\+\,\-\.\/\:\;\<\=\>\?\@\[\\\]\^\_\`\{\|\}\~
-.
-<p>!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~</p>
-````````````````````````````````
-
-
-Backslashes before other characters are treated as literal
-backslashes:
-
-```````````````````````````````` example
-\→\A\a\ \3\φ\«
-.
-<p>\→\A\a\ \3\φ\«</p>
-````````````````````````````````
-
-
-Escaped characters are treated as regular characters and do
-not have their usual Markdown meanings:
-
-```````````````````````````````` example
-\*not emphasized*
-\<br/> not a tag
-\[not a link](/foo)
-\`not code`
-1\. not a list
-\* not a list
-\# not a heading
-\[foo]: /url "not a reference"
-.
-<p>*not emphasized*
-<br/> not a tag
-[not a link](/foo)
-`not code`
-1. not a list
-* not a list
-# not a heading
-[foo]: /url "not a reference"</p>
-````````````````````````````````
-
-
-If a backslash is itself escaped, the following character is not:
-
-```````````````````````````````` example
-\\*emphasis*
-.
-<p>\<em>emphasis</em></p>
-````````````````````````````````
-
-
-A backslash at the end of the line is a [hard line break]:
-
-```````````````````````````````` example
-foo\
-bar
-.
-<p>foo<br />
-bar</p>
-````````````````````````````````
-
-
-Backslash escapes do not work in code blocks, code spans, autolinks, or
-raw HTML:
-
-```````````````````````````````` example
-`` \[\` ``
-.
-<p><code>\[\`</code></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
- \[\]
-.
-<pre><code>\[\]
-</code></pre>
-````````````````````````````````
-
-
-```````````````````````````````` example
-~~~
-\[\]
-~~~
-.
-<pre><code>\[\]
-</code></pre>
-````````````````````````````````
-
-
-```````````````````````````````` example
-<http://example.com?find=\*>
-.
-<p><a href="http://example.com?find=%5C*">http://example.com?find=\*</a></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-<a href="/bar\/)">
-.
-<a href="/bar\/)">
-````````````````````````````````
-
-
-But they work in all other contexts, including URLs and link titles,
-link references, and [info strings] in [fenced code blocks]:
-
-```````````````````````````````` example
-[foo](/bar\* "ti\*tle")
-.
-<p><a href="/bar*" title="ti*tle">foo</a></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-[foo]
-
-[foo]: /bar\* "ti\*tle"
-.
-<p><a href="/bar*" title="ti*tle">foo</a></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-``` foo\+bar
-foo
-```
-.
-<pre><code class="language-foo+bar">foo
-</code></pre>
-````````````````````````````````
-
-
-
-## Entity and numeric character references
-
-All valid HTML entity references and numeric character
-references, except those occuring in code blocks and code spans,
-are recognized as such and treated as equivalent to the
-corresponding Unicode characters. Conforming CommonMark parsers
-need not store information about whether a particular character
-was represented in the source using a Unicode character or
-an entity reference.
-
-[Entity references](@) consist of `&` + any of the valid
-HTML5 entity names + `;`. The
-document <https://html.spec.whatwg.org/multipage/entities.json>
-is used as an authoritative source for the valid entity
-references and their corresponding code points.
-
-```````````````````````````````` example
- & © Æ Ď
-¾ ℋ ⅆ
-∲ ≧̸
-.
-<p> & © Æ Ď
-¾ ℋ ⅆ
-∲ ≧̸</p>
-````````````````````````````````
-
-
-[Decimal numeric character
-references](@)
-consist of `&#` + a string of 1--8 arabic digits + `;`. A
-numeric character reference is parsed as the corresponding
-Unicode character. Invalid Unicode code points will be replaced by
-the REPLACEMENT CHARACTER (`U+FFFD`). For security reasons,
-the code point `U+0000` will also be replaced by `U+FFFD`.
-
-```````````````````````````````` example
-# Ӓ Ϡ � �
-.
-<p># Ӓ Ϡ � �</p>
-````````````````````````````````
-
-
-[Hexadecimal numeric character
-references](@) consist of `&#` +
-either `X` or `x` + a string of 1-8 hexadecimal digits + `;`.
-They too are parsed as the corresponding Unicode character (this
-time specified with a hexadecimal numeral instead of decimal).
-
-```````````````````````````````` example
-" ആ ಫ
-.
-<p>" ആ ಫ</p>
-````````````````````````````````
-
-
-Here are some nonentities:
-
-```````````````````````````````` example
-  &x; &#; &#x;
-&ThisIsNotDefined; &hi?;
-.
-<p>&nbsp &x; &#; &#x;
-&ThisIsNotDefined; &hi?;</p>
-````````````````````````````````
-
-
-Although HTML5 does accept some entity references
-without a trailing semicolon (such as `©`), these are not
-recognized here, because it makes the grammar too ambiguous:
-
-```````````````````````````````` example
-©
-.
-<p>&copy</p>
-````````````````````````````````
-
-
-Strings that are not on the list of HTML5 named entities are not
-recognized as entity references either:
-
-```````````````````````````````` example
-&MadeUpEntity;
-.
-<p>&MadeUpEntity;</p>
-````````````````````````````````
-
-
-Entity and numeric character references are recognized in any
-context besides code spans or code blocks, including
-URLs, [link titles], and [fenced code block][] [info strings]:
-
-```````````````````````````````` example
-<a href="öö.html">
-.
-<a href="öö.html">
-````````````````````````````````
-
-
-```````````````````````````````` example
-[foo](/föö "föö")
-.
-<p><a href="/f%C3%B6%C3%B6" title="föö">foo</a></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-[foo]
-
-[foo]: /föö "föö"
-.
-<p><a href="/f%C3%B6%C3%B6" title="föö">foo</a></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-``` föö
-foo
-```
-.
-<pre><code class="language-föö">foo
-</code></pre>
-````````````````````````````````
-
-
-Entity and numeric character references are treated as literal
-text in code spans and code blocks:
-
-```````````````````````````````` example
-`föö`
-.
-<p><code>f&ouml;&ouml;</code></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
- föfö
-.
-<pre><code>f&ouml;f&ouml;
-</code></pre>
-````````````````````````````````
-
-
-## Code spans
-
-A [backtick string](@)
-is a string of one or more backtick characters (`` ` ``) that is neither
-preceded nor followed by a backtick.
-
-A [code span](@) begins with a backtick string and ends with
-a backtick string of equal length. The contents of the code span are
-the characters between the two backtick strings, with leading and
-trailing spaces and [line endings] removed, and
-[whitespace] collapsed to single spaces.
-
-This is a simple code span:
-
-```````````````````````````````` example
-`foo`
-.
-<p><code>foo</code></p>
-````````````````````````````````
-
-
-Here two backticks are used, because the code contains a backtick.
-This example also illustrates stripping of leading and trailing spaces:
-
-```````````````````````````````` example
-`` foo ` bar ``
-.
-<p><code>foo ` bar</code></p>
-````````````````````````````````
-
-
-This example shows the motivation for stripping leading and trailing
-spaces:
-
-```````````````````````````````` example
-` `` `
-.
-<p><code>``</code></p>
-````````````````````````````````
-
-
-[Line endings] are treated like spaces:
-
-```````````````````````````````` example
-``
-foo
-``
-.
-<p><code>foo</code></p>
-````````````````````````````````
-
-
-Interior spaces and [line endings] are collapsed into
-single spaces, just as they would be by a browser:
-
-```````````````````````````````` example
-`foo bar
- baz`
-.
-<p><code>foo bar baz</code></p>
-````````````````````````````````
-
-
-Q: Why not just leave the spaces, since browsers will collapse them
-anyway? A: Because we might be targeting a non-HTML format, and we
-shouldn't rely on HTML-specific rendering assumptions.
-
-(Existing implementations differ in their treatment of internal
-spaces and [line endings]. Some, including `Markdown.pl` and
-`showdown`, convert an internal [line ending] into a
-`<br />` tag. But this makes things difficult for those who like to
-hard-wrap their paragraphs, since a line break in the midst of a code
-span will cause an unintended line break in the output. Others just
-leave internal spaces as they are, which is fine if only HTML is being
-targeted.)
-
-```````````````````````````````` example
-`foo `` bar`
-.
-<p><code>foo `` bar</code></p>
-````````````````````````````````
-
-
-Note that backslash escapes do not work in code spans. All backslashes
-are treated literally:
-
-```````````````````````````````` example
-`foo\`bar`
-.
-<p><code>foo\</code>bar`</p>
-````````````````````````````````
-
-
-Backslash escapes are never needed, because one can always choose a
-string of *n* backtick characters as delimiters, where the code does
-not contain any strings of exactly *n* backtick characters.
-
-Code span backticks have higher precedence than any other inline
-constructs except HTML tags and autolinks. Thus, for example, this is
-not parsed as emphasized text, since the second `*` is part of a code
-span:
-
-```````````````````````````````` example
-*foo`*`
-.
-<p>*foo<code>*</code></p>
-````````````````````````````````
-
-
-And this is not parsed as a link:
-
-```````````````````````````````` example
-[not a `link](/foo`)
-.
-<p>[not a <code>link](/foo</code>)</p>
-````````````````````````````````
-
-
-Code spans, HTML tags, and autolinks have the same precedence.
-Thus, this is code:
-
-```````````````````````````````` example
-`<a href="`">`
-.
-<p><code><a href="</code>">`</p>
-````````````````````````````````
-
-
-But this is an HTML tag:
-
-```````````````````````````````` example
-<a href="`">`
-.
-<p><a href="`">`</p>
-````````````````````````````````
-
-
-And this is code:
-
-```````````````````````````````` example
-`<http://foo.bar.`baz>`
-.
-<p><code><http://foo.bar.</code>baz>`</p>
-````````````````````````````````
-
-
-But this is an autolink:
-
-```````````````````````````````` example
-<http://foo.bar.`baz>`
-.
-<p><a href="http://foo.bar.%60baz">http://foo.bar.`baz</a>`</p>
-````````````````````````````````
-
-
-When a backtick string is not closed by a matching backtick string,
-we just have literal backticks:
-
-```````````````````````````````` example
-```foo``
-.
-<p>```foo``</p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-`foo
-.
-<p>`foo</p>
-````````````````````````````````
-
-
-## Emphasis and strong emphasis
-
-John Gruber's original [Markdown syntax
-description](http://daringfireball.net/projects/markdown/syntax#em) says:
-
-> Markdown treats asterisks (`*`) and underscores (`_`) as indicators of
-> emphasis. Text wrapped with one `*` or `_` will be wrapped with an HTML
-> `<em>` tag; double `*`'s or `_`'s will be wrapped with an HTML `<strong>`
-> tag.
-
-This is enough for most users, but these rules leave much undecided,
-especially when it comes to nested emphasis. The original
-`Markdown.pl` test suite makes it clear that triple `***` and
-`___` delimiters can be used for strong emphasis, and most
-implementations have also allowed the following patterns:
-
-``` markdown
-***strong emph***
-***strong** in emph*
-***emph* in strong**
-**in strong *emph***
-*in emph **strong***
-```
-
-The following patterns are less widely supported, but the intent
-is clear and they are useful (especially in contexts like bibliography
-entries):
-
-``` markdown
-*emph *with emph* in it*
-**strong **with strong** in it**
-```
-
-Many implementations have also restricted intraword emphasis to
-the `*` forms, to avoid unwanted emphasis in words containing
-internal underscores. (It is best practice to put these in code
-spans, but users often do not.)
-
-``` markdown
-internal emphasis: foo*bar*baz
-no emphasis: foo_bar_baz
-```
-
-The rules given below capture all of these patterns, while allowing
-for efficient parsing strategies that do not backtrack.
-
-First, some definitions. A [delimiter run](@) is either
-a sequence of one or more `*` characters that is not preceded or
-followed by a `*` character, or a sequence of one or more `_`
-characters that is not preceded or followed by a `_` character.
-
-A [left-flanking delimiter run](@) is
-a [delimiter run] that is (a) not followed by [Unicode whitespace],
-and (b) either not followed by a [punctuation character], or
-preceded by [Unicode whitespace] or a [punctuation character].
-For purposes of this definition, the beginning and the end of
-the line count as Unicode whitespace.
-
-A [right-flanking delimiter run](@) is
-a [delimiter run] that is (a) not preceded by [Unicode whitespace],
-and (b) either not preceded by a [punctuation character], or
-followed by [Unicode whitespace] or a [punctuation character].
-For purposes of this definition, the beginning and the end of
-the line count as Unicode whitespace.
-
-Here are some examples of delimiter runs.
-
- - left-flanking but not right-flanking:
-
- ```
- ***abc
- _abc
- **"abc"
- _"abc"
- ```
-
- - right-flanking but not left-flanking:
-
- ```
- abc***
- abc_
- "abc"**
- "abc"_
- ```
-
- - Both left and right-flanking:
-
- ```
- abc***def
- "abc"_"def"
- ```
-
- - Neither left nor right-flanking:
-
- ```
- abc *** def
- a _ b
- ```
-
-(The idea of distinguishing left-flanking and right-flanking
-delimiter runs based on the character before and the character
-after comes from Roopesh Chander's
-[vfmd](http://www.vfmd.org/vfmd-spec/specification/#procedure-for-identifying-emphasis-tags).
-vfmd uses the terminology "emphasis indicator string" instead of "delimiter
-run," and its rules for distinguishing left- and right-flanking runs
-are a bit more complex than the ones given here.)
-
-The following rules define emphasis and strong emphasis:
-
-1. A single `*` character [can open emphasis](@)
- iff (if and only if) it is part of a [left-flanking delimiter run].
-
-2. A single `_` character [can open emphasis] iff
- it is part of a [left-flanking delimiter run]
- and either (a) not part of a [right-flanking delimiter run]
- or (b) part of a [right-flanking delimiter run]
- preceded by punctuation.
-
-3. A single `*` character [can close emphasis](@)
- iff it is part of a [right-flanking delimiter run].
-
-4. A single `_` character [can close emphasis] iff
- it is part of a [right-flanking delimiter run]
- and either (a) not part of a [left-flanking delimiter run]
- or (b) part of a [left-flanking delimiter run]
- followed by punctuation.
-
-5. A double `**` [can open strong emphasis](@)
- iff it is part of a [left-flanking delimiter run].
-
-6. A double `__` [can open strong emphasis] iff
- it is part of a [left-flanking delimiter run]
- and either (a) not part of a [right-flanking delimiter run]
- or (b) part of a [right-flanking delimiter run]
- preceded by punctuation.
-
-7. A double `**` [can close strong emphasis](@)
- iff it is part of a [right-flanking delimiter run].
-
-8. A double `__` [can close strong emphasis]
- it is part of a [right-flanking delimiter run]
- and either (a) not part of a [left-flanking delimiter run]
- or (b) part of a [left-flanking delimiter run]
- followed by punctuation.
-
-9. Emphasis begins with a delimiter that [can open emphasis] and ends
- with a delimiter that [can close emphasis], and that uses the same
- character (`_` or `*`) as the opening delimiter. There must
- be a nonempty sequence of inlines between the open delimiter
- and the closing delimiter; these form the contents of the emphasis
- inline.
-
-10. Strong emphasis begins with a delimiter that
- [can open strong emphasis] and ends with a delimiter that
- [can close strong emphasis], and that uses the same character
- (`_` or `*`) as the opening delimiter.
- There must be a nonempty sequence of inlines between the open
- delimiter and the closing delimiter; these form the contents of
- the strong emphasis inline.
-
-11. A literal `*` character cannot occur at the beginning or end of
- `*`-delimited emphasis or `**`-delimited strong emphasis, unless it
- is backslash-escaped.
-
-12. A literal `_` character cannot occur at the beginning or end of
- `_`-delimited emphasis or `__`-delimited strong emphasis, unless it
- is backslash-escaped.
-
-Where rules 1--12 above are compatible with multiple parsings,
-the following principles resolve ambiguity:
-
-13. The number of nestings should be minimized. Thus, for example,
- an interpretation `<strong>...</strong>` is always preferred to
- `<em><em>...</em></em>`.
-
-14. An interpretation `<strong><em>...</em></strong>` is always
- preferred to `<em><strong>..</strong></em>`.
-
-15. When two potential emphasis or strong emphasis spans overlap,
- so that the second begins before the first ends and ends after
- the first ends, the first takes precedence. Thus, for example,
- `*foo _bar* baz_` is parsed as `<em>foo _bar</em> baz_` rather
- than `*foo <em>bar* baz</em>`. For the same reason,
- `**foo*bar**` is parsed as `<em><em>foo</em>bar</em>*`
- rather than `<strong>foo*bar</strong>`.
-
-16. When there are two potential emphasis or strong emphasis spans
- with the same closing delimiter, the shorter one (the one that
- opens later) takes precedence. Thus, for example,
- `**foo **bar baz**` is parsed as `**foo <strong>bar baz</strong>`
- rather than `<strong>foo **bar baz</strong>`.
-
-17. Inline code spans, links, images, and HTML tags group more tightly
- than emphasis. So, when there is a choice between an interpretation
- that contains one of these elements and one that does not, the
- former always wins. Thus, for example, `*[foo*](bar)` is
- parsed as `*<a href="bar">foo*</a>` rather than as
- `<em>[foo</em>](bar)`.
-
-These rules can be illustrated through a series of examples.
-
-Rule 1:
-
-```````````````````````````````` example
-*foo bar*
-.
-<p><em>foo bar</em></p>
-````````````````````````````````
-
-
-This is not emphasis, because the opening `*` is followed by
-whitespace, and hence not part of a [left-flanking delimiter run]:
-
-```````````````````````````````` example
-a * foo bar*
-.
-<p>a * foo bar*</p>
-````````````````````````````````
-
-
-This is not emphasis, because the opening `*` is preceded
-by an alphanumeric and followed by punctuation, and hence
-not part of a [left-flanking delimiter run]:
-
-```````````````````````````````` example
-a*"foo"*
-.
-<p>a*"foo"*</p>
-````````````````````````````````
-
-
-Unicode nonbreaking spaces count as whitespace, too:
-
-```````````````````````````````` example
-* a *
-.
-<p>* a *</p>
-````````````````````````````````
-
-
-Intraword emphasis with `*` is permitted:
-
-```````````````````````````````` example
-foo*bar*
-.
-<p>foo<em>bar</em></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-5*6*78
-.
-<p>5<em>6</em>78</p>
-````````````````````````````````
-
-
-Rule 2:
-
-```````````````````````````````` example
-_foo bar_
-.
-<p><em>foo bar</em></p>
-````````````````````````````````
-
-
-This is not emphasis, because the opening `_` is followed by
-whitespace:
-
-```````````````````````````````` example
-_ foo bar_
-.
-<p>_ foo bar_</p>
-````````````````````````````````
-
-
-This is not emphasis, because the opening `_` is preceded
-by an alphanumeric and followed by punctuation:
-
-```````````````````````````````` example
-a_"foo"_
-.
-<p>a_"foo"_</p>
-````````````````````````````````
-
-
-Emphasis with `_` is not allowed inside words:
-
-```````````````````````````````` example
-foo_bar_
-.
-<p>foo_bar_</p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-5_6_78
-.
-<p>5_6_78</p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-пристаням_стремятся_
-.
-<p>пристаням_стремятся_</p>
-````````````````````````````````
-
-
-Here `_` does not generate emphasis, because the first delimiter run
-is right-flanking and the second left-flanking:
-
-```````````````````````````````` example
-aa_"bb"_cc
-.
-<p>aa_"bb"_cc</p>
-````````````````````````````````
-
-
-This is emphasis, even though the opening delimiter is
-both left- and right-flanking, because it is preceded by
-punctuation:
-
-```````````````````````````````` example
-foo-_(bar)_
-.
-<p>foo-<em>(bar)</em></p>
-````````````````````````````````
-
-
-Rule 3:
-
-This is not emphasis, because the closing delimiter does
-not match the opening delimiter:
-
-```````````````````````````````` example
-_foo*
-.
-<p>_foo*</p>
-````````````````````````````````
-
-
-This is not emphasis, because the closing `*` is preceded by
-whitespace:
-
-```````````````````````````````` example
-*foo bar *
-.
-<p>*foo bar *</p>
-````````````````````````````````
-
-
-A newline also counts as whitespace:
-
-```````````````````````````````` example
-*foo bar
-*
-.
-<p>*foo bar</p>
-<ul>
-<li></li>
-</ul>
-````````````````````````````````
-
-
-This is not emphasis, because the second `*` is
-preceded by punctuation and followed by an alphanumeric
-(hence it is not part of a [right-flanking delimiter run]:
-
-```````````````````````````````` example
-*(*foo)
-.
-<p>*(*foo)</p>
-````````````````````````````````
-
-
-The point of this restriction is more easily appreciated
-with this example:
-
-```````````````````````````````` example
-*(*foo*)*
-.
-<p><em>(<em>foo</em>)</em></p>
-````````````````````````````````
-
-
-Intraword emphasis with `*` is allowed:
-
-```````````````````````````````` example
-*foo*bar
-.
-<p><em>foo</em>bar</p>
-````````````````````````````````
-
-
-
-Rule 4:
-
-This is not emphasis, because the closing `_` is preceded by
-whitespace:
-
-```````````````````````````````` example
-_foo bar _
-.
-<p>_foo bar _</p>
-````````````````````````````````
-
-
-This is not emphasis, because the second `_` is
-preceded by punctuation and followed by an alphanumeric:
-
-```````````````````````````````` example
-_(_foo)
-.
-<p>_(_foo)</p>
-````````````````````````````````
-
-
-This is emphasis within emphasis:
-
-```````````````````````````````` example
-_(_foo_)_
-.
-<p><em>(<em>foo</em>)</em></p>
-````````````````````````````````
-
-
-Intraword emphasis is disallowed for `_`:
-
-```````````````````````````````` example
-_foo_bar
-.
-<p>_foo_bar</p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-_пристаням_стремятся
-.
-<p>_пристаням_стремятся</p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-_foo_bar_baz_
-.
-<p><em>foo_bar_baz</em></p>
-````````````````````````````````
-
-
-This is emphasis, even though the closing delimiter is
-both left- and right-flanking, because it is followed by
-punctuation:
-
-```````````````````````````````` example
-_(bar)_.
-.
-<p><em>(bar)</em>.</p>
-````````````````````````````````
-
-
-Rule 5:
-
-```````````````````````````````` example
-**foo bar**
-.
-<p><strong>foo bar</strong></p>
-````````````````````````````````
-
-
-This is not strong emphasis, because the opening delimiter is
-followed by whitespace:
-
-```````````````````````````````` example
-** foo bar**
-.
-<p>** foo bar**</p>
-````````````````````````````````
-
-
-This is not strong emphasis, because the opening `**` is preceded
-by an alphanumeric and followed by punctuation, and hence
-not part of a [left-flanking delimiter run]:
-
-```````````````````````````````` example
-a**"foo"**
-.
-<p>a**"foo"**</p>
-````````````````````````````````
-
-
-Intraword strong emphasis with `**` is permitted:
-
-```````````````````````````````` example
-foo**bar**
-.
-<p>foo<strong>bar</strong></p>
-````````````````````````````````
-
-
-Rule 6:
-
-```````````````````````````````` example
-__foo bar__
-.
-<p><strong>foo bar</strong></p>
-````````````````````````````````
-
-
-This is not strong emphasis, because the opening delimiter is
-followed by whitespace:
-
-```````````````````````````````` example
-__ foo bar__
-.
-<p>__ foo bar__</p>
-````````````````````````````````
-
-
-A newline counts as whitespace:
-```````````````````````````````` example
-__
-foo bar__
-.
-<p>__
-foo bar__</p>
-````````````````````````````````
-
-
-This is not strong emphasis, because the opening `__` is preceded
-by an alphanumeric and followed by punctuation:
-
-```````````````````````````````` example
-a__"foo"__
-.
-<p>a__"foo"__</p>
-````````````````````````````````
-
-
-Intraword strong emphasis is forbidden with `__`:
-
-```````````````````````````````` example
-foo__bar__
-.
-<p>foo__bar__</p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-5__6__78
-.
-<p>5__6__78</p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-пристаням__стремятся__
-.
-<p>пристаням__стремятся__</p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-__foo, __bar__, baz__
-.
-<p><strong>foo, <strong>bar</strong>, baz</strong></p>
-````````````````````````````````
-
-
-This is strong emphasis, even though the opening delimiter is
-both left- and right-flanking, because it is preceded by
-punctuation:
-
-```````````````````````````````` example
-foo-__(bar)__
-.
-<p>foo-<strong>(bar)</strong></p>
-````````````````````````````````
-
-
-
-Rule 7:
-
-This is not strong emphasis, because the closing delimiter is preceded
-by whitespace:
-
-```````````````````````````````` example
-**foo bar **
-.
-<p>**foo bar **</p>
-````````````````````````````````
-
-
-(Nor can it be interpreted as an emphasized `*foo bar *`, because of
-Rule 11.)
-
-This is not strong emphasis, because the second `**` is
-preceded by punctuation and followed by an alphanumeric:
-
-```````````````````````````````` example
-**(**foo)
-.
-<p>**(**foo)</p>
-````````````````````````````````
-
-
-The point of this restriction is more easily appreciated
-with these examples:
-
-```````````````````````````````` example
-*(**foo**)*
-.
-<p><em>(<strong>foo</strong>)</em></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-**Gomphocarpus (*Gomphocarpus physocarpus*, syn.
-*Asclepias physocarpa*)**
-.
-<p><strong>Gomphocarpus (<em>Gomphocarpus physocarpus</em>, syn.
-<em>Asclepias physocarpa</em>)</strong></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-**foo "*bar*" foo**
-.
-<p><strong>foo "<em>bar</em>" foo</strong></p>
-````````````````````````````````
-
-
-Intraword emphasis:
-
-```````````````````````````````` example
-**foo**bar
-.
-<p><strong>foo</strong>bar</p>
-````````````````````````````````
-
-
-Rule 8:
-
-This is not strong emphasis, because the closing delimiter is
-preceded by whitespace:
-
-```````````````````````````````` example
-__foo bar __
-.
-<p>__foo bar __</p>
-````````````````````````````````
-
-
-This is not strong emphasis, because the second `__` is
-preceded by punctuation and followed by an alphanumeric:
-
-```````````````````````````````` example
-__(__foo)
-.
-<p>__(__foo)</p>
-````````````````````````````````
-
-
-The point of this restriction is more easily appreciated
-with this example:
-
-```````````````````````````````` example
-_(__foo__)_
-.
-<p><em>(<strong>foo</strong>)</em></p>
-````````````````````````````````
-
-
-Intraword strong emphasis is forbidden with `__`:
-
-```````````````````````````````` example
-__foo__bar
-.
-<p>__foo__bar</p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-__пристаням__стремятся
-.
-<p>__пристаням__стремятся</p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-__foo__bar__baz__
-.
-<p><strong>foo__bar__baz</strong></p>
-````````````````````````````````
-
-
-This is strong emphasis, even though the closing delimiter is
-both left- and right-flanking, because it is followed by
-punctuation:
-
-```````````````````````````````` example
-__(bar)__.
-.
-<p><strong>(bar)</strong>.</p>
-````````````````````````````````
-
-
-Rule 9:
-
-Any nonempty sequence of inline elements can be the contents of an
-emphasized span.
-
-```````````````````````````````` example
-*foo [bar](/url)*
-.
-<p><em>foo <a href="/url">bar</a></em></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-*foo
-bar*
-.
-<p><em>foo
-bar</em></p>
-````````````````````````````````
-
-
-In particular, emphasis and strong emphasis can be nested
-inside emphasis:
-
-```````````````````````````````` example
-_foo __bar__ baz_
-.
-<p><em>foo <strong>bar</strong> baz</em></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-_foo _bar_ baz_
-.
-<p><em>foo <em>bar</em> baz</em></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-__foo_ bar_
-.
-<p><em><em>foo</em> bar</em></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-*foo *bar**
-.
-<p><em>foo <em>bar</em></em></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-*foo **bar** baz*
-.
-<p><em>foo <strong>bar</strong> baz</em></p>
-````````````````````````````````
-
-
-But note:
-
-```````````````````````````````` example
-*foo**bar**baz*
-.
-<p><em>foo</em><em>bar</em><em>baz</em></p>
-````````````````````````````````
-
-
-The difference is that in the preceding case, the internal delimiters
-[can close emphasis], while in the cases with spaces, they cannot.
-
-```````````````````````````````` example
-***foo** bar*
-.
-<p><em><strong>foo</strong> bar</em></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-*foo **bar***
-.
-<p><em>foo <strong>bar</strong></em></p>
-````````````````````````````````
-
-
-Note, however, that in the following case we get no strong
-emphasis, because the opening delimiter is closed by the first
-`*` before `bar`:
-
-```````````````````````````````` example
-*foo**bar***
-.
-<p><em>foo</em><em>bar</em>**</p>
-````````````````````````````````
-
-
-
-Indefinite levels of nesting are possible:
-
-```````````````````````````````` example
-*foo **bar *baz* bim** bop*
-.
-<p><em>foo <strong>bar <em>baz</em> bim</strong> bop</em></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-*foo [*bar*](/url)*
-.
-<p><em>foo <a href="/url"><em>bar</em></a></em></p>
-````````````````````````````````
-
-
-There can be no empty emphasis or strong emphasis:
-
-```````````````````````````````` example
-** is not an empty emphasis
-.
-<p>** is not an empty emphasis</p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-**** is not an empty strong emphasis
-.
-<p>**** is not an empty strong emphasis</p>
-````````````````````````````````
-
-
-
-Rule 10:
-
-Any nonempty sequence of inline elements can be the contents of an
-strongly emphasized span.
-
-```````````````````````````````` example
-**foo [bar](/url)**
-.
-<p><strong>foo <a href="/url">bar</a></strong></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-**foo
-bar**
-.
-<p><strong>foo
-bar</strong></p>
-````````````````````````````````
-
-
-In particular, emphasis and strong emphasis can be nested
-inside strong emphasis:
-
-```````````````````````````````` example
-__foo _bar_ baz__
-.
-<p><strong>foo <em>bar</em> baz</strong></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-__foo __bar__ baz__
-.
-<p><strong>foo <strong>bar</strong> baz</strong></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-____foo__ bar__
-.
-<p><strong><strong>foo</strong> bar</strong></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-**foo **bar****
-.
-<p><strong>foo <strong>bar</strong></strong></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-**foo *bar* baz**
-.
-<p><strong>foo <em>bar</em> baz</strong></p>
-````````````````````````````````
-
-
-But note:
-
-```````````````````````````````` example
-**foo*bar*baz**
-.
-<p><em><em>foo</em>bar</em>baz**</p>
-````````````````````````````````
-
-
-The difference is that in the preceding case, the internal delimiters
-[can close emphasis], while in the cases with spaces, they cannot.
-
-```````````````````````````````` example
-***foo* bar**
-.
-<p><strong><em>foo</em> bar</strong></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-**foo *bar***
-.
-<p><strong>foo <em>bar</em></strong></p>
-````````````````````````````````
-
-
-Indefinite levels of nesting are possible:
-
-```````````````````````````````` example
-**foo *bar **baz**
-bim* bop**
-.
-<p><strong>foo <em>bar <strong>baz</strong>
-bim</em> bop</strong></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-**foo [*bar*](/url)**
-.
-<p><strong>foo <a href="/url"><em>bar</em></a></strong></p>
-````````````````````````````````
-
-
-There can be no empty emphasis or strong emphasis:
-
-```````````````````````````````` example
-__ is not an empty emphasis
-.
-<p>__ is not an empty emphasis</p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-____ is not an empty strong emphasis
-.
-<p>____ is not an empty strong emphasis</p>
-````````````````````````````````
-
-
-
-Rule 11:
-
-```````````````````````````````` example
-foo ***
-.
-<p>foo ***</p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-foo *\**
-.
-<p>foo <em>*</em></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-foo *_*
-.
-<p>foo <em>_</em></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-foo *****
-.
-<p>foo *****</p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-foo **\***
-.
-<p>foo <strong>*</strong></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-foo **_**
-.
-<p>foo <strong>_</strong></p>
-````````````````````````````````
-
-
-Note that when delimiters do not match evenly, Rule 11 determines
-that the excess literal `*` characters will appear outside of the
-emphasis, rather than inside it:
-
-```````````````````````````````` example
-**foo*
-.
-<p>*<em>foo</em></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-*foo**
-.
-<p><em>foo</em>*</p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-***foo**
-.
-<p>*<strong>foo</strong></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-****foo*
-.
-<p>***<em>foo</em></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-**foo***
-.
-<p><strong>foo</strong>*</p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-*foo****
-.
-<p><em>foo</em>***</p>
-````````````````````````````````
-
-
-
-Rule 12:
-
-```````````````````````````````` example
-foo ___
-.
-<p>foo ___</p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-foo _\__
-.
-<p>foo <em>_</em></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-foo _*_
-.
-<p>foo <em>*</em></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-foo _____
-.
-<p>foo _____</p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-foo __\___
-.
-<p>foo <strong>_</strong></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-foo __*__
-.
-<p>foo <strong>*</strong></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-__foo_
-.
-<p>_<em>foo</em></p>
-````````````````````````````````
-
-
-Note that when delimiters do not match evenly, Rule 12 determines
-that the excess literal `_` characters will appear outside of the
-emphasis, rather than inside it:
-
-```````````````````````````````` example
-_foo__
-.
-<p><em>foo</em>_</p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-___foo__
-.
-<p>_<strong>foo</strong></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-____foo_
-.
-<p>___<em>foo</em></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-__foo___
-.
-<p><strong>foo</strong>_</p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-_foo____
-.
-<p><em>foo</em>___</p>
-````````````````````````````````
-
-
-Rule 13 implies that if you want emphasis nested directly inside
-emphasis, you must use different delimiters:
-
-```````````````````````````````` example
-**foo**
-.
-<p><strong>foo</strong></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-*_foo_*
-.
-<p><em><em>foo</em></em></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-__foo__
-.
-<p><strong>foo</strong></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-_*foo*_
-.
-<p><em><em>foo</em></em></p>
-````````````````````````````````
-
-
-However, strong emphasis within strong emphasis is possible without
-switching delimiters:
-
-```````````````````````````````` example
-****foo****
-.
-<p><strong><strong>foo</strong></strong></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-____foo____
-.
-<p><strong><strong>foo</strong></strong></p>
-````````````````````````````````
-
-
-
-Rule 13 can be applied to arbitrarily long sequences of
-delimiters:
-
-```````````````````````````````` example
-******foo******
-.
-<p><strong><strong><strong>foo</strong></strong></strong></p>
-````````````````````````````````
-
-
-Rule 14:
-
-```````````````````````````````` example
-***foo***
-.
-<p><strong><em>foo</em></strong></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-_____foo_____
-.
-<p><strong><strong><em>foo</em></strong></strong></p>
-````````````````````````````````
-
-
-Rule 15:
-
-```````````````````````````````` example
-*foo _bar* baz_
-.
-<p><em>foo _bar</em> baz_</p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-**foo*bar**
-.
-<p><em><em>foo</em>bar</em>*</p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-*foo __bar *baz bim__ bam*
-.
-<p><em>foo <strong>bar *baz bim</strong> bam</em></p>
-````````````````````````````````
-
-
-Rule 16:
-
-```````````````````````````````` example
-**foo **bar baz**
-.
-<p>**foo <strong>bar baz</strong></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-*foo *bar baz*
-.
-<p>*foo <em>bar baz</em></p>
-````````````````````````````````
-
-
-Rule 17:
-
-```````````````````````````````` example
-*[bar*](/url)
-.
-<p>*<a href="/url">bar*</a></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-_foo [bar_](/url)
-.
-<p>_foo <a href="/url">bar_</a></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-*<img src="foo" title="*"/>
-.
-<p>*<img src="foo" title="*"/></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-**<a href="**">
-.
-<p>**<a href="**"></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-__<a href="__">
-.
-<p>__<a href="__"></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-*a `*`*
-.
-<p><em>a <code>*</code></em></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-_a `_`_
-.
-<p><em>a <code>_</code></em></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-**a<http://foo.bar/?q=**>
-.
-<p>**a<a href="http://foo.bar/?q=**">http://foo.bar/?q=**</a></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-__a<http://foo.bar/?q=__>
-.
-<p>__a<a href="http://foo.bar/?q=__">http://foo.bar/?q=__</a></p>
-````````````````````````````````
-
-
-
-## Links
-
-A link contains [link text] (the visible text), a [link destination]
-(the URI that is the link destination), and optionally a [link title].
-There are two basic kinds of links in Markdown. In [inline links] the
-destination and title are given immediately after the link text. In
-[reference links] the destination and title are defined elsewhere in
-the document.
-
-A [link text](@) consists of a sequence of zero or more
-inline elements enclosed by square brackets (`[` and `]`). The
-following rules apply:
-
-- Links may not contain other links, at any level of nesting. If
- multiple otherwise valid link definitions appear nested inside each
- other, the inner-most definition is used.
-
-- Brackets are allowed in the [link text] only if (a) they
- are backslash-escaped or (b) they appear as a matched pair of brackets,
- with an open bracket `[`, a sequence of zero or more inlines, and
- a close bracket `]`.
-
-- Backtick [code spans], [autolinks], and raw [HTML tags] bind more tightly
- than the brackets in link text. Thus, for example,
- `` [foo`]` `` could not be a link text, since the second `]`
- is part of a code span.
-
-- The brackets in link text bind more tightly than markers for
- [emphasis and strong emphasis]. Thus, for example, `*[foo*](url)` is a link.
-
-A [link destination](@) consists of either
-
-- a sequence of zero or more characters between an opening `<` and a
- closing `>` that contains no spaces, line breaks, or unescaped
- `<` or `>` characters, or
-
-- a nonempty sequence of characters that does not include
- ASCII space or control characters, and includes parentheses
- only if (a) they are backslash-escaped or (b) they are part of
- a balanced pair of unescaped parentheses that is not itself
- inside a balanced pair of unescaped parentheses.
-
-A [link title](@) consists of either
-
-- a sequence of zero or more characters between straight double-quote
- characters (`"`), including a `"` character only if it is
- backslash-escaped, or
-
-- a sequence of zero or more characters between straight single-quote
- characters (`'`), including a `'` character only if it is
- backslash-escaped, or
-
-- a sequence of zero or more characters between matching parentheses
- (`(...)`), including a `)` character only if it is backslash-escaped.
-
-Although [link titles] may span multiple lines, they may not contain
-a [blank line].
-
-An [inline link](@) consists of a [link text] followed immediately
-by a left parenthesis `(`, optional [whitespace], an optional
-[link destination], an optional [link title] separated from the link
-destination by [whitespace], optional [whitespace], and a right
-parenthesis `)`. The link's text consists of the inlines contained
-in the [link text] (excluding the enclosing square brackets).
-The link's URI consists of the link destination, excluding enclosing
-`<...>` if present, with backslash-escapes in effect as described
-above. The link's title consists of the link title, excluding its
-enclosing delimiters, with backslash-escapes in effect as described
-above.
-
-Here is a simple inline link:
-
-```````````````````````````````` example
-[link](/uri "title")
-.
-<p><a href="/uri" title="title">link</a></p>
-````````````````````````````````
-
-
-The title may be omitted:
-
-```````````````````````````````` example
-[link](/uri)
-.
-<p><a href="/uri">link</a></p>
-````````````````````````````````
-
-
-Both the title and the destination may be omitted:
-
-```````````````````````````````` example
-[link]()
-.
-<p><a href="">link</a></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-[link](<>)
-.
-<p><a href="">link</a></p>
-````````````````````````````````
-
-
-The destination cannot contain spaces or line breaks,
-even if enclosed in pointy brackets:
-
-```````````````````````````````` example
-[link](/my uri)
-.
-<p>[link](/my uri)</p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-[link](</my uri>)
-.
-<p>[link](</my uri>)</p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-[link](foo
-bar)
-.
-<p>[link](foo
-bar)</p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-[link](<foo
-bar>)
-.
-<p>[link](<foo
-bar>)</p>
-````````````````````````````````
-
-Parentheses inside the link destination may be escaped:
-
-```````````````````````````````` example
-[link](\(foo\))
-.
-<p><a href="(foo)">link</a></p>
-````````````````````````````````
-
-One level of balanced parentheses is allowed without escaping:
-
-```````````````````````````````` example
-[link]((foo)and(bar))
-.
-<p><a href="(foo)and(bar)">link</a></p>
-````````````````````````````````
-
-However, if you have parentheses within parentheses, you need to escape
-or use the `<...>` form:
-
-```````````````````````````````` example
-[link](foo(and(bar)))
-.
-<p>[link](foo(and(bar)))</p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-[link](foo(and\(bar\)))
-.
-<p><a href="foo(and(bar))">link</a></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-[link](<foo(and(bar))>)
-.
-<p><a href="foo(and(bar))">link</a></p>
-````````````````````````````````
-
-
-Parentheses and other symbols can also be escaped, as usual
-in Markdown:
-
-```````````````````````````````` example
-[link](foo\)\:)
-.
-<p><a href="foo):">link</a></p>
-````````````````````````````````
-
-
-A link can contain fragment identifiers and queries:
-
-```````````````````````````````` example
-[link](#fragment)
-
-[link](http://example.com#fragment)
-
-[link](http://example.com?foo=3#frag)
-.
-<p><a href="#fragment">link</a></p>
-<p><a href="http://example.com#fragment">link</a></p>
-<p><a href="http://example.com?foo=3#frag">link</a></p>
-````````````````````````````````
-
-
-Note that a backslash before a non-escapable character is
-just a backslash:
-
-```````````````````````````````` example
-[link](foo\bar)
-.
-<p><a href="foo%5Cbar">link</a></p>
-````````````````````````````````
-
-
-URL-escaping should be left alone inside the destination, as all
-URL-escaped characters are also valid URL characters. Entity and
-numerical character references in the destination will be parsed
-into the corresponding Unicode code points, as usual. These may
-be optionally URL-escaped when written as HTML, but this spec
-does not enforce any particular policy for rendering URLs in
-HTML or other formats. Renderers may make different decisions
-about how to escape or normalize URLs in the output.
-
-```````````````````````````````` example
-[link](foo%20bä)
-.
-<p><a href="foo%20b%C3%A4">link</a></p>
-````````````````````````````````
-
-
-Note that, because titles can often be parsed as destinations,
-if you try to omit the destination and keep the title, you'll
-get unexpected results:
-
-```````````````````````````````` example
-[link]("title")
-.
-<p><a href="%22title%22">link</a></p>
-````````````````````````````````
-
-
-Titles may be in single quotes, double quotes, or parentheses:
-
-```````````````````````````````` example
-[link](/url "title")
-[link](/url 'title')
-[link](/url (title))
-.
-<p><a href="/url" title="title">link</a>
-<a href="/url" title="title">link</a>
-<a href="/url" title="title">link</a></p>
-````````````````````````````````
-
-
-Backslash escapes and entity and numeric character references
-may be used in titles:
-
-```````````````````````````````` example
-[link](/url "title \""")
-.
-<p><a href="/url" title="title """>link</a></p>
-````````````````````````````````
-
-
-Nested balanced quotes are not allowed without escaping:
-
-```````````````````````````````` example
-[link](/url "title "and" title")
-.
-<p>[link](/url "title "and" title")</p>
-````````````````````````````````
-
-
-But it is easy to work around this by using a different quote type:
-
-```````````````````````````````` example
-[link](/url 'title "and" title')
-.
-<p><a href="/url" title="title "and" title">link</a></p>
-````````````````````````````````
-
-
-(Note: `Markdown.pl` did allow double quotes inside a double-quoted
-title, and its test suite included a test demonstrating this.
-But it is hard to see a good rationale for the extra complexity this
-brings, since there are already many ways---backslash escaping,
-entity and numeric character references, or using a different
-quote type for the enclosing title---to write titles containing
-double quotes. `Markdown.pl`'s handling of titles has a number
-of other strange features. For example, it allows single-quoted
-titles in inline links, but not reference links. And, in
-reference links but not inline links, it allows a title to begin
-with `"` and end with `)`. `Markdown.pl` 1.0.1 even allows
-titles with no closing quotation mark, though 1.0.2b8 does not.
-It seems preferable to adopt a simple, rational rule that works
-the same way in inline links and link reference definitions.)
-
-[Whitespace] is allowed around the destination and title:
-
-```````````````````````````````` example
-[link]( /uri
- "title" )
-.
-<p><a href="/uri" title="title">link</a></p>
-````````````````````````````````
-
-
-But it is not allowed between the link text and the
-following parenthesis:
-
-```````````````````````````````` example
-[link] (/uri)
-.
-<p>[link] (/uri)</p>
-````````````````````````````````
-
-
-The link text may contain balanced brackets, but not unbalanced ones,
-unless they are escaped:
-
-```````````````````````````````` example
-[link [foo [bar]]](/uri)
-.
-<p><a href="/uri">link [foo [bar]]</a></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-[link] bar](/uri)
-.
-<p>[link] bar](/uri)</p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-[link [bar](/uri)
-.
-<p>[link <a href="/uri">bar</a></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-[link \[bar](/uri)
-.
-<p><a href="/uri">link [bar</a></p>
-````````````````````````````````
-
-
-The link text may contain inline content:
-
-```````````````````````````````` example
-[link *foo **bar** `#`*](/uri)
-.
-<p><a href="/uri">link <em>foo <strong>bar</strong> <code>#</code></em></a></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-[![moon](moon.jpg)](/uri)
-.
-<p><a href="/uri"><img src="moon.jpg" alt="moon" /></a></p>
-````````````````````````````````
-
-
-However, links may not contain other links, at any level of nesting.
-
-```````````````````````````````` example
-[foo [bar](/uri)](/uri)
-.
-<p>[foo <a href="/uri">bar</a>](/uri)</p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-[foo *[bar [baz](/uri)](/uri)*](/uri)
-.
-<p>[foo <em>[bar <a href="/uri">baz</a>](/uri)</em>](/uri)</p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-![[[foo](uri1)](uri2)](uri3)
-.
-<p><img src="uri3" alt="[foo](uri2)" /></p>
-````````````````````````````````
-
-
-These cases illustrate the precedence of link text grouping over
-emphasis grouping:
-
-```````````````````````````````` example
-*[foo*](/uri)
-.
-<p>*<a href="/uri">foo*</a></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-[foo *bar](baz*)
-.
-<p><a href="baz*">foo *bar</a></p>
-````````````````````````````````
-
-
-Note that brackets that *aren't* part of links do not take
-precedence:
-
-```````````````````````````````` example
-*foo [bar* baz]
-.
-<p><em>foo [bar</em> baz]</p>
-````````````````````````````````
-
-
-These cases illustrate the precedence of HTML tags, code spans,
-and autolinks over link grouping:
-
-```````````````````````````````` example
-[foo <bar attr="](baz)">
-.
-<p>[foo <bar attr="](baz)"></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-[foo`](/uri)`
-.
-<p>[foo<code>](/uri)</code></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-[foo<http://example.com/?search=](uri)>
-.
-<p>[foo<a href="http://example.com/?search=%5D(uri)">http://example.com/?search=](uri)</a></p>
-````````````````````````````````
-
-
-There are three kinds of [reference link](@)s:
-[full](#full-reference-link), [collapsed](#collapsed-reference-link),
-and [shortcut](#shortcut-reference-link).
-
-A [full reference link](@)
-consists of a [link text] immediately followed by a [link label]
-that [matches] a [link reference definition] elsewhere in the document.
-
-A [link label](@) begins with a left bracket (`[`) and ends
-with the first right bracket (`]`) that is not backslash-escaped.
-Between these brackets there must be at least one [non-whitespace character].
-Unescaped square bracket characters are not allowed in
-[link labels]. A link label can have at most 999
-characters inside the square brackets.
-
-One label [matches](@)
-another just in case their normalized forms are equal. To normalize a
-label, perform the *Unicode case fold* and collapse consecutive internal
-[whitespace] to a single space. If there are multiple
-matching reference link definitions, the one that comes first in the
-document is used. (It is desirable in such cases to emit a warning.)
-
-The contents of the first link label are parsed as inlines, which are
-used as the link's text. The link's URI and title are provided by the
-matching [link reference definition].
-
-Here is a simple example:
-
-```````````````````````````````` example
-[foo][bar]
-
-[bar]: /url "title"
-.
-<p><a href="/url" title="title">foo</a></p>
-````````````````````````````````
-
-
-The rules for the [link text] are the same as with
-[inline links]. Thus:
-
-The link text may contain balanced brackets, but not unbalanced ones,
-unless they are escaped:
-
-```````````````````````````````` example
-[link [foo [bar]]][ref]
-
-[ref]: /uri
-.
-<p><a href="/uri">link [foo [bar]]</a></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-[link \[bar][ref]
-
-[ref]: /uri
-.
-<p><a href="/uri">link [bar</a></p>
-````````````````````````````````
-
-
-The link text may contain inline content:
-
-```````````````````````````````` example
-[link *foo **bar** `#`*][ref]
-
-[ref]: /uri
-.
-<p><a href="/uri">link <em>foo <strong>bar</strong> <code>#</code></em></a></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-[![moon](moon.jpg)][ref]
-
-[ref]: /uri
-.
-<p><a href="/uri"><img src="moon.jpg" alt="moon" /></a></p>
-````````````````````````````````
-
-
-However, links may not contain other links, at any level of nesting.
-
-```````````````````````````````` example
-[foo [bar](/uri)][ref]
-
-[ref]: /uri
-.
-<p>[foo <a href="/uri">bar</a>]<a href="/uri">ref</a></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-[foo *bar [baz][ref]*][ref]
-
-[ref]: /uri
-.
-<p>[foo <em>bar <a href="/uri">baz</a></em>]<a href="/uri">ref</a></p>
-````````````````````````````````
-
-
-(In the examples above, we have two [shortcut reference links]
-instead of one [full reference link].)
-
-The following cases illustrate the precedence of link text grouping over
-emphasis grouping:
-
-```````````````````````````````` example
-*[foo*][ref]
-
-[ref]: /uri
-.
-<p>*<a href="/uri">foo*</a></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-[foo *bar][ref]
-
-[ref]: /uri
-.
-<p><a href="/uri">foo *bar</a></p>
-````````````````````````````````
-
-
-These cases illustrate the precedence of HTML tags, code spans,
-and autolinks over link grouping:
-
-```````````````````````````````` example
-[foo <bar attr="][ref]">
-
-[ref]: /uri
-.
-<p>[foo <bar attr="][ref]"></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-[foo`][ref]`
-
-[ref]: /uri
-.
-<p>[foo<code>][ref]</code></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-[foo<http://example.com/?search=][ref]>
-
-[ref]: /uri
-.
-<p>[foo<a href="http://example.com/?search=%5D%5Bref%5D">http://example.com/?search=][ref]</a></p>
-````````````````````````````````
-
-
-Matching is case-insensitive:
-
-```````````````````````````````` example
-[foo][BaR]
-
-[bar]: /url "title"
-.
-<p><a href="/url" title="title">foo</a></p>
-````````````````````````````````
-
-
-Unicode case fold is used:
-
-```````````````````````````````` example
-[Толпой][Толпой] is a Russian word.
-
-[ТОЛПОЙ]: /url
-.
-<p><a href="/url">Толпой</a> is a Russian word.</p>
-````````````````````````````````
-
-
-Consecutive internal [whitespace] is treated as one space for
-purposes of determining matching:
-
-```````````````````````````````` example
-[Foo
- bar]: /url
-
-[Baz][Foo bar]
-.
-<p><a href="/url">Baz</a></p>
-````````````````````````````````
-
-
-No [whitespace] is allowed between the [link text] and the
-[link label]:
-
-```````````````````````````````` example
-[foo] [bar]
-
-[bar]: /url "title"
-.
-<p>[foo] <a href="/url" title="title">bar</a></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-[foo]
-[bar]
-
-[bar]: /url "title"
-.
-<p>[foo]
-<a href="/url" title="title">bar</a></p>
-````````````````````````````````
-
-
-This is a departure from John Gruber's original Markdown syntax
-description, which explicitly allows whitespace between the link
-text and the link label. It brings reference links in line with
-[inline links], which (according to both original Markdown and
-this spec) cannot have whitespace after the link text. More
-importantly, it prevents inadvertent capture of consecutive
-[shortcut reference links]. If whitespace is allowed between the
-link text and the link label, then in the following we will have
-a single reference link, not two shortcut reference links, as
-intended:
-
-``` markdown
-[foo]
-[bar]
-
-[foo]: /url1
-[bar]: /url2
-```
-
-(Note that [shortcut reference links] were introduced by Gruber
-himself in a beta version of `Markdown.pl`, but never included
-in the official syntax description. Without shortcut reference
-links, it is harmless to allow space between the link text and
-link label; but once shortcut references are introduced, it is
-too dangerous to allow this, as it frequently leads to
-unintended results.)
-
-When there are multiple matching [link reference definitions],
-the first is used:
-
-```````````````````````````````` example
-[foo]: /url1
-
-[foo]: /url2
-
-[bar][foo]
-.
-<p><a href="/url1">bar</a></p>
-````````````````````````````````
-
-
-Note that matching is performed on normalized strings, not parsed
-inline content. So the following does not match, even though the
-labels define equivalent inline content:
-
-```````````````````````````````` example
-[bar][foo\!]
-
-[foo!]: /url
-.
-<p>[bar][foo!]</p>
-````````````````````````````````
-
-
-[Link labels] cannot contain brackets, unless they are
-backslash-escaped:
-
-```````````````````````````````` example
-[foo][ref[]
-
-[ref[]: /uri
-.
-<p>[foo][ref[]</p>
-<p>[ref[]: /uri</p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-[foo][ref[bar]]
-
-[ref[bar]]: /uri
-.
-<p>[foo][ref[bar]]</p>
-<p>[ref[bar]]: /uri</p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-[[[foo]]]
-
-[[[foo]]]: /url
-.
-<p>[[[foo]]]</p>
-<p>[[[foo]]]: /url</p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-[foo][ref\[]
-
-[ref\[]: /uri
-.
-<p><a href="/uri">foo</a></p>
-````````````````````````````````
-
-
-Note that in this example `]` is not backslash-escaped:
-
-```````````````````````````````` example
-[bar\\]: /uri
-
-[bar\\]
-.
-<p><a href="/uri">bar\</a></p>
-````````````````````````````````
-
-
-A [link label] must contain at least one [non-whitespace character]:
-
-```````````````````````````````` example
-[]
-
-[]: /uri
-.
-<p>[]</p>
-<p>[]: /uri</p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-[
- ]
-
-[
- ]: /uri
-.
-<p>[
-]</p>
-<p>[
-]: /uri</p>
-````````````````````````````````
-
-
-A [collapsed reference link](@)
-consists of a [link label] that [matches] a
-[link reference definition] elsewhere in the
-document, followed by the string `[]`.
-The contents of the first link label are parsed as inlines,
-which are used as the link's text. The link's URI and title are
-provided by the matching reference link definition. Thus,
-`[foo][]` is equivalent to `[foo][foo]`.
-
-```````````````````````````````` example
-[foo][]
-
-[foo]: /url "title"
-.
-<p><a href="/url" title="title">foo</a></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-[*foo* bar][]
-
-[*foo* bar]: /url "title"
-.
-<p><a href="/url" title="title"><em>foo</em> bar</a></p>
-````````````````````````````````
-
-
-The link labels are case-insensitive:
-
-```````````````````````````````` example
-[Foo][]
-
-[foo]: /url "title"
-.
-<p><a href="/url" title="title">Foo</a></p>
-````````````````````````````````
-
-
-
-As with full reference links, [whitespace] is not
-allowed between the two sets of brackets:
-
-```````````````````````````````` example
-[foo]
-[]
-
-[foo]: /url "title"
-.
-<p><a href="/url" title="title">foo</a>
-[]</p>
-````````````````````````````````
-
-
-A [shortcut reference link](@)
-consists of a [link label] that [matches] a
-[link reference definition] elsewhere in the
-document and is not followed by `[]` or a link label.
-The contents of the first link label are parsed as inlines,
-which are used as the link's text. the link's URI and title
-are provided by the matching link reference definition.
-Thus, `[foo]` is equivalent to `[foo][]`.
-
-```````````````````````````````` example
-[foo]
-
-[foo]: /url "title"
-.
-<p><a href="/url" title="title">foo</a></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-[*foo* bar]
-
-[*foo* bar]: /url "title"
-.
-<p><a href="/url" title="title"><em>foo</em> bar</a></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-[[*foo* bar]]
-
-[*foo* bar]: /url "title"
-.
-<p>[<a href="/url" title="title"><em>foo</em> bar</a>]</p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-[[bar [foo]
-
-[foo]: /url
-.
-<p>[[bar <a href="/url">foo</a></p>
-````````````````````````````````
-
-
-The link labels are case-insensitive:
-
-```````````````````````````````` example
-[Foo]
-
-[foo]: /url "title"
-.
-<p><a href="/url" title="title">Foo</a></p>
-````````````````````````````````
-
-
-A space after the link text should be preserved:
-
-```````````````````````````````` example
-[foo] bar
-
-[foo]: /url
-.
-<p><a href="/url">foo</a> bar</p>
-````````````````````````````````
-
-
-If you just want bracketed text, you can backslash-escape the
-opening bracket to avoid links:
-
-```````````````````````````````` example
-\[foo]
-
-[foo]: /url "title"
-.
-<p>[foo]</p>
-````````````````````````````````
-
-
-Note that this is a link, because a link label ends with the first
-following closing bracket:
-
-```````````````````````````````` example
-[foo*]: /url
-
-*[foo*]
-.
-<p>*<a href="/url">foo*</a></p>
-````````````````````````````````
-
-
-Full references take precedence over shortcut references:
-
-```````````````````````````````` example
-[foo][bar]
-
-[foo]: /url1
-[bar]: /url2
-.
-<p><a href="/url2">foo</a></p>
-````````````````````````````````
-
-
-In the following case `[bar][baz]` is parsed as a reference,
-`[foo]` as normal text:
-
-```````````````````````````````` example
-[foo][bar][baz]
-
-[baz]: /url
-.
-<p>[foo]<a href="/url">bar</a></p>
-````````````````````````````````
-
-
-Here, though, `[foo][bar]` is parsed as a reference, since
-`[bar]` is defined:
-
-```````````````````````````````` example
-[foo][bar][baz]
-
-[baz]: /url1
-[bar]: /url2
-.
-<p><a href="/url2">foo</a><a href="/url1">baz</a></p>
-````````````````````````````````
-
-
-Here `[foo]` is not parsed as a shortcut reference, because it
-is followed by a link label (even though `[bar]` is not defined):
-
-```````````````````````````````` example
-[foo][bar][baz]
-
-[baz]: /url1
-[foo]: /url2
-.
-<p>[foo]<a href="/url1">bar</a></p>
-````````````````````````````````
-
-
-
-## Images
-
-Syntax for images is like the syntax for links, with one
-difference. Instead of [link text], we have an
-[image description](@). The rules for this are the
-same as for [link text], except that (a) an
-image description starts with `![` rather than `[`, and
-(b) an image description may contain links.
-An image description has inline elements
-as its contents. When an image is rendered to HTML,
-this is standardly used as the image's `alt` attribute.
-
-```````````````````````````````` example
-![foo](/url "title")
-.
-<p><img src="/url" alt="foo" title="title" /></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-![foo *bar*]
-
-[foo *bar*]: train.jpg "train & tracks"
-.
-<p><img src="train.jpg" alt="foo bar" title="train & tracks" /></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-![foo ![bar](/url)](/url2)
-.
-<p><img src="/url2" alt="foo bar" /></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-![foo [bar](/url)](/url2)
-.
-<p><img src="/url2" alt="foo bar" /></p>
-````````````````````````````````
-
-
-Though this spec is concerned with parsing, not rendering, it is
-recommended that in rendering to HTML, only the plain string content
-of the [image description] be used. Note that in
-the above example, the alt attribute's value is `foo bar`, not `foo
-[bar](/url)` or `foo <a href="/url">bar</a>`. Only the plain string
-content is rendered, without formatting.
-
-```````````````````````````````` example
-![foo *bar*][]
-
-[foo *bar*]: train.jpg "train & tracks"
-.
-<p><img src="train.jpg" alt="foo bar" title="train & tracks" /></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-![foo *bar*][foobar]
-
-[FOOBAR]: train.jpg "train & tracks"
-.
-<p><img src="train.jpg" alt="foo bar" title="train & tracks" /></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-![foo](train.jpg)
-.
-<p><img src="train.jpg" alt="foo" /></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-My ![foo bar](/path/to/train.jpg "title" )
-.
-<p>My <img src="/path/to/train.jpg" alt="foo bar" title="title" /></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-![foo](<url>)
-.
-<p><img src="url" alt="foo" /></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-![](/url)
-.
-<p><img src="/url" alt="" /></p>
-````````````````````````````````
-
-
-Reference-style:
-
-```````````````````````````````` example
-![foo][bar]
-
-[bar]: /url
-.
-<p><img src="/url" alt="foo" /></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-![foo][bar]
-
-[BAR]: /url
-.
-<p><img src="/url" alt="foo" /></p>
-````````````````````````````````
-
-
-Collapsed:
-
-```````````````````````````````` example
-![foo][]
-
-[foo]: /url "title"
-.
-<p><img src="/url" alt="foo" title="title" /></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-![*foo* bar][]
-
-[*foo* bar]: /url "title"
-.
-<p><img src="/url" alt="foo bar" title="title" /></p>
-````````````````````````````````
-
-
-The labels are case-insensitive:
-
-```````````````````````````````` example
-![Foo][]
-
-[foo]: /url "title"
-.
-<p><img src="/url" alt="Foo" title="title" /></p>
-````````````````````````````````
-
-
-As with reference links, [whitespace] is not allowed
-between the two sets of brackets:
-
-```````````````````````````````` example
-![foo]
-[]
-
-[foo]: /url "title"
-.
-<p><img src="/url" alt="foo" title="title" />
-[]</p>
-````````````````````````````````
-
-
-Shortcut:
-
-```````````````````````````````` example
-![foo]
-
-[foo]: /url "title"
-.
-<p><img src="/url" alt="foo" title="title" /></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-![*foo* bar]
-
-[*foo* bar]: /url "title"
-.
-<p><img src="/url" alt="foo bar" title="title" /></p>
-````````````````````````````````
-
-
-Note that link labels cannot contain unescaped brackets:
-
-```````````````````````````````` example
-![[foo]]
-
-[[foo]]: /url "title"
-.
-<p>![[foo]]</p>
-<p>[[foo]]: /url "title"</p>
-````````````````````````````````
-
-
-The link labels are case-insensitive:
-
-```````````````````````````````` example
-![Foo]
-
-[foo]: /url "title"
-.
-<p><img src="/url" alt="Foo" title="title" /></p>
-````````````````````````````````
-
-
-If you just want bracketed text, you can backslash-escape the
-opening `!` and `[`:
-
-```````````````````````````````` example
-\!\[foo]
-
-[foo]: /url "title"
-.
-<p>![foo]</p>
-````````````````````````````````
-
-
-If you want a link after a literal `!`, backslash-escape the
-`!`:
-
-```````````````````````````````` example
-\![foo]
-
-[foo]: /url "title"
-.
-<p>!<a href="/url" title="title">foo</a></p>
-````````````````````````````````
-
-
-## Autolinks
-
-[Autolink](@)s are absolute URIs and email addresses inside
-`<` and `>`. They are parsed as links, with the URL or email address
-as the link label.
-
-A [URI autolink](@) consists of `<`, followed by an
-[absolute URI] not containing `<`, followed by `>`. It is parsed as
-a link to the URI, with the URI as the link's label.
-
-An [absolute URI](@),
-for these purposes, consists of a [scheme] followed by a colon (`:`)
-followed by zero or more characters other than ASCII
-[whitespace] and control characters, `<`, and `>`. If
-the URI includes these characters, they must be percent-encoded
-(e.g. `%20` for a space).
-
-For purposes of this spec, a [scheme](@) is any sequence
-of 2--32 characters beginning with an ASCII letter and followed
-by any combination of ASCII letters, digits, or the symbols plus
-("+"), period ("."), or hyphen ("-").
-
-Here are some valid autolinks:
-
-```````````````````````````````` example
-<http://foo.bar.baz>
-.
-<p><a href="http://foo.bar.baz">http://foo.bar.baz</a></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-<http://foo.bar.baz/test?q=hello&id=22&boolean>
-.
-<p><a href="http://foo.bar.baz/test?q=hello&id=22&boolean">http://foo.bar.baz/test?q=hello&id=22&boolean</a></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-<irc://foo.bar:2233/baz>
-.
-<p><a href="irc://foo.bar:2233/baz">irc://foo.bar:2233/baz</a></p>
-````````````````````````````````
-
-
-Uppercase is also fine:
-
-```````````````````````````````` example
-<MAILTO:FOO@BAR.BAZ>
-.
-<p><a href="MAILTO:FOO@BAR.BAZ">MAILTO:FOO@BAR.BAZ</a></p>
-````````````````````````````````
-
-
-Note that many strings that count as [absolute URIs] for
-purposes of this spec are not valid URIs, because their
-schemes are not registered or because of other problems
-with their syntax:
-
-```````````````````````````````` example
-<a+b+c:d>
-.
-<p><a href="a+b+c:d">a+b+c:d</a></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-<made-up-scheme://foo,bar>
-.
-<p><a href="made-up-scheme://foo,bar">made-up-scheme://foo,bar</a></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-<http://../>
-.
-<p><a href="http://../">http://../</a></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-<localhost:5001/foo>
-.
-<p><a href="localhost:5001/foo">localhost:5001/foo</a></p>
-````````````````````````````````
-
-
-Spaces are not allowed in autolinks:
-
-```````````````````````````````` example
-<http://foo.bar/baz bim>
-.
-<p><http://foo.bar/baz bim></p>
-````````````````````````````````
-
-
-Backslash-escapes do not work inside autolinks:
-
-```````````````````````````````` example
-<http://example.com/\[\>
-.
-<p><a href="http://example.com/%5C%5B%5C">http://example.com/\[\</a></p>
-````````````````````````````````
-
-
-An [email autolink](@)
-consists of `<`, followed by an [email address],
-followed by `>`. The link's label is the email address,
-and the URL is `mailto:` followed by the email address.
-
-An [email address](@),
-for these purposes, is anything that matches
-the [non-normative regex from the HTML5
-spec](https://html.spec.whatwg.org/multipage/forms.html#e-mail-state-(type=email)):
-
- /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?
- (?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/
-
-Examples of email autolinks:
-
-```````````````````````````````` example
-<foo@bar.example.com>
-.
-<p><a href="mailto:foo@bar.example.com">foo@bar.example.com</a></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-<foo+special@Bar.baz-bar0.com>
-.
-<p><a href="mailto:foo+special@Bar.baz-bar0.com">foo+special@Bar.baz-bar0.com</a></p>
-````````````````````````````````
-
-
-Backslash-escapes do not work inside email autolinks:
-
-```````````````````````````````` example
-<foo\+@bar.example.com>
-.
-<p><foo+@bar.example.com></p>
-````````````````````````````````
-
-
-These are not autolinks:
-
-```````````````````````````````` example
-<>
-.
-<p><></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-< http://foo.bar >
-.
-<p>< http://foo.bar ></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-<m:abc>
-.
-<p><m:abc></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-<foo.bar.baz>
-.
-<p><foo.bar.baz></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-http://example.com
-.
-<p>http://example.com</p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-foo@bar.example.com
-.
-<p>foo@bar.example.com</p>
-````````````````````````````````
-
-
-## Raw HTML
-
-Text between `<` and `>` that looks like an HTML tag is parsed as a
-raw HTML tag and will be rendered in HTML without escaping.
-Tag and attribute names are not limited to current HTML tags,
-so custom tags (and even, say, DocBook tags) may be used.
-
-Here is the grammar for tags:
-
-A [tag name](@) consists of an ASCII letter
-followed by zero or more ASCII letters, digits, or
-hyphens (`-`).
-
-An [attribute](@) consists of [whitespace],
-an [attribute name], and an optional
-[attribute value specification].
-
-An [attribute name](@)
-consists of an ASCII letter, `_`, or `:`, followed by zero or more ASCII
-letters, digits, `_`, `.`, `:`, or `-`. (Note: This is the XML
-specification restricted to ASCII. HTML5 is laxer.)
-
-An [attribute value specification](@)
-consists of optional [whitespace],
-a `=` character, optional [whitespace], and an [attribute
-value].
-
-An [attribute value](@)
-consists of an [unquoted attribute value],
-a [single-quoted attribute value], or a [double-quoted attribute value].
-
-An [unquoted attribute value](@)
-is a nonempty string of characters not
-including spaces, `"`, `'`, `=`, `<`, `>`, or `` ` ``.
-
-A [single-quoted attribute value](@)
-consists of `'`, zero or more
-characters not including `'`, and a final `'`.
-
-A [double-quoted attribute value](@)
-consists of `"`, zero or more
-characters not including `"`, and a final `"`.
-
-An [open tag](@) consists of a `<` character, a [tag name],
-zero or more [attributes], optional [whitespace], an optional `/`
-character, and a `>` character.
-
-A [closing tag](@) consists of the string `</`, a
-[tag name], optional [whitespace], and the character `>`.
-
-An [HTML comment](@) consists of `<!--` + *text* + `-->`,
-where *text* does not start with `>` or `->`, does not end with `-`,
-and does not contain `--`. (See the
-[HTML5 spec](http://www.w3.org/TR/html5/syntax.html#comments).)
-
-A [processing instruction](@)
-consists of the string `<?`, a string
-of characters not including the string `?>`, and the string
-`?>`.
-
-A [declaration](@) consists of the
-string `<!`, a name consisting of one or more uppercase ASCII letters,
-[whitespace], a string of characters not including the
-character `>`, and the character `>`.
-
-A [CDATA section](@) consists of
-the string `<![CDATA[`, a string of characters not including the string
-`]]>`, and the string `]]>`.
-
-An [HTML tag](@) consists of an [open tag], a [closing tag],
-an [HTML comment], a [processing instruction], a [declaration],
-or a [CDATA section].
-
-Here are some simple open tags:
-
-```````````````````````````````` example
-<a><bab><c2c>
-.
-<p><a><bab><c2c></p>
-````````````````````````````````
-
-
-Empty elements:
-
-```````````````````````````````` example
-<a/><b2/>
-.
-<p><a/><b2/></p>
-````````````````````````````````
-
-
-[Whitespace] is allowed:
-
-```````````````````````````````` example
-<a /><b2
-data="foo" >
-.
-<p><a /><b2
-data="foo" ></p>
-````````````````````````````````
-
-
-With attributes:
-
-```````````````````````````````` example
-<a foo="bar" bam = 'baz <em>"</em>'
-_boolean zoop:33=zoop:33 />
-.
-<p><a foo="bar" bam = 'baz <em>"</em>'
-_boolean zoop:33=zoop:33 /></p>
-````````````````````````````````
-
-
-Custom tag names can be used:
-
-```````````````````````````````` example
-Foo <responsive-image src="foo.jpg" />
-.
-<p>Foo <responsive-image src="foo.jpg" /></p>
-````````````````````````````````
-
-
-Illegal tag names, not parsed as HTML:
-
-```````````````````````````````` example
-<33> <__>
-.
-<p><33> <__></p>
-````````````````````````````````
-
-
-Illegal attribute names:
-
-```````````````````````````````` example
-<a h*#ref="hi">
-.
-<p><a h*#ref="hi"></p>
-````````````````````````````````
-
-
-Illegal attribute values:
-
-```````````````````````````````` example
-<a href="hi'> <a href=hi'>
-.
-<p><a href="hi'> <a href=hi'></p>
-````````````````````````````````
-
-
-Illegal [whitespace]:
-
-```````````````````````````````` example
-< a><
-foo><bar/ >
-.
-<p>< a><
-foo><bar/ ></p>
-````````````````````````````````
-
-
-Missing [whitespace]:
-
-```````````````````````````````` example
-<a href='bar'title=title>
-.
-<p><a href='bar'title=title></p>
-````````````````````````````````
-
-
-Closing tags:
-
-```````````````````````````````` example
-</a></foo >
-.
-<p></a></foo ></p>
-````````````````````````````````
-
-
-Illegal attributes in closing tag:
-
-```````````````````````````````` example
-</a href="foo">
-.
-<p></a href="foo"></p>
-````````````````````````````````
-
-
-Comments:
-
-```````````````````````````````` example
-foo <!-- this is a
-comment - with hyphen -->
-.
-<p>foo <!-- this is a
-comment - with hyphen --></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-foo <!-- not a comment -- two hyphens -->
-.
-<p>foo <!-- not a comment -- two hyphens --></p>
-````````````````````````````````
-
-
-Not comments:
-
-```````````````````````````````` example
-foo <!--> foo -->
-
-foo <!-- foo--->
-.
-<p>foo <!--> foo --></p>
-<p>foo <!-- foo---></p>
-````````````````````````````````
-
-
-Processing instructions:
-
-```````````````````````````````` example
-foo <?php echo $a; ?>
-.
-<p>foo <?php echo $a; ?></p>
-````````````````````````````````
-
-
-Declarations:
-
-```````````````````````````````` example
-foo <!ELEMENT br EMPTY>
-.
-<p>foo <!ELEMENT br EMPTY></p>
-````````````````````````````````
-
-
-CDATA sections:
-
-```````````````````````````````` example
-foo <![CDATA[>&<]]>
-.
-<p>foo <![CDATA[>&<]]></p>
-````````````````````````````````
-
-
-Entity and numeric character references are preserved in HTML
-attributes:
-
-```````````````````````````````` example
-foo <a href="ö">
-.
-<p>foo <a href="ö"></p>
-````````````````````````````````
-
-
-Backslash escapes do not work in HTML attributes:
-
-```````````````````````````````` example
-foo <a href="\*">
-.
-<p>foo <a href="\*"></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-<a href="\"">
-.
-<p><a href="""></p>
-````````````````````````````````
-
-
-## Hard line breaks
-
-A line break (not in a code span or HTML tag) that is preceded
-by two or more spaces and does not occur at the end of a block
-is parsed as a [hard line break](@) (rendered
-in HTML as a `<br />` tag):
-
-```````````````````````````````` example
-foo
-baz
-.
-<p>foo<br />
-baz</p>
-````````````````````````````````
-
-
-For a more visible alternative, a backslash before the
-[line ending] may be used instead of two spaces:
-
-```````````````````````````````` example
-foo\
-baz
-.
-<p>foo<br />
-baz</p>
-````````````````````````````````
-
-
-More than two spaces can be used:
-
-```````````````````````````````` example
-foo
-baz
-.
-<p>foo<br />
-baz</p>
-````````````````````````````````
-
-
-Leading spaces at the beginning of the next line are ignored:
-
-```````````````````````````````` example
-foo
- bar
-.
-<p>foo<br />
-bar</p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-foo\
- bar
-.
-<p>foo<br />
-bar</p>
-````````````````````````````````
-
-
-Line breaks can occur inside emphasis, links, and other constructs
-that allow inline content:
-
-```````````````````````````````` example
-*foo
-bar*
-.
-<p><em>foo<br />
-bar</em></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-*foo\
-bar*
-.
-<p><em>foo<br />
-bar</em></p>
-````````````````````````````````
-
-
-Line breaks do not occur inside code spans
-
-```````````````````````````````` example
-`code
-span`
-.
-<p><code>code span</code></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-`code\
-span`
-.
-<p><code>code\ span</code></p>
-````````````````````````````````
-
-
-or HTML tags:
-
-```````````````````````````````` example
-<a href="foo
-bar">
-.
-<p><a href="foo
-bar"></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-<a href="foo\
-bar">
-.
-<p><a href="foo\
-bar"></p>
-````````````````````````````````
-
-
-Hard line breaks are for separating inline content within a block.
-Neither syntax for hard line breaks works at the end of a paragraph or
-other block element:
-
-```````````````````````````````` example
-foo\
-.
-<p>foo\</p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-foo
-.
-<p>foo</p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-### foo\
-.
-<h3>foo\</h3>
-````````````````````````````````
-
-
-```````````````````````````````` example
-### foo
-.
-<h3>foo</h3>
-````````````````````````````````
-
-
-## Soft line breaks
-
-A regular line break (not in a code span or HTML tag) that is not
-preceded by two or more spaces or a backslash is parsed as a
-softbreak. (A softbreak may be rendered in HTML either as a
-[line ending] or as a space. The result will be the same in
-browsers. In the examples here, a [line ending] will be used.)
-
-```````````````````````````````` example
-foo
-baz
-.
-<p>foo
-baz</p>
-````````````````````````````````
-
-
-Spaces at the end of the line and beginning of the next line are
-removed:
-
-```````````````````````````````` example
-foo
- baz
-.
-<p>foo
-baz</p>
-````````````````````````````````
-
-
-A conforming parser may render a soft line break in HTML either as a
-line break or as a space.
-
-A renderer may also provide an option to render soft line breaks
-as hard line breaks.
-
-## Textual content
-
-Any characters not given an interpretation by the above rules will
-be parsed as plain textual content.
-
-```````````````````````````````` example
-hello $.;'there
-.
-<p>hello $.;'there</p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-Foo χρῆν
-.
-<p>Foo χρῆν</p>
-````````````````````````````````
-
-
-Internal spaces are preserved verbatim:
-
-```````````````````````````````` example
-Multiple spaces
-.
-<p>Multiple spaces</p>
-````````````````````````````````
-
-
-<!-- END TESTS -->
-
-# Appendix: A parsing strategy
-
-In this appendix we describe some features of the parsing strategy
-used in the CommonMark reference implementations.
-
-## Overview
-
-Parsing has two phases:
-
-1. In the first phase, lines of input are consumed and the block
-structure of the document---its division into paragraphs, block quotes,
-list items, and so on---is constructed. Text is assigned to these
-blocks but not parsed. Link reference definitions are parsed and a
-map of links is constructed.
-
-2. In the second phase, the raw text contents of paragraphs and headings
-are parsed into sequences of Markdown inline elements (strings,
-code spans, links, emphasis, and so on), using the map of link
-references constructed in phase 1.
-
-At each point in processing, the document is represented as a tree of
-**blocks**. The root of the tree is a `document` block. The `document`
-may have any number of other blocks as **children**. These children
-may, in turn, have other blocks as children. The last child of a block
-is normally considered **open**, meaning that subsequent lines of input
-can alter its contents. (Blocks that are not open are **closed**.)
-Here, for example, is a possible document tree, with the open blocks
-marked by arrows:
-
-``` tree
--> document
- -> block_quote
- paragraph
- "Lorem ipsum dolor\nsit amet."
- -> list (type=bullet tight=true bullet_char=-)
- list_item
- paragraph
- "Qui *quodsi iracundia*"
- -> list_item
- -> paragraph
- "aliquando id"
-```
-
-## Phase 1: block structure
-
-Each line that is processed has an effect on this tree. The line is
-analyzed and, depending on its contents, the document may be altered
-in one or more of the following ways:
-
-1. One or more open blocks may be closed.
-2. One or more new blocks may be created as children of the
- last open block.
-3. Text may be added to the last (deepest) open block remaining
- on the tree.
-
-Once a line has been incorporated into the tree in this way,
-it can be discarded, so input can be read in a stream.
-
-For each line, we follow this procedure:
-
-1. First we iterate through the open blocks, starting with the
-root document, and descending through last children down to the last
-open block. Each block imposes a condition that the line must satisfy
-if the block is to remain open. For example, a block quote requires a
-`>` character. A paragraph requires a non-blank line.
-In this phase we may match all or just some of the open
-blocks. But we cannot close unmatched blocks yet, because we may have a
-[lazy continuation line].
-
-2. Next, after consuming the continuation markers for existing
-blocks, we look for new block starts (e.g. `>` for a block quote.
-If we encounter a new block start, we close any blocks unmatched
-in step 1 before creating the new block as a child of the last
-matched block.
-
-3. Finally, we look at the remainder of the line (after block
-markers like `>`, list markers, and indentation have been consumed).
-This is text that can be incorporated into the last open
-block (a paragraph, code block, heading, or raw HTML).
-
-Setext headings are formed when we see a line of a paragraph
-that is a [setext heading underline].
-
-Reference link definitions are detected when a paragraph is closed;
-the accumulated text lines are parsed to see if they begin with
-one or more reference link definitions. Any remainder becomes a
-normal paragraph.
-
-We can see how this works by considering how the tree above is
-generated by four lines of Markdown:
-
-``` markdown
-> Lorem ipsum dolor
-sit amet.
-> - Qui *quodsi iracundia*
-> - aliquando id
-```
-
-At the outset, our document model is just
-
-``` tree
--> document
-```
-
-The first line of our text,
-
-``` markdown
-> Lorem ipsum dolor
-```
-
-causes a `block_quote` block to be created as a child of our
-open `document` block, and a `paragraph` block as a child of
-the `block_quote`. Then the text is added to the last open
-block, the `paragraph`:
-
-``` tree
--> document
- -> block_quote
- -> paragraph
- "Lorem ipsum dolor"
-```
-
-The next line,
-
-``` markdown
-sit amet.
-```
-
-is a "lazy continuation" of the open `paragraph`, so it gets added
-to the paragraph's text:
-
-``` tree
--> document
- -> block_quote
- -> paragraph
- "Lorem ipsum dolor\nsit amet."
-```
-
-The third line,
-
-``` markdown
-> - Qui *quodsi iracundia*
-```
-
-causes the `paragraph` block to be closed, and a new `list` block
-opened as a child of the `block_quote`. A `list_item` is also
-added as a child of the `list`, and a `paragraph` as a child of
-the `list_item`. The text is then added to the new `paragraph`:
-
-``` tree
--> document
- -> block_quote
- paragraph
- "Lorem ipsum dolor\nsit amet."
- -> list (type=bullet tight=true bullet_char=-)
- -> list_item
- -> paragraph
- "Qui *quodsi iracundia*"
-```
-
-The fourth line,
-
-``` markdown
-> - aliquando id
-```
-
-causes the `list_item` (and its child the `paragraph`) to be closed,
-and a new `list_item` opened up as child of the `list`. A `paragraph`
-is added as a child of the new `list_item`, to contain the text.
-We thus obtain the final tree:
-
-``` tree
--> document
- -> block_quote
- paragraph
- "Lorem ipsum dolor\nsit amet."
- -> list (type=bullet tight=true bullet_char=-)
- list_item
- paragraph
- "Qui *quodsi iracundia*"
- -> list_item
- -> paragraph
- "aliquando id"
-```
-
-## Phase 2: inline structure
-
-Once all of the input has been parsed, all open blocks are closed.
-
-We then "walk the tree," visiting every node, and parse raw
-string contents of paragraphs and headings as inlines. At this
-point we have seen all the link reference definitions, so we can
-resolve reference links as we go.
-
-``` tree
-document
- block_quote
- paragraph
- str "Lorem ipsum dolor"
- softbreak
- str "sit amet."
- list (type=bullet tight=true bullet_char=-)
- list_item
- paragraph
- str "Qui "
- emph
- str "quodsi iracundia"
- list_item
- paragraph
- str "aliquando id"
-```
-
-Notice how the [line ending] in the first paragraph has
-been parsed as a `softbreak`, and the asterisks in the first list item
-have become an `emph`.
-
-### An algorithm for parsing nested emphasis and links
-
-By far the trickiest part of inline parsing is handling emphasis,
-strong emphasis, links, and images. This is done using the following
-algorithm.
-
-When we're parsing inlines and we hit either
-
-- a run of `*` or `_` characters, or
-- a `[` or `![`
-
-we insert a text node with these symbols as its literal content, and we
-add a pointer to this text node to the [delimiter stack](@).
-
-The [delimiter stack] is a doubly linked list. Each
-element contains a pointer to a text node, plus information about
-
-- the type of delimiter (`[`, `![`, `*`, `_`)
-- the number of delimiters,
-- whether the delimiter is "active" (all are active to start), and
-- whether the delimiter is a potential opener, a potential closer,
- or both (which depends on what sort of characters precede
- and follow the delimiters).
-
-When we hit a `]` character, we call the *look for link or image*
-procedure (see below).
-
-When we hit the end of the input, we call the *process emphasis*
-procedure (see below), with `stack_bottom` = NULL.
-
-#### *look for link or image*
-
-Starting at the top of the delimiter stack, we look backwards
-through the stack for an opening `[` or `![` delimiter.
-
-- If we don't find one, we return a literal text node `]`.
-
-- If we do find one, but it's not *active*, we remove the inactive
- delimiter from the stack, and return a literal text node `]`.
-
-- If we find one and it's active, then we parse ahead to see if
- we have an inline link/image, reference link/image, compact reference
- link/image, or shortcut reference link/image.
-
- + If we don't, then we remove the opening delimiter from the
- delimiter stack and return a literal text node `]`.
-
- + If we do, then
-
- * We return a link or image node whose children are the inlines
- after the text node pointed to by the opening delimiter.
-
- * We run *process emphasis* on these inlines, with the `[` opener
- as `stack_bottom`.
-
- * We remove the opening delimiter.
-
- * If we have a link (and not an image), we also set all
- `[` delimiters before the opening delimiter to *inactive*. (This
- will prevent us from getting links within links.)
-
-#### *process emphasis*
-
-Parameter `stack_bottom` sets a lower bound to how far we
-descend in the [delimiter stack]. If it is NULL, we can
-go all the way to the bottom. Otherwise, we stop before
-visiting `stack_bottom`.
-
-Let `current_position` point to the element on the [delimiter stack]
-just above `stack_bottom` (or the first element if `stack_bottom`
-is NULL).
-
-We keep track of the `openers_bottom` for each delimiter
-type (`*`, `_`). Initialize this to `stack_bottom`.
-
-Then we repeat the following until we run out of potential
-closers:
-
-- Move `current_position` forward in the delimiter stack (if needed)
- until we find the first potential closer with delimiter `*` or `_`.
- (This will be the potential closer closest
- to the beginning of the input -- the first one in parse order.)
-
-- Now, look back in the stack (staying above `stack_bottom` and
- the `openers_bottom` for this delimiter type) for the
- first matching potential opener ("matching" means same delimiter).
-
-- If one is found:
-
- + Figure out whether we have emphasis or strong emphasis:
- if both closer and opener spans have length >= 2, we have
- strong, otherwise regular.
-
- + Insert an emph or strong emph node accordingly, after
- the text node corresponding to the opener.
-
- + Remove any delimiters between the opener and closer from
- the delimiter stack.
-
- + Remove 1 (for regular emph) or 2 (for strong emph) delimiters
- from the opening and closing text nodes. If they become empty
- as a result, remove them and remove the corresponding element
- of the delimiter stack. If the closing node is removed, reset
- `current_position` to the next element in the stack.
-
-- If none in found:
-
- + Set `openers_bottom` to the element before `current_position`.
- (We know that there are no openers for this kind of closer up to and
- including this point, so this puts a lower bound on future searches.)
-
- + If the closer at `current_position` is not a potential opener,
- remove it from the delimiter stack (since we know it can't
- be a closer either).
-
- + Advance `current_position` to the next element in the stack.
-
-After we're done, we remove all delimiters above `stack_bottom` from the
-delimiter stack.
-
+++ /dev/null
-import "Prelude"\r
-\r
-main :: Double -> Double\r
-main m = loop 1 0\r
- where\r
- loop x cur = if x > m\r
- then cur\r
- else loop (x+1) (cur + 1 / x)
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-main :: Integer -> Double\r
-main m = sum [1/(fromInteger x) | x <- [1..m]]\r
+++ /dev/null
-\r
-\r
-class Show a where\r
- show :: a -> String\r
- \r
-class Read a where\r
- read :: String -> a\r
- \r
-combine x = show (read x)\r
---\r
-9:13-9:17: Constrain Show a contains free variables not mentioned in the type of the value.\r
-9:19-9:23: Constrain Read a contains free variables not mentioned in the type of the value.
\ No newline at end of file
+++ /dev/null
-main = "Hello" "world!"\r
---\r
-1:8-1:24: Application of non-function.\r
+++ /dev/null
-\r
-data Foo a = Foo a\r
-\r
-f :: Foo a -> a\r
-f = \Foo a -> a \r
-\r
-main = "Not to be executed"\r
---\r
-5:6-5:11: Arity is 1 but 2 patterns have been given.
\ No newline at end of file
+++ /dev/null
-import "JavaBuiltin" as Java\r
-\r
-sort p@(a,b) | Java.icmpgt a b = (b,a)\r
- | True = p\r
- \r
-main = sort (sort (2 :: Integer,1 :: Integer))\r
---\r
-(1,2)
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-main = do \r
- a1 = 1\r
- a2 = 1\r
- a3 = 1\r
- a4 = 1\r
- a5 = 1\r
- a6 = 1\r
- a7 = 1\r
- a8 = 1\r
- a9 = 1\r
- a10 = 1\r
- a11 = 1\r
- a12 = 1\r
- a13 = 1\r
- a14 = 1\r
- a15 = 1\r
- a16 = 1\r
- a17 = 1\r
- a18 = 1\r
- a19 = 1\r
- a20 = 1\r
- f x = x + a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10 + \r
- a11 + a12 + a13 + a14 + a15 + a16 + a17 + a18 + a19 + a20\r
- f 10\r
---\r
-30
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-f a b c d e f g h = a + b + c + d + e + f + g + h\r
-\r
-main = (id f) 1 2 3 4 5 6 7 8\r
---\r
-36
\ No newline at end of file
+++ /dev/null
-\r
-class Foo a where\r
- foo :: a\r
- \r
-class (Foo a) => Bar a where\r
- bar :: a\r
- \r
-instance Bar Double where\r
- foo x = x\r
- bar x = x\r
- \r
-main = foo 3.0 + bar 4.0\r
---\r
-7.0\r
-\r
-
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-data E = E String\r
-\r
-instance Additive E where\r
- zero = E "0"\r
- E a + E b = E ("(" + a + "+" + b + ")")\r
- \r
-instance Ring E where\r
- one = E "1"\r
- neg (E a) = E ("(-" + a + ")")\r
- E a - E b = E ("(" + a + "-" + b + ")")\r
- E a * E b = E ("(" + a + "*" + b + ")") \r
- fromInteger x = E (show x)\r
-\r
-eToString (E a) = a\r
-\r
-a = E "a"\r
-b = E "b"\r
-c = E "c"\r
-d = E "d"\r
-\r
-main = eToString (-a + b + (-c*d))\r
---\r
-(((-a)+b)+(-(c*d)))
\ No newline at end of file
+++ /dev/null
-main = _\r
---\r
-???
\ No newline at end of file
+++ /dev/null
-@private\r
-@inline\r
-not True = False\r
-not False = True\r
-\r
-@private\r
-@inline\r
-id x = not (not x)\r
-\r
-main = id True\r
---\r
-true
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-csvWrite :: String -> [[String]] -> <Proc> ()\r
-csvWrite fname rows = ()\r
-\r
-/// Like writeEntries but with a transformer function also for values.\r
-/// kfun key + vfun value should have the length of header.\r
-writeEntries' :: (k -> [String]) -> (v -> [String])\r
- -> String -> [String] -> [(k, v)] -> <Proc> ()\r
-writeEntries' kfun vfun fname header rows =\r
- csvWrite fname $ [header] + [kfun k + vfun v | (k, v) <- rows]\r
- \r
-main = "OK"\r
---\r
-OK
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-main = subChar '6' '0'\r
---\r
-6\r
+++ /dev/null
-\r
-class A a where\r
- foo :: a\r
- \r
-class A a where\r
- bar :: a\r
---\r
-5:1-6:13: Class A has already been defined in this module.
\ No newline at end of file
+++ /dev/null
-\r
-data A = A\r
-data A = B\r
---\r
-3:1-3:11: Type A has already been defined in this module.
\ No newline at end of file
+++ /dev/null
-import "JavaBuiltin" as Java\r
-\r
-infixl 6 (+)\r
-\r
-class Additive a where \r
- (+) :: a -> a -> a \r
- \r
-instance Additive Double where\r
- (+) = Java.dadd\r
-\r
-instance Additive Double where\r
- (+) = Java.dadd\r
---\r
-11:1-12:20: Duplicate definition of the instance Additive Double.
\ No newline at end of file
+++ /dev/null
-a = 1\r
-a = 2\r
-main = "Should not be executed."\r
---\r
-???
\ No newline at end of file
+++ /dev/null
-\r
-id :: Integer -> Integer\r
-id :: Double -> Double\r
-id x = x\r
---\r
-3:1-3:23: Type of id has already been declared in this module.
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-f x = if x `mod` 2 == 0\r
- then x `div` 2\r
- else 3*x + 1\r
-fd x = unfoldr (\x -> do\r
- r = f x \r
- if x == 1\r
- then Nothing\r
- else Just (x,r)\r
- ) x\r
-\r
-//main :: [Integer] \r
-main = fd 7\r
---\r
-[7, 22, 11, 34, 17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2]
\ No newline at end of file
+++ /dev/null
-import "JavaBuiltin" as Java\r
-\r
-(+) = Java.iadd\r
-(-) = Java.isub\r
-(*) = Java.imul\r
-\r
-data List a = Nil | Cons a (List a) \r
-\r
-compose :: List (a -> a) -> a -> a\r
-compose Nil x = x\r
-compose (Cons h t) x = compose t (h x)\r
-\r
-succ x = x + 1\r
-prec x = x - 1\r
-double x = x * 2\r
-\r
-f = compose (Cons succ (Cons double (Cons prec Nil)))\r
-main = f 13\r
---\r
-27
\ No newline at end of file
+++ /dev/null
-infixr 9 (.)\r
-\r
-@private\r
-@inline\r
-(f . g) = \x -> f (g x)\r
-\r
-@private\r
-@inline\r
-flip (x,y) = (y,x)\r
-\r
-@private\r
-@inline\r
-flip4 = flip . flip . flip . flip\r
-\r
-main = flip4 ("a", "b")\r
---\r
-(a,b)
\ No newline at end of file
+++ /dev/null
-(&&) :: Boolean -> (<e> Boolean) -> <e> Boolean\r
-a && b = if a then b else False\r
-\r
-main = False && fail "Should not be evaluated!"\r
---\r
-false
\ No newline at end of file
+++ /dev/null
-\r
-a = 14 :: Integer\r
-\r
-main = a\r
---\r
-14
\ No newline at end of file
+++ /dev/null
-\r
-data Vec2 = Vec2 Double Double\r
-data Vec3 = Vec2 Double Double Double\r
-\r
-main = "Not to be executed."\r
---\r
-3:13-3:38: Value Vec2 is already defined.
\ No newline at end of file
+++ /dev/null
-import "JavaBuiltin" as Java\r
-\r
-class Ord a where\r
- (<) :: a -> a -> Boolean\r
- min :: a -> a -> a\r
- min x y = if x < y then x else y\r
- \r
-instance Ord Integer where\r
- (<) = Java.icmplt\r
-\r
-main = min (43 :: Integer) (69 :: Integer) \r
---\r
-43
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-a,b,c,d :: Either Boolean Boolean\r
-a = Left False\r
-b = Left True \r
-c = Right False\r
-d = Right True\r
-\r
-main = a == a\r
- && a < b\r
- && a < c\r
- && a < d\r
- \r
- && b > a\r
- && b == b\r
- && b < c\r
- && b < d\r
-\r
- && c > a\r
- && c > b\r
- && c == c\r
- && c < d\r
-\r
- && d > a\r
- && d > b\r
- && d > c\r
- && d == d\r
---\r
-true
\ No newline at end of file
+++ /dev/null
-import "Prelude"
-
-data Foo = Foo Integer Long Double Float
-
-deriving instance Show Foo
-
-main = show (Foo (-1) (-1) (-1) (-1))
---
-Foo (-1) (-1) (-1.0) (-1.0)
\ No newline at end of file
+++ /dev/null
-import "Prelude"
-
-foo n = n
- where
- if n > 0
- then 1
- else "asd"
-
-bar n = n
- where
- do
- c = n+1
- if c > 0
- then 1
- else "asd"
-
-main = foo 3 + bar 3
---
-6
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-main = 7 `div` 3\r
---\r
-2
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-f :: Float\r
-f = 1.0\r
-\r
-d :: Double\r
-d = 1.0\r
-\r
-d2f :: Float\r
-d2f = fromDouble d\r
-\r
-f2d :: Double\r
-f2d = toDouble f\r
-\r
-main = show (d+f2d, f+d2f)\r
---\r
-(2.0, 2.0)
\ No newline at end of file
+++ /dev/null
-app :: (Integer -> <e1> Integer) -> <e1> ((Integer -> <e2> Integer) -> <e2> Integer)\r
-app f = do\r
- a = f 1\r
- \g -> g a\r
- \r
-main = app (\x -> x) (\x -> x)\r
---\r
-1
\ No newline at end of file
+++ /dev/null
-import "JavaBuiltin" as Java\r
-\r
-importJava "java.util.regex.Pattern" where\r
- data Pattern\r
-\r
- compile :: String -> Pattern\r
- matcher :: Pattern -> String -> <Proc> Matcher\r
-\r
-importJava "java.util.regex.Matcher" where\r
- data Matcher\r
-\r
- matches :: Matcher -> <Proc> Boolean\r
-\r
-doMatch pattern text = matches (matcher pattern text)\r
-\r
-main = doMatch (compile ".*xxx.*") "fffxxooxxxlll"\r
---\r
-true
\ No newline at end of file
+++ /dev/null
-import "JavaBuiltin" as Java\r
-\r
-importJava "java.util.List" where\r
- data List a\r
-\r
- add :: List a -> a -> <Proc> Boolean\r
-\r
-importJava "java.util.ArrayList" where\r
- @JavaName "<init>"\r
- arrayList :: Integer -> <Proc> List a\r
-\r
-singleton :: a -> <Proc> List a\r
-singleton el = result\r
- where\r
- result = arrayList 1\r
- r = add result el\r
-\r
-main :: List Integer\r
-main = runProc (singleton (13 :: Integer))\r
---\r
-[13]
\ No newline at end of file
+++ /dev/null
-effectfulId :: a -> <Proc> a\r
-effectfulId x = x\r
-\r
-(.) :: (b -> <e> c) -> (a -> <e> b) -> a -> <e> c\r
-(f . g) x = f (g x)\r
-\r
-doubleId = effectfulId . effectfulId\r
-\r
-main :: Integer\r
-main = runProc (doubleId (13 :: Integer))\r
---\r
-13
\ No newline at end of file
+++ /dev/null
-effectfulId :: a -> <Proc> a\r
-effectfulId x = x\r
-\r
-//double :: (a -> <e> a) -> a -> <e> a\r
-double f x = f (f x)\r
-\r
-doubleId = double effectfulId\r
-\r
-main :: Integer\r
-main = runProc (doubleId (13 :: Integer))\r
---\r
-13
\ No newline at end of file
+++ /dev/null
-effectfulId :: a -> <Proc> a\r
-effectfulId x = x\r
-\r
-(.) :: (b -> <e2> c) -> (a -> <e1> b) -> a -> <e1,e2> c\r
-(f . g) x = f (g x)\r
-\r
-//doubleId :: a -> <Proc> a\r
-doubleId = effectfulId . effectfulId\r
-\r
-main :: Integer\r
-main = runProc (doubleId (13 :: Integer))\r
---\r
-13
\ No newline at end of file
+++ /dev/null
-effectfulId :: a -> <Proc> a\r
-effectfulId x = x\r
-\r
-(.) :: (b -> <e2> c) -> (a -> <e1> b) -> a -> <e1,e2> c\r
-(f . g) x = f (g x)\r
-\r
-doubleId :: a -> <Proc> a\r
-doubleId = effectfulId . effectfulId\r
-\r
-main :: Integer\r
-main = runProc (doubleId (13 :: Integer))\r
---\r
-13
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-ex1 = let in 1\r
-ex2 = let {} in 2\r
-ex3 = let {a=3} in a \r
-\r
-main = ex1 + ex2 + ex3\r
---\r
-6
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-main = """\r
-\(newEq () ())\r
-\(newEq True True)\r
-\(newEq False False)\r
-\(newEq True False)\r
-\(newEq False True)\r
-\(newEq (1::Integer) (1::Integer))\r
-\(newEq (1::Integer) (2::Integer))\r
-\(newEq (1::Long) (1::Long))\r
-\(newEq (1::Long) (2::Long))\r
-\(newEq (1::Double) (1::Double))\r
-\(newEq (1::Double) (2::Double))\r
-\(newEq "a" "a")\r
-\(newEq "a" "b")\r
-\(newEq (Just "a") (Just "a"))\r
-\(newEq (Just "a") (Just "b"))\r
-\(newEq Nothing Nothing)\r
-\(newEq (Just "a") Nothing)\r
-\(newEq Nothing (Just "a"))\r
-"""\r
---\r
-True\r
-True\r
-True\r
-False\r
-False\r
-True\r
-False\r
-True\r
-False\r
-True\r
-False\r
-True\r
-False\r
-True\r
-False\r
-True\r
-False\r
-False
\ No newline at end of file
+++ /dev/null
-import "Prelude"
-import "Expressions/Equations"
-
-main = v
- where
- v = solveEquations do
- listenEquationVariable "a" $ \a -> setEquationVariable "c" (a-1)
- setEquationVariable "a" 123
- listenEquationVariable "a" $ \a -> setEquationVariable "b" (a+1)
- print v
---
-[(a,123), (b,124), (c,122)]
-
+++ /dev/null
-import "JavaBuiltin" as Java\r
-\r
-(+) = Java.iadd\r
-\r
-data Thunk a = /* forall s. */ Thunk s (s -> a)\r
-\r
-id :: a -> a\r
-id x = x\r
-\r
-runThunk :: Thunk a -> a\r
-runThunk (Thunk s f) = f s\r
-\r
-makeThunk :: a -> Thunk a\r
-makeThunk x = Thunk x id\r
-\r
-mapThunk :: (a -> b) -> Thunk a -> Thunk b\r
-mapThunk f (Thunk s g) = Thunk s (\x -> f (g x))\r
-\r
-a = makeThunk (13 :: Integer)\r
-b = mapThunk (\x -> x+1) a\r
-main = runThunk b\r
---\r
-14
\ No newline at end of file
+++ /dev/null
-data Thunk a = /* forall s. */ Thunk s (s -> a)\r
-\r
-mixThunks (Thunk s0 f0) (Thunk s1 f1) = f0 s1\r
-\r
-main = "Not to be executed!"\r
---\r
-3:44-3:46: Expected <a> got <b>.
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-data Exp = Exp String\r
-\r
-expToString :: Exp -> String\r
-expToString (Exp s) = s\r
-\r
-instance Additive Exp where\r
- zero = Exp "0"\r
- Exp a + Exp b = Exp ("(" + a + " + " + b + ")")\r
-\r
-instance Ring Exp where\r
- one = Exp "1"\r
- neg (Exp a) = Exp ("(-" + a + ")")\r
- Exp a * Exp b = Exp ("(" + a + " * " + b + ")")\r
- Exp a - Exp b = Exp ("(" + a + " - " + b + ")")\r
- fromInteger x = Exp (show x)\r
- \r
-a = Exp "a"\r
-b = Exp "b"\r
-c = Exp "c"\r
-d = Exp "d"\r
-e = Exp "e"\r
-\r
-main = expToString (a + b*c + d*e)\r
---\r
-((a + (b * c)) + (d * e))
\ No newline at end of file
+++ /dev/null
-fib n = fib\r
---\r
-1:9-1:12: Expected <a> got <b -> <c> a>.
\ No newline at end of file
+++ /dev/null
-import "JavaBuiltin" as Java\r
-\r
-(+) = Java.iadd\r
-(-) = Java.isub\r
-(<=) = Java.icmple\r
-\r
-fibonacci x = if x <= (1 :: Integer) \r
- then 1 :: Integer \r
- else fibonacci (x - 1) \r
- + fibonacci (x - 2)\r
-\r
-main = fibonacci 10\r
---\r
-89
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-fibonacci :: Integer -> Integer\r
-fibonacci x = if x <= 1 \r
- then 1 \r
- else fibonacci (x - 1) \r
- + fibonacci (x - 2)\r
-\r
-main = fibonacci 10\r
---\r
-89
\ No newline at end of file
+++ /dev/null
-import "JavaBuiltin" as Java\r
- \r
-class Num a where\r
- (+) :: a -> a -> a\r
- (-) :: a -> a -> a\r
-\r
-instance Num Integer where\r
- (+) = Java.iadd\r
- (-) = Java.isub\r
-\r
-(<=) = Java.icmple\r
-\r
-fibonacci x = if x <= (1 :: Integer) \r
- then 1 :: Integer\r
- else fibonacci (x - (1 :: Integer)) \r
- + fibonacci (x - (2 :: Integer))\r
-\r
-main = fibonacci 10\r
---\r
-89
\ No newline at end of file
+++ /dev/null
-import "JavaBuiltin" as Java\r
-\r
-main = foldl Java.iadd (0 :: Integer) (concat (concat (Single (1 :: Integer)) \r
- (Single (2 :: Integer))) (Single (3 :: Integer))) \r
-\r
-data Digit a = Digit1 a\r
- | Digit2 a a\r
- | Digit3 a a a\r
- | Digit4 a a a a\r
-data Node a = Node2 a a | Node3 a a a\r
-data FingerTree a = Empty | Single a | Deep (Digit a) (FingerTree (Node a)) (Digit a)\r
-\r
-insertL :: a -> FingerTree a -> FingerTree a\r
-insertL a Empty = Single a\r
-insertL a (Single b) = Deep (Digit1 a) Empty (Digit1 b)\r
-insertL a (Deep (Digit1 b) m r) = Deep (Digit2 a b) m r\r
-insertL a (Deep (Digit2 b c) m r) = Deep (Digit3 a b c) m r\r
-insertL a (Deep (Digit3 b c d) m r) = Deep (Digit4 a b c d) m r\r
-insertL a (Deep (Digit4 b c d e) m r) = Deep (Digit2 a b) (insertL (Node3 c d e) m) r\r
-\r
-insertR :: FingerTree a -> a -> FingerTree a\r
-insertR Empty a = Single a\r
-insertR (Single a) b = Deep (Digit1 a) Empty (Digit1 b)\r
-insertR (Deep l m (Digit1 a)) b = Deep l m (Digit2 a b)\r
-insertR (Deep l m (Digit2 a b)) c = Deep l m (Digit3 a b c)\r
-insertR (Deep l m (Digit3 a b c)) d = Deep l m (Digit4 a b c d)\r
-insertR (Deep l m (Digit4 a b c d)) e = Deep l (insertR m (Node3 a b c)) (Digit2 d e)\r
-\r
-foldl :: (a -> b -> a) -> a -> FingerTree b -> a\r
-foldl f init Empty = init\r
-foldl f init (Single x) = f init x\r
-foldl f init (Deep l m r) = foldlD (foldl foldlN (foldlD init l) m) r\r
- where\r
- foldlD init (Digit1 a) = f init a\r
- foldlD init (Digit2 a b) = f (f init a) b\r
- foldlD init (Digit3 a b c) = f (f (f init a) b) c\r
- foldlD init (Digit4 a b c d) = f (f (f (f init a) b) c) d\r
- \r
- foldlN init (Node2 a b) = f (f init a) b\r
- foldlN init (Node3 a b c) = f (f (f init a) b) c\r
-\r
-data View a = Nil | Cons a (FingerTree a)\r
-\r
-viewL :: FingerTree a -> View a\r
-viewL Empty = Nil\r
-viewL (Single a) = Cons a Empty\r
-viewL (Deep (Digit1 a) m r) = Cons a tail\r
- where\r
- tail = match viewL m with\r
- Nil -> digitToFingerTree r\r
- Cons h t -> Deep (nodeToDigit h) t r\r
-viewL (Deep (Digit2 a b) m r) = Cons a (Deep (Digit1 a) m r)\r
-viewL (Deep (Digit3 a b c) m r) = Cons a (Deep (Digit2 a b) m r)\r
-viewL (Deep (Digit4 a b c d) m r) = Cons a (Deep (Digit3 a b c) m r)\r
-\r
-concat :: FingerTree a -> FingerTree a -> FingerTree a\r
-concat Empty a = a\r
-concat a Empty = a\r
-concat (Single a) b = insertL a b\r
-concat a (Single b) = insertR a b\r
-concat (Deep l1 m1 r1) (Deep l2 m2 r2) = Deep l1 mm r2\r
- where\r
- mm = concatAux m1 (digitsToNodes r1 l2) m2\r
- \r
-// --- Implementation details -------------------------------------------------\r
-\r
-digitToFingerTree :: Digit a -> FingerTree a\r
-digitToFingerTree (Digit1 a) = Single a\r
-digitToFingerTree (Digit2 a b) = Deep (Digit1 a) Empty (Digit1 b)\r
-digitToFingerTree (Digit3 a b c) = Deep (Digit2 a b) Empty (Digit1 c)\r
-digitToFingerTree (Digit4 a b c d) = Deep (Digit2 a b) Empty (Digit2 c d)\r
-\r
-nodeToDigit :: Node a -> Digit a\r
-nodeToDigit (Node2 a b) = Digit2 a b\r
-nodeToDigit (Node3 a b c) = Digit3 a b c\r
- \r
-concatAux :: FingerTree a -> Digit a -> FingerTree a -> FingerTree a\r
-concatAux Empty ds a = insertLD ds a\r
-concatAux a ds Empty = insertRD a ds\r
-concatAux (Single a) ds b = insertL a (insertLD ds b)\r
-concatAux a ds (Single b) = insertR (insertRD a ds) b\r
-concatAux (Deep l1 m1 r1) ds (Deep l2 m2 r2) = Deep l1 mm r2\r
- where\r
- mm = concatAux m1 (digitsToNodes3 r1 ds r2) m2\r
-\r
-insertLD :: Digit a -> FingerTree a -> FingerTree a\r
-insertLD (Digit1 a) t = insertL a t\r
-insertLD (Digit2 a b) t = insertL a (insertL b t)\r
-insertLD (Digit3 a b c) t = insertL a (insertL b (insertL c t))\r
-insertLD (Digit4 a b c d) t = insertL a (insertL b (insertL c (insertL d t)))\r
-\r
-insertRD :: FingerTree a -> Digit a -> FingerTree a\r
-insertRD t (Digit1 a) = insertR t a\r
-insertRD t (Digit2 a b) = insertR (insertR t a) b\r
-insertRD t (Digit3 a b c) = insertR (insertR (insertR t a) b) c\r
-insertRD t (Digit4 a b c d) = insertR (insertR (insertR (insertR t a) b) c) d\r
- \r
-digitsToNodes :: Digit a -> Digit a -> Digit (Node a)\r
-digitsToNodes (Digit1 a) x = dd1 a x\r
-digitsToNodes (Digit2 a b) x = dd2 a b x \r
-digitsToNodes (Digit3 a b c) x = dd3 a b c x\r
-digitsToNodes (Digit4 a b c d) x = dd4 a b c d x \r
-\r
-digitsToNodes3 :: Digit a -> Digit a -> Digit a -> Digit (Node a)\r
-digitsToNodes3 (Digit1 a) x y = ddd1 a x y\r
-digitsToNodes3 (Digit2 a b) x y = ddd2 a b x y\r
-digitsToNodes3 (Digit3 a b c) x y = ddd3 a b c x y\r
-digitsToNodes3 (Digit4 a b c d) x y = ddd4 a b c d x y \r
- \r
-d2 a b = Digit1 (Node2 a b)\r
-d3 a b c = Digit1 (Node3 a b c)\r
-d4 a b c d = Digit2 (Node2 a b) (Node2 c d)\r
-d5 a b c d e = Digit2 (Node3 a b c) (Node2 d e)\r
-d6 a b c d e f = Digit2 (Node3 a b c) (Node3 d e f)\r
-d7 a b c d e f g = Digit3 (Node3 a b c) (Node2 d e) (Node2 f g)\r
-d8 a b c d e f g h = Digit3 (Node3 a b c) (Node3 d e f) (Node2 g h)\r
-d9 a b c d e f g h i = Digit3 (Node3 a b c) (Node3 d e f) (Node3 g h i)\r
-d10 a b c d e f g h i j = Digit4 (Node3 a b c) (Node3 d e f) (Node2 g h) (Node2 i j)\r
-d11 a b c d e f g h i j k = Digit4 (Node3 a b c) (Node3 d e f) (Node3 g h i) (Node2 j k)\r
-d12 a b c d e f g h i j k l = Digit4 (Node3 a b c) (Node3 d e f) (Node3 g h i) (Node3 j k l)\r
-\r
-dd1 a (Digit1 b) = d2 a b\r
-dd1 a (Digit2 b c) = d3 a b c\r
-dd1 a (Digit3 b c d) = d4 a b c d\r
-dd1 a (Digit4 b c d e) = d5 a b c d e\r
-dd2 a b (Digit1 c) = d3 a b c\r
-dd2 a b (Digit2 c d) = d4 a b c d\r
-dd2 a b (Digit3 c d e) = d5 a b c d e\r
-dd2 a b (Digit4 c d e f) = d6 a b c d e f\r
-dd3 a b c (Digit1 d) = d4 a b c d\r
-dd3 a b c (Digit2 d e) = d5 a b c d e\r
-dd3 a b c (Digit3 d e f) = d6 a b c d e f\r
-dd3 a b c (Digit4 d e f g) = d7 a b c d e f g\r
-dd4 a b c d (Digit1 e) = d5 a b c d e\r
-dd4 a b c d (Digit2 e f) = d6 a b c d e f\r
-dd4 a b c d (Digit3 e f g) = d7 a b c d e f g\r
-dd4 a b c d (Digit4 e f g h) = d8 a b c d e f g h\r
-dd5 a b c d e (Digit1 f) = d6 a b c d e f\r
-dd5 a b c d e (Digit2 f g) = d7 a b c d e f g\r
-dd5 a b c d e (Digit3 f g h) = d8 a b c d e f g h\r
-dd5 a b c d e (Digit4 f g h i) = d9 a b c d e f g h i\r
-dd6 a b c d e f (Digit1 g) = d7 a b c d e f g\r
-dd6 a b c d e f (Digit2 g h) = d8 a b c d e f g h\r
-dd6 a b c d e f (Digit3 g h i) = d9 a b c d e f g h i\r
-dd6 a b c d e f (Digit4 g h i j) = d10 a b c d e f g h i j\r
-dd7 a b c d e f g (Digit1 h) = d8 a b c d e f g h\r
-dd7 a b c d e f g (Digit2 h i) = d9 a b c d e f g h i\r
-dd7 a b c d e f g (Digit3 h i j) = d10 a b c d e f g h i j\r
-dd7 a b c d e f g (Digit4 h i j k) = d11 a b c d e f g h i j k\r
-dd8 a b c d e f g h (Digit1 i) = d9 a b c d e f g h i\r
-dd8 a b c d e f g h (Digit2 i j) = d10 a b c d e f g h i j\r
-dd8 a b c d e f g h (Digit3 i j k) = d11 a b c d e f g h i j k\r
-dd8 a b c d e f g h (Digit4 i j k l) = d12 a b c d e f g h i j k l\r
-\r
-ddd1 a (Digit1 b) y = dd2 a b y\r
-ddd1 a (Digit2 b c) y = dd3 a b c y\r
-ddd1 a (Digit3 b c d) y = dd4 a b c d y\r
-ddd1 a (Digit4 b c d e) y = dd5 a b c d e y\r
-ddd2 a b (Digit1 c) y = dd3 a b c y\r
-ddd2 a b (Digit2 c d) y = dd4 a b c d y\r
-ddd2 a b (Digit3 c d e) y = dd5 a b c d e y\r
-ddd2 a b (Digit4 c d e f) y = dd6 a b c d e f y\r
-ddd3 a b c (Digit1 d) y = dd4 a b c d y\r
-ddd3 a b c (Digit2 d e) y = dd5 a b c d e y\r
-ddd3 a b c (Digit3 d e f) y = dd6 a b c d e f y\r
-ddd3 a b c (Digit4 d e f g) y = dd7 a b c d e f g y\r
-ddd4 a b c d (Digit1 e) y = dd5 a b c d e y\r
-ddd4 a b c d (Digit2 e f) y = dd6 a b c d e f y\r
-ddd4 a b c d (Digit3 e f g) y = dd7 a b c d e f g y\r
-ddd4 a b c d (Digit4 e f g h) y = dd8 a b c d e f g h y\r
-\r
---\r
-6
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-f p l = (foldl (+) (map ((+)p) l)) + p\r
---\r
-3:1-3:39: Couldn't simplify all effect subsumptions away. The current compiler cannot handle this situation. Try adding more type annotations.\r
-3:25-3:31: Type [a b] -> <c> a b is not a subtype of a.
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-inc :: Ref Integer -> <Proc> Integer\r
-inc r = do \r
- v = getRef r\r
- newV = v+1\r
- r := newV\r
- newV\r
-\r
-main = do\r
- r = ref 0\r
- // Because both map and for get side-effectful functions\r
- // as parameters, the fusion is not allowed.\r
- l = map (\_ -> inc r) [1..4] \r
- for l (\i -> r := i+1)\r
- getRef r\r
---\r
-5\r
+++ /dev/null
-import "Prelude"\r
-\r
-inc :: Ref Integer -> <Proc> Integer\r
-inc r = do \r
- v = getRef r\r
- newV = v+1\r
- r := newV\r
- newV\r
-\r
-main = do\r
- r = ref 0\r
- l = map (\_ -> inc r) [1..4]\r
- r := 4 // Map must be executed before this statement\r
- foldl (+) 0 l\r
---\r
-10\r
+++ /dev/null
- \r
-id :: forall a. a -> a\r
- // ^ not usually needed, but we test just that this is possible\r
-id x = x\r
-\r
-main = id (3 :: Integer)\r
---\r
-3
\ No newline at end of file
+++ /dev/null
-\r
-data List a = Nil | Cons a (List a)\r
-\r
-build :: (forall l. l -> (a -> l -> l) -> l) -> List a\r
-build f = f Nil Cons\r
-\r
-main = build (\nil cons -> cons (1 :: Integer) (cons (2 :: Integer) nil))\r
--- \r
-(Cons 1 (Cons 2 Nil))
\ No newline at end of file
+++ /dev/null
-\r
-data List a = Nil | Cons a (List a)\r
-\r
-build :: (forall l. l -> (a -> l -> l) -> l) -> List a\r
-build f = f Nil Cons\r
-\r
-main = build (\nil cons -> cons (1 :: Integer) (Cons (2 :: Integer) nil))\r
- // ^^^^\r
--- \r
-7:48-7:73: Expected <a> got <List Integer>.\r
-7:69-7:72: Expected <List Integer> got <a>.
\ No newline at end of file
+++ /dev/null
-import "Prelude"
-
-data Formula a = TrueF
- | FalseF
- | XorF (Formula a) (Formula a)
- | AndF (Formula a) (Formula a)
- | ConditionF a
- | NextF (Formula a)
- | UntilF (Formula a) (Formula a)
-
-deriving instance (Ord a) => Ord (Formula a)
-
-instance (Show a) => Show (Formula a) where
- sb <+ TrueF = sb << "true"
- sb <+ FalseF = sb << "false"
- sb <+ XorF a b = sb << "(" <+ a << " `XorF` " <+ b << ")"
- sb <+ AndF a b = sb << "(" <+ a << " &&& " <+ b << ")"
- sb <+ ConditionF c = sb <+ c
- sb <+ NextF a = sb << "(next " <+ a << ")"
- sb <+ UntilF a b = sb << "(" <+ a << " `UntilF` " <+ b << ")"
-
-xorF FalseF f2 = f2
-xorF f1 FalseF = f1
-xorF f1@(XorF h1 t1) f2@(XorF h2 t2) =
- let cmp = compare h1 h2
- in if cmp < 0
- then XorF h1 (xorF t1 f2)
- else if cmp > 0
- then XorF h2 (xorF f1 t2)
- else xorF t1 t2
-xorF f1@(XorF h1 t1) f2 =
- let cmp = compare h1 f2
- in if cmp < 0
- then XorF h1 (xorF t1 f2)
- else if cmp > 0
- then XorF f2 f1
- else t1
-xorF f1 f2@(XorF h2 t2) =
- let cmp = compare f1 h2
- in if cmp < 0
- then XorF f1 f2
- else if cmp > 0
- then XorF h2 (xorF f1 t2)
- else t2
-xorF f1 f2 =
- let cmp = compare f1 f2
- in if cmp < 0
- then XorF f1 f2
- else if cmp > 0
- then XorF f2 f1
- else TrueF
-
-notF f = xorF TrueF f
-
-TrueF &&& f2 = f2
-f1 &&& TrueF = f1
-FalseF &&& _ = FalseF
-_ &&& FalseF = FalseF
-XorF h1 t1 &&& f2 = xorF (h1 &&& f2) (t1 &&& f2)
-f1 &&& XorF h2 t2 = xorF (f1 &&& h2) (f1 &&& t2)
-f1@(AndF h1 t1) &&& f2@(AndF h2 t2) =
- let cmp = compare h1 h2
- in if cmp < 0
- then AndF h1 (t1 &&& f2)
- else if cmp > 0
- then AndF h2 (f1 &&& t2)
- else AndF h1 (t1 &&& t2)
-f1@(AndF h1 t1) &&& f2 =
- let cmp = compare h1 f2
- in if cmp < 0
- then AndF h1 (t1 &&& f2)
- else if cmp > 0
- then AndF f2 f1
- else f1
-f1 &&& f2@(AndF h2 t2) =
- let cmp = compare f1 h2
- in if cmp < 0
- then AndF f1 f2
- else if cmp > 0
- then AndF h2 (f1 &&& t2)
- else f2
-f1 &&& f2 =
- let cmp = compare f1 f2
- in if cmp < 0
- then AndF f1 f2
- else if cmp > 0
- then AndF f2 f1
- else f1
-
-f1 ||| f2 = xorF (xorF f1 f2) (f1 &&& f2)
-
-eval :: Ord a => (a -> <e> Boolean) -> Formula a -> <e> Formula a
-eval s TrueF = TrueF
-eval s FalseF = FalseF
-eval s (XorF f1 f2) = xorF (eval s f1) (eval s f2)
-eval s (AndF f1 f2) = eval s f1 &&& eval s f2
-eval s (ConditionF c) = if s c then TrueF else FalseF
-eval s (NextF f) = f
-eval s (UntilF f1 f2) = eval s f2 ||| (eval s f1 &&& UntilF f1 f2)
-
-// Concrete conditions
-
-data V = V String (Ref Boolean)
-
-instance Ord V where
- compare (V a _) (V b _) = compare a b
-instance Show V where
- sb <+ V a _ = sb <+ a
-
-cond :: String -> Ref Boolean -> Formula V
-cond name ref = ConditionF (V name ref)
-
-// Testing
-
-x = ref True
-y = ref False
-
-f = cond "x" x `UntilF` cond "y" y
-
-evalV = eval (\(V _ c) -> getRef c)
-
-main = do
- print (evalV f)
- x := False
- print (evalV f)
- y = ref True
- print (evalV f)
- x := True
- print (evalV f)
---
-()
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-main = (fromDynamic (toDynamic 42) :: String) + "foo"\r
---\r
-42foo
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-main = (fromDynamic (toDynamic "42") :: Integer) - 2\r
---\r
-40
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-main = arrayToList (fromDynamic (toDynamic ["42"]) :: (Array Integer))\r
---\r
-[42]
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-import "Vector"\r
-\r
-main = (fromDynamic (toDynamic ["42"]) :: (Vector Double))!0\r
---\r
-42.0
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-import "Vector"\r
-\r
-main = (fromDynamic (toDynamic (mvector [42.0]))) :: [Integer]\r
---\r
-[42]
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-// vvvvvv mistake, parantheses missing\r
-instance Functor (->) a where\r
- map f g x = f (g x)\r
- \r
-main = "Not to be executed."\r
---\r
-4:1-5:24: Wrong number of parameters to type class Functor.
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-class Container c a b | c -> a, c -> b where\r
- get :: c -> a -> b\r
-\r
-instance Container [a] Integer a where\r
- get = (!)\r
-\r
-main = get [1,2,3,4,5] 3\r
---\r
-4
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-class Mul a b c | a b -> c where\r
- mul :: a -> b -> c\r
-\r
-instance Mul Integer Integer Integer where\r
- mul = (*)\r
-\r
-main :: Integer\r
-main = mul (mul (1 :: Integer) (2 :: Integer)) (3 :: Integer)\r
---\r
-6
\ No newline at end of file
+++ /dev/null
-import "JavaBuiltin" as Java\r
-\r
-class Functor f where\r
- map :: (a -> b) -> f a -> f b\r
- \r
-data Foo a = Foo a\r
-\r
-instance Functor Foo where\r
- map f (Foo x) = Foo (f x)\r
- \r
-instance Functor Maybe where\r
- map f Nothing = Nothing\r
- map f (Just x) = Just (f x)\r
- \r
-data List a = Nil | Cons a (List a)\r
-\r
-instance Functor List where\r
- map f Nil = Nil\r
- map f (Cons h t) = Cons (f h) (map f t)\r
- \r
-main = map (map (Java.iadd 1)) (Cons Nothing (Cons (Just (1 :: Integer)) Nil))\r
---\r
-(Cons null (Cons 2 Nil))
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-main = sequence [[1,2], [3,4], [5,6]]\r
-/*\r
- x <- [1,2]\r
- y <- [3,4]\r
- z <- [5,6]\r
- return [x,y,z]\r
-*/ \r
---\r
-[[1, 3, 5], [1, 3, 6], [1, 4, 5], [1, 4, 6], [2, 3, 5], [2, 3, 6], [2, 4, 5], [2, 4, 6]]
\ No newline at end of file
+++ /dev/null
-import "JavaBuiltin" as Java\r
-\r
-(+) = Java.iadd\r
-\r
-data Foo = Foo Integer\r
-\r
-escapeFoo (Foo x) = x\r
-\r
-id x = x\r
-\r
-main = id (3 :: Integer) + escapeFoo (id (Foo (4 :: Integer)))\r
---\r
-7
\ No newline at end of file
+++ /dev/null
-// Idea of this test is to ensure that generic type variables\r
-// and constraints are handled correctly with mutually recursive\r
-// functions\r
-\r
-import "Prelude"\r
-\r
-deepId count x = deepId2 count x\r
-deepId2 count x = if count <= 0 then x else deepId (count-1) x\r
-\r
-main = deepId 5 "FOO"\r
---\r
-FOO
\ No newline at end of file
+++ /dev/null
-import "Prelude"
-
-global :: Ref Integer
-global = ref 0
-
-inc :: <Proc> ()
-inc = global := getRef global + 1
-
-main = do
- inc
- inc
- getRef global
---
-2
\ No newline at end of file
+++ /dev/null
-\r
-/**\r
- * Databoard\r
- */\r
-data Binding // Private\r
-class Serializable a where\r
- getBinding :: Binding\r
-\r
-/**\r
- * Reading graph\r
- */\r
-data Resource\r
-data ReadGraph // Private\r
-class ReadTransaction where\r
- getGraph :: ReadGraph\r
-\r
-resource :: ReadTransaction => String -> Resource\r
-(#) :: ReadTransaction => Resource -> Resource -> [Resource]\r
-valueOf :: ReadTransaction => Serializable a => Resource -> a\r
-\r
-/**\r
- * Writing graph\r
- */\r
-data WriteGraph // Private\r
-data Graph a = Graph (WriteGraph -> a)\r
-\r
-instance Monad Graph where\r
- return x = Graph (\_ -> x)\r
- Graph g >>= f = \wg -> f (g wg) wg\r
- map f (Graph g) = Graph (f . g)\r
-\r
-newResource :: Graph Resource\r
-newResource = Graph __WriteGraph_newResource\r
-newLiteral :: Serializable a => a -> Graph Resource\r
-newLiteral = Graph (\wg -> \r
- literal = __WriteGraph_newResource wg\r
- _ = __WriteGraph_claimValue wg literal a getBinding\r
- literal \r
-)\r
-statement :: Resource -> Resource -> Resource -> Graph ()\r
-statement s p o = Graph (\wg -> __WriteGraph_claim wg s p o)
\ No newline at end of file
+++ /dev/null
-tableIndex :: Double -> Double
-tableIndex x
- | True = x
- where
- f _ = x
-
-main = "Foo"
---
-Foo
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-fib :: Integer -> Integer\r
-fib x | x <= 2 = 1\r
- | True = fib (x-1) + fib (x-2)\r
-\r
-main = fib 13\r
---\r
-233
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-fib :: Integer -> Integer\r
-fib x = match x with\r
- v | v <= 2 -> 1\r
- | True -> fib (v-1) + fib (v-2)\r
-\r
-main = fib 13\r
---\r
-233
\ No newline at end of file
+++ /dev/null
-import "JavaBuiltin" as Java\r
-\r
-infixl 5 minus\r
-\r
-minus = Java.isub\r
-\r
-main = 5 `minus` 3 `minus` 2\r
---\r
-0
\ No newline at end of file
+++ /dev/null
-a = ¤\r
---\r
-1:5-1:6: Illegal character '¤'.\r
+++ /dev/null
-\r
-@JavaType "org.simantics.scl.compiler.elaboration.expressions.Expression"\r
-data Expression = \r
- @JavaType "org/simantics/scl/compiler/elaboration/expressions/EIntegerLiteral"\r
- @FieldNames [value]\r
- EIntegerLiteral String\r
- | @JavaType "org.simantics.scl.compiler.elaboration.expressions.ERealLiteral"\r
- @FieldNames [value]\r
- ERealLiteral String\r
-\r
-changeType :: Expression -> Expression\r
-changeType (EIntegerLiteral value) = ERealLiteral value\r
-changeType (ERealLiteral value) = EIntegerLiteral value\r
-\r
-main :: Expression\r
-main = changeType (EIntegerLiteral "123") \r
---\r
-123
\ No newline at end of file
+++ /dev/null
-importJava "org.simantics.scl.runtime.procedure.Ref" where\r
- data Ref a\r
- \r
- @JavaName "<init>"\r
- ref :: a -> <Proc> (Ref a)\r
- \r
- @JavaName "value"\r
- getRef :: Ref a -> <Proc> a\r
- \r
- @JavaName "<set>value"\r
- (:=) :: Ref a -> a -> <Proc> ()\r
-\r
-main = do\r
- r = ref (13 :: Integer)\r
- r := (14 :: Integer)\r
- getRef r\r
---\r
-14
\ No newline at end of file
+++ /dev/null
-f a b = a\r
-f x = x\r
---\r
-2:1-2:4: Inconsistent arity. This case has arity 1 while previous cases had arity 2.
\ No newline at end of file
+++ /dev/null
-class Foo a where\r
- x :: a\r
- y :: a\r
---\r
-3:3-3:4: Unexpected token 'y' (ID). Expected one of EOF, RBRACE, SEMICOLON.
\ No newline at end of file
+++ /dev/null
-// The last character of the program is an extra closing parenthesis\r
-data List a = Nil | Cons a (List a)\r
-\r
-first Nil = 0\r
-first (Cons x _) = x\r
-\r
-reverse l = reverseAux Nil l \r
- where\r
- reverseAux accum Nil = accum\r
- reverseAux accum (Cons h t) = reverseAux (Cons h accum) t \r
-\r
-main = first (reverse l) \r
- where\r
- l = Cons 1 (Cons 2 (Cons 3 Nil)))\r
---\r
-14:37-14:38: No corresponding opening parenthesis for ')'.
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-f :: Integer -> Maybe Integer\r
-f = index [(1,2),(2,4),(3,6),(4,8)]\r
-\r
-main = f 3\r
---\r
-6
\ No newline at end of file
+++ /dev/null
-main = id "Foo" \r
- where\r
- id x = x\r
---\r
-Foo
\ No newline at end of file
+++ /dev/null
-data SList a = Nil | Cons a (SList a)
-
-@inline
-copy (Cons h t) = Cons h (copy t)
-copy l = l
-
-main = "OK"
---
-OK
\ No newline at end of file
+++ /dev/null
-import "Prelude" hiding (zero, one)\r
-\r
-class MyAdditive a where\r
- zero :: a\r
- \r
-class (MyAdditive a) => MyRing a where\r
- one :: a\r
-\r
-instance MyAdditive Integer where\r
- zero = 0\r
-\r
-instance MyRing Integer where\r
- one = 1\r
- \r
-data Poly a = Poly [a]\r
-\r
-instance (MyAdditive a) => MyAdditive (Poly a) where\r
- zero = Poly []\r
-\r
-instance (MyRing a) => MyRing (Poly a) where\r
- one = Poly [one]\r
- \r
-main :: Poly Integer\r
-main = one\r
---\r
-[1]
\ No newline at end of file
+++ /dev/null
-class Functor f where\r
- map :: (a -> b) -> f a -> f b\r
- \r
-data Foo a = Foo a\r
-\r
-class Functor Foo where\r
- map f (Foo x) = Foo (f x)\r
---\r
-6:1-7:30: Class Functor has already been defined in this module.
\ No newline at end of file
+++ /dev/null
-class Foo a b where\r
- foo :: a -> b\r
-\r
-instance Foo a a where\r
- foo x = x :: a\r
-\r
-main = "OK"\r
---\r
-OK\r
-\r
+++ /dev/null
-class Foo a where\r
- infix 3 (+)\r
---\r
-2:5-2:16: Invalid declaration under class definition.
\ No newline at end of file
+++ /dev/null
-main = "Hello w�rld!"\r
---\r
-1:16-1:17: Character does not conform to UTF-8 encoding.
\ No newline at end of file
+++ /dev/null
-class Foo a where\r
- (+) :: a -> a -> a\r
-\r
-instance Foo Double where\r
- infix 3 (+)\r
- x + y = x\r
---\r
-5:5-5:16: Invalid declaration under instance definition.
\ No newline at end of file
+++ /dev/null
-@JavaType 123 "sdf"\r
-data Foo\r
-\r
-main = "Not to be executed"\r
---\r
-1:1-1:20: Invalid parameters. Expected @JavaType "className".
\ No newline at end of file
+++ /dev/null
-\r
-data List a = Nil | Cons a (List a)\r
-\r
-foo :: List\r
-foo = foo\r
---\r
-4:8-4:12: Expected a type with kind * but got * -> *.
\ No newline at end of file
+++ /dev/null
-class Functor f where\r
- map :: (a -> b) -> f a -> f b\r
- \r
-instance Functor Integer where\r
- map = fail "Not implemented."\r
-\r
-main = "Not to be executed."\r
---\r
-4:18-4:25: Expected a type with kind * -> * but got *.
\ No newline at end of file
+++ /dev/null
-\r
-data List a = Nil | Cons a List\r
-\r
---\r
-2:28-2:32: Expected a type with kind * but got ?a -> *.
\ No newline at end of file
+++ /dev/null
-
-main = \ /* no parameters */ -> 3
---
-2:30-2:32: Unexpected token '->' (ARROW). Expected one of ATTACHED_HASH, BEGIN_STRING, BLANK, CHAR, DO, ENFORCE, EQ, ESCAPED_SYMBOL, FLOAT, ID, IF, INTEGER, LAMBDA, LBRACKET, LET, LPAREN, MATCH, MDO, SELECT, SELECT_DISTINCT, SELECT_FIRST, TRANSFORMATION, WHEN.
+++ /dev/null
-import "INVALID_MODULE" as Foo
---
-1:1-1:31: Failed to import INVALID_MODULE, because it does not exist.
\ No newline at end of file
+++ /dev/null
-id x = x\r
-\r
-f (\x -> x) y = y\r
-\r
-main = f id "Foo"\r
---\r
-3:3-3:12: Pattern was expected here.
\ No newline at end of file
+++ /dev/null
-if x then y else z = x\r
-\r
-main = "Not to be executed."\r
---\r
-1:1-1:19: Illegal left hand side of the definition.
\ No newline at end of file
+++ /dev/null
-foo x = b\r
- where\r
- if a then b else c = x\r
-\r
-main = "Not to be executed."\r
---\r
-1:9-1:10: Couldn't resolve variable b.\r
-3:5-3:23: Pattern was expected here.
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-a # b # c = a + b + c\r
-\r
-main = "Not to be executed."\r
---\r
-3:1-3:10: Illegal left hand side of the definition.
\ No newline at end of file
+++ /dev/null
-data Fact = Foo | Bar\r
-\r
-rs = ruleset\r
- Foo => Bar\r
-\r
-main = "Not to be executed."\r
---\r
-4:10-4:13: Expected\r
- <[Fact]> got\r
- <Fact>.
\ No newline at end of file
+++ /dev/null
-data Fact = Foo1 | Foo2\r
-data Fact2 = Bar\r
-\r
-rs = ruleset\r
- Foo1, Foo2 <=> [Bar]\r
-\r
-main = "Not to be executed."\r
---\r
-5:19-5:22: Expected\r
- <Fact> got\r
- <Fact2>.
\ No newline at end of file
+++ /dev/null
-\r
-class Foo a where\r
- foo :: a -> Integer\r
- \r
-instance Foo Long where\r
- foo x = x\r
- \r
---\r
-6:13-6:14: Expected <Integer> got <Long>.
\ No newline at end of file
+++ /dev/null
-import "JavaBuiltin" as Java\r
-\r
-importJava "java.lang.String" where\r
- substring :: String -> Integer -> Integer -> String\r
-\r
-main = substring "01234" 1 4\r
---\r
-123
\ No newline at end of file
+++ /dev/null
-\r
-@JavaType "org.simantics.scl.runtime.tuple.Tuple3"\r
-data Tuple3 a b c =\r
- @FieldNames [c0, c1, c2] \r
- Tuple3 a b c\r
- \r
-toTuple (Tuple3 x y z) = (x, y, z)\r
-\r
-main = toTuple (Tuple3 "x" "y" "z")\r
---\r
-(x,y,z)
\ No newline at end of file
+++ /dev/null
-import "JavaBuiltin" as Java\r
-\r
-importJava "java.lang.Integer" where\r
- @JavaName "parseInt"\r
- stringToInteger :: String -> Integer\r
-\r
-main = stringToInteger "13"\r
---\r
-13
\ No newline at end of file
+++ /dev/null
-import "JavaBuiltin" as Java\r
-\r
-importJava "java.math.BigInteger" where\r
- data BigInteger\r
- \r
- @JavaName "add"\r
- (+) :: BigInteger -> BigInteger -> BigInteger\r
-\r
- @JavaName "<init>"\r
- fromString :: String -> BigInteger\r
-\r
-main = fromString "123" + fromString "234"\r
---\r
-357
\ No newline at end of file
+++ /dev/null
-class Functor f where\r
- map :: (a -> b) -> f a -> f b\r
-\r
-data Either a b = Left a | Right b\r
-\r
-instance Functor (Either a) where\r
- map _ (Left x) = Left x\r
- map f (Right y) = Right (f y)\r
-\r
-id :: Integer -> Integer\r
-id x = x\r
-\r
-main = map id (Left (12 :: Integer))\r
---\r
-(Left 12)
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-importJava "gnu.trove.map.hash.TIntFloatHashMap" where\r
- data LMap\r
- \r
- @JavaName adjustOrPutValue\r
- adjustLMap_ :: LMap -> Integer -> Float -> Float -> <Proc> ()\r
- \r
-@inline\r
-adjustLMap :: LMap -> Integer -> Float -> <Proc> ()\r
-adjustLMap m k v = adjustLMap_ m k v v\r
-\r
-data LPTerm = LPTerm (LMap -> Float -> <Proc> ())\r
-\r
-instance Additive LPTerm where\r
- @inline\r
- zero = LPTerm (\_ _ -> ())\r
- @inline\r
- LPTerm a + LPTerm b = LPTerm (\m s -> do a m s ; b m s)\r
- sum ts = LPTerm (\m s -> for ts (\(LPTerm t) -> t m s))\r
-\r
-instance Ring LPTerm where\r
- @inline\r
- neg (LPTerm a) = LPTerm (\m s -> a m (-s))\r
- @inline\r
- LPTerm a - LPTerm b = LPTerm (\m s -> do a m s ; b m (-s))\r
- @inline\r
- fromInteger c = LPTerm (\m s -> adjustLMap m (-1) (fromInteger c*s))\r
- @inline\r
- one = LPTerm (\m s -> adjustLMap m (-1) s)\r
- _ * _ = fail "Multiplication is not supported."\r
-\r
-data LPProblem = LPProblem (Ref Integer)\r
-\r
-newProblem :: () -> <Proc> LPProblem\r
-newProblem _ = LPProblem (ref 0)\r
-\r
-newVar :: LPProblem -> <Proc> LPTerm\r
-newVar (LPProblem varCounter) = do\r
- curId = getRef varCounter\r
- varCounter := curId + 1\r
- LPTerm (\m s -> adjustLMap m curId s)\r
-\r
-infixl 7 (**)\r
-\r
-@inline\r
-(**) :: Float -> LPTerm -> LPTerm\r
-s0 ** LPTerm t = LPTerm (\m s -> t m (s0*s))\r
-\r
-/*\r
-data LPTerm = LPTerm Double (Map.T String Double)\r
-\r
-instance Additive LPTerm where\r
- zero = LPTerm 0 Map.empty\r
- LPTerm c1 m1 + LPTerm c2 m2 = LPTerm (c1+c2) (Map.merge (+) m1 m2)\r
-\r
-instance Ring LPTerm where\r
- one = LPTerm 1 Map.empty\r
- neg (LPTerm c m) = LPTerm (-c) (map neg m)\r
- LPTerm c1 m1 - LPTerm c2 m2 = LPTerm (c1-c2) (Map.merge (-) m1 m2)\r
- \r
- LPTerm c1 [] * LPTerm c2 m2 = LPTerm (c1*c2) (Map.merge (\x -> c1*x) m2)\r
- LPTerm c1 m1 * LPTerm c2 [] = LPTerm (c1*c2) (Map.merge (\x -> c2*x) m1)\r
- _ * _ = fail "Invalid expression: not linear."\r
- \r
- fromInteger i = LPTerm (fromInteger i) Map.empty\r
-\r
-data LPConstraint = LPConstraint String LPTerm\r
-\r
-(>==) :: LPTerm -> LPTerm -> String -> [LPConstraint]\r
-(a >== b) name = [LPConstraint name (a-b)] \r
-\r
-(<==) :: LPTerm -> LPTerm -> String -> [LPConstraint]\r
-(a <== b) name = [LPConstraint name (b-a)]\r
-\r
-*/\r
-\r
-testi () = do\r
- problem = newProblem ()\r
- a = newVar problem\r
- b = newVar problem\r
- 3 ** a + 4 ** b + 15\r
-\r
-main = "OK"\r
---\r
-OK
\ No newline at end of file
+++ /dev/null
-\r
-data List a = Nil | Cons a (List a)\r
-\r
-map :: (a -> b) -> List a -> List b\r
-map f Nil = Nil\r
-map f (Cons h t) = Cons (f h) (map f t)\r
-\r
-constMap :: a -> List b -> List a\r
-constMap c = map (\x -> c)\r
-\r
-main = constMap (5 :: Integer) (Cons (1 :: Integer) (Cons (2 :: Integer) (Cons (3 :: Integer) Nil)))\r
---\r
-(Cons 5 (Cons 5 (Cons 5 Nil)))
\ No newline at end of file
+++ /dev/null
-import "Prelude"
-
-foobar x = match x with
- Left lt -> foo lt
- Right rt -> bar rt
- where
- foo x = "left " + show x
- bar x = "right " + show x
-
-main = foobar (Left "ASD" :: Either String String)
---
-left "ASD"
\ No newline at end of file
+++ /dev/null
-\r
-data List a = Nil | Cons a (List a)\r
-\r
-main :: List Integer\r
-main = Cons (3 :: Integer) Nil\r
---\r
-(Cons 3 Nil)
\ No newline at end of file
+++ /dev/null
-a :: [Integer]\r
-a = a\r
-\r
-main :: [Double]\r
-main = [x | x <- a]\r
---\r
-5:9-5:10: Expected <Double> got <Integer>.
\ No newline at end of file
+++ /dev/null
-a :: Integer\r
-a = a\r
-\r
-main :: [Integer]\r
-main = [x | x <- a]\r
---\r
-5:18-5:19: Expected <[a]> got <Integer>.
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-a = [1,2]\r
-b = [5,9]\r
-main = [(x,y) | x <- a, y <- b]\r
---\r
-[(1,5), (1,9), (2,5), (2,9)]
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-dists l = sum [sqrt (dx*dx + dy*dy) \r
- | i <- [0..length l-2]\r
- , (x1,y1) = l!i\r
- , (x2,y2) = l!(i+1)\r
- , dx = x1-x2\r
- , dy = y1-y2 ]\r
- \r
-main = dists [(0,0),(1,1),(2,0)]\r
--- \r
-2.8284271247461903
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-dists l = sum [sqrt (x*x+y*y) \r
- | (x,y) <- l ]\r
- \r
-main = dists [(0,0),(1,1),(2,0)]\r
--- \r
-3.414213562373095
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
- \r
-main = foldl (+) 0 [x | y <- [1..10], x <- [1..y]]\r
--- \r
-220
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-a = [1,2]\r
-b = [5,9]\r
-main = [(x, y) | x <- a, x==2, y <- b]\r
---\r
-[(2,5), (2,9)]
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-main = [1,2,3,4]\r
---\r
-[1, 2, 3, 4]
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-main :: [Integer]\r
-main = [y | x <- [1..3], y = x+4]\r
---\r
-[5, 6, 7]
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-a = [1,2,3,4]\r
-\r
-main :: [Integer]\r
-main = [x+y | x <- a, y <- a, x!=y]\r
---\r
-[3, 4, 5, 3, 5, 6, 4, 5, 7, 5, 6, 7]\r
+++ /dev/null
-import "Prelude"\r
-\r
-main :: [Integer]\r
-main = [x | x <- [1..10], then take 3]\r
---\r
-[1, 2, 3]
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-main :: [Integer]\r
-main = [x | x <- [2,4,3,5,4,6], then sortBy by x]\r
---\r
-[2, 3, 4, 4, 5, 6]
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-a :: [Either Integer Integer]\r
-a = [Left 1, Right 2, Left 3, Right 4]\r
-\r
-lefts :: [Either a b] -> [a]\r
-lefts l = [x | Left x <- l] \r
-\r
-main :: [Integer]\r
-main = lefts a\r
---\r
-[1, 3]
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-a :: [Either Integer Integer]\r
-a = [Left 1, Right 2, Left 3, Right 4]\r
-\r
-lefts :: [Either a b] -> [a]\r
-lefts l = [x | y <- l, Left x = y] \r
-\r
-main :: [Integer]\r
-main = lefts a\r
---\r
-[1, 3]
\ No newline at end of file
+++ /dev/null
-main = [1 :: Integer,2 :: Integer,3 :: Integer]\r
---\r
-[1, 2, 3]
\ No newline at end of file
+++ /dev/null
-\r
-data List a = Nil | Cons a (List a)\r
-\r
-reverse :: List a -> List a\r
-reverse l = do \r
- reverseAux accum Nil = accum\r
- reverseAux accum (Cons h t) = reverseAux (Cons h accum) t\r
- reverseAux Nil l\r
- \r
-main = reverse (Cons (1 :: Integer) (Cons (2 :: Integer) (Cons (3 :: Integer) (Cons (4 :: Integer) Nil))))\r
---\r
-(Cons 4 (Cons 3 (Cons 2 (Cons 1 Nil))))
\ No newline at end of file
+++ /dev/null
-\r
-data List a = Nil | Cons a (List a)\r
-\r
-hasEvenLength :: List a -> Boolean\r
-hasEvenLength l = do \r
- even Nil = True\r
- even (Cons _ t) = odd t\r
- odd Nil = False\r
- odd (Cons _ t) = even t\r
- even l\r
-\r
-main = hasEvenLength (Cons (1 :: Integer) (Cons (2 :: Integer) (Cons (3 :: Integer) (Cons (4 :: Integer) Nil))))\r
---\r
-true
\ No newline at end of file
+++ /dev/null
-\r
-data Step s = Skip s\r
-\r
-next :: (s -> Step s) -> s -> Step s \r
-next next0 ss = match next0 ss with \r
- Skip ss -> Skip ss\r
- \r
-main = next (\x -> Skip x) (3 :: Integer)\r
---\r
-3
\ No newline at end of file
+++ /dev/null
-\r
-first p = x\r
- where \r
- (x,y) = p\r
- \r
-main = first (3 :: Integer,4 :: Integer)\r
---\r
-3
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-data Foo = Foo Double Double\r
-\r
-a = Foo 1 2\r
-\r
-b = y\r
- where\r
- Foo x y = a\r
- \r
-main = show b\r
---\r
-2.0
\ No newline at end of file
+++ /dev/null
-@macro\r
-(||) :: Boolean -> Boolean -> Boolean \r
-a || b = if a then True else b\r
-\r
-main :: Boolean\r
-main = True || (fail "This should not be executed")\r
---\r
-true
\ No newline at end of file
+++ /dev/null
-import "JavaBuiltin" as Java\r
-\r
-(==) = Java.icmpeq\r
-\r
-@macro\r
-(&<&) :: Integer -> Integer -> Integer\r
-a &<& b = if cmp == 0 then b else cmp\r
- where \r
- cmp = a\r
-\r
-main = 3 &<& 7\r
---\r
-3
\ No newline at end of file
+++ /dev/null
-import "JavaBuiltin" as Java\r
-\r
-@JavaType "java.util.Collection"\r
-data Collection a\r
-\r
-@macro\r
-collectionToList :: Collection a -> [a]\r
-collectionToList = Java.unsafeCoerce\r
-\r
-singleton :: a -> Collection a\r
-singleton = Java.staticMethod "java.util.Collections.singletonList"\r
-\r
-main :: [Integer]\r
-main = collectionToList (singleton 15)\r
---\r
-[15]
\ No newline at end of file
+++ /dev/null
-@macro\r
-@inline\r
-($) :: (a -> <e> b) -> a -> <e> b\r
-f $ x = f x\r
-\r
-justExecute :: (() -> a) -> a\r
-justExecute f = f ()\r
-\r
-main :: Integer\r
-main = justExecute $ \() -> (13 :: Integer)\r
---\r
-13
\ No newline at end of file
+++ /dev/null
-data List a = Nil | Cons a (List a)\r
-\r
-map f Nil = Nil\r
-map f (Cons h t) = Cons (f h) (map f t)\r
-\r
-map2 f l = run l\r
- where\r
- run Nil = Nil\r
- run (Cons h t) = Cons (f h) (run t)\r
-\r
-map3 f l = run l\r
- where\r
- run Nil = Nil\r
- run (Cons h t) = Cons (f h) (map f t)\r
- \r
-main = "Foo"\r
---\r
-Foo
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-l :: [Integer]\r
-l = [2,3]\r
-\r
-f :: Integer -> <Proc> [Integer]\r
-f n = [n] + [0 | i <- l]\r
- \r
-main = f 1\r
---\r
-[1, 0, 0]
\ No newline at end of file
+++ /dev/null
-import "IterN"\r
-import "Random"\r
-\r
-foo :: Integer -> <Proc> Double\r
-foo n = runRandom $ foldlN addRandom 0.0 n\r
-\r
-addRandom :: Double -> Integer -> <Random,Proc> Double\r
-addRandom v i = v + randomDouble\r
-\r
-main = "Foo"\r
---\r
-Foo
\ No newline at end of file
+++ /dev/null
-\r
-data List a = Nil | Cons a (List a)\r
-\r
-first :: List Integer -> Integer\r
-//first Nil = 0 :: Integer\r
-first (Cons x _) = x\r
-\r
-reverse :: List a -> List a\r
-reverse l = reverseAux Nil l \r
- where\r
- reverseAux accum Nil = accum\r
- reverseAux accum (Cons h t) = reverseAux (Cons h accum) t \r
-\r
-main :: Integer\r
-main = first (reverse l) \r
- where\r
- l = Cons (1 :: Integer) (Cons (2 :: Integer) (Cons (3 :: Integer) Nil))\r
---\r
-3
\ No newline at end of file
+++ /dev/null
-\r
-main = match (5 :: Integer) with\r
- (1 :: Integer) -> "wrong"\r
- (2 :: Integer) -> "wrong"\r
- (5 :: Integer) -> "right"\r
- (6 :: Integer) -> "wrong"\r
- _ -> "wrong"\r
---\r
-right
\ No newline at end of file
+++ /dev/null
-\r
-a = 5 :: Long\r
-main = match a with\r
- 1 -> "wrong"\r
- 2 -> "wrong"\r
- 5 -> "right"\r
- 6 -> "wrong"\r
- _ -> "wrong"\r
---\r
-right
\ No newline at end of file
+++ /dev/null
-import "StandardLibrary"
-
-foo 1 = "one"
-foo 2 = "two"
-
-main = if True then foo (2 :: Long) else foo (1 :: Integer)
---
-two
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-dummySum [] = 0\r
-dummySum [a] = a\r
-dummySum [a,b] = a + b\r
-dummySum [a,b,c] = a + b + c\r
-dummySum l = sum l\r
-\r
-main = dummySum [] + dummySum [1] + dummySum [1,2] + dummySum [1,2,3]\r
---\r
-10
\ No newline at end of file
+++ /dev/null
-main = do \r
- match () with\r
- () -> "Hello"\r
---\r
-Hello
\ No newline at end of file
+++ /dev/null
-data Foo = Foo Integer Integer
- | Bar
-
-isFoo (Foo _) = True
-isFoo _ = False
-
-main = "Hello world!"
---
-4:7-4:14: The function is applied with too few parameters.
-
+++ /dev/null
-\r
-data List a = Nil | Cons a (List a)\r
-\r
-//first :: List Integer -> Integer\r
-first Nil = 0 :: Integer\r
-first (Cons x _) = x\r
-\r
-main = first (Cons (9 :: Integer) (Cons (8 :: Integer) Nil))\r
---\r
-9
\ No newline at end of file
+++ /dev/null
-import "Prelude" hiding (maximumBy)\r
-\r
-maximumBy :: Ord b => (a -> b) -> [a] -> a\r
-maximumBy f = snd . foldl1 maxF . map (\x -> (f x, x))\r
- where\r
- maxF (a @ (aV,_)) (b @ (bV,_)) = if aV >= bV then a else b\r
- \r
-main = maximumBy (`mod` 10) [1::Integer, 14, 23, 9, 14, 67] \r
---\r
-9
\ No newline at end of file
+++ /dev/null
-a = Nothing\r
-main = match a with\r
- Nothing -> "Correct"\r
- Just x -> "Incorrect"\r
---\r
-Correct
\ No newline at end of file
+++ /dev/null
-a = Just True\r
-main = match a with\r
- Nothing -> False\r
- Just x -> x\r
---\r
-true
\ No newline at end of file
+++ /dev/null
-a = Just "ABC"\r
-main = match a with\r
- Nothing -> "Incorrect"\r
- Just x -> x\r
---\r
-ABC
\ No newline at end of file
+++ /dev/null
-import "Prelude" hiding (fromMaybe)\r
-import "Random"\r
-\r
-importJava "org.simantics.scl.compiler.tests.imports.Maybe4Imports" where\r
- toMaybeDouble :: String -> <Random> Maybe a\r
-\r
-fromMaybe :: a -> Maybe a -> a\r
-fromMaybe _ (Just v) = v\r
-fromMaybe def _ = def\r
-\r
-f x = do\r
- a = fromMaybe (-1.0) (toMaybeDouble x)\r
- b = fromMaybe (-1.0) (toMaybeDouble ("1" + x))\r
- a+b\r
-\r
-main = withSeed 123 (f "2.0")\r
---\r
-14.0
\ No newline at end of file
+++ /dev/null
-import "Prelude" hiding (findFirst)\r
-\r
-findFirst :: (a -> <e> Maybe b) -> [a] -> Maybe b\r
-findFirst f l = loop 0\r
- where\r
- len = length l\r
- loop i \r
- | i >= len = Nothing\r
- | otherwise = match f (l!i) with\r
- s @ (Just _) -> s\r
- Nothing -> loop (i+1)\r
-\r
-main = "Not to be executed"\r
---\r
-9:29-9:36: Side-effect a is forbidden here.
\ No newline at end of file
+++ /dev/null
-class FooBar a where\r
- foo :: a -> a\r
- bar :: a -> a\r
- \r
-instance FooBar Integer where\r
- foo x = x\r
-\r
-main = "Not to be executed."\r
---\r
-5:1-6:14: Method bar is not defined.\r
- \r
-\r
+++ /dev/null
-importJava "java.util.Arrays" where\r
- toString :: MVector /*Double*/ -> String\r
-\r
-main = "Not to be executed."\r
---\r
-???
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-d = map (+1) c\r
-a = [1,2,3]\r
-c = map (+1) b\r
-b = map (+1) a\r
-e = map (+1) d\r
-\r
-main = e\r
---\r
-[5, 6, 7]
\ No newline at end of file
+++ /dev/null
-class Monad m where\r
- (>>=) :: m a -> (a -> m b) -> m b\r
-\r
-@macro\r
-(>>) :: Monad m => m a -> m b -> m b\r
-ma >> mb = ma >>= (\_ -> mb)\r
-\r
-main = "OK"\r
---\r
-OK
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-a = [1, 2]\r
-b = [5, 6]\r
-\r
-main = mdo \r
- x <- a\r
- y <- b\r
- return (x+y) \r
---\r
-[6, 7, 7, 8]
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-a = [1, 2]\r
-b = [5, 6]\r
-\r
-main = do \r
- x <- a\r
- y <- b\r
- return (x+y) \r
---\r
-7:3-7:9: Bind statements are allowed only in mdo-blocks.\r
-8:3-8:9: Bind statements are allowed only in mdo-blocks.
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-a = [1, 2]\r
-b = [5, 6]\r
-\r
-main = a >>= \x -> b >>= \y -> return (x+y) \r
---\r
-[6, 7, 7, 8]
\ No newline at end of file
+++ /dev/null
-// Idea of this test is that the missing definition should only cause\r
-// one error message pointing to the type declaration.\r
-a :: Double\r
-b :: Double\r
-b = a\r
---\r
-3:1-3:12: a is not defined.
\ No newline at end of file
+++ /dev/null
-\r
-class Foo a where\r
- foo :: a\r
-\r
-x :: Double\r
-x = foo\r
-\r
---\r
-6:5-6:8: Constraint <Foo Double> is not given and cannot be derived.
\ No newline at end of file
+++ /dev/null
-\r
-class Foo a where\r
- foo :: a\r
-\r
-y :: Double\r
-y = y\r
- \r
-x = if True then foo else y\r
---\r
-8:18-8:21: There is no instance for <Foo Double>.
\ No newline at end of file
+++ /dev/null
-infix 3 (+)\r
-\r
-a + b = a\r
-\r
-threeTimes x = x + x + x\r
---\r
-5:22-5:23: Operator + is not associative.
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-deepId :: FooBar b => b -> a -> a\r
-deepId count x = deepId2 count x\r
-deepId2 count x = if count <= 0 then x else deepId (count-1) x\r
-\r
-main = deepId (5 :: Integer) "FOO"\r
---\r
-3:11-3:17: Unresolved type class FooBar.
\ No newline at end of file
+++ /dev/null
-importJava "java.lang.System" where\r
- nanoTime :: () -> <Pred> Long\r
-\r
-main = nanoTime ()\r
---\r
-2:24-2:28: Didn't find effect constructor Pred.
\ No newline at end of file
+++ /dev/null
-// Tests that match cases can be given in the same line as the scrutinee\r
-data FooBar a = Foo a | Bar a\r
-extract x = match x with Foo v -> v ; Bar v -> v\r
-main = extract (Foo (3 :: Integer))\r
---\r
-3
\ No newline at end of file
+++ /dev/null
-"asd \r
---\r
-1:1-1:6: Unclosed string literal.
\ No newline at end of file
+++ /dev/null
-"asd \r
-\r
-\r
-asd\r
---\r
-1:1-1:6: Unclosed string literal.
\ No newline at end of file
+++ /dev/null
-import "JavaBuiltin" as Java\r
-\r
-infixl 6 (+)\r
-\r
-class Additive a where \r
- (+) :: a -> a -> a \r
- \r
-instance Additive Double where\r
- x + y = Java.dadd x y\r
-\r
-instance Additive Integer where\r
- x + y = Java.iadd x y\r
- \r
-main = ((1.0 :: Double)+(2.0 :: Double),(3::Integer)+(4::Integer))\r
---\r
-(3.0,7)\r
-\r
+++ /dev/null
-import "JavaBuiltin" as Java\r
-\r
-infixl 6 (+)\r
-\r
-class Additive a where \r
- (+) :: a -> a -> a \r
- \r
-instance Additive Double where\r
- x + y = Java.dadd x y\r
-\r
-instance Additive Integer where\r
- x + y = Java.iadd x y\r
- \r
-instance (Additive a, Additive b) => Additive (a,b) where\r
- (x1,y1) + (x2,y2) = (x1+x2,y1+y2)\r
- \r
-main = (1.0::Double,3::Integer) + (2.0::Double,4::Integer)\r
---\r
-(3.0,7)\r
-\r
+++ /dev/null
-import "JavaBuiltin" as Java\r
-\r
-infixl 7 (*)\r
-infixl 6 (+)\r
-\r
-class Additive a where \r
- (+) :: a -> a -> a \r
-\r
-class (Additive a) => Ring a where\r
- (*) :: a -> a -> a\r
-\r
-instance Additive Double where\r
- x + y = Java.dadd x y\r
-\r
-instance Ring Double where\r
- x * y = Java.dmul x y\r
-\r
-instance Additive Integer where\r
- x + y = Java.iadd x y\r
-\r
-instance Ring Integer where\r
- x * y = Java.imul x y\r
-\r
-main = (1.0 :: Double)*(2.0 :: Double)+(3.0 :: Double)*(4.0 :: Double)\r
---\r
-14.0\r
-\r
+++ /dev/null
-import "Prelude"\r
-\r
-inc :: Ring a => a -> a\r
-inc x = x + 1\r
-\r
-main :: Double\r
-main = inc 34\r
---\r
-35.0
\ No newline at end of file
+++ /dev/null
-// module Foo1
-import "Prelude"
-
-foo :: Integer -> Boolean
-foo i = i == 5
---
-// module Foo2
-import "Prelude"
-
-foo :: Integer -> Integer -> Boolean
-foo i j = i == j
---
-import "Prelude"
-import "Foo1"
-import "Foo2"
-
-main = foo 5 && foo 5 4
---
-false
\ No newline at end of file
+++ /dev/null
-// module Max1
-import "Prelude"
-
-myMax :: Ord a => a -> a -> a
-myMax = max
---
-// module Max2
-import "Prelude"
-
-myMax :: Ord a => a -> a -> a -> a
-myMax a b c = max a (max b c)
---
-import "Prelude"
-import "Max1"
-import "Max2"
-
-main = myMax (1 :: Integer) 2 3 + myMax (3 :: Integer) 2 1 + myMax 4 2 :: Integer
---
-10
-
+++ /dev/null
-// module M1
-import "Prelude"
-
-foo :: Ring a => Boolean -> a -> a
-foo True v = v+1
-foo False v = v+1
---
-// module M2
-import "Prelude"
-
-foo :: Ring a => String -> a -> a
-foo cond v = if cond=="true"
- then v+1
- else v-1
---
-import "Prelude"
-import "M1"
-import "M2"
-
-main = foo False (foo "True" 10) :: Integer
---
-10
-
+++ /dev/null
-import "Prelude"\r
-\r
-"""\r
-Parser is a function from a string and a position in the\r
-string to a possible semantics of a substring and the \r
-end of the substring.\r
-"""\r
-data Parser a = Parser (String -> Integer -> Maybe (a, Integer))\r
-\r
-runParser :: Parser a -> String -> Integer -> Maybe (a, Integer)\r
-runParser (Parser f) = f \r
-\r
-instance Functor Parser where\r
- fmap f (Parser p) = Parser (\input pos -> match p input pos with\r
- Nothing -> Nothing\r
- Just (a, newPos) -> Just (f a, newPos)\r
- )\r
-\r
-instance Monad Parser where\r
- return x = Parser (\_ pos -> Just (x, pos)) \r
- (pa >>= f) = Parser (\input pos -> match runParser pa input pos with\r
- Nothing -> Nothing\r
- Just (a, newPos) -> runParser (f a) input newPos\r
- ) \r
-\r
-(|||) :: Parser a -> Parser a -> Parser a\r
-Parser a ||| Parser b = Parser (\input pos -> match a input pos with\r
- Nothing -> b input pos\r
- Just x -> Just x\r
-) \r
-\r
-keyword :: String -> Parser ()\r
-keyword word = Parser (\input pos ->\r
- if regionMatches word 0 input pos (length word)\r
- then Just ((), pos + (length word))\r
- else Nothing\r
-)\r
-\r
-data List a = Nil | Cons a (List a)\r
-\r
-listSepL :: Parser () -> Parser a -> Parser (List a)\r
-listSepL sep el = mdo\r
- head <- el\r
- tail <- (sep >> listSepL sep el) ||| return Nil\r
- return (Cons head tail) \r
-\r
-fromList :: List a -> [a]\r
-fromList = unfoldr gen\r
- where\r
- gen Nil = Nothing\r
- gen (Cons h t) = Just (h, t)\r
- \r
-listSep :: Parser () -> Parser a -> Parser [a] \r
-listSep sep el = fmap fromList (listSepL sep el) \r
-\r
-aOrB = (keyword "a" >> return "a") ||| (keyword "b" >> return "b")\r
-\r
-myParser = listSep (keyword ",") aOrB\r
-\r
-main = show (runParser myParser "a,b,b,a" 0)\r
---\r
-Just (["a", "b", "b", "a"], 7)
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-data CP = CP Integer String\r
-\r
-//cpName :: CP -> String\r
-cpName CP cp name = name\r
-\r
-connectionPoints :: Integer -> [(CP, CP)]\r
-connectionPoints n = []\r
-\r
-hasTerminalProblems :: Integer -> Boolean\r
-hasTerminalProblems uc =\r
- let cps = connectionPoints uc\r
- cpCount = length cps\r
- dcps = map snd cps\r
- dnames = map cpName dcps\r
- dcpNameCount = length $ unique $ sort dnames\r
- in cpCount != dcpNameCount\r
-\r
-main = "Not OK"\r
---\r
-6:8-6:10: ???
\ No newline at end of file
+++ /dev/null
-// Idea here is to test the following property:\r
-// When a function is called recursively it has locally a monomorphic type.\r
-// Therefore the definition of cons does not work even if it works\r
-// with a proper type annotation.\r
-\r
-data Vec a = Nil | Zero (Vec (a,a)) | One a (Vec (a,a))\r
-\r
-// cons :: a -> Vec a -> Vec a\r
-cons x Nil = One x Nil\r
-cons x (Zero ps) = One x ps\r
-cons x (One y ps) = Zero (cons (x, y) ps)\r
---\r
-11:21-11:42: Expected <Vec (a, a)> got <Vec a>.\r
-11:33-11:34: Type (a, a) is not a subtype of a.\r
-11:36-11:37: Type (a, a) is not a subtype of a.\r
-11:39-11:41: Expected <Vec a> got <Vec (a, a)>.
\ No newline at end of file
+++ /dev/null
-\r
-\r
-class Foo a where\r
- foo :: a\r
- \r
-data List a = Nil | Cons a (List a)\r
-\r
-r x = Cons foo (r x)\r
-\r
-main = (1.0 :: Double)\r
---\r
-1.0
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-data Poly a = Poly [a]\r
-\r
-normalize l = go (length l)\r
- where\r
- go i = if i > 0 && l!(i-1)==zero\r
- then go (i-1)\r
- else take i l \r
-\r
-instance (Eq a, Additive a) => Additive (Poly a) where\r
- zero = Poly []\r
- Poly a + Poly b = \r
- Poly ( \r
- normalize (\r
- zipWith (+) a b + \r
- if la > lb\r
- then drop lb a\r
- else drop la b\r
- )\r
- )\r
- where\r
- la = length a\r
- lb = length b \r
-\r
-instance (Eq a, Ring a) => Ring (Poly a) where\r
- one = Poly [one]\r
- neg (Poly l) = Poly (map neg l)\r
- a - b = a + (neg b)\r
- Poly a * Poly b = \r
- Poly ( if aDeg < bDeg\r
- then [ segSum n 0 n | n <- [0 ..aDeg] ]\r
- + [ segSum n 0 aDeg | n <- [aDeg+1..bDeg] ]\r
- + [ segSum n (n-bDeg) aDeg | n <- [bDeg+1..sumDeg] ]\r
- else [ segSum n 0 n | n <- [0 ..bDeg] ]\r
- + [ segSum n (n-bDeg) n | n <- [bDeg+1..aDeg] ]\r
- + [ segSum n (n-bDeg) aDeg | n <- [aDeg+1..sumDeg] ]\r
- )\r
- where \r
- aDeg = length a - 1\r
- bDeg = length b - 1\r
- sumDeg = aDeg + bDeg\r
- segSum n low high = sum [ a!i * b!(n-i) | i <- [low..high] ]\r
- fromInteger x = Poly [fromInteger x]\r
- \r
-a = Poly [4.0,5.0,8.0,3.0,2.0,1.0]\r
-b = Poly [1.0,0.0,2.0,1.0]\r
-main = a * a + a * b + b * a + b * b - (a+b)*(a+b)\r
---\r
-[]
\ No newline at end of file
+++ /dev/null
-infixr 2 l\r
-infixr 1 r\r
-\r
-l a b = a\r
-r a b = b\r
-\r
-main = (1 :: Integer) `l` (2 :: Integer) `r` (3 :: Integer) `l` (4 :: Integer)\r
---\r
-3
\ No newline at end of file
+++ /dev/null
-import "JavaBuiltin" as Java\r
-\r
-infixl 7 (%)\r
-infixl 6 (+)\r
-infix 4 (==), (<)\r
-\r
-(+) = Java.iadd\r
-(%) = Java.irem\r
-(<) = Java.icmplt\r
-(==) = Java.icmpeq\r
-\r
-isPrime p = isPrimeAux (2 :: Integer) p\r
- where\r
- isPrimeAux d p = if d == p then True\r
- else if p % d == 0 then False\r
- else isPrimeAux (d+1) p\r
- \r
-nextPrime p = if isPrime p \r
- then p\r
- else nextPrime (p+(1 :: Integer)) \r
- \r
-main = nextPrime 32\r
---\r
-37
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
- \r
-main = do\r
- r = ref 13\r
- r := 14\r
- getRef r\r
---\r
-14
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-data RealWorld = RealWorld\r
-data IO a = IO (RealWorld -> (RealWorld, a))\r
-\r
-@inline\r
-unIO (IO m) = m \r
-\r
-instance Functor IO where\r
- @inline\r
- fmap f x = x >>= (return . f)\r
-\r
-instance Monad IO where\r
- @inline\r
- return x = IO (\s -> (s, x))\r
- \r
- @inline\r
- (IO m) >>= f = IO (\s -> do\r
- (newS, v) = m s\r
- unIO (f v) newS \r
- )\r
-\r
-@inline\r
-runIO :: IO a -> a\r
-runIO m = snd (unIO m RealWorld)\r
-\r
-main = runIO (return (13 :: Integer))\r
---\r
-13\r
+++ /dev/null
-import "Prelude"\r
-\r
-@private\r
-repeat :: Integer -> (() -> <e> a) -> <e> ()\r
-repeat n proc = \r
- if n > 0 then do\r
- proc ()\r
- repeat (n-1) proc\r
- else () \r
-\r
-main = do\r
- a = ref 1 \r
- repeat 3 (\() -> a := 2)\r
- getRef a\r
---\r
-2
\ No newline at end of file
+++ /dev/null
-import "JavaBuiltin" as Java\r
-\r
-infixl 7 (*)\r
-infixl 6 (+)\r
-\r
-(+) :: Double -> Double -> Double\r
-(+) = Java.dadd\r
-(*) :: Double -> Double -> Double\r
-(*) = Java.dmul\r
-\r
-importJava "java.lang.Math" where\r
- sqrt :: Double -> Double\r
- sin :: Double -> Double\r
- cos :: Double -> Double\r
-\r
-square x = x * x\r
-\r
-length x y = sqrt (square x + square y)\r
-\r
-pythagoras a = length (cos a) (sin a)\r
-\r
-main = pythagoras 2.0\r
---\r
-1.0\r
+++ /dev/null
-import "StandardLibrary"\r
-\r
-// Actual program\r
-\r
-"""This function returns either 0 or 1 such that\r
-the expected value is pi/4"""\r
-approximatePi :: () -> <Random> Double\r
-approximatePi () = if x*x + y*y < 1 then 1 else 0\r
- where\r
- x = randomDouble\r
- y = randomDouble\r
-\r
-averageOfNRepeats n f = sum [f () | n <- [1..n]] / fromInteger n\r
-\r
-betterApproximatePi () = averageOfNRepeats 1000 approximatePi * 4\r
-\r
-main = withSeed 13 (betterApproximatePi ())\r
---\r
-3.068
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-main = [5..9]\r
---\r
-[5, 6, 7, 8, 9]
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-data XYS = XYS { x :: Double, y :: Double, s :: String }\r
-\r
-len XYS {x = x, y = y} = sqrt (x*x + y*y)\r
-\r
-main = len (XYS { x = 4, y = 3, s = "Hello world!" })\r
--- \r
-5.0
\ No newline at end of file
+++ /dev/null
-import "Prelude"
-
-data Vec = Vec { x :: Double, y :: Double }
-deriving instance Show Vec
-
-createVec x y = Vec {x, y}
-sumVec Vec { x1, y1 } Vec { x2, y2 } = Vec { x = x1+x2, y = y1 + y2 }
-
-main = sumVec (createVec 1 2) (createVec 3 4)
---
-(Vec 4.0 6.0)
\ No newline at end of file
+++ /dev/null
-import "JavaBuiltin" as Java\r
-\r
-infixl 6 (+), (-)\r
-\r
-class Num a where \r
- (+) :: a -> a -> a\r
- (-) :: a -> a -> a\r
- isZero :: a -> Boolean\r
- one :: a \r
- \r
-instance Num Integer where\r
- x + y = Java.iadd x y\r
- x - y = Java.isub x y\r
- isZero x = Java.icmpeq Java.iconst_0 x\r
- one = Java.iconst_1\r
- \r
-even x = if isZero x then True else odd (x - one)\r
-odd x = if isZero x then False else even (x - one) \r
- \r
-main = odd (8 :: Integer)\r
---\r
-false\r
-\r
+++ /dev/null
-a = b\r
-b = a\r
-\r
-main = a\r
---\r
-???: Variables defined recursively must all be functions.
\ No newline at end of file
+++ /dev/null
-f g = a\r
- where \r
- a = g a\r
---\r
-3:11-3:12: Couldn't resolve variable a.
\ No newline at end of file
+++ /dev/null
-data Nat = O | S Nat\r
-\r
-// It is important for this test that even and or are not annotated\r
-even O = True\r
-even (S x) = odd x\r
-\r
-odd O = False\r
-odd (S x) = even x\r
-\r
-main = even (S (S (S (S (S O)))))\r
---\r
-false
\ No newline at end of file
+++ /dev/null
-(foo, bar) = (foo, "Hello world!")\r
-\r
-main = "ERROR"\r
---\r
-1:1-1:11: Illegal left hand side of the definition.
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-// Version 1, 'untyped'\r
-data Color = R | B \r
-\r
-deriving instance Show Color\r
-\r
-data RB a = E | T Color (RB a) a (RB a)\r
-\r
-rbToList :: RB a -> [a]\r
-rbToList E = []\r
-rbToList (T _ l a r) = rbToList l + [a] + rbToList r\r
-\r
-deriving instance (Show a) => Show (RB a)\r
-\r
-// Insertion and membership test as by Okasaki\r
-insert :: Ord a => a -> RB a -> RB a\r
-insert x s = (match ins s with T _ a z b -> T B a z b) \r
- where\r
- ins E = T R E x E\r
- ins s = match s with\r
- T B a y b ->\r
- if x<y \r
- then balance (ins a) y b\r
- else if x>y \r
- then balance a y (ins b)\r
- else s\r
- T R a y b ->\r
- if x<y\r
- then T R (ins a) y b\r
- else if x>y \r
- then T R a y (ins b)\r
- else s\r
-\r
-member :: Ord a => a -> RB a -> Boolean\r
-member x E = False\r
-member x (T _ a y b)\r
- | x<y = member x a\r
- | x>y = member x b\r
- | otherwise = True\r
-\r
-// balance: first equation is new, to make it work with a weaker invariant\r
-balance :: RB a -> a -> RB a -> RB a\r
-balance (T R a x b) y (T R c z d) = T R (T B a x b) y (T B c z d)\r
-balance (T R (T R a x b) y c) z d = T R (T B a x b) y (T B c z d)\r
-balance (T R a x (T R b y c)) z d = T R (T B a x b) y (T B c z d)\r
-balance a x (T R b y (T R c z d)) = T R (T B a x b) y (T B c z d)\r
-balance a x (T R (T R b y c) z d) = T R (T B a x b) y (T B c z d)\r
-balance a x b = T B a x b\r
-\r
-// deletion a la SMK \r
-delete :: Ord a => a -> RB a -> RB a\r
-delete x t = (match del t with \r
- T _ a y b -> T B a y b\r
- _ -> E)\r
- where\r
- del E = E\r
- del (T _ a y b)\r
- | x<y = delformLeft a y b\r
- | x>y = delformRight a y b\r
- | otherwise = app a b\r
- delformLeft a y b= match a with\r
- T B _ _ _ -> balleft (del a) y b\r
- _ -> T R (del a) y b\r
- delformRight a y b = match b with\r
- T B _ _ _ -> balright a y (del b)\r
- _ -> T R a y (del b)\r
-\r
-balleft :: RB a -> a -> RB a -> RB a\r
-balleft (T R a x b) y c = T R (T B a x b) y c\r
-balleft bl x (T B a y b) = balance bl x (T R a y b)\r
-balleft bl x (T R (T B a y b) z c) = T R (T B bl x a) y (balance b z (sub1 c))\r
-\r
-balright :: RB a -> a -> RB a -> RB a\r
-balright a x (T R b y c) = T R a x (T B b y c)\r
-balright (T B a x b) y bl = balance (T R a x b) y bl\r
-balright (T R a x (T B b y c)) z bl = T R (balance (sub1 a) x b) y (T B c z bl)\r
-\r
-sub1 :: RB a -> RB a\r
-sub1 (T B a x b) = T R a x b\r
-sub1 _ = fail "invariance violation"\r
-\r
-app :: RB a -> RB a -> RB a\r
-app E x = x\r
-app x E = x\r
-app (T R a x b) (T R c y d) =\r
- match app b c with\r
- T R b' z c' -> T R(T R a x b') z (T R c' y d)\r
- bc -> T R a x (T R bc y d)\r
-app (T B a x b) (T B c y d) = \r
- match app b c with\r
- T R b' z c' -> T R(T B a x b') z (T B c' y d)\r
- bc -> balleft a x (T B bc y d)\r
-app a (T R b x c) = T R (app a b) x c\r
-app (T R a x b) c = T R a x (app b c)\r
-\r
-testList = [4,6,2,7,4,7,2,5]\r
-\r
-main = rbToList (foldl (flip insert) E testList)\r
---\r
-[2, 4, 5, 6, 7]
\ No newline at end of file
+++ /dev/null
-import "StandardLibrary"
-
-Concat ?x ?y ?z :-
- @bbf 1
- ?z = ?x + ?y
-
- @bfb 0.5
- startsWith ?z ?x
- ?y = drop (length ?x) ?z
-
- @fbb 0.5
- endsWith ?z ?y
- ?x = take (length ?z - length ?y) ?z
-
-main = select ?y where
- Concat "Hello " ?y "Hello world!"
---
-[world!]
\ No newline at end of file
+++ /dev/null
-import "StandardLibrary"
-
-MyExecute ?procedure :-
- @enforce
- Execute (?procedure "Foo")
-
-main = do
- v = ref ""
- enforce MyExecute (v :=)
- getRef v
---
-Foo
\ No newline at end of file
+++ /dev/null
-invalidProject :: (a,a) -> a\r
-invalidProject (a,a) = a\r
-\r
-main = "Not to be executed!"\r
---\r
-2:19-2:20: Repeated variable a in pattern.
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-test :: () -> [Integer]\r
-test _ = do\r
- header = [0]\r
- rows = map (\foo -> map (\bar -> bar) [foo]) [1..5]\r
- foldl (+) header rows\r
- \r
-main = test ()\r
---\r
-[0, 1, 2, 3, 4, 5]
\ No newline at end of file
+++ /dev/null
-import "Prelude" hiding (scanl)\r
-\r
-scanl :: (b -> a -> <e> b) -> b -> [a] -> <e> [b]\r
-scanl f initial l = build (loop initial 0)\r
- where\r
- len = length l\r
- loop cur i accum cons = let nl = cons accum cur\r
- in if i==len\r
- then nl\r
- else loop (f cur (l!i)) (i+1) nl cons\r
- \r
-main = scanl (+) 0 [1,2,3]\r
---\r
-[0, 1, 3, 6]
\ No newline at end of file
+++ /dev/null
-import "Prelude" hiding (findFirst)\r
-\r
-infinity = 1e9\r
-\r
-@inline\r
-findFirst :: (a -> <e> Maybe b) -> [a] -> <e> Maybe b\r
-findFirst f l = loop 0\r
- where\r
- len = length l\r
- loop i \r
- | i >= len = Nothing\r
- | otherwise = match f (l!i) with\r
- s @ (Just _) -> s\r
- Nothing -> loop (i+1)\r
-\r
-dfsFirst :: (a -> <e> Boolean) -> (a -> <e> [a]) -> [a] -> <e> (Maybe a)\r
-dfsFirst acceptable successors initial = tryAll initial\r
- where\r
- tryAll l = findFirst loop l\r
- loop p \r
- | acceptable p = Just p\r
- | otherwise = tryAll (successors p)\r
-\r
-data Weighted a = Weighted a Double\r
-\r
-//type SearchAlgorithm e a =\r
-// (a -> <e> Boolean) -> (a -> <e> [Weighted a]) -> [Weighted a] -> <e> Weighted (Maybe a)\r
- \r
-//dfs :: SearchAlgorithm e a\r
-dfs :: (a -> <e> Boolean) -> (a -> <e> [Weighted a]) -> [Weighted a] -> <e> Weighted (Maybe a)\r
-dfs acceptable successors initial = foldl loop (Weighted Nothing infinity) initial\r
- where\r
- loop best@(Weighted _ bestW) (Weighted p w)\r
- | w >= bestW = best\r
- | acceptable p = Weighted (Just p) w\r
- | otherwise = foldl loop best\r
- $ map (\(Weighted p' w') -> Weighted p' (w+w'))\r
- $ successors p\r
-\r
-/*\r
-bfs :: SearchAlgorithm e a\r
-\r
-aStar :: (a -> <e> Double) -> SearchAlgorithm e a\r
-*/\r
-main = "Hello"\r
---\r
-Hello
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-main = map (1/) $ map (*3) [1,2,3]\r
---\r
-[0.3333333333333333, 0.16666666666666666, 0.1111111111111111]
\ No newline at end of file
+++ /dev/null
-import "StandardLibrary"\r
-\r
-main = let\r
- l = [1..3] \r
- in\r
- select (?x,?y) where \r
- ?x <- l\r
- ?y <- l\r
- ?x = ?y\r
---\r
-[(1,1), (2,2), (3,3)]
\ 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 a (r!1) (b!3)
- Statement (b!1) (r!0) (b!2)
- R a :- {}
- R ?x :- R ?y ; Statement ?y (r!0) ?x
- S ?x :- R ?x ; Statement ?x (r!0) _
- sort $ map uriOf $ select ?x where S ?x
---
-[a, b1]
+++ /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]
+++ /dev/null
-import "StandardLibrary"
-import "Minigraph"
-
-main = withGraph do
- a = resource "a"
- b = map resource ["b0", "b1", "b2"]
- r = map resource ["r0", "r1"]
-
- enforce
- Statement a (r!0) (b!0)
- Statement a (r!0) (b!1)
- Statement a (r!1) (b!1)
- Statement a (r!1) (b!2)
- sort $ map uriOf $ select ?x where
- <|> Statement a (r!0) ?x
- Statement a (r!1) ?x
---
-[b0, b1, b1, b2]
+++ /dev/null
-import "StandardLibrary"
-import "Minigraph"
-
-main = withGraph do
- r = map resource ["r0", "r1"]
- sort $ map uriOf $ select ?x where
- Statement ?y (r!0) ?x
- Statement ?x (r!1) ?y
---
-6:24-8:30: Failed to compile the query.
-Unsolved variables: ?x, ?y
\ No newline at end of file
+++ /dev/null
-import "StandardLibrary"
-
-main = select ?x where
- (?x,?y) = (1,2)
---
-[1]
\ No newline at end of file
+++ /dev/null
-import "StandardLibrary"
-
-main = select ?x where
- (?x, 3) <- [(1,2),(2,3),(3,4)]
---
-[2]
\ No newline at end of file
+++ /dev/null
-import "StandardLibrary"
-
-Foo ?a ?b ?l :-
- @ffb
- (?a,?b) <- ?l
-
-main = select ?x where
- Foo ?x 3 [(1,2),(2,3),(3,4)]
---
-[2]
\ No newline at end of file
+++ /dev/null
-import "StandardLibrary"
-
-s1 = [1,2,3]
-s2 = [1,3]
-
-main = do
- C ?x :-
- ?x <- s1
- <!> ?x <- s2
- select ?x where C ?x
---
-[2]
\ No newline at end of file
+++ /dev/null
-class Ord a where\r
- min :: Ord a => a -> a -> a\r
-\r
-main = "Not to be executed."\r
---\r
-2:12-2:15: Unresolved type class Ord.
\ No newline at end of file
+++ /dev/null
-import "Prelude"
-
-rt :: Serializable a => a -> a
-rt v = deserialize (serialize v)
-
-main :: String
-main = show (
- (rt "Hello", rt ()),
- (rt 1.2 :: Double, rt 1.2 :: Float, 3 :: Integer, 4 :: Long),
- rt (Just (1 :: Integer)),
- (rt [1::Integer,2,3], rt [[1::Integer,2],[3,4]], fromDoubleArray (rt (toDoubleArray [3::Double,2,1])))
- )
---
-(("Hello", ()), (1.2, 1.2, 3, 4), Just 1, ([1, 2, 3], [[1, 2], [3, 4]], [3.0, 2.0, 1.0]))
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-import "Serialization"\r
-\r
-rt :: IO a => a -> a\r
-rt v = readByteArray (writeByteArray v)\r
-\r
-main = show (\r
- (rt "Hello", rt ()),\r
- (rt 1.2 :: Double, rt 1.2 :: Float, 3 :: Integer, 4 :: Long),\r
- rt (Just (1 :: Integer)),\r
- (rt [1::Integer,2,3], rt [[1::Integer,2],[3,4]], fromDoubleArray (rt (toDoubleArray [3,2,1])))\r
- )\r
---\r
-(("Hello", ()), (1.2, 1.2, 3, 4), Just 1, ([1, 2, 3], [[1, 2], [3, 4]], [3.0, 2.0, 1.0]))
\ No newline at end of file
+++ /dev/null
-import "Prelude"
-import "Serialization" as Serialization
-
-rt :: Serialization.IO a => a -> a
-rt v = Serialization.readByteArray (Serialization.writeByteArray v)
-
-data FooBar a = Foo Integer | Bar a
-
-deriving instance (Show a) => Show (FooBar a)
-deriving instance (Serialization.IO a) => Serialization.IO (FooBar a)
-
-/*
-instance IO FooBar where
- read s = match Serialization.read s :: Integer with
- 0 -> Foo (Serialization.read s)
- 1 -> Bar (Serialization.read s)
- write s (Foo x) = do Serialization.write s (0 :: Integer) ; Serialization.write s x
- write s (Bar x) = do Serialization.write s (1 :: Integer) ; Serialization.write s x
-*/
-main = show (rt (Foo 3 :: FooBar Double))
---
-Foo 3
\ No newline at end of file
+++ /dev/null
-import "StandardLibrary"\r
-\r
-s1 = Set.set [3,2,1,4]\r
-s2 = Set.set [9,8,3,2]\r
-s1s2 = Set.union s1 s2\r
-\r
-main = show s1s2\r
---\r
-set [1, 2, 3, 4, 8, 9]
\ No newline at end of file
+++ /dev/null
-// Idea here is that the type variable in the top level type annotation\r
-// and the type annotation in the expression should be the same type.\r
-id :: a -> a\r
-id x = (x :: a)\r
-\r
-main = id "OK"\r
---\r
-OK
\ No newline at end of file
+++ /dev/null
-data List a = Nil | Cons a (List a)\r
-\r
-@private\r
-@inline\r
-build :: (forall a. a -> (b -> a -> a) -> a) -> List b\r
-build f = f Nil Cons\r
-\r
-@private\r
-foldr :: (a -> b -> b) -> b -> List a -> b\r
-foldr cons nil Nil = nil\r
-foldr cons nil (Cons h t) = cons h (foldr cons nil t)\r
-\r
-@private\r
-@inline\r
-singleton :: a -> List a\r
-singleton x = build (\nil cons -> cons x nil)\r
-\r
-@private\r
-@inline\r
-last :: List a -> a -> a\r
-last l def = foldr (\x _ -> x) def l\r
-\r
-main = last (singleton "Hello") "Foo"\r
---\r
-Hello
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-main = show [(1,2),(3,4),(5,6)]\r
---\r
-[(1, 2), (3, 4), (5, 6)]
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-// --- Signals ------------------------------------------------------\r
-\r
-data Signal =\r
- SigSum [Signal]\r
- | SigConst Double\r
- | SigNeg Signal\r
- | SigMul [Signal]\r
-\r
-deriving instance Eq Signal\r
-deriving instance Hashable Signal\r
-deriving instance Show Signal\r
-\r
-instance Additive Signal where\r
- zero = SigConst 0\r
- a + b = SigSum [a,b]\r
- sum l = SigSum l\r
-\r
-instance Ring Signal where\r
- one = SigConst 1\r
- neg a = SigNeg a\r
- fromInteger i = SigConst (fromInteger i)\r
- a * b = SigMul [a,b]\r
-\r
-/*\r
-instance Real Signal where\r
- fromDouble d = SigConst d\r
-*/\r
-\r
-main :: Signal\r
-main = 1 + 2 * 3 - 4 \r
---\r
-???
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-main = (sin + const 1) 0\r
---\r
-1.0
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-main :: [Integer]\r
-main = sort [1,5,2,4,3]\r
---\r
-[1, 2, 3, 4, 5]
\ No newline at end of file
+++ /dev/null
-import "JavaBuiltin" as Java\r
-\r
-importJava "org.simantics.scl.runtime.Lists" where\r
- sortWith :: (a -> a -> Integer) -> [a] -> [a]\r
-\r
-//@JavaStaticMethod "org.simantics.scl.runtime.Lists.sortWith"\r
-//sortWith :: (a -> a -> Integer) -> [a] -> [a]\r
-\r
-\r
-//sortWith = Java.staticMethod "org.simantics.scl.runtime.Lists.sortWith"\r
-\r
-dumbCompare :: a -> a -> Integer\r
-dumbCompare x y = 0\r
-\r
-dumbSort = sortWith dumbCompare \r
-\r
-main = "Foo"\r
---\r
-Foo
\ No newline at end of file
+++ /dev/null
-data Either a b = Left a | Right b\r
-\r
-data List a = Nil | Cons a (List a)\r
-\r
-data Nat = Zero | Succ Nat\r
-\r
-sum Zero a = a\r
-sum a Zero = a\r
-sum (Succ a) (Succ b) = Succ (Succ (sum a b))\r
-\r
-sum_append xs ys\r
- = go Zero (Left xs)\r
- where\r
- go z (Left xs)\r
- = match xs with\r
- Nil -> go z (Right ys)\r
- Cons x xs' -> go (sum x z) (Left xs')\r
- go z (Right ys)\r
- = match ys with\r
- Nil -> z\r
- Cons y ys' -> go (sum y z) (Right ys')\r
-\r
-main = "Hello world!"\r
---\r
-Hello world!
\ No newline at end of file
+++ /dev/null
-main = fail "badly"
---
-???
\ No newline at end of file
+++ /dev/null
-import "JavaBuiltin" as Java\r
-\r
-data Either a b = Left a | Right b\r
-\r
-data Stream a = Stream (s -> Step a s) s\r
-data Step a s = Done | Yield a s | Skip s\r
-\r
-// stream :: [a] -> Stream a\r
-// unstream :: Stream a -> [a] \r
-// streamRev :: [a] -> Stream a\r
-// unstreamRev :: Stream a -> [a]\r
-\r
-//toStream :: [a] -> Stream a\r
-//toStream l = Stream (\i -> if i >= length l then Done else Yield (get l i) (i+1)) 0\r
-\r
-filterS :: (a -> Boolean) -> Stream a -> Stream a\r
-filterS p (Stream next0 s0) = Stream next s0\r
- where\r
- next s = match next s with\r
- Done -> Done\r
- Skip s -> Skip s \r
- Yield a s -> if p a then Yield a s else Skip s\r
-\r
-mapS :: (a -> b) -> Stream a -> Stream b\r
-mapS f (Stream next0 s0) = Stream next s0\r
- where\r
- next s = match next0 s with\r
- Done -> Done\r
- Skip s -> Skip s \r
- Yield a s -> Yield (f a) s\r
- \r
-appendS :: Stream a -> Stream a -> Stream a\r
-appendS (Stream next1 s1) (Stream next2 s2) = Stream next (Left s1)\r
- where\r
- next (Left s) = match next1 s with\r
- Done -> Skip (Right s2)\r
- Skip s -> Skip (Left s) \r
- Yield a s -> Yield a (Left s)\r
- next (Right s) = match next2 s with\r
- Done -> Done\r
- Skip s -> Skip (Right s) \r
- Yield a s -> Yield a (Right s) \r
-\r
-decomposeS :: Stream a -> Maybe (a, Stream a)\r
-decomposeS (Stream next s0) = loop s0\r
- where\r
- loop s = match next s with\r
- Done -> Nothing\r
- Skip s -> loop s\r
- Yield a s -> Just (a, Stream next s) \r
-\r
-returnS :: a -> Stream a\r
-returnS x = Stream next True\r
- where \r
- next True = Yield x False\r
- next False = Done\r
- \r
-isEmptyS :: Stream a -> Boolean \r
-isEmptyS (Stream next s0) = loop s0\r
- where\r
- loop s = match next s with\r
- Done -> True\r
- Skip s -> loop s \r
- Yield _ _ -> False\r
- \r
-foldlS :: (a -> b -> a) -> a -> Stream b -> a\r
-foldlS f init (Stream next s0) = go init s0\r
- where\r
- go cur s = match next s with\r
- Done -> cur\r
- Skip s -> go cur s\r
- Yield x s -> go (f cur x) s\r
- \r
-scanlS :: (a -> b -> a) -> a -> Stream b -> Stream a\r
-scanlS f init (Stream next0 s0) = Stream next (s0, init)\r
- where\r
- next (s,v) = match next0 s with\r
- Done -> Done\r
- Skip s -> Skip (s, v)\r
- Yield x s -> Yield v (s, f v x) \r
- \r
-concatMapS :: (a -> Stream b) -> Stream a -> Stream b\r
-concatMapS f (Stream next0 s0) = Stream next (s0, Nothing)\r
- where\r
- next (s, Nothing) = match next0 s with\r
- Done -> Done\r
- Skip s -> Skip (s, Nothing)\r
- Yield x s -> Skip (s, Just (f x))\r
- next (s0, Just (Stream next1 s1)) = match next1 s1 with\r
- Done -> Skip (s0, Nothing)\r
- Skip s -> Skip (s0, Just (Stream next1 s))\r
- Yield x s -> Yield x (s0, Just (Stream next1 s))\r
-\r
-zipWithS :: (a -> b -> c) -> Stream a -> Stream b -> Stream c\r
-zipWithS f (Stream next0 s0) (Stream next1 s1) = Stream next (s0, s1, Nothing)\r
- where\r
- next (s0, s1, Nothing) = match next0 s0 with\r
- Done -> Done\r
- Skip s -> Skip (s, s1, Nothing)\r
- Yield x s -> Skip (s, s1, Just x)\r
- next (s0, s1, Just x) = match next1 s1 with\r
- Done -> Done\r
- Skip s -> Skip (s0, s, Just x)\r
- Yield y s -> Yield (f x y) (s0, s, Nothing)\r
-\r
-guardS :: Boolean -> Stream a -> Stream a\r
-guardS b (Stream next0 s0) = Stream next (b, s0)\r
- where\r
- next (False, _) = Done\r
- next (True, s) = match next0 s with\r
- Done -> Done\r
- Skip s -> Skip (True, s)\r
- Yield x s -> Yield x (True, s)\r
-/*\r
-takeS :: Integer -> Stream a -> Stream a\r
-takeS count (Stream next0 s0) = Stream next (count, s0)\r
- where\r
- next (count, s) = if count <= 0 then Done\r
- else match next0 s with\r
- Done -> Done\r
- | Skip s -> Skip (count, s)\r
- | Yield x s -> Yield x (count, s)\r
-*/\r
-repeatS :: a -> Stream a\r
-repeatS v = Stream next ()\r
- where\r
- next () = Yield v ()\r
-\r
-iterateS :: (a -> a) -> a -> Stream a\r
-iterateS f v = Stream next v\r
- where\r
- next v = Yield v (f v)\r
- \r
-main :: Integer\r
-main = foldlS Java.iadd (0 :: Integer) \r
- (appendS (appendS (returnS (1 :: Integer)) \r
- (returnS (2 :: Integer))) (returnS (3 :: Integer)))\r
---\r
-6
\ No newline at end of file
+++ /dev/null
-main = "a\nb\"c\'d"\r
---\r
-a\r
-b"c'd\r
---\r
-main = "a\u0053"\r
---\r
-aS\r
---\r
-main = "a\xb"\r
---\r
-1:8-1:10: Illegal string escape character.\r
+++ /dev/null
-import "Prelude"\r
-\r
-f x = x + 1\r
-\r
-g a b = """\(a) + \(b) = \(a+b)"""\r
-\r
-main = "f 3 = \(f 3), " + g 1 2\r
---\r
-f 3 = 4, 1 + 2 = 3
\ No newline at end of file
+++ /dev/null
-stringSum :: String -> Integer\r
-stringSum "(\(a),\(b),\(c))" = a + b + c\r
-\r
-main = stringSum "(1,2,3)"\r
---\r
-6
\ No newline at end of file
+++ /dev/null
-main :: Integer\r
-main = match "Bar" with\r
- "Foo" -> 1\r
- "Bar" -> 2\r
- _ -> 3\r
---\r
-2
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-f :: Integer -> Double\r
-f m = sum [1/(fromInteger x) | x <- [1..m]]\r
-\r
-main = f 100\r
---\r
-5.187377517639621\r
+++ /dev/null
-import "StandardLibrary"\r
-\r
-main = do \r
- (r,t) = Debug.time (foldl (+) 0 \r
- $ map (\(_,_,z) -> z) \r
- $ [(a,b,c) | a <- [1..50], b <- [1..50], c <- [1..50], a*a + b*b == c*c])\r
- print t\r
- r\r
---\r
-1172
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-main = sin 1 2\r
---\r
-3:8-3:11: Constrain Real (a -> b) contains free variables not mentioned in the type of the value.\r
-3:14-3:15: Constrain Ring a contains free variables not mentioned in the type of the value.
\ No newline at end of file
+++ /dev/null
-import "StandardLibrary"
-import "Minigraph"
-import "MMap" as MMap
-
-consistsOf :: <Graph> Integer
-consistsOf = resource "consistsOf"
-instanceOf :: <Graph> Integer
-instanceOf = resource "instanceOf"
-areConnected :: <Graph> Integer
-areConnected = resource "areConnected"
-from :: <Graph> Integer
-from = resource "from"
-to :: <Graph> Integer
-to = resource "to"
-
-element :: <Graph> Integer
-element = resource "Element"
-connection :: <Graph> Integer
-connection = resource "Connection"
-
-mapping relation MapDiagrams Integer Integer
-
-rule ElementsRule where
- @when
- MapDiagrams ?dA ?dB
-
- @from
- Statement ?dA consistsOf ?elA
- Statement ?elA instanceOf element
-
- @to
- Statement ?dB consistsOf ?elB
- Statement ?elB instanceOf element
-
- @where
- MapElements ?elA ?elB
-
-rule ConnectionsRule where
- @when
- MapElements ?elA1 ?elB1
- MapElements ?elA2 ?elB2
-
- @from
- Statement ?elA1 areConnected ?elA2
-
- @to
- Statement ?conn instanceOf connection
- Statement ?conn from ?elB1
- Statement ?conn to ?elB2
-
-foo :: <Graph,Proc> ()
-foo = transformation OneShotForward where
- MapDiagrams 0 0
-
-main = withGraph do
- foo
- "OK"
---
-OK
+++ /dev/null
-import "StandardLibrary"
-
-mapping relation Fib Integer Integer
-
-rule FibRecurrence where
- @when
- Fib ?n ?a
- Fib (?n+1) ?b
- ?n < 20
-
- @where
- Fib (?n+2) (?a + 1)
-/*
-rule PrintIt where
- @when
- Fib ?n ?a
-
- @to
- Execute (print "\(?n) -> \(?a)")
-*/
-main = transformation OneShotForward where
- Fib 0 1
- Fib 1 1
---
-()
+++ /dev/null
-import "StandardLibrary"
-
-mapping relation Fib Integer Integer
-
-rule FibRecurrence where
- @when
- Fib ?n (?a + ?b)
- ?n >= 2
-
- @where
- Fib (?n-1) ?b
- Fib (?n-2) ?a
-
-rule Init where
- @when
- Fib ?x 1
- ?x < 2
-
-rule Seed where
- @where
- Fib 20 ?hmm
-
-rule PrintIt where
- @when
- Fib ?n ?a
-
- @to
- Execute (print "\(?n) -> \(?a)")
-
-main = transformation OneShotForward where
---
-()
+++ /dev/null
-import "StandardLibrary"
-
-mapping relation M Integer (Integer,Integer)
-
-rule Mix where
- @when
- M ?a (?b, ?c)
- ?a <= 10
-
- @where
- M (?a + 1) (?c, ?b)
-
-rule PrintIt where
- @when
- M ?a (?b,?c)
-
- @to
- Execute (print "\(?a) -> \(?b), \(?c)")
-
-rule Seed where
- @where
- M 0 (1,?x)
- M 10 (?y,2)
-
-main = transformation OneShotForward where
---
-()
+++ /dev/null
-import "StandardLibrary"
-
-Foo ?x :-
- @enforce 1
- Execute (?x := (1 :: Integer))
-
-Bar ?x :-
- @enforce 2
- Execute (if getRef ?x == 1 then () else fail "Test failed.")
-
-rule DoIt where
- @from
- ?x = ref (0 :: Integer)
-
- @to
- Bar ?x
- Foo ?x
-
-main :: ()
-main = transformation OneShotForward where
---
-()
+++ /dev/null
-import "StandardLibrary"
-
-mapping relation Foo String String
-
-rule DoIt where
- @when
- Foo ?a ?b
-
- @to
- Foo ?b "c"
-
-main = transformation OneShotForward where
- Foo "a" "b"
---
-10:9-10:11: Cannot resolve the variable ?b using the source patterns.
\ No newline at end of file
+++ /dev/null
-import "StandardLibrary"
-
-Foo ?x :-
- @enforce
- Execute (iterList printString [?x :: String])
-
-
-rule DoIt where
- @to
- Foo "Hello world!"
-
-main = transformation OneShotForward where
---
-()
+++ /dev/null
-import "StandardLibrary"
-
-rule A where
- @to
- Execute (print "A")
-
-rule B where
- @to
- Execute (print "B")
-
-rule C where
- @to
- Execute (print "C")
-
-main = transformation OneShotForward where
---
-()
+++ /dev/null
-id0 () = ()\r
-\r
-id0A :: () -> ()\r
-id0A () = ()\r
-\r
-id2 (a,b) = (a,b)\r
-\r
-id2A :: (a,b) -> (a,b)\r
-id2A (a,b) = (a,b)\r
-\r
-id3 (a,b,c) = (a,b,c)\r
-\r
-id3A :: (a,b,c) -> (a,b,c)\r
-id3A (a,b,c) = (a,b,c)\r
-\r
-main = id3 (1 :: Integer,id0 (),3 :: Integer)\r
---\r
-(1,(),3)
\ No newline at end of file
+++ /dev/null
-// This is just a restricted version of Tuples test\r
-id0 () = ()\r
-\r
-main = id0 ()\r
---\r
-()
\ No newline at end of file
+++ /dev/null
-\r
-type Id = Integer\r
-\r
-incrementId :: Id -> Id\r
-incrementId x = x\r
-\r
-main = incrementId 3\r
---\r
-3
\ No newline at end of file
+++ /dev/null
-type List a = [a]
-
-convert :: List Integer -> List Double
-convert v = v
-
-main = "Not to be executed."
---
-4:13-4:14: Expected <[Double]> got <[Integer]>.
\ No newline at end of file
+++ /dev/null
-type IntegerList = [Integer]
-type DoubleList = [Double]
-
-convert :: IntegerList -> DoubleList
-convert v = v
-
-main = "Not to be executed."
---
-5:13-5:14: Expected <[Double]> got <[Integer]>.
\ No newline at end of file
+++ /dev/null
-type Foo = Bar
-type Bar = Integer
-main = 1 :: Foo
---
-1
---
-type Bar = Integer
-type Foo = Bar
-main = 1 :: Foo
---
-1
---
-type Foo = Foo
-main = 1 :: Foo
---
-1:1-1:15: Type alias has a self reference.
---
-type Foo = Bar
-type Bar = Foo
-main = 1 :: Foo
---
-1:1-1:15: Recursively defined type alias (Foo, Bar).
\ No newline at end of file
+++ /dev/null
-id x = x :: Integer\r
-\r
-main = id "foo"\r
---\r
-3:11-3:16: Expected <Integer> got <String>.
\ No newline at end of file
+++ /dev/null
-id (x :: Integer) = x\r
-\r
-main = id "foo"\r
---\r
-3:11-3:16: Expected <Integer> got <String>.
\ No newline at end of file
+++ /dev/null
-\r
-class Foo a where\r
- foo :: a -> Integer\r
- \r
-instance Foo Integer where\r
- foo x = x\r
- \r
-main = foo (13 :: Integer)\r
---\r
-13
\ No newline at end of file
+++ /dev/null
-import "JavaBuiltin" as Java\r
-\r
-(+) = Java.iadd\r
-\r
-class Foo a where\r
- foo :: a -> Integer\r
- /*\r
-class (Foo a) => Bar a where\r
- bar :: a -> Integer\r
- */\r
-instance Foo Integer where\r
- foo x = x+1\r
- /* \r
-instance Bar Integer where\r
- bar x = x+2\r
-*/\r
-data X a = X a\r
-\r
-instance (Foo a) => Foo (X a) where\r
- foo (X a) = foo a\r
- /*\r
-instance (Bar a) => Bar (X a) where\r
- bar (X a) = bar a*/\r
- \r
-main = foo (X (1 :: Integer))\r
-// + bar (X (2 :: Integer))\r
---\r
-2
\ No newline at end of file
+++ /dev/null
-import "JavaBuiltin" as Java\r
-\r
-importJava "org.simantics.scl.runtime.Lists" where\r
- foldl :: (a -> b -> a) -> a -> [b] -> a\r
-\r
-class Additive a where\r
- zero :: a\r
- (+) :: a -> a -> a \r
- \r
- sum :: [a] -> a\r
- sum = foldl (+) zero \r
- \r
-instance (Additive a, Additive b, Additive c) => Additive (a, b, c) where\r
- zero = (zero, zero, zero)\r
- (a0, b0, c0) + (a1, b1, c1) = (a0+a1, b0+b1, c0+c1)\r
- \r
-main = "OK"\r
---\r
-OK
\ No newline at end of file
+++ /dev/null
-data Foo1 a = Foo1 a\r
-data Foo2 a = Foo2 a\r
-\r
-foo1 :: Foo1 a -> a\r
-foo1 (Foo1 x) = x\r
-\r
-foo2 :: Foo2 a -> a\r
-foo2 (Foo2 x) = x\r
-\r
-class Makeable s where\r
- make :: a -> s a\r
-\r
-instance Makeable Foo1 where\r
- make = Foo1\r
-\r
-instance Makeable Foo2 where\r
- make = Foo2\r
-\r
-class (Makeable f) => Foo f where\r
- foo :: f a -> a\r
-\r
-class (Makeable b) => Bar b where\r
- bar :: b a -> a\r
-\r
-class (Makeable b) => Baz b where\r
- baz :: b a -> a\r
-\r
-class (Makeable b) => Bim b where\r
- bim :: b a -> a\r
-\r
-instance Foo Foo1 where\r
- foo = foo1\r
- \r
-instance Bar Foo2 where\r
- bar = foo2\r
- \r
-instance (Bar b) => Baz b where\r
- baz = bar\r
-\r
-instance Bim Foo1 where\r
- bim = foo1\r
-\r
-instance (Baz b) => Bim b where\r
- bim = baz\r
-\r
-doFoo1 (Foo1 x) = x\r
-doFoo2 (Foo2 x) = x\r
-\r
-useBim :: Bim b => (forall a. b a -> a) -> a -> [a]\r
-useBim doit x = [doit (make x), bim (make x :: Foo1 a)]\r
-\r
-main = "OK"\r
---\r
-"OK"\r
+++ /dev/null
-import "Prelude"\r
-\r
-distance (x1,y1) (x2,y2) = let dx = x1-x2\r
- dy = y1-y2\r
- in sqrt (dx*dx + dy*dy) print x1\r
---\r
-5:31-5:35: Constrain Real ((a -> <b> ()) -> ((c -> <d> ()) -> <h> e -> <g> f) -> <j> i) contains free variables not mentioned in the type of the value.\r
-5:52-5:57: Constrain Show a contains free variables not mentioned in the type of the value.\r
-5:58-5:60: Unification of types failed.
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-main = typeOf (\(a,b) -> a+b :: Double)\r
---\r
-(Double, Double) -> Double
\ No newline at end of file
+++ /dev/null
-id x = x\r
-main = id id (5 :: Integer)\r
---\r
-5
\ No newline at end of file
+++ /dev/null
-a :: Double
-a = a
-
-id :: Integer -> Integer
-id x = x
-
-b = id a
---
-7:8-7:9: Expected <Integer> got <Double>.
\ No newline at end of file
+++ /dev/null
-a :: Integer\r
-a = a\r
-\r
-id :: Integer -> Integer\r
-id x = x\r
-\r
-b = id a a\r
---\r
-7:5-7:11: Function of arity 1 is applied with 2 parameters.
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-main = -5\r
---\r
--5
\ No newline at end of file
+++ /dev/null
-\r
-foo :: Integer\r
-// foo = 0\r
-\r
---\r
-2:1-2:15: foo is not defined.
\ No newline at end of file
+++ /dev/null
-a = =
-b = 4
---
-1:5-1:6: Unexpected token '=' (EQUALS). Expected one of ATTACHED_HASH, BEGIN_STRING, BLANK, CHAR, DO, ENFORCE, EQ, ESCAPED_SYMBOL, FLOAT, ID, IF, INTEGER, LAMBDA, LBRACKET, LET, LPAREN, MATCH, MDO, MINUS, SELECT, SELECT_DISTINCT, SELECT_FIRST, TRANSFORMATION, WHEN.
\ No newline at end of file
+++ /dev/null
-import "JavaBuiltin" as Java
-import "StandardLibrary"
-import "Unification"
-
-pair :: Default a => Default b => UTag (a, b) (Unifiable a, Unifiable b)
-pair = uTag 0 (\(ua, ub) -> (extract ua, extract ub)) Java.unsafeCoerce
-
-/*triple :: Default a => Default b => Default c =>
- UTag (a, b, c) (Unifiable a, Unifiable b, Unifiable c)*/
-triple = uTag 0 (\(ua, ub, uc) -> (extract ua, extract ub, extract uc)) Java.unsafeCoerce
-
-main :: (Integer,Integer,Integer)
-main = do
- um1 = createUMap
- um2 = createUMap
- v1 = uVar
- v2 = uVar
- v3 = uVar
- vX = uVar
- putUMap um1 "a" (uCons triple (v1, v2, v3))
- putUMap um1 "a" (uCons triple (v2, v3, v1))
- putUMap um1 "a" (uCons triple (vX, uVar, uVar))
- putUMap um2 "b" vX
- putUMapC um2 "b" 12
-
- getUMap um1 "a"
---
-(12,12,12)
\ No newline at end of file
+++ /dev/null
-\r
-@sdlfkmsdlfkm\r
-main = "Not to be executed"\r
---\r
-2:1-2:14: Unknown annotation.
\ No newline at end of file
+++ /dev/null
-\r
-data List a = Nil | Cons a (List a)\r
-\r
-instance Monoid List where\r
- zero = Nil\r
- \r
---\r
-4:10-4:16: Couldn't resolve class Monoid.
\ No newline at end of file
+++ /dev/null
-main :: List Integer\r
-main = 13\r
---\r
-1:9-1:13: Didn't find type constructor List.
\ No newline at end of file
+++ /dev/null
-class Functor f where\r
- map :: (a -> b) -> f a -> f b\r
-\r
-data Iddd a = Idd a\r
-\r
-instance Functor Idd where\r
- map (Idd x) = x\r
---\r
-6:18-6:21: Didn't find type constructor Idd.
\ No newline at end of file
+++ /dev/null
-a = b\r
-\r
---\r
-1:5-1:6: Couldn't resolve variable b.
\ No newline at end of file
+++ /dev/null
-\r
-a = a\r
-b = b\r
-c = a + b\r
-\r
---\r
-4:7-4:8: Couldn't resolve variable +.
\ No newline at end of file
+++ /dev/null
-\r
-data List a = Nil | Cons a (List a)\r
-\r
-data Foo = Foo\r
-\r
-main = Foo `Cons` (Foo `Cons` Nil)\r
---\r
-(Cons Foo (Cons Foo Nil))
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-import "Vector"\r
-\r
-main = fromDynamic (toDynamic (vector [3 :: Double])) :: [Double]\r
---\r
-[3.0]
\ No newline at end of file
+++ /dev/null
-import "StandardLibrary"\r
-\r
-a :: Vector Double\r
-a = vector [1,2,3]\r
-\r
-main = map (a !) [0..length a-1]\r
---\r
-[1.0, 2.0, 3.0]
\ No newline at end of file
+++ /dev/null
-import "StandardLibrary"\r
-\r
-convertDataset :: [Double] -> [Double] -> Vector (Vector Double)\r
-convertDataset xs ys = vector [vector xs, vector ys]\r
-\r
-main = "Foo"\r
---\r
-Foo
\ No newline at end of file
+++ /dev/null
-importJava "java.util.List" where\r
- data List a\r
- \r
- @JavaName add\r
- addList :: List a -> a -> <Proc> Boolean\r
-\r
-importJava "java.util.ArrayList" where\r
- @JavaName "<init>"\r
- newList :: () -> <Proc> (List a)\r
-\r
-main = do\r
- l = newList ()\r
- addList l (3 :: Integer)\r
- l\r
---\r
-[3]
\ No newline at end of file
+++ /dev/null
-import "JavaBuiltin" as Java\r
-\r
-class Foo a where\r
- foo :: a -> () -> a\r
- \r
-instance Foo Integer where\r
- foo x () = x\r
- \r
-idWithFoo x = foo x () \r
- \r
-main = idWithFoo (13 :: Integer)\r
---\r
-13
\ No newline at end of file
+++ /dev/null
-import "JavaBuiltin" as Java\r
-\r
-data Foo = Foo ()\r
-\r
-\r
-ff = Foo ()\r
-\r
-gg () = 3 :: Integer\r
-\r
-main = gg (match ff with Foo a -> a)\r
---\r
-3
\ No newline at end of file
+++ /dev/null
-\r
-while :: (<e> Boolean) -> (<e> a) -> <e> ()\r
-while cond body = loop ()\r
- where loop _ = if cond\r
- then do body ; loop ()\r
- else ()\r
-\r
-main = "FOO"\r
---\r
-FOO
\ No newline at end of file
+++ /dev/null
-import "Prelude" hiding (while)\r
-\r
-while :: Maybe Boolean -> Maybe a -> Maybe ()\r
-while condM bodyM = mdo\r
- cond <- condM\r
- if cond \r
- then bodyM >> while condM bodyM\r
- else return ()\r
-\r
-main = "FOO"\r
---\r
-FOO
\ No newline at end of file
+++ /dev/null
-import "Prelude"\r
-\r
-main = do\r
- a = ref 1\r
- b = ref 0\r
- while (getRef a < 5) do\r
- b := getRef b + 1\r
- a := getRef a + 1\r
- getRef b \r
---\r
-4
\ No newline at end of file
+++ /dev/null
-\r
-class Foo a where\r
- foo :: a\r
- bar = foo\r
- \r
-main = "Not to be executed."\r
---\r
-4:5-4:14: Method bar is not defined in this class.
\ No newline at end of file
+++ /dev/null
-\r
-class Foo a where\r
- foo :: a\r
- \r
-instance Foo Integer where\r
- foo = foo\r
- bar = foo\r
- \r
-main = "Not to be executed."\r
---\r
-7:5-7:14: Method bar is not defined in the type class Foo.
\ No newline at end of file
+++ /dev/null
-> 1+1
-2
-> 1-1
-0
-> 1+1.0
-2.0
-> 2*5
-10
-> 4/3
-1.3333333333333333
-> 4 `div` 3
-1
\ No newline at end of file
+++ /dev/null
-> id x = x
-> id 2
-2
-> id "Hello!"
-"Hello!"
-
-> id = \x -> x
-> id 2
-2
-
-> fib 0 = 1
-> fib 1 = 1
-> fib n = fib (n-1) + fib (n-2)
-
-> fib 2
-2
-> fib 3
-3
-> fib 4
-5
\ No newline at end of file
+++ /dev/null
-> f x = x + 1
-> f 3
-4
-> f 4.5
-5.5
\ No newline at end of file
+++ /dev/null
-> [1,2,3]
-[1, 2, 3]
-
-> [5..9]
-[5, 6, 7, 8, 9]
+++ /dev/null
-package org.simantics.scl.compiler.tests.unit;
-
-import org.junit.Test;
-import org.simantics.scl.compiler.environment.Environment;
-import org.simantics.scl.compiler.environment.specification.EnvironmentSpecification;
-import org.simantics.scl.compiler.errors.Locations;
-import org.simantics.scl.compiler.internal.elaboration.constraints2.ConstraintSolver;
-import org.simantics.scl.compiler.tests.TestBase;
-import org.simantics.scl.compiler.types.TCon;
-import org.simantics.scl.compiler.types.TMetaVar;
-import org.simantics.scl.compiler.types.Types;
-import org.simantics.scl.compiler.types.kinds.Kinds;
-
-public class TestConstraintSolver {
-
- public final TCon COLLECTION = Types.con("Collection", "Collection");
-
- @Test
- public void testConstraintSolver() throws Exception {
- EnvironmentSpecification environmentSpecification = new EnvironmentSpecification();
- environmentSpecification.importModule("Builtin", "");
- environmentSpecification.importModule("Prelude", "");
- environmentSpecification.importModule("Collection", "");
-
- Environment environment = TestBase.PRELUDE_MODULE_REPOSITORY
- .createRuntimeEnvironment(environmentSpecification,
- getClass().getClassLoader()).getEnvironment();
-
- ConstraintSolver solver = new ConstraintSolver(environment);
-
- TMetaVar a = Types.metaVar(Kinds.STAR);
- TMetaVar b = Types.metaVar(Kinds.STAR);
- solver.addDemand(Types.pred(COLLECTION, Types.list(a), b), Locations.NO_LOCATION);
-
- solver.print();
- }
-
-}
+++ /dev/null
-package org.simantics.scl.compiler.tests.unit;\r
-\r
-import java.util.Collection;\r
-\r
-import org.junit.Test;\r
-import org.simantics.scl.compiler.environment.filter.AcceptAllNamespaceFilter;\r
-import org.simantics.scl.compiler.environment.filter.NamespaceFilter;\r
-import org.simantics.scl.compiler.environment.filter.NamespaceFilters;\r
-import org.simantics.scl.compiler.environment.filter.NegativeNamespaceFilter;\r
-import org.simantics.scl.compiler.environment.filter.PositiveNamespaceFilter;\r
-\r
-import gnu.trove.set.hash.THashSet;\r
-import junit.framework.Assert;\r
-\r
-public class TestNamespaceFilter {\r
- \r
- private void testBooleanOperations(Collection<String> all, NamespaceFilter a, NamespaceFilter b) {\r
- {\r
- NamespaceFilter c = NamespaceFilters.union(a, b);\r
- //System.out.println("union(" + a + ", " + b + ") = " + c);\r
- for(String name : all)\r
- Assert.assertEquals(\r
- a.isValueIncluded(name) || b.isValueIncluded(name),\r
- c.isValueIncluded(name));\r
- }\r
- {\r
- NamespaceFilter c = NamespaceFilters.intersection(a, b);\r
- //System.out.println("intersection(" + a + ", " + b + ") = " + c);\r
- for(String name : all)\r
- Assert.assertEquals(\r
- a.isValueIncluded(name) && b.isValueIncluded(name),\r
- c.isValueIncluded(name));\r
- }\r
- }\r
-\r
- private void testBooleanOperations(THashSet<String> a, THashSet<String> b) {\r
- THashSet<String> all = new THashSet<String>();\r
- all.addAll(a);\r
- all.addAll(b);\r
- all.add("dummy");\r
- \r
- PositiveNamespaceFilter pa = new PositiveNamespaceFilter(a);\r
- NegativeNamespaceFilter na = new NegativeNamespaceFilter(a);\r
- PositiveNamespaceFilter pb = new PositiveNamespaceFilter(b);\r
- NegativeNamespaceFilter nb = new NegativeNamespaceFilter(b);\r
- testBooleanOperations(all, pa, pb);\r
- testBooleanOperations(all, na, pb);\r
- testBooleanOperations(all, pa, nb);\r
- testBooleanOperations(all, na, nb);\r
- }\r
- \r
- private void testBooleanOperations(THashSet<String> a) {\r
- THashSet<String> all = new THashSet<String>();\r
- all.addAll(a);\r
- all.add("dummy");\r
- \r
- PositiveNamespaceFilter pa = new PositiveNamespaceFilter(a);\r
- NegativeNamespaceFilter na = new NegativeNamespaceFilter(a);\r
- testBooleanOperations(all, pa, AcceptAllNamespaceFilter.INSTANCE);\r
- testBooleanOperations(all, na, AcceptAllNamespaceFilter.INSTANCE);\r
- testBooleanOperations(all, AcceptAllNamespaceFilter.INSTANCE, pa);\r
- testBooleanOperations(all, AcceptAllNamespaceFilter.INSTANCE, na);\r
- testBooleanOperations(all, AcceptAllNamespaceFilter.INSTANCE, AcceptAllNamespaceFilter.INSTANCE);\r
- }\r
- \r
- @Test\r
- public void testBooleanOperations() {\r
- for(int p=0;p<8;++p) {\r
- THashSet<String> a = new THashSet<String>();\r
- for(int i=0;i<3;++i)\r
- if(((p >> i) & 1) == 1)\r
- a.add(String.valueOf(i));\r
- testBooleanOperations(a);\r
- }\r
- \r
- for(int p=0;p<64;++p) {\r
- THashSet<String> a = new THashSet<String>();\r
- THashSet<String> b = new THashSet<String>();\r
- for(int i=0;i<3;++i) {\r
- if(((p >> i) & 1) == 1)\r
- a.add(String.valueOf(i));\r
- if(((p >> (i+3)) & 1) == 1)\r
- b.add(String.valueOf(i));\r
- }\r
- testBooleanOperations(a, b);\r
- }\r
- }\r
- \r
-}\r
+++ /dev/null
-package org.simantics.scl.compiler.tests.unit;\r
-\r
-import java.util.ArrayList;\r
-\r
-import org.junit.Assert;\r
-import org.junit.Test;\r
-import org.simantics.scl.compiler.errors.ErrorLog;\r
-import org.simantics.scl.compiler.internal.elaboration.subsumption.SubSolver;\r
-import org.simantics.scl.compiler.internal.elaboration.subsumption.Subsumption;\r
-import org.simantics.scl.compiler.types.TMetaVar;\r
-import org.simantics.scl.compiler.types.Type;\r
-import org.simantics.scl.compiler.types.Types;\r
-import org.simantics.scl.compiler.types.kinds.Kinds;\r
-import org.simantics.scl.compiler.types.util.Polarity;\r
-\r
-\r
-public class TestSubSolver {\r
-\r
- @Test\r
- public void testBipolarBounded() {\r
- ErrorLog errorLog = new ErrorLog();\r
- ArrayList<Subsumption> subsumptions = new ArrayList<Subsumption>();\r
- ArrayList<Type> potentialSingletonEffects = new ArrayList<Type>();\r
- \r
- TMetaVar in = Types.metaVar(Kinds.EFFECT);\r
- TMetaVar out = Types.metaVar(Kinds.EFFECT);\r
- in.addPolarity(Polarity.NEGATIVE);\r
- out.addPolarity(Polarity.POSITIVE);\r
- subsumptions.add(new Subsumption(0, Types.READ_GRAPH, out));\r
- subsumptions.add(new Subsumption(0, in, out));\r
- \r
- SubSolver solver = new SubSolver(errorLog, subsumptions, potentialSingletonEffects, 0);\r
- solver.solve();\r
- Assert.assertEquals("", errorLog.getErrorsAsString());\r
- }\r
- \r
-}\r
+++ /dev/null
-package org.simantics.scl.compiler.tests.unit;\r
-\r
-import org.junit.Test;\r
-import org.simantics.scl.compiler.environment.Environment;\r
-import org.simantics.scl.compiler.environment.Environments;\r
-import org.simantics.scl.compiler.environment.specification.EnvironmentSpecification;\r
-import org.simantics.scl.compiler.runtime.RuntimeEnvironment;\r
-import org.simantics.scl.compiler.tests.TestBase;\r
-import org.simantics.scl.compiler.types.Type;\r
-\r
-public class TestTypeParser {\r
- \r
- @Test\r
- public void testTypeParser() throws Exception {\r
- EnvironmentSpecification spec = new EnvironmentSpecification();\r
- spec.importModule("Builtin", "");\r
- spec.importModule("Prelude", "");\r
- RuntimeEnvironment runtimeEnvironment =\r
- TestBase.PRELUDE_MODULE_REPOSITORY.createRuntimeEnvironment(spec, getClass().getClassLoader());\r
- Environment environment = runtimeEnvironment.getEnvironment();\r
- Type type = Environments.getType(environment, "String -> <Proc> ()");\r
- System.out.println(type);\r
- }\r
- \r
-}\r
VALUE_NUMBER_INT :: JsonToken\r
VALUE_STRING :: JsonToken\r
VALUE_TRUE :: JsonToken\r
-instance Eq JsonToken where\r
- (==) = Java.equals\r
\r
importJava "com.fasterxml.jackson.core.JsonParser" where\r
data JsonParser\r
data JsonField = JsonField String Json\r
\r
deriving instance Show Json\r
-deriving instance Eq Json\r
deriving instance Show JsonField\r
-deriving instance Eq JsonField\r
\r
instance Json Json where\r
writeJson g (JsonString value) = writeString g value\r
makeTypeEqual _ _ = ()\r
\r
@private\r
-testValue :: Json a => Show a => Eq a => a -> <Proc> ()\r
+testValue :: Json a => Show a => a -> <Proc> ()\r
testValue v1 = do\r
v2 = toJsonString v1\r
v3 = fromJsonString v2\r
\r
setAttribute :: Element -> String -> String -> <Proc> ()\r
\r
- @JavaName equals\r
- equalsElement :: Element -> Element -> Boolean\r
-\r
-instance Eq Element where\r
- (==) = equalsElement\r
-\r
importJava "org.jdom2.Attribute" where\r
data Attribute\r
\r
importJava "org.simantics.db.ReadGraph" where\r
data ReadGraphX\r
\r
-importJava "java.lang.Object" where \r
- @JavaName equals\r
- resourceEquals :: Resource -> Resource -> Boolean\r
- @JavaName hashCode\r
- resourceHash :: Resource -> Integer\r
-\r
-instance Eq Resource where\r
- (==) = resourceEquals\r
-\r
instance Ord Resource where\r
compare a b = compare (resourceId a) (resourceId b)\r
- \r
-instance Hashable Resource where\r
- hashP = hashP . resourceHash\r
- \r
+ \r
instance Show Resource where\r
show r = "#" + show (resourceId r)\r
\r
include "Simantics/DB"\r
import "Simantics/DB" as DB\r
\r
-importJava "java.lang.Object" where\r
- @JavaName equals\r
- """\r
-Function **variableEquals** compares the given input variables and returns True if they are the same.\r
-\r
-Example:\r
-\r
- import "Simantics/Variables"\r
- import "Apros/Module"\r
- my_variable_1 = moduleVariable "PO01"\r
- my_variable_2 = moduleVariable "PO02"\r
- variableEquals my_variable_1 my_variable_2\r
- \r
- > False\r
- \r
- """\r
- variableEquals :: Variable -> Variable -> Boolean\r
- @JavaName hashCode\r
- variableHash :: Variable -> Integer\r
-\r
-instance Eq Variable where\r
- (==) = variableEquals\r
- \r
-instance Hashable Variable where\r
- hashP = hashP . variableHash\r
-\r
importJava "org.simantics.db.layer0.variable.Variables" where\r
@JavaName getVariable\r
"""\r
Bundle-Activator: org.simantics.scl.osgi.internal.Activator
Require-Bundle: org.eclipse.core.runtime,
gnu.trove3;bundle-version="3.0.0",
- org.simantics.scl.compiler;bundle-version="0.2.0";visibility:=reexport
+ org.simantics.scl.compiler;bundle-version="0.6.0";visibility:=reexport
Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Export-Package: org.simantics.scl.osgi,
org.simantics.scl.osgi.internal
-Service-Component: OSGI-INF/org.simantics.scl.osgi.internal.BundleTestScriptRepository.xml,
+Service-Component: OSGI-INF/org.simantics.scl.osgi.internal.BundleModuleSourceRepository.xml,
OSGI-INF/org.simantics.scl.osgi.internal.FileSystemModuleSourceRepository.xml,
- OSGI-INF/org.simantics.scl.osgi.internal.BundleModuleSourceRepository.xml
+ OSGI-INF/org.simantics.scl.osgi.internal.BundleTestScriptRepository.xml
Import-Package: org.osgi.service.component,
org.osgi.service.component.annotations
bin.includes = META-INF/,\\r
.,\\r
scl/,\\r
- OSGI-INF/org.simantics.scl.osgi.internal.BundleTestScriptRepository.xml,\\r
+ OSGI-INF/org.simantics.scl.osgi.internal.BundleModuleSourceRepository.xml,\\r
OSGI-INF/org.simantics.scl.osgi.internal.FileSystemModuleSourceRepository.xml,\\r
- OSGI-INF/org.simantics.scl.osgi.internal.BundleModuleSourceRepository.xml\r
+ OSGI-INF/org.simantics.scl.osgi.internal.BundleTestScriptRepository.xml\r
src.includes = scl/\r
package org.simantics.scl.osgi.internal;\r
\r
-import java.io.File;\r
import java.io.IOException;\r
import java.io.InputStream;\r
import java.net.URISyntaxException;\r
import java.net.URL;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Enumeration;
import org.osgi.framework.Bundle;
import org.osgi.util.tracker.BundleTracker;
import org.simantics.scl.compiler.module.repository.UpdateListener;
import org.simantics.scl.compiler.source.ModuleSource;
-import org.simantics.scl.compiler.source.repository.AbstractModuleSourceRepository;
import org.simantics.scl.compiler.source.repository.ModuleSourceRepository;
import gnu.trove.map.hash.THashMap;
import gnu.trove.procedure.TObjectObjectProcedure;
-import gnu.trove.procedure.TObjectProcedure;
import gnu.trove.set.hash.THashSet;
@Component
-public class BundleModuleSourceRepository extends AbstractModuleSourceRepository implements ModuleSourceRepository {
+public class BundleModuleSourceRepository implements ModuleSourceRepository {
Tracker tracker;
THashMap<String, BundleModuleSource> modules = new THashMap<String, BundleModuleSource>();
}
@Override
- synchronized public void forAllModules(TObjectProcedure<String> procedure) {
- modules.forEachKey(procedure);
+ public synchronized Collection<String> getModuleNames() {
+ return new ArrayList<String>(modules.keySet());
+ }
+
+ @Override
+ public synchronized Collection<String> getDocumentationNames() {
+ return new ArrayList<String>(documentations.keySet());
}
@Override
else
return source.getText();
}
-
- @Override
- synchronized public void forAllDocumentations(TObjectProcedure<String> procedure) {
- documentations.forEachKey(procedure);
- }
-
+
@Override
public void checkUpdates() {
synchronized(this) {
package org.simantics.scl.osgi.internal;
import java.io.File;
+import java.util.Collection;
+import java.util.Collections;
import org.osgi.service.component.annotations.Component;
import org.simantics.scl.compiler.module.repository.UpdateListener;
}
@Override
- synchronized public void forAllModules(TObjectProcedure<String> procedure) {
+ public Collection<String> getModuleNames() {
+ return Collections.emptyList();
}
@Override
- public String getDocumentation(String documentationName) {
- return null;
+ public void forAllModules(TObjectProcedure<String> procedure) {
}
- @Override
- public void forAllDocumentations(TObjectProcedure<String> procedure) {
- }
-
- @Override
- public void checkUpdates() {
- }
-
- @Override
- public void clear() {
- }
}
package org.simantics.scl.osgi.internal;
-import gnu.trove.procedure.TObjectProcedure;
+import java.util.ArrayList;
+import java.util.Collection;
import org.osgi.framework.BundleContext;
import org.osgi.util.tracker.ServiceTracker;
import org.simantics.scl.compiler.source.ModuleSource;
import org.simantics.scl.compiler.source.repository.ModuleSourceRepository;
+import gnu.trove.procedure.TObjectProcedure;
+
public class ServiceBasedModuleSourceRepository implements ModuleSourceRepository {
ServiceTracker<ModuleSourceRepository, ModuleSourceRepository> sourceRepositories;
@Override
public String getDocumentation(String documentationName) {
+ // getServices is internally synchronized, so no need to synchronize here
Object[] services = sourceRepositories.getServices();
if(services != null)
for(Object sourceRepository_ : services) {
@Override
public void forAllModules(TObjectProcedure<String> procedure) {
- for(Object sourceRepository_ : sourceRepositories.getServices()) {
- ModuleSourceRepository sourceLoader = (ModuleSourceRepository)sourceRepository_;
- sourceLoader.forAllModules(procedure);
- }
+ // getServices is internally synchronized, so no need to synchronize here
+ Object[] services = sourceRepositories.getServices();
+ if(services != null)
+ for(Object sourceRepository_ : services) {
+ ModuleSourceRepository sourceLoader = (ModuleSourceRepository)sourceRepository_;
+ sourceLoader.forAllModules(procedure);
+ }
+ }
+
+ @Override
+ public Collection<String> getModuleNames() {
+ ArrayList<String> result = new ArrayList<>();
+ forAllModules((String name) -> {
+ result.add(name);
+ return true;
+ });
+ return result;
}
@Override
public void forAllDocumentations(TObjectProcedure<String> procedure) {
- for(Object sourceRepository_ : sourceRepositories.getServices()) {
- ModuleSourceRepository sourceLoader = (ModuleSourceRepository)sourceRepository_;
- sourceLoader.forAllDocumentations(procedure);
- }
+ Object[] services = sourceRepositories.getServices();
+ if(services != null)
+ for(Object sourceRepository_ : services) {
+ ModuleSourceRepository sourceLoader = (ModuleSourceRepository)sourceRepository_;
+ sourceLoader.forAllDocumentations(procedure);
+ }
+ }
+
+ @Override
+ public Collection<String> getDocumentationNames() {
+ ArrayList<String> result = new ArrayList<>();
+ forAllDocumentations((String name) -> {
+ result.add(name);
+ return true;
+ });
+ return result;
}
@Override
}
}
- @Override
- public void clear() {
- }
-
}
Bundle-Version: 0.4.0.qualifier
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Export-Package: org.simantics.scl.runtime,
+ org.simantics.scl.runtime.chr,
org.simantics.scl.runtime.collection,
org.simantics.scl.runtime.exceptions,
org.simantics.scl.runtime.function,
instance Arbitrary Character where
arbitrary = genRandom randomCharacter
instance CoArbitrary Character where
- variateSeed _ seed v = seed + fromInteger (hash (showCharacter v))
+ variateSeed _ seed v = seed + fromInteger (hashCode (showCharacter v))
"""Generates a random string that is a valid SCL or Java identifier"""
arbitraryIdentifier = Gen $ \n -> string (Vector.vectorF (1+randomN (max n 1))
instance Arbitrary String where
arbitrary = Gen $ \n -> string (Vector.vectorF (randomN (1+n)) (\_ -> randomCharacter))
instance CoArbitrary String where
- variateSeed _ seed v = seed + fromInteger (hash v)
+ variateSeed _ seed v = seed + fromInteger (hashCode v)
instance Arbitrary () where
arbitrary = genRandom ()
@JavaName size
length :: T a -> <Proc> Integer
-contains :: Eq a => T a -> a -> <Proc> Boolean
+contains :: T a -> a -> <Proc> Boolean
contains l a = loop 0
where
len = length l
@JavaName intValue
toIntegerBigInteger :: BigInteger -> Integer
-instance Eq BigInteger where
- (==) = equalsBigInteger
-
instance Show BigInteger where
show = showBigInteger
min = minBigInteger
max = maxBigInteger
-instance Hashable BigInteger where
- hashP v x = hashBigInteger v + 31*x
-
instance Additive BigInteger where
zero = zeroBigInteger
(+) = addBigInteger
all :: (El a -> <e> Boolean) -> a -> <e> Boolean
filter :: (El a -> <e> Boolean) -> a -> <e> a
partition :: (El a -> <e> Boolean) -> a -> <e> (a,a)
- groupBy :: Hashable b => (El a -> b) -> [(b, a)]
+ groupBy :: (El a -> b) -> [(b, a)]
uniqueElement :: a -> El a // may fail
fromList :: [El a] -> a
toList :: a -> [El a]
foldl1 :: (El a -> El a -> <e> El a) -> a -> <e> a
foldr1 :: (El a -> El a -> <e> El a) -> a -> <e> a
- elem :: Eq (El a) => El a -> a -> Boolean
- elemIndex :: Eq (El a) => El a -> a -> Maybe Integer
- elemIndices :: Eq (El a) => El a -> a -> [Integer]
+ elem :: El a -> a -> Boolean
+ elemIndex :: El a -> a -> Maybe Integer
+ elemIndices :: El a -> a -> [Integer]
find :: (El a -> <e> Boolean) -> a -> <e> Maybe (El a)
findIndex :: (El a -> <e> Boolean) -> a -> <e> Maybe Integer
findIndices :: (El a -> <e> Boolean) -> a -> <e> [Integer]
"Get a component type of a composite data type"\r
@JavaName getComponentType\r
datatypeComponentType :: Datatype -> ChildReference -> Datatype\r
- \r
- @private\r
- @JavaName equals\r
- datatypeEquals :: Datatype -> Datatype -> Boolean \r
+\r
\r
instance Show Datatype where\r
show = showDatatype\r
\r
-instance Eq Datatype where\r
- (==) = datatypeEquals\r
-\r
/// Binding ///\r
\r
importJava "org.simantics.databoard.binding.Binding" where\r
@JavaName compare\r
compareObjects :: Serializable a => a -> a -> Integer\r
\r
- "Return true, if two serializable values are equal" \r
- @JavaName equals\r
- serializableEq :: Serializable a => a -> a -> Boolean\r
- \r
"The default value of a serializable type"\r
@JavaName createDefault\r
serializableDefaultValue :: Serializable a => a\r
@JavaName getComponentBinding\r
getComponentBinding :: Binding a -> ChildReference -> Binding b\r
\r
- @private\r
- @JavaName equals\r
- bindingEquals :: Binding a -> Binding a -> Boolean\r
- \r
-instance Eq (Binding a) where\r
- (==) = bindingEquals\r
-\r
"Get a child data component of a composite serializable value"\r
getSerializableComponent :: Serializable a => Serializable b => a -> ChildReference -> b\r
getSerializableComponent object ref = getSerializableComponent_ object ref binding\r
***********************************************************/
importJava "java.util.Arrays" where
- @private
- @JavaName equals
- equalsDoubleArray :: DoubleArray -> DoubleArray -> Boolean
-
@private
@JavaName toString
showDoubleArray :: DoubleArray -> String
@JavaName toArray
listToArray :: [a] -> Array a
-instance Eq DoubleArray where
- (==) = equalsDoubleArray
instance Show DoubleArray where
show = showDoubleArray
infixl 7 (*), (/), div, mod
infixl 6 (+), (-)
infixl 5 (\\), (<<), (<+)
-infix 4 (==), (!=), (<), (<=), (>=), (>)
+infix 4 (!=), (<), (<=), (>=), (>)
infixr 3 (&&), (&<&)
infixr 2 (||), orElse, morelse
infixr 1 (>>=), (>>), (:=)
/// Comparison ///
-"""
-The class of types whose elements can be compared for equality.
-Method `(==)` must be implemented in instances.
-"""
-class Eq a where
- "Equality"
- (==) :: a -> a -> Boolean
- "Inequality: `a != b = not (a == b)`"
- (!=) :: a -> a -> Boolean
-
- a != b = not (a == b)
+@inline
+(!=) :: a -> a -> Boolean
+a != b = not (a == b)
"""
The class of linearly ordered types.
Method `compare` must be implemented in instances.
"""
-class (Eq a) => Ord a where
+class Ord a where
"""
`compare x y` returns a negative number, if `x` is smaller than `y`,
a positive number, if `x` is bigger than `y` and zero if they are equal.
where
minF a b = if fst a <= fst b then a else b
-"""
-The class of types with method to compute hash codes.
-"""
-class (Eq a) => Hashable a where
- "`hashP v seed` computes the hash code of `v` using `seed` as a seed."
- hashP :: a -> Integer -> Integer
-
-"`hash v` computes the hash code of `v`"
-hash :: Hashable a => a -> Integer
-hash a = hashP a 1166136261
-
/// Functions ///
/*
instance Functor ((->) a) where
@JavaName parseByte
readByte :: String -> Byte
-instance Eq Byte where
- (==) = Java.bcmpeq
- (!=) = Java.bcmpne
-
instance Ord Byte where
(<) = Java.bcmplt
(<=) = Java.bcmple
@JavaName parseShort
readShort :: String -> Short
-instance Eq Short where
- (==) = Java.scmpeq
- (!=) = Java.scmpne
-
instance Ord Short where
(<) = Java.scmplt
(<=) = Java.scmple
@JavaName parseInt
readInteger :: String -> Integer
-instance Eq Integer where
- (==) = Java.icmpeq
- (!=) = Java.icmpne
-
instance Ord Integer where
(<) = Java.icmplt
(<=) = Java.icmple
(>) = Java.icmpgt
(>=) = Java.icmpge
-
-instance Hashable Integer where
- hashP v x = Java.ixor v (Java.imul x 16777619) // prime for FNV-1 hash
instance Additive Integer where
zero = Java.iconst_0
@JavaName parseLong
readLong :: String -> Long
-instance Eq Long where
- (==) = Java.lcmpeq
- (!=) = Java.lcmpne
-
instance Ord Long where
(<) = Java.lcmplt
(<=) = Java.lcmple
(>) = Java.lcmpgt
(>=) = Java.lcmpge
-
-instance Hashable Long where
- hashP v x = Java.l2i (Java.lxor v (Java.lushr v 32)) + x*16777619
instance Additive Long where
zero = Java.lconst_0
"Converts 32-bit floating point number to a 32-bit integer with the same byte level representation."
floatToIntBits :: Float -> Integer
-instance Eq Float where
- (==) = Java.fcmpeq
- (!=) = Java.fcmpne
-
instance Ord Float where
compare = compareFloat
(<) = Java.fcmplt
(>) = Java.fcmpgt
(>=) = Java.fcmpge
-instance Hashable Float where
- hashP v x = hashP (floatToIntBits v) x
-
instance Additive Float where
zero = Java.fconst_0
(+) = Java.fadd
isNaN :: Double -> Boolean
isInfinite :: Double -> Boolean
-instance Eq Double where
- (==) = Java.dcmpeq
- (!=) = Java.dcmpne
-
instance Ord Double where
compare = compareDouble
(<) = Java.dcmplt
(<=) = Java.dcmple
(>) = Java.dcmpgt
- (>=) = Java.dcmpge
-
-instance Hashable Double where
- hashP v x = hashP (doubleToLongBits v) x
+ (>=) = Java.dcmpge
instance Additive Double where
zero = Java.dconst_0
"Returns true, if the given character is a digit."
isDigit :: Character -> Boolean
-instance Eq Character where
- (==) = Java.ccmpeq
- (!=) = Java.ccmpne
-
instance Ord Character where
(<) = Java.ccmplt
(<=) = Java.ccmple
otherwise :: Boolean
otherwise = True
-instance Eq Boolean where
- a == b = if a then b else not b
- a != b = if a then not b else b
-
instance Ord Boolean where
compare False False = 0
compare False True = neg 1
fromJust :: Maybe a -> a
fromJust (Just a) = a
-deriving instance (Eq a) => Eq (Maybe a)
deriving instance (Ord a) => Ord (Maybe a)
deriving instance (Show a) => Show (Maybe a)
-deriving instance (Hashable a) => Hashable (Maybe a)
instance Functor Maybe where
fmap _ Nothing = Nothing
"""
data Either a b = Left a | Right b
-deriving instance (Eq a, Eq b) => Eq (Either a b)
deriving instance (Ord a, Ord b) => Ord (Either a b)
deriving instance (Show a, Show b) => Show (Either a b)
-deriving instance (Hashable a, Hashable b) => Hashable (Either a b)
instance Functor (Either a) where
fmap _ (Left x) = Left x
@JavaName "compareTo"
compareString :: String -> String -> Integer
@private
-// @JavaName "hashCode"
-// hashString :: String -> Integer
- @private
- @JavaName "equals"
- equalsString :: String -> String -> Boolean
- @private
@JavaName "length"
lengthString :: String -> Integer
@JavaName "<init>"
string :: Vector Character -> String
-instance Eq String where
- (==) = equalsString
-
-instance Hashable String where
- hashP x v = Java.hashCode x + v*16777619
-
instance Ord String where
compare = compareString
/// Tuple0 ///
-instance Eq () where
- () == () = True
-
instance Ord () where
compare () () = 0
-instance Hashable () where
- hashP () x = x
-
instance Additive () where
zero = ()
() + () = ()
snd :: (a,b) -> b
snd (x,y) = y
-instance (Eq a, Eq b) => Eq (a, b) where
- (a0, b0) == (a1, b1) = a0 == a1 && b0 == b1
-
instance (Ord a, Ord b) => Ord (a, b) where
compare (a0, b0) (a1, b1) = compare a0 a1 &<& compare b0 b1
-instance (Hashable a, Hashable b) => Hashable (a, b) where
- hashP (a,b) x = hashP b $ hashP a x
-
instance (Additive a, Additive b) => Additive (a, b) where
zero = (zero, zero)
(a0, b0) + (a1, b1) = (a0+a1, b0+b1)
/// Tuple3 ///
-instance (Eq a, Eq b, Eq c) => Eq (a, b, c) where
- (a0, b0, c0) == (a1, b1, c1) = a0 == a1 && b0 == b1 && c0 == c1
-
instance (Ord a, Ord b, Ord c) => Ord (a, b, c) where
compare (a0, b0, c0) (a1, b1, c1) = compare a0 a1 &<& compare b0 b1 &<& compare c0 c1
-instance (Hashable a, Hashable b, Hashable c) => Hashable (a, b, c) where
- hashP (a,b,c) x = hashP c $ hashP b $ hashP a x
-
instance (Additive a, Additive b, Additive c) => Additive (a, b, c) where
zero = (zero, zero, zero)
(a0, b0, c0) + (a1, b1, c1) = (a0+a1, b0+b1, c0+c1)
/// Tuple4 ///
-instance (Eq a, Eq b, Eq c, Eq d) => Eq (a, b, c, d) where
- (a0, b0, c0, d0) == (a1, b1, c1, d1) = a0 == a1 && b0 == b1 && c0 == c1 && d0 == d1
-
instance (Ord a, Ord b, Ord c, Ord d) => Ord (a, b, c, d) where
compare (a0, b0, c0, d0) (a1, b1, c1, d1) =
compare a0 a1 &<& compare b0 b1 &<& compare c0 c1 &<& compare d0 d1
-instance (Hashable a, Hashable b, Hashable c, Hashable d) => Hashable (a, b, c, d) where
- hashP (a,b,c,d) x = hashP d $ hashP c $ hashP b $ hashP a x
-
instance (Additive a, Additive b, Additive c, Additive d) => Additive (a, b, c, d) where
zero = (zero, zero, zero, zero)
(a0, b0, c0, d0) + (a1, b1, c1, d1) = (a0+a1, b0+b1, c0+c1, d0+d1)
/// Tuple5 ///
-instance (Eq a, Eq b, Eq c, Eq d, Eq e) => Eq (a, b, c, d, e) where
- (a0, b0, c0, d0, e0) == (a1, b1, c1, d1, e1) =
- a0 == a1 && b0 == b1 && c0 == c1 && d0 == d1 && e0 == e1
-
instance (Ord a, Ord b, Ord c, Ord d, Ord e) => Ord (a, b, c, d, e) where
compare (a0, b0, c0, d0, e0) (a1, b1, c1, d1, e1) =
compare a0 a1 &<& compare b0 b1 &<& compare c0 c1 &<& compare d0 d1 &<& compare e0 e1
-
-instance (Hashable a, Hashable b, Hashable c, Hashable d, Hashable e)
- => Hashable (a, b, c, d, e) where
- hashP (a,b,c,d,e) x = hashP e $ hashP d $ hashP c $ hashP b $ hashP a x
instance (Additive a, Additive b, Additive c, Additive d, Additive e) => Additive (a, b, c, d, e) where
zero = (zero, zero, zero, zero, zero)
/// Lists ///
-instance (Eq a) => Eq [a] where
- a == b = lA == lB && loop 0
- where
- lA = length a
- lB = length b
- loop i = i>=lA || (a!i == b!i && loop (i+1))
-
instance (Ord a) => Ord [a] where
compare a b = loop 0
where
then 1
else compare (a!i) (b!i) &<& loop (i+1)
-instance (Hashable a) => Hashable [a] where
- hashP a x = loop 0 x
- where
- lA = length a
- loop i x = if i == lA
- then x
- else loop (i+1) (hashP (a!i) x)
-
instance Functor [] where
fmap = mapList
//build :: (forall a. a -> (a -> b -> <e> a) -> <e> a) -> <e> [b]
"`elem el lst` return true, if `el` occurs in the list `lst`."
-elem :: Eq a => a -> [a] -> Boolean
+elem :: a -> [a] -> Boolean
elem el l = loop 0
where
len = length l
| otherwise = False
"`elemMaybe v1 (Just v2)` returns true if `v1 == v2`. `elemMaybe v1 Nothing` is always false."
-elemMaybe :: Eq a => a -> Maybe a -> Boolean
+elemMaybe :: a -> Maybe a -> Boolean
elemMaybe el m = match m with
Just el2 -> el == el2
Nothing -> False
"""
Computes a list that contains only elements that belongs to both input lists.
"""
-intersect :: Eq a => [a] -> [a] -> [a]
+intersect :: [a] -> [a] -> [a]
intersect a b = filter f a
where
f e = elem e b
len = length l
"Tries to find the given key from the list of key-value pairs and returns the corresponding value."
-lookup :: Eq a => a -> [(a, b)] -> Maybe b
+lookup :: a -> [(a, b)] -> Maybe b
lookup el l = do
len = length l
loop i = if i < len
Given a list of key-value pairs, the function produces a function that finds a value
efficiently for the given key.
"""
-index :: Hashable a => [(a,b)] -> a -> Maybe b
-index = indexWith hash (==)
+index :: [(a,b)] -> a -> Maybe b
+index = indexWith hashCode (==)
"""
Given a list of values and a function computing a key for each value, the function produces a function that finds a value
effeciently for the given key.
"""
-indexBy :: Hashable b => (a -> b) -> [a] -> b -> Maybe a
+indexBy :: (a -> b) -> [a] -> b -> Maybe a
indexBy f l = index [(f x, x) | x <- l]
"Groups a list values by a key computed by the given function."
-groupBy :: Hashable b => (a -> <e> b) -> [a] -> <e> [(b, [a])]
-groupBy f l = groupWith hash (==) f id l
+groupBy :: (a -> <e> b) -> [a] -> <e> [(b, [a])]
+groupBy f l = groupWith hashCode (==) f id l
"Groups a list of key-value pairs by the keys."
-group :: Hashable a => [(a,b)] -> [(a, [b])]
-group = groupWith hash (==) fst snd
+group :: [(a,b)] -> [(a, [b])]
+group = groupWith hashCode (==) fst snd
"Removes duplicates (all but the first occurrence) from the list but otherwise preserves the order of the elements."
-unique :: Eq a => [a] -> [a]
+unique :: [a] -> [a]
unique = uniqueWith (==)
"Like `unique`, but uses the given function for finding the key values used for uniqueness testing."
-uniqueBy :: Eq b => (a -> b) -> [a] -> [a]
+uniqueBy :: (a -> b) -> [a] -> [a]
uniqueBy f = uniqueWith (\a b -> f a == f b)
//sortAndUniqueBy :: Ord b => (a -> b) -> [a] -> [a]
//sortAndUniqueBy f = map snd . uniqueWith (\a b -> fst a == fst b) . sortBy fst . map (\x -> (f x, x))
"`a \\\\ b` removes all elements of `b` from the list `a`."
-(\\) :: Eq a => [a] -> [a] -> [a]
+(\\) :: [a] -> [a] -> [a]
(\\) = deleteAllBy (==)
/// Dynamic ///
data SList a = Nil | Cons a (SList a)
-deriving instance (Eq a) => Eq (SList a)
deriving instance (Ord a) => Ord (SList a)
-deriving instance (Hashable a) => Hashable (SList a)
deriving instance (Show a) => Show (SList a)
@inline
mapFirstVector f v = mapFirstN (\i -> f (getVector v i)) (lengthVector v)
@inline
-containsVector :: Eq a => a -> Vector a -> Boolean
+containsVector :: a -> Vector a -> Boolean
containsVector x v = foldlN (\result i -> result || (v!i == x)) False (lengthVector v)
@inline
--- /dev/null
+/*\r
+ * Copyright 2014 the original author or authors.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.simantics.scl.runtime.chr;\r
+\r
+import static java.util.Arrays.binarySearch;\r
+\r
+import java.util.Arrays;\r
+\r
+/**\r
+ * This class is adapted from MutableQHashObjSetGO class generated by Koloboke library.\r
+ * It is used by code generated by SCL compiler.\r
+ */\r
+public class CHRHashIndex {\r
+\r
+ private static final double MIN_LOAD = 1.0 / 3.0;\r
+ private static final double MAX_LOAD = 2.0 / 3.0;\r
+ private static final double TARGET_LOAD = 0.5;\r
+ private static final double GROWTH_FACTOR = 2.0;\r
+ private static final int INITIAL_CAPACITY = 10;\r
+\r
+ private static final Object REMOVED = new Object();\r
+ private static final Object FREE = null;\r
+\r
+ ////////////////////////////\r
+ // Fields\r
+\r
+ /** The current number of occupied slots in the hash. */\r
+ private int size;\r
+\r
+ private int maxSize;\r
+\r
+ /** The current number of free slots in the hash. */\r
+ private int freeSlots;\r
+\r
+ private int minFreeSlots;\r
+\r
+ private int removedSlots;\r
+\r
+ private Object[] set;\r
+\r
+ private static int mix(int hash) {\r
+ return hash & Integer.MAX_VALUE;\r
+ }\r
+\r
+ private boolean noRemoved() {\r
+ return removedSlots == 0;\r
+ }\r
+\r
+ /**\r
+ * Creates data structures with a prime capacity at or near the minimum\r
+ * needed to hold {@code size} elements without triggering a rehash.\r
+ *\r
+ * <p>Should be called only in constructors and externalization code.\r
+ */\r
+ private void init(int size) {\r
+ this.size = 0;\r
+ internalInit(targetCapacity(size));\r
+ }\r
+\r
+ private void internalInit(int capacity) {\r
+ initSlotCounts(capacity);\r
+ allocateArrays(capacity);\r
+ }\r
+\r
+ private void initSlotCounts(int capacity) {\r
+ // No sense in trying to rehash after each insertion\r
+ // if the capacity is already reached the limit.\r
+ maxSize = !isMaxCapacity(capacity) ? maxSize(capacity) : capacity - 1;\r
+ minFreeSlots = minFreeSlots(capacity, size, MAX_LOAD, maxSize);\r
+ int freeSlots = this.freeSlots = capacity - size;\r
+ // free could be less than minFreeSlots only in case when capacity\r
+ // is not sufficient to comply load factor (due to saturation with\r
+ // Java array size limit). Set minFreeSlots to a half of free to avoid\r
+ // too often (instant) rehashing in this case.\r
+ if (freeSlots < minFreeSlots) this.minFreeSlots = (freeSlots + 1) / 2;\r
+ removedSlots = 0;\r
+ }\r
+\r
+ private static int minFreeSlots(int capacity, int size, double maxLoad, int maxSize) {\r
+ double load = (double) size / (double) capacity;\r
+ // See "Tombstones purge from hashtable: theory and practice" wiki page\r
+ double rehashLoad =\r
+ 0.55 + 0.721 * load - 0.274 * load * load;\r
+\r
+ int minFreeSlots;\r
+ // minFreeSlots shouldn't be less than `capacity - maxSize`\r
+ if (rehashLoad > maxLoad) {\r
+ minFreeSlots = (int) ((double) capacity * (1.0 - rehashLoad));\r
+ } else {\r
+ minFreeSlots = capacity - maxSize;\r
+ }\r
+ // Need at least one free slot for open addressing\r
+ return minFreeSlots > 0 ? minFreeSlots : 1;\r
+ }\r
+\r
+ /////////////////////////////\r
+ // Modification hooks and rehash logic\r
+\r
+ public boolean shrink() {\r
+ int newCapacity = targetCapacity(size);\r
+ if (removedSlots > 0 || newCapacity < set.length) {\r
+ rehash(newCapacity);\r
+ return true;\r
+ } else {\r
+ return false;\r
+ }\r
+ }\r
+\r
+ private boolean tryRehashForExpansion(int newCapacity) {\r
+ // No sense in rehashing for expansion if we already reached Java array\r
+ // size limit.\r
+ if (newCapacity > set.length || removedSlots > 0) {\r
+ rehash(newCapacity);\r
+ return true;\r
+ } else {\r
+ if (freeSlots < minFreeSlots)\r
+ minFreeSlots = (freeSlots + 1) / 2;\r
+ return false;\r
+ }\r
+ }\r
+\r
+ public boolean ensureCapacity(long minSize) {\r
+ int intMinSize = (int) Math.min(minSize, (long) Integer.MAX_VALUE);\r
+ if (minSize < 0L)\r
+ throw new IllegalArgumentException(\r
+ "Min size should be positive, " + minSize + " given.");\r
+ int additionalSize = intMinSize - size;\r
+ if (additionalSize <= 0)\r
+ return false;\r
+ if (intMinSize > maxSize || freeSlots - additionalSize < minFreeSlots) {\r
+ return tryRehashForExpansion(targetCapacity(intMinSize));\r
+ } else {\r
+ return false;\r
+ }\r
+ }\r
+\r
+ private void postRemoveHook() {\r
+ size--;\r
+ removedSlots++;\r
+ }\r
+\r
+ private void postFreeSlotInsertHook() {\r
+ if (++size > maxSize) {\r
+ if (tryRehashForExpansion(grownCapacity()))\r
+ return;\r
+ }\r
+ if (--freeSlots < minFreeSlots) {\r
+ if (!tryRehashIfTooFewFreeSlots() && freeSlots == 0) {\r
+ throw new CHRHashOverflowException();\r
+ }\r
+ }\r
+ }\r
+\r
+ private void postRemovedSlotInsertHook() {\r
+ if (++size > maxSize) {\r
+ if (tryRehashForExpansion(grownCapacity()))\r
+ return;\r
+ }\r
+ removedSlots--;\r
+ }\r
+\r
+ private boolean tryRehashIfTooFewFreeSlots() {\r
+ if (removedSlots > 0) {\r
+ rehash(targetCapacity(size));\r
+ return true;\r
+ } else {\r
+ return tryRehashForExpansion(grownCapacity());\r
+ }\r
+ }\r
+\r
+ /** For initial hash table construction and rehash to target load (shrink, tombstones purge). */\r
+ private int targetCapacity(int size) {\r
+ return capacity(size, targetLoadInverse.scaleUpper(size));\r
+ }\r
+ \r
+ /** The highest qHash prime below Integer.MAX_VALUE (which is a qHash prime too). */\r
+ private static final int MAX_INT_CAPACITY = 2147483587;\r
+\r
+\r
+ private boolean isMaxCapacity(int capacity) {\r
+ return capacity >= MAX_INT_CAPACITY;\r
+ }\r
+\r
+ private int grownCapacity() {\r
+ return nearestGreaterCapacity(grow(set.length), size);\r
+ }\r
+\r
+ protected boolean keyEquals(Object a, Object b) {\r
+ return a.equals(b);\r
+ }\r
+\r
+ protected int keyHashCode(Object key) {\r
+ return key.hashCode();\r
+ }\r
+\r
+\r
+ public boolean contains(Object key) {\r
+ return index(key) >= 0;\r
+ }\r
+\r
+ private int index(Object key) {\r
+ // noinspection unchecked\r
+ Object[] keys = set;\r
+ int capacity, index;\r
+ Object cur;\r
+ if ((cur = keys[index = mix(keyHashCode(key)) % (capacity = keys.length)]) == key) {\r
+ // key is present\r
+ return index;\r
+ } else {\r
+ if (cur == FREE) {\r
+ // key is absent, free slot\r
+ return -1;\r
+ } else {\r
+ if (cur != REMOVED) {\r
+ if (keyEquals(key, cur)) {\r
+ // key is present\r
+ return index;\r
+ } else {\r
+ if (noRemoved()) {\r
+ int bIndex = index, fIndex = index, step = 1;\r
+ while (true) {\r
+ if ((bIndex -= step) < 0) bIndex += capacity;\r
+ if ((cur = keys[bIndex]) == key) {\r
+ // key is present\r
+ return bIndex;\r
+ } else if (cur == FREE) {\r
+ // key is absent, free slot\r
+ return -1;\r
+ }\r
+ else if (keyEquals(key, cur)) {\r
+ // key is present\r
+ return bIndex;\r
+ }\r
+ int t;\r
+ if ((t = (fIndex += step) - capacity) >= 0) fIndex = t;\r
+ if ((cur = keys[fIndex]) == key) {\r
+ // key is present\r
+ return fIndex;\r
+ } else if (cur == FREE) {\r
+ // key is absent, free slot\r
+ return -1;\r
+ }\r
+ else if (keyEquals(key, cur)) {\r
+ // key is present\r
+ return fIndex;\r
+ }\r
+ step += 2;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ int bIndex = index, fIndex = index, step = 1;\r
+ while (true) {\r
+ if ((bIndex -= step) < 0) bIndex += capacity;\r
+ if ((cur = keys[bIndex]) == key) {\r
+ // key is present\r
+ return bIndex;\r
+ } else if (cur == FREE) {\r
+ // key is absent, free slot\r
+ return -1;\r
+ }\r
+ else if (cur != REMOVED && keyEquals(key, cur)) {\r
+ // key is present\r
+ return bIndex;\r
+ }\r
+ int t;\r
+ if ((t = (fIndex += step) - capacity) >= 0) fIndex = t;\r
+ if ((cur = keys[fIndex]) == key) {\r
+ // key is present\r
+ return fIndex;\r
+ } else if (cur == FREE) {\r
+ // key is absent, free slot\r
+ return -1;\r
+ }\r
+ else if (cur != REMOVED && keyEquals(key, cur)) {\r
+ // key is present\r
+ return fIndex;\r
+ }\r
+ step += 2;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ private void allocateArrays(int capacity) {\r
+ set = new Object[capacity];\r
+ // not necessary because FREE = null\r
+ // Arrays.fill(set, FREE);\r
+ }\r
+\r
+\r
+ public Object[] toArray() {\r
+ Object[] result = new Object[size];\r
+ if (size == 0)\r
+ return result;\r
+ int resultIndex = 0;\r
+ Object[] keys = set;\r
+ if (noRemoved()) {\r
+ for (int i = keys.length - 1; i >= 0; i--) {\r
+ Object key;\r
+ // noinspection unchecked\r
+ if ((key = keys[i]) != FREE) {\r
+ result[resultIndex++] = key;\r
+ }\r
+ }\r
+ } else {\r
+ for (int i = keys.length - 1; i >= 0; i--) {\r
+ Object key;\r
+ // noinspection unchecked\r
+ if ((key = keys[i]) != FREE && key != REMOVED) {\r
+ result[resultIndex++] = key;\r
+ }\r
+ }\r
+ }\r
+ return result;\r
+ }\r
+\r
+ @SuppressWarnings("unchecked")\r
+ public <T> T[] toArray(T[] a) {\r
+ if (a.length < size) {\r
+ Class<?> elementType = a.getClass().getComponentType();\r
+ a = (T[]) java.lang.reflect.Array.newInstance(elementType, size);\r
+ }\r
+ if (size == 0) {\r
+ if (a.length > 0)\r
+ a[0] = null;\r
+ return a;\r
+ }\r
+ int resultIndex = 0;\r
+ Object[] keys = set;\r
+ if (noRemoved()) {\r
+ for (int i = keys.length - 1; i >= 0; i--) {\r
+ Object key;\r
+ // noinspection unchecked\r
+ if ((key = keys[i]) != FREE) {\r
+ a[resultIndex++] = (T) key;\r
+ }\r
+ }\r
+ } else {\r
+ for (int i = keys.length - 1; i >= 0; i--) {\r
+ Object key;\r
+ // noinspection unchecked\r
+ if ((key = keys[i]) != FREE && key != REMOVED) {\r
+ a[resultIndex++] = (T) key;\r
+ }\r
+ }\r
+ }\r
+ if (a.length > resultIndex)\r
+ a[resultIndex] = null;\r
+ return a;\r
+ }\r
+\r
+ private void rehash(int newCapacity) {\r
+ Object[] keys = set;\r
+ int removedSlots = this.removedSlots;\r
+ internalInit(newCapacity);\r
+ Object[] newKeys = set;\r
+ int capacity = newKeys.length;\r
+ if (removedSlots == 0) {\r
+ for (int i = keys.length - 1; i >= 0; i--) {\r
+ Object key;\r
+ // noinspection unchecked\r
+ if ((key = keys[i]) != FREE) {\r
+ int index;\r
+ if (newKeys[index = mix(keyHashCode(key)) % capacity] != FREE) {\r
+ int bIndex = index, fIndex = index, step = 1;\r
+ while (true) {\r
+ if ((bIndex -= step) < 0) bIndex += capacity;\r
+ if (newKeys[bIndex] == FREE) {\r
+ index = bIndex;\r
+ break;\r
+ }\r
+ int t;\r
+ if ((t = (fIndex += step) - capacity) >= 0) fIndex = t;\r
+ if (newKeys[fIndex] == FREE) {\r
+ index = fIndex;\r
+ break;\r
+ }\r
+ step += 2;\r
+ }\r
+ }\r
+ newKeys[index] = key;\r
+ }\r
+ }\r
+ } else {\r
+ for (int i = keys.length - 1; i >= 0; i--) {\r
+ Object key;\r
+ // noinspection unchecked\r
+ if ((key = keys[i]) != FREE && key != REMOVED) {\r
+ int index;\r
+ if (newKeys[index = mix(keyHashCode(key)) % capacity] != FREE) {\r
+ int bIndex = index, fIndex = index, step = 1;\r
+ while (true) {\r
+ if ((bIndex -= step) < 0) bIndex += capacity;\r
+ if (newKeys[bIndex] == FREE) {\r
+ index = bIndex;\r
+ break;\r
+ }\r
+ int t;\r
+ if ((t = (fIndex += step) - capacity) >= 0) fIndex = t;\r
+ if (newKeys[fIndex] == FREE) {\r
+ index = fIndex;\r
+ break;\r
+ }\r
+ step += 2;\r
+ }\r
+ }\r
+ newKeys[index] = key;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ public void clear() {\r
+ size = 0;\r
+ freeSlots = set.length;\r
+ removedSlots = 0;\r
+ Arrays.fill(set, FREE);\r
+ }\r
+\r
+\r
+ public CHRHashIndex() {\r
+ init(INITIAL_CAPACITY);\r
+ }\r
+\r
+ public boolean add(Object key) {\r
+ Object[] keys = set;\r
+ int capacity, index;\r
+ Object cur;\r
+ keyAbsentFreeSlot:\r
+ if ((cur = keys[index = mix(keyHashCode(key)) % (capacity = keys.length)]) != FREE) {\r
+ if (cur == key) {\r
+ // key is present\r
+ return false;\r
+ } else {\r
+ int firstRemoved;\r
+ if (cur != REMOVED) {\r
+ if (!keyEquals(key, cur)) {\r
+ if (noRemoved()) {\r
+ int bIndex = index, fIndex = index, step = 1;\r
+ while (true) {\r
+ if ((bIndex -= step) < 0) bIndex += capacity;\r
+ if ((cur = keys[bIndex]) == FREE) {\r
+ index = bIndex;\r
+ break keyAbsentFreeSlot;\r
+ } else if (cur == key || (keyEquals(key, cur))) {\r
+ // key is present\r
+ return false;\r
+ }\r
+ int t;\r
+ if ((t = (fIndex += step) - capacity) >= 0) fIndex = t;\r
+ if ((cur = keys[fIndex]) == FREE) {\r
+ index = fIndex;\r
+ break keyAbsentFreeSlot;\r
+ } else if (cur == key || (keyEquals(key, cur))) {\r
+ // key is present\r
+ return false;\r
+ }\r
+ step += 2;\r
+ }\r
+ } else {\r
+ firstRemoved = -1;\r
+ }\r
+ } else {\r
+ // key is present\r
+ return false;\r
+ }\r
+ } else {\r
+ firstRemoved = index;\r
+ }\r
+ keyAbsentRemovedSlot: {\r
+ int bIndex = index, fIndex = index, step = 1;\r
+ while (true) {\r
+ if ((bIndex -= step) < 0) bIndex += capacity;\r
+ if ((cur = keys[bIndex]) == FREE) {\r
+ if (firstRemoved < 0) {\r
+ index = bIndex;\r
+ break keyAbsentFreeSlot;\r
+ } else {\r
+ break keyAbsentRemovedSlot;\r
+ }\r
+ } else if (cur == key) {\r
+ // key is present\r
+ return false;\r
+ } else if (cur != REMOVED) {\r
+ if (keyEquals(key, cur)) {\r
+ // key is present\r
+ return false;\r
+ }\r
+ } else if (firstRemoved < 0) {\r
+ firstRemoved = bIndex;\r
+ }\r
+ int t;\r
+ if ((t = (fIndex += step) - capacity) >= 0) fIndex = t;\r
+ if ((cur = keys[fIndex]) == FREE) {\r
+ if (firstRemoved < 0) {\r
+ index = fIndex;\r
+ break keyAbsentFreeSlot;\r
+ } else {\r
+ break keyAbsentRemovedSlot;\r
+ }\r
+ } else if (cur == key) {\r
+ // key is present\r
+ return false;\r
+ } else if (cur != REMOVED) {\r
+ if (keyEquals(key, cur)) {\r
+ // key is present\r
+ return false;\r
+ }\r
+ } else if (firstRemoved < 0) {\r
+ firstRemoved = fIndex;\r
+ }\r
+ step += 2;\r
+ }\r
+ }\r
+ // key is absent, removed slot\r
+ keys[firstRemoved] = key;\r
+ postRemovedSlotInsertHook();\r
+ return true;\r
+ }\r
+ }\r
+ // key is absent, free slot\r
+ keys[index] = key;\r
+ postFreeSlotInsertHook();\r
+ return true;\r
+ }\r
+\r
+ /**\r
+ * Assumes that the given value doesn't already exist in the index\r
+ * (only optimized with this assumption, the method works correctly\r
+ * even if the assumption does not hold).\r
+ * Returns the old equal element that the given value replaces or\r
+ * null if there is no such elements.\r
+ */\r
+ public Object addFreshAndReturnOld(Object key) {\r
+ Object[] keys = set;\r
+ int capacity, index;\r
+ Object cur;\r
+ keyAbsentFreeSlot: if ((cur = keys[index = mix(keyHashCode(key)) % (capacity = keys.length)]) != FREE) {\r
+ int firstRemoved;\r
+ if (cur != REMOVED) {\r
+ if (!keyEquals(key, cur)) {\r
+ if (noRemoved()) {\r
+ int bIndex = index, fIndex = index, step = 1;\r
+ while (true) {\r
+ if ((bIndex -= step) < 0) bIndex += capacity;\r
+ if ((cur = keys[bIndex]) == FREE) {\r
+ index = bIndex;\r
+ break keyAbsentFreeSlot;\r
+ } else if (keyEquals(key, cur)) {\r
+ keys[bIndex] = key;\r
+ return cur;\r
+ }\r
+ int t;\r
+ if ((t = (fIndex += step) - capacity) >= 0) fIndex = t;\r
+ if ((cur = keys[fIndex]) == FREE) {\r
+ index = fIndex;\r
+ break keyAbsentFreeSlot;\r
+ } else if (keyEquals(key, cur)) {\r
+ keys[fIndex] = key;\r
+ return cur;\r
+ }\r
+ step += 2;\r
+ }\r
+ } else {\r
+ firstRemoved = -1;\r
+ }\r
+ } else {\r
+ keys[index] = key;\r
+ return cur;\r
+ }\r
+ } else {\r
+ firstRemoved = index;\r
+ }\r
+ keyAbsentRemovedSlot: {\r
+ int bIndex = index, fIndex = index, step = 1;\r
+ while (true) {\r
+ if ((bIndex -= step) < 0) bIndex += capacity;\r
+ if ((cur = keys[bIndex]) == FREE) {\r
+ if (firstRemoved < 0) {\r
+ index = bIndex;\r
+ break keyAbsentFreeSlot;\r
+ } else {\r
+ break keyAbsentRemovedSlot;\r
+ }\r
+ } else if (cur != REMOVED) {\r
+ if (keyEquals(key, cur)) {\r
+ keys[bIndex] = key;\r
+ return cur;\r
+ }\r
+ } else if (firstRemoved < 0) {\r
+ firstRemoved = bIndex;\r
+ }\r
+ int t;\r
+ if ((t = (fIndex += step) - capacity) >= 0) fIndex = t;\r
+ if ((cur = keys[fIndex]) == FREE) {\r
+ if (firstRemoved < 0) {\r
+ index = fIndex;\r
+ break keyAbsentFreeSlot;\r
+ } else {\r
+ break keyAbsentRemovedSlot;\r
+ }\r
+ } else if (cur != REMOVED) {\r
+ if (keyEquals(key, cur)) {\r
+ keys[fIndex] = key;\r
+ return cur;\r
+ }\r
+ } else if (firstRemoved < 0) {\r
+ firstRemoved = fIndex;\r
+ }\r
+ step += 2;\r
+ }\r
+ }\r
+ // key is absent, removed slot\r
+ keys[firstRemoved] = key;\r
+ postRemovedSlotInsertHook();\r
+ return null;\r
+ }\r
+ // key is absent, free slot\r
+ keys[index] = key;\r
+ postFreeSlotInsertHook();\r
+ return null;\r
+ }\r
+ \r
+ public Object addFreshAndReturnOldNoRemovals(Object key) {\r
+ Object[] keys = set;\r
+ int capacity, index;\r
+ Object cur;\r
+ keyAbsentFreeSlot: if ((cur = keys[index = mix(keyHashCode(key)) % (capacity = keys.length)]) != FREE) {\r
+ if (!keyEquals(key, cur)) {\r
+ int bIndex = index, fIndex = index, step = 1;\r
+ while (true) {\r
+ if ((bIndex -= step) < 0) bIndex += capacity;\r
+ if ((cur = keys[bIndex]) == FREE) {\r
+ index = bIndex;\r
+ break keyAbsentFreeSlot;\r
+ } else if (keyEquals(key, cur)) {\r
+ keys[bIndex] = key;\r
+ return cur;\r
+ }\r
+ int t;\r
+ if ((t = (fIndex += step) - capacity) >= 0) fIndex = t;\r
+ if ((cur = keys[fIndex]) == FREE) {\r
+ index = fIndex;\r
+ break keyAbsentFreeSlot;\r
+ } else if (keyEquals(key, cur)) {\r
+ keys[fIndex] = key;\r
+ return cur;\r
+ }\r
+ step += 2;\r
+ }\r
+ } else {\r
+ keys[index] = key;\r
+ return cur;\r
+ }\r
+ }\r
+ // key is absent, free slot\r
+ keys[index] = key;\r
+ postFreeSlotInsertHook();\r
+ return null;\r
+ }\r
+\r
+ public boolean remove(Object key) {\r
+ // noinspection unchecked\r
+ Object[] keys = set;\r
+ int capacity, index;\r
+ Object cur;\r
+ keyPresent:\r
+ if ((cur = keys[index = mix(keyHashCode(key)) % (capacity = keys.length)]) != key) {\r
+ if (cur == FREE) {\r
+ // key is absent, free slot\r
+ return false;\r
+ } else {\r
+ if (cur != REMOVED) {\r
+ if (keyEquals(key, cur)) {\r
+ break keyPresent;\r
+ } else {\r
+ if (noRemoved()) {\r
+ int bIndex = index, fIndex = index, step = 1;\r
+ while (true) {\r
+ if ((bIndex -= step) < 0) bIndex += capacity;\r
+ if ((cur = keys[bIndex]) == key) {\r
+ index = bIndex;\r
+ break keyPresent;\r
+ } else if (cur == FREE) {\r
+ // key is absent, free slot\r
+ return false;\r
+ }\r
+ else if (keyEquals(key, cur)) {\r
+ index = bIndex;\r
+ break keyPresent;\r
+ }\r
+ int t;\r
+ if ((t = (fIndex += step) - capacity) >= 0) fIndex = t;\r
+ if ((cur = keys[fIndex]) == key) {\r
+ index = fIndex;\r
+ break keyPresent;\r
+ } else if (cur == FREE) {\r
+ // key is absent, free slot\r
+ return false;\r
+ }\r
+ else if (keyEquals(key, cur)) {\r
+ index = fIndex;\r
+ break keyPresent;\r
+ }\r
+ step += 2;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ int bIndex = index, fIndex = index, step = 1;\r
+ while (true) {\r
+ if ((bIndex -= step) < 0) bIndex += capacity;\r
+ if ((cur = keys[bIndex]) == key) {\r
+ index = bIndex;\r
+ break keyPresent;\r
+ } else if (cur == FREE) {\r
+ // key is absent, free slot\r
+ return false;\r
+ }\r
+ else if (cur != REMOVED && keyEquals(key, cur)) {\r
+ index = bIndex;\r
+ break keyPresent;\r
+ }\r
+ int t;\r
+ if ((t = (fIndex += step) - capacity) >= 0) fIndex = t;\r
+ if ((cur = keys[fIndex]) == key) {\r
+ index = fIndex;\r
+ break keyPresent;\r
+ } else if (cur == FREE) {\r
+ // key is absent, free slot\r
+ return false;\r
+ }\r
+ else if (cur != REMOVED && keyEquals(key, cur)) {\r
+ index = fIndex;\r
+ break keyPresent;\r
+ }\r
+ step += 2;\r
+ }\r
+ }\r
+ }\r
+ // key is present\r
+ keys[index] = REMOVED;\r
+ postRemoveHook();\r
+ return true;\r
+ }\r
+ \r
+ /**\r
+ * Assumes that the key exists in the index. Removes it.\r
+ */\r
+ public void removeKnownToExistKey(Object key) {\r
+ Object[] keys = set;\r
+ int capacity, index;\r
+ keyPresent: if (keys[index = mix(keyHashCode(key)) % (capacity = keys.length)] != key) {\r
+ int bIndex = index, fIndex = index, step = 1;\r
+ while (true) {\r
+ if ((bIndex -= step) < 0) bIndex += capacity;\r
+ if (keys[bIndex] == key) {\r
+ index = bIndex;\r
+ break keyPresent;\r
+ }\r
+ int t;\r
+ if ((t = (fIndex += step) - capacity) >= 0) fIndex = t;\r
+ if (keys[fIndex] == key) {\r
+ index = fIndex;\r
+ break keyPresent;\r
+ }\r
+ step += 2;\r
+ }\r
+ }\r
+ keys[index] = REMOVED;\r
+ postRemoveHook();\r
+ }\r
+ \r
+ /**\r
+ * Assumes that the key exists in the index. Replaces it with an equal key.\r
+ */\r
+ public void replaceKnownToExistKey(Object key, Object replacement) {\r
+ Object[] keys = set;\r
+ int capacity, index;\r
+ keyPresent: if (keys[index = mix(keyHashCode(key)) % (capacity = keys.length)] != key) {\r
+ int bIndex = index, fIndex = index, step = 1;\r
+ while (true) {\r
+ if ((bIndex -= step) < 0) bIndex += capacity;\r
+ if (keys[bIndex] == key) {\r
+ index = bIndex;\r
+ break keyPresent;\r
+ }\r
+ int t;\r
+ if ((t = (fIndex += step) - capacity) >= 0) fIndex = t;\r
+ if (keys[fIndex] == key) {\r
+ index = fIndex;\r
+ break keyPresent;\r
+ }\r
+ step += 2;\r
+ }\r
+ }\r
+ keys[index] = replacement;\r
+ }\r
+\r
+ public Object getEqual(Object key) {\r
+ // noinspection unchecked\r
+ Object[] keys = set;\r
+ int capacity, index;\r
+ Object cur;\r
+ if ((cur = keys[index = mix(keyHashCode(key)) % (capacity = keys.length)]) == FREE)\r
+ return null;\r
+ if (cur != REMOVED) {\r
+ if (keyEquals(key, cur))\r
+ return cur;\r
+ if (noRemoved()) {\r
+ int bIndex = index, fIndex = index, step = 1;\r
+ while (true) {\r
+ if ((bIndex -= step) < 0) bIndex += capacity;\r
+ if ((cur = keys[bIndex]) == FREE)\r
+ return null;\r
+ else if (keyEquals(key, cur))\r
+ return cur;\r
+ int t;\r
+ if ((t = (fIndex += step) - capacity) >= 0) fIndex = t;\r
+ if ((cur = keys[fIndex]) == FREE)\r
+ return null;\r
+ else if (keyEquals(key, cur))\r
+ return cur;\r
+ step += 2;\r
+ }\r
+ }\r
+ }\r
+ int bIndex = index, fIndex = index, step = 1;\r
+ while (true) {\r
+ if ((bIndex -= step) < 0) bIndex += capacity;\r
+ if ((cur = keys[bIndex]) == FREE)\r
+ return null;\r
+ else if (cur != REMOVED && keyEquals(key, cur))\r
+ return cur;\r
+ int t;\r
+ if ((t = (fIndex += step) - capacity) >= 0) fIndex = t;\r
+ if ((cur = keys[fIndex]) == FREE)\r
+ return null;\r
+ else if (cur != REMOVED && keyEquals(key, cur))\r
+ return cur;\r
+ step += 2;\r
+ }\r
+ }\r
+\r
+ public Object getEqualNoRemovals(Object key) {\r
+ Object[] keys = set;\r
+ int capacity, index;\r
+ Object cur;\r
+ if ((cur = keys[index = mix(keyHashCode(key)) % (capacity = keys.length)]) == FREE)\r
+ return null;\r
+ if (keyEquals(key, cur))\r
+ return cur;\r
+ int bIndex = index, fIndex = index, step = 1;\r
+ while (true) {\r
+ if ((bIndex -= step) < 0) bIndex += capacity;\r
+ if ((cur = keys[bIndex]) == FREE)\r
+ return null;\r
+ else if (keyEquals(key, cur))\r
+ return cur;\r
+ int t;\r
+ if ((t = (fIndex += step) - capacity) >= 0) fIndex = t;\r
+ if ((cur = keys[fIndex]) == FREE)\r
+ return null;\r
+ else if (keyEquals(key, cur))\r
+ return cur;\r
+ step += 2;\r
+ }\r
+ }\r
+ \r
+ private static final Scaler minLoadInverse = Scaler.by(1.0 / MIN_LOAD);\r
+ private static final Scaler targetLoadInverse = Scaler.by(1.0 / TARGET_LOAD);\r
+ private static final Scaler maxLoad = Scaler.by(MAX_LOAD);\r
+ private static final Scaler maxLoadInverse = Scaler.by(1.0 / MAX_LOAD);\r
+ private static final Scaler growthFactor = Scaler.by(GROWTH_FACTOR);\r
+\r
+ /**\r
+ * Computes hash table capacity for the given size and min load of this config.\r
+ *\r
+ * @param size size of the hash table to compute capacity for\r
+ * @return if the given size is non-negative, returns the least int capacity such that\r
+ * size / capacity < {@code config().getMinLoad()}, or {@code Integer.MAX_VALUE}\r
+ * if there is no such capacity. If size is negative, result is undefined.\r
+ */\r
+ private static int maxCapacity(int size) {\r
+ return minLoadInverse.scaleUpper(size);\r
+ }\r
+\r
+ /**\r
+ * Computes hash table capacity for the given size and max load of this config.\r
+ *\r
+ * @param size size of the hash table to compute capacity for\r
+ * @return if the given size is non-negative, returns the least int capacity such that\r
+ * size / capacity < {@code config().getMaxLoad()}, or {@code Integer.MAX_VALUE}\r
+ * if there is no such capacity. If size is negative, result is undefined.\r
+ */\r
+ private static int minCapacity(int size) {\r
+ return maxLoadInverse.scaleUpper(size);\r
+ }\r
+\r
+ private static int maxSize(int capacity) {\r
+ return maxLoad.scaleLower(capacity);\r
+ }\r
+\r
+ /**\r
+ * Computes grown hash table capacity for the given capacity and growth factor of this config.\r
+ *\r
+ * @param capacity capacity of the hash table to grow\r
+ * @return if the given capacity is non-negative, returns the least int capacity\r
+ * such that |new capacity - the given capacity * {@code config().getGrowthFactor()}| <\r
+ * 1, or {@code Integer.MAX_VALUE} if there is no such capacity.\r
+ * If the given capacity is negative, result is undefined.\r
+ */\r
+ private static int grow(int capacity) {\r
+ return growthFactor.scaleLower(capacity);\r
+ }\r
+ \r
+ /**\r
+ * Chooses lesser or greater capacity, which one is better for the given {@code size} and\r
+ * hash config. (The {@code desiredCapacity} is just precomputed\r
+ * {@code conf.targetCapacity(size)}).\r
+ *\r
+ * <p>Chooses the capacity which is closer to the {@code desiredCapacity} and conform min or\r
+ * max capacity bounds for the given {@code size} and hash config.\r
+ *\r
+ * <p>If both {@code lesserCapacity} and {@code greaterCapacity} are out of these bounds,\r
+ * {@code onFail} value is returned.\r
+ *\r
+ * @param conf the {@code HashConfigWrapper}\r
+ * @param size should be non-negative\r
+ * @param desiredCapacity precomputed {@code conf.targetCapacity(size)}\r
+ * @param lesserCapacity should be greater than the {@code size} but lesser\r
+ * than the {@code desiredCapacity}\r
+ * @param greaterCapacity should be greater than the {@code desiredCapacity}\r
+ * @param onFail the value to return if both {@code lesserCapacity} and {@code greaterCapacity}\r
+ * are lesser than min size and greater than max size respectively\r
+ * for the given hash config and size\r
+ * @return {@code lesserCapacity} or {@code greaterCapacity}\r
+ * @see #chooseBetter(HashConfigWrapper, long, long, long, long, long)\r
+ */\r
+ private static int chooseBetter(int size,\r
+ int desiredCapacity, int lesserCapacity, int greaterCapacity, int onFail) {\r
+ assert 0 <= size;\r
+ assert size < lesserCapacity && lesserCapacity < desiredCapacity;\r
+ assert desiredCapacity < greaterCapacity;\r
+ if (greaterCapacity - desiredCapacity <= desiredCapacity - lesserCapacity &&\r
+ greaterCapacity <= maxCapacity(size)) {\r
+ return greaterCapacity;\r
+ }\r
+ return lesserCapacity >= minCapacity(size) ? lesserCapacity : onFail;\r
+ }\r
+ \r
+ private static int capacity(int size, int desiredCapacity) {\r
+ int lesserCapacity, greaterCapacity;\r
+ if (desiredCapacity <= MAX_LOOKUP_CAPACITY) {\r
+ int smallTableIndex = SMALL_LOOKUP_TABLE_INDICES[desiredCapacity];\r
+ greaterCapacity = SMALL_LOOKUP_TABLE_CAPACITIES[smallTableIndex];\r
+ if (greaterCapacity == desiredCapacity || smallTableIndex == 0)\r
+ return greaterCapacity;\r
+ lesserCapacity = SMALL_LOOKUP_TABLE_CAPACITIES[smallTableIndex - 1];\r
+ }\r
+ else if (desiredCapacity <= MAX_REGULAR_CHAR_CAPACITY) {\r
+ int capIndex = binarySearch(REGULAR_CHAR_CAPACITIES, (char) desiredCapacity);\r
+ if (capIndex >= 0) // desiredCapacity is found in REGULAR_CHAR_CAPACITIES\r
+ return desiredCapacity;\r
+ capIndex = ~capIndex;\r
+ lesserCapacity = capIndex > 0 ?\r
+ (int) REGULAR_CHAR_CAPACITIES[capIndex - 1] : MAX_LOOKUP_CAPACITY;\r
+ greaterCapacity = REGULAR_CHAR_CAPACITIES[capIndex];\r
+ }\r
+ else if (desiredCapacity <= MAX_REGULAR_INT_CAPACITY) {\r
+ int capIndex = binarySearch(REGULAR_INT_CAPACITIES, desiredCapacity);\r
+ if (capIndex >= 0) // desiredCapacity is found in REGULAR_INT_CAPACITIES\r
+ return desiredCapacity;\r
+ capIndex = ~capIndex;\r
+ lesserCapacity = capIndex > 0 ?\r
+ REGULAR_INT_CAPACITIES[capIndex - 1] : MAX_REGULAR_CHAR_CAPACITY;\r
+ greaterCapacity = REGULAR_INT_CAPACITIES[capIndex];\r
+ }\r
+ else {\r
+ // Since size could be virtual (expected), don't prematurely throw\r
+ // HashOverflowException. If sizes near to Integer.MAX_VALUE is the case,\r
+ // version accepting long size should be used.\r
+ return MAX_INT_CAPACITY;\r
+ }\r
+ return chooseBetter(size, desiredCapacity, lesserCapacity, greaterCapacity,\r
+ greaterCapacity);\r
+ }\r
+\r
+ /** For grow rehash. */\r
+ private static int nearestGreaterCapacity(int desiredCapacity, int currentSize) {\r
+ assert currentSize >= 0 : "currentSize must be non-negative";\r
+ if (desiredCapacity <= MAX_LOOKUP_CAPACITY)\r
+ return SMALL_LOOKUP_TABLE_CAPACITIES[SMALL_LOOKUP_TABLE_INDICES[desiredCapacity]];\r
+ if (desiredCapacity <= MAX_REGULAR_CHAR_CAPACITY) {\r
+ int capIndex = binarySearch(REGULAR_CHAR_CAPACITIES, (char) desiredCapacity);\r
+ // capIndex >= 0 => desiredCapacity IS a regular capacity\r
+ return capIndex < 0 ? REGULAR_CHAR_CAPACITIES[~capIndex] : desiredCapacity;\r
+ }\r
+ final boolean simpleArrays = true;\r
+ if (desiredCapacity <= MAX_REGULAR_INT_CAPACITY) {\r
+ int capIndex = binarySearch(REGULAR_INT_CAPACITIES, desiredCapacity);\r
+ return capIndex < 0 ? REGULAR_INT_CAPACITIES[~capIndex] : desiredCapacity;\r
+ }\r
+ int maxCapacity = MAX_INT_CAPACITY;\r
+ // overflow-aware\r
+ if (currentSize - maxCapacity < 0)\r
+ return maxCapacity;\r
+ if (simpleArrays && currentSize - Integer.MAX_VALUE < 0) {\r
+ // Integer.MAX_VALUE is also a qHash prime, but likely will cause OutOfMemoryError\r
+ return Integer.MAX_VALUE;\r
+ } else {\r
+ // QHash must have at least 1 free slot\r
+ throw new CHRHashOverflowException();\r
+ }\r
+ }\r
+\r
+ private static final char[] SMALL_LOOKUP_TABLE_CAPACITIES = new char[] {\r
+ 7, 11, 19, 23, 31, 43, 47, 59, 67, 71,\r
+ 79, 83, 103, 107, 127, 131, 139, 151, 163, 167,\r
+ 179, 191, 199, 211, 223, 227, 239, 251, 263, 271,\r
+ 283, 307, 311, 331, 347, 359, 367, 379, 383, 419,\r
+ 431, 439, 443, 463, 467, 479, 487, 491, 499, 503,\r
+ 523, 547, 563, 571, 587, 599, 607, 619, 631, 643,\r
+ 647, 659, 683, 691, 719, 727, 739, 743, 751, 787,\r
+ 811, 823, 827, 839, 859, 863, 883, 887, 907, 911,\r
+ 919, 947, 967, 971, 983, 991, 1019\r
+ };\r
+\r
+ private static final byte[] SMALL_LOOKUP_TABLE_INDICES = new byte[] {\r
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,\r
+ 1, 1, 2, 2, 2, 2, 2, 2, 2, 2,\r
+ 3, 3, 3, 3, 4, 4, 4, 4, 4, 4,\r
+ 4, 4, 5, 5, 5, 5, 5, 5, 5, 5,\r
+ 5, 5, 5, 5, 6, 6, 6, 6, 7, 7,\r
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,\r
+ 8, 8, 8, 8, 8, 8, 8, 8, 9, 9,\r
+ 9, 9, 10, 10, 10, 10, 10, 10, 10, 10,\r
+ 11, 11, 11, 11, 12, 12, 12, 12, 12, 12,\r
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,\r
+ 12, 12, 12, 12, 13, 13, 13, 13, 14, 14,\r
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,\r
+ 14, 14, 14, 14, 14, 14, 14, 14, 15, 15,\r
+ 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,\r
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,\r
+ 17, 17, 18, 18, 18, 18, 18, 18, 18, 18,\r
+ 18, 18, 18, 18, 19, 19, 19, 19, 20, 20,\r
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,\r
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,\r
+ 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,\r
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,\r
+ 23, 23, 24, 24, 24, 24, 24, 24, 24, 24,\r
+ 24, 24, 24, 24, 25, 25, 25, 25, 26, 26,\r
+ 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,\r
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,\r
+ 27, 27, 28, 28, 28, 28, 28, 28, 28, 28,\r
+ 28, 28, 28, 28, 29, 29, 29, 29, 29, 29,\r
+ 29, 29, 30, 30, 30, 30, 30, 30, 30, 30,\r
+ 30, 30, 30, 30, 31, 31, 31, 31, 31, 31,\r
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,\r
+ 31, 31, 31, 31, 31, 31, 31, 31, 32, 32,\r
+ 32, 32, 33, 33, 33, 33, 33, 33, 33, 33,\r
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,\r
+ 33, 33, 34, 34, 34, 34, 34, 34, 34, 34,\r
+ 34, 34, 34, 34, 34, 34, 34, 34, 35, 35,\r
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,\r
+ 36, 36, 36, 36, 36, 36, 36, 36, 37, 37,\r
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,\r
+ 38, 38, 38, 38, 39, 39, 39, 39, 39, 39,\r
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,\r
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,\r
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,\r
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,\r
+ 40, 40, 41, 41, 41, 41, 41, 41, 41, 41,\r
+ 42, 42, 42, 42, 43, 43, 43, 43, 43, 43,\r
+ 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,\r
+ 43, 43, 43, 43, 44, 44, 44, 44, 45, 45,\r
+ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,\r
+ 46, 46, 46, 46, 46, 46, 46, 46, 47, 47,\r
+ 47, 47, 48, 48, 48, 48, 48, 48, 48, 48,\r
+ 49, 49, 49, 49, 50, 50, 50, 50, 50, 50,\r
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,\r
+ 50, 50, 50, 50, 51, 51, 51, 51, 51, 51,\r
+ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,\r
+ 51, 51, 51, 51, 51, 51, 51, 51, 52, 52,\r
+ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,\r
+ 52, 52, 52, 52, 53, 53, 53, 53, 53, 53,\r
+ 53, 53, 54, 54, 54, 54, 54, 54, 54, 54,\r
+ 54, 54, 54, 54, 54, 54, 54, 54, 55, 55,\r
+ 55, 55, 55, 55, 55, 55, 55, 55, 55, 55,\r
+ 56, 56, 56, 56, 56, 56, 56, 56, 57, 57,\r
+ 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,\r
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,\r
+ 58, 58, 59, 59, 59, 59, 59, 59, 59, 59,\r
+ 59, 59, 59, 59, 60, 60, 60, 60, 61, 61,\r
+ 61, 61, 61, 61, 61, 61, 61, 61, 61, 61,\r
+ 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,\r
+ 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,\r
+ 62, 62, 62, 62, 63, 63, 63, 63, 63, 63,\r
+ 63, 63, 64, 64, 64, 64, 64, 64, 64, 64,\r
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,\r
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,\r
+ 65, 65, 65, 65, 65, 65, 65, 65, 66, 66,\r
+ 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,\r
+ 67, 67, 67, 67, 68, 68, 68, 68, 68, 68,\r
+ 68, 68, 69, 69, 69, 69, 69, 69, 69, 69,\r
+ 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,\r
+ 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,\r
+ 69, 69, 69, 69, 69, 69, 69, 69, 70, 70,\r
+ 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,\r
+ 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,\r
+ 70, 70, 71, 71, 71, 71, 71, 71, 71, 71,\r
+ 71, 71, 71, 71, 72, 72, 72, 72, 73, 73,\r
+ 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,\r
+ 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,\r
+ 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,\r
+ 75, 75, 75, 75, 76, 76, 76, 76, 76, 76,\r
+ 76, 76, 76, 76, 76, 76, 76, 76, 76, 76,\r
+ 76, 76, 76, 76, 77, 77, 77, 77, 78, 78,\r
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,\r
+ 78, 78, 78, 78, 78, 78, 78, 78, 79, 79,\r
+ 79, 79, 80, 80, 80, 80, 80, 80, 80, 80,\r
+ 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,\r
+ 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,\r
+ 81, 81, 81, 81, 81, 81, 81, 81, 82, 82,\r
+ 82, 82, 82, 82, 82, 82, 82, 82, 82, 82,\r
+ 82, 82, 82, 82, 82, 82, 82, 82, 83, 83,\r
+ 83, 83, 84, 84, 84, 84, 84, 84, 84, 84,\r
+ 84, 84, 84, 84, 85, 85, 85, 85, 85, 85,\r
+ 85, 85, 86, 86, 86, 86, 86, 86, 86, 86,\r
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,\r
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86\r
+ };\r
+\r
+ /** Compile-time constant expression */\r
+ private static final int MAX_LOOKUP_CAPACITY = 1019;\r
+ static {\r
+ if (MAX_LOOKUP_CAPACITY !=\r
+ SMALL_LOOKUP_TABLE_CAPACITIES[SMALL_LOOKUP_TABLE_CAPACITIES.length - 1]) {\r
+ throw new AssertionError();\r
+ }\r
+ }\r
+\r
+ /**\r
+ * These capacities and other regular capacities from {@link #REGULAR_INT_CAPACITIES}\r
+ * and {@link #REGULAR_LONG_CAPACITIES} arrays are generated using a single command\r
+ * {@code $ java QHashCapacities 40 0.005}, i. e. trying to keep 0.5% max difference between\r
+ * neighbouring capacities.\r
+ *\r
+ * @see {@link #main(String[])}\r
+ * @see {@link #generateRegularCapacities(long, double)}\r
+ */\r
+ private static final char[] REGULAR_CHAR_CAPACITIES = new char[] {\r
+ 1031, 1039,\r
+ 1051, 1063, 1087, 1091, 1103, 1123, 1151, 1163, 1171, 1187,\r
+ 1223, 1231, 1259, 1279, 1283, 1291, 1303, 1307, 1319, 1327,\r
+ 1367, 1399, 1423, 1427, 1439, 1447, 1451, 1459, 1471, 1483,\r
+ 1487, 1499, 1511, 1523, 1531, 1543, 1559, 1567, 1571, 1579,\r
+ 1583, 1607, 1619, 1627, 1663, 1667, 1699, 1723, 1747, 1759,\r
+ 1783, 1787, 1811, 1823, 1831, 1847, 1867, 1871, 1879, 1907,\r
+ 1931, 1951, 1979, 1987, 1999, 2003, 2011, 2027, 2039, 2063,\r
+ 2083, 2087, 2099, 2111, 2131, 2143, 2179, 2203, 2207, 2239,\r
+ 2243, 2251, 2267, 2287, 2311, 2339, 2347, 2351, 2371, 2383,\r
+ 2399, 2411, 2423, 2447, 2459, 2467, 2503, 2531, 2539, 2543,\r
+ 2551, 2579, 2591, 2647, 2659, 2663, 2671, 2683, 2687, 2699,\r
+ 2707, 2711, 2719, 2731, 2767, 2791, 2803, 2819, 2843, 2851,\r
+ 2879, 2887, 2903, 2927, 2939, 2963, 2971, 2999, 3011, 3019,\r
+ 3023, 3067, 3079, 3083, 3119, 3163, 3167, 3187, 3191, 3203,\r
+ 3251, 3259, 3271, 3299, 3307, 3319, 3323, 3331, 3343, 3347,\r
+ 3359, 3371, 3391, 3407, 3463, 3467, 3491, 3499, 3511, 3527,\r
+ 3539, 3547, 3559, 3571, 3583, 3607, 3623, 3631, 3643, 3659,\r
+ 3671, 3691, 3719, 3727, 3739, 3767, 3779, 3803, 3823, 3847,\r
+ 3851, 3863, 3907, 3911, 3919, 3923, 3931, 3943, 3947, 3967,\r
+ 4003, 4007, 4019, 4027, 4051, 4079, 4091, 4099, 4111, 4127,\r
+ 4139, 4159, 4211, 4219, 4231, 4243, 4259, 4271, 4283, 4327,\r
+ 4339, 4363, 4391, 4423, 4447, 4451, 4463, 4483, 4507, 4519,\r
+ 4523, 4547, 4567, 4583, 4591, 4603, 4639, 4643, 4651, 4663,\r
+ 4679, 4691, 4703, 4723, 4751, 4759, 4783, 4787, 4799, 4831,\r
+ 4871, 4903, 4919, 4931, 4943, 4951, 4967, 4987, 4999, 5003,\r
+ 5011, 5023, 5039, 5051, 5059, 5087, 5099, 5107, 5119, 5147,\r
+ 5167, 5171, 5179, 5227, 5231, 5279, 5303, 5323, 5347, 5351,\r
+ 5387, 5399, 5407, 5419, 5431, 5443, 5471, 5479, 5483, 5503,\r
+ 5507, 5519, 5527, 5531, 5563, 5591, 5623, 5639, 5647, 5651,\r
+ 5659, 5683, 5711, 5743, 5779, 5783, 5791, 5807, 5827, 5839,\r
+ 5843, 5851, 5867, 5879, 5903, 5923, 5927, 5939, 5987, 6007,\r
+ 6011, 6043, 6047, 6067, 6079, 6091, 6131, 6143, 6151, 6163,\r
+ 6199, 6203, 6211, 6247, 6263, 6271, 6287, 6299, 6311, 6323,\r
+ 6343, 6359, 6367, 6379, 6427, 6451, 6491, 6547, 6551, 6563,\r
+ 6571, 6599, 6607, 6619, 6659, 6679, 6691, 6703, 6719, 6763,\r
+ 6779, 6791, 6803, 6823, 6827, 6863, 6871, 6883, 6899, 6907,\r
+ 6911, 6947, 6959, 6967, 6971, 6983, 6991, 7019, 7027, 7039,\r
+ 7043, 7079, 7103, 7127, 7151, 7159, 7187, 7207, 7211, 7219,\r
+ 7243, 7247, 7283, 7307, 7331, 7351, 7411, 7451, 7459, 7487,\r
+ 7499, 7507, 7523, 7547, 7559, 7583, 7591, 7603, 7607, 7639,\r
+ 7643, 7687, 7691, 7699, 7703, 7723, 7727, 7759, 7823, 7867,\r
+ 7879, 7883, 7907, 7919, 7927, 7951, 7963, 8011, 8039, 8059,\r
+ 8087, 8111, 8123, 8147, 8167, 8171, 8179, 8191, 8219, 8231,\r
+ 8243, 8263, 8287, 8291, 8311, 8363, 8387, 8419, 8423, 8431,\r
+ 8443, 8447, 8467, 8527, 8539, 8543, 8563, 8599, 8623, 8627,\r
+ 8647, 8663, 8699, 8707, 8719, 8731, 8747, 8779, 8783, 8803,\r
+ 8807, 8819, 8831, 8839, 8863, 8867, 8887, 8923, 8951, 8963,\r
+ 8971, 8999, 9007, 9011, 9043, 9059, 9067, 9091, 9103, 9127,\r
+ 9151, 9187, 9199, 9203, 9227, 9239, 9283, 9311, 9319, 9323,\r
+ 9343, 9371, 9391, 9403, 9419, 9431, 9439, 9463, 9467, 9479,\r
+ 9491, 9511, 9539, 9547, 9551, 9587, 9619, 9623, 9631, 9643,\r
+ 9679, 9719, 9739, 9743, 9767, 9787, 9791, 9803, 9811, 9839,\r
+ 9851, 9859, 9871, 9883, 9887, 9907, 9923, 9931, 9967, 10007,\r
+ 10039, 10067, 10079, 10091, 10099, 10103, 10111, 10139, 10151, 10159,\r
+ 10163, 10211, 10223, 10243, 10247, 10259, 10267, 10271, 10303, 10331,\r
+ 10343, 10391, 10399, 10427, 10459, 10463, 10487, 10499, 10531, 10559,\r
+ 10567, 10607, 10627, 10631, 10639, 10651, 10663, 10667, 10687, 10691,\r
+ 10711, 10723, 10739, 10771, 10799, 10831, 10847, 10859, 10867, 10883,\r
+ 10891, 10903, 10939, 10979, 10987, 11003, 11027, 11047, 11059, 11071,\r
+ 11083, 11087, 11119, 11131, 11159, 11171, 11239, 11243, 11251, 11279,\r
+ 11287, 11299, 11311, 11351, 11383, 11399, 11411, 11423, 11443, 11447,\r
+ 11467, 11471, 11483, 11491, 11503, 11519, 11527, 11551, 11579, 11587,\r
+ 11699, 11719, 11731, 11743, 11779, 11783, 11807, 11827, 11831, 11839,\r
+ 11863, 11867, 11887, 11903, 11923, 11927, 11939, 11959, 11971, 11987,\r
+ 12007, 12011, 12043, 12071, 12107, 12119, 12143, 12163, 12203, 12211,\r
+ 12227, 12239, 12251, 12263, 12323, 12343, 12347, 12379, 12391, 12451,\r
+ 12479, 12487, 12491, 12503, 12511, 12527, 12539, 12547, 12583, 12611,\r
+ 12619, 12647, 12659, 12671, 12703, 12739, 12743, 12763, 12791, 12799,\r
+ 12823, 12899, 12919, 12979, 13043, 13099, 13159, 13219, 13259, 13291,\r
+ 13339, 13399, 13463, 13523, 13567, 13619, 13679, 13711, 13763, 13831,\r
+ 13879, 13931, 13999, 14051, 14083, 14143, 14207, 14243, 14303, 14323,\r
+ 14387, 14431, 14503, 14563, 14627, 14683, 14723, 14779, 14851, 14923,\r
+ 14983, 15031, 15083, 15131, 15187, 15259, 15307, 15383, 15439, 15511,\r
+ 15551, 15607, 15667, 15727, 15787, 15859, 15919, 15991, 16063, 16111,\r
+ 16187, 16267, 16339, 16411, 16427, 16487, 16547, 16619, 16691, 16747,\r
+ 16811, 16879, 16963, 17047, 17123, 17207, 17291, 17359, 17443, 17519,\r
+ 17579, 17659, 17747, 17807, 17891, 17959, 18043, 18119, 18199, 18287,\r
+ 18367, 18427, 18503, 18583, 18671, 18719, 18787, 18839, 18899, 18959,\r
+ 19051, 19139, 19231, 19319, 19379, 19423, 19507, 19603, 19687, 19751,\r
+ 19843, 19927, 20023, 20123, 20219, 20287, 20347, 20443, 20543, 20611,\r
+ 20707, 20807, 20879, 20939, 21011, 21107, 21179, 21283, 21379, 21467,\r
+ 21559, 21647, 21739, 21839, 21943, 22039, 22147, 22247, 22343, 22447,\r
+ 22531, 22639, 22751, 22859, 22943, 23027, 23131, 23227, 23339, 23447,\r
+ 23563, 23663, 23767, 23879, 23971, 24043, 24151, 24239, 24359, 24379,\r
+ 24499, 24571, 24683, 24799, 24907, 25031, 25111, 25219, 25339, 25463,\r
+ 25579, 25679, 25799, 25903, 25999, 26099, 26227, 26339, 26407, 26539,\r
+ 26627, 26759, 26879, 27011, 27143, 27271, 27407, 27527, 27631, 27751,\r
+ 27883, 28019, 28151, 28279, 28387, 28499, 28619, 28751, 28879, 29023,\r
+ 29167, 29303, 29443, 29587, 29723, 29851, 29983, 30119, 30259, 30391,\r
+ 30539, 30671, 30803, 30931, 31079, 31231, 31387, 31543, 31699, 31847,\r
+ 31963, 32099, 32251, 32371, 32531, 32687, 32839, 32887, 33023, 33179,\r
+ 33331, 33479, 33647, 33811, 33967, 34123, 34231, 34403, 34543, 34703,\r
+ 34871, 35023, 35171, 35339, 35507, 35671, 35803, 35951, 36131, 36299,\r
+ 36451, 36587, 36767, 36943, 37123, 37307, 37447, 37619, 37799, 37987,\r
+ 38167, 38351, 38543, 38671, 38851, 39043, 39227, 39419, 39607, 39779,\r
+ 39971, 40151, 40343, 40499, 40699, 40847, 41039, 41243, 41443, 41647,\r
+ 41843, 41983, 42179, 42359, 42571, 42743, 42943, 43151, 43331, 43543,\r
+ 43759, 43943, 44131, 44351, 44563, 44771, 44959, 45179, 45403, 45599,\r
+ 45823, 46051, 46271, 46471, 46687, 46919, 47111, 47339, 47563, 47791,\r
+ 48023, 48259, 48491, 48731, 48947, 49171, 49391, 49627, 49871, 50111,\r
+ 50359, 50587, 50839, 51031, 51263, 51511, 51767, 52027, 52259, 52511,\r
+ 52747, 53003, 53267, 53527, 53791, 54059, 54311, 54583, 54851, 55079,\r
+ 55331, 55579, 55843, 56123, 56383, 56659, 56911, 57191, 57467, 57719,\r
+ 57991, 58271, 58543, 58831, 59107, 59387, 59659, 59951, 60251, 60527,\r
+ 60811, 61091, 61379, 61687, 61991, 62299, 62591, 62903, 63179, 63487,\r
+ 63803, 64123, 64439, 64747, 65063, 65371\r
+ };\r
+\r
+ /** Compile-time constant expression */\r
+ private static final int MAX_REGULAR_CHAR_CAPACITY = 65371;\r
+ static {\r
+ if (MAX_REGULAR_CHAR_CAPACITY !=\r
+ REGULAR_CHAR_CAPACITIES[REGULAR_CHAR_CAPACITIES.length - 1])\r
+ throw new AssertionError();\r
+ }\r
+\r
+\r
+ private static final int[] REGULAR_INT_CAPACITIES = new int[] {\r
+ 65687, 65827, 66103, 66431,\r
+ 66751, 67079, 67391, 67699, 68023, 68351, 68687, 69031, 69371, 69691,\r
+ 69991, 70327, 70627, 70979, 71327, 71647, 71947, 72271, 72623, 72931,\r
+ 73291, 73643, 73999, 74323, 74687, 75011, 75367, 75731, 76091, 76463,\r
+ 76819, 77167, 77527, 77899, 78259, 78607, 78979, 79319, 79687, 80039,\r
+ 80407, 80803, 81203, 81611, 82003, 82387, 82787, 83203, 83563, 83891,\r
+ 84299, 84691, 85103, 85523, 85931, 86351, 86783, 87211, 87643, 88079,\r
+ 88499, 88919, 89363, 89759, 90187, 90631, 91079, 91499, 91939, 92399,\r
+ 92863, 93307, 93763, 94219, 94687, 95131, 95603, 96059, 96527, 96979,\r
+ 97459, 97919, 98387, 98867, 99347, 99823, 100291, 100787, 101267, 101719,\r
+ 102191, 102667, 103171, 103687, 104207, 104707, 105227, 105751, 106279, 106787,\r
+ 107323, 107827, 108343, 108883, 109423, 109943, 110479, 111031, 111539, 112067,\r
+ 112603, 113159, 113719, 114259, 114799, 115363, 115931, 116491, 117071, 117659,\r
+ 118247, 118831, 119419, 119963, 120539, 121123, 121687, 122263, 122867, 123479,\r
+ 124067, 124643, 125243, 125863, 126443, 127031, 127607, 128239, 128879, 129499,\r
+ 130147, 130783, 131363, 131543, 132199, 132859, 133519, 134171, 134807, 135463,\r
+ 136139, 136811, 137491, 138179, 138863, 139511, 140191, 140891, 141587, 142271,\r
+ 142979, 143687, 144379, 145091, 145799, 146519, 147211, 147919, 148627, 149371,\r
+ 150107, 150847, 151603, 152363, 153107, 153871, 154619, 155371, 156119, 156887,\r
+ 157667, 158443, 159223, 160019, 160807, 161611, 162419, 163211, 164023, 164839,\r
+ 165667, 166487, 167311, 168151, 168991, 169823, 170647, 171491, 172331, 173183,\r
+ 174047, 174907, 175783, 176651, 177511, 178403, 179287, 180179, 181003, 181871,\r
+ 182779, 183691, 184607, 185519, 186451, 187367, 188291, 189199, 190147, 191047,\r
+ 192007, 192971, 193939, 194911, 195887, 196871, 197831, 198811, 199783, 200771,\r
+ 201743, 202751, 203767, 204751, 205759, 206779, 207799, 208843, 209887, 210907,\r
+ 211927, 212987, 214003, 215051, 216119, 217199, 218279, 219371, 220447, 221539,\r
+ 222587, 223667, 224683, 225751, 226819, 227947, 228983, 230123, 231271, 232391,\r
+ 233551, 234659, 235783, 236947, 238099, 239287, 240479, 241603, 242807, 244003,\r
+ 245171, 246371, 247607, 248851, 250091, 251323, 252559, 253787, 255043, 256307,\r
+ 257591, 258871, 260171, 261427, 262723, 263951, 265271, 266587, 267887, 269219,\r
+ 270563, 271919, 273271, 274579, 275911, 277223, 278591, 279967, 281363, 282767,\r
+ 284159, 285559, 286987, 288403, 289843, 291299, 292759, 294223, 295699, 297151,\r
+ 298631, 300119, 301579, 303091, 304559, 306083, 307583, 309091, 310643, 312199,\r
+ 313679, 315247, 316819, 318403, 319967, 321547, 323123, 324743, 326351, 327967,\r
+ 329587, 331231, 332887, 334547, 336199, 337859, 339467, 341171, 342871, 344587,\r
+ 346303, 348011, 349759, 351503, 353263, 355027, 356803, 358591, 360391, 362143,\r
+ 363959, 365779, 367603, 369407, 371227, 373091, 374939, 376787, 378667, 380563,\r
+ 382463, 384359, 386279, 388211, 390151, 392099, 394063, 396031, 398011, 399979,\r
+ 401939, 403951, 405947, 407923, 409967, 412019, 414083, 416147, 418199, 420263,\r
+ 422311, 424423, 426527, 428639, 430783, 432931, 435103, 437263, 439459, 441667,\r
+ 443867, 446087, 448303, 450479, 452731, 454991, 457267, 459523, 461803, 464119,\r
+ 466423, 468739, 471091, 473443, 475807, 478171, 480563, 482947, 485347, 487783,\r
+ 490207, 492647, 495119, 497587, 500083, 502543, 505067, 507599, 510127, 512663,\r
+ 515191, 517739, 520339, 522947, 525571, 528163, 530807, 533447, 536111, 538799,\r
+ 541483, 544199, 546919, 549623, 552379, 555143, 557927, 560719, 563503, 566311,\r
+ 569083, 571939, 574799, 577627, 580471, 583367, 586291, 589187, 592139, 595087,\r
+ 598051, 601031, 604031, 607043, 610063, 613099, 616171, 619247, 622331, 625451,\r
+ 628583, 631711, 634859, 638023, 641227, 644431, 647659, 650911, 654163, 657431,\r
+ 660727, 664043, 667363, 670711, 674059, 677387, 680783, 684191, 687623, 691051,\r
+ 694511, 697979, 701479, 704999, 708527, 712067, 715639, 719179, 722783, 726367,\r
+ 729991, 733651, 737327, 741007, 744727, 748463, 752183, 755959, 759719, 763523,\r
+ 767323, 771143, 775007, 778871, 782783, 786659, 790567, 794531, 798487, 802471,\r
+ 806503, 810539, 814579, 818659, 822763, 826879, 831023, 835123, 839303, 843503,\r
+ 847727, 851971, 856187, 860479, 864803, 869119, 873463, 877843, 882239, 886651,\r
+ 891103, 895571, 900019, 904531, 909071, 913639, 918199, 922807, 927403, 931999,\r
+ 936679, 941383, 946091, 950839, 955607, 960383, 965179, 970027, 974891, 979787,\r
+ 984703, 989623, 994559, 999491, 1004483, 1009483, 1014547, 1019639, 1024703, 1029823,\r
+ 1034983, 1040167, 1045391, 1050631, 1054171, 1059439, 1064743, 1070087, 1075463, 1080847,\r
+ 1086259, 1091711, 1097179, 1102691, 1108223, 1113787, 1119359, 1124983, 1130627, 1136299,\r
+ 1142003, 1147739, 1153487, 1159283, 1165103, 1170947, 1176827, 1182739, 1188667, 1194631,\r
+ 1200607, 1206619, 1212671, 1218727, 1224823, 1230967, 1237139, 1243343, 1249559, 1255811,\r
+ 1262119, 1268447, 1274803, 1281187, 1287623, 1294087, 1300571, 1307063, 1313623, 1320191,\r
+ 1326791, 1333411, 1340107, 1346827, 1353551, 1360327, 1367159, 1374007, 1380887, 1387783,\r
+ 1394747, 1401739, 1408763, 1415803, 1422899, 1430027, 1437199, 1444411, 1451603, 1458871,\r
+ 1466147, 1473503, 1480903, 1488343, 1495751, 1503247, 1510759, 1518343, 1525963, 1533583,\r
+ 1541251, 1548947, 1556719, 1564499, 1572359, 1580251, 1588159, 1596107, 1604123, 1612183,\r
+ 1620247, 1628383, 1636543, 1644691, 1652947, 1661243, 1669543, 1677899, 1686319, 1694767,\r
+ 1703267, 1711799, 1720399, 1729043, 1737691, 1746419, 1755179, 1763959, 1772819, 1781699,\r
+ 1790599, 1799591, 1808627, 1817663, 1826771, 1835923, 1845119, 1854379, 1863671, 1873019,\r
+ 1882403, 1891859, 1901359, 1910891, 1920487, 1930099, 1939787, 1949527, 1959283, 1969111,\r
+ 1978927, 1988839, 1998827, 2008807, 2018899, 2029003, 2039179, 2049419, 2059711, 2069959,\r
+ 2080339, 2090771, 2101259, 2106551, 2117119, 2127739, 2138387, 2149127, 2159923, 2170771,\r
+ 2181671, 2192623, 2203631, 2214691, 2225819, 2236987, 2248223, 2259503, 2270803, 2282207,\r
+ 2293567, 2305091, 2316667, 2328307, 2340007, 2351731, 2363507, 2375327, 2387243, 2399207,\r
+ 2411243, 2423359, 2435519, 2447743, 2460043, 2472403, 2484803, 2497259, 2509807, 2522407,\r
+ 2535059, 2547791, 2560583, 2573423, 2586343, 2599327, 2612383, 2625487, 2638651, 2651899,\r
+ 2665199, 2678551, 2692003, 2705519, 2719111, 2732759, 2746423, 2760223, 2774071, 2788007,\r
+ 2802011, 2816059, 2830151, 2844367, 2858623, 2872967, 2887363, 2901839, 2916383, 2930999,\r
+ 2945707, 2960467, 2975339, 2990279, 3005267, 3020351, 3035507, 3050759, 3066067, 3081443,\r
+ 3096911, 3112391, 3127979, 3143671, 3159439, 3175259, 3191099, 3207119, 3223223, 3239419,\r
+ 3255683, 3272039, 3288479, 3304991, 3321583, 3338263, 3355031, 3371867, 3388799, 3405791,\r
+ 3422807, 3439987, 3457271, 3474599, 3492043, 3509587, 3527219, 3544907, 3562711, 3580579,\r
+ 3598519, 3616583, 3634727, 3652991, 3671347, 3689771, 3708283, 3726911, 3745631, 3764443,\r
+ 3783343, 3802283, 3821327, 3840479, 3859759, 3879023, 3898483, 3918067, 3937751, 3957479,\r
+ 3977339, 3997307, 4017359, 4037531, 4057799, 4078187, 4098659, 4119239, 4139923, 4160711,\r
+ 4181579, 4202567, 4210807, 4231943, 4253203, 4274551, 4295999, 4317571, 4339207, 4361003,\r
+ 4382879, 4404899, 4426999, 4449227, 4471559, 4494019, 4516571, 4539247, 4562039, 4584959,\r
+ 4607987, 4631131, 4654399, 4677779, 4701239, 4724831, 4748563, 4772399, 4796371, 4820443,\r
+ 4844659, 4868999, 4893419, 4918007, 4942687, 4967491, 4992419, 5017447, 5042647, 5067967,\r
+ 5093423, 5119007, 5144707, 5170519, 5196467, 5222579, 5248787, 5275159, 5301623, 5328251,\r
+ 5355019, 5381927, 5408947, 5436127, 5463391, 5490787, 5518351, 5546071, 5573927, 5601907,\r
+ 5630039, 5658307, 5686739, 5715299, 5743987, 5772847, 5801843, 5830963, 5860243, 5889683,\r
+ 5919271, 5948939, 5978831, 6008867, 6038999, 6069311, 6099767, 6130391, 6161063, 6192023,\r
+ 6223099, 6254359, 6285787, 6317327, 6349043, 6380939, 6412999, 6445223, 6477599, 6510107,\r
+ 6542803, 6575671, 6608639, 6641839, 6675211, 6708739, 6742363, 6776207, 6810247, 6844447,\r
+ 6878803, 6913351, 6948079, 6982907, 7017979, 7053223, 7088611, 7124231, 7159987, 7195963,\r
+ 7232111, 7268423, 7304939, 7341647, 7378531, 7415599, 7452859, 7490303, 7527911, 7565627,\r
+ 7603627, 7641791, 7680191, 7718771, 7757543, 7796491, 7835647, 7874983, 7914551, 7954319,\r
+ 7994279, 8034451, 8074811, 8115383, 8156147, 8197099, 8238247, 8279627, 8321227, 8363023,\r
+ 8405003, 8419511, 8461787, 8504291, 8546999, 8589923, 8633063, 8676431, 8719987, 8763803,\r
+ 8807803, 8852059, 8896483, 8941171, 8986091, 9031207, 9076579, 9122143, 9167923, 9213979,\r
+ 9260263, 9306779, 9353483, 9400463, 9447667, 9495139, 9542843, 9590699, 9638891, 9687323,\r
+ 9735991, 9784903, 9834047, 9883463, 9933059, 9982939, 10033063, 10083443, 10134107, 10185011,\r
+ 10236179, 10287587, 10339267, 10391219, 10443431, 10495907, 10548623, 10601627, 10654871, 10708403,\r
+ 10762211, 10816271, 10870619, 10925227, 10980059, 11035223, 11090627, 11146279, 11202251, 11258483,\r
+ 11314987, 11371807, 11428931, 11486347, 11544047, 11602043, 11660339, 11718923, 11777791, 11836963,\r
+ 11896427, 11956199, 12016187, 12076567, 12137183, 12198139, 12259399, 12320983, 12382823, 12445039,\r
+ 12507559, 12570403, 12633559, 12697039, 12760843, 12824899, 12889339, 12954079, 13019143, 13084531,\r
+ 13150279, 13216331, 13282723, 13349411, 13416463, 13483751, 13551467, 13619563, 13687987, 13756739,\r
+ 13825831, 13895291, 13965103, 14035279, 14105759, 14176619, 14247847, 14319419, 14391359, 14463667,\r
+ 14536307, 14609351, 14682719, 14756491, 14830603, 14905123, 14980019, 15055259, 15130903, 15206899,\r
+ 15283291, 15360071, 15437239, 15514783, 15592739, 15671087, 15749819, 15828947, 15908423, 15988363,\r
+ 16068691, 16149431, 16230491, 16312039, 16394003, 16476371, 16559159, 16642343, 16725971, 16810007,\r
+ 16836587, 16921183, 17006167, 17091623, 17177507, 17263783, 17350519, 17437691, 17525243, 17613307,\r
+ 17701807, 17790739, 17880067, 17969911, 18060187, 18150911, 18242083, 18333703, 18425819, 18518363,\r
+ 18611419, 18704927, 18798907, 18893351, 18988267, 19083679, 19179551, 19275847, 19372699, 19470019,\r
+ 19567811, 19666123, 19764947, 19864267, 19964059, 20064371, 20165143, 20266391, 20368211, 20470547,\r
+ 20573411, 20676791, 20780659, 20885071, 20989967, 21095423, 21201347, 21307859, 21414923, 21522511,\r
+ 21630659, 21739351, 21848579, 21958367, 22068647, 22179511, 22290943, 22402951, 22515511, 22628651,\r
+ 22742303, 22856527, 22971259, 23086667, 23202643, 23319227, 23436407, 23554099, 23672459, 23791399,\r
+ 23910947, 24031087, 24151807, 24273163, 24395023, 24517607, 24640799, 24764611, 24889043, 25014071,\r
+ 25139767, 25266071, 25393031, 25520623, 25648867, 25777639, 25907143, 26037299, 26168099, 26299571,\r
+ 26431723, 26564507, 26697991, 26832139, 26966963, 27102419, 27238559, 27375419, 27512951, 27651191,\r
+ 27790127, 27929723, 28070071, 28211123, 28352887, 28495351, 28638539, 28782419, 28927039, 29072399,\r
+ 29218403, 29365207, 29512739, 29661043, 29810023, 29959819, 30110347, 30261643, 30413707, 30566519,\r
+ 30720119, 30874483, 31029587, 31185443, 31342139, 31499599, 31657783, 31816847, 31976723, 32137403,\r
+ 32298863, 32461159, 32624239, 32788099, 32952839, 33118391, 33284803, 33452047, 33619979, 33670103,\r
+ 33839243, 34009279, 34180163, 34351879, 34524491, 34697951, 34872283, 35047483, 35223599, 35400583,\r
+ 35578471, 35757247, 35936903, 36117467, 36298943, 36481343, 36664651, 36848891, 37033987, 37220047,\r
+ 37407059, 37595027, 37783927, 37973783, 38164571, 38356327, 38548999, 38742707, 38937319, 39132979,\r
+ 39329627, 39527123, 39725723, 39925339, 40125947, 40327571, 40530199, 40733867, 40938523, 41144203,\r
+ 41350943, 41558687, 41767483, 41977367, 42188287, 42400243, 42613303, 42827431, 43042631, 43258907,\r
+ 43476287, 43694747, 43914307, 44134931, 44356639, 44579503, 44803511, 45028639, 45254899, 45482291,\r
+ 45710831, 45940523, 46171351, 46403347, 46636519, 46870867, 47106379, 47343083, 47580983, 47820079,\r
+ 48060359, 48301867, 48544583, 48788503, 49033651, 49280003, 49527619, 49776479, 50026607, 50277979,\r
+ 50530619, 50784523, 51039683, 51296159, 51553903, 51812927, 52073279, 52334951, 52597891, 52862143,\r
+ 53127779, 53394727, 53663039, 53932651, 54203659, 54476027, 54749771, 55024859, 55301359, 55579243,\r
+ 55858459, 56139079, 56421151, 56704667, 56989571, 57275927, 57563699, 57852943, 58143583, 58435703,\r
+ 58729331, 59024443, 59321039, 59619127, 59918687, 60219779, 60522379, 60826511, 61132163, 61439239,\r
+ 61747963, 62058247, 62370079, 62683463, 62998451, 63314959, 63633079, 63952799, 64274159, 64597111,\r
+ 64921699, 65247907, 65575747, 65905267, 66236431, 66569267, 66903779, 67239967, 67338643, 67677007,\r
+ 68017067, 68358739, 68702143, 69047299, 69394219, 69742919, 70093327, 70445519, 70799507, 71155267,\r
+ 71512787, 71872127, 72233279, 72596243, 72961039, 73327651, 73696111, 74066411, 74438591, 74812651,\r
+ 75188591, 75566347, 75946067, 76327703, 76711231, 77096707, 77484083, 77873431, 78264727, 78657983,\r
+ 79053187, 79450363, 79849543, 80250763, 80654027, 81059287, 81466579, 81875951, 82287379, 82700791,\r
+ 83116367, 83534023, 83953763, 84375623, 84799619, 85225739, 85653947, 86084287, 86516863, 86951603,\r
+ 87388531, 87827647, 88268987, 88712527, 89158283, 89606287, 90056467, 90508987, 90963799, 91420867,\r
+ 91880263, 92341967, 92805983, 93272327, 93741019, 94212031, 94685419, 95161219, 95639387, 96119927,\r
+ 96602903, 97088339, 97576163, 98066491, 98559259, 99054523, 99552227, 100052467, 100555243, 101060539,\r
+ 101568287, 102078679, 102591631, 103107119, 103625239, 104145887, 104669179, 105195127, 105723743, 106254899,\r
+ 106788827, 107325451, 107864747, 108406763, 108951503, 109498943, 110049059, 110602031, 111157807, 111716383,\r
+ 112277699, 112841863, 113408767, 113978507, 114551263, 115126883, 115705351, 116286743, 116871091, 117458347,\r
+ 118048547, 118641739, 119237927, 119837059, 120439243, 121044431, 121652599, 122263903, 122878211, 123495683,\r
+ 124116191, 124739887, 125366567, 125996539, 126629663, 127265951, 127905443, 128548139, 129194083, 129843299,\r
+ 130495763, 131151491, 131810491, 132472831, 133138519, 133807547, 134479879, 134673607, 135350351, 136030471,\r
+ 136714027, 137400979, 138091427, 138785203, 139482599, 140183503, 140887919, 141595859, 142307287, 143022359,\r
+ 143741047, 144463339, 145189259, 145918711, 146651903, 147388823, 148129447, 148873787, 149621891, 150373759,\r
+ 151129399, 151888843, 152652103, 153419159, 154190087, 154964867, 155743583, 156526207, 157312763, 158103259,\r
+ 158897743, 159696211, 160498699, 161305211, 162115787, 162930419, 163749119, 164571971, 165398927, 166230007,\r
+ 167065303, 167904791, 168748499, 169596463, 170448683, 171305207, 172165991, 173031143, 173900563, 174774427,\r
+ 175652671, 176535311, 177422411, 178313951, 179209991, 180110471, 181015519, 181925111, 182839303, 183758039,\r
+ 184681411, 185609447, 186542099, 187479491, 188421539, 189368371, 190319959, 191276291, 192237431, 193203431,\r
+ 194174191, 195149939, 196130579, 197116159, 198106663, 199102151, 200102579, 201108043, 202118563, 203134123,\r
+ 204154859, 205180751, 206211799, 207248011, 208289351, 209336027, 210387907, 211445131, 212507651, 213575503,\r
+ 214648699, 215727247, 216811267, 217900763, 218995739, 220096183, 221202119, 222313643, 223430791, 224553523,\r
+ 225681923, 226815983, 227955727, 229101203, 230252411, 231409439, 232572299, 233740999, 234915539, 236095939,\r
+ 237282343, 238474711, 239672963, 240877339, 242087771, 243304219, 244526851, 245755619, 246990559, 248231707,\r
+ 249479099, 250732739, 251992667, 253258879, 254531507, 255810559, 257096039, 258387967, 259686391, 260991287,\r
+ 262302791, 263620879, 264945587, 266276947, 267614983, 268959767, 269344759, 270698227, 272058491, 273425591,\r
+ 274799579, 276180431, 277568219, 278963011, 280364803, 281773571, 283189499, 284612527, 286042723, 287480071,\r
+ 288924599, 290376451, 291835627, 293302123, 294775991, 296257271, 297745967, 299242171, 300745843, 302257051,\r
+ 303775919, 305302427, 306836599, 308378407, 309928027, 311485423, 313050587, 314623703, 316204703, 317793559,\r
+ 319390507, 320995471, 322608491, 324229639, 325858867, 327496339, 329142019, 330795991, 332458267, 334128887,\r
+ 335807831, 337495303, 339191227, 340895683, 342608719, 344330351, 346060571, 347799511, 349547071, 351303583,\r
+ 353068907, 354843119, 356626211, 358418243, 360219283, 362029403, 363848627, 365676923, 367514491, 369361231,\r
+ 371217299, 373082707, 374957483, 376841587, 378735251, 380638387, 382551083, 384473399, 386405387, 388347103,\r
+ 390298547, 392259767, 394230899, 396211903, 398202899, 400203871, 402214927, 404236087, 406267391, 408308899,\r
+ 410360539, 412422631, 414495091, 416577947, 418671283, 420775151, 422889583, 425014571, 427150247, 429296719,\r
+ 431453983, 433622011, 435800971, 437990923, 440191879, 442403887, 444627019, 446861267, 449106787, 451363571,\r
+ 453631727, 455911259, 458202211, 460504699, 462818767, 465144487, 467481851, 469831003, 472191851, 474564667,\r
+ 476949379, 479346103, 481754807, 484175663, 486608687, 489053951, 491511491, 493981363, 496463519, 498958307,\r
+ 501465563, 503985479, 506518063, 509063299, 511621387, 514192271, 516776131, 519372859, 521982751, 524605747,\r
+ 527241899, 529891199, 532553939, 535230083, 537919639, 538685971, 541392743, 544113239, 546847447, 549595367,\r
+ 552357139, 555132803, 557922367, 560725951, 563543663, 566375527, 569221603, 572081959, 574956703, 577845787,\r
+ 580749511, 583667831, 586600783, 589548499, 592511039, 595488451, 598480807, 601488211, 604510703, 607548371,\r
+ 610601371, 613669687, 616753427, 619852679, 622967503, 626097991, 629244167, 632406163, 635584031, 638777903,\r
+ 641987839, 645213847, 648456091, 651714607, 654989519, 658280863, 661588783, 664913323, 668254571, 671612587,\r
+ 674987507, 678379379, 681788203, 685214251, 688657483, 692117983, 695595931, 699091331, 702604327, 706134991,\r
+ 709683371, 713249591, 716833727, 720435851, 724056107, 727694531, 731351279, 735026371, 738719939, 742432063,\r
+ 746162863, 749912399, 753680731, 757468067, 761274403, 765099883, 768944587, 772808551, 776691959, 780594923,\r
+ 784517507, 788459759, 792421843, 796403831, 800405831, 804427927, 808470259, 812532911, 816615971, 820719539,\r
+ 824843651, 828988331, 833154031, 837340703, 841548427, 845777279, 850027351, 854298799, 858591751, 862906279,\r
+ 867242491, 871600487, 875980379, 880382287, 884806283, 889252471, 893721071, 898212083, 902725711, 907261963,\r
+ 911821051, 916403011, 921007907, 925636079, 930287503, 934962299, 939660587, 944382499, 949128119, 953897599,\r
+ 958691051, 963508519, 968350231, 973216267, 978106799, 983021807, 987961591, 992926211, 997915771, 1002930347,\r
+ 1007970143, 1013035271, 1018125743, 1023241907, 1028383823, 1033551523, 1038745151, 1043964947, 1049210831, 1054483151,\r
+ 1059782051, 1065107587, 1070459851, 1075839019, 1077368339, 1082782187, 1088223299, 1093691743, 1099187591, 1104711019,\r
+ 1110262327, 1115841499, 1121448739, 1127084059, 1132747771, 1138439959, 1144160711, 1149910183, 1155688603, 1161496079,\r
+ 1167332711, 1173198647, 1179094079, 1185019067, 1190973899, 1196958667, 1202973511, 1209018599, 1215094019, 1221199951,\r
+ 1227336631, 1233504079, 1239702463, 1245932059, 1252193003, 1258485419, 1264809463, 1271165167, 1277552923, 1283972759,\r
+ 1290424799, 1296909343, 1303426459, 1309976287, 1316559071, 1323174883, 1329823987, 1336506463, 1343222567, 1349972251,\r
+ 1356756031, 1363573879, 1370425967, 1377312463, 1384233491, 1391189419, 1398180307, 1405206307, 1412267611, 1419364259,\r
+ 1426496711, 1433664959, 1440869279, 1448109779, 1455386671, 1462700131, 1470050363, 1477437523, 1484861771, 1492323307,\r
+ 1499822383, 1507359151, 1514933747, 1522546447, 1530197423, 1537886851, 1545614899, 1553381771, 1561187699, 1569032827,\r
+ 1576917379, 1584841567, 1592805583, 1600809611, 1608853859, 1616938507, 1625063819, 1633229951, 1641437099, 1649685467,\r
+ 1657975307, 1666306819, 1674680207, 1683095671, 1691553427, 1700053627, 1708596587, 1717182347, 1725811267, 1734483643,\r
+ 1743199571, 1751959367, 1760763107, 1769611087, 1778503583, 1787440747, 1796422847, 1805449999, 1814522603, 1823640799,\r
+ 1832804767, 1842014791, 1851271043, 1860573907, 1869923411, 1879319999, 1888763743, 1898254999, 1907793931, 1917380807,\r
+ 1927015879, 1936699351, 1946431363, 1956212243, 1966042451, 1975922059, 1985851247, 1995830323, 2005859543, 2015939239,\r
+ 2026069559, 2036250751, 2046483151, 2056766983, 2067102431, 2077489807, 2087929451, 2098421519, 2108966287, 2119564099,\r
+ 2130215159, 2140919723,\r
+ };\r
+\r
+\r
+ // Compile-time constant expressions\r
+ private static final int MAX_REGULAR_CAPACITY_FOR_DOUBLED_ARRAY = 107325451;\r
+ private static final int MAX_REGULAR_INT_CAPACITY = 2140919723;\r
+ static {\r
+ if (MAX_REGULAR_INT_CAPACITY != REGULAR_INT_CAPACITIES[REGULAR_INT_CAPACITIES.length - 1] ||\r
+ binarySearch(REGULAR_INT_CAPACITIES, MAX_REGULAR_CAPACITY_FOR_DOUBLED_ARRAY) < 0)\r
+ throw new AssertionError();\r
+ }\r
+ \r
+ /**\r
+ * Class for precise and fast scaling non-negative integers by positive doubles.\r
+ *\r
+ * <p>Used in {@link com.koloboke.collect.impl.hash.HashConfigWrapper}.\r
+ *\r
+ * <p>Latencies of operations on floating stack, required for simple approach scaling\r
+ * <pre>\r
+ * Haswell Steamroller\r
+ * FILD (long -> double) 6 11\r
+ * FMUL 5 5\r
+ * FDIV 10-24 9-37\r
+ * FIST (double -> long) 7 7\r
+ * </pre>\r
+ *\r
+ * <p>In major cases {@code Scaler} allows to replace this\r
+ * with megamorphic call cost + a few clock cycles.\r
+ */\r
+ private static class Scaler {\r
+\r
+ public static Scaler by(double scale) {\r
+ if (Double.isNaN(scale) || scale <= 0.0 || Double.isInfinite(scale))\r
+ throw new IllegalArgumentException(\r
+ "Scale should be a finite positive number, " + scale + " is given");\r
+ if (scale == 0.25) return BY_0_25;\r
+ // Special "precise" BigDecimal forms for scales which are inversions of custom\r
+ // scales are needed to preserve inversion consistency\r
+ if (scale == 1.0 / 3.0) return BY_3_0_INVERSE;\r
+ if (scale == 0.5) return BY_0_5;\r
+ if (scale == 1 / 1.5) return BY_1_5_INVERSE;\r
+ if (scale == 0.75) return BY_0_75;\r
+ if (scale == 1.0) return BY_1_0;\r
+ if (scale == 1.0 / 0.75) return BY_0_75_INVERSE;\r
+ if (scale == 1.5) return BY_1_5;\r
+ if (scale == 2.0) return BY_2_0;\r
+ if (scale == 3.0) return BY_3_0;\r
+ if (scale == 4.0) return BY_4_0;\r
+ return new Scaler(scale);\r
+ }\r
+\r
+ static final Scaler BY_0_25 = new Scaler(0.25) {\r
+ @Override public int scaleUpper(int n) { check(n); return (n >> 2) + 1 ; }\r
+ @Override public int scaleLower(int n) { check(n); return n >> 2 ; }\r
+ };\r
+\r
+ static final Scaler BY_3_0_INVERSE = new Scaler(1.0 / 3.0);\r
+\r
+ static final Scaler BY_0_5 = new Scaler(0.5) {\r
+ @Override public int scaleUpper(int n) { check(n); return (n >> 1) + 1 ; }\r
+ @Override public int scaleLower(int n) { check(n); return n >> 1 ; }\r
+ };\r
+\r
+ static final Scaler BY_1_5_INVERSE = new Scaler(1.0 / 1.5);\r
+\r
+ static final Scaler BY_0_75 = new Scaler(0.75) {\r
+ @Override public int scaleUpper(int n) { check(n); int r = n - (n >> 2); return (n & 3 ) != 0 ? r : r + 1 ; }\r
+ @Override public int scaleLower(int n) { check(n); int r = n - (n >> 2); return (n & 3 ) != 0 ? r - 1 : r ; }\r
+ };\r
+\r
+ static final Scaler BY_1_0 = new Scaler(1.0) {\r
+ @Override public int scaleUpper(int n) { check(n); return n < Integer.MAX_VALUE ? n + 1 : Integer.MAX_VALUE; }\r
+ @Override public int scaleLower(int n) { check(n); return n ; }\r
+ };\r
+\r
+ static final Scaler BY_0_75_INVERSE = new Scaler(1.0 / 0.75);\r
+\r
+ static final Scaler BY_1_5 = new Scaler(1.5) {\r
+ @Override public int scaleUpper(int n) { check(n); return n <= 1431655764 ? n + (n >> 1) + 1 : Integer.MAX_VALUE; }\r
+ @Override public int scaleLower(int n) { check(n); return n <= 1431655764 ? n + (n >> 1) : Integer.MAX_VALUE; }\r
+ };\r
+\r
+ static final Scaler BY_2_0 = new Scaler(2.0) {\r
+ @Override public int scaleUpper(int n) { check(n); return n < (1 << 30) ? (n << 1) + 1 : Integer.MAX_VALUE; }\r
+ @Override public int scaleLower(int n) { check(n); return n < (1 << 30) ? (n << 1) : Integer.MAX_VALUE; }\r
+ };\r
+\r
+ static final Scaler BY_3_0 = new Scaler(3.0) {\r
+ @Override public int scaleUpper(int n) { check(n); return n <= 715827882 ? n + (n << 1) + 1 : Integer.MAX_VALUE; }\r
+ @Override public int scaleLower(int n) { check(n); return n <= 715827882 ? n + (n << 1) : Integer.MAX_VALUE; }\r
+ };\r
+\r
+ static final Scaler BY_4_0 = new Scaler(4.0) {\r
+ @Override public int scaleUpper(int n) { check(n); return n < (1 << 29) ? (n << 2) + 1 : Integer.MAX_VALUE; }\r
+ @Override public int scaleLower(int n) { check(n); return n < (1 << 29) ? (n << 2) : Integer.MAX_VALUE; }\r
+ };\r
+\r
+ private static void check(int n) {\r
+ assert n >= 0 : "n should be non-negative, otherwise result is undefined";\r
+ }\r
+\r
+ final double scale;\r
+\r
+ private Scaler(double scale) {\r
+ this.scale = scale;\r
+ }\r
+\r
+ public int scaleUpper(int n) {\r
+ check(n);\r
+ int lower = (int) ((double) n * scale);\r
+ return lower < Integer.MAX_VALUE ? lower + 1 : Integer.MAX_VALUE;\r
+ }\r
+\r
+ public int scaleLower(int n) {\r
+ check(n);\r
+ return (int) ((double) n * scale);\r
+ }\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright 2014 the original author or authors.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+\r
+package org.simantics.scl.runtime.chr;\r
+\r
+/**\r
+ * An exception thrown when element or entry couldn't be inserted into the hash container\r
+ * due to implementation limitations.\r
+ */\r
+public class CHRHashOverflowException extends IllegalStateException {\r
+ private static final long serialVersionUID = 0L;\r
+ public CHRHashOverflowException() {\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+package org.simantics.scl.runtime.chr;\r
+\r
+public interface Fact {\r
+ /**\r
+ * Activates the fact with the given priority. The method returns\r
+ * the new priority of the fact or a negative number if the fact\r
+ * is deactivated.\r
+ */\r
+ int activate(Object context, int priority);\r
+ boolean isAlive();\r
+}\r
--- /dev/null
+package org.simantics.scl.runtime.chr;\r
+\r
+import java.util.Arrays;\r
+\r
+public class FactActivationQueue {\r
+ public static final boolean TRACE = false;\r
+ \r
+ private final PriorityContainer[] containers;\r
+ private PriorityContainer[] activeContainers = new PriorityContainer[8];\r
+ private int activeContainerCount; \r
+\r
+ public FactActivationQueue(int priorityCount) {\r
+ if(TRACE)\r
+ System.out.println("priorityCount = " + priorityCount);\r
+ containers = new PriorityContainer[priorityCount];\r
+ for(int i=0;i<priorityCount;++i)\r
+ containers[i] = new PriorityContainer(i); \r
+ }\r
+ \r
+ /**\r
+ * Adds a new fact with a given priority\r
+ */\r
+ public void add(int priority, Fact item) {\r
+ if(TRACE)\r
+ System.out.println("FactActivationQueue.add " + priority + "@" + item);\r
+ PriorityContainer container = containers[priority];\r
+ if(container.size == 0)\r
+ activateContainer(container);\r
+ container.push(item);\r
+ }\r
+ \r
+ private void activateContainer(PriorityContainer container) {\r
+ if(TRACE)\r
+ System.out.println("FactActivationQueue.activate priority " + container.priority);\r
+ if(activeContainers.length == activeContainerCount)\r
+ activeContainers = Arrays.copyOf(activeContainers, activeContainerCount*2);\r
+ adjustUpwards(activeContainerCount, container);\r
+ ++activeContainerCount;\r
+ }\r
+\r
+ private void deactivateContainer() {\r
+ --activeContainerCount;\r
+ adjustDownwards(0, activeContainers[activeContainerCount]);\r
+ activeContainers[activeContainerCount] = null;\r
+ }\r
+\r
+ private void adjustDownwards(int pos, PriorityContainer item) {\r
+ int priority = item.priority;\r
+ while(true) {\r
+ int npos = 2*pos+1;\r
+ if(npos+1 >= activeContainerCount) {\r
+ if(npos >= activeContainerCount)\r
+ break;\r
+ PriorityContainer item1 = activeContainers[npos];\r
+ if(priority > item1.priority) {\r
+ activeContainers[pos] = item1;\r
+ activeContainers[npos] = item;\r
+ return;\r
+ }\r
+ else\r
+ break;\r
+ }\r
+ PriorityContainer item1 = activeContainers[npos];\r
+ PriorityContainer item2 = activeContainers[npos+1];\r
+ if(priority < item1.priority) {\r
+ if(priority < item2.priority)\r
+ break;\r
+ }\r
+ else {\r
+ if(item1.priority < item2.priority) {\r
+ activeContainers[pos] = item1;\r
+ pos = npos;\r
+ continue;\r
+ }\r
+ }\r
+ activeContainers[pos] = item2;\r
+ pos = npos+1;\r
+ }\r
+ activeContainers[pos] = item;\r
+ }\r
+\r
+ private void adjustUpwards(int pos, PriorityContainer item) {\r
+ int priority = item.priority;\r
+ while(pos > 0) {\r
+ int npos = (pos-1)/2;\r
+ PriorityContainer item1 = activeContainers[npos];\r
+ if(item1.priority > priority) {\r
+ activeContainers[pos] = item1;\r
+ pos = npos;\r
+ }\r
+ else\r
+ break;\r
+ }\r
+ activeContainers[pos] = item;\r
+ }\r
+ \r
+ /**\r
+ * Activates all facts with priority less than the current priority\r
+ */\r
+ public void activate(Object context, int currentPriority) {\r
+ if(TRACE)\r
+ System.out.println("FactActivationQueue.activate " + currentPriority);\r
+ while(activeContainerCount > 0) {\r
+ PriorityContainer topContainer = activeContainers[0];\r
+ int priority = topContainer.priority;\r
+ if(priority >= currentPriority)\r
+ return;\r
+ \r
+ Fact fact = topContainer.pop();\r
+ if(topContainer.size == 0)\r
+ deactivateContainer();\r
+ \r
+ int newPriority = fact.activate(context, priority);\r
+ if(TRACE)\r
+ System.out.println(" [" + currentPriority + "] " + fact + " oldPriority=" + priority + ", newPriority=" + newPriority);\r
+ if(newPriority >= 0)\r
+ add(newPriority, fact);\r
+ }\r
+ }\r
+}\r
--- /dev/null
+package org.simantics.scl.runtime.chr;\r
+\r
+import java.util.Arrays;\r
+\r
+class PriorityContainer {\r
+ private static final boolean CLEANUP_ENABLED = true;\r
+ \r
+ final int priority;\r
+ Fact[] facts = new Fact[4];\r
+ int size;\r
+\r
+ public PriorityContainer(int priority) {\r
+ this.priority = priority;\r
+ }\r
+ \r
+ public void push(Fact item) {\r
+ if(size == facts.length)\r
+ increaseCapacity();\r
+ facts[size++] = item;\r
+ }\r
+\r
+ private void increaseCapacity() {\r
+ if(CLEANUP_ENABLED) {\r
+ // Cleanup dead facts\r
+ int j=0;\r
+ for(int i=0;i<size;++i) {\r
+ Fact fact = facts[i];\r
+ if(fact.isAlive())\r
+ facts[j++] = fact;\r
+ }\r
+ size = j;\r
+ }\r
+ \r
+ // Resize if necessary\r
+ if(size >= facts.length*3/4)\r
+ facts = Arrays.copyOf(facts, size*2);\r
+ }\r
+\r
+ public Fact pop() {\r
+ return facts[--size];\r
+ }\r
+}\r
--- /dev/null
+package org.simantics.scl.runtime.tests;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collections;\r
+import java.util.LinkedHashSet;\r
+import java.util.List;\r
+import java.util.Random;\r
+\r
+import org.junit.Assert;\r
+import org.junit.Before;\r
+import org.junit.Test;\r
+import org.simantics.scl.runtime.chr.CHRHashIndex;\r
+\r
+import gnu.trove.map.hash.TIntObjectHashMap;\r
+import gnu.trove.set.hash.THashSet;\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
+public class TestCHRHashIndex {\r
+ \r
+ Random random;\r
+ Store store;\r
+ Store2 store2;\r
+ THashSet<Fact> aliveFacts = new THashSet<Fact>(); \r
+ \r
+ public static class Store {\r
+ CHRHashIndex bfIndex = new CHRHashIndex() {\r
+ @Override\r
+ protected boolean keyEquals(Object a, Object b) {\r
+ return ((Fact)a).a == ((Fact)b).a;\r
+ }\r
+ @Override\r
+ protected int keyHashCode(Object key) {\r
+ return ((Fact)key).a;\r
+ }\r
+ };\r
+ }\r
+ \r
+ public static class Store2 {\r
+ TIntObjectHashMap<LinkedHashSet<Fact>> bfIndex = new TIntObjectHashMap<LinkedHashSet<Fact>>(); \r
+ }\r
+ \r
+ public static class Fact {\r
+ public int a; // key\r
+ public int b;\r
+ public Fact bfPrev;\r
+ public Fact bfNext;\r
+ \r
+ public Fact(int a, int b) {\r
+ this.a = a;\r
+ this.b = b;\r
+ }\r
+ \r
+ public void add(Store store) {\r
+ bfNext = (Fact)store.bfIndex.addFreshAndReturnOld(this);\r
+ if(bfNext != null)\r
+ bfNext.bfPrev = this;\r
+ }\r
+ \r
+ public void remove(Store store) {\r
+ if(bfPrev == null) {\r
+ if(bfNext == null)\r
+ store.bfIndex.removeKnownToExistKey(this);\r
+ else {\r
+ bfNext.bfPrev = null;\r
+ store.bfIndex.replaceKnownToExistKey(this, bfNext);\r
+ }\r
+ }\r
+ else {\r
+ bfPrev.bfNext = bfNext;\r
+ if(bfNext != null)\r
+ bfNext.bfPrev = bfPrev;\r
+ }\r
+ }\r
+ \r
+ public List<Fact> get(Store store) {\r
+ Object r = store.bfIndex.getEqual(this);\r
+ if(r == null)\r
+ return Collections.emptyList();\r
+ else {\r
+ ArrayList<Fact> result = new ArrayList<Fact>(); \r
+ for(Fact cur=(Fact)r;cur!=null;cur=cur.bfNext)\r
+ result.add(cur);\r
+ Collections.reverse(result);\r
+ return result;\r
+ }\r
+ }\r
+ \r
+ public void add(Store2 store) {\r
+ LinkedHashSet<Fact> set = store.bfIndex.get(a);\r
+ if(set == null) {\r
+ set = new LinkedHashSet<>();\r
+ store.bfIndex.put(a, set);\r
+ }\r
+ set.add(this);\r
+ }\r
+ \r
+ public void remove(Store2 store) {\r
+ store.bfIndex.get(a).remove(this);\r
+ }\r
+ \r
+ public List<Fact> get(Store2 store) {\r
+ LinkedHashSet<Fact> set = store.bfIndex.get(a);\r
+ if(set == null)\r
+ return Collections.emptyList();\r
+ else\r
+ return new ArrayList<Fact>(set);\r
+ }\r
+ }\r
+ \r
+ @Before\r
+ public void init() {\r
+ random = new Random(123L);\r
+ store = new Store();\r
+ store2 = new Store2();\r
+ }\r
+ \r
+ public Fact createFact(int maxA, int maxB) {\r
+ return new Fact(random.nextInt(maxA), random.nextInt(maxB));\r
+ }\r
+ \r
+ public void add(Fact fact) {\r
+ fact.add(store);\r
+ fact.add(store2);\r
+ aliveFacts.add(fact);\r
+ }\r
+ \r
+ public void remove(Fact fact) {\r
+ fact.remove(store);\r
+ fact.remove(store2);\r
+ aliveFacts.remove(fact);\r
+ }\r
+ \r
+ public void checkConsistency() {\r
+ TIntHashSet keys = new TIntHashSet();\r
+ for(Fact fact : aliveFacts)\r
+ keys.add(fact.a);\r
+ Fact temp = new Fact(0, 0);\r
+ for(int a : keys.toArray()) {\r
+ temp.a = a;\r
+ Assert.assertEquals(temp.get(store2), temp.get(store));\r
+ }\r
+ TIntHashSet keys2 = new TIntHashSet();\r
+ for(Fact fact : store.bfIndex.toArray(new Fact[keys.size()]))\r
+ keys2.add(fact.a);\r
+ Assert.assertEquals(keys, keys2);\r
+ }\r
+ \r
+ @Test\r
+ public void testStore() {\r
+ for(int i=0;;++i) {\r
+ System.out.println("Run " + i);\r
+ for(int j=0;j<1000000;++j)\r
+ add(createFact(10000, 1000000));\r
+ checkConsistency();\r
+ ArrayList<Fact> factArray = new ArrayList<Fact>(aliveFacts);\r
+ Collections.shuffle(factArray, random);\r
+ for(Fact fact : factArray.subList(100000, factArray.size()))\r
+ remove(fact);\r
+ checkConsistency();\r
+ }\r
+ }\r
+ \r
+}\r
--- /dev/null
+package org.simantics.scl.runtime.tests;\r
+\r
+import java.util.Random;\r
+\r
+import org.junit.Assert;\r
+import org.junit.Test;\r
+import org.simantics.scl.runtime.chr.Fact;\r
+import org.simantics.scl.runtime.chr.FactActivationQueue;\r
+\r
+import gnu.trove.list.array.TIntArrayList;\r
+\r
+public class TestFactActivationQueue {\r
+ public static Random RANDOM = new Random();\r
+ \r
+ private static class MyFact implements Fact {\r
+ TIntArrayList list;\r
+ int priority;\r
+\r
+ public MyFact(TIntArrayList list, int priority) {\r
+ this.list = list;\r
+ this.priority = priority;\r
+ }\r
+\r
+ @Override\r
+ public int activate(Object context, int priority) {\r
+ Assert.assertEquals(this.priority, priority);\r
+ list.add(priority);\r
+ return -1;\r
+ }\r
+\r
+ @Override\r
+ public boolean isAlive() {\r
+ return true;\r
+ }\r
+ }\r
+ \r
+ private void testRandomly(int priorities, int size) {\r
+ FactActivationQueue queue = new FactActivationQueue(priorities);\r
+ TIntArrayList list = new TIntArrayList(size); \r
+ for(int i=0;i<size;++i) {\r
+ int val = RANDOM.nextInt(priorities);\r
+ queue.add(val, new MyFact(list, val));\r
+ }\r
+ queue.activate(null, priorities);\r
+ Assert.assertEquals(size, list.size());\r
+ for(int i=1;i<list.size();++i) {\r
+ int a = list.get(i-1);\r
+ int b = list.get(i);\r
+ Assert.assertTrue(a <= b);\r
+ }\r
+ }\r
+ \r
+ @Test\r
+ public void testRandomly() {\r
+ for(int i=0;i<10000;++i)\r
+ testRandomly(10, 10000);\r
+ }\r
+}\r
org.simantics.scl.runtime;bundle-version="0.2.0",
gnu.trove3;bundle-version="3.0.0",
org.simantics.scl.osgi;bundle-version="1.0.0",
- org.simantics.scl.compiler,
+ org.simantics.scl.compiler;bundle-version="0.6.0",
org.junit;bundle-version="4.12.0";resolution:=optional
Export-Package: org.simantics.scl.ui.console,
org.simantics.scl.ui.editor,
package org.simantics.scl.ui.editor;\r
\r
import org.eclipse.jface.preference.IPreferenceStore;\r
-import org.eclipse.jface.resource.FontDescriptor;\r
import org.eclipse.jface.resource.ResourceManager;\r
import org.eclipse.jface.text.DefaultInformationControl;\r
+import org.eclipse.jface.text.DefaultTextHover;\r
import org.eclipse.jface.text.IDocument;\r
import org.eclipse.jface.text.IInformationControl;\r
import org.eclipse.jface.text.IInformationControlCreator;\r
import org.eclipse.jface.text.ITextHover;\r
-import org.eclipse.jface.text.TextAttribute;\r
import org.eclipse.jface.text.contentassist.ContentAssistant;\r
import org.eclipse.jface.text.contentassist.IContentAssistant;\r
import org.eclipse.jface.text.presentation.IPresentationReconciler;\r
-import org.eclipse.jface.text.presentation.PresentationReconciler;\r
-import org.eclipse.jface.text.rules.DefaultDamagerRepairer;\r
-import org.eclipse.jface.text.rules.EndOfLineRule;\r
-import org.eclipse.jface.text.rules.IRule;\r
-import org.eclipse.jface.text.rules.ITokenScanner;\r
-import org.eclipse.jface.text.rules.IWordDetector;\r
-import org.eclipse.jface.text.rules.MultiLineRule;\r
-import org.eclipse.jface.text.rules.PatternRule;\r
-import org.eclipse.jface.text.rules.RuleBasedScanner;\r
-import org.eclipse.jface.text.rules.Token;\r
-import org.eclipse.jface.text.rules.WordRule;\r
import org.eclipse.jface.text.source.DefaultAnnotationHover;\r
import org.eclipse.jface.text.source.IAnnotationHover;\r
import org.eclipse.jface.text.source.ISourceViewer;\r
import org.eclipse.jface.text.source.SourceViewerConfiguration;\r
-import org.eclipse.swt.SWT;\r
-import org.eclipse.swt.graphics.Font;\r
-import org.eclipse.swt.graphics.RGB;\r
import org.eclipse.swt.widgets.Shell;\r
import org.eclipse.ui.editors.text.EditorsUI;\r
import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants;\r
import org.simantics.scl.ui.Activator;\r
import org.simantics.scl.ui.editor.completion.SCLCompletionAssistProcessor;\r
-import org.simantics.scl.ui.editor.completion.SCLEditorTextHover;\r
import org.simantics.scl.ui.editor.completion.SCLTextEditorEnvironment;\r
-import org.simantics.scl.ui.info.SCLInfo;\r
+import org.simantics.scl.ui.editor2.SCLPresentationReconciler;\r
\r
public class SCLSourceViewerConfigurationNew extends SourceViewerConfiguration {\r
\r
}\r
\r
public IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer) {\r
- PresentationReconciler reconciler = new PresentationReconciler();\r
- \r
- DefaultDamagerRepairer dr = new DefaultDamagerRepairer(getSclTokenScanner());\r
- \r
- reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE);\r
- reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE);\r
- \r
- return reconciler;\r
- }\r
- \r
- private static final FontDescriptor FONT_NORMAL = FontDescriptor.createFrom("Consolas", 10, SWT.NORMAL);\r
- private static final FontDescriptor FONT_BOLD = FontDescriptor.createFrom("Consolas", 10, SWT.BOLD);\r
- \r
- ITokenScanner getSclTokenScanner() {\r
- RuleBasedScanner scanner = new RuleBasedScanner();\r
- \r
- Font font = resourceManager.createFont(FONT_NORMAL);\r
- Font boldFont = resourceManager.createFont(FONT_BOLD);\r
- \r
- Token defaultToken = new Token(\r
- new TextAttribute(\r
- resourceManager.createColor(new RGB(0, 0, 0)),\r
- null,\r
- 0,\r
- font\r
- ));\r
- Token string = new Token(new TextAttribute(\r
- resourceManager.createColor(new RGB(42, 0, 255)),\r
- null,\r
- 0,\r
- font\r
- ));\r
- Token reserved = new Token(\r
- new TextAttribute(\r
- resourceManager.createColor(new RGB(127, 0, 85)),\r
- null,\r
- SWT.BOLD,\r
- boldFont\r
- ));\r
- Token comment = new Token(new TextAttribute(\r
- resourceManager.createColor(new RGB(63, 127, 95)),\r
- null,\r
- 0,\r
- font\r
- ));\r
-\r
- WordRule reservedWord = new WordRule(new IWordDetector() { \r
- @Override\r
- public boolean isWordStart(char c) {\r
- return Character.isJavaIdentifierStart(c);\r
- }\r
- \r
- @Override\r
- public boolean isWordPart(char c) {\r
- return Character.isJavaIdentifierPart(c) || c=='.';\r
- }\r
- });\r
-\r
- for(String word : SCLInfo.RESERVED_WORDS)\r
- reservedWord.addWord(word, reserved);\r
- \r
- IRule[] rules = new IRule[] {\r
- //new MultiLineRule("\"\"\"", "\"\"\"", string),\r
- new PatternRule("\"", "\"", string, '\\', true),\r
- new MultiLineRule("/*", "*/", comment),\r
- new EndOfLineRule("//", comment),\r
- reservedWord\r
- };\r
- scanner.setRules(rules);\r
- scanner.setDefaultReturnToken(defaultToken);\r
- \r
- return scanner;\r
+ return new SCLPresentationReconciler(resourceManager);\r
}\r
\r
@Override\r
public ITextHover getTextHover(ISourceViewer sourceViewer, String contentType) {\r
- return new SCLEditorTextHover(sourceViewer, sclTextEditorEnvironment);\r
+ //return new SCLEditorTextHover(sourceViewer, sclTextEditorEnvironment);\r
+ return new DefaultTextHover(sourceViewer);\r
}\r
\r
@Override\r
\r
import java.io.StringReader;\r
import java.util.ArrayList;\r
-import java.util.Arrays;\r
import java.util.Collections;\r
import java.util.Comparator;\r
import java.util.List;\r
import org.simantics.scl.compiler.module.ImportDeclaration;\r
import org.simantics.scl.compiler.module.Module;\r
import org.simantics.scl.compiler.module.repository.ImportFailureException;\r
-import org.simantics.scl.compiler.source.TextualModuleSource;\r
import org.simantics.scl.compiler.types.TCon;\r
import org.simantics.scl.osgi.SCLOsgi;\r
\r
String contents = document.get();\r
String[] lines = contents.split("\\R+");\r
List<ImportDeclaration> imports = new ArrayList<>();\r
- imports.addAll(Arrays.asList(TextualModuleSource.DEFAULT_IMPORTS));\r
+ imports.add(new ImportDeclaration("StandardLibrary", ""));\r
for (String line : lines) {\r
line = line.trim();\r
if (line.startsWith("import") || line.startsWith("include")) {\r
--- /dev/null
+package org.simantics.scl.ui.editor2;\r
+\r
+import org.eclipse.jface.text.IDocument;\r
+import org.eclipse.jface.text.rules.IPartitionTokenScanner;\r
+import org.eclipse.jface.text.rules.IToken;\r
+\r
+public class DebugPartionTokenScanner implements IPartitionTokenScanner {\r
+ IPartitionTokenScanner base;\r
+\r
+ public DebugPartionTokenScanner(IPartitionTokenScanner base) {\r
+ this.base = base;\r
+ }\r
+\r
+ @Override\r
+ public void setRange(IDocument document, int offset, int length) {\r
+ System.out.println(">>> setRange(" + offset + ", " + length + ")");\r
+ base.setRange(document, offset, length);\r
+ }\r
+\r
+ @Override\r
+ public IToken nextToken() {\r
+ IToken result = base.nextToken();\r
+ System.out.println(">>> nextToken -> " + result + " " + result.getData());\r
+ return result;\r
+ }\r
+\r
+ @Override\r
+ public int getTokenOffset() {\r
+ int result = base.getTokenOffset();\r
+ System.out.println(">>> getTokenOffset -> " + result);\r
+ return result;\r
+ }\r
+\r
+ @Override\r
+ public int getTokenLength() {\r
+ int result = base.getTokenLength();\r
+ System.out.println(">>> getTokenLength -> " + result);\r
+ return result;\r
+ }\r
+\r
+ @Override\r
+ public void setPartialRange(IDocument document, int offset, int length, String contentType, int partitionOffset) {\r
+ System.out.println(">>> setPartialRange(" + offset + ", " + length + ", " + contentType + ", " + partitionOffset + ")");\r
+ base.setPartialRange(document, offset, length, contentType, partitionOffset);\r
+ }\r
+ \r
+ \r
+}\r
import org.eclipse.jface.operation.IRunnableContext;\r
import org.eclipse.jface.text.Document;\r
import org.eclipse.jface.text.IDocument;\r
+import org.eclipse.jface.text.IDocumentPartitioner;\r
+import org.eclipse.jface.text.rules.FastPartitioner;\r
import org.eclipse.jface.text.source.AnnotationModel;\r
import org.eclipse.jface.text.source.IAnnotationModel;\r
import org.eclipse.ui.texteditor.AbstractDocumentProvider;\r
new Status(Status.ERROR, "org.simantics.scl.ui", "Reading SCL module failed.", e)\r
);\r
}\r
+ IDocumentPartitioner partitioner = new FastPartitioner(new SCLPartitionScanner(), SCLPartitionScanner.PARTITION_TYPES);\r
+ partitioner.connect(document);\r
+ document.setDocumentPartitioner(partitioner);\r
sourceViewer.updateCompletionAssistModuleName(source.getModuleName());\r
return document;\r
}\r
--- /dev/null
+package org.simantics.scl.ui.editor2;\r
+\r
+import org.eclipse.jface.text.rules.EndOfLineRule;\r
+import org.eclipse.jface.text.rules.IPredicateRule;\r
+import org.eclipse.jface.text.rules.IToken;\r
+import org.eclipse.jface.text.rules.MultiLineRule;\r
+import org.eclipse.jface.text.rules.RuleBasedPartitionScanner;\r
+import org.eclipse.jface.text.rules.SingleLineRule;\r
+import org.eclipse.jface.text.rules.Token;\r
+\r
+public class SCLPartitionScanner extends RuleBasedPartitionScanner {\r
+ public static final String SCL_COMMENT = "COMMENT";\r
+ public static final String SCL_STRING = "STRING";\r
+ \r
+ public static final IToken COMMENT_TOKEN = new Token(SCL_COMMENT);\r
+ public static final IToken STRING_TOKEN = new Token(SCL_STRING);\r
+ \r
+ public static final String[] PARTITION_TYPES = new String[] {\r
+ SCL_COMMENT,\r
+ SCL_STRING\r
+ };\r
+ \r
+ public SCLPartitionScanner() {\r
+ super();\r
+\r
+ setPredicateRules(new IPredicateRule[] {\r
+ new EndOfLineRule("//", COMMENT_TOKEN),\r
+ new MultiLineRule("\"\"\"", "\"\"\"", STRING_TOKEN, (char) 0, true),\r
+ new SingleLineRule("\"", "\"", STRING_TOKEN, '\\'),\r
+ new MultiLineRule("/*", "*/", COMMENT_TOKEN, (char) 0, true),\r
+ });\r
+ }\r
+}\r
--- /dev/null
+package org.simantics.scl.ui.editor2;\r
+\r
+import org.eclipse.jface.resource.FontDescriptor;\r
+import org.eclipse.jface.resource.ResourceManager;\r
+import org.eclipse.jface.text.IDocument;\r
+import org.eclipse.jface.text.TextAttribute;\r
+import org.eclipse.jface.text.presentation.PresentationReconciler;\r
+import org.eclipse.jface.text.rules.DefaultDamagerRepairer;\r
+import org.eclipse.jface.text.rules.IRule;\r
+import org.eclipse.jface.text.rules.ITokenScanner;\r
+import org.eclipse.jface.text.rules.IWhitespaceDetector;\r
+import org.eclipse.jface.text.rules.IWordDetector;\r
+import org.eclipse.jface.text.rules.RuleBasedScanner;\r
+import org.eclipse.jface.text.rules.Token;\r
+import org.eclipse.jface.text.rules.WhitespaceRule;\r
+import org.eclipse.jface.text.rules.WordRule;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.graphics.Font;\r
+import org.eclipse.swt.graphics.RGB;\r
+import org.simantics.scl.ui.info.SCLInfo;\r
+\r
+public class SCLPresentationReconciler extends PresentationReconciler {\r
+ private static final FontDescriptor FONT_NORMAL = FontDescriptor.createFrom("Consolas", 10, SWT.NORMAL);\r
+ private static final FontDescriptor FONT_BOLD = FontDescriptor.createFrom("Consolas", 10, SWT.BOLD);\r
+ \r
+ public SCLPresentationReconciler(ResourceManager resourceManager) {\r
+ Font font = resourceManager.createFont(FONT_NORMAL);\r
+ {\r
+ DefaultDamagerRepairer dr = new DefaultDamagerRepairer(new SingleTokenScanner(new TextAttribute(\r
+ resourceManager.createColor(new RGB(63, 127, 95)),\r
+ null,\r
+ 0,\r
+ font\r
+ )));\r
+ setDamager(dr, SCLPartitionScanner.SCL_COMMENT);\r
+ setRepairer(dr, SCLPartitionScanner.SCL_COMMENT);\r
+ }\r
+ {\r
+ DefaultDamagerRepairer dr = new DefaultDamagerRepairer(new StringTokenScanner(new TextAttribute(\r
+ resourceManager.createColor(new RGB(42, 0, 255)),\r
+ null,\r
+ 0,\r
+ font\r
+ )));\r
+ setDamager(dr, SCLPartitionScanner.SCL_STRING);\r
+ setRepairer(dr, SCLPartitionScanner.SCL_STRING);\r
+ }\r
+ {\r
+ DefaultDamagerRepairer dr = new DefaultDamagerRepairer(getSclTokenScanner(resourceManager));\r
+\r
+ setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE);\r
+ setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE);\r
+ }\r
+ }\r
+ \r
+ private static ITokenScanner getSclTokenScanner(ResourceManager resourceManager) {\r
+ RuleBasedScanner scanner = new RuleBasedScanner();\r
+ \r
+ Token defaultToken = new Token(\r
+ new TextAttribute(\r
+ resourceManager.createColor(new RGB(0, 0, 0)),\r
+ null,\r
+ 0,\r
+ resourceManager.createFont(FONT_NORMAL)\r
+ ));\r
+ Token reserved = new Token(\r
+ new TextAttribute(\r
+ resourceManager.createColor(new RGB(127, 0, 85)),\r
+ null,\r
+ SWT.BOLD,\r
+ resourceManager.createFont(FONT_BOLD)\r
+ ));\r
+\r
+ WordRule reservedWord = new WordRule(new IWordDetector() {\r
+ @Override\r
+ public boolean isWordStart(char c) {\r
+ return ('a' <= c && c <= 'z')\r
+ || ('A' <= c && c <= 'Z')\r
+ || c == '_' || c == '?';\r
+ }\r
+ @Override\r
+ public boolean isWordPart(char c) {\r
+ return ('a' <= c && c <= 'z')\r
+ || ('A' <= c && c <= 'Z')\r
+ || ('0' <= c && c <= '9')\r
+ || c == '_' || c == '.' || c == '\'';\r
+ }\r
+ }, defaultToken);\r
+\r
+ for(String word : SCLInfo.RESERVED_WORDS)\r
+ reservedWord.addWord(word, reserved);\r
+ \r
+ scanner.setRules(new IRule[] {\r
+ new WhitespaceRule(new IWhitespaceDetector() {\r
+ @Override\r
+ public boolean isWhitespace(char c) {\r
+ return c==' ' || c=='\t' || c=='\n' || c=='\r';\r
+ }\r
+ }, defaultToken),\r
+ reservedWord\r
+ });\r
+ scanner.setDefaultReturnToken(defaultToken);\r
+ \r
+ return scanner;\r
+ }\r
+}\r
--- /dev/null
+package org.simantics.scl.ui.editor2;\r
+\r
+import org.eclipse.jface.text.IDocument;\r
+import org.eclipse.jface.text.rules.IToken;\r
+import org.eclipse.jface.text.rules.RuleBasedScanner;\r
+import org.eclipse.jface.text.rules.Token;\r
+\r
+public class SingleTokenScanner extends RuleBasedScanner {\r
+ public SingleTokenScanner(Object attribute) {\r
+ setDefaultReturnToken(new Token(attribute));\r
+ }\r
+ \r
+ @Override\r
+ public IToken nextToken() {\r
+ return super.nextToken();\r
+ }\r
+ \r
+ @Override\r
+ public void setRange(IDocument document, int offset, int length) {\r
+ super.setRange(document, offset, length);\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+package org.simantics.scl.ui.editor2;\r
+\r
+import org.eclipse.jface.text.IDocument;\r
+import org.eclipse.jface.text.rules.IToken;\r
+import org.eclipse.jface.text.rules.RuleBasedScanner;\r
+import org.eclipse.jface.text.rules.Token;\r
+\r
+public class StringTokenScanner extends RuleBasedScanner {\r
+ public StringTokenScanner(Object attribute) {\r
+ setDefaultReturnToken(new Token(attribute));\r
+ }\r
+ \r
+ @Override\r
+ public IToken nextToken() {\r
+ return super.nextToken();\r
+ }\r
+ \r
+ @Override\r
+ public void setRange(IDocument document, int offset, int length) {\r
+ super.setRange(document, offset, length);\r
+ }\r
+}
\ No newline at end of file
"select",\r
"enforce",\r
"transformation",\r
+ "when"\r
};\r
\r
}\r
@VP.namedRelationChildRule TestsUI.Contributions.STSTests L0.Entity L0.ConsistsOf TESTS.STSTest
@VP.namedConstantImageRule TestsUI.Contributions.TestImage TESTS.STSTest TestsUI.testImage
+MBC
+ VP.BrowseContext.HasVisualsContribution _ : VP.VisualsContribution
+ VP.VisualsContribution.HasNodeType TESTS.STSSuite
+ VP.VisualsContribution.HasRule MBC.STSSuiteSorterRule
+
+MBC.STSSuiteSorterRule : VP.SorterRule
+
MAC = TestsUI.ModelingActionContext : VP.BrowseContext
VP.BrowseContext.IsIncludedIn PROJECT.ProjectActionContext
public class TestsUIResource {\r
\r
public final Resource BrowseContext;\r
+ public final Resource BrowseContext_STSSuiteSorterRule;\r
public final Resource Contributions;\r
public final Resource Contributions_NewSTSSuite;\r
public final Resource Contributions_NewSTSTest;\r
\r
public static class URIs {\r
public static final String BrowseContext = "http://www.simantics.org/TestsUI-1.0/BrowseContext";\r
+ public static final String BrowseContext_STSSuiteSorterRule = "http://www.simantics.org/TestsUI-1.0/BrowseContext/STSSuiteSorterRule";\r
public static final String Contributions = "http://www.simantics.org/TestsUI-1.0/Contributions";\r
public static final String Contributions_NewSTSSuite = "http://www.simantics.org/TestsUI-1.0/Contributions/NewSTSSuite";\r
public static final String Contributions_NewSTSTest = "http://www.simantics.org/TestsUI-1.0/Contributions/NewSTSTest";\r
\r
public TestsUIResource(ReadGraph graph) {\r
BrowseContext = getResourceOrNull(graph, URIs.BrowseContext);\r
+ BrowseContext_STSSuiteSorterRule = getResourceOrNull(graph, URIs.BrowseContext_STSSuiteSorterRule);\r
Contributions = getResourceOrNull(graph, URIs.Contributions);\r
Contributions_NewSTSSuite = getResourceOrNull(graph, URIs.Contributions_NewSTSSuite);\r
Contributions_NewSTSTest = getResourceOrNull(graph, URIs.Contributions_NewSTSTest);\r
org.simantics.tests.modelled.ui.ontology;bundle-version="1.0.0",
org.simantics.tests.modelled;bundle-version="1.0.0",
org.eclipse.e4.ui.model.workbench,
- org.simantics.scl.osgi
+ org.simantics.scl.osgi,
+ org.simantics.browsing.ui.model
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-ActivationPolicy: lazy
Bundle-Vendor: Semantum Oy
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<adapters>\r
+ \r
+ <target interface="org.simantics.browsing.ui.model.visuals.VisualsRule">\r
+ <resource\r
+ uri="http://www.simantics.org/TestsUI-0.0/BrowseContext/STSSuiteSorterRule"\r
+ class="org.simantics.tests.modelled.ui.STSSuiteSorterRule" />\r
+ </target>\r
+\r
+</adapters>
\ No newline at end of file
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.tests.modelled.ui;\r
+\r
+import java.util.Collections;\r
+import java.util.Comparator;\r
+import java.util.List;\r
+\r
+import org.simantics.browsing.ui.BuiltinKeys;\r
+import org.simantics.browsing.ui.NodeContext;\r
+import org.simantics.browsing.ui.model.browsecontexts.BrowseContext;\r
+import org.simantics.browsing.ui.model.sorters.Sorter;\r
+import org.simantics.browsing.ui.model.sorters.SorterRule;\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.request.ResourceRead;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.exception.RuntimeDatabaseException;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.tests.modelled.ontology.TestsResource;\r
+import org.simantics.utils.datastructures.Pair;\r
+import org.simantics.utils.strings.AlphanumComparator;\r
+\r
+public class STSSuiteSorterRule implements SorterRule, Sorter {\r
+\r
+ @Override\r
+ public boolean isCompatible(Class<?> contentType) {\r
+ return contentType.equals(Resource.class);\r
+ }\r
+\r
+ @Override\r
+ public Sorter getSorter(ReadGraph graph, Object content) throws DatabaseException {\r
+ return this;\r
+ }\r
+ \r
+ @Override\r
+ public void sort(ReadGraph graph, BrowseContext context, List<NodeContext> nodes) throws DatabaseException \r
+ {\r
+ try {\r
+ STSTestComparator stc = new STSTestComparator();\r
+ stc.graph = graph;\r
+ Collections.sort(nodes, stc);\r
+ } catch (RuntimeDatabaseException e) {\r
+ if (e.getCause()!=null && e.getCause() instanceof DatabaseException) throw (DatabaseException) e.getCause();\r
+ throw e;\r
+ }\r
+ }\r
+ \r
+ static class STSTestQuery extends ResourceRead<Pair<Integer, String>> {\r
+\r
+ public STSTestQuery(Resource resource) {\r
+ super(resource);\r
+ }\r
+\r
+ @Override\r
+ public Pair<Integer, String> perform(ReadGraph graph) throws DatabaseException {\r
+ Layer0 L0 = Layer0.getInstance(graph);\r
+ TestsResource TESTS = TestsResource.getInstance(graph);\r
+ \r
+ String name = graph.getRelatedValue2(resource, L0.HasName, Bindings.STRING);\r
+ Integer priority = graph.getRelatedValue2(resource, TESTS.STSTest_executionPriority, Bindings.INTEGER);\r
+\r
+ return new Pair<Integer, String>(priority, name);\r
+ }\r
+\r
+ }\r
+ \r
+ static class STSTestComparator implements Comparator<NodeContext> {\r
+ ReadGraph graph;\r
+\r
+ @Override\r
+ public int compare(NodeContext nc1, NodeContext nc2) {\r
+ Resource r1 = (Resource) nc1.getConstant(BuiltinKeys.INPUT);\r
+ Resource r2 = (Resource) nc2.getConstant(BuiltinKeys.INPUT);\r
+ \r
+ try {\r
+ Pair<Integer, String> test1 = graph.sync(new STSTestQuery(r1));\r
+ Pair<Integer, String> test2 = graph.sync(new STSTestQuery(r2));\r
+\r
+ if (test1.first < test2.first)\r
+ return -1;\r
+ else if (test1.first > test2.first)\r
+ return 1;\r
+ else return AlphanumComparator.COMPARATOR.compare(test1.second, test2.second);\r
+ \r
+ } catch (DatabaseException e) {\r
+ throw new RuntimeDatabaseException(e);\r
+ }\r
+ }\r
+ }\r
+}\r
import org.simantics.scl.osgi.SCLOsgi;\r
import org.simantics.scl.runtime.reporting.AbstractSCLReportingHandler;\r
import org.simantics.tests.modelled.ontology.TestsResource;\r
+import org.simantics.utils.strings.AlphanumComparator;\r
\r
public class STSTestSuiteModel {\r
\r
Collections.sort(tests, (o1, o2) -> {\r
if (o1.priority < o2.priority)\r
return -1;\r
- if (o1.priority > o2.priority)\r
+ else if (o1.priority > o2.priority)\r
return 1;\r
- return 0;\r
+ else return AlphanumComparator.COMPARATOR.compare(o1.name, o2.name);\r
});\r
suite.children(tests.toArray(new STSTest[tests.size()]));\r
} else {\r
import org.junit.runner.notification.RunNotifier;\r
import org.junit.runners.ParentRunner;\r
\r
-public abstract class RuntimeSTSRunner extends ParentRunner<Runner> {\r
+public abstract class RuntimeSTSRunner<T extends Runner> extends ParentRunner<T> {\r
\r
public RuntimeSTSRunner(Class<?> testClass) throws Exception {\r
super(testClass);\r
\r
public abstract void deinitialize() throws Exception;\r
\r
- @Override\r
- protected List<Runner> getChildren() {\r
- System.out.println("getting children");\r
- return RuntimeTestCollector.collectTests();\r
- }\r
-\r
@Override\r
protected Description describeChild(Runner child) {\r
return child.getDescription();\r
import java.util.List;\r
\r
import org.junit.runner.Description;\r
-import org.junit.runner.Runner;\r
import org.simantics.scl.compiler.commands.CommandSession;\r
import org.simantics.scl.osgi.SCLOsgi;\r
\r
-public class RuntimeSTSSuiteRunner extends RuntimeSTSRunner {\r
+public class RuntimeSTSSuiteRunner extends RuntimeSTSRunner<RuntimeSTSTestRunner> {\r
\r
private final List<RuntimeSTSTestRunner> children = new ArrayList<>();\r
private final String suiteName;\r
\r
- RuntimeSTSSuiteRunner(String suiteName) throws Exception {\r
- super(RuntimeSTSSuiteRunner.class);\r
+ protected RuntimeSTSSuiteRunner(Class<?> clazz, String suiteName) throws Exception {\r
+ super(clazz);\r
this.suiteName = suiteName;\r
}\r
- \r
+\r
@Override\r
protected String getName() {\r
return suiteName;\r
testChildren.forEach(c -> c.setCommandSession(session));\r
children.addAll(testChildren);\r
}\r
- \r
- @SuppressWarnings({ "unchecked", "rawtypes" })\r
+\r
@Override\r
- protected List<Runner> getChildren() {\r
- return (List) children;\r
+ public List<RuntimeSTSTestRunner> getChildren() {\r
+ return children;\r
}\r
\r
@Override\r
- public void initialize() {\r
+ public void initialize() throws Exception {\r
}\r
\r
@Override\r
- public void deinitialize() {\r
+ public void deinitialize() throws Exception {\r
}\r
\r
}\r
}\r
}\r
\r
+ public String getName() {\r
+ return name;\r
+ }\r
+ \r
public Integer getPriority() {\r
return priority;\r
}\r
-}\r
+\r
+}
\ No newline at end of file
import java.util.List;\r
import java.util.Set;\r
\r
-import org.junit.runner.Runner;\r
import org.simantics.Simantics;\r
import org.simantics.databoard.Bindings;\r
import org.simantics.db.ReadGraph;\r
import org.simantics.modeling.ModelingUtils;\r
import org.simantics.scl.runtime.tuple.Tuple0;\r
import org.simantics.tests.modelled.ontology.TestsResource;\r
+import org.simantics.utils.strings.AlphanumComparator;\r
\r
public class RuntimeTestCollector {\r
\r
if (tests.isEmpty())\r
continue;\r
\r
- RuntimeSTSSuiteRunner suite = new RuntimeSTSSuiteRunner(suiteName);\r
+ RuntimeSTSSuiteRunner suite = new RuntimeSTSSuiteRunner(RuntimeSTSSuiteRunner.class, suiteName);\r
List<RuntimeSTSTestRunner> testRunners = new ArrayList<>();\r
for (Resource test : tests) {\r
String testName = graph.getRelatedValue(test, L0.HasName, Bindings.STRING);\r
}\r
\r
testRunners.sort((test1, test2) -> {\r
- if (test1.getPriority() <= test2.getPriority())\r
+ if (test1.getPriority() < test2.getPriority())\r
return -1;\r
- else\r
+ else if (test1.getPriority() > test2.getPriority())\r
return 1;\r
+ else return AlphanumComparator.COMPARATOR.compare(test1.getName(), test2.getName());\r
});\r
suite.addChildren(testRunners);\r
suites.add(suite);\r
}\r
}\r
\r
- public static List<Runner> collectTests() {\r
+ public static List<RuntimeSTSSuiteRunner> collectTests() {\r
return new ArrayList<>(collectTestsFromGraph());\r
}\r
}\r
/**\r
* Default database driver ID\r
*/\r
- private static final String DEFAULT_DATABASE_DRIVER_ID = "procore";\r
+ private static final String DEFAULT_DATABASE_DRIVER_ID = "acorn";\r
\r
private static String defaultDatabaseDriverId = DEFAULT_DATABASE_DRIVER_ID;\r
\r
id="org.simantics.desktop"\r
version="0.0.0"/>\r
\r
+ <includes\r
+ id="org.simantics.modeling.ui.workbench.feature"\r
+ version="0.0.0"/>\r
+\r
<plugin\r
id="org.simantics.desktop.product"\r
download-size="0"\r
<feature\r
id="org.simantics.help.addons"\r
label="Simantics Help Add-on Features"\r
- version="1.25.0.qualifier"\r
+ version="1.26.0.qualifier"\r
provider-name="Semantum Oy">\r
\r
<description url="http://www.example.com/description">\r
<feature\r
id="org.simantics.modeling.ui.workbench.feature"\r
label="Modeling Workbench Feature"\r
- version="1.25.0.qualifier"\r
+ version="1.26.0.qualifier"\r
provider-name="Semantum Oy">\r
\r
<description>\r
<feature\r
id="org.simantics.platform"\r
label="Simantics Platform Base"\r
- version="1.25.0.qualifier"\r
+ version="1.26.0.qualifier"\r
provider-name="VTT Technical Research Centre of Finland">\r
\r
<description url="http://www.example.com/description">\r
<feature\r
id="org.simantics.platform.ui"\r
label="Simantics Platform UI Base"\r
- version="1.25.0.qualifier"\r
+ version="1.26.0.qualifier"\r
provider-name="VTT Technical Research Centre of Finland">\r
\r
<description>\r
<feature\r
id="org.simantics.sdk"\r
label="Simantics SDK"\r
- version="1.25.0"\r
+ version="1.26.0"\r
provider-name="VTT Technical Research Centre of Finland">\r
\r
<description url="http://www.example.com/description">\r
<feature\r
id="org.simantics.ui.workbench"\r
label="Simantics Workbench Basic UI"\r
- version="1.25.0.qualifier"\r
+ version="1.26.0.qualifier"\r
provider-name="VTT Technical Research Centre of Finland">\r
\r
<description url="http://www.example.com/description">\r
<feature\r
id="org.simantics.utils"\r
label="Simantics Platform Utilities"\r
- version="1.25.0.qualifier"\r
+ version="1.26.0.qualifier"\r
provider-name="VTT Technical Research Centre of Finland">\r
\r
<description url="http://www.example.com/description">\r
<feature\r
id="org.simantics.utils.ui.feature"\r
label="UI Utils Feature"\r
- version="1.25.0.qualifier"\r
+ version="1.26.0.qualifier"\r
provider-name="VTT Technical Research Centre of Finland">\r
\r
<description url="http://www.example.com/description">\r
<feature\r
id="org.simantics.wiki.ui.feature"\r
label="Wiki Documentation Feature"\r
- version="1.25.0.qualifier"\r
+ version="1.26.0.qualifier"\r
provider-name="Semantum Oy">\r
\r
<description url="http://www.example.com/description">\r
<feature\r
id="org.simantics.workbench"\r
label="Simantics Workbench"\r
- version="1.25.0.qualifier"\r
+ version="1.26.0.qualifier"\r
provider-name="VTT Technical Research Centre of Finland"\r
plugin="org.simantics.workbench">\r
\r
--- /dev/null
+#!/bin/bash
+
+major=$1
+minor=$2
+service=$3
+wikidb=$4
+wikidbusr=$5
+
+srcdb=${wikidb}
+srcdbusr=${wikidbusr}
+tgtdb=${wikidb}_${major}_${minor}_${service}
+
+echo "Dumping database ${srcdb} to ${tgtdb} as user ${srcdbusr}"
+echo "Press enter to continue or C-c to cancel"
+read foo
+
+echo "Dumping $srcdb"
+mysqldump -u ${srcdbusr} -p ${srcdb} > ${tgtdb}.dump
--- /dev/null
+#!/bin/bash
+
+
+major=1
+minor=25
+service=0
+ver=${major}.${minor}.${service}
+
+mkdir ${ver}
+cd ${ver}
+OLDIFS=$IFS
+IFS=','
+for db in enduserwikidb,enduserwikiuser devwikidb,devwikiuser; do
+ set $db
+ sh ../dump-mysql-db.sh ${major} ${minor} ${service} ${1} ${2}
+done
+IFS=$OLDIFS
+
+cd ..
+tar zcvf ${ver}.tar.gz ${ver}
+rm -rf ${ver}
--- /dev/null
+<!DOCTYPE html>\r
+<html>\r
+<head>\r
+<title>release</title>\r
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />\r
+<style type="text/css">\r
+/* GitHub stylesheet for MarkdownPad (http://markdownpad.com) */\r
+/* Author: Nicolas Hery - http://nicolashery.com */\r
+/* Version: b13fe65ca28d2e568c6ed5d7f06581183df8f2ff */\r
+/* Source: https://github.com/nicolahery/markdownpad-github */\r
+\r
+/* RESET\r
+=============================================================================*/\r
+\r
+html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video {\r
+ margin: 0;\r
+ padding: 0;\r
+ border: 0;\r
+}\r
+\r
+/* BODY\r
+=============================================================================*/\r
+\r
+body {\r
+ font-family: Helvetica, arial, freesans, clean, sans-serif;\r
+ font-size: 14px;\r
+ line-height: 1.6;\r
+ color: #333;\r
+ background-color: #fff;\r
+ padding: 20px;\r
+ max-width: 960px;\r
+ margin: 0 auto;\r
+}\r
+\r
+body>*:first-child {\r
+ margin-top: 0 !important;\r
+}\r
+\r
+body>*:last-child {\r
+ margin-bottom: 0 !important;\r
+}\r
+\r
+/* BLOCKS\r
+=============================================================================*/\r
+\r
+p, blockquote, ul, ol, dl, table, pre {\r
+ margin: 15px 0;\r
+}\r
+\r
+/* HEADERS\r
+=============================================================================*/\r
+\r
+h1, h2, h3, h4, h5, h6 {\r
+ margin: 20px 0 10px;\r
+ padding: 0;\r
+ font-weight: bold;\r
+ -webkit-font-smoothing: antialiased;\r
+}\r
+\r
+h1 tt, h1 code, h2 tt, h2 code, h3 tt, h3 code, h4 tt, h4 code, h5 tt, h5 code, h6 tt, h6 code {\r
+ font-size: inherit;\r
+}\r
+\r
+h1 {\r
+ font-size: 28px;\r
+ color: #000;\r
+}\r
+\r
+h2 {\r
+ font-size: 24px;\r
+ border-bottom: 1px solid #ccc;\r
+ color: #000;\r
+}\r
+\r
+h3 {\r
+ font-size: 18px;\r
+}\r
+\r
+h4 {\r
+ font-size: 16px;\r
+}\r
+\r
+h5 {\r
+ font-size: 14px;\r
+}\r
+\r
+h6 {\r
+ color: #777;\r
+ font-size: 14px;\r
+}\r
+\r
+body>h2:first-child, body>h1:first-child, body>h1:first-child+h2, body>h3:first-child, body>h4:first-child, body>h5:first-child, body>h6:first-child {\r
+ margin-top: 0;\r
+ padding-top: 0;\r
+}\r
+\r
+a:first-child h1, a:first-child h2, a:first-child h3, a:first-child h4, a:first-child h5, a:first-child h6 {\r
+ margin-top: 0;\r
+ padding-top: 0;\r
+}\r
+\r
+h1+p, h2+p, h3+p, h4+p, h5+p, h6+p {\r
+ margin-top: 10px;\r
+}\r
+\r
+/* LINKS\r
+=============================================================================*/\r
+\r
+a {\r
+ color: #4183C4;\r
+ text-decoration: none;\r
+}\r
+\r
+a:hover {\r
+ text-decoration: underline;\r
+}\r
+\r
+/* LISTS\r
+=============================================================================*/\r
+\r
+ul, ol {\r
+ padding-left: 30px;\r
+}\r
+\r
+ul li > :first-child, \r
+ol li > :first-child, \r
+ul li ul:first-of-type, \r
+ol li ol:first-of-type, \r
+ul li ol:first-of-type, \r
+ol li ul:first-of-type {\r
+ margin-top: 0px;\r
+}\r
+\r
+ul ul, ul ol, ol ol, ol ul {\r
+ margin-bottom: 0;\r
+}\r
+\r
+dl {\r
+ padding: 0;\r
+}\r
+\r
+dl dt {\r
+ font-size: 14px;\r
+ font-weight: bold;\r
+ font-style: italic;\r
+ padding: 0;\r
+ margin: 15px 0 5px;\r
+}\r
+\r
+dl dt:first-child {\r
+ padding: 0;\r
+}\r
+\r
+dl dt>:first-child {\r
+ margin-top: 0px;\r
+}\r
+\r
+dl dt>:last-child {\r
+ margin-bottom: 0px;\r
+}\r
+\r
+dl dd {\r
+ margin: 0 0 15px;\r
+ padding: 0 15px;\r
+}\r
+\r
+dl dd>:first-child {\r
+ margin-top: 0px;\r
+}\r
+\r
+dl dd>:last-child {\r
+ margin-bottom: 0px;\r
+}\r
+\r
+/* CODE\r
+=============================================================================*/\r
+\r
+pre, code, tt {\r
+ font-size: 12px;\r
+ font-family: Consolas, "Liberation Mono", Courier, monospace;\r
+}\r
+\r
+code, tt {\r
+ margin: 0 0px;\r
+ padding: 0px 0px;\r
+ white-space: nowrap;\r
+ border: 1px solid #eaeaea;\r
+ background-color: #f8f8f8;\r
+ border-radius: 3px;\r
+}\r
+\r
+pre>code {\r
+ margin: 0;\r
+ padding: 0;\r
+ white-space: pre;\r
+ border: none;\r
+ background: transparent;\r
+}\r
+\r
+pre {\r
+ background-color: #f8f8f8;\r
+ border: 1px solid #ccc;\r
+ font-size: 13px;\r
+ line-height: 19px;\r
+ overflow: auto;\r
+ padding: 6px 10px;\r
+ border-radius: 3px;\r
+}\r
+\r
+pre code, pre tt {\r
+ background-color: transparent;\r
+ border: none;\r
+}\r
+\r
+kbd {\r
+ -moz-border-bottom-colors: none;\r
+ -moz-border-left-colors: none;\r
+ -moz-border-right-colors: none;\r
+ -moz-border-top-colors: none;\r
+ background-color: #DDDDDD;\r
+ background-image: linear-gradient(#F1F1F1, #DDDDDD);\r
+ background-repeat: repeat-x;\r
+ border-color: #DDDDDD #CCCCCC #CCCCCC #DDDDDD;\r
+ border-image: none;\r
+ border-radius: 2px 2px 2px 2px;\r
+ border-style: solid;\r
+ border-width: 1px;\r
+ font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;\r
+ line-height: 10px;\r
+ padding: 1px 4px;\r
+}\r
+\r
+/* QUOTES\r
+=============================================================================*/\r
+\r
+blockquote {\r
+ border-left: 4px solid #DDD;\r
+ padding: 0 15px;\r
+ color: #777;\r
+}\r
+\r
+blockquote>:first-child {\r
+ margin-top: 0px;\r
+}\r
+\r
+blockquote>:last-child {\r
+ margin-bottom: 0px;\r
+}\r
+\r
+/* HORIZONTAL RULES\r
+=============================================================================*/\r
+\r
+hr {\r
+ clear: both;\r
+ margin: 15px 0;\r
+ height: 0px;\r
+ overflow: hidden;\r
+ border: none;\r
+ background: transparent;\r
+ border-bottom: 4px solid #ddd;\r
+ padding: 0;\r
+}\r
+\r
+/* TABLES\r
+=============================================================================*/\r
+\r
+table th {\r
+ font-weight: bold;\r
+}\r
+\r
+table th, table td {\r
+ border: 1px solid #ccc;\r
+ padding: 6px 13px;\r
+}\r
+\r
+table tr {\r
+ border-top: 1px solid #ccc;\r
+ background-color: #fff;\r
+}\r
+\r
+table tr:nth-child(2n) {\r
+ background-color: #f8f8f8;\r
+}\r
+\r
+/* IMAGES\r
+=============================================================================*/\r
+\r
+img {\r
+ max-width: 100%\r
+}\r
+</style>\r
+</head>\r
+<body>\r
+<h1>Definition of Done for Simantics Platform Releases</h1>\r
+<ol>\r
+<li>The <code>simantics/platform</code> and <code>simantics/third-party</code> Git repositories have a branch <code>release/x.y.z[.w]</code> and tag <code>x.y.z[.w]</code>.</li>\r
+<li><a href="https://www.simantics.org/redmine/projects/simantics-platform/wiki/ChangeLog">A change log entry</a> is compiled from the issues in this release and made available to the general public separately for the platform and for the open products included in the release train.</li>\r
+<li><a href="http://dev.simantics.org/index.php/Roadmap">Roadmap</a> is up-to-date.</li>\r
+<li><a href="http://dev.simantics.org/index.php/Tutorials">Tutorials</a> are up-to-date and coherent with the platform.</li>\r
+<li>For all new major/minor releases, Wiki documentation is backed up (cloned).</li>\r
+</ol>\r
+<hr />\r
+<h1>Simantics Platform Release Process</h1>\r
+<ul>\r
+<li>Create <code>release/x.y.z[.w]</code> release stabilisation branch</li>\r
+<li>Repeat until stable:\r
+<ul>\r
+<li>Develop, test and document components and test products</li>\r
+</ul>\r
+</li>\r
+<li>Tag the release in repository</li>\r
+<li>Backup documentation wiki databases</li>\r
+<li>Build and publish SDK package with and without sources\r
+<ul>\r
+<li>Does not really require any work</li>\r
+</ul>\r
+</li>\r
+<li>Build Simantics open source products and plug-in components which are a part of the release train</li>\r
+<li>Update websites to reflect the new release</li>\r
+</ul>\r
+<hr />\r
+<h1>Released Plug-in Components and Products</h1>\r
+<p>There are both plug-in components and products that are part of the "Simantics release train" that shall be released simultaneously to a major or minor Simantics release.</p>\r
+<p>Plug-in components are installable features that are deployed online as P2 repositories for general availability. Products are deployed as ZIP files and made available online in designated locations on simantics.org.</p>\r
+<p>Products that are part of the release train:</p>\r
+<ul>\r
+<li>Simantics Desktop</li>\r
+<li>Simantics System Dynamics Tool - <a href="https://www.simantics.org:8088/r/gitweb?p=simantics/sysdyn.git;a=summary">simantics/sysdyn.git</a></li>\r
+</ul>\r
+<p>Plug-in components that are part of the release train:</p>\r
+<ul>\r
+<li>Simantics R - <a href="https://www.simantics.org:8088/r/gitweb?p=simantics/r.git;a=summary">simantics/r.git</a></li>\r
+<li>FMIL - <a href="https://www.simantics.org:8088/r/gitweb?p=simantics/fmil.git;a=summary">simantics/fmil.git</a></li>\r
+<li>FMI Studio - <a href="https://www.simantics.org:8088/r/gitweb?p=members/fmi.git;a=summary">members/fmi.git</a></li>\r
+<li>Simupedia - <a href="https://www.simantics.org/svn/members/simupedia">Members SVN</a></li>\r
+</ul>\r
+<p>For simplicity, each of these components are versioned accoring to platform versioning, i.e. for Platform SDK 1.26.0 there will be Simantics Desktop 1.26.0, Sysdyn 1.26.0, and so on.</p>\r
+<hr />\r
+<h1>Release Schedule</h1>\r
+<ul>\r
+<li>Releases are branched 4 weeks before the set release date.</li>\r
+<li>During this time no more new features are allowed in the release branch and the existing work shall be stabilized. Work must be focused on bug fixes and documentation.</li>\r
+<li>Source code changes to release branches are forbidden in the last 2 weeks. Documentation-only changes are still allowed. However, if critical show-stopper problems surface during that time, the changes must be done. After that the release engineering team must decide whether to stick to the original release schedule or whether to delay the release.</li>\r
+</ul>\r
+<hr />\r
+<h1>Simantics Platform Release - Step by Step</h1>\r
+<h2>Create release branch from selected commit</h2>\r
+<p>When release stabilisation starts, branch <code>simantics/platform</code> and <code>simantics/third-party</code> repositories:</p>\r
+<pre><code>git clone ssh://<user>@www.simantics.org:29418/simantics/platform.git\r
+cd platform\r
+git branch release/x.y.z[.w] <commit>\r
+git push origin release/x.y.z[.w]\r
+\r
+git clone ssh://<user>@www.simantics.org:29418/simantics/third-party.git\r
+cd third-party\r
+git branch release/x.y.z[.w] <commit>\r
+git push origin release/x.y.z[.w]\r
+</code></pre>\r
+<p>When creating major/minor releases <code><commit></code> is usually a commit in the <code>master</code> branch.\r
+With service releases, branch from an existing <code>release/*</code> branch instead.</p>\r
+<h2>Prepare release branch for use</h2>\r
+<h3>Prepare .target files</h3>\r
+<ol>\r
+<li>\r
+<p>Retrieve release branch of the platform repository</p>\r
+<pre><code>git clone ssh://<user>@www.simantics.org:29418/simantics/platform.git\r
+cd platform\r
+git branch release/x.y.z[.w] remotes/origin/release/x.y.z[.w]\r
+git checkout release/x.y.z[.w]\r
+</code></pre>\r
+</li>\r
+<li>\r
+<p>Edit all target platform files in <code>releng/org.simantics.sdk.build.targetdefinition/</code>, i.e.</p>\r
+<ul>\r
+<li><code>simantics.target</code></li>\r
+<li><code>org.simantics.sdk.build.targetdefinition.target</code></li>\r
+</ul>\r
+<p>At the beginning of simantics.target file, increment <code>sequenceNumber</code> by 1</p>\r
+<pre><code><?xml version="1.0" encoding="UTF-8" standalone="no"?>\r
+<?pde version="3.8"?>\r
+<target name="Simantics x.y.z[.w]" sequenceNumber="11">\r
+</code></pre>\r
+<p>Next, replace the following rows in both mentioned files:</p>\r
+<pre><code><repository location="http://www.simantics.org/download/master/sdk"/>\r
+<repository location="http://www.simantics.org/download/master/external-components/maven"/>\r
+<repository location="http://www.simantics.org/download/master/external-components/manual"/>\r
+</code></pre>\r
+<p>with</p>\r
+<pre><code><repository location="http://www.simantics.org/download/release/x.y.z[.w]/sdk"/>\r
+<repository location="http://www.simantics.org/download/release/x.y.z[.w]/external-components/maven"/>\r
+<repository location="http://www.simantics.org/download/release/x.y.z[.w]/external-components/manual"/>\r
+</code></pre>\r
+</li>\r
+</ol>\r
+<h3>Initialize release branch distribution web site</h3>\r
+<ul>\r
+<li>Run <a href="https://www.simantics.org/jenkins/job/SDK/job/Deploy%20External%20Components%20to%20Web/">SDK/Deploy External Components to Web</a> build with parameters:\r
+<ul>\r
+<li><strong>GERRIT_REFNAME:</strong> <code>release/x.y.z[.w]</code></li>\r
+<li><strong>PUBLISH_ARTIFACTS:</strong> <code>true</code></li>\r
+</ul>\r
+</li>\r
+<li>Run the <a href="https://www.simantics.org/jenkins/job/SDK/job/Simantics%20SDK/">SDK/Simantics SDK</a> build with parameters:\r
+<ul>\r
+<li><strong>GERRIT_REFNAME:</strong> <code>release/x.y.z[.w]</code></li>\r
+<li><strong>PUBLISH_ARTIFACTS:</strong> <code>true</code></li>\r
+</ul>\r
+</li>\r
+</ul>\r
+<p>Running these two builds will ensure that both the external components required to build the SDK and the Simantics SDK for the new release branch are published online at <code>http://www.simantics.org/download/release/x.y.z[.w]/</code>.</p>\r
+<p>After this, whenever changes are pushed/merged to <code>release/x.y.z[.w]</code> branch in Gerrit, new <strong>SDK/Simantics SDK</strong> builds are triggered automatically and they will publish the results at the same location online.</p>\r
+<p>This means that one does not have to do any tricks after this to build and publish the SDK as a P2 repository online. It is an automated process that is performed by the <a href="https://www.simantics.org/jenkins/job/SDK/job/Simantics%20SDK/">SDK/Simantics SDK</a> Jenkins job.</p>\r
+<h2>Review documentation</h2>\r
+<p>Documentation to review:</p>\r
+<ul>\r
+<li><a href="http://dev.simantics.org/">Developer wiki</a></li>\r
+<li><a href="https://www.simantics.org/end_user_wiki">End-user wiki</a></li>\r
+<li><a href="https://www.simantics.org/members">Member wiki</a></li>\r
+</ul>\r
+<p>For each wiki page:</p>\r
+<ul>\r
+<li>Read through and get authors to fix found problems, such as TODOs or invalid information.</li>\r
+</ul>\r
+<h2>Review tutorials</h2>\r
+<ul>\r
+<li>\r
+<p>Ensure tutorial wiki documentation at http://dev.simantics.org/index.php/Tutorials is up-to-date with the released platform</p>\r
+</li>\r
+<li>\r
+<p>Ensure tutorial projects and product build properly</p>\r
+</li>\r
+<li>\r
+<p>com.acme.movie</p>\r
+<ul>\r
+<li>Build with Buckminster, com.acme.movie.product.site.feature</li>\r
+</ul>\r
+</li>\r
+</ul>\r
+<h2>Tag release/* branches</h2>\r
+<p>When the release branches are ready for the release, tag them with the tag <code>vx.y.z[.w]</code>:</p>\r
+<pre><code>git clone ssh://<user>@www.simantics.org:29418/simantics/platform.git\r
+cd platform \r
+git checkout release/x.y.z[.w]\r
+git tag vx.y.z[.w] -m "Simantics x.y.z[.w] release"\r
+git push origin --tags\r
+\r
+git clone ssh://<user>@www.simantics.org:29418/simantics/third-party.git\r
+cd third-party\r
+git checkout release/x.y.z[.w]\r
+git tag vx.y.z[.w] -m "Simantics x.y.z[.w] release"\r
+git push origin --tags\r
+</code></pre>\r
+<blockquote>\r
+<p>Note The -m argument must be supplied to create an <a href="https://git-scm.com/book/en/v2/Git-Basics-Tagging">annotated tag</a>.\r
+Only annotated or signed tags can be pushed to Gerrit.</p>\r
+</blockquote>\r
+<h2>Backup documentation wiki databases</h2>\r
+<p>This step is only necessary for major/minor releases, not for service releases.</p>\r
+<p>The wiki databases to be backed up are:</p>\r
+<ul>\r
+<li><a href="http://dev.simantics.org/">Developer wiki</a></li>\r
+<li><a href="https://www.simantics.org/end_user_wiki">End-user wiki</a></li>\r
+</ul>\r
+<p>These are MediaWiki installations. The only sane way to "tag" the documentation\r
+is to back up the mysql database backing the wiki. Should the wiki be required\r
+at a later time for some reason, we'll put the documentation up then in a\r
+separate Mediawiki installation.</p>\r
+<ol>\r
+<li>Dump documentation wiki databases using [dump-wikis.sh](./dump-wikis.sh) script.</li>\r
+<li>Put the generated backup x.y.z.tar.gz at /var/backup/simantics-releases/x.y.z/wiki/</li>\r
+</ol>\r
+<h2>Compile change log entry</h2>\r
+<ul>\r
+<li>Edit the <a href="https://www.simantics.org/redmine/projects/simantics-platform/wiki/ChangeLog">main page</a> and add a a link for release x.y.z[.w].</li>\r
+<li>Open the change log page of the previous release, e.g. <a href="https://www.simantics.org/redmine/projects/simantics-platform/wiki/Simantics_1250">1.25.0</a></li>\r
+<li>Open the new link in another browser/tab to start editing the new wiki page</li>\r
+<li>Edit the previous release's page and copy its wiki source contents over to the new release's page.</li>\r
+<li>Fix the content to match the new release:\r
+<ul>\r
+<li>Remove the issue content of the previous release</li>\r
+<li>Fix release number, release date, release branch link and the link to all issues closed for the release\r
+<ul>\r
+<li>Save new public issue query that lists all issues closed for the release by <a href="https://www.simantics.org/redmine/projects/simantics-platform/issues?query_id=122">starting from the previous release's query</a></li>\r
+</ul>\r
+</li>\r
+<li>Add filter to query: <strong>Release Notes: Any</strong> to only show issues that have some content in their Release Notes field</li>\r
+<li>Export closed issue list as CSV with selected columns only. Open the resulting CSV file in Excel.</li>\r
+<li>Use <strong>Data -> Text to Columns</strong> with tab column separation to columnize the result</li>\r
+<li>Format the list as a table so that there is only one issue / row</li>\r
+<li>Remove all other columns besides: Issue #, Tracker, Release Notes</li>\r
+<li>Format the data into a Textile table:\r
+<ul>\r
+<li>Copy to table contents as text into <a href="http://www.pspad.com/">PSPad</a></li>\r
+<li>Replace (CTRL+H) tabs (<code>\t</code>) with <code>|</code> with <code>Regular Expressions</code> selection checked</li>\r
+<li>Use <strong>Insert Text Into Lines..</strong> (ALT-I) to fix line beginnings and ends:\r
+<ul>\r
+<li>Text:\r
+<ul>\r
+<li>At Lines Begin: <code>|#</code></li>\r
+<li>At Lines End: <code>|</code></li>\r
+</ul>\r
+</li>\r
+</ul>\r
+</li>\r
+</ul>\r
+</li>\r
+<li>Copy the resulting textile table over to the change log page</li>\r
+</ul>\r
+</li>\r
+<li>Highlight major issues in the list by changing the text background color of the <strong>Type</strong> column:\r
+<ul>\r
+<li><code>%{background: lightsalmon}Major Bug%</code></li>\r
+<li><code>%{background: lightgreen}Major Feature%</code></li>\r
+<li><code>%{background: lightgreen}Major Enhancement%</code></li>\r
+</ul>\r
+</li>\r
+</ul>\r
+<h2>Disseminate information about the release</h2>\r
+<ul>\r
+<li><a href="http://dev.simantics.org">Developer Wiki</a>: Update roadmap at http://dev.simantics.org/index.php/Roadmap</li>\r
+<li><a href="https://www.simantics.org/redmine/">Redmine</a>: Post news on the developer/user-visible changes here.</li>\r
+<li><a href="https://www.simantics.org">simantics.org</a>: Post news on the release and a link to the redmine post</li>\r
+<li><a href="https://www.simantics.org/members/">Members Wiki</a>: Update frame plan to reflect the realized dates and link to Redmine news</li>\r
+<li><a href="mailto:simantics-developers@simantics.org">mailto:simantics-developers@simantics.org</a> Send "newsletter" to `simantics-developers@simantics.org:</li>\r
+</ul>\r
+<p><strong>Newsletter template:</strong></p>\r
+<pre><code>Hello everyone,\r
+ \r
+Simantics release x.y.z[.w] has been released. Head over to\r
+https://www.simantics.org/redmine/news/<news number>\r
+for the release news.\r
+\r
+Best regards,\r
+Simantics Release Engineering Team\r
+</code></pre>\r
+<p><strong>Redmine news template:</strong></p>\r
+<pre><code>Title: Simantics x.y.z[.w] released\r
+\r
+Simantics x.y.z[.w] was released on <date>.\r
+Please find change log at: [[simantics-platform:Simantics_xyzw|Simantics x.y.z[.w]]]\r
+\r
+Insert some general thoughts on the release...\r
+</code></pre>\r
+<hr />\r
+<h1>TODO</h1>\r
+<ul>\r
+<li>Create a parametrized release train pipeline build in Jenkins that creates all artifacts of a simantics release\r
+<ul>\r
+<li>Desktop, Sysdyn, R, Simupedia, FMIL, FMI Studio</li>\r
+</ul>\r
+</li>\r
+</ul>\r
+<ul>\r
+<li>\r
+<p>Incorporate tutorial code in the platform repository as a separate folder to allow platform builds to directly ensure that the tutorial code still builds OK</p>\r
+</li>\r
+<li>\r
+<p>Start using https://github.com/mbarbero/fr.obeo.releng.targetplatform to generate <code>.target</code> files. <code>.tpd</code> files allow specifying version ranges instead of specific versions.</p>\r
+</li>\r
+</ul>\r
+\r
+</body>\r
+</html>\r
+<!-- This document was created with MarkdownPad, the Markdown editor for Windows (http://markdownpad.com) -->\r
--- /dev/null
+# Definition of Done for Simantics Platform Releases\r
+\r
+1. The `simantics/platform` and `simantics/third-party` Git repositories have a branch `release/x.y.z[.w]` and tag `x.y.z[.w]`.\r
+2. [A change log entry](https://www.simantics.org/redmine/projects/simantics-platform/wiki/ChangeLog) is compiled from the issues in this release and made available to the general public separately for the platform and for the open products included in the release train.\r
+3. [Roadmap](http://dev.simantics.org/index.php/Roadmap) is up-to-date.\r
+4. [Tutorials](http://dev.simantics.org/index.php/Tutorials) are up-to-date and coherent with the platform.\r
+5. For all new major/minor releases, Wiki documentation is backed up (cloned).\r
+\r
+----\r
+\r
+# Simantics Platform Release Process\r
+\r
+* Create `release/x.y.z[.w]` release stabilisation branch\r
+* Repeat until stable:\r
+ * Develop, test and document components and test products\r
+* Tag the release in repository\r
+* Backup documentation wiki databases\r
+* Build and publish SDK package with and without sources\r
+ * Does not really require any work\r
+* Build Simantics open source products and plug-in components which are a part of the release train\r
+* Update websites to reflect the new release\r
+\r
+----\r
+\r
+# Released Plug-in Components and Products \r
+\r
+There are both plug-in components and products that are part of the "Simantics release train" that shall be released simultaneously to a major or minor Simantics release.\r
+\r
+Plug-in components are installable features that are deployed online as P2 repositories for general availability. Products are deployed as ZIP files and made available online in designated locations on simantics.org. \r
+\r
+Products that are part of the release train: \r
+* Simantics Desktop\r
+* Simantics System Dynamics Tool - [simantics/sysdyn.git](https://www.simantics.org:8088/r/gitweb?p=simantics/sysdyn.git;a=summary)\r
+\r
+Plug-in components that are part of the release train:\r
+* Simantics R - [simantics/r.git](https://www.simantics.org:8088/r/gitweb?p=simantics/r.git;a=summary)\r
+* FMIL - [simantics/fmil.git](https://www.simantics.org:8088/r/gitweb?p=simantics/fmil.git;a=summary)\r
+* FMI Studio - [members/fmi.git](https://www.simantics.org:8088/r/gitweb?p=members/fmi.git;a=summary)\r
+* Simupedia - [Members SVN](https://www.simantics.org/svn/members/simupedia)\r
+\r
+For simplicity, each of these components are versioned accoring to platform versioning, i.e. for Platform SDK 1.26.0 there will be Simantics Desktop 1.26.0, Sysdyn 1.26.0, and so on. \r
+\r
+----\r
+\r
+# Release Schedule\r
+\r
+* Releases are branched 4 weeks before the set release date.\r
+* During this time no more new features are allowed in the release branch and the existing work shall be stabilized. Work must be focused on bug fixes and documentation.\r
+* Source code changes to release branches are forbidden in the last 2 weeks. Documentation-only changes are still allowed. However, if critical show-stopper problems surface during that time, the changes must be done. After that the release engineering team must decide whether to stick to the original release schedule or whether to delay the release. \r
+\r
+----\r
+\r
+# Simantics Platform Release - Step by Step\r
+\r
+## Create release branch from selected commit\r
+\r
+When release stabilisation starts, branch `simantics/platform` and `simantics/third-party` repositories:\r
+\r
+ git clone ssh://<user>@www.simantics.org:29418/simantics/platform.git\r
+ cd platform\r
+ git branch release/x.y.z[.w] <commit>\r
+ git push origin release/x.y.z[.w]\r
+\r
+ git clone ssh://<user>@www.simantics.org:29418/simantics/third-party.git\r
+ cd third-party\r
+ git branch release/x.y.z[.w] <commit>\r
+ git push origin release/x.y.z[.w]\r
+\r
+When creating major/minor releases `<commit>` is usually a commit in the `master` branch.\r
+With service releases, branch from an existing `release/*` branch instead.\r
+\r
+## Prepare release branch for use\r
+\r
+### Prepare .target files\r
+\r
+1. Retrieve release branch of the platform repository\r
+\r
+ git clone ssh://<user>@www.simantics.org:29418/simantics/platform.git\r
+ cd platform\r
+ git branch release/x.y.z[.w] remotes/origin/release/x.y.z[.w]\r
+ git checkout release/x.y.z[.w]\r
+\r
+2. Edit all target platform files in `releng/org.simantics.sdk.build.targetdefinition/`, i.e.\r
+ * `simantics.target`\r
+ * `org.simantics.sdk.build.targetdefinition.target`\r
+\r
+ At the beginning of simantics.target file, increment `sequenceNumber` by 1\r
+ ~~~\r
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>\r
+ <?pde version="3.8"?>\r
+ <target name="Simantics x.y.z[.w]" sequenceNumber="11">\r
+ ~~~\r
+\r
+ Next, replace the following rows in both mentioned files: \r
+\r
+ ~~~\r
+ <repository location="http://www.simantics.org/download/master/sdk"/>\r
+ <repository location="http://www.simantics.org/download/master/external-components/maven"/>\r
+ <repository location="http://www.simantics.org/download/master/external-components/manual"/>\r
+ ~~~\r
+\r
+ with\r
+\r
+ ~~~\r
+ <repository location="http://www.simantics.org/download/release/x.y.z[.w]/sdk"/>\r
+ <repository location="http://www.simantics.org/download/release/x.y.z[.w]/external-components/maven"/>\r
+ <repository location="http://www.simantics.org/download/release/x.y.z[.w]/external-components/manual"/>\r
+ ~~~\r
+\r
+### Initialize release branch distribution web site\r
+\r
+* Run [SDK/Deploy External Components to Web](https://www.simantics.org/jenkins/job/SDK/job/Deploy%20External%20Components%20to%20Web/) build with parameters:\r
+ * **GERRIT_REFNAME:** `release/x.y.z[.w]`\r
+ * **PUBLISH_ARTIFACTS:** `true`\r
+* Run the [SDK/Simantics SDK](https://www.simantics.org/jenkins/job/SDK/job/Simantics%20SDK/) build with parameters:\r
+ * **GERRIT_REFNAME:** `release/x.y.z[.w]`\r
+ * **PUBLISH_ARTIFACTS:** `true`\r
+\r
+Running these two builds will ensure that both the external components required to build the SDK and the Simantics SDK for the new release branch are published online at `http://www.simantics.org/download/release/x.y.z[.w]/`.\r
+\r
+After this, whenever changes are pushed/merged to `release/x.y.z[.w]` branch in Gerrit, new **SDK/Simantics SDK** builds are triggered automatically and they will publish the results at the same location online.\r
+\r
+This means that one does not have to do any tricks after this to build and publish the SDK as a P2 repository online. It is an automated process that is performed by the [SDK/Simantics SDK](https://www.simantics.org/jenkins/job/SDK/job/Simantics%20SDK/) Jenkins job.\r
+\r
+## Review documentation\r
+\r
+Documentation to review:\r
+* [Developer wiki](http://dev.simantics.org/)\r
+* [End-user wiki](https://www.simantics.org/end_user_wiki)\r
+* [Member wiki](https://www.simantics.org/members)\r
+\r
+For each wiki page:\r
+* Read through and get authors to fix found problems, such as TODOs or invalid information.\r
+\r
+## Review tutorials\r
+\r
+* Ensure tutorial wiki documentation at http://dev.simantics.org/index.php/Tutorials is up-to-date with the released platform\r
+* Ensure tutorial projects and product build properly\r
+\r
+* com.acme.movie\r
+ - Build with Buckminster, com.acme.movie.product.site.feature\r
+\r
+## Tag release/* branches\r
+\r
+When the release branches are ready for the release, tag them with the tag `vx.y.z[.w]`:\r
+\r
+ git clone ssh://<user>@www.simantics.org:29418/simantics/platform.git\r
+ cd platform \r
+ git checkout release/x.y.z[.w]\r
+ git tag vx.y.z[.w] -m "Simantics x.y.z[.w] release"\r
+ git push origin --tags\r
+\r
+ git clone ssh://<user>@www.simantics.org:29418/simantics/third-party.git\r
+ cd third-party\r
+ git checkout release/x.y.z[.w]\r
+ git tag vx.y.z[.w] -m "Simantics x.y.z[.w] release"\r
+ git push origin --tags\r
+\r
+> Note The -m argument must be supplied to create an [annotated tag](https://git-scm.com/book/en/v2/Git-Basics-Tagging).\r
+> Only annotated or signed tags can be pushed to Gerrit.\r
+\r
+## Backup documentation wiki databases \r
+\r
+This step is only necessary for major/minor releases, not for service releases.\r
+\r
+The wiki databases to be backed up are:\r
+* [Developer wiki](http://dev.simantics.org/)\r
+* [End-user wiki](https://www.simantics.org/end_user_wiki)\r
+\r
+These are MediaWiki installations. The only sane way to "tag" the documentation\r
+is to back up the mysql database backing the wiki. Should the wiki be required\r
+at a later time for some reason, we'll put the documentation up then in a\r
+separate Mediawiki installation. \r
+\r
+1. Dump documentation wiki databases using [dump-wikis.sh](./dump-wikis.sh) script.\r
+2. Put the generated backup x.y.z.tar.gz at /var/backup/simantics-releases/x.y.z/wiki/\r
+\r
+## Compile change log entry\r
+\r
+* Edit the [main page](https://www.simantics.org/redmine/projects/simantics-platform/wiki/ChangeLog) and add a a link for release x.y.z[.w].\r
+* Open the change log page of the previous release, e.g. [1.25.0](https://www.simantics.org/redmine/projects/simantics-platform/wiki/Simantics_1250)\r
+* Open the new link in another browser/tab to start editing the new wiki page\r
+* Edit the previous release's page and copy its wiki source contents over to the new release's page.\r
+* Fix the content to match the new release:\r
+ * Remove the issue content of the previous release\r
+ * Fix release number, release date, release branch link and the link to all issues closed for the release\r
+ * Save new public issue query that lists all issues closed for the release by [starting from the previous release's query](https://www.simantics.org/redmine/projects/simantics-platform/issues?query_id=122)\r
+ * Add filter to query: **Release Notes: Any** to only show issues that have some content in their Release Notes field\r
+ * Export closed issue list as CSV with selected columns only. Open the resulting CSV file in Excel.\r
+ * Use **Data -> Text to Columns** with tab column separation to columnize the result\r
+ * Format the list as a table so that there is only one issue / row\r
+ * Remove all other columns besides: Issue #, Tracker, Release Notes\r
+ * Format the data into a Textile table:\r
+ * Copy to table contents as text into [PSPad](http://www.pspad.com/)\r
+ * Replace (CTRL+H) tabs (`\t`) with `|` with `Regular Expressions` selection checked\r
+ * Use **Insert Text Into Lines..** (ALT-I) to fix line beginnings and ends:\r
+ * Text:\r
+ * At Lines Begin: `|#`\r
+ * At Lines End: `|`\r
+ * Copy the resulting textile table over to the change log page\r
+* Highlight major issues in the list by changing the text background color of the **Type** column:\r
+ * `%{background: lightsalmon}Major Bug%`\r
+ * `%{background: lightgreen}Major Feature%`\r
+ * `%{background: lightgreen}Major Enhancement%`\r
+\r
+## Disseminate information about the release\r
+\r
+* [Developer Wiki](http://dev.simantics.org): Update roadmap at http://dev.simantics.org/index.php/Roadmap\r
+* [Redmine](https://www.simantics.org/redmine/): Post news on the developer/user-visible changes here.\r
+* [simantics.org](https://www.simantics.org): Post news on the release and a link to the redmine post\r
+* [Members Wiki](https://www.simantics.org/members/): Update frame plan to reflect the realized dates and link to Redmine news\r
+* [mailto:simantics-developers@simantics.org](mailto:simantics-developers@simantics.org) Send "newsletter" to `simantics-developers@simantics.org:\r
+\r
+**Newsletter template:**\r
+~~~\r
+Hello everyone,\r
+ \r
+Simantics release x.y.z[.w] has been released. Head over to\r
+https://www.simantics.org/redmine/news/<news number>\r
+for the release news.\r
+\r
+Best regards,\r
+Simantics Release Engineering Team\r
+~~~\r
+\r
+**Redmine news template:**\r
+~~~\r
+Title: Simantics x.y.z[.w] released\r
+\r
+Simantics x.y.z[.w] was released on <date>.\r
+Please find change log at: [[simantics-platform:Simantics_xyzw|Simantics x.y.z[.w]]]\r
+\r
+Insert some general thoughts on the release...\r
+~~~\r
+\r
+----\r
+\r
+# TODO\r
+\r
+* Create a parametrized release train pipeline build in Jenkins that creates all artifacts of a simantics release\r
+ * Desktop, Sysdyn, R, Simupedia, FMIL, FMI Studio\r
+\r
+\r
+* Incorporate tutorial code in the platform repository as a separate folder to allow platform builds to directly ensure that the tutorial code still builds OK\r
+ \r
+* Start using https://github.com/mbarbero/fr.obeo.releng.targetplatform to generate `.target` files. `.tpd` files allow specifying version ranges instead of specific versions.\r
+\r
<groupId>org.simantics</groupId>
<artifactId>org.simantics.sdk.build.p2.site</artifactId>
<packaging>pom</packaging>
- <version>1.25.0</version>
+ <version>1.26.0</version>
<properties>
<itext.version.actual>2.1.7.b1</itext.version.actual>
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<?pde version="3.8"?><target name="Eclipse Mars.2" sequenceNumber="223">
-<locations>
-<location includeAllPlatforms="true" includeConfigurePhase="false" includeMode="slicer" includeSource="true" type="InstallableUnit">
-<unit id="org.eclipse.mylyn.wikitext_feature.feature.group" version="2.7.0.v20151015-1452"/>
-<unit id="org.eclipse.emf.sdk.feature.group" version="2.11.2.v20160208-0841"/>
-<unit id="org.eclipse.epp.mpc.feature.group" version="1.4.2.v20160210-2005"/>
-<repository location="http://dev.simupedia.com/download/mars"/>
-</location>
-<location includeAllPlatforms="true" includeConfigurePhase="false" includeMode="slicer" includeSource="true" type="InstallableUnit">
-<unit id="org.eclipse.ecf.core.ssl.feature.feature.group" version="1.1.0.v20151130-0157"/>
-<unit id="org.eclipse.rcp.source.feature.group" version="4.5.2.v20160212-1500"/>
-<unit id="org.eclipse.e4.core.tools.feature.feature.group" version="4.5.1.v20160129-0959"/>
-<unit id="org.eclipse.ecf.filetransfer.source.feature.feature.group" version="3.12.0.v20151130-0157"/>
-<unit id="org.eclipse.ecf.filetransfer.ssl.feature.feature.group" version="1.1.0.v20151130-0157"/>
-<unit id="org.eclipse.help.feature.group" version="2.1.2.v20160212-1500"/>
-<unit id="org.eclipse.ecf.filetransfer.httpclient4.source.feature.feature.group" version="3.12.0.v20151130-0157"/>
-<unit id="org.eclipse.e4.core.tools.feature.source.feature.group" version="4.5.1.v20160129-0959"/>
-<unit id="org.eclipse.swt.tools.feature.feature.group" version="3.104.2.v20160128-0900"/>
-<unit id="org.eclipse.ecf.filetransfer.httpclient4.feature.feature.group" version="3.12.0.v20151130-0157"/>
-<unit id="org.eclipse.ecf.filetransfer.ssl.source.feature.feature.group" version="1.1.0.v20151130-0157"/>
-<unit id="org.eclipse.platform.feature.group" version="4.5.2.v20160212-1500"/>
-<unit id="org.eclipse.ecf.core.ssl.source.feature.feature.group" version="1.1.0.v20151130-0157"/>
-<unit id="org.eclipse.rcp.feature.group" version="4.5.2.v20160212-1500"/>
-<unit id="org.eclipse.equinox.p2.discovery.feature.feature.group" version="1.0.300.v20150430-1836"/>
-<unit id="org.eclipse.ecf.core.feature.feature.group" version="1.2.0.v20151130-0157"/>
-<unit id="org.eclipse.ecf.core.source.feature.feature.group" version="1.2.0.v20151130-0157"/>
-<unit id="org.eclipse.equinox.sdk.feature.group" version="3.11.2.v20160202-2102"/>
-<unit id="org.eclipse.platform.source.feature.group" version="4.5.2.v20160212-1500"/>
-<unit id="org.eclipse.releng.tools.feature.group" version="3.6.0.v20150527-0145"/>
-<unit id="org.eclipse.ecf.filetransfer.feature.feature.group" version="3.12.0.v20151130-0157"/>
-<unit id="org.eclipse.sdk.ide" version="4.5.2.M20160212-1500"/>
-<unit id="org.eclipse.ecf.filetransfer.httpclient4.ssl.feature.feature.group" version="1.1.0.v20151130-0157"/>
-<unit id="org.eclipse.help.source.feature.group" version="2.1.2.v20160212-1500"/>
-<unit id="org.eclipse.ecf.filetransfer.httpclient4.ssl.source.feature.feature.group" version="1.1.0.v20151130-0157"/>
-<repository location="http://dev.simupedia.com/download/eclipse/updates/4.5"/>
-</location>
-<location includeAllPlatforms="true" includeConfigurePhase="false" includeMode="slicer" includeSource="true" type="InstallableUnit">
-<unit id="org.eclipse.nebula.effects.stw.feature.feature.group" version="1.0.0.201605182147"/>
-<unit id="org.eclipse.nebula.visualization.feature.feature.group" version="1.0.0.201605182147"/>
-<unit id="org.eclipse.nebula.widgets.calendarcombo.feature.feature.group" version="1.0.0.201605182147"/>
-<unit id="org.eclipse.nebula.widgets.gallery.feature.feature.group" version="1.0.0.201605182147"/>
-<unit id="org.eclipse.nebula.feature.feature.group" version="1.0.0.201605182147"/>
-<unit id="org.eclipse.nebula.cwt.feature.feature.group" version="1.0.0.201605182147"/>
-<unit id="org.eclipse.nebula.widgets.oscilloscope.feature.feature.group" version="1.2.0.201605182147"/>
-<unit id="org.eclipse.nebula.widgets.pshelf.css.feature.feature.group" version="1.0.0.201605182147"/>
-<unit id="org.eclipse.nebula.widgets.ganttchart.feature.feature.group" version="1.0.0.201605182147"/>
-<unit id="org.eclipse.nebula.widgets.xviewer.feature.feature.group" version="1.0.0.201605182147"/>
-<unit id="org.eclipse.nebula.widgets.compositetable.feature.feature.group" version="1.0.0.201605182147"/>
-<unit id="org.eclipse.nebula.widgets.grid.feature.feature.group" version="1.0.0.201605182147"/>
-<unit id="org.eclipse.nebula.widgets.cdatetime.feature.feature.group" version="1.0.0.201605182147"/>
-<unit id="org.eclipse.nebula.widgets.pshelf.feature.feature.group" version="1.0.0.201605182147"/>
-<unit id="org.eclipse.nebula.widgets.richtext.feature.feature.group" version="1.0.0.201605182147"/>
-<unit id="org.eclipse.nebula.widgets.tablecombo.feature.feature.group" version="1.0.0.201605182147"/>
-<unit id="org.eclipse.nebula.widgets.paperclips.feature.feature.group" version="2.0.0.201605182147"/>
-<unit id="org.eclipse.nebula.examples.release.feature.feature.group" version="1.0.4.201605182147"/>
-<unit id="org.eclipse.nebula.widgets.pgroup.feature.feature.group" version="1.0.0.201605182147"/>
-<repository location="http://dev.simupedia.com/download/nebula/Q22016/release/"/>
-</location>
-<location includeAllPlatforms="true" includeConfigurePhase="false" includeMode="slicer" includeSource="true" type="InstallableUnit">
-<unit id="org.eclipse.e4.tools.spies.feature.feature.group" version="0.17.0.v20160919-2121"/>
-<repository location="http://dev.simupedia.com/download/e4/snapshots/org.eclipse.e4.tools/latest/"/>
-</location>
-<location includeAllPlatforms="true" includeConfigurePhase="false" includeMode="slicer" includeSource="true" type="InstallableUnit">
-<unit id="org.eclipse.nebula.incubation.feature.feature.group" version="1.0.0.201605182147"/>
-<unit id="org.eclipse.nebula.examples.incubation.feature.feature.group" version="1.0.0.201605182147"/>
-<repository location="http://dev.simupedia.com/download/nebula/Q22016/incubation"/>
-</location>
-<location includeAllPlatforms="true" includeConfigurePhase="false" includeMode="slicer" includeSource="true" type="InstallableUnit">
-<unit id="org.eclipse.nebula.widgets.nattable.core.feature.feature.group" version="1.4.0.201606011907"/>
-<unit id="org.eclipse.nebula.widgets.nattable.extension.e4.source.feature.feature.group" version="1.0.0.201606011907"/>
-<unit id="org.eclipse.nebula.widgets.nattable.extension.poi.feature.feature.group" version="1.4.0.201606011907"/>
-<unit id="org.eclipse.nebula.widgets.nattable.extension.glazedlists.feature.feature.group" version="1.4.0.201606011907"/>
-<unit id="org.eclipse.nebula.widgets.nattable.core.source.feature.feature.group" version="1.4.0.201606011907"/>
-<unit id="org.eclipse.nebula.widgets.nattable.extension.glazedlists.source.feature.feature.group" version="1.4.0.201606011907"/>
-<unit id="org.eclipse.nebula.widgets.nattable.extension.nebula.feature.feature.group" version="1.0.0.201606011907"/>
-<unit id="org.eclipse.nebula.widgets.nattable.extension.e4.feature.feature.group" version="1.0.0.201606011907"/>
-<unit id="org.eclipse.nebula.widgets.nattable.extension.nebula.source.feature.feature.group" version="1.0.0.201606011907"/>
-<unit id="org.eclipse.nebula.widgets.nattable.extension.poi.source.feature.feature.group" version="1.4.0.201606011907"/>
-<repository location="http://dev.simupedia.com/download/nebula/nattable/releases/1.4.0/repository/"/>
-</location>
-<location includeAllPlatforms="true" includeConfigurePhase="false" includeMode="slicer" includeSource="true" type="InstallableUnit">
-<unit id="ch.qos.logback.classic" version="1.1.7"/>
-<unit id="ch.qos.logback.classic.source" version="1.1.7"/>
-<unit id="ch.qos.logback.core" version="1.1.7"/>
-<unit id="ch.qos.logback.core.source" version="1.1.7"/>
-<unit id="com.fasterxml.jackson.core.jackson-annotations" version="2.8.0"/>
-<unit id="com.fasterxml.jackson.core.jackson-annotations.source" version="2.8.0"/>
-<unit id="com.fasterxml.jackson.core.jackson-core" version="2.8.5"/>
-<unit id="com.fasterxml.jackson.core.jackson-core.source" version="2.8.5"/>
-<unit id="com.fasterxml.jackson.core.jackson-databind" version="2.8.5"/>
-<unit id="com.fasterxml.jackson.core.jackson-databind.source" version="2.8.5"/>
-<unit id="com.fasterxml.jackson.dataformat.jackson-dataformat-csv" version="2.8.5"/>
-<unit id="com.fasterxml.jackson.dataformat.jackson-dataformat-csv.source" version="2.8.5"/>
-<unit id="com.fasterxml.jackson.dataformat.jackson-dataformat-xml" version="2.8.5"/>
-<unit id="com.fasterxml.jackson.dataformat.jackson-dataformat-xml.source" version="2.8.5"/>
-<unit id="com.fasterxml.jackson.module.jackson-module-jaxb-annotations" version="2.8.5"/>
-<unit id="com.fasterxml.jackson.module.jackson-module-jaxb-annotations.source" version="2.8.5"/>
-<unit id="com.fasterxml.woodstox.woodstox-core" version="5.0.3"/>
-<unit id="com.fasterxml.woodstox.woodstox-core.source" version="5.0.3"/>
-<unit id="com.github.virtuald.curvesapi" version="1.4.0"/>
-<unit id="com.github.virtuald.curvesapi.source" version="1.4.0"/>
-<unit id="com.healthmarketscience.jackcess" version="2.1.3"/>
-<unit id="com.healthmarketscience.jackcess.source" version="2.1.3"/>
-<unit id="com.koloboke.api-jdk8" version="1.0.0"/>
-<unit id="com.koloboke.api-jdk8.source" version="1.0.0"/>
-<unit id="com.koloboke.compile" version="0.5.1"/>
-<unit id="com.koloboke.compile.source" version="0.5.1"/>
-<unit id="com.koloboke.impl-common-jdk8" version="1.0.0"/>
-<unit id="com.koloboke.impl-common-jdk8.source" version="1.0.0"/>
-<unit id="com.lowagie.text" version="2.1.7.b1"/>
-<unit id="com.lowagie.text.source" version="2.1.7.b1"/>
-<unit id="com.sun.jna" version="4.2.2"/>
-<unit id="com.sun.jna.source" version="4.2.2"/>
-<unit id="com.sun.jna.platform" version="4.2.2"/>
-<unit id="com.sun.jna.platform.source" version="4.2.2"/>
-<unit id="freemarker" version="2.3.23.stable"/>
-<unit id="freemarker.source" version="2.3.23.stable"/>
-<unit id="gnu.trove2" version="2.1.0"/>
-<unit id="gnu.trove2.source" version="2.1.0"/>
-<unit id="gnu.trove3" version="3.0.3"/>
-<unit id="gnu.trove3.source" version="3.0.3"/>
-<unit id="it.unimi.dsi.fastutil" version="7.0.13"/>
-<unit id="it.unimi.dsi.fastutil.source" version="7.0.13"/>
-<unit id="jakarta-regexp" version="1.4.0"/>
-<unit id="javax.vecmath" version="1.5.2"/>
-<unit id="net.jcip.annotations" version="1.0.0"/>
-<unit id="net.jcip.annotations.source" version="1.0.0"/>
-<unit id="net.ucanaccess" version="3.0.7"/>
-<unit id="net.ucanaccess.source" version="3.0.7"/>
-<unit id="org.antlr.runtime" version="3.5.2"/>
-<unit id="org.antlr.runtime.source" version="3.5.2"/>
-<unit id="org.apache.log4j" version="1.2.17"/>
-<unit id="org.apache.log4j.source" version="1.2.17"/>
-<unit id="org.apache.commons.codec" version="1.10.0"/>
-<unit id="org.apache.commons.codec.source" version="1.10.0"/>
-<unit id="org.apache.commons.collections" version="3.2.2"/>
-<unit id="org.apache.commons.collections.source" version="3.2.2"/>
-<unit id="org.apache.commons.collections4" version="4.1.0"/>
-<unit id="org.apache.commons.collections4.source" version="4.1.0"/>
-<unit id="org.apache.commons.compress" version="1.12.0"/>
-<unit id="org.apache.commons.compress.source" version="1.12.0"/>
-<unit id="org.apache.commons.logging" version="1.2.0"/>
-<unit id="org.apache.commons.logging.source" version="1.2.0"/>
-<unit id="org.apache.commons.io" version="1.4.0"/>
-<unit id="org.apache.commons.io.source" version="1.4.0"/>
-<unit id="org.apache.commons.lang" version="2.6.0"/>
-<unit id="org.apache.commons.lang.source" version="2.6.0"/>
-<unit id="org.apache.lucene4.analyzers-common" version="4.9.0.b0003"/>
-<unit id="org.apache.lucene4.analyzers-common.source" version="4.9.0.b0003"/>
-<unit id="org.apache.lucene4.core" version="4.9.0.b0003"/>
-<unit id="org.apache.lucene4.core.source" version="4.9.0.b0003"/>
-<unit id="org.apache.lucene4.queryparser" version="4.9.0.b0003"/>
-<unit id="org.apache.lucene4.queryparser.source" version="4.9.0.b0003"/>
-<unit id="org.apache.lucene4.sandbox" version="4.9.0.b0003"/>
-<unit id="org.apache.lucene4.sandbox.source" version="4.9.0.b0003"/>
-<unit id="org.apache.lucene4.queries" version="4.9.0.b0003"/>
-<unit id="org.apache.lucene4.queries.source" version="4.9.0.b0003"/>
-<unit id="org.apache.pdfbox" version="2.0.3"/>
-<unit id="org.apache.pdfbox.source" version="2.0.3"/>
-<unit id="org.apache.pdfbox.xmpbox" version="2.0.3"/>
-<unit id="org.apache.pdfbox.xmpbox.source" version="2.0.3"/>
-<unit id="org.apache.pdfbox.fontbox" version="2.0.3"/>
-<unit id="org.apache.pdfbox.fontbox.source" version="2.0.3"/>
-<unit id="org.apache.xmlbeans" version="2.6.0"/>
-<unit id="org.eclipse.collections.eclipse-collections-api" version="7.1.0"/>
-<unit id="org.eclipse.collections.eclipse-collections-api.source" version="7.1.0"/>
-<unit id="org.eclipse.collections.eclipse-collections" version="7.1.0"/>
-<unit id="org.eclipse.collections.eclipse-collections.source" version="7.1.0"/>
-<unit id="org.hsqldb.hsqldb" version="2.3.1"/>
-<unit id="org.hsqldb.hsqldb.source" version="2.3.1"/>
-<unit id="org.jdom2" version="2.0.6"/>
-<unit id="org.jdom2.source" version="2.0.6"/>
-<unit id="org.jfree.jchart" version="1.0.19"/>
-<unit id="org.jfree.jchart.source" version="1.0.19"/>
-<unit id="org.jfree.jcommon" version="1.0.23"/>
-<unit id="org.jfree.jcommon.source" version="1.0.23"/>
-<unit id="org.mozilla.rhino" version="1.7.7.1"/>
-<unit id="org.mozilla.rhino.source" version="1.7.7.1"/>
-<unit id="org.supercsv" version="2.4.0"/>
-<unit id="org.supercsv.source" version="2.4.0"/>
-<unit id="bouncycastle.bcprov-jdk14" version="138.0.0"/>
-<unit id="bouncycastle.bcmail-jdk14" version="138.0.0"/>
-<unit id="org.bouncycastle.bcprov-jdk14" version="1.38.0"/>
-<unit id="org.bouncycastle.bcprov-jdk14.source" version="1.38.0"/>
-<unit id="org.bouncycastle.bcmail-jdk14" version="1.38.0"/>
-<unit id="org.bouncycastle.bcmail-jdk14.source" version="1.38.0"/>
-<unit id="org.bouncycastle.bctsp-jdk14" version="1.38.0"/>
-<unit id="org.bouncycastle.bctsp-jdk14.source" version="1.38.0"/>
-<unit id="org.ini4j" version="0.5.4"/>
-<unit id="org.ini4j.source" version="0.5.4"/>
-<unit id="org.slf4j.api" version="1.7.20"/>
-<unit id="org.slf4j.api.source" version="1.7.20"/>
-<unit id="stax2-api" version="3.1.4"/>
-<unit id="stax2-api.source" version="3.1.4"/>
-<repository location="http://www.simantics.org/download/master/external-components/maven"/>
-</location>
-<location includeAllPlatforms="true" includeConfigurePhase="false" includeMode="slicer" includeSource="true" type="InstallableUnit">
-<unit id="org.apache.poi.feature.feature.group" version="3.15.0.b0002"/>
-<unit id="org.apache.batik" version="1.8.0.201611220734"/>
-<repository location="http://www.simantics.org/download/master/external-components/manual"/>
-</location>
-<location includeAllPlatforms="true" includeConfigurePhase="false" includeMode="slicer" includeSource="true" type="InstallableUnit">
-<unit id="org.objectweb.asm.xml.source" version="5.0.1.v201404251740"/>
-<unit id="org.objectweb.asm.util.source" version="5.0.1.v201404251740"/>
-<unit id="org.objectweb.asm.source" version="5.0.1.v201404251740"/>
-<unit id="com.google.guava" version="15.0.0.v201403281430"/>
-<unit id="org.objectweb.asm.util" version="5.0.1.v201404251740"/>
-<unit id="org.objectweb.asm.xml" version="5.0.1.v201404251740"/>
-<unit id="com.google.guava.source" version="15.0.0.v201403281430"/>
-<unit id="org.objectweb.asm" version="5.0.1.v201404251740"/>
-<unit id="org.objectweb.asm.commons" version="5.0.1.v201404251740"/>
-<unit id="org.objectweb.asm.analysis.source" version="5.0.1.v201505121915"/>
-<unit id="org.objectweb.asm.commons.source" version="5.0.1.v201404251740"/>
-<unit id="org.objectweb.asm.tree.source" version="5.0.1.v201404251740"/>
-<unit id="org.objectweb.asm.analysis" version="5.0.1.v201505121915"/>
-<unit id="org.objectweb.asm.tree" version="5.0.1.v201404251740"/>
-<repository location="http://dev.simupedia.com/download/tools/orbit/downloads/drops/R20160221192158/repository/"/>
-</location>
-</locations>
-</target>
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>\r
+<?pde version="3.8"?>\r
+<target name="Simantics 1.26.0" sequenceNumber="11">\r
+<locations>\r
+<location includeAllPlatforms="true" includeConfigurePhase="false" includeMode="slicer" includeSource="true" type="InstallableUnit">\r
+<unit id="org.simantics.sdk.feature.group" version="1.26.0"/>\r
+<unit id="org.simantics.sdk.source.feature.group" version="1.26.0"/>\r
+<repository location="http://www.simantics.org/download/master/sdk"/>\r
+</location>\r
+<location includeAllPlatforms="true" includeConfigurePhase="false" includeMode="slicer" includeSource="true" type="InstallableUnit">\r
+<unit id="org.objectweb.asm.xml.source" version="5.0.1.v201404251740"/>\r
+<unit id="org.objectweb.asm.util.source" version="5.0.1.v201404251740"/>\r
+<unit id="org.objectweb.asm.source" version="5.0.1.v201404251740"/>\r
+<unit id="com.google.guava" version="15.0.0.v201403281430"/>\r
+<unit id="org.objectweb.asm.util" version="5.0.1.v201404251740"/>\r
+<unit id="org.objectweb.asm.xml" version="5.0.1.v201404251740"/>\r
+<unit id="com.google.guava.source" version="15.0.0.v201403281430"/>\r
+<unit id="org.objectweb.asm" version="5.0.1.v201404251740"/>\r
+<unit id="org.objectweb.asm.commons" version="5.0.1.v201404251740"/>\r
+<unit id="org.objectweb.asm.analysis.source" version="5.0.1.v201505121915"/>\r
+<unit id="org.objectweb.asm.commons.source" version="5.0.1.v201404251740"/>\r
+<unit id="org.objectweb.asm.tree.source" version="5.0.1.v201404251740"/>\r
+<unit id="org.objectweb.asm.analysis" version="5.0.1.v201505121915"/>\r
+<unit id="org.objectweb.asm.tree" version="5.0.1.v201404251740"/>\r
+<repository location="http://www.simantics.org/update/tools/orbit/downloads/drops/R20160221192158/repository/"/>\r
+</location>\r
+<location includeAllPlatforms="true" includeConfigurePhase="false" includeMode="slicer" includeSource="true" type="InstallableUnit">\r
+<unit id="org.eclipse.mylyn.wikitext_feature.feature.group" version="2.7.0.v20151015-1452"/>\r
+<unit id="org.eclipse.emf.sdk.feature.group" version="2.11.2.v20160208-0841"/>\r
+<unit id="org.eclipse.epp.mpc.feature.group" version="1.4.2.v20160210-2005"/>\r
+<repository location="http://www.simantics.org/update/mars"/>\r
+</location>\r
+<location includeAllPlatforms="true" includeConfigurePhase="false" includeMode="slicer" includeSource="true" type="InstallableUnit">\r
+<unit id="org.eclipse.ecf.core.ssl.feature.feature.group" version="1.1.0.v20151130-0157"/>\r
+<unit id="org.eclipse.rcp.source.feature.group" version="4.5.2.v20160212-1500"/>\r
+<unit id="org.eclipse.e4.core.tools.feature.feature.group" version="4.5.1.v20160129-0959"/>\r
+<unit id="org.eclipse.ecf.filetransfer.source.feature.feature.group" version="3.12.0.v20151130-0157"/>\r
+<unit id="org.eclipse.ecf.filetransfer.ssl.feature.feature.group" version="1.1.0.v20151130-0157"/>\r
+<unit id="org.eclipse.help.feature.group" version="2.1.2.v20160212-1500"/>\r
+<unit id="org.eclipse.ecf.filetransfer.httpclient4.source.feature.feature.group" version="3.12.0.v20151130-0157"/>\r
+<unit id="org.eclipse.e4.core.tools.feature.source.feature.group" version="4.5.1.v20160129-0959"/>\r
+<unit id="org.eclipse.swt.tools.feature.feature.group" version="3.104.2.v20160128-0900"/>\r
+<unit id="org.eclipse.ecf.filetransfer.httpclient4.feature.feature.group" version="3.12.0.v20151130-0157"/>\r
+<unit id="org.eclipse.ecf.filetransfer.ssl.source.feature.feature.group" version="1.1.0.v20151130-0157"/>\r
+<unit id="org.eclipse.platform.feature.group" version="4.5.2.v20160212-1500"/>\r
+<unit id="org.eclipse.ecf.core.ssl.source.feature.feature.group" version="1.1.0.v20151130-0157"/>\r
+<unit id="org.eclipse.rcp.feature.group" version="4.5.2.v20160212-1500"/>\r
+<unit id="org.eclipse.equinox.p2.discovery.feature.feature.group" version="1.0.300.v20150430-1836"/>\r
+<unit id="org.eclipse.ecf.core.feature.feature.group" version="1.2.0.v20151130-0157"/>\r
+<unit id="org.eclipse.ecf.core.source.feature.feature.group" version="1.2.0.v20151130-0157"/>\r
+<unit id="org.eclipse.equinox.sdk.feature.group" version="3.11.2.v20160202-2102"/>\r
+<unit id="org.eclipse.platform.source.feature.group" version="4.5.2.v20160212-1500"/>\r
+<unit id="org.eclipse.releng.tools.feature.group" version="3.6.0.v20150527-0145"/>\r
+<unit id="org.eclipse.ecf.filetransfer.feature.feature.group" version="3.12.0.v20151130-0157"/>\r
+<unit id="org.eclipse.sdk.ide" version="4.5.2.M20160212-1500"/>\r
+<unit id="org.eclipse.ecf.filetransfer.httpclient4.ssl.feature.feature.group" version="1.1.0.v20151130-0157"/>\r
+<unit id="org.eclipse.help.source.feature.group" version="2.1.2.v20160212-1500"/>\r
+<unit id="org.eclipse.ecf.filetransfer.httpclient4.ssl.source.feature.feature.group" version="1.1.0.v20151130-0157"/>\r
+<repository location="http://www.simantics.org/update/eclipse/updates/4.5"/>\r
+</location>\r
+<location includeAllPlatforms="true" includeConfigurePhase="false" includeMode="slicer" includeSource="true" type="InstallableUnit">\r
+<unit id="org.eclipse.nebula.effects.stw.feature.feature.group" version="1.0.0.201605182147"/>\r
+<unit id="org.eclipse.nebula.visualization.feature.feature.group" version="1.0.0.201605182147"/>\r
+<unit id="org.eclipse.nebula.widgets.calendarcombo.feature.feature.group" version="1.0.0.201605182147"/>\r
+<unit id="org.eclipse.nebula.widgets.gallery.feature.feature.group" version="1.0.0.201605182147"/>\r
+<unit id="org.eclipse.nebula.feature.feature.group" version="1.0.0.201605182147"/>\r
+<unit id="org.eclipse.nebula.cwt.feature.feature.group" version="1.0.0.201605182147"/>\r
+<unit id="org.eclipse.nebula.widgets.oscilloscope.feature.feature.group" version="1.2.0.201605182147"/>\r
+<unit id="org.eclipse.nebula.widgets.pshelf.css.feature.feature.group" version="1.0.0.201605182147"/>\r
+<unit id="org.eclipse.nebula.widgets.ganttchart.feature.feature.group" version="1.0.0.201605182147"/>\r
+<unit id="org.eclipse.nebula.widgets.xviewer.feature.feature.group" version="1.0.0.201605182147"/>\r
+<unit id="org.eclipse.nebula.widgets.compositetable.feature.feature.group" version="1.0.0.201605182147"/>\r
+<unit id="org.eclipse.nebula.widgets.grid.feature.feature.group" version="1.0.0.201605182147"/>\r
+<unit id="org.eclipse.nebula.widgets.cdatetime.feature.feature.group" version="1.0.0.201605182147"/>\r
+<unit id="org.eclipse.nebula.widgets.pshelf.feature.feature.group" version="1.0.0.201605182147"/>\r
+<unit id="org.eclipse.nebula.widgets.richtext.feature.feature.group" version="1.0.0.201605182147"/>\r
+<unit id="org.eclipse.nebula.widgets.tablecombo.feature.feature.group" version="1.0.0.201605182147"/>\r
+<unit id="org.eclipse.nebula.widgets.paperclips.feature.feature.group" version="2.0.0.201605182147"/>\r
+<unit id="org.eclipse.nebula.examples.release.feature.feature.group" version="1.0.4.201605182147"/>\r
+<unit id="org.eclipse.nebula.widgets.pgroup.feature.feature.group" version="1.0.0.201605182147"/>\r
+<repository location="http://www.simantics.org/update/nebula/Q22016/release/"/>\r
+</location>\r
+<location includeAllPlatforms="true" includeConfigurePhase="false" includeMode="slicer" includeSource="true" type="InstallableUnit">\r
+<unit id="org.eclipse.e4.tools.spies.feature.feature.group" version="0.17.0.v20160919-2121"/>\r
+<repository location="http://www.simantics.org/update/e4/snapshots/org.eclipse.e4.tools/latest/"/>\r
+</location>\r
+<location includeAllPlatforms="true" includeConfigurePhase="false" includeMode="slicer" includeSource="true" type="InstallableUnit">\r
+<unit id="org.eclipse.nebula.incubation.feature.feature.group" version="1.0.0.201605182147"/>\r
+<unit id="org.eclipse.nebula.examples.incubation.feature.feature.group" version="1.0.0.201605182147"/>\r
+<repository location="http://www.simantics.org/update/nebula/Q22016/incubation"/>\r
+</location>\r
+<location includeAllPlatforms="true" includeConfigurePhase="false" includeMode="slicer" includeSource="true" type="InstallableUnit">\r
+<unit id="org.eclipse.nebula.widgets.nattable.core.feature.feature.group" version="1.4.0.201606011907"/>\r
+<unit id="org.eclipse.nebula.widgets.nattable.extension.e4.source.feature.feature.group" version="1.0.0.201606011907"/>\r
+<unit id="org.eclipse.nebula.widgets.nattable.extension.poi.feature.feature.group" version="1.4.0.201606011907"/>\r
+<unit id="org.eclipse.nebula.widgets.nattable.extension.glazedlists.feature.feature.group" version="1.4.0.201606011907"/>\r
+<unit id="org.eclipse.nebula.widgets.nattable.core.source.feature.feature.group" version="1.4.0.201606011907"/>\r
+<unit id="org.eclipse.nebula.widgets.nattable.extension.glazedlists.source.feature.feature.group" version="1.4.0.201606011907"/>\r
+<unit id="org.eclipse.nebula.widgets.nattable.extension.nebula.feature.feature.group" version="1.0.0.201606011907"/>\r
+<unit id="org.eclipse.nebula.widgets.nattable.extension.e4.feature.feature.group" version="1.0.0.201606011907"/>\r
+<unit id="org.eclipse.nebula.widgets.nattable.extension.nebula.source.feature.feature.group" version="1.0.0.201606011907"/>\r
+<unit id="org.eclipse.nebula.widgets.nattable.extension.poi.source.feature.feature.group" version="1.4.0.201606011907"/>\r
+<repository location="http://www.simantics.org/update/nebula/nattable/releases/1.4.0/repository/"/>\r
+</location>\r
+<location includeAllPlatforms="true" includeConfigurePhase="false" includeMode="slicer" includeSource="true" type="InstallableUnit">\r
+<unit id="ch.qos.logback.classic" version="1.1.7"/>\r
+<unit id="ch.qos.logback.classic.source" version="1.1.7"/>\r
+<unit id="ch.qos.logback.core" version="1.1.7"/>\r
+<unit id="ch.qos.logback.core.source" version="1.1.7"/>\r
+<unit id="com.fasterxml.jackson.core.jackson-annotations" version="2.8.0"/>\r
+<unit id="com.fasterxml.jackson.core.jackson-annotations.source" version="2.8.0"/>\r
+<unit id="com.fasterxml.jackson.core.jackson-core" version="2.8.5"/>\r
+<unit id="com.fasterxml.jackson.core.jackson-core.source" version="2.8.5"/>\r
+<unit id="com.fasterxml.jackson.core.jackson-databind" version="2.8.5"/>\r
+<unit id="com.fasterxml.jackson.core.jackson-databind.source" version="2.8.5"/>\r
+<unit id="com.fasterxml.jackson.dataformat.jackson-dataformat-csv" version="2.8.5"/>\r
+<unit id="com.fasterxml.jackson.dataformat.jackson-dataformat-csv.source" version="2.8.5"/>\r
+<unit id="com.fasterxml.jackson.dataformat.jackson-dataformat-xml" version="2.8.5"/>\r
+<unit id="com.fasterxml.jackson.dataformat.jackson-dataformat-xml.source" version="2.8.5"/>\r
+<unit id="com.fasterxml.jackson.module.jackson-module-jaxb-annotations" version="2.8.5"/>\r
+<unit id="com.fasterxml.jackson.module.jackson-module-jaxb-annotations.source" version="2.8.5"/>\r
+<unit id="com.fasterxml.woodstox.woodstox-core" version="5.0.3"/>\r
+<unit id="com.fasterxml.woodstox.woodstox-core.source" version="5.0.3"/>\r
+<unit id="com.github.virtuald.curvesapi" version="1.4.0"/>\r
+<unit id="com.github.virtuald.curvesapi.source" version="1.4.0"/>\r
+<unit id="com.healthmarketscience.jackcess" version="2.1.3"/>\r
+<unit id="com.healthmarketscience.jackcess.source" version="2.1.3"/>\r
+<unit id="com.koloboke.api-jdk8" version="1.0.0"/>\r
+<unit id="com.koloboke.api-jdk8.source" version="1.0.0"/>\r
+<unit id="com.koloboke.compile" version="0.5.1"/>\r
+<unit id="com.koloboke.compile.source" version="0.5.1"/>\r
+<unit id="com.koloboke.impl-common-jdk8" version="1.0.0"/>\r
+<unit id="com.koloboke.impl-common-jdk8.source" version="1.0.0"/>\r
+<unit id="com.lowagie.text" version="2.1.7.b1"/>\r
+<unit id="com.lowagie.text.source" version="2.1.7.b1"/>\r
+<unit id="com.sun.jna" version="4.2.2"/>\r
+<unit id="com.sun.jna.source" version="4.2.2"/>\r
+<unit id="com.sun.jna.platform" version="4.2.2"/>\r
+<unit id="com.sun.jna.platform.source" version="4.2.2"/>\r
+<unit id="freemarker" version="2.3.23.stable"/>\r
+<unit id="freemarker.source" version="2.3.23.stable"/>\r
+<unit id="gnu.trove2" version="2.1.0"/>\r
+<unit id="gnu.trove2.source" version="2.1.0"/>\r
+<unit id="gnu.trove3" version="3.0.3"/>\r
+<unit id="gnu.trove3.source" version="3.0.3"/>\r
+<unit id="it.unimi.dsi.fastutil" version="7.0.13"/>\r
+<unit id="it.unimi.dsi.fastutil.source" version="7.0.13"/>\r
+<unit id="jakarta-regexp" version="1.4.0"/>\r
+<unit id="javax.vecmath" version="1.5.2"/>\r
+<unit id="net.jcip.annotations" version="1.0.0"/>\r
+<unit id="net.jcip.annotations.source" version="1.0.0"/>\r
+<unit id="net.ucanaccess" version="3.0.7"/>\r
+<unit id="net.ucanaccess.source" version="3.0.7"/>\r
+<unit id="org.antlr.runtime" version="3.5.2"/>\r
+<unit id="org.antlr.runtime.source" version="3.5.2"/>\r
+<unit id="org.apache.log4j" version="1.2.17"/>\r
+<unit id="org.apache.log4j.source" version="1.2.17"/>\r
+<unit id="org.apache.commons.codec" version="1.10.0"/>\r
+<unit id="org.apache.commons.codec.source" version="1.10.0"/>\r
+<unit id="org.apache.commons.collections" version="3.2.2"/>\r
+<unit id="org.apache.commons.collections.source" version="3.2.2"/>\r
+<unit id="org.apache.commons.collections4" version="4.1.0"/>\r
+<unit id="org.apache.commons.collections4.source" version="4.1.0"/>\r
+<unit id="org.apache.commons.compress" version="1.12.0"/>\r
+<unit id="org.apache.commons.compress.source" version="1.12.0"/>\r
+<unit id="org.apache.commons.logging" version="1.2.0"/>\r
+<unit id="org.apache.commons.logging.source" version="1.2.0"/>\r
+<unit id="org.apache.commons.io" version="1.4.0"/>\r
+<unit id="org.apache.commons.io.source" version="1.4.0"/>\r
+<unit id="org.apache.commons.lang" version="2.6.0"/>\r
+<unit id="org.apache.commons.lang.source" version="2.6.0"/>\r
+<unit id="org.apache.lucene4.analyzers-common" version="4.9.0.b0003"/>\r
+<unit id="org.apache.lucene4.analyzers-common.source" version="4.9.0.b0003"/>\r
+<unit id="org.apache.lucene4.core" version="4.9.0.b0003"/>\r
+<unit id="org.apache.lucene4.core.source" version="4.9.0.b0003"/>\r
+<unit id="org.apache.lucene4.queryparser" version="4.9.0.b0003"/>\r
+<unit id="org.apache.lucene4.queryparser.source" version="4.9.0.b0003"/>\r
+<unit id="org.apache.lucene4.sandbox" version="4.9.0.b0003"/>\r
+<unit id="org.apache.lucene4.sandbox.source" version="4.9.0.b0003"/>\r
+<unit id="org.apache.lucene4.queries" version="4.9.0.b0003"/>\r
+<unit id="org.apache.lucene4.queries.source" version="4.9.0.b0003"/>\r
+<unit id="org.apache.pdfbox" version="2.0.3"/>\r
+<unit id="org.apache.pdfbox.source" version="2.0.3"/>\r
+<unit id="org.apache.pdfbox.xmpbox" version="2.0.3"/>\r
+<unit id="org.apache.pdfbox.xmpbox.source" version="2.0.3"/>\r
+<unit id="org.apache.pdfbox.fontbox" version="2.0.3"/>\r
+<unit id="org.apache.pdfbox.fontbox.source" version="2.0.3"/>\r
+<unit id="org.apache.xmlbeans" version="2.6.0"/>\r
+<unit id="org.eclipse.collections.eclipse-collections-api" version="7.1.0"/>\r
+<unit id="org.eclipse.collections.eclipse-collections-api.source" version="7.1.0"/>\r
+<unit id="org.eclipse.collections.eclipse-collections" version="7.1.0"/>\r
+<unit id="org.eclipse.collections.eclipse-collections.source" version="7.1.0"/>\r
+<unit id="org.hsqldb.hsqldb" version="2.3.1"/>\r
+<unit id="org.hsqldb.hsqldb.source" version="2.3.1"/>\r
+<unit id="org.jdom2" version="2.0.6"/>\r
+<unit id="org.jdom2.source" version="2.0.6"/>\r
+<unit id="org.jfree.jchart" version="1.0.19"/>\r
+<unit id="org.jfree.jchart.source" version="1.0.19"/>\r
+<unit id="org.jfree.jcommon" version="1.0.23"/>\r
+<unit id="org.jfree.jcommon.source" version="1.0.23"/>\r
+<unit id="org.mozilla.rhino" version="1.7.7.1"/>\r
+<unit id="org.mozilla.rhino.source" version="1.7.7.1"/>\r
+<unit id="org.supercsv" version="2.4.0"/>\r
+<unit id="org.supercsv.source" version="2.4.0"/>\r
+<unit id="bouncycastle.bcprov-jdk14" version="138.0.0"/>\r
+<unit id="bouncycastle.bcmail-jdk14" version="138.0.0"/>\r
+<unit id="org.bouncycastle.bcprov-jdk14" version="1.38.0"/>\r
+<unit id="org.bouncycastle.bcprov-jdk14.source" version="1.38.0"/>\r
+<unit id="org.bouncycastle.bcmail-jdk14" version="1.38.0"/>\r
+<unit id="org.bouncycastle.bcmail-jdk14.source" version="1.38.0"/>\r
+<unit id="org.bouncycastle.bctsp-jdk14" version="1.38.0"/>\r
+<unit id="org.bouncycastle.bctsp-jdk14.source" version="1.38.0"/>\r
+<unit id="org.ini4j" version="0.5.4"/>\r
+<unit id="org.ini4j.source" version="0.5.4"/>\r
+<unit id="org.slf4j.api" version="1.7.20"/>\r
+<unit id="org.slf4j.api.source" version="1.7.20"/>\r
+<unit id="stax2-api" version="3.1.4"/>\r
+<unit id="stax2-api.source" version="3.1.4"/>\r
+<repository location="http://www.simantics.org/download/master/external-components/maven"/>\r
+</location>\r
+<location includeAllPlatforms="true" includeConfigurePhase="false" includeMode="slicer" includeSource="true" type="InstallableUnit">\r
+<unit id="org.apache.poi.feature.feature.group" version="3.15.0.b0002"/>\r
+<unit id="org.apache.batik" version="1.8.0.201611220734"/>\r
+<repository location="http://www.simantics.org/download/master/external-components/manual"/>\r
+</location>\r
+</locations>\r
+</target>\r
<?xml version="1.0" encoding="UTF-8"?>\r
<site>\r
- <feature url="features/org.simantics.sdk_1.25.0.jar" id="org.simantics.sdk" version="1.25.0">\r
+ <feature id="org.simantics.sdk">\r
+ <category name="org.simantics.target"/>\r
+ </feature>\r
+ <feature id="org.simantics.sdk.source">\r
<category name="org.simantics.target"/>\r
</feature>\r
<category-def name="org.simantics.target" label="Simantics Target">\r
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
<modelVersion>4.0.0</modelVersion>\r
<artifactId>org.simantics.sdk.repository</artifactId>\r
- <version>1.25.0-SNAPSHOT</version>\r
+ <version>1.26.0-SNAPSHOT</version>\r
<packaging>eclipse-repository</packaging>\r
\r
<parent>\r
+++ /dev/null
-member:ng8YuO16fR2C.
-anonymous:G2JhW8U3GQYUU
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>\r
-<projectDescription>\r
- <name>org.simantics.target</name>\r
- <comment></comment>\r
- <projects>\r
- </projects>\r
- <buildSpec>\r
- </buildSpec>\r
- <natures>\r
- </natures>\r
-</projectDescription>\r
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>\r
-<rmap xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.eclipse.org/buckminster/RMap-1.0"\r
- xmlns:bc="http://www.eclipse.org/buckminster/Common-1.0" xmlns:pv="http://www.eclipse.org/buckminster/Provider-1.0">\r
-\r
- <property key="REPOS"\r
- value="https://{1}:{2}@www.simantics.org/svn/simantics" />\r
- <property key="INCUBATOR"\r
- value="https://{1}:{2}@www.simantics.org/svn/simantics-incubator" />\r
-\r
- <searchPath name="modelica">\r
- <provider readerType="svn" componentTypes="eclipse.feature" mutable="true" source="true">\r
- <uri\r
- format="${REPOS}/modelica/trunk/{0}.feature?moduleAfterTag&moduleAfterBranch">\r
- <bc:propertyRef key="buckminster.component" />\r
- <bc:propertyRef key="simantics.user" />\r
- <bc:propertyRef key="simantics.password" />\r
- </uri>\r
- </provider>\r
- <provider readerType="svn" componentTypes="osgi.bundle" mutable="true" source="true">\r
- <uri format="${REPOS}/modelica/trunk/{0}?moduleAfterTag&moduleAfterBranch">\r
- <bc:propertyRef key="buckminster.component" />\r
- <bc:propertyRef key="simantics.user" />\r
- <bc:propertyRef key="simantics.password" />\r
- </uri>\r
- </provider>\r
- </searchPath>\r
-\r
- <locator searchPathRef="modelica" pattern="^org\.simantics\.modelica" />\r
-\r
- <redirect href="SDK.rmap" /> \r
-\r
-</rmap>\r
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<rmap
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns="http://www.eclipse.org/buckminster/RMap-1.0"
- xmlns:bc="http://www.eclipse.org/buckminster/Common-1.0"
- xmlns:pv="http://www.eclipse.org/buckminster/Provider-1.0">
-
- <property key="SIMANTICS" value="https://{1}:{2}@www.simantics.org/svn/simantics"/>
-
- <searchPath name="2d">
- <provider readerType="svn" componentTypes="eclipse.feature" mutable="true" source="true">
- <uri format="${SIMANTICS}/2d/trunk/{0}.feature?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- <provider readerType="svn" componentTypes="osgi.bundle" mutable="true" source="true">
- <uri format="${SIMANTICS}/2d/trunk/{0}?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- </searchPath>
-
- <searchPath name="3d">
- <provider readerType="svn" componentTypes="eclipse.feature" mutable="true" source="true">
- <uri format="${SIMANTICS}/3d/trunk/{0}.feature?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- <provider readerType="svn" componentTypes="osgi.bundle" mutable="true" source="true">
- <uri format="${SIMANTICS}/3d/trunk/{0}?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- </searchPath>
-
- <searchPath name="agent">
- <provider readerType="svn" componentTypes="osgi.bundle" mutable="true" source="true">
- <uri format="${SIMANTICS}/agent/trunk/{0}?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- </searchPath>
-
- <searchPath name="desktop">
- <provider readerType="svn" componentTypes="eclipse.feature" mutable="true" source="true">
- <uri format="${SIMANTICS}/desktop/trunk/{0}.feature?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- <provider readerType="svn" componentTypes="osgi.bundle" mutable="true" source="true">
- <uri format="${SIMANTICS}/desktop/trunk/{0}?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- </searchPath>
-
- <searchPath name="db">
- <provider readerType="svn" componentTypes="eclipse.feature" mutable="true" source="true">
- <uri format="${SIMANTICS}/db/trunk/{0}.feature?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- <provider readerType="svn" componentTypes="osgi.bundle" mutable="true" source="true">
- <uri format="${SIMANTICS}/db/trunk/{0}?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- </searchPath>
-
- <searchPath name="documentation">
- <provider readerType="svn" componentTypes="eclipse.feature" mutable="true" source="true">
- <uri format="${SIMANTICS}/documentation/trunk/{0}.feature?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- <provider readerType="svn" componentTypes="osgi.bundle" mutable="true" source="true">
- <uri format="${SIMANTICS}/documentation/trunk/{0}?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- </searchPath>
-
- <searchPath name="foundation">
- <provider readerType="svn" componentTypes="eclipse.feature" mutable="true" source="true">
- <uri format="${SIMANTICS}/foundation/trunk/{0}.feature?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- <provider readerType="svn" componentTypes="osgi.bundle" mutable="true" source="true">
- <uri format="${SIMANTICS}/foundation/trunk/{0}?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- </searchPath>
-
- <searchPath name="foundation/base">
- <provider readerType="svn" componentTypes="eclipse.feature" mutable="true" source="true">
- <uri format="${SIMANTICS}/foundation/base/trunk/{0}.feature?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- <provider readerType="svn" componentTypes="osgi.bundle" mutable="true" source="true">
- <uri format="${SIMANTICS}/foundation/base/trunk/{0}?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- </searchPath>
-
- <searchPath name="foundation/breakdown">
- <provider readerType="svn" componentTypes="eclipse.feature" mutable="true" source="true">
- <uri format="${SIMANTICS}/foundation/breakdown/trunk/{0}.feature?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- <provider readerType="svn" componentTypes="osgi.bundle" mutable="true" source="true">
- <uri format="${SIMANTICS}/foundation/breakdown/trunk/{0}?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- </searchPath>
-
- <searchPath name="foundation/browsing">
- <provider readerType="svn" componentTypes="eclipse.feature" mutable="true" source="true">
- <uri format="${SIMANTICS}/foundation/browsing/trunk/{0}.feature?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- <provider readerType="svn" componentTypes="osgi.bundle" mutable="true" source="true">
- <uri format="${SIMANTICS}/foundation/browsing/trunk/{0}?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- </searchPath>
-
- <searchPath name="foundation/charts">
- <provider readerType="svn" componentTypes="eclipse.feature" mutable="true" source="true">
- <uri format="${SIMANTICS}/foundation/charts/trunk/{0}.feature?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- <provider readerType="svn" componentTypes="osgi.bundle" mutable="true" source="true">
- <uri format="${SIMANTICS}/foundation/charts/trunk/{0}?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- </searchPath>
-
- <searchPath name="foundation/databoard">
- <provider readerType="svn" componentTypes="eclipse.feature" mutable="true" source="true">
- <uri format="${SIMANTICS}/foundation/databoard/trunk/{0}.feature?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- <provider readerType="svn" componentTypes="osgi.bundle" mutable="true" source="true">
- <uri format="${SIMANTICS}/foundation/databoard/trunk/{0}?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- </searchPath>
-
- <searchPath name="foundation/devs">
- <provider readerType="svn" componentTypes="eclipse.feature" mutable="true" source="true">
- <uri format="${SIMANTICS}/foundation/devs/trunk/{0}.feature?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- <provider readerType="svn" componentTypes="osgi.bundle" mutable="true" source="true">
- <uri format="${SIMANTICS}/foundation/devs/trunk/{0}?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- </searchPath>
-
- <searchPath name="foundation/document">
- <provider readerType="svn" componentTypes="eclipse.feature" mutable="true" source="true">
- <uri format="${SIMANTICS}/foundation/document/trunk/{0}.feature?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- <provider readerType="svn" componentTypes="osgi.bundle" mutable="true" source="true">
- <uri format="${SIMANTICS}/foundation/document/trunk/{0}?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- </searchPath>
-
- <searchPath name="foundation/event">
- <provider readerType="svn" componentTypes="eclipse.feature" mutable="true" source="true">
- <uri format="${SIMANTICS}/foundation/event/trunk/{0}.feature?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- <provider readerType="svn" componentTypes="osgi.bundle" mutable="true" source="true">
- <uri format="${SIMANTICS}/foundation/event/trunk/{0}?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- </searchPath>
-
- <searchPath name="foundation/graphfile">
- <provider readerType="svn" componentTypes="eclipse.feature" mutable="true" source="true">
- <uri format="${SIMANTICS}/foundation/graphfile/trunk/{0}.feature?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- <provider readerType="svn" componentTypes="osgi.bundle" mutable="true" source="true">
- <uri format="${SIMANTICS}/foundation/graphfile/trunk/{0}?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- </searchPath>
-
- <searchPath name="foundation/message">
- <provider readerType="svn" componentTypes="eclipse.feature" mutable="true" source="true">
- <uri format="${SIMANTICS}/foundation/message/trunk/{0}.feature?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- <provider readerType="svn" componentTypes="osgi.bundle" mutable="true" source="true">
- <uri format="${SIMANTICS}/foundation/message/trunk/{0}?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- </searchPath>
-
- <searchPath name="foundation/migration">
- <provider readerType="svn" componentTypes="eclipse.feature" mutable="true" source="true">
- <uri format="${SIMANTICS}/foundation/migration/trunk/{0}.feature?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- <provider readerType="svn" componentTypes="osgi.bundle" mutable="true" source="true">
- <uri format="${SIMANTICS}/foundation/migration/trunk/{0}?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- </searchPath>
-
- <searchPath name="foundation/project">
- <provider readerType="svn" componentTypes="eclipse.feature" mutable="true" source="true">
- <uri format="${SIMANTICS}/foundation/project/trunk/{0}.feature?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- <provider readerType="svn" componentTypes="osgi.bundle" mutable="true" source="true">
- <uri format="${SIMANTICS}/foundation/project/trunk/{0}?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- </searchPath>
-
- <searchPath name="foundation/ontologies">
- <provider readerType="svn" componentTypes="osgi.bundle" mutable="true" source="true">
- <uri format="${SIMANTICS}/foundation/ontologies/trunk/{0}?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- </searchPath>
-
- <searchPath name="foundation/team">
- <provider readerType="svn" componentTypes="eclipse.feature" mutable="true" source="true">
- <uri format="${SIMANTICS}/foundation/team/trunk/{0}.feature?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- <provider readerType="svn" componentTypes="osgi.bundle" mutable="true" source="true">
- <uri format="${SIMANTICS}/foundation/team/trunk/{0}?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- </searchPath>
-
- <searchPath name="foundation/views">
- <provider readerType="svn" componentTypes="eclipse.feature" mutable="true" source="true">
- <uri format="${SIMANTICS}/foundation/views/trunk/{0}.feature?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- <provider readerType="svn" componentTypes="osgi.bundle" mutable="true" source="true">
- <uri format="${SIMANTICS}/foundation/views/trunk/{0}?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- </searchPath>
-
- <searchPath name="issues">
- <provider readerType="svn" componentTypes="eclipse.feature" mutable="true" source="true">
- <uri format="${SIMANTICS}/issues/trunk/{0}.feature?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- <provider readerType="svn" componentTypes="osgi.bundle" mutable="true" source="true">
- <uri format="${SIMANTICS}/issues/trunk/{0}?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- </searchPath>
-
- <searchPath name="modeling">
- <provider readerType="svn" componentTypes="eclipse.feature" mutable="true" source="true">
- <uri format="${SIMANTICS}/modeling/trunk/{0}.feature?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- <provider readerType="svn" componentTypes="osgi.bundle" mutable="true" source="true">
- <uri format="${SIMANTICS}/modeling/trunk/{0}?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- </searchPath>
-
- <searchPath name="ode">
- <provider readerType="svn" componentTypes="eclipse.feature" mutable="true" source="true">
- <uri format="${SIMANTICS}/ode/trunk/{0}.feature?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- <provider readerType="svn" componentTypes="osgi.bundle" mutable="true" source="true">
- <uri format="${SIMANTICS}/ode/trunk/{0}?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- </searchPath>
-
- <searchPath name="operating">
- <provider readerType="svn" componentTypes="eclipse.feature" mutable="true" source="true">
- <uri format="${SIMANTICS}/operating/trunk/{0}.feature?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- <provider readerType="svn" componentTypes="osgi.bundle" mutable="true" source="true">
- <uri format="${SIMANTICS}/operating/trunk/{0}?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- </searchPath>
-
- <searchPath name="project">
- <provider readerType="svn" componentTypes="eclipse.feature" mutable="true" source="true">
- <uri format="${SIMANTICS}/project/trunk/{0}.feature?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- <provider readerType="svn" componentTypes="osgi.bundle" mutable="true" source="true">
- <uri format="${SIMANTICS}/project/trunk/{0}?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- </searchPath>
-
- <searchPath name="scl">
- <provider readerType="svn" componentTypes="eclipse.feature" mutable="true" source="true">
- <uri format="${SIMANTICS}/scl/trunk/{0}.feature?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- <provider readerType="svn" componentTypes="osgi.bundle" mutable="true" source="true">
- <uri format="${SIMANTICS}/scl/trunk/{0}?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- </searchPath>
-
- <searchPath name="spreadsheet">
- <provider readerType="svn" componentTypes="eclipse.feature" mutable="true" source="true">
- <uri format="${SIMANTICS}/spreadsheet/trunk/{0}.feature?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- <provider readerType="svn" componentTypes="osgi.bundle" mutable="true" source="true">
- <uri format="${SIMANTICS}/spreadsheet/trunk/{0}?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- </searchPath>
-
- <searchPath name="third-party">
- <provider readerType="svn" componentTypes="eclipse.feature" mutable="true" source="true">
- <uri format="${SIMANTICS}/third-party/trunk/{0}.feature?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- <provider readerType="svn" componentTypes="osgi.bundle" mutable="true" source="true">
- <uri format="${SIMANTICS}/third-party/trunk/{0}?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- </searchPath>
-
- <searchPath name="utils">
- <provider readerType="svn" componentTypes="eclipse.feature" mutable="true" source="true">
- <uri format="${SIMANTICS}/utils/trunk/{0}.feature?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- <provider readerType="svn" componentTypes="osgi.bundle" mutable="true" source="true">
- <uri format="${SIMANTICS}/utils/trunk/{0}?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- </searchPath>
-
- <searchPath name="utils/optimization">
- <provider readerType="svn" componentTypes="eclipse.feature" mutable="true" source="true">
- <uri format="${SIMANTICS}/utils/optimization/trunk/{0}.feature?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- <provider readerType="svn" componentTypes="osgi.bundle" mutable="true" source="true">
- <uri format="${SIMANTICS}/utils/optimization/trunk/{0}?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- </searchPath>
-
- <searchPath name="wiki">
- <provider readerType="svn" componentTypes="eclipse.feature" mutable="true" source="true">
- <uri format="${SIMANTICS}/wiki/trunk/{0}.feature?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- <provider readerType="svn" componentTypes="osgi.bundle" mutable="true" source="true">
- <uri format="${SIMANTICS}/wiki/trunk/{0}?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- </searchPath>
-
- <searchPath name="workbench">
- <provider readerType="svn" componentTypes="eclipse.feature" mutable="true" source="true">
- <uri format="${SIMANTICS}/workbench/trunk/{0}.feature?moduleAfterBranch&moduleAfterTag">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- <provider readerType="svn" componentTypes="osgi.bundle" mutable="true" source="true">
- <uri format="${SIMANTICS}/workbench/trunk/{0}?moduleAfterBranch&moduleAfterTag">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- </searchPath>
-
- <!-- Personal development locations -->
-
- <!--
- <searchPath name="hannu">
- <provider readerType="svn" componentTypes="osgi.bundle" mutable="true" source="true">
- <uri format="${SIMANTICS}-incubator/hannu/{0}">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- </searchPath>
- -->
-
- <!-- Locators -->
- <locator searchPathRef="foundation/document" pattern="^org\.simantics\.document\.base\.ontology$"/>
- <!-- This resolves org.simantics.layer0 PLUG-IN, FEATURE is resolved later, do not fail on error -->
- <locator searchPathRef="foundation/ontologies" pattern="^org\.simantics\.layer0$" failOnError="false"/>
- <locator searchPathRef="foundation/ontologies" pattern="^org\.simantics\.([^\.]+\.)+ontology$" failOnError="false"/>
-
- <locator searchPathRef="2d" pattern="^net\.sf\.cglib"/>
- <locator searchPathRef="2d" pattern="^org\.simantics\.g2d"/>
- <locator searchPathRef="2d" pattern="^org\.simantics\.diagram" failOnError="false"/>
- <locator searchPathRef="2d" pattern="^org\.simantics\.scenegraph"/>
- <locator searchPathRef="3d" pattern="^org\.simantics\.g3d"/>
- <locator searchPathRef="3d" pattern="^org\.simantics\.objmap2"/>
- <locator searchPathRef="3d" pattern="^org\.simantics\.opencascade"/>
- <locator searchPathRef="agent" pattern="^org\.simantics\.agent"/>
- <locator searchPathRef="db" pattern="^org\.simantics\.db"/>
- <locator searchPathRef="db" pattern="^org\.simantics\.datatypes"/>
- <locator searchPathRef="db" pattern="^org\.simantics\.layer0.utils$"/>
- <!-- This resolves org.simantics.layer0 FEATURE, PLUG-IN should already be resolved earlier -->
- <locator searchPathRef="db" pattern="^org\.simantics\.layer0$"/>
- <locator searchPathRef="desktop" pattern="^org\.simantics\.desktop"/>
- <locator searchPathRef="foundation/base" pattern="^org\.simantics\.common$"/>
- <locator searchPathRef="foundation/base" pattern="^org\.simantics$"/>
- <locator searchPathRef="foundation/base" pattern="^org\.simantics\.export"/>
- <locator searchPathRef="foundation/breakdown" pattern="^org\.simantics\.breakdown"/>
- <locator searchPathRef="foundation/browsing" pattern="^org\.simantics\.browsing"/>
- <locator searchPathRef="foundation/browsing" pattern="^org\.simantics\.selectionview"/>
- <locator searchPathRef="foundation/charts" pattern="^org\.simantics\.charts"/>
- <locator searchPathRef="foundation/charts" pattern="^org\.simantics\.trend"/>
- <locator searchPathRef="foundation/databoard" pattern="^org\.simantics\.data"/>
- <locator searchPathRef="foundation/databoard" pattern="^org\.simantics\.databoard"/>
- <locator searchPathRef="foundation/devs" pattern="^org\.simantics\.devs"/>
- <locator searchPathRef="foundation/document" pattern="^org\.simantics\.document"/>
- <locator searchPathRef="foundation/event" pattern="^org\.simantics\.event"/>
- <locator searchPathRef="foundation/graphfile" pattern="^org\.simantics\.graphfile"/>
- <locator searchPathRef="foundation/message" pattern="^org\.simantics\.message"/>
- <locator searchPathRef="foundation/migration" pattern="^org\.simantics\.migration"/>
- <locator searchPathRef="foundation/project" pattern="^org\.simantics\.project" failOnError="false"/>
- <locator searchPathRef="foundation/team" pattern="^org\.simantics\.team"/>
- <locator searchPathRef="foundation/views" pattern="^org\.simantics\.views"/>
- <locator searchPathRef="issues" pattern="^org\.simantics\.issues"/>
- <locator searchPathRef="modeling" pattern="^org\.simantics\.annotation"/>
- <locator searchPathRef="modeling" pattern="^org\.simantics\.image"/>
- <locator searchPathRef="modeling" pattern="^org\.simantics\.mapping"/>
- <locator searchPathRef="modeling" pattern="^org\.simantics\.modeling"/>
- <locator searchPathRef="modeling" pattern="^org\.simantics\.structural" failOnError="false"/>
- <locator searchPathRef="ode" pattern="^org\.simantics\.graph$"/>
- <locator searchPathRef="ode" pattern="^org\.simantics\.graph\."/>
- <locator searchPathRef="ode" pattern="^org\.simantics\.ltk"/>
- <locator searchPathRef="ode" pattern="^org\.simantics\.ode"/>
- <locator searchPathRef="operating" pattern="^org\.simantics\.operating"/>
- <locator searchPathRef="project" pattern="^org\.simantics\.project"/>
- <locator searchPathRef="scl" pattern="^org\.cojen"/>
- <locator searchPathRef="scl" pattern="^org\.simantics\.scl"/>
- <locator searchPathRef="spreadsheet" pattern="^org\.simantics\.spreadsheet"/>
- <locator searchPathRef="spreadsheet" pattern="^org\.simantics\.excel"/>
- <locator searchPathRef="third-party" pattern="^xtc\.parser\.runtime"/>
- <locator searchPathRef="third-party" pattern="^org\.lobobrowser\.cobra"/>
- <locator searchPathRef="third-party" pattern="^org\.ini4j"/>
- <locator searchPathRef="third-party" pattern="^org\.objectweb\.asm5"/>
- <locator searchPathRef="third-party" pattern="^it\.unimi\.dsi\.fastutil"/>
- <locator searchPathRef="third-party" pattern="^winterwell\.markdown"/>
- <locator searchPathRef="utils" pattern="^org\.simantics\.eclipsec"/>
- <locator searchPathRef="utils" pattern="^org\.simantics\.backup"/>
- <locator searchPathRef="utils" pattern="^org\.simantics\.basicexpression"/>
- <locator searchPathRef="utils" pattern="^org\.simantics\.fastlz"/>
- <locator searchPathRef="utils" pattern="^org\.simantics\.compressions"/>
- <locator searchPathRef="utils" pattern="^org\.simantics\.fileimport"/>
- <locator searchPathRef="utils" pattern="^org\.simantics\.lz4"/>
- <locator searchPathRef="utils" pattern="^org\.simantics\.gnuplot"/>
- <locator searchPathRef="utils" pattern="^org\.simantics\.graphviz"/>
- <locator searchPathRef="utils" pattern="^org\.simantics\.msvc\.runtime"/>
- <locator searchPathRef="utils" pattern="^org\.simantics\.nativemem"/>
- <locator searchPathRef="utils" pattern="^org\.simantics\.utils"/>
- <locator searchPathRef="utils" pattern="^net\.jpountz\.lz4$"/>
- <locator searchPathRef="utils/optimization" pattern="^org\.simantics\.newuoa$"/>
- <locator searchPathRef="utils/optimization" pattern="^org\.simantics\.optimization$"/>
- <locator searchPathRef="wiki" pattern="^org\.simantics\.wiki"/>
- <locator searchPathRef="workbench" pattern="^org\.simantics\.sdk"/>
- <locator searchPathRef="workbench" pattern="^org\.simantics\.workbench"/>
-
- <locator searchPathRef="documentation" pattern="^org\.simantics\.foundation\.doc"/>
- <locator searchPathRef="documentation" pattern="^org\.simantics\.doc\.isv"/>
-
- <!-- Fallback locations (no pattern) -->
- <locator searchPathRef="foundation" failOnError="false"/>
-
- <searchPath name="eclipse-nebula">
- <provider readerType="p2" componentTypes="osgi.bundle,eclipse.feature" mutable="false" source="true">
- <uri format="http://www.simantics.org/update/nebula/Q22016/release" />
- </provider>
- </searchPath>
- <searchPath name="eclipse-nebula-incubation">
- <provider readerType="p2" componentTypes="osgi.bundle,eclipse.feature" mutable="false" source="true">
- <uri format="http://www.simantics.org/update/nebula/Q22016/incubation" />
- </provider>
- </searchPath>
- <searchPath name="eclipse-nebula-nattable">
- <provider readerType="p2" componentTypes="osgi.bundle,eclipse.feature" mutable="false" source="true">
- <uri format="http://www.simantics.org/update/nebula/nattable/releases/1.4.0/repository" />
- </provider>
- </searchPath>
-
- <locator searchPathRef="third-party" pattern="^org\.apache\.commons\.lang" failOnError="false" />
- <locator searchPathRef="third-party" pattern="^org\.apache\.commons\.compress" failOnError="false" />
- <locator searchPathRef="third-party" pattern="^org\.apache\.poi" failOnError="false" />
- <locator searchPathRef="third-party" pattern="^org\.eclipse\.nebula\.widgets\.nattable" failOnError="false" />
- <locator searchPathRef="third-party" pattern="^org\.jdom2" failOnError="false" />
- <locator searchPathRef="third-party" pattern="^net\.ucanaccess" failOnError="false" />
- <locator searchPathRef="eclipse-nebula" pattern="^org\.eclipse\.nebula" failOnError="false" />
- <locator searchPathRef="eclipse-nebula-incubation" pattern="^org\.eclipse\.nebula" failOnError="false" />
- <locator searchPathRef="eclipse-nebula-nattable" pattern="^org\.eclipse\.nebula" failOnError="false" />
-
-</rmap>
-
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<rmap xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.eclipse.org/buckminster/RMap-1.0"
- xmlns:bc="http://www.eclipse.org/buckminster/Common-1.0" xmlns:pv="http://www.eclipse.org/buckminster/Provider-1.0">
-
- <redirect href="SDK.rmap" pattern="^org\.apache" />
- <redirect href="SDK.rmap" pattern="^org\.cojen" />
- <redirect href="SDK.rmap" pattern="^org\.jdom2" />
- <redirect href="SDK.rmap" pattern="^org\.lobobrowser.cobra" />
- <redirect href="SDK.rmap" pattern="^org\.simantics" />
- <redirect href="SDK.rmap" pattern="^org\.eclipse\.nebula" />
- <redirect href="SDK.rmap" pattern="^org\.ini4j" />
- <redirect href="SDK.rmap" pattern="^org\.objectweb\.asm5"/>
- <redirect href="SDK.rmap" pattern="^net\.jpountz\.lz4" />
- <redirect href="SDK.rmap" pattern="^winterwell\.markdown" />
-
- <searchPath name="eclipse">
- <provider readerType="p2" componentTypes="osgi.bundle,eclipse.feature" mutable="false" source="true">
- <uri format="http://download.eclipse.org/eclipse/updates/4.5" />
- </provider>
- <provider readerType="p2" componentTypes="osgi.bundle,eclipse.feature" mutable="false" source="true">
- <uri format="http://download.eclipse.org/releases/mars" />
- </provider>
- </searchPath>
-
- <locator searchPathRef="eclipse" />
-
-</rmap>
-
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<rmap xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.eclipse.org/buckminster/RMap-1.0"
- xmlns:bc="http://www.eclipse.org/buckminster/Common-1.0" xmlns:pv="http://www.eclipse.org/buckminster/Provider-1.0">
-
- <property key="SIMANTICS" value="https://{1}:{2}@www.simantics.org/svn/simantics" />
-
- <searchPath name="sysdyn">
- <provider readerType="svn" componentTypes="eclipse.feature" mutable="true" source="true">
- <uri format="${SIMANTICS}/sysdyn/trunk/{0}.feature?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- <provider readerType="svn" componentTypes="osgi.bundle" mutable="true" source="true">
- <uri format="${SIMANTICS}/sysdyn/trunk/{0}?moduleAfterTag&moduleAfterBranch">
- <bc:propertyRef key="buckminster.component" />
- <bc:propertyRef key="simantics.user" />
- <bc:propertyRef key="simantics.password" />
- </uri>
- </provider>
- </searchPath>
-
- <locator searchPathRef="sysdyn" pattern="^fi\.semantum\.sysdyn\.solver" />
- <locator searchPathRef="sysdyn" pattern="^org\.simantics\.modelica" />
- <locator searchPathRef="sysdyn" pattern="^org\.simantics\.fmu" />
- <locator searchPathRef="sysdyn" pattern="^org\.simantics\.objmap" />
- <locator searchPathRef="sysdyn" pattern="^org\.simantics\.om" />
- <locator searchPathRef="sysdyn" pattern="^org\.simantics\.sysdyn" />
- <locator searchPathRef="sysdyn" pattern="^org\.simantics\.jfreechart" />
-
- <redirect href="SDK.rmap" />
-
-</rmap>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>\r
-<rmap\r
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
- xmlns="http://www.eclipse.org/buckminster/RMap-1.0"\r
- xmlns:bc="http://www.eclipse.org/buckminster/Common-1.0"\r
- xmlns:pv="http://www.eclipse.org/buckminster/Provider-1.0">\r
- \r
- <property key="SIMANTICS" value="https://{1}:{2}@www.simantics.org/svn/simantics"/>\r
- \r
- <searchPath name="tutorials">\r
- <provider readerType="svn" componentTypes="eclipse.feature" mutable="true" source="true">\r
- <uri format="${SIMANTICS}/tutorials/trunk/{0}.feature?moduleAfterTag&moduleAfterBranch">\r
- <bc:propertyRef key="buckminster.component" />\r
- <bc:propertyRef key="simantics.user" />\r
- <bc:propertyRef key="simantics.password" />\r
- </uri>\r
- </provider> \r
- <provider readerType="svn" componentTypes="osgi.bundle" mutable="true" source="true">\r
- <uri format="${SIMANTICS}/tutorials/trunk/{0}?moduleAfterTag&moduleAfterBranch">\r
- <bc:propertyRef key="buckminster.component" />\r
- <bc:propertyRef key="simantics.user" />\r
- <bc:propertyRef key="simantics.password" />\r
- </uri>\r
- </provider>\r
- </searchPath>\r
-\r
- <locator searchPathRef="tutorials" pattern="^com\.acme\." />\r
- \r
- <redirect href="Simantics.rmap" />\r
- \r
-</rmap>\r
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>\r
-<?pde version="3.8"?>\r
-<target name="Simantics Trunk" sequenceNumber="9">\r
-<locations>\r
-<location includeAllPlatforms="true" includeConfigurePhase="false" includeMode="slicer" includeSource="true" type="InstallableUnit">\r
-<unit id="org.simantics.sdk.feature.group" version="1.25.0"/>\r
-<repository location="http://www.simantics.org/download/master/sdk"/>\r
-</location>\r
-<location includeAllPlatforms="true" includeConfigurePhase="false" includeMode="slicer" includeSource="true" type="InstallableUnit">\r
-<unit id="org.eclipse.nebula.feature.feature.group" version="1.0.0.201605182147"/>\r
-<repository location="http://www.simantics.org/update/nebula/Q22016/release/"/>\r
-</location>\r
-<location includeAllPlatforms="true" includeConfigurePhase="false" includeMode="slicer" includeSource="true" type="InstallableUnit">\r
-<unit id="org.eclipse.nebula.incubation.feature.feature.group" version="1.0.0.201605182147"/>\r
-<repository location="http://www.simantics.org/update/nebula/Q22016/incubation"/>\r
-</location>\r
-</locations>\r
-</target>\r
<packaging>pom</packaging>\r
\r
<properties>\r
- <tycho.version>0.25.0</tycho.version>\r
- <tycho.extras.version>0.25.0</tycho.extras.version>\r
+ <tycho.version>0.26.0</tycho.version>\r
+ <tycho.extras.version>0.26.0</tycho.extras.version>\r
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>\r
<mars-repo.url>http://download.eclipse.org/releases/mars</mars-repo.url>\r
</properties>\r
<version>${tycho.version}</version>\r
<extensions>true</extensions>\r
</plugin>\r
+ <plugin>\r
+ <groupId>org.eclipse.tycho</groupId>\r
+ <artifactId>tycho-versions-plugin</artifactId>\r
+ <version>${tycho.version}</version>\r
+ </plugin>\r
<plugin>\r
<groupId>org.eclipse.tycho</groupId>\r
<artifactId>tycho-packaging-plugin</artifactId>\r
</environments>\r
</configuration>\r
</plugin>\r
+ <plugin>\r
+ <groupId>org.eclipse.tycho.extras</groupId>\r
+ <artifactId>tycho-source-feature-plugin</artifactId>\r
+ <version>${tycho.extras.version}</version>\r
+ </plugin>\r
</plugins>\r
</build>\r
</project>\r
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Require-Bundle: org.junit;bundle-version="4.12.0",
org.simantics.scl.compiler;bundle-version="0.5.0",
- org.simantics.scl.osgi;bundle-version="1.0.4",
gnu.trove3,
+ org.simantics.scl.osgi;bundle-version="1.0.4",
org.objectweb.asm.util,
+ ch.qos.logback.classic;bundle-version="1.1.7",
+ ch.qos.logback.core;bundle-version="1.1.7",
+ org.apache.commons.collections;bundle-version="3.2.2",
org.eclipse.equinox.ds;bundle-version="1.4.300"
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<configuration>\r
+\r
+ <appender name="console" class="ch.qos.logback.core.ConsoleAppender">\r
+ <!-- encoders are assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->\r
+ <encoder>\r
+ <pattern>%-5p [%d] %c: %m%n%rEx</pattern>\r
+ </encoder>\r
+ </appender>\r
+\r
+ <appender name="async-console" class="ch.qos.logback.classic.AsyncAppender">\r
+ <appender-ref ref="console" />\r
+ </appender>\r
+\r
+ <root level="debug">\r
+ <appender-ref ref="async-console" />\r
+ </root>\r
+</configuration>
\ No newline at end of file
package org.simantics.scl.compiler.tests;
-import org.junit.Ignore;
import org.junit.Test;
public class ActiveTests extends TestBase {
*/
//@Test public void CityoptSetup() { test(); }
- @Test public void EmptyLet() { test(); }
}
-package org.simantics.scl.compiler.tests;
-
-import org.junit.runner.RunWith;
-import org.junit.runners.Suite;
-import org.junit.runners.Suite.SuiteClasses;
-
-@RunWith(Suite.class)
-@SuiteClasses({
- ActiveTests.class
-})
-public class TestActive {
-}
+package org.simantics.scl.compiler.tests;\r
+\r
+import org.junit.runner.RunWith;\r
+import org.junit.runners.Suite;\r
+import org.junit.runners.Suite.SuiteClasses;\r
+import org.simantics.scl.compiler.tests.markdown.MarkdownTests;\r
+\r
+@RunWith(Suite.class)\r
+@SuiteClasses({\r
+ TestRegression.class,\r
+ ActiveTests.class,\r
+ MarkdownTests.class\r
+})\r
+public class AllTestsForCoverage {\r
+\r
+}\r
package org.simantics.scl.compiler.tests;
-import org.junit.AfterClass;
-import org.junit.Ignore;
import org.junit.Test;
-import org.simantics.scl.compiler.errors.Failable;
-import org.simantics.scl.compiler.module.Module;
-import org.simantics.scl.compiler.module.coverage.CoverageUtils;
-import org.simantics.scl.compiler.module.coverage.ModuleCoverage;
import org.simantics.scl.compiler.top.ValueNotFound;
-import org.simantics.scl.runtime.profiling.BranchPoint;
public class ModuleRegressionTests extends TestBase {
@Test public void ClashingData() { test(); }
@Test public void ClashingInstance() { test(); }
@Test public void ClashingValueType() { test(); }
+ @Test public void ClosingBrace() { test(); }
@Test public void Collaz() { test(); }
@Test public void Compose() { test(); }
@Test public void Composition() { test(); }
@Test public void Effects4() { test(); }
@Test public void Effects5() { test(); }
@Test public void Effects6() { test(); }
+ @Test public void EmptyLet() { test(); }
@Test(expected=ValueNotFound.class)
public void EmptyModule() throws ValueNotFound {
test(new String[]{"EmptyModule"}, new String[]{""});
@Test public void Fibonacci2() { test(); }
@Test public void Fibonacci3() { test(); }
@Test public void FingerTree() { test(); }
- @Ignore
- @Test public void FoldMissingInitialValue() { test(); }
@Test public void FoldlBuild1() { test(); }
@Test public void FoldlBuild2() { test(); }
+ @Test public void FoldMissingInitialValue() { test(); }
@Test public void Forall1() { test(); }
@Test public void Forall2() { test(); }
@Test public void Forall3() { test(); }
- @Ignore
@Test public void Formula() { test(); }
@Test public void FromDynamic() { test(); }
@Test public void FromDynamic2() { test(); }
@Test public void GuardedExpressionBug() { test(); }
@Test public void Guards1() { test(); }
@Test public void Guards2() { test(); }
- @Test public void IdAsOperator() { test(); }
+ @Test public void IdAsOperator() { test(); }
+ //@Test public void IfWithoutElse() { test(); }
@Test public void IllegalChar() { test(); }
@Test public void ImportJavaConstructor() { test(); }
@Test public void ImportRef() { test(); }
@Test public void JavaTypes() { test(); }
@Test public void Kinds1() { test(); }
@Test public void Lambda() { test(); }
+ @Test public void LambdaMatch() { test(); }
@Test public void Layout1() { test(); }
@Test public void List() { test(); }
- @Test public void ListError1() { test(); }
- @Test public void ListError2() { test(); }
+ @Test public void ListError1() { test(); }
+ @Test public void ListError2() { test(); }
@Test public void ListSyntax() { test(); }
@Test public void ListSyntax10() { test(); }
@Test public void ListSyntax11() { test(); }
@Test public void Macros1() { test(); }
@Test public void Macros2() { test(); }
@Test public void Macros4() { test(); }
- @Test public void Map1() { test(); }
- @Test public void MarketModel() { test(); }
+ @Test public void Map1() { test(); }
+ @Test public void MarketModel() { test(); }
@Test public void Matching() { test(); }
@Test public void Matching2() { test(); }
@Test public void Matching4() { test(); }
@Test public void MatchingWithoutTypeAnnotations() { test(); }
@Test public void MaximumBy() { test(); }
@Test public void Maybe1() { test(); }
- @Test public void Maybe2() { test(); }
- @Test public void Maybe3() { test(); }
+ @Test public void Maybe2() { test(); }
+ @Test public void Maybe3() { test(); }
@Test public void Maybe4() { test(); }
@Test public void MissingEffect() { test(); }
@Test public void MissingMethod() { test(); }
@Test public void ModuleInitialization() { test(); }
@Test public void MonadBug1() { test(); }
- @Test public void MonadSyntax1() { test(); }
@Test public void Monads1() { test(); }
- @Test public void NoDefinitionErrorMessage() { test(); }
+ @Test public void MonadSyntax1() { test(); }
+ @Test public void NoDefinitionErrorMessage() { test(); }
@Test public void NoInstance() { test(); }
@Test public void NoInstance2() { test(); }
@Test public void NonassociativeOperator() { test(); }
@Test public void NonexistentTypeClassInAnnotation() { test(); }
- @Test public void NonexistingEffect() { test(); }
- @Test public void OneLineMatch() { test(); }
+ @Test public void NonexistingEffect() { test(); }
+ @Test public void OneLineMatch() { test(); }
@Test public void OpenString1() { test(); }
@Test public void OpenString2() { test(); }
@Test public void OverloadedArithmetic1() { test(); }
@Test public void OverloadedArithmetic2() { test(); }
@Test public void OverloadedArithmetic3() { test(); }
@Test public void OverloadedLiterals2() { test(); }
- @Ignore
- @Test public void Overloading1() { test(); }
- @Test public void Parsing() { test(); }
+ @Test public void Overloading1() { test(); }
+ @Test public void Parsing() { test(); }
@Test public void PolymorphicRecursion() { test(); }
@Test public void PolymorphicRecursion2() { test(); }
- @Test public void Polynomials() { test(); }
- @Test public void PrecedenceOfNonoperators() { test(); }
+ @Test public void Polynomials() { test(); }
+ @Test public void PrecedenceOfNonoperators() { test(); }
@Test public void Primes() { test(); }
@Test public void Proc1() { test(); }
@Test public void Proc2() { test(); }
@Test public void RecursiveValues4() { test(); }
@Test public void RedBlackTrees() { test(); }
@Test public void Relations1() { test(); }
- @Test public void Relations2() { test(); }
- @Test public void RepeatedVariableInPattern() { test(); }
- @Test public void SSATypingBug() { test(); }
+ @Test public void Relations2() { test(); }
+ @Test public void RepeatedVariableInPattern() { test(); }
@Test public void Scanl() { test(); }
@Test public void Search() { test(); }
@Test public void Sections() { test(); }
@Test public void SelfReferringContextInTypeClass() { test(); }
@Test public void Serialization2() { test(); }
@Test public void Serialization3() { test(); }
+ @Test public void Serialization4() { test(); }
@Test public void SharedTypeVariable() { test(); }
@Test public void ShortcutFusion() { test(); }
@Test public void Show1() { test(); }
@Test public void SinConst1() { test(); }
@Test public void Sort() { test(); }
@Test public void Sort2() { test(); }
+ @Test public void SSATypingBug() { test(); }
@Test public void StreamFusion() { test(); }
@Test public void StringEscape() { test(); }
@Test public void StringInterpolation1() { test(); }
- @Test public void StringMatching1() { test(); }
+ @Test public void StringInterpolation2() { test(); }
+ @Test public void StringInterpolation3() { test(); }
+ @Test public void StringMatching1() { test(); }
@Test public void SumOfInverses2() { test(); }
@Test public void TooManyParametersToSin() { test(); }
@Test public void Transformation1() { test(); }
@Test public void TypeAliasRefsToTypeAlias() { test(); }
@Test public void TypeAnnotation1() { test(); }
@Test public void TypeAnnotation2() { test(); }
- @Test public void TypeClass() { test(); }
- @Test public void TypeClassBug1() { test(); }
+ @Test public void TypeClass() { test(); }
+ @Test public void TypeClassBug1() { test(); }
@Test(timeout=1000L) public void TypeInferenceBug2() { test(); }
@Test public void TypeOf1() { test(); }
@Test public void TypingBug1() { test(); }
@Test public void Unification1() { test(); }
@Test public void UnknownAnnotation() { test(); }
@Test public void UnresolvedClass() { test(); }
- @Test public void UnresolvedTypeInAnnotation() { test(); }
- @Test public void UnresolvedTypeInInstance() { test(); }
- @Test public void UnresolvedVariable() { test(); }
- @Test public void UnresolvedVariable2() { test(); }
+ @Test public void UnresolvedTypeInAnnotation() { test(); }
+ @Test public void UnresolvedTypeInInstance() { test(); }
+ @Test public void UnresolvedVariable() { test(); }
+ @Test public void UnresolvedVariable2() { test(); }
@Test public void ValueAsOperator() { test(); }
@Test public void ValueConversion() { test(); }
@Test public void Vector1() { test(); }
@Test public void Vector2() { test(); }
+ @Test public void ViewPatterns1() { test(); }
@Test public void Void1() { test(); }
@Test public void Void2() { test(); }
@Test public void Void3() { test(); }
- @Test public void While() { test(); }
+ @Test public void While() { test(); }
@Test public void While2() { test(); }
- @Test public void While3() { test(); }
+ @Test public void While3() { test(); }
@Test public void WrongDefaultMethod() { test(); }
@Test public void WrongInstanceMethod() { test(); }
+ /*
@AfterClass
public static void checkCoverage() {
Failable<Module> maybeModule = PRELUDE_MODULE_REPOSITORY.getModule("Prelude");
System.out.println(bp.getCodeSize());
printCoverageTree(bp.getChildren(), ind+1);
}
- }
+ }*/
}
import org.simantics.scl.compiler.module.repository.UpdateListener;
import org.simantics.scl.compiler.source.ModuleSource;
import org.simantics.scl.compiler.source.StringModuleSource;
-import org.simantics.scl.compiler.source.repository.CompositeModuleSourceRepository;
import org.simantics.scl.compiler.source.repository.MapModuleSourceRepository;
-import org.simantics.scl.compiler.source.repository.SourceRepositories;
import org.simantics.scl.compiler.top.ValueNotFound;
public class TestBase {
package org.simantics.scl.compiler.tests;\r
\r
+import org.junit.Assert;\r
import org.junit.Test;\r
import org.simantics.scl.compiler.elaboration.java.Builtins;\r
import org.simantics.scl.compiler.environment.specification.EnvironmentSpecification;\r
import org.simantics.scl.compiler.source.repository.ModuleSourceRepository;\r
import org.simantics.scl.compiler.top.ExpressionEvaluator;\r
\r
-import junit.framework.Assert;\r
-\r
public class TestClassNaming {\r
\r
private static class SimpleModuleSource extends StringModuleSource {\r
import org.junit.Test;
import org.simantics.scl.compiler.commands.CommandSession;
import org.simantics.scl.compiler.module.repository.ModuleRepository;
-import org.simantics.scl.compiler.source.repository.CompositeModuleSourceRepository;
-import org.simantics.scl.compiler.source.repository.SourceRepositories;
import org.simantics.scl.runtime.reporting.AbstractSCLReportingHandler;
import org.simantics.scl.runtime.reporting.SCLReportingHandler;
import java.util.Arrays;
+import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.simantics.scl.compiler.elaboration.expressions.EVariable;
import org.simantics.scl.runtime.function.Function;
import org.simantics.scl.runtime.tuple.Tuple0;
-import junit.framework.Assert;
-
public class TestExpressionEvaluator {
public static final boolean TIMING = false;
-package org.simantics.scl.compiler.tests.markdown;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.StringReader;
-import java.nio.charset.Charset;
-
-import org.simantics.scl.compiler.markdown.internal.MarkdownParser;
-import org.simantics.scl.compiler.markdown.nodes.Node;
-
-public class RunMarkdownTests {
-
- public static int FAILED = 0;
- public static int SUCCEEDED = 1;
- public static int SKIPPED = 2;
-
- public static void main(String[] args) throws IOException {
- BufferedReader reader = new BufferedReader(
- new InputStreamReader(
- RunMarkdownTests.class.getResourceAsStream("spec.txt"),
- Charset.forName("UTF-8")));
-
- StringBuilder in = new StringBuilder();
- StringBuilder out = new StringBuilder();
- int state = 0;
- int testId = 0;
- int passed = 0;
- int failed = 0;
- int skipped = 0;
- while(true) {
- String line = reader.readLine();
- if(line == null)
- break;
- switch(state) {
- case 0:
- if(line.equals("```````````````````````````````` example"))
- ++state;
- break;
- case 1:
- if(line.equals("."))
- ++state;
- else {
- if(in.length() > 0)
- in.append('\n');
- in.append(line);
- }
- break;
- case 2:
- if(line.equals("````````````````````````````````")) {
- ++testId;
- int status = test(testId, in.toString(), out.toString());
- if(status == SUCCEEDED)
- ++passed;
- else if(status == FAILED)
- ++failed;
- else
- ++skipped;
- in = new StringBuilder();
- out = new StringBuilder();
- state = 0;
- }
- else {
- if(out.length() > 0)
- out.append('\n');
- out.append(line);
- }
- break;
- }
- }
-
- System.out.println("Passed: " + passed + "/" + testId);
- System.out.println("Failed: " + failed + "/" + testId);
- System.out.println("Skipped: " + skipped + "/" + testId);
- }
-
- public static int test(int id, String in, String out) throws IOException {
- MarkdownParser parser = new MarkdownParser();
- Node node = parser.parseDocument(new StringReader(in.replace('\u2192', '\t')));
-
- String result = node.toHtml().replace('\t', '\u2192');
-
- boolean passed = result.equals(out);
-
- if(!passed) {
- System.out.println("Example " + id); // + (passed ? " passed" : " failed"));
- System.out.println("---- in --------------------------------------------------------------------");
- System.out.println(in);
- System.out.println("---- expected --------------------------------------------------------------");
- System.out.println(out);
- System.out.println("---- actual ----------------------------------------------------------------");
- System.out.println(result);
- System.out.println("----------------------------------------------------------------------------");
- System.out.println();
- }
-
- return passed ? SUCCEEDED : FAILED;
- }
-
-}
+package org.simantics.scl.compiler.tests.markdown;\r
+\r
+import java.io.BufferedReader;\r
+import java.io.IOException;\r
+import java.io.InputStreamReader;\r
+import java.io.StringReader;\r
+import java.nio.charset.Charset;\r
+\r
+import org.junit.Test;\r
+import org.simantics.scl.compiler.markdown.internal.MarkdownParser;\r
+import org.simantics.scl.compiler.markdown.nodes.Node;\r
+\r
+public class MarkdownTests {\r
+ \r
+ public static int FAILED = 0;\r
+ public static int SUCCEEDED = 1;\r
+ public static int SKIPPED = 2;\r
+ \r
+ @Test\r
+ public void markdownTests() throws IOException {\r
+ BufferedReader reader = new BufferedReader(\r
+ new InputStreamReader(\r
+ MarkdownTests.class.getResourceAsStream("spec.txt"),\r
+ Charset.forName("UTF-8")));\r
+ \r
+ StringBuilder in = new StringBuilder();\r
+ StringBuilder out = new StringBuilder();\r
+ int state = 0;\r
+ int testId = 0;\r
+ int passed = 0;\r
+ int failed = 0;\r
+ int skipped = 0;\r
+ while(true) {\r
+ String line = reader.readLine();\r
+ if(line == null)\r
+ break;\r
+ switch(state) {\r
+ case 0:\r
+ if(line.equals("```````````````````````````````` example"))\r
+ ++state;\r
+ break;\r
+ case 1:\r
+ if(line.equals("."))\r
+ ++state;\r
+ else {\r
+ if(in.length() > 0)\r
+ in.append('\n');\r
+ in.append(line);\r
+ }\r
+ break;\r
+ case 2:\r
+ if(line.equals("````````````````````````````````")) {\r
+ ++testId;\r
+ int status = test(testId, in.toString(), out.toString());\r
+ if(status == SUCCEEDED)\r
+ ++passed;\r
+ else if(status == FAILED)\r
+ ++failed;\r
+ else\r
+ ++skipped;\r
+ in = new StringBuilder();\r
+ out = new StringBuilder();\r
+ state = 0;\r
+ }\r
+ else {\r
+ if(out.length() > 0)\r
+ out.append('\n');\r
+ out.append(line);\r
+ }\r
+ break;\r
+ }\r
+ }\r
+ \r
+ System.out.println("Passed: " + passed + "/" + testId);\r
+ System.out.println("Failed: " + failed + "/" + testId);\r
+ System.out.println("Skipped: " + skipped + "/" + testId);\r
+ }\r
+\r
+ public static int test(int id, String in, String out) throws IOException {\r
+ MarkdownParser parser = new MarkdownParser();\r
+ Node node = parser.parseDocument(new StringReader(in.replace('\u2192', '\t')));\r
+ \r
+ String result = node.toHtml().replace('\t', '\u2192');\r
+ \r
+ boolean passed = result.equals(out);\r
+ \r
+ if(!passed) {\r
+ System.out.println("Example " + id); // + (passed ? " passed" : " failed"));\r
+ System.out.println("---- in --------------------------------------------------------------------");\r
+ System.out.println(in);\r
+ System.out.println("---- expected --------------------------------------------------------------");\r
+ System.out.println(out);\r
+ System.out.println("---- actual ----------------------------------------------------------------");\r
+ System.out.println(result);\r
+ System.out.println("----------------------------------------------------------------------------");\r
+ System.out.println();\r
+ }\r
+ \r
+ return passed ? SUCCEEDED : FAILED;\r
+ }\r
+ \r
+}\r
+++ /dev/null
-package org.simantics.scl.compiler.tests.markdown;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.StringReader;
-import java.nio.charset.Charset;
-
-import org.simantics.scl.compiler.markdown.internal.MarkdownParser;
-import org.simantics.scl.compiler.markdown.nodes.Node;
-
-public class RunMarkdownTests {
-
- public static int FAILED = 0;
- public static int SUCCEEDED = 1;
- public static int SKIPPED = 2;
-
- public static void main(String[] args) throws IOException {
- BufferedReader reader = new BufferedReader(
- new InputStreamReader(
- RunMarkdownTests.class.getResourceAsStream("spec.txt"),
- Charset.forName("UTF-8")));
-
- StringBuilder in = new StringBuilder();
- StringBuilder out = new StringBuilder();
- int state = 0;
- int testId = 0;
- int passed = 0;
- int failed = 0;
- int skipped = 0;
- while(true) {
- String line = reader.readLine();
- if(line == null)
- break;
- switch(state) {
- case 0:
- if(line.equals("```````````````````````````````` example"))
- ++state;
- break;
- case 1:
- if(line.equals("."))
- ++state;
- else {
- if(in.length() > 0)
- in.append('\n');
- in.append(line);
- }
- break;
- case 2:
- if(line.equals("````````````````````````````````")) {
- ++testId;
- int status = test(testId, in.toString(), out.toString());
- if(status == SUCCEEDED)
- ++passed;
- else if(status == FAILED)
- ++failed;
- else
- ++skipped;
- in = new StringBuilder();
- out = new StringBuilder();
- state = 0;
- }
- else {
- if(out.length() > 0)
- out.append('\n');
- out.append(line);
- }
- break;
- }
- }
-
- System.out.println("Passed: " + passed + "/" + testId);
- System.out.println("Failed: " + failed + "/" + testId);
- System.out.println("Skipped: " + skipped + "/" + testId);
- }
-
- public static int test(int id, String in, String out) throws IOException {
- MarkdownParser parser = new MarkdownParser();
- Node node = parser.parseDocument(new StringReader(in.replace('\u2192', '\t')));
-
- String result = node.toHtml().replace('\t', '\u2192');
-
- boolean passed = result.equals(out);
-
- if(!passed) {
- System.out.println("Example " + id); // + (passed ? " passed" : " failed"));
- System.out.println("---- in --------------------------------------------------------------------");
- System.out.println(in);
- System.out.println("---- expected --------------------------------------------------------------");
- System.out.println(out);
- System.out.println("---- actual ----------------------------------------------------------------");
- System.out.println(result);
- System.out.println("----------------------------------------------------------------------------");
- System.out.println();
- }
-
- return passed ? SUCCEEDED : FAILED;
- }
-
-}
---
title: CommonMark Spec
author: John MacFarlane
-version: 0.25
-date: '2016-03-24'
+version: 0.26
+date: '2016-07-15'
license: '[CC-BY-SA 4.0](http://creativecommons.org/licenses/by-sa/4.0/)'
...
Markdown is a plain text format for writing structured documents,
based on conventions used for indicating formatting in email and
usenet posts. It was developed in 2004 by John Gruber, who wrote
-the first Markdown-to-HTML converter in perl, and it soon became
-widely used in websites. By 2014 there were dozens of
-implementations in many languages. Some of them extended basic
-Markdown syntax with conventions for footnotes, definition lists,
-tables, and other constructs, and some allowed output not just in
-HTML but in LaTeX and many other formats.
+the first Markdown-to-HTML converter in Perl, and it soon became
+ubiquitous. In the next decade, dozens of implementations were
+developed in many languages. Some extended the original
+Markdown syntax with conventions for footnotes, tables, and
+other document elements. Some allowed Markdown documents to be
+rendered in formats other than HTML. Websites like Reddit,
+StackOverflow, and GitHub had millions of people using Markdown.
+And Markdown started to be used beyond the web, to author books,
+articles, slide shows, letters, and lecture notes.
+
+What distinguishes Markdown from many other lightweight markup
+syntaxes, which are often easier to write, is its readability.
+As Gruber writes:
+
+> The overriding design goal for Markdown's formatting syntax is
+> to make it as readable as possible. The idea is that a
+> Markdown-formatted document should be publishable as-is, as
+> plain text, without looking like it's been marked up with tags
+> or formatting instructions.
+> (<http://daringfireball.net/projects/markdown/>)
+
+The point can be illustrated by comparing a sample of
+[AsciiDoc](http://www.methods.co.nz/asciidoc/) with
+an equivalent sample of Markdown. Here is a sample of
+AsciiDoc from the AsciiDoc manual:
+
+```
+1. List item one.
++
+List item one continued with a second paragraph followed by an
+Indented block.
++
+.................
+$ ls *.sh
+$ mv *.sh ~/tmp
+.................
++
+List item continued with a third paragraph.
+
+2. List item two continued with an open block.
++
+--
+This paragraph is part of the preceding list item.
+
+a. This list is nested and does not require explicit item
+continuation.
++
+This paragraph is part of the preceding list item.
+
+b. List item b.
+
+This paragraph belongs to item two of the outer list.
+--
+```
+
+And here is the equivalent in Markdown:
+```
+1. List item one.
+
+ List item one continued with a second paragraph followed by an
+ Indented block.
+
+ $ ls *.sh
+ $ mv *.sh ~/tmp
+
+ List item continued with a third paragraph.
+
+2. List item two continued with an open block.
+
+ This paragraph is part of the preceding list item.
+
+ 1. This list is nested and does not require explicit item continuation.
+
+ This paragraph is part of the preceding list item.
+
+ 2. List item b.
+
+ This paragraph belongs to item two of the outer list.
+```
+
+The AsciiDoc version is, arguably, easier to write. You don't need
+to worry about indentation. But the Markdown version is much easier
+to read. The nesting of list items is apparent to the eye in the
+source, not just in the processed document.
## Why is a spec needed?
## Tabs
Tabs in lines are not expanded to [spaces]. However,
-in contexts where indentation is significant for the
-document's structure, tabs behave as if they were replaced
-by spaces with a tab stop of 4 characters.
+in contexts where whitespace helps to define block structure,
+tabs behave as if they were replaced by spaces with a tab stop
+of 4 characters.
+
+Thus, for example, a tab can be used instead of four spaces
+in an indented code block. (Note, however, that internal
+tabs are passed through as literal tabs, not expanded to
+spaces.)
```````````````````````````````` example
→foo→baz→→bim
</code></pre>
````````````````````````````````
-
```````````````````````````````` example
→foo→baz→→bim
.
</code></pre>
````````````````````````````````
-
```````````````````````````````` example
a→a
ὐ→a
</code></pre>
````````````````````````````````
+In the following example, a continuation paragraph of a list
+item is indented with a tab; this has exactly the same effect
+as indentation with four spaces would:
```````````````````````````````` example
- foo
</ul>
````````````````````````````````
+Normally the `>` that begins a block quote may be followed
+optionally by a space, which is not considered part of the
+content. In the following case `>` is followed by a tab,
+which is treated as if it were expanded into spaces.
+Since one of theses spaces is considered part of the
+delimiter, `foo` is considered to be indented six spaces
+inside the block quote context, so we get an indented
+code block starting with two spaces.
+
```````````````````````````````` example
>→→foo
.
</ul>
````````````````````````````````
+```````````````````````````````` example
+#→Foo
+.
+<h1>Foo</h1>
+````````````````````````````````
+
+```````````````````````````````` example
+*→*→*→
+.
+<hr />
+````````````````````````````````
## Insecure characters
````````````````````````````````
-A tab will not work:
-
-```````````````````````````````` example
-#→foo
-.
-<p>#→foo</p>
-````````````````````````````````
-
-
This is not a heading, because the first `#` is escaped:
```````````````````````````````` example
meets a [start condition](@) (after up to three spaces
optional indentation). It ends with the first subsequent line that
meets a matching [end condition](@), or the last line of
-the document, if no line is encountered that meets the
+the document or other [container block]), if no line is encountered that meets the
[end condition]. If the first line meets both the [start condition]
and the [end condition], the block will contain just that line.
`article`, `aside`, `base`, `basefont`, `blockquote`, `body`,
`caption`, `center`, `col`, `colgroup`, `dd`, `details`, `dialog`,
`dir`, `div`, `dl`, `dt`, `fieldset`, `figcaption`, `figure`,
-`footer`, `form`, `frame`, `frameset`, `h1`, `head`, `header`, `hr`,
+`footer`, `form`, `frame`, `frameset`,
+`h1`, `h2`, `h3`, `h4`, `h5`, `h6`, `head`, `header`, `hr`,
`html`, `iframe`, `legend`, `li`, `link`, `main`, `menu`, `menuitem`,
`meta`, `nav`, `noframes`, `ol`, `optgroup`, `option`, `p`, `param`,
`section`, `source`, `summary`, `table`, `tbody`, `td`,
main :: IO ()
main = print $ parseTags tags
</code></pre>
+okay
.
<pre language="haskell"><code>
import Text.HTML.TagSoup
main :: IO ()
main = print $ parseTags tags
</code></pre>
+<p>okay</p>
````````````````````````````````
document.getElementById("demo").innerHTML = "Hello JavaScript!";
</script>
+okay
.
<script type="text/javascript">
// JavaScript example
document.getElementById("demo").innerHTML = "Hello JavaScript!";
</script>
+<p>okay</p>
````````````````````````````````
p {color:blue;}
</style>
+okay
.
<style
type="text/css">
p {color:blue;}
</style>
+<p>okay</p>
````````````````````````````````
bar
baz -->
+okay
.
<!-- Foo
bar
baz -->
+<p>okay</p>
````````````````````````````````
echo '>';
?>
+okay
.
<?php
echo '>';
?>
+<p>okay</p>
````````````````````````````````
}
}
]]>
+okay
.
<![CDATA[
function matchwo(a,b)
}
}
]]>
+<p>okay</p>
````````````````````````````````
````````````````````````````````
-The Laziness clause allows us to omit the `>` before a
-paragraph continuation line:
+The Laziness clause allows us to omit the `>` before
+[paragraph continuation text]:
```````````````````````````````` example
> # Foo
````````````````````````````````
-Note that in the following case, we have a paragraph
-continuation line:
+Note that in the following case, we have a [lazy
+continuation line]:
```````````````````````````````` example
> foo
the `- bar` is indented too far to start a list, and can't
be an indented code block because indented code blocks cannot
-interrupt paragraphs, so it is a [paragraph continuation line].
+interrupt paragraphs, so it is [paragraph continuation text].
A block quote can be empty:
1. **Basic case.** If a sequence of lines *Ls* constitute a sequence of
blocks *Bs* starting with a [non-whitespace character] and not separated
from each other by more than one blank line, and *M* is a list
- marker of width *W* followed by 0 < *N* < 5 spaces, then the result
+ marker of width *W* followed by 1 ≤ *N* ≤ 4 spaces, then the result
of prepending *M* and the following spaces to the first line of
*Ls*, and indenting subsequent lines of *Ls* by *W + N* spaces, is a
list item with *Bs* as its contents. The type of the list item
If the list item is ordered, then it is also assigned a start
number, based on the ordered list marker.
+ Exceptions: When the first list item in a [list] interrupts
+ a paragraph---that is, when it starts on a line that would
+ otherwise count as [paragraph continuation text]---then (a)
+ the lines *Ls* must not begin with a blank line, and (b) if
+ the list item is ordered, the start number must be 1.
+
For example, let *Ls* be the lines
```````````````````````````````` example
````````````````````````````````
-A list item may not contain blocks that are separated by more than
-one blank line. Thus, two blank lines will end a list, unless the
-two blanks are contained in a [fenced code block].
+A list item may contain blocks that are separated by more than
+one blank line.
```````````````````````````````` example
-- foo
-
- bar
-
- foo
bar
-
-- ```
- foo
-
-
- bar
- ```
-
-- baz
-
- + ```
- foo
-
-
- bar
- ```
.
<ul>
<li>
<p>foo</p>
<p>bar</p>
</li>
-<li>
-<p>foo</p>
-</li>
-</ul>
-<p>bar</p>
-<ul>
-<li>
-<pre><code>foo
-
-
-bar
-</code></pre>
-</li>
-<li>
-<p>baz</p>
-<ul>
-<li>
-<pre><code>foo
-
-
-bar
-</code></pre>
-</li>
-</ul>
-</li>
</ul>
````````````````````````````````
A list item that contains an indented code block will preserve
-empty lines within the code block verbatim, unless there are two
-or more empty lines in a row (since as described above, two
-blank lines end the list):
+empty lines within the code block verbatim.
```````````````````````````````` example
- Foo
bar
+
baz
.
<ul>
<p>Foo</p>
<pre><code>bar
-baz
-</code></pre>
-</li>
-</ul>
-````````````````````````````````
-
-```````````````````````````````` example
-- Foo
-
- bar
-
-
- baz
-.
-<ul>
-<li>
-<p>Foo</p>
-<pre><code>bar
+baz
</code></pre>
</li>
</ul>
-<pre><code> baz
-</code></pre>
````````````````````````````````
-
Note that ordered list start numbers must be nine digits or less:
```````````````````````````````` example
</ul>
````````````````````````````````
+However, an empty list item cannot interrupt a paragraph:
+
+```````````````````````````````` example
+foo
+*
+
+foo
+1.
+.
+<p>foo
+*</p>
+<p>foo
+1.</p>
+````````````````````````````````
4. **Indentation.** If a sequence of lines *Ls* constitutes a list item
- foo
- bar
- baz
+ - boo
.
<ul>
<li>foo
<ul>
<li>bar
<ul>
-<li>baz</li>
+<li>baz
+<ul>
+<li>boo</li>
+</ul>
+</li>
</ul>
</li>
</ul>
- foo
- bar
- baz
+ - boo
.
<ul>
<li>foo</li>
<li>bar</li>
<li>baz</li>
+<li>boo</li>
</ul>
````````````````````````````````
A [list](@) is a sequence of one or more
list items [of the same type]. The list items
-may be separated by single [blank lines], but two
-blank lines end all containing lists.
+may be separated by any number of blank lines.
Two list items are [of the same type](@)
if they begin with a [list marker] of the same type.
</ul>
````````````````````````````````
-
`Markdown.pl` does not allow this, through fear of triggering a list
via a numeral in a hard-wrapped line:
-```````````````````````````````` example
+``` markdown
The number of windows in my house is
14. The number of doors is 6.
-.
-<p>The number of windows in my house is</p>
-<ol start="14">
-<li>The number of doors is 6.</li>
-</ol>
-````````````````````````````````
-
+```
-Oddly, `Markdown.pl` *does* allow a blockquote to interrupt a paragraph,
-even though the same considerations might apply. We think that the two
-cases should be treated the same. Here are two reasons for allowing
-lists to interrupt paragraphs:
+Oddly, though, `Markdown.pl` *does* allow a blockquote to
+interrupt a paragraph, even though the same considerations might
+apply.
-First, it is natural and not uncommon for people to start lists without
-blank lines:
+In CommonMark, we do allow lists to interrupt paragraphs, for
+two reasons. First, it is natural and not uncommon for people
+to start lists without blank lines:
- I need to buy
- - new shoes
- - a coat
- - a plane ticket
+``` markdown
+I need to buy
+- new shoes
+- a coat
+- a plane ticket
+```
Second, we are attracted to a
(Indeed, the spec for [list items] and [block quotes] presupposes
this principle.) This principle implies that if
- * I need to buy
- - new shoes
- - a coat
- - a plane ticket
+``` markdown
+ * I need to buy
+ - new shoes
+ - a coat
+ - a plane ticket
+```
is a list item containing a paragraph followed by a nested sublist,
as all Markdown implementations agree it is (though the paragraph
may be rendered without `<p>` tags, since the list is "tight"),
then
- I need to buy
- - new shoes
- - a coat
- - a plane ticket
+``` markdown
+I need to buy
+- new shoes
+- a coat
+- a plane ticket
+```
by itself should be a paragraph followed by a nested sublist.
-Our adherence to the [principle of uniformity]
-thus inclines us to think that there are two coherent packages:
+Since it is well established Markdown practice to allow lists to
+interrupt paragraphs inside list items, the [principle of
+uniformity] requires us to allow this outside list items as
+well. ([reStructuredText](http://docutils.sourceforge.net/rst.html)
+takes a different approach, requiring blank lines before lists
+even inside other list items.)
-1. Require blank lines before *all* lists and blockquotes,
- including lists that occur as sublists inside other list items.
+In order to solve of unwanted lists in paragraphs with
+hard-wrapped numerals, we allow only lists starting with `1` to
+interrupt paragraphs. Thus,
-2. Require blank lines in none of these places.
+```````````````````````````````` example
+The number of windows in my house is
+14. The number of doors is 6.
+.
+<p>The number of windows in my house is
+14. The number of doors is 6.</p>
+````````````````````````````````
-[reStructuredText](http://docutils.sourceforge.net/rst.html) takes
-the first approach, for which there is much to be said. But the second
-seems more consistent with established practice with Markdown.
+We may still get an unintended result in cases like
-There can be blank lines between items, but two blank lines end
-a list:
+```````````````````````````````` example
+The number of windows in my house is
+1. The number of doors is 6.
+.
+<p>The number of windows in my house is</p>
+<ol>
+<li>The number of doors is 6.</li>
+</ol>
+````````````````````````````````
+
+but this rule should prevent most spurious list captures.
+
+There can be any number of blank lines between items:
```````````````````````````````` example
- foo
<li>
<p>bar</p>
</li>
-</ul>
-<ul>
-<li>baz</li>
-</ul>
-````````````````````````````````
-
-
-As illustrated above in the section on [list items],
-two blank lines between blocks *within* a list item will also end a
-list:
-
-```````````````````````````````` example
-- foo
-
-
- bar
-- baz
-.
-<ul>
-<li>foo</li>
-</ul>
-<p>bar</p>
-<ul>
-<li>baz</li>
+<li>
+<p>baz</p>
+</li>
</ul>
````````````````````````````````
-
-Indeed, two blank lines will end *all* containing lists:
-
```````````````````````````````` example
- foo
- bar
<ul>
<li>bar
<ul>
-<li>baz</li>
+<li>
+<p>baz</p>
+<p>bim</p>
+</li>
</ul>
</li>
</ul>
</li>
</ul>
-<pre><code> bim
-</code></pre>
````````````````````````````````
-Thus, two blank lines can be used to separate consecutive lists of
-the same type, or to separate a list from an indented code block
-that would otherwise be parsed as a subparagraph of the final list
-item:
+To separate consecutive lists of the same type, or to separate a
+list from an indented code block that would otherwise be parsed
+as a subparagraph of the final list item, you can insert a blank HTML
+comment:
```````````````````````````````` example
- foo
- bar
+<!-- -->
- baz
- bim
<li>foo</li>
<li>bar</li>
</ul>
+<!-- -->
<ul>
<li>baz</li>
<li>bim</li>
- foo
+<!-- -->
code
.
<p>foo</p>
</li>
</ul>
+<!-- -->
<pre><code>code
</code></pre>
````````````````````````````````
````````````````````````````````
+Not all [Unicode whitespace] (for instance, non-breaking space) is
+collapsed, however:
+
+```````````````````````````````` example
+`a b`
+.
+<p><code>a b</code></p>
+````````````````````````````````
+
+
Q: Why not just leave the spaces, since browsers will collapse them
anyway? A: Because we might be targeting a non-HTML format, and we
shouldn't rely on HTML-specific rendering assumptions.
9. Emphasis begins with a delimiter that [can open emphasis] and ends
with a delimiter that [can close emphasis], and that uses the same
- character (`_` or `*`) as the opening delimiter. There must
- be a nonempty sequence of inlines between the open delimiter
- and the closing delimiter; these form the contents of the emphasis
- inline.
+ character (`_` or `*`) as the opening delimiter. The
+ opening and closing delimiters must belong to separate
+ [delimiter runs]. If one of the delimiters can both
+ open and close emphasis, then the sum of the lengths of the
+ delimiter runs containing the opening and closing delimiters
+ must not be a multiple of 3.
10. Strong emphasis begins with a delimiter that
[can open strong emphasis] and ends with a delimiter that
[can close strong emphasis], and that uses the same character
- (`_` or `*`) as the opening delimiter.
- There must be a nonempty sequence of inlines between the open
- delimiter and the closing delimiter; these form the contents of
- the strong emphasis inline.
+ (`_` or `*`) as the opening delimiter. The
+ opening and closing delimiters must belong to separate
+ [delimiter runs]. If one of the delimiters can both open
+ and close strong emphasis, then the sum of the lengths of
+ the delimiter runs containing the opening and closing
+ delimiters must not be a multiple of 3.
11. A literal `*` character cannot occur at the beginning or end of
`*`-delimited emphasis or `**`-delimited strong emphasis, unless it
so that the second begins before the first ends and ends after
the first ends, the first takes precedence. Thus, for example,
`*foo _bar* baz_` is parsed as `<em>foo _bar</em> baz_` rather
- than `*foo <em>bar* baz</em>`. For the same reason,
- `**foo*bar**` is parsed as `<em><em>foo</em>bar</em>*`
- rather than `<strong>foo*bar</strong>`.
+ than `*foo <em>bar* baz</em>`.
16. When there are two potential emphasis or strong emphasis spans
with the same closing delimiter, the shorter one (the one that
*foo bar
*
.
-<p>*foo bar</p>
-<ul>
-<li></li>
-</ul>
+<p>*foo bar
+*</p>
````````````````````````````````
<p><em>foo <strong>bar</strong> baz</em></p>
````````````````````````````````
-
-But note:
-
```````````````````````````````` example
*foo**bar**baz*
.
-<p><em>foo</em><em>bar</em><em>baz</em></p>
+<p><em>foo<strong>bar</strong>baz</em></p>
````````````````````````````````
+Note that in the preceding case, the interpretation
+
+``` markdown
+<p><em>foo</em><em>bar<em></em>baz</em></p>
+```
+
+
+is precluded by the condition that a delimiter that
+can both open and close (like the `*` after `foo`)
+cannot form emphasis if the sum of the lengths of
+the delimiter runs containing the opening and
+closing delimiters is a multiple of 3.
+
+The same condition ensures that the following
+cases are all strong emphasis nested inside
+emphasis, even when the interior spaces are
+omitted:
-The difference is that in the preceding case, the internal delimiters
-[can close emphasis], while in the cases with spaces, they cannot.
```````````````````````````````` example
***foo** bar*
````````````````````````````````
-Note, however, that in the following case we get no strong
-emphasis, because the opening delimiter is closed by the first
-`*` before `bar`:
-
```````````````````````````````` example
*foo**bar***
.
-<p><em>foo</em><em>bar</em>**</p>
+<p><em>foo<strong>bar</strong></em></p>
````````````````````````````````
-
Indefinite levels of nesting are possible:
```````````````````````````````` example
````````````````````````````````
-But note:
-
```````````````````````````````` example
**foo*bar*baz**
.
-<p><em><em>foo</em>bar</em>baz**</p>
+<p><strong>foo<em>bar</em>baz</strong></p>
````````````````````````````````
-The difference is that in the preceding case, the internal delimiters
-[can close emphasis], while in the cases with spaces, they cannot.
-
```````````````````````````````` example
***foo* bar**
.
````````````````````````````````
-```````````````````````````````` example
-**foo*bar**
-.
-<p><em><em>foo</em>bar</em>*</p>
-````````````````````````````````
-
-
```````````````````````````````` example
*foo __bar *baz bim__ bam*
.
````````````````````````````````
+Titles must be separated from the link using a [whitespace].
+Other [Unicode whitespace] like non-breaking space doesn't work.
+
+```````````````````````````````` example
+[link](/url "title")
+.
+<p><a href="/url%C2%A0%22title%22">link</a></p>
+````````````````````````````````
+
+
Nested balanced quotes are not allowed without escaping:
```````````````````````````````` example
[link reference definition] elsewhere in the
document and is not followed by `[]` or a link label.
The contents of the first link label are parsed as inlines,
-which are used as the link's text. the link's URI and title
+which are used as the link's text. The link's URI and title
are provided by the matching link reference definition.
Thus, `[foo]` is equivalent to `[foo][]`.
````````````````````````````````
-Full references take precedence over shortcut references:
+Full and compact references take precedence over shortcut
+references:
```````````````````````````````` example
[foo][bar]
<p><a href="/url2">foo</a></p>
````````````````````````````````
+```````````````````````````````` example
+[foo][]
+
+[foo]: /url1
+.
+<p><a href="/url1">foo</a></p>
+````````````````````````````````
+
+Inline links also take precedence:
+
+```````````````````````````````` example
+[foo]()
+
+[foo]: /url1
+.
+<p><a href="">foo</a></p>
+````````````````````````````````
+
+```````````````````````````````` example
+[foo](not a link)
+
+[foo]: /url1
+.
+<p><a href="/url1">foo</a>(not a link)</p>
+````````````````````````````````
In the following case `[bar][baz]` is parsed as a reference,
`[foo]` as normal text:
A regular line break (not in a code span or HTML tag) that is not
preceded by two or more spaces or a backslash is parsed as a
-softbreak. (A softbreak may be rendered in HTML either as a
+[softbreak](@). (A softbreak may be rendered in HTML either as a
[line ending] or as a space. The result will be the same in
browsers. In the examples here, a [line ending] will be used.)
[lazy continuation line].
2. Next, after consuming the continuation markers for existing
-blocks, we look for new block starts (e.g. `>` for a block quote.
+blocks, we look for new block starts (e.g. `>` for a block quote).
If we encounter a new block start, we close any blocks unmatched
in step 1 before creating the new block as a child of the last
matched block.
-\r
-data Foo a = Foo a\r
-\r
-f :: Foo a -> a\r
-f = \Foo a -> a \r
-\r
-main = "Not to be executed"\r
---\r
-5:6-5:11: Arity is 1 but 2 patterns have been given.
\ No newline at end of file
+data Foo a = Foo a
+
+f :: Foo a -> a
+f = \Foo a -> a
+
+main = "Not to be executed"
+--
+3:1-3:2: Possible problem: type declaration has 1 parameter types, but function definition has 2 parameters.
+4:6-4:11: Arity is 1 but 2 patterns have been given.
+--
+import "Prelude"
+
+f :: Integer -> Integer -> <Proc> Integer
+f x = do
+ print x
+ x
+
+main = "Not to be executed"
+--
+3:1-3:2: Possible problem: type declaration has 2 parameter types, but function definition has 1 parameters.
+5:5-5:12: No side-effects allowed here.
+6:5-6:6: Expected <Integer -> <Proc> Integer> got <Integer>.
\ No newline at end of file
--- /dev/null
+import "Prelude"\r
+\r
+slowSum :: [Integer] -> <Proc> Integer\r
+slowSum list = getRef answer\r
+ where\r
+ answer = ref 0\r
+ \r
+ constraint El Integer\r
+ \r
+ ?x <- list => El ?x\r
+ -El ?x, -El ?y => El (?x + ?y)\r
+ El ?x => answer := ?x\r
+ \r
+main = slowSum [1,6,9]\r
+--\r
+16\r
+--\r
+import "Prelude"\r
+\r
+slowGcd :: [Integer] -> <Proc> Integer\r
+slowGcd list = getRef answer\r
+ where\r
+ answer = ref 0\r
+ \r
+ constraint Gcd Integer\r
+ \r
+ ?x <- list => Gcd ?x\r
+ -Gcd 0 => True\r
+ -Gcd ?m, Gcd ?n, ?n <= ?m => Gcd (?m `mod` ?n)\r
+ Gcd ?answer => answer := ?answer\r
+ \r
+main = slowGcd [12,20]\r
+--\r
+4\r
+--\r
+import "Prelude"\r
+\r
+isReachable :: [(Integer,Integer)] -> Integer -> Integer -> <Proc> Boolean\r
+isReachable edges a b = getRef answer\r
+ where\r
+ answer = ref False\r
+ \r
+ constraint Edge Integer Integer\r
+ constraint Reachable Integer\r
+ \r
+ (?x,?y) <- edges => Edge ?x ?y\r
+ True => Reachable a\r
+ Reachable ?x, Edge ?x ?y => Reachable ?y\r
+ Reachable b => answer := True\r
+\r
+graph :: [(Integer, Integer)]\r
+graph = [(0,1), (1,2), (2,3), (4,5)]\r
+\r
+main = (isReachable graph 0 3, isReachable graph 0 5)\r
+--\r
+(true,false)\r
+--\r
+import "StandardLibrary"\r
+\r
+primes1 limit = MList.freeze answer\r
+ where\r
+ answer = MList.create ()\r
+ MList.add answer 2\r
+ \r
+ constraint Prime Integer\r
+ constraint PrimeCandidate Integer\r
+ \r
+ True => PrimeCandidate 3\r
+ -PrimeCandidate ?x, ?x > limit => True\r
+ -PrimeCandidate ?x, Prime ?y, ?x `mod` ?y = 0 => PrimeCandidate (?x + 2)\r
+ -PrimeCandidate ?x => MList.add answer ?x, Prime ?x, PrimeCandidate (?x + 2)\r
+\r
+main = primes1 30\r
+--\r
+[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]\r
+--\r
+import "StandardLibrary"\r
+\r
+powersOfTwo n = sort (MList.freeze answer)\r
+ where\r
+ answer = MList.create ()\r
+ \r
+ constraint N Integer\r
+ \r
+ ?i <- [1..n] => N 1\r
+ -N ?x, -N ?x => N (2*?x)\r
+ N ?x => MList.add answer ?x\r
+ \r
+main = powersOfTwo 25\r
+--\r
+[1, 8, 16]\r
+--\r
+import "StandardLibrary"\r
+\r
+main = MList.freeze answer\r
+ where\r
+ answer = MList.create ()\r
+ add = MList.add answer\r
+ \r
+ constraint A\r
+ constraint B\r
+ constraint C\r
+ \r
+ A => add "A1"\r
+ B => add "B1"\r
+ C => add "C1"\r
+ A => add "A2"\r
+ B => add "B2"\r
+ C => add "C2"\r
+ \r
+ True => A\r
+ -A => B\r
+ -B => C\r
+--\r
+[A1, A2, B1, B2, C1, C2] \r
+--\r
+import "StandardLibrary"\r
+\r
+graph = [("1","2"), ("2","3"), ("3","4"), ("3","5"), ("1","4"), ("5","5")]\r
+\r
+main = sort (MList.freeze answer)\r
+ where\r
+ answer = MList.create ()\r
+ \r
+ constraint Init\r
+ constraint Edge String String\r
+ constraint Degree String Integer\r
+ \r
+ True => Init\r
+ (?x, ?y) <- graph => Edge ?x ?y\r
+ \r
+ Init, Edge ?x ?y => Degree ?x 1, Degree ?y 1\r
+ Init, -Degree ?x ?a, -Degree ?x ?b => Degree ?x (?a + ?b)\r
+ -Init => True\r
+\r
+ -Degree ?x 0 => print "Remove node \(?x)"\r
+ -Degree ?x ?a, -Edge ?x ?x => Degree ?x (?a - 2), print "Remove loop (\(?x),\(?x))"\r
+ -Degree ?x ?a, -Edge ?x ?y, -Degree ?y ?b, (?a==1 || ?b==1) => Degree ?x (?a - 1), Degree ?y (?b - 1), print "Remove dangling edge (\(?x),\(?y))"\r
+ -Degree ?y 2, -Edge ?x ?y, -Edge ?y ?z => Edge ?x ?z, print "Simplify path (\(?x),\(?y),\(?z))"\r
+ \r
+ Edge ?x ?y => MList.add answer (?x, ?y)\r
+--\r
+[(1,4), (1,4)]\r
+--\r
+import "StandardLibrary"\r
+\r
+uniq :: [a] -> <Proc> [a]\r
+uniq l = MList.freeze answer\r
+ where\r
+ answer = MList.create ()\r
+ \r
+ constraint El a\r
+ ?x <- l => El ?x\r
+ -El ?x, El ?x => True\r
+ El ?x => MList.add answer ?x\r
+ \r
+main = sort $ uniq [1,1,2,2,3]\r
+--\r
+[1, 2, 3]
\ No newline at end of file
--- /dev/null
+import "Prelude"\r
+\r
+gSum :: Additive a => [a] -> <Proc> a\r
+gSum list = getRef answer\r
+ where\r
+ answer = ref zero\r
+ \r
+ constraint El a\r
+ \r
+ ?x <- list => El ?x\r
+ -El ?x, -El ?y => El (?x + ?y)\r
+ El ?x => answer := ?x\r
+ \r
+main = (gSum [1,6,9], gSum [1.0,6.0,9.0]) \r
+--\r
+(16,16.0)\r
+--\r
+import "StandardLibrary"\r
+\r
+topologicalSort :: [(a,a)] -> <Proc> [a]\r
+topologicalSort dependencies = MList.freeze answer\r
+ where\r
+ answer = MList.create ()\r
+ \r
+ (?x,?y) <- dependencies => Dep ?x ?y, InDegree ?x 0, InDegree ?y 1\r
+ -InDegree ?x ?a, -InDegree ?x ?b => InDegree ?x (?a + ?b)\r
+ InDegree ?x 0 => AdjustInDegrees ?x, MList.add answer ?x\r
+ AdjustInDegrees ?x, Dep ?x ?y => InDegree ?y (-1)\r
+ \r
+main = topologicalSort [(2,4),(3,7),(7,2),(1,3)]\r
+--\r
+[1, 3, 7, 2, 4]\r
+--\r
+import "StandardLibrary"\r
+\r
+topologicalSort :: Show a => [(a,a)] -> <Proc> [a]\r
+topologicalSort dependencies = MList.freeze answer\r
+ where\r
+ answer = MList.create ()\r
+ \r
+ -Candidate ?x, Candidate ?x => True\r
+ (?x,?y) <- dependencies => Dep ?x ?y, Candidate ?x\r
+ -Candidate ?x, Dep _ ?x => True\r
+ Candidate ?x => MList.add answer ?x \r
+ Candidate ?x, -Dep ?x ?y => Candidate ?y\r
+\r
+main = topologicalSort [(2,4),(3,7),(7,2),(1,3)]\r
+--\r
+[1, 3, 7, 2, 4]\r
--- /dev/null
+import "Prelude"\r
+\r
+main = ()\r
+ where\r
+ A ?x => print ?x\r
+ A ?x, not A (?x+1) => A (?x-1)\r
+ True => A 0\r
+--\r
+()\r
+ \r
+\r
--- /dev/null
+)\r
+--\r
+1:1-1:2: No corresponding opening parenthesis for ')'.\r
+--\r
+}\r
+--\r
+1:1-1:2: No corresponding opening parenthesis for '}'.\r
+--\r
+]\r
+--\r
+1:1-1:2: No corresponding opening parenthesis for ']'.
\ No newline at end of file
import "Prelude"\r
\r
+newEq = (==)\r
+\r
main = """\r
\(newEq () ())\r
\(newEq True True)\r
\r
f p l = (foldl (+) (map ((+)p) l)) + p\r
--\r
-3:1-3:39: Couldn't simplify all effect subsumptions away. The current compiler cannot handle this situation. Try adding more type annotations.\r
3:25-3:31: Type [a b] -> <c> a b is not a subtype of a.
\ No newline at end of file
--- /dev/null
+import "Prelude"\r
+\r
+main = do\r
+ x = ref 3\r
+ if 2 > 1\r
+ then x := 4\r
+ if 1 > 2\r
+ then x := 8\r
+ getRef x\r
+--\r
+4
\ No newline at end of file
main = \ /* no parameters */ -> 3
--
-2:30-2:32: Unexpected token '->' (ARROW). Expected one of ATTACHED_HASH, BEGIN_STRING, BLANK, CHAR, DO, ENFORCE, EQ, ESCAPED_SYMBOL, FLOAT, ID, IF, INTEGER, LAMBDA, LBRACKET, LET, LPAREN, MATCH, MDO, SELECT, SELECT_DISTINCT, SELECT_FIRST, TRANSFORMATION, WHEN.
+2:30-2:32: Unexpected token '->' (ARROW). Expected one of ATTACHED_HASH, BEGIN_STRING, BLANK, CHAR, DO, ENFORCE, EQ, ESCAPED_SYMBOL, FLOAT, ID, IF, INTEGER, LAMBDA, LAMBDA_MATCH, LBRACKET, LET, LPAREN, MATCH, MDO, SELECT, SELECT_DISTINCT, SELECT_FIRST, TRANSFORMATION.
\ No newline at end of file
--- /dev/null
+import "Prelude"\r
+\r
+f :: Maybe String -> String\r
+f = \match\r
+ Just a -> a\r
+ Nothing -> ""\r
+\r
+main = f Nothing + f (Just "foo")\r
+--\r
+foo\r
import "JavaBuiltin" as Java\r
\r
-(==) = Java.icmpeq\r
-\r
@macro\r
(&<&) :: Integer -> Integer -> Integer\r
a &<& b = if cmp == 0 then b else cmp\r
then go (i-1)\r
else take i l \r
\r
-instance (Eq a, Additive a) => Additive (Poly a) where\r
+instance (Additive a) => Additive (Poly a) where\r
zero = Poly []\r
Poly a + Poly b = \r
Poly ( \r
la = length a\r
lb = length b \r
\r
-instance (Eq a, Ring a) => Ring (Poly a) where\r
+instance (Ring a) => Ring (Poly a) where\r
one = Poly [one]\r
neg (Poly l) = Poly (map neg l)\r
a - b = a + (neg b)\r
\r
infixl 7 (%)\r
infixl 6 (+)\r
-infix 4 (==), (<)\r
+infix 4 (<)\r
\r
(+) = Java.iadd\r
(%) = Java.irem\r
(<) = Java.icmplt\r
-(==) = Java.icmpeq\r
\r
isPrime p = isPrimeAux (2 :: Integer) p\r
where\r
--- /dev/null
+import "StandardLibrary"\r
+\r
+rt :: Serializable a => a -> a\r
+rt v = deserialize (serialize v)\r
+\r
+main :: String\r
+main = do\r
+ a = (1 :: Integer,"asd")\r
+ b = MMap.create ()\r
+ MMap.put b "asdasd" (4 :: Long)\r
+ show (rt a, MMap.get (rt b) "asdasd")\r
+--\r
+((1, "asd"), Just 4)
\ No newline at end of file
| SigNeg Signal\r
| SigMul [Signal]\r
\r
-deriving instance Eq Signal\r
-deriving instance Hashable Signal\r
deriving instance Show Signal\r
\r
instance Additive Signal where\r
-stringSum :: String -> Integer\r
-stringSum "(\(a),\(b),\(c))" = a + b + c\r
+import "Prelude"\r
\r
-main = stringSum "(1,2,3)"\r
+main = match "abc123def" with\r
+ "abc\(x)fed" -> "X\(x)"\r
+ "cba\(x)def" -> "Y\(x)"\r
+ "abc\(x)def" -> "Z\(x)"\r
+ x -> "W\(x)"\r
--\r
-6
\ No newline at end of file
+Z123
\ No newline at end of file
--- /dev/null
+import "Prelude"\r
+// Test optimized special cases\r
+\r
+main = let\r
+ a = "123"\r
+ b = "456"\r
+ c = "\(a)"\r
+ d = "abc\(b)"\r
+ e = "\(d)def"\r
+ in "\(c)\(e)"\r
+--\r
+123abc456def
\ No newline at end of file
@where
Fib (?n+2) (?a + 1)
-/*
+
rule PrintIt where
@when
Fib ?n ?a
@to
Execute (print "\(?n) -> \(?a)")
-*/
+
main = transformation OneShotForward where
Fib 0 1
Fib 1 1
a = =
b = 4
--
-1:5-1:6: Unexpected token '=' (EQUALS). Expected one of ATTACHED_HASH, BEGIN_STRING, BLANK, CHAR, DO, ENFORCE, EQ, ESCAPED_SYMBOL, FLOAT, ID, IF, INTEGER, LAMBDA, LBRACKET, LET, LPAREN, MATCH, MDO, MINUS, SELECT, SELECT_DISTINCT, SELECT_FIRST, TRANSFORMATION, WHEN.
\ No newline at end of file
+1:5-1:6: Unexpected token '=' (EQUALS). Expected one of ATTACHED_HASH, BEGIN_STRING, BLANK, CHAR, DO, ENFORCE, EQ, ESCAPED_SYMBOL, FLOAT, ID, IF, INTEGER, LAMBDA, LAMBDA_MATCH, LBRACKET, LET, LPAREN, MATCH, MDO, MINUS, SELECT, SELECT_DISTINCT, SELECT_FIRST, TRANSFORMATION.
\ No newline at end of file
--- /dev/null
+import "Prelude"\r
+\r
+f :: String -> String\r
+f (split "/" -> [a,b]) = "\(a)foo\(b)"\r
+f (split "/" -> [a,b,c]) = "\(a)foo\(b)bar\(c)"\r
+f str = str\r
+\r
+main = f "123" + f "abc/def" + f "123/456/789"\r
+--\r
+123abcfoodef123foo456bar789\r
--- /dev/null
+package org.simantics.scl.compiler.tests.unit;\r
+\r
+import java.lang.reflect.Constructor;\r
+import java.lang.reflect.Field;\r
+import java.lang.reflect.Method;\r
+\r
+import org.junit.Assert;\r
+import org.junit.Test;\r
+import org.simantics.scl.compiler.compilation.CompilationContext;\r
+import org.simantics.scl.compiler.elaboration.chr.CHRRuleset;\r
+import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint;\r
+import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint.IndexInfo;\r
+import org.simantics.scl.compiler.environment.specification.EnvironmentSpecification;\r
+import org.simantics.scl.compiler.errors.Locations;\r
+import org.simantics.scl.compiler.internal.codegen.chr.CHRCodeGenerator;\r
+import org.simantics.scl.compiler.internal.codegen.types.JavaTypeTranslator;\r
+import org.simantics.scl.compiler.internal.codegen.utils.JavaNamingPolicy;\r
+import org.simantics.scl.compiler.internal.codegen.utils.ModuleBuilder;\r
+import org.simantics.scl.compiler.module.repository.ModuleRepository;\r
+import org.simantics.scl.compiler.runtime.MutableClassLoader;\r
+import org.simantics.scl.compiler.runtime.RuntimeEnvironment;\r
+import org.simantics.scl.compiler.tests.InitialRepository;\r
+import org.simantics.scl.compiler.types.Type;\r
+import org.simantics.scl.compiler.types.Types;\r
+\r
+public class TestCHRCodeGenerator {\r
+ @Test\r
+ public void testCodeGenerator() throws Throwable {\r
+ try {\r
+ ModuleRepository repository = InitialRepository.getInitialRepository();\r
+ RuntimeEnvironment environment = repository.createRuntimeEnvironment(EnvironmentSpecification.of("StandardLibrary", "", "Builtin", ""), getClass().getClassLoader());\r
+ JavaNamingPolicy policy = new JavaNamingPolicy("Expression");\r
+ JavaTypeTranslator jtt = new JavaTypeTranslator(environment.getEnvironment());\r
+ CompilationContext compilationContext = new CompilationContext();\r
+ compilationContext.environment = environment.getEnvironment();\r
+ compilationContext.javaTypeTranslator = jtt;\r
+ compilationContext.namingPolicy = policy;\r
+ ModuleBuilder moduleBuilder = new ModuleBuilder(policy, jtt);\r
+ \r
+ CHRRuleset ruleset = new CHRRuleset(); \r
+ CHRConstraint exampleFact = new CHRConstraint(Locations.NO_LOCATION, "ExampleFact", new Type[] { Types.INTEGER, Types.INTEGER });\r
+ ruleset.constraints.add(exampleFact);\r
+ \r
+ System.out.println("==============================================================================================");\r
+ ruleset.initializeCodeGeneration(compilationContext);\r
+ exampleFact.indices.put(0, new IndexInfo(0, "ff", null, null));\r
+ exampleFact.indices.put(1, new IndexInfo(1, "bf", null, null));\r
+ exampleFact.indices.put(2, new IndexInfo(2, "fb", null, null));\r
+ exampleFact.indices.put(3, new IndexInfo(3, "bb", null, null));\r
+ exampleFact.setMayBeRemoved();\r
+\r
+ CHRCodeGenerator.generateStore(moduleBuilder, ruleset);\r
+ \r
+ MutableClassLoader classLoader = environment.getMutableClassLoader();\r
+ classLoader.addClasses(moduleBuilder.getClasses());\r
+ \r
+ String storeClassName = ruleset.storeClassName.replace('/', '.');\r
+ Class<?> storeClass = classLoader.loadClass(storeClassName);\r
+ Class<?> factClass = classLoader.loadClass(storeClassName+"$ExampleFact");\r
+ Constructor<?> factConstructor = factClass.getConstructor(int.class, int.class, int.class);\r
+ Method addMethod = factClass.getMethod("add", storeClass);\r
+ Method removeMethod = factClass.getMethod("remove", storeClass);\r
+ Method getMethod = storeClass.getMethod("ExampleFact$bf", int.class);\r
+ Field nextField = factClass.getField("bfNext");\r
+ \r
+ Object store = storeClass.newInstance();\r
+ Object fact1 = factConstructor.newInstance(0, 1,2);\r
+ Object fact2 = factConstructor.newInstance(0, 1,3);\r
+ Object fact3 = factConstructor.newInstance(0, 2,4);\r
+ Object fact4 = factConstructor.newInstance(0, 1,4);\r
+ addMethod.invoke(fact1, store);\r
+ addMethod.invoke(fact4, store);\r
+ addMethod.invoke(fact2, store);\r
+ addMethod.invoke(fact3, store);\r
+ removeMethod.invoke(fact4, store);\r
+ {\r
+ Object f1 = getMethod.invoke(store, 1);\r
+ Assert.assertEquals(fact2, f1);\r
+ Object f2 = nextField.get(f1);\r
+ Assert.assertEquals(fact1, f2);\r
+ Object f3 = nextField.get(f2);\r
+ Assert.assertEquals(null, f3);\r
+ }\r
+ removeMethod.invoke(fact2, store);\r
+ {\r
+ Object f1 = getMethod.invoke(store, 1);\r
+ Assert.assertEquals(fact1, f1);\r
+ Object f2 = nextField.get(f1);\r
+ Assert.assertEquals(null, f2);\r
+ }\r
+ addMethod.invoke(fact2, store);\r
+ removeMethod.invoke(fact1, store);\r
+ {\r
+ Object f1 = getMethod.invoke(store, 1);\r
+ Assert.assertEquals(fact2, f1);\r
+ Object f2 = nextField.get(f1);\r
+ Assert.assertEquals(null, f2);\r
+ }\r
+ removeMethod.invoke(fact2, store);\r
+ {\r
+ Object f1 = getMethod.invoke(store, 1);\r
+ Assert.assertEquals(null, f1);\r
+ }\r
+ } catch(Throwable e) {\r
+ e.printStackTrace();\r
+ throw e;\r
+ }\r
+ }\r
+ \r
+}\r
\r
import java.util.Collection;\r
\r
+import org.junit.Assert;\r
import org.junit.Test;\r
import org.simantics.scl.compiler.environment.filter.AcceptAllNamespaceFilter;\r
import org.simantics.scl.compiler.environment.filter.NamespaceFilter;\r
import org.simantics.scl.compiler.environment.filter.PositiveNamespaceFilter;\r
\r
import gnu.trove.set.hash.THashSet;\r
-import junit.framework.Assert;\r
\r
public class TestNamespaceFilter {\r
\r