]> gerrit.simantics Code Review - simantics/platform.git/commitdiff
Merged changes from feature/scl to master. 21/221/6
authorHannu Niemistö <hannu.niemisto@semantum.fi>
Tue, 20 Dec 2016 10:09:30 +0000 (12:09 +0200)
committerHannu Niemistö <hannu.niemisto@semantum.fi>
Tue, 20 Dec 2016 12:39:38 +0000 (14:39 +0200)
This commit contains lots of SCL compiler and runtime changes:
* New CHR-rule based sublanguage. This change alters meaning of
when-keyword and so some code using when may break.
* Removed type classes Eq and Hashable. Compiler now generates and uses
Java methods equals and hashCode. This change is needed for better
interoperability with Java code.
* Type based overloading for symbols imported from different modules
* Some expressions ignore their return value (statements in
do/let/where, if and match cases if the return value of if/match is
ignored). These expressions can have any type and if/match expression
branches may have different types. Also if-expressions may have only
else branch. If the return value of apply-experssion is ignored, the
expression cannot be partial application that does not have
side-effects.
* View pattern support
(https://ghc.haskell.org/trac/ghc/wiki/ViewPatterns)
* Lambda-match support
(https://ghc.haskell.org/trac/ghc/wiki/LambdasVsPatternMatching)
* String interpolation can be used also in patterns
* SCL compiler regression test suite has been moved to a new bundle
org.simantics.scl.compiler.tests
* Improvements to SCL module editor syntax coloring
* SCL compiler refactorings, for example all name constants are now in a
dedicated class Names and CompilationContext merging old context classes
* Improved byte code for comparisons
* Improved code generation from string interpolation
* Anonymous object support in SCL backend (not yet frontend support)
* Bugfixes and new regression tests

refs #6888

Change-Id: I9d4c001d0323069d3b86a83369fa3581f02ee305

592 files changed:
bundles/org.simantics.image.ui/scl/Simantics/Image.scl
bundles/org.simantics.modeling.ui/scl/Simantics/Testing/ActionBrowseContext.scl
bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphPropertyRelation.java
bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphRelation.java
bundles/org.simantics.scl.compiler/.classpath
bundles/org.simantics.scl.compiler/.settings/org.eclipse.core.resources.prefs [deleted file]
bundles/org.simantics.scl.compiler/ActiveTests.launch [deleted file]
bundles/org.simantics.scl.compiler/META-INF/MANIFEST.MF
bundles/org.simantics.scl.compiler/SCLRegressionTests.launch [deleted file]
bundles/org.simantics.scl.compiler/build.properties
bundles/org.simantics.scl.compiler/src/org/cojen/classfile/TypeDesc.java
bundles/org.simantics.scl.compiler/src/org/cojen/util/KeyFactory.java [deleted file]
bundles/org.simantics.scl.compiler/src/org/cojen/util/ReferencedValueHashMap.java
bundles/org.simantics.scl.compiler/src/org/cojen/util/WeakIdentityMap.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/commands/CommandSession.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/common/names/Names.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/CodeGeneration.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/CompilationContext.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/DeclarationClassification.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/DocumentationGeneration.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/Elaboration.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/EnvironmentOfModule.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/NameExistenceChecks.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/NamespaceOfModule.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/SCLCompiler.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/TypeChecking.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/TypeCheckingScheduler.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/BooleanConstant.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/ComparisonFunction.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/JavaComparisonOperation.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/JavaComparisonToZeroOperation.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/SCLConstant.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/StringInterpolation.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/UnsafeCoerce.java [deleted file]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/generic/CallJava.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/generic/Pop2OutputFilter.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/generic/PopOutputFilter.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/singletons/IncreaseByOne.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/singletons/ListElement.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/singletons/ListLength.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/singletons/NullCheck.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/singletons/UnsafeCoerce.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRLiteral.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRQuery.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRRelation.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRRule.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRRuleset.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRRulesetObject.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/analysis/UsageAnalysis.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/AccessFactOp.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/AssignOp.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/CheckOp.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/ClaimOp.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/ExecuteOp.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/IterateConstraintOp.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/IterateListOp.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/IterateRelationOp.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/MatchOp.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/PartnerFact.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/PlanContext.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/PlanOp.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/PlanRealizer.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/PostCommitOp.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/PreCommitOp.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/PrioritizedPlan.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/planning/PlanPriorityQueue.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/planning/PrePlanItem.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/planning/QueryPlanningContext.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/planning/items/CheckPrePlanItem.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/planning/items/EqualsPrePlanItem.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/planning/items/GenericPrePlanItem.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/planning/items/MemberPrePlanItem.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/relations/CHRConstraint.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/relations/ExternalCHRRelation.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/relations/SpecialCHRRelation.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/relations/UnresolvedCHRRelation.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/translation/CHRTranslation.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/contexts/SimplificationContext.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/contexts/TranslationContext.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/contexts/TypeTranslationContext.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/contexts/TypingContext.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EApply.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EAsPattern.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EBinary.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EBlock.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ECHRRuleset.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EConstant.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EFieldAccess.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EIf.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EIntegerLiteral.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ELiteral.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ERange.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ERealLiteral.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ERuleset.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ESelect.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EStringLiteral.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EVariable.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EViewPattern.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/Expression.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ExpressionTransformer.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ExpressionVisitor.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/Expressions.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/StandardExpressionTransformer.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/StandardExpressionVisitor.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/block/BindStatement.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/block/CHRStatement.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/block/ConstraintStatement.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/block/GuardStatement.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/block/LetStatement.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/block/RuleStatement.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/block/Statement.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/block/StatementGroup.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/printing/ExpressionToStringVisitor.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/Builtins.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/EqualsFunction.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/ListConstructor.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/MemberRelation.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/OptionalRelation.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/modules/TypeAlias.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/modules/TypeConstructor.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/modules/TypeDescriptor.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QNegation.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/compilation/EnforcingContext.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/compilation/QueryCompilationContext.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/relations/AbstractRelation.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/relations/ConcreteRelation.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/relations/LocalRelation.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/relations/SCLRelation.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/relations/TransitiveClosureRelation.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/AbstractEnvironment.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/EmptyNamespace.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/Environment.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/Environments.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/Namespace.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/NamespaceImpl.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/analysis/LoopAnalysis.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/analysis/StatementBrowser.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/chr/CHRCodeGenerator.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/chr/ExampleStore.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/optimization/FoldlBuildFusion.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/optimization/OptimizationMap.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/references/Val.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/SSABlock.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/SSAClosure.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/SSAExit.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/SSAFunction.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/SSAModule.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/SSAObject.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/SSAStatement.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/StaticField.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/binders/ClosureBinder.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/binders/FunctionBinder.java [deleted file]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/exits/If.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/exits/Jump.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/exits/Switch.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/exits/Throw.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/statements/LetApply.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/statements/LetFunctions.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/types/JavaTypeTranslator.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/types/StandardTypeConstructor.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/ClassBuilder.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/CodeBuilderUtils.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/JavaNamingPolicy.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/MethodBuilder.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/MethodBuilderBase.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/SSALambdaLiftingContext.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/ValRefVisitor.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/writer/CodeWriter.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/writer/ModuleWriter.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/writer/RecursiveDefinitionWriter.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/deriving/EqDeriver.java [deleted file]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/deriving/HashableDeriver.java [deleted file]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/deriving/IODeriver.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/deriving/InstanceDerivers.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/deriving/OrdDeriver.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/deriving/ShowDeriver.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/constraints/ConstraintEnvironment.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/constraints/ConstraintSolver.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/matching/PatternMatchingCompiler.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/matching/Row.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/matching2/PatternMatchingCompiler2.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/matching2/Row2.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/profiling/BranchPointInjector.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/transformations/TransformationBuilder.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/transformations/UnifiableFactory.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCL.grammar
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCLLexer.flex
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCLLexer.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCLParser.dat
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCLParser.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCLParserImpl.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCLPostLexer.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCLTerminals.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/types/TApplyAst.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/types/TVarAst.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/html/SCLDocumentationExtensionNodeHandler.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/module/ConcreteModule.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/module/LazyModule.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/module/Module.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/module/repository/ModuleRepository.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/runtime/ExpressionClassLoader.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/runtime/RuntimeModule.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/source/TextualModuleSource.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/top/ExpressionEvaluator.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/top/SCLCompilerConfiguration.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/top/ToplevelEffectDecorator.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/Skeletons.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/TApply.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/TCon.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/TForAll.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/TFun.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/TMetaVar.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/TPred.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/TUnion.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/TVar.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/Type.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/Types.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/util/SkeletonKeyMap.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/ActiveTests.java [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/FindAllowedChars.java [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/ModuleRegressionTests.java [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/RegressionTests.java [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/ScriptTestBase.java [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/ScriptTests.java [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/TestAll.java [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/TestBase.java [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/TestClassNaming.java [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/TestCommandParsing.java [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/TestCommandSession.java [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/TestExpressionEvaluator.java [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/TestTypeDesc.java [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/UnimplementedTests.java [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/experimentation/RecursiveInitialization.java [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/experimentation/TestEquals.java [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/experimentation/TestTypeDesc.java [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/imports/Maybe4Imports.java [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/markdown/spec.txt [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/performance/SumOfInverses.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/performance/SumOfInverses2.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/AmbiguousType.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ApplicationOfNunfunction.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Arity1.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/AsPattern.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/BigContext.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/BigFunction.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/BigInstances.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/BinaryOperators1.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/BlankExpression.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/BooleanId.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Bug4450.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Character1.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ClashingClass.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ClashingData.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ClashingInstance.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ClashingValueDefinition.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ClashingValueType.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Collaz.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Compose.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Composition.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ConjunctionMacro.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Constant.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ConstructorNameClash.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/DefaultMethods1.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Deriving3.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Deriving4.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/DifferentBranchTypes.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Div.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/DoubleConversion.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/DoubleEffect.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Effects1.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Effects2.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Effects3.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Effects4.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Effects5.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Effects6.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/EmptyLet.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Equality.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Equations1.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ExistentialData.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ExistentialData2.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ExpressionParsing.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/FaultyRecursion.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Fibonacci.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Fibonacci2.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Fibonacci3.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/FingerTree.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/FoldMissingInitialValue.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/FoldlBuild1.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/FoldlBuild2.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Forall1.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Forall2.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Forall3.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Formula.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/FromDynamic.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/FromDynamic2.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/FromDynamic3.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/FromDynamic4.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/FromDynamic5.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/FunctionFunctor.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/FunctionalDependencies1.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/FunctionalDependencies2.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Functor.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/FunctorM1.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Generalization.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/GenericMutualRecursion.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/GlobalVariables.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/GraphPrelude.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/GuardedExpressionBug.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Guards1.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Guards2.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/IdAsOperator.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/IllegalChar.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ImportJavaConstructor.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ImportRef.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InconsistentArity.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InconsistentIndentation.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/IndentationAndParenthesis.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Index.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Inline1.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InlineLoop.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InstanceHierarchy.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InstanceIsTypoedAsClass.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InstanceTypeVariables.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InvalidClass1.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InvalidEncoding.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InvalidInstance1.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InvalidJavaTypeAnnotation.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InvalidKinds.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InvalidKinds2.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InvalidKinds3.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InvalidLambda.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InvalidModule.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InvalidPattern1.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InvalidPattern2.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InvalidPattern3.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InvalidPattern4.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InvalidRuleset1.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InvalidRuleset2.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InvalidTypeClassInstance1.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/JavaAccess1.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/JavaConstructors.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/JavaMethods.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/JavaTypes.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Kinds1.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/LP.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Lambda.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Layout1.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/List.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ListError1.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ListError2.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ListSyntax.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ListSyntax10.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ListSyntax11.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ListSyntax12.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ListSyntax2.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ListSyntax3.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ListSyntax4.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ListSyntax5.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ListSyntax6.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ListSyntax7.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ListSyntax8.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ListSyntax9.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ListSyntaxWithoutPrelude.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/LocalDefinitions.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/LocalDefinitions2.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/LocalDefinitions3.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/LocalDefinitions4.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/LocalDefinitions5.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Macros1.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Macros2.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Macros3.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Macros4.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Map1.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/MarketModel.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/MarketModel2.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Matching.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Matching2.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Matching3.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Matching3b.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Matching4.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Matching5.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/MatchingWithMissingParameter.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/MatchingWithoutTypeAnnotations.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/MaximumBy.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Maybe1.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Maybe2.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Maybe3.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Maybe4.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/MissingEffect.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/MissingMethod.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/MissingTypeParameter.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ModuleInitialization.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/MonadBug1.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/MonadSyntax1.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/MonadSyntax2.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Monads1.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/NoDefinitionErrorMessage.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/NoInstance.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/NoInstance2.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/NonassociativeOperator.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/NonexistentTypeClassInAnnotation.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/NonexistingEffect.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/OneLineMatch.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/OpenString1.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/OpenString2.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/OverloadedArithmetic1.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/OverloadedArithmetic2.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/OverloadedArithmetic3.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/OverloadedLiterals2.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Overloading1.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Overloading2.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Overloading3.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Parsing.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/PatternError.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/PolymorphicRecursion.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/PolymorphicRecursion2.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Polynomials.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/PrecedenceOfNonoperators.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Primes.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Proc1.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Proc2.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Proc3.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Pythagoras.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Random1.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/RangeSyntax.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Record1.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/RecordShorthand.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/RecursiveContext.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/RecursiveValues.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/RecursiveValues2.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/RecursiveValues3.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/RecursiveValues4.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/RedBlackTrees.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Relations1.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Relations2.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/RepeatedVariableInPattern.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/SSATypingBug.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Scanl.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Search.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Sections.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Select1.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Select2.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Select3.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Select4.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Select5.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Select6.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Select7.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Select8.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Select9.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/SelfReferringContextInTypeClass.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Serialization.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Serialization2.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Serialization3.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Set1.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/SharedTypeVariable.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ShortcutFusion.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Show1.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Signals.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/SinConst1.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Sort.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Sort2.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/SpecConstr1.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/StackTrace.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/StreamFusion.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/StringEscape.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/StringInterpolation1.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/StringInterpolation2.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/StringMatching1.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/SumOfInverses2.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Timing.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/TooManyParametersToSin.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Transformation1.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Transformation2.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Transformation3.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Transformation4.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Transformation5.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Transformation6.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Transformation7.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/TransformationOrder.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Tuples.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Tuples2.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/TypeAlias1.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/TypeAlias2.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/TypeAlias3.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/TypeAliasRefsToTypeAlias.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/TypeAnnotation1.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/TypeAnnotation2.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/TypeClass.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/TypeClass2.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/TypeClassBug1.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/TypeClassBug2.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/TypeInferenceBug2.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/TypeOf1.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/TypingBug1.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/TypingError1.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/TypingError2.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/UnaryMinus.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/UndefinedValue.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/UnexpectedToken.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Unification1.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/UnknownAnnotation.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/UnresolvedClass.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/UnresolvedTypeInAnnotation.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/UnresolvedTypeInInstance.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/UnresolvedVariable.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/UnresolvedVariable2.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ValueAsOperator.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ValueConversion.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Vector1.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Vector2.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Void1.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Void2.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Void3.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/While.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/While2.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/While3.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/WrongDefaultMethod.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/WrongInstanceMethod.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scripts/Arithmetic.sts [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scripts/Functions.sts [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scripts/Functions2.sts [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scripts/Lists.sts [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/unit/TestConstraintSolver.java [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/unit/TestNamespaceFilter.java [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/unit/TestSubSolver.java [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/unit/TestTypeParser.java [deleted file]
bundles/org.simantics.scl.data/scl/Data/Json.scl
bundles/org.simantics.scl.data/scl/Data/XML.scl
bundles/org.simantics.scl.db/scl/Simantics/DB.scl
bundles/org.simantics.scl.db/scl/Simantics/Variables.scl
bundles/org.simantics.scl.osgi/META-INF/MANIFEST.MF
bundles/org.simantics.scl.osgi/build.properties
bundles/org.simantics.scl.osgi/src/org/simantics/scl/osgi/internal/BundleModuleSource.java
bundles/org.simantics.scl.runtime/META-INF/MANIFEST.MF
bundles/org.simantics.scl.runtime/scl/Arbitrary.scl
bundles/org.simantics.scl.runtime/scl/ArrayList.scl
bundles/org.simantics.scl.runtime/scl/BigInteger.scl
bundles/org.simantics.scl.runtime/scl/Collection.scl
bundles/org.simantics.scl.runtime/scl/Databoard.scl
bundles/org.simantics.scl.runtime/scl/Prelude.scl
bundles/org.simantics.scl.runtime/scl/SList.scl
bundles/org.simantics.scl.runtime/scl/Vector.scl
bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/chr/CHRHashIndex.java [new file with mode: 0644]
bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/chr/CHRHashOverflowException.java [new file with mode: 0644]
bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/chr/Fact.java [new file with mode: 0644]
bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/chr/FactActivationQueue.java [new file with mode: 0644]
bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/chr/PriorityContainer.java [new file with mode: 0644]
bundles/org.simantics.scl.runtime/tests/org/simantics/scl/runtime/tests/TestCHRHashIndex.java [new file with mode: 0644]
bundles/org.simantics.scl.runtime/tests/org/simantics/scl/runtime/tests/TestFactActivationQueue.java [new file with mode: 0644]
bundles/org.simantics.scl.ui/META-INF/MANIFEST.MF
bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor/SCLSourceViewerConfigurationNew.java
bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor/completion/SCLTextEditorEnvironment.java
bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/DebugPartionTokenScanner.java [new file with mode: 0644]
bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/SCLModuleEditor2DocumentProvider.java
bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/SCLPartitionScanner.java [new file with mode: 0644]
bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/SCLPresentationReconciler.java [new file with mode: 0644]
bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/SingleTokenScanner.java [new file with mode: 0644]
bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/StringTokenScanner.java [new file with mode: 0644]
bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/info/SCLInfo.java
tests/org.simantics.scl.compiler.tests/META-INF/MANIFEST.MF
tests/org.simantics.scl.compiler.tests/logback.xml [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/ActiveTests.java
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/AllTestsForCoverage.java [moved from bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/TestActive.java with 51% similarity]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/ModuleRegressionTests.java
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/TestBase.java
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/TestClassNaming.java
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/TestCommandSession.java
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/TestExpressionEvaluator.java
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/markdown/MarkdownTests.java [moved from bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/markdown/RunMarkdownTests.java with 92% similarity]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/markdown/RunMarkdownTests.java [deleted file]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/markdown/spec.txt
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/CHR1.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/CHR2.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/CHR3.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ClosingBrace.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Equality.scl
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/FoldMissingInitialValue.scl
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/IfWithoutElse.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InvalidLambda.scl
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/LambdaMatch.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Macros2.scl
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Polynomials.scl
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Primes.scl
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Serialization4.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Signals.scl
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/StringInterpolation2.scl
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/StringInterpolation3.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Transformation2.scl
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/UnexpectedToken.scl
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ViewPatterns1.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/unit/TestCHRCodeGenerator.java [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/unit/TestNamespaceFilter.java

index df9ba836019a09c8b5a12aa43d8d9b4a29be4e4f..2faaaf9e2dd3fed2281ab90d8e00e496447d95cb 100644 (file)
@@ -1,7 +1,6 @@
 include "Simantics/Entity" hiding (nameOf)\r
 import "Simantics/Misc"\r
 import "Simantics/Library"\r
-import "Simantics/DrawingTemplate"\r
 \r
 type Image = Resource\r
 \r
index 471a83ef9cf8b84d865ba95921e2b6485315653a..510603d5194be82c216e2cee440dfe535ab3111a 100644 (file)
@@ -20,9 +20,6 @@ importJava "org.simantics.modeling.ui.actions.ModeledActions" where
     """\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
index 45ac24f1c7ad4f5913e933f3448b90f82d9d483f..4e450005b24b100f13b90b2bdeeb576f46a0aca9 100644 (file)
@@ -2,6 +2,8 @@ package org.simantics.modeling.scl;
 \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
@@ -10,7 +12,9 @@ import org.simantics.scl.compiler.elaboration.expressions.Variable;
 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
@@ -63,7 +67,7 @@ public class GraphPropertyRelation implements SCLRelation {
         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
@@ -72,9 +76,8 @@ public class GraphPropertyRelation implements SCLRelation {
         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
@@ -95,7 +98,7 @@ public class GraphPropertyRelation implements SCLRelation {
         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
@@ -108,4 +111,14 @@ public class GraphPropertyRelation implements SCLRelation {
         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
index 807d44a16612c48ff3d670b672b3ad0d6e00b0b9..72bfa128e9f58e5394414aa5876569c7d87598a9 100644 (file)
@@ -2,6 +2,7 @@ package org.simantics.modeling.scl;
 \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
@@ -10,7 +11,9 @@ import org.simantics.scl.compiler.elaboration.expressions.Variable;
 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
@@ -69,7 +72,7 @@ public class GraphRelation implements SCLRelation {
             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
@@ -80,7 +83,7 @@ public class GraphRelation implements SCLRelation {
             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
@@ -91,7 +94,7 @@ public class GraphRelation implements SCLRelation {
                     ? 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
@@ -101,7 +104,7 @@ public class GraphRelation implements SCLRelation {
                     : 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
@@ -121,7 +124,7 @@ public class GraphRelation implements SCLRelation {
         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
@@ -133,4 +136,50 @@ public class GraphRelation implements SCLRelation {
         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
index 1c982aa6bde2a2c322c13b59ff4443e110441a31..b862a296d38fe04269faeee6c9d77d11ff77380d 100755 (executable)
@@ -3,7 +3,5 @@
        <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
diff --git a/bundles/org.simantics.scl.compiler/.settings/org.eclipse.core.resources.prefs b/bundles/org.simantics.scl.compiler/.settings/org.eclipse.core.resources.prefs
deleted file mode 100644 (file)
index ba02823..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-eclipse.preferences.version=1\r
-encoding//tests/org/simantics/scl/compiler/tests/scl/InvalidEncoding.scl=ISO-8859-1\r
diff --git a/bundles/org.simantics.scl.compiler/ActiveTests.launch b/bundles/org.simantics.scl.compiler/ActiveTests.launch
deleted file mode 100644 (file)
index 379d4db..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-<?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
index 916e66cfd22f510b5c8ac238454a1e277015fc74..603cdaf4881c8a8eea8b1fca9f21d3908144eb28 100755 (executable)
@@ -2,14 +2,15 @@ Manifest-Version: 1.0
 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,
@@ -19,6 +20,10 @@ Export-Package: org.cojen.classfile,
  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,
@@ -39,6 +44,11 @@ Export-Package: org.cojen.classfile,
  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,
@@ -62,7 +72,6 @@ Export-Package: org.cojen.classfile,
  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
diff --git a/bundles/org.simantics.scl.compiler/SCLRegressionTests.launch b/bundles/org.simantics.scl.compiler/SCLRegressionTests.launch
deleted file mode 100644 (file)
index 893498e..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-<?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
index 2038552d7dc88b2c84f0ba651bc0f5a73c7422fd..33fbae442a6a2ac62cd1e16763b4a2f095d9482a 100755 (executable)
@@ -2,5 +2,4 @@ source.. = src/
 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
index cfc5a1deb0fcf7a303651c39782af93fc6e8742b..acf2bb18d643ae4f40c1d3a6d1896d9782787f63 100644 (file)
@@ -16,7 +16,6 @@
 
 package org.cojen.classfile;
 
-import java.io.Serializable;
 import java.lang.ref.SoftReference;
 import java.lang.reflect.Array;
 import java.util.Collections;
@@ -34,7 +33,7 @@ import org.cojen.util.WeakIdentityMap;
  * @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.
diff --git a/bundles/org.simantics.scl.compiler/src/org/cojen/util/KeyFactory.java b/bundles/org.simantics.scl.compiler/src/org/cojen/util/KeyFactory.java
deleted file mode 100644 (file)
index 1bd1b01..0000000
+++ /dev/null
@@ -1,709 +0,0 @@
-/*
- *  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);
-        }
-    }
-}
index d854fafecc77582743c1707f31c8be94c4fc14de..cf2772f408d349d7745d894876e9ddb2e827ec37 100644 (file)
@@ -46,6 +46,12 @@ import java.util.Set;
 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;
@@ -128,7 +134,7 @@ public abstract class ReferencedValueHashMap<K, V> extends AbstractMap<K, V>
 
     public boolean containsValue(Object value) {
         if (value == null) {
-            value = KeyFactory.NULL;
+            value = NULL;
         }
 
         Entry[] tab = this.table;
@@ -221,7 +227,7 @@ public abstract class ReferencedValueHashMap<K, V> extends AbstractMap<K, V>
                     }
                     count--;
                 } else if (e.hash == hash && key.equals(e.key)) {
-                    return (entryValue == KeyFactory.NULL) ? null : entryValue;
+                    return (entryValue == NULL) ? null : entryValue;
                 } else {
                     prev = e;
                 }
@@ -241,7 +247,7 @@ public abstract class ReferencedValueHashMap<K, V> extends AbstractMap<K, V>
                     }
                     this.count--;
                 } else if (e.key == null) {
-                    return (entryValue == KeyFactory.NULL) ? null : entryValue;
+                    return (entryValue == NULL) ? null : entryValue;
                 } else {
                     prev = e;
                 }
@@ -311,7 +317,7 @@ public abstract class ReferencedValueHashMap<K, V> extends AbstractMap<K, V>
 
     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.
@@ -336,7 +342,7 @@ public abstract class ReferencedValueHashMap<K, V> extends AbstractMap<K, V>
                     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;
                 }
@@ -358,7 +364,7 @@ public abstract class ReferencedValueHashMap<K, V> extends AbstractMap<K, V>
                     this.count--;
                 } else if (e.key == null) {
                     e.setValue(value);
-                    return (entryValue == KeyFactory.NULL) ? null : entryValue;
+                    return (entryValue == NULL) ? null : entryValue;
                 } else {
                     prev = e;
                 }
@@ -415,7 +421,7 @@ public abstract class ReferencedValueHashMap<K, V> extends AbstractMap<K, V>
                     this.count--;
 
                     e.setValue(null);
-                    return (entryValue == KeyFactory.NULL) ? null : entryValue;
+                    return (entryValue == NULL) ? null : entryValue;
                 } else {
                     prev = e;
                 }
@@ -443,7 +449,7 @@ public abstract class ReferencedValueHashMap<K, V> extends AbstractMap<K, V>
                     this.count--;
 
                     e.setValue(null);
-                    return (entryValue == KeyFactory.NULL) ? null : entryValue;
+                    return (entryValue == NULL) ? null : entryValue;
                 } else {
                     prev = e;
                 }
@@ -693,12 +699,12 @@ public abstract class ReferencedValueHashMap<K, V> extends AbstractMap<K, V>
 
         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;
         }
 
@@ -713,7 +719,7 @@ public abstract class ReferencedValueHashMap<K, V> extends AbstractMap<K, V>
             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())) &&
index 70030ab88d24888d07bafaf1d07124c221f6791f..b771a982fb3b5d77c7a902ff974f1045e62127a4 100644 (file)
@@ -208,7 +208,7 @@ public class WeakIdentityMap<K, V> extends AbstractMap<K, V> implements Map<K, V
 
     public boolean containsKey(Object key) {
         if (key == null) {
-            key = KeyFactory.NULL;
+            key = ReferencedValueHashMap.NULL;
         }
 
         Entry[] tab = this.table;
@@ -239,7 +239,7 @@ public class WeakIdentityMap<K, V> extends AbstractMap<K, V> implements Map<K, V
 
     public V get(Object key) {
         if (key == null) {
-            key = KeyFactory.NULL;
+            key = ReferencedValueHashMap.NULL;
         }
 
         Entry<K, V>[] tab = this.table;
@@ -329,7 +329,7 @@ public class WeakIdentityMap<K, V> extends AbstractMap<K, V> implements Map<K, V
 
     public V put(K key, V value) {
         if (key == null) {
-            key = (K) KeyFactory.NULL;
+            key = (K) ReferencedValueHashMap.NULL;
         }
 
         cleanup();
@@ -378,7 +378,7 @@ public class WeakIdentityMap<K, V> extends AbstractMap<K, V> implements Map<K, V
 
     public V remove(Object key) {
         if (key == null) {
-            key = KeyFactory.NULL;
+            key = ReferencedValueHashMap.NULL;
         }
 
         Entry<K, V>[] tab = this.table;
@@ -637,7 +637,7 @@ public class WeakIdentityMap<K, V> extends AbstractMap<K, V> implements Map<K, V
 
         public K getKey() {
             K key = Entry.this.get();
-            return key == KeyFactory.NULL ? null : key;
+            return key == ReferencedValueHashMap.NULL ? null : key;
         }
 
         public V getValue() {
@@ -661,7 +661,7 @@ public class WeakIdentityMap<K, V> extends AbstractMap<K, V> implements Map<K, V
             Object thisKey = get();
             if (thisKey == null) {
                 return false;
-            } else if (thisKey == KeyFactory.NULL) {
+            } else if (thisKey == ReferencedValueHashMap.NULL) {
                 thisKey = null;
             }
             return (thisKey == e.getKey()) &&
index e463a4e6a4ca420c8308e405c4dc0017dd321d8c..82d615ca89f476e248615ffb158075d5b7fa5826 100644 (file)
@@ -16,7 +16,7 @@ import java.util.List;
 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;
@@ -47,7 +47,6 @@ import org.simantics.scl.compiler.runtime.RuntimeEnvironment;
 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;
@@ -78,10 +77,6 @@ public class CommandSession {
     
     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(
@@ -202,7 +197,7 @@ public class CommandSession {
         }, 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();
@@ -212,7 +207,7 @@ public class CommandSession {
         }, 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;
@@ -255,7 +250,7 @@ public class CommandSession {
         }, 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;
@@ -267,13 +262,13 @@ public class CommandSession {
 
     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))
                             );
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/common/names/Names.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/common/names/Names.java
new file mode 100644 (file)
index 0000000..046d31f
--- /dev/null
@@ -0,0 +1,80 @@
+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
index 470b8e9f0701c0418fb08bf02757e0b4717616d5..52abbc6d87b48542b60e26152d917d4b64eaa22a 100644 (file)
@@ -25,7 +25,6 @@ import org.simantics.scl.compiler.elaboration.modules.SCLValueProperty;
 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;
@@ -37,7 +36,6 @@ import org.simantics.scl.compiler.internal.codegen.utils.ClassBuilder;
 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;
@@ -61,10 +59,8 @@ public class CodeGeneration {
     
     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;
@@ -75,28 +71,22 @@ public class CodeGeneration {
     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()]);
         
@@ -116,7 +106,7 @@ public class CodeGeneration {
     }
     
     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();
@@ -124,8 +114,6 @@ public class CodeGeneration {
                 continue;
 
             Name name = value.getName();
-            DecomposedExpression decomposed = 
-                    DecomposedExpression.decompose(expression);
             
             SCLConstant constant = new SCLConstant(name, value.getType());
             value.setValue(constant);            
@@ -177,7 +165,7 @@ public class CodeGeneration {
                 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;
@@ -199,7 +187,7 @@ public class CodeGeneration {
         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);        
@@ -247,7 +235,7 @@ public class CodeGeneration {
                     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);
                 }
@@ -274,7 +262,7 @@ public class CodeGeneration {
                     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);
                 }
@@ -379,7 +367,7 @@ public class CodeGeneration {
                 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;
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/CompilationContext.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/CompilationContext.java
new file mode 100644 (file)
index 0000000..d5cbe61
--- /dev/null
@@ -0,0 +1,44 @@
+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
index 54f0bb7d84a500f6a5967d7e2463794647c5f80a..6f82720c4675b805f997e1976695571be3ad6951 100644 (file)
@@ -69,8 +69,8 @@ public class DeclarationClassification {
     
     ErrorLog errorLog;
     
-    public DeclarationClassification(ErrorLog errorLog) {
-        this.errorLog = errorLog;
+    public DeclarationClassification(CompilationContext compilationContext) {
+        this.errorLog = compilationContext.errorLog;
     }
     
     public void handle(DeclarationAst declaration) {
index b242431806efc334f6fd463f9dbcaa8eba48a8df..69f4b7014543d2c70e429a698ae8a1a151d574c5 100644 (file)
@@ -5,7 +5,7 @@ import java.util.ArrayList;
 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;
@@ -48,7 +48,7 @@ public class DocumentationGeneration {
                 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);
index d331283fd76f3ddfd624f65a4fc7c03e288379a5..d89c00c829773e1a7552c8644966ab070838752f 100644 (file)
@@ -16,6 +16,7 @@ import org.simantics.scl.compiler.constants.generic.ConvertToListFilter;
 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;
@@ -110,18 +111,17 @@ import gnu.trove.set.hash.TIntHashSet;
 
 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;
@@ -130,12 +130,13 @@ public class Elaboration {
     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;
@@ -144,6 +145,7 @@ public class Elaboration {
         this.relationDefinitionsAst = relationDefinitionsAst;
 
         module = new ConcreteModule(moduleName);
+        compilationContext.module = module;
         try {
             if(timer != null)
                 timer.suspendTimer();
@@ -151,7 +153,7 @@ public class Elaboration {
                     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());
@@ -164,7 +166,7 @@ public class Elaboration {
                     false,
                     importAst.spec));
         localEnvironmentFactory.addBuiltinDependencies(module);
-        namingPolicy = new JavaNamingPolicy(moduleName);
+        compilationContext.namingPolicy = new JavaNamingPolicy(moduleName);
     }
     
     private ArrayList<ImportDeclaration> processRelativeImports(ArrayList<ImportDeclaration> relativeImports) {
@@ -229,7 +231,7 @@ public class Elaboration {
 
             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;
         }
@@ -238,7 +240,7 @@ public class Elaboration {
             TypeAlias alias = new TypeAlias(Types.con(moduleName, typeAlias.name), typeAlias.parameters.length);
             NameExistenceChecks.checkIfTypeExists(errorLog,
                     typeAlias.location, importedEnvironment, typeAlias.name);
-            if(module.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.");
             }
         }
@@ -253,7 +255,8 @@ public class Elaboration {
             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];
@@ -309,7 +312,7 @@ public class Elaboration {
         
         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]);
@@ -346,7 +349,7 @@ public class Elaboration {
             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;
             
@@ -366,7 +369,7 @@ public class Elaboration {
                 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")) {
@@ -433,7 +436,7 @@ public class Elaboration {
             TypeClass typeClass = new TypeClass(classAst.location, 
                     classContext, 
                     con, 
-                    namingPolicy.getTypeClassInterfaceName(con),
+                    compilationContext.namingPolicy.getTypeClassInterfaceName(con),
                     parameters,
                     Fundep.mapFundeps(classAst.parameters, classAst.fundeps));
             
@@ -451,7 +454,7 @@ public class Elaboration {
                         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)
                                 );
@@ -484,7 +487,7 @@ public class Elaboration {
     }
 
     private TypeTranslationContext createTypeTranslationContext() {
-        return new TypeTranslationContext(errorLog, environment);
+        return new TypeTranslationContext(compilationContext);
     }
     
     public void processDerivingInstances(ArrayList<DDerivingInstanceAst> derivingInstancesAst,
@@ -493,7 +496,7 @@ public class Elaboration {
             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;
@@ -506,7 +509,7 @@ public class Elaboration {
             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);
         }
     }
     
@@ -520,7 +523,7 @@ public class Elaboration {
                 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;
@@ -529,7 +532,7 @@ public class Elaboration {
                     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) {
@@ -550,7 +553,7 @@ public class Elaboration {
                 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;
@@ -626,6 +629,7 @@ public class Elaboration {
                         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;
@@ -848,7 +852,7 @@ public class Elaboration {
             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);
@@ -893,8 +897,12 @@ public class Elaboration {
                     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;
@@ -995,7 +1003,7 @@ public class Elaboration {
                     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 + ".");
@@ -1181,7 +1189,7 @@ public class Elaboration {
     }
     
     private TranslationContext createTranslationContext() {
-        return new TranslationContext(errorLog, environment, null);
+        return new TranslationContext(compilationContext, null);
     }
     
     private void handleAnnotation(SCLValue value, ArrayList<DValueAst> defs, DAnnotationAst annotation) {
index a2324970962b67027100e96c9c3c529197e443c3..0b4d03a046775d772b17b7955876cf8a5fb6a625 100644 (file)
@@ -5,10 +5,9 @@ import java.util.Collection;
 
 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;
@@ -56,11 +55,11 @@ public class EnvironmentOfModule implements Environment {
             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) {
@@ -70,13 +69,6 @@ public class EnvironmentOfModule implements Environment {
             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);
index 1f45c5f41a9d88c8345686e70fcd8b4834dd37ff..090f200c437a7ff4049fb5d79127ddc5795d3df6 100644 (file)
@@ -1,7 +1,7 @@
 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
@@ -32,11 +32,11 @@ public class NameExistenceChecks {
     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
index 8ade1602e23e730ba4e37227eb5ef09dd861eb7c..c010835e9dc1383081033c8c28da0408dfef7f7f 100644 (file)
@@ -4,9 +4,9 @@ import java.util.Arrays;
 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;
@@ -59,9 +59,9 @@ public class NamespaceOfModule implements Namespace {
             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);
         }
     }
 
@@ -83,12 +83,12 @@ public class NamespaceOfModule implements Namespace {
     }
 
     @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
@@ -107,14 +107,6 @@ public class NamespaceOfModule implements Namespace {
             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)
index b5bd4ef312c997038e5856164d2ef34dfbe69cb7..27583ea53b30e25df56ff6e3b73caf7cf1901b65 100644 (file)
@@ -18,8 +18,8 @@ import org.simantics.scl.compiler.top.SCLCompilerConfiguration;
 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;
@@ -42,9 +42,9 @@ public class SCLCompiler {
             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();
@@ -55,13 +55,17 @@ public class SCLCompiler {
         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,
@@ -72,24 +76,24 @@ public class SCLCompiler {
             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);
@@ -101,9 +105,9 @@ public class SCLCompiler {
             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");
             
@@ -125,36 +129,33 @@ public class SCLCompiler {
             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);
@@ -166,12 +167,12 @@ public class SCLCompiler {
                 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() {
index 554a360811b69b2312151b9c4f8fe503d131c790..667c089c3e24fe58561a674622f053a0ed6d9662 100644 (file)
@@ -25,7 +25,6 @@ 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.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;
@@ -45,17 +44,16 @@ import gnu.trove.set.hash.THashSet;
 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;
     }
     
@@ -100,7 +98,7 @@ public class TypeChecking {
                             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();
@@ -129,7 +127,7 @@ public class TypeChecking {
                                 
                                 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)
@@ -212,12 +210,12 @@ public class TypeChecking {
                                 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());
                                 ArrayList<EVariable> demands = context.getConstraintDemand();
@@ -226,10 +224,10 @@ public class TypeChecking {
                                             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);
@@ -239,13 +237,13 @@ public class TypeChecking {
                                     }
                                 }
                                 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);
                             }
                         }
                     });
@@ -336,7 +334,7 @@ public class TypeChecking {
     
     public void typeCheck() {
         ce = new ConstraintEnvironment(environment);
-        scheduler = new TypeCheckingScheduler(errorLog, environment);
+        scheduler = new TypeCheckingScheduler(compilationContext);
         
         typeCheckValues();
         typeCheckRelations();
@@ -424,7 +422,7 @@ public class TypeChecking {
                     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;
                             }
                 }
index cb6752527605e5dc9c1d659515c2272234cd3aa9..e2b0109d17ce77f3d187e671b63eac26d4bc15ee 100644 (file)
@@ -5,8 +5,6 @@ import java.util.ArrayList;
 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;
@@ -24,15 +22,13 @@ import gnu.trove.set.hash.TIntHashSet;
  * @author Hannu Niemist&ouml;
  */
 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) {
@@ -74,7 +70,7 @@ public class TypeCheckingScheduler {
     }
     
     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)
@@ -106,7 +102,7 @@ public class TypeCheckingScheduler {
                             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.");
             }
index 89a902ece006dedc6c49bea7ce027f5c0fe15c90..194e0382823a723ea18ab7b0840a4a4791b38196 100644 (file)
@@ -9,6 +9,9 @@ import org.simantics.scl.compiler.internal.codegen.utils.TransientClassBuilder;
 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) {
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/ComparisonFunction.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/ComparisonFunction.java
new file mode 100644 (file)
index 0000000..1e69a16
--- /dev/null
@@ -0,0 +1,11 @@
+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
index 684e7ed5d8454646a6e61da67e4abd179bd057b6..53cbfd7aa53edf57f71ce324bdd7b3294ad716cf 100644 (file)
@@ -2,6 +2,7 @@ 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.types.JavaTypeTranslator;
 import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder;
@@ -9,7 +10,13 @@ import org.simantics.scl.compiler.types.TVar;
 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;
     
@@ -23,10 +30,11 @@ public class JavaComparisonOperation extends FunctionValue {
         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);
@@ -43,4 +51,15 @@ public class JavaComparisonOperation extends FunctionValue {
         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_);
+    }
+
 }
index e5a58bb77cb44d5b9bfd1cd2fd52a7d43a0351ba..058faf9c349ccaea8b8af8403a029d53d141867c 100644 (file)
@@ -1,13 +1,20 @@
 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;
     
@@ -34,6 +41,14 @@ public class JavaComparisonToZeroOperation extends FunctionValue {
         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;
index a4c47ea76a8cb55a8bf39288cb9acbbd8d5c59ae..ce39a6780e4ba8920360ca15a241d6ad543f54fa 100644 (file)
@@ -99,7 +99,7 @@ public class SCLConstant extends DelegateConstant implements Named {
         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
@@ -363,7 +363,7 @@ public class SCLConstant extends DelegateConstant implements Named {
         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
@@ -371,6 +371,6 @@ public class SCLConstant extends DelegateConstant implements Named {
 \r
     public void saveInlinableDefinition() {\r
         if(inlineArity < Integer.MAX_VALUE)\r
-            inlinableDefinition = definition.copy();\r
+            inlinableDefinition = (SSAFunction)definition.copy();\r
     }\r
 }\r
index 55bba560472aaced6f5b74925dd953d436c8cb29..9b3bbca92a342dfa6a0fa774f9d10c82d60d57d7 100644 (file)
@@ -1,8 +1,16 @@
 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
@@ -22,6 +30,22 @@ public class StringInterpolation extends FunctionValue {
     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
@@ -32,6 +56,37 @@ public class StringInterpolation extends FunctionValue {
 \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
@@ -60,5 +115,55 @@ public class StringInterpolation extends FunctionValue {
         \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
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/UnsafeCoerce.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/UnsafeCoerce.java
deleted file mode 100644 (file)
index 0ac69c1..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-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
index 300f11802ae4df144649a7d0a6f156294dc6e999..b5a3a8e4d17a4ec6c72fa6e5a3f5e69d70ed4142 100644 (file)
@@ -21,6 +21,11 @@ public class CallJava extends FunctionValue {
             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
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/generic/Pop2OutputFilter.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/generic/Pop2OutputFilter.java
new file mode 100644 (file)
index 0000000..374209f
--- /dev/null
@@ -0,0 +1,12 @@
+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
index fea7a57e5b8c171c80939735eedd6583b4a19345..050921adb05d567629daeca7d7d1678ea437d433 100644 (file)
@@ -9,5 +9,4 @@ public enum PopOutputFilter implements OutputFilter {
     public void filter(MethodBuilder mb) {
         mb.pop();
     }
-
 }
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/singletons/IncreaseByOne.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/singletons/IncreaseByOne.java
new file mode 100644 (file)
index 0000000..3d2878a
--- /dev/null
@@ -0,0 +1,31 @@
+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
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/singletons/ListElement.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/singletons/ListElement.java
new file mode 100644 (file)
index 0000000..aaba3de
--- /dev/null
@@ -0,0 +1,32 @@
+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
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/singletons/ListLength.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/singletons/ListLength.java
new file mode 100644 (file)
index 0000000..148db39
--- /dev/null
@@ -0,0 +1,32 @@
+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
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/singletons/NullCheck.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/singletons/NullCheck.java
new file mode 100644 (file)
index 0000000..3089a18
--- /dev/null
@@ -0,0 +1,49 @@
+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
index 99f14b941672909e72fd220f1059422c4b1001cf..173076ea5398e676dbc38624afa0deddd963c289 100644 (file)
@@ -22,4 +22,9 @@ public class UnsafeCoerce extends FunctionValue {
         mb.pushBoxed(parameters[0]);\r
         return getReturnType();\r
     }\r
+\r
+    @Override\r
+    public String toString() {\r
+        return "unsafeCoerce";\r
+    }\r
 }\r
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRLiteral.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRLiteral.java
new file mode 100644 (file)
index 0000000..597ee9d
--- /dev/null
@@ -0,0 +1,138 @@
+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
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRQuery.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRQuery.java
new file mode 100644 (file)
index 0000000..8bcd14b
--- /dev/null
@@ -0,0 +1,94 @@
+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
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRRelation.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRRelation.java
new file mode 100644 (file)
index 0000000..af6e5a2
--- /dev/null
@@ -0,0 +1,13 @@
+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
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRRule.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRRule.java
new file mode 100644 (file)
index 0000000..8ba172f
--- /dev/null
@@ -0,0 +1,123 @@
+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
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRRuleset.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRRuleset.java
new file mode 100644 (file)
index 0000000..a2b5c21
--- /dev/null
@@ -0,0 +1,197 @@
+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
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRRulesetObject.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRRulesetObject.java
new file mode 100644 (file)
index 0000000..f14cb0c
--- /dev/null
@@ -0,0 +1,31 @@
+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
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/analysis/UsageAnalysis.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/analysis/UsageAnalysis.java
new file mode 100644 (file)
index 0000000..3e13e0f
--- /dev/null
@@ -0,0 +1,149 @@
+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
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/AccessFactOp.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/AccessFactOp.java
new file mode 100644 (file)
index 0000000..befcfdd
--- /dev/null
@@ -0,0 +1,51 @@
+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
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/AssignOp.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/AssignOp.java
new file mode 100644 (file)
index 0000000..ed32ca6
--- /dev/null
@@ -0,0 +1,30 @@
+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
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/CheckOp.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/CheckOp.java
new file mode 100644 (file)
index 0000000..8603656
--- /dev/null
@@ -0,0 +1,24 @@
+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
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/ClaimOp.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/ClaimOp.java
new file mode 100644 (file)
index 0000000..663d237
--- /dev/null
@@ -0,0 +1,38 @@
+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
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/ExecuteOp.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/ExecuteOp.java
new file mode 100644 (file)
index 0000000..d604321
--- /dev/null
@@ -0,0 +1,27 @@
+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
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/IterateConstraintOp.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/IterateConstraintOp.java
new file mode 100644 (file)
index 0000000..ec7dd9d
--- /dev/null
@@ -0,0 +1,91 @@
+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
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/IterateListOp.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/IterateListOp.java
new file mode 100644 (file)
index 0000000..57abca1
--- /dev/null
@@ -0,0 +1,30 @@
+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
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/IterateRelationOp.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/IterateRelationOp.java
new file mode 100644 (file)
index 0000000..51dcb37
--- /dev/null
@@ -0,0 +1,42 @@
+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
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/MatchOp.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/MatchOp.java
new file mode 100644 (file)
index 0000000..aac4a94
--- /dev/null
@@ -0,0 +1,46 @@
+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
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/PartnerFact.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/PartnerFact.java
new file mode 100644 (file)
index 0000000..cdec9a3
--- /dev/null
@@ -0,0 +1,43 @@
+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
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/PlanContext.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/PlanContext.java
new file mode 100644 (file)
index 0000000..48ecc7b
--- /dev/null
@@ -0,0 +1,71 @@
+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
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/PlanOp.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/PlanOp.java
new file mode 100644 (file)
index 0000000..d4f1cc9
--- /dev/null
@@ -0,0 +1,22 @@
+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
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/PlanRealizer.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/PlanRealizer.java
new file mode 100644 (file)
index 0000000..8433c43
--- /dev/null
@@ -0,0 +1,26 @@
+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
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/PostCommitOp.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/PostCommitOp.java
new file mode 100644 (file)
index 0000000..edbb975
--- /dev/null
@@ -0,0 +1,69 @@
+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
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/PreCommitOp.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/PreCommitOp.java
new file mode 100644 (file)
index 0000000..0188edb
--- /dev/null
@@ -0,0 +1,25 @@
+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
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/PrioritizedPlan.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/PrioritizedPlan.java
new file mode 100644 (file)
index 0000000..64d3b62
--- /dev/null
@@ -0,0 +1,19 @@
+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
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/planning/PlanPriorityQueue.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/planning/PlanPriorityQueue.java
new file mode 100644 (file)
index 0000000..7eb8ae5
--- /dev/null
@@ -0,0 +1,86 @@
+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
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/planning/PrePlanItem.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/planning/PrePlanItem.java
new file mode 100644 (file)
index 0000000..bb85900
--- /dev/null
@@ -0,0 +1,31 @@
+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
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/planning/QueryPlanningContext.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/planning/QueryPlanningContext.java
new file mode 100644 (file)
index 0000000..c083b8f
--- /dev/null
@@ -0,0 +1,240 @@
+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
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/planning/items/CheckPrePlanItem.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/planning/items/CheckPrePlanItem.java
new file mode 100644 (file)
index 0000000..b54a214
--- /dev/null
@@ -0,0 +1,41 @@
+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
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/planning/items/EqualsPrePlanItem.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/planning/items/EqualsPrePlanItem.java
new file mode 100644 (file)
index 0000000..8a5d4ef
--- /dev/null
@@ -0,0 +1,81 @@
+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
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/planning/items/GenericPrePlanItem.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/planning/items/GenericPrePlanItem.java
new file mode 100644 (file)
index 0000000..fcf42ee
--- /dev/null
@@ -0,0 +1,128 @@
+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
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/planning/items/MemberPrePlanItem.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/planning/items/MemberPrePlanItem.java
new file mode 100644 (file)
index 0000000..d2b88dc
--- /dev/null
@@ -0,0 +1,66 @@
+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
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/relations/CHRConstraint.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/relations/CHRConstraint.java
new file mode 100644 (file)
index 0000000..9c21f54
--- /dev/null
@@ -0,0 +1,208 @@
+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
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/relations/ExternalCHRRelation.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/relations/ExternalCHRRelation.java
new file mode 100644 (file)
index 0000000..1ee4726
--- /dev/null
@@ -0,0 +1,29 @@
+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
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/relations/SpecialCHRRelation.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/relations/SpecialCHRRelation.java
new file mode 100644 (file)
index 0000000..dac7514
--- /dev/null
@@ -0,0 +1,31 @@
+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
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/relations/UnresolvedCHRRelation.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/relations/UnresolvedCHRRelation.java
new file mode 100644 (file)
index 0000000..28944ce
--- /dev/null
@@ -0,0 +1,26 @@
+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
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/translation/CHRTranslation.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/translation/CHRTranslation.java
new file mode 100644 (file)
index 0000000..1410671
--- /dev/null
@@ -0,0 +1,142 @@
+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
index 90e93f3d00a014b6de9d1dc13e5f0bffe05f4ecd..bd01859c91042486877c626bd657fb7fdf790d9c 100755 (executable)
@@ -2,6 +2,8 @@ package org.simantics.scl.compiler.elaboration.contexts;
 
 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;
@@ -31,19 +33,10 @@ import gnu.trove.list.array.TLongArrayList;
 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>();
     
@@ -52,11 +45,11 @@ public class SimplificationContext implements EnvironmentalContext {
     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;         
     }
     
@@ -167,20 +160,20 @@ public class SimplificationContext implements EnvironmentalContext {
     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);
@@ -190,11 +183,11 @@ public class SimplificationContext implements EnvironmentalContext {
     }
     
     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) {
@@ -244,7 +237,7 @@ public class SimplificationContext implements EnvironmentalContext {
         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
@@ -257,7 +250,7 @@ public class SimplificationContext implements EnvironmentalContext {
         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
@@ -271,4 +264,8 @@ public class SimplificationContext implements EnvironmentalContext {
             result[i] = new EVariable(parameters[i]);
         return result;
     }
+
+    public CompilationContext getCompilationContext() {
+        return compilationContext;
+    }
 }
\ No newline at end of file
index b5f9f93e942cb17bcf21c411d7e37702244bd415..41f807592b7ad1de8c0b28d20183a3d4c80a3948 100644 (file)
@@ -4,8 +4,11 @@ import java.util.ArrayList;
 import java.util.Arrays;
 
 import org.simantics.scl.compiler.common.names.Name;
+import org.simantics.scl.compiler.common.names.Names;
 import org.simantics.scl.compiler.common.precedence.Associativity;
 import org.simantics.scl.compiler.common.precedence.Precedence;
+import org.simantics.scl.compiler.compilation.CompilationContext;
+import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint;
 import org.simantics.scl.compiler.elaboration.expressions.Case;
 import org.simantics.scl.compiler.elaboration.expressions.EAmbiguous;
 import org.simantics.scl.compiler.elaboration.expressions.EConstant;
@@ -24,12 +27,10 @@ import org.simantics.scl.compiler.elaboration.modules.SCLValue;
 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;
@@ -58,6 +59,10 @@ public class TranslationContext extends TypeTranslationContext implements Enviro
     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;
@@ -76,14 +81,23 @@ public class TranslationContext extends TypeTranslationContext implements Enviro
         }
     }
     
-    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);
     }
     
@@ -338,6 +352,26 @@ public class TranslationContext extends TypeTranslationContext implements Enviro
         }
     }
     
+    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>());
@@ -372,6 +406,11 @@ public class TranslationContext extends TypeTranslationContext implements Enviro
         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();
@@ -382,55 +421,55 @@ public class TranslationContext extends TypeTranslationContext implements Enviro
     }
 
     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) {        
@@ -496,11 +535,9 @@ public class TranslationContext extends TypeTranslationContext implements Enviro
                 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;
     }
@@ -522,6 +559,10 @@ public class TranslationContext extends TypeTranslationContext implements Enviro
             return null;
         }
     }
+    
+    public CHRConstraint resolveCHRConstraint(String name) {
+        return chrConstraints.get(name);
+    }
 
     @Override
     public SCLValue getValue(Name name) {
index b9dbb4be823b1e3d7c1bb769073c91f7bbe654c3..927720611de5cab6816d5b517223bea54ff34995 100644 (file)
@@ -1,5 +1,6 @@
 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;
@@ -17,15 +18,18 @@ import gnu.trove.map.hash.THashMap;
 
 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;
     }
     
     /**
@@ -106,7 +110,7 @@ public class TypeTranslationContext {
     }
 
     public Kind getKind(TCon con) {
-        return environment.getTypeConstructor(con).kind;
+        return environment.getTypeDescriptor(con).getKind();
     }
 
     /**
index 850f077db32d3ec9c8b81a2ebe5b4f6b32b30aa6..ac004eab692a062e0777c0ebd1d8c3dab3329087 100644 (file)
@@ -3,12 +3,10 @@ package org.simantics.scl.compiler.elaboration.contexts;
 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;
@@ -17,7 +15,6 @@ 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.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;
@@ -42,9 +39,9 @@ import org.simantics.scl.compiler.types.util.TypeUnparsingContext;
 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>();
@@ -71,11 +68,10 @@ public class TypingContext implements EnvironmentalContext {
     //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;
     }
 
     /**
@@ -94,7 +90,7 @@ public class TypingContext implements EnvironmentalContext {
             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;
             }
         }
@@ -336,7 +332,7 @@ public class TypingContext implements EnvironmentalContext {
                     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;
                 }
@@ -361,7 +357,7 @@ public class TypingContext implements EnvironmentalContext {
                     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;
                     }
                 
@@ -386,7 +382,7 @@ public class TypingContext implements EnvironmentalContext {
         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)
@@ -398,7 +394,7 @@ public class TypingContext implements EnvironmentalContext {
     
     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) {
@@ -415,7 +411,7 @@ public class TypingContext implements EnvironmentalContext {
     }
 
     public ErrorLog getErrorLog() {
-        return errorLog;
+        return compilationContext.errorLog;
     }
 
     public boolean isInPattern() {
@@ -470,7 +466,7 @@ public class TypingContext implements EnvironmentalContext {
 
     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) {
@@ -486,33 +482,20 @@ public class TypingContext implements EnvironmentalContext {
                     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;
     }
 
 }
index 8df327362560bc8574eefc96542d9e6f4da4de4a..1de0944ebd3d0dc80d9f66d285b4a4c02949f2bc 100755 (executable)
@@ -37,8 +37,8 @@ import gnu.trove.set.hash.THashSet;
 import gnu.trove.set.hash.TIntHashSet;\r
 \r
 public class EApply extends Expression {\r
-    Expression function;\r
-    Expression[] parameters;\r
+    public Expression function;\r
+    public Expression[] parameters;\r
     Type effect = Types.NO_EFFECTS;\r
     \r
     public EApply(Expression function, Expression ... parameters) {\r
@@ -397,4 +397,19 @@ public class EApply extends Expression {
     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
+        EApply other = (EApply)expression;\r
+        if(parameters.length != other.parameters.length)\r
+            return false;\r
+        if(!function.equalsExpression(other.function))\r
+            return false;\r
+        for(int i=0;i<parameters.length;++i)\r
+            if(!parameters[i].equalsExpression(other.parameters[i]))\r
+                return false;\r
+        return true;\r
+    }\r
 }\r
index 8f6892a42f4f8cfb1e5a78e91386aef908c11c5e..53bfca3506bf163454d28b344a5587ba09733ca1 100644 (file)
@@ -58,8 +58,13 @@ public class EAsPattern extends Expression {
 \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
index e74dde7f6df929fc766b4a8f755b120a6172286c..58274a7a0269553521a840af33b5362faf6d8a70 100755 (executable)
@@ -3,7 +3,7 @@ package org.simantics.scl.compiler.elaboration.expressions;
 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.names.Names;\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
@@ -46,8 +46,6 @@ public class EBinary extends ASTExpression {
     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
@@ -87,7 +85,7 @@ public class EBinary extends ASTExpression {
             }\r
             if(negation != null && ops.isEmpty()) {\r
                 if(opPrec.level <= NEGATION_LEVEL) {      \r
-                    SCLValue neg = context.getEnvironment().getValue(NEG);\r
+                    SCLValue neg = context.getEnvironment().getValue(Names.Prelude_neg);\r
                     if(neg == null) {\r
                         context.getErrorLog().log(location, \r
                                 "Couldn't resolve variable neg.");\r
@@ -112,7 +110,7 @@ public class EBinary extends ASTExpression {
             output.add(binary(l, oldOp, opAsts.remove(opAsts.size()-1), r));\r
         }\r
         if(negation != null) {\r
-            SCLValue neg = context.getEnvironment().getValue(NEG);\r
+            SCLValue neg = context.getEnvironment().getValue(Names.Prelude_neg);\r
             if(neg == null) {\r
                 context.getErrorLog().log(location, \r
                         "Couldn't resolve variable neg.");\r
index ff131254081f7c4ce0a27b3bf9a18cf29fbc9195..fb5c2bdfaf1ca6ce0777d5f5aeeea2c066fe82ae 100755 (executable)
@@ -5,11 +5,16 @@ import java.util.LinkedList;
 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 {
@@ -34,10 +39,8 @@ 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)) {
@@ -48,21 +51,25 @@ public class EBlock extends ASTExpression {
         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);
     }
@@ -70,6 +77,21 @@ public class EBlock extends ASTExpression {
     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) {
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ECHRRuleset.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ECHRRuleset.java
new file mode 100644 (file)
index 0000000..b2d3b22
--- /dev/null
@@ -0,0 +1,117 @@
+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
index 590cbbd96bf75ab80fd0d7d674b7c47d9164e6d6..068c6c8741629ef58d5f0b3a508ec3c6439aa5c9 100755 (executable)
@@ -232,7 +232,7 @@ public class EConstant extends Expression {
             return this;\r
         }\r
         else\r
-            return applyPUnit(context);\r
+            return applyPUnit(context.getCompilationContext());\r
     }\r
 \r
     @Override\r
@@ -283,4 +283,11 @@ public class EConstant extends Expression {
         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
index b49999c06e72c35b021f99bacba81c02b54dd2b9..faadca33e0f10ccbf0f5059ed7c4742d904e4c42 100644 (file)
@@ -1,6 +1,6 @@
 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
@@ -80,10 +80,6 @@ public class EFieldAccess extends SimplifiableExpression {
             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
@@ -99,7 +95,7 @@ public class EFieldAccess extends SimplifiableExpression {
                 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
@@ -107,7 +103,7 @@ public class EFieldAccess extends SimplifiableExpression {
                 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
@@ -117,7 +113,7 @@ public class EFieldAccess extends SimplifiableExpression {
                 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
index e1ccd53ddc3bc2a7bdf99d30fe12eb7ac19e6044..b714d7678aa7e4c88461b5c3ac529a0fc75414bb 100755 (executable)
@@ -9,12 +9,14 @@ import org.simantics.scl.compiler.errors.Locations;
 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.IConstant;\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
+import org.simantics.scl.runtime.tuple.Tuple0;\r
 \r
 import gnu.trove.map.hash.TObjectIntHashMap;\r
 import gnu.trove.set.hash.THashSet;\r
@@ -23,7 +25,7 @@ import gnu.trove.set.hash.TIntHashSet;
 public class EIf extends Expression {\r
     public Expression condition;\r
     public Expression then_;\r
-    public Expression else_;\r
+    public Expression else_; // may be null\r
     \r
     public EIf(Expression condition, Expression then_, Expression else_) {\r
         this.condition = condition;\r
@@ -41,7 +43,8 @@ public class EIf extends Expression {
        public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {\r
         condition.collectRefs(allRefs, refs);\r
         then_.collectRefs(allRefs, refs);\r
-        else_.collectRefs(allRefs, refs);\r
+        if(else_ != null)\r
+            else_.collectRefs(allRefs, refs);\r
     }\r
 \r
        @Override\r
@@ -49,7 +52,8 @@ public class EIf extends Expression {
                TIntHashSet vars) {\r
            condition.collectVars(allVars, vars);\r
         then_.collectVars(allVars, vars);\r
-        else_.collectVars(allVars, vars);\r
+        if(else_ != null)\r
+            else_.collectVars(allVars, vars);\r
        }\r
 \r
        @Override\r
@@ -60,20 +64,20 @@ public class EIf extends Expression {
        @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
+        CodeWriter thenBlock = w.createBlock();\r
+        if(else_ != null) {\r
+            CodeWriter elseBlock = w.createBlock();        \r
+            w.if_(conditionVal, thenBlock.getContinuation(), elseBlock.getContinuation());\r
+                \r
+            IVal elseVal = else_.toVal(env, elseBlock);\r
+            elseBlock.jump(joinPoint.getContinuation(), elseVal);\r
+        }\r
+        else {\r
+            w.if_(conditionVal, thenBlock.getContinuation(), joinPoint.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
@@ -83,14 +87,16 @@ public class EIf extends Expression {
     public void collectFreeVariables(THashSet<Variable> vars) {\r
         condition.collectFreeVariables(vars);\r
         then_.collectFreeVariables(vars);\r
-        else_.collectFreeVariables(vars);\r
+        if(else_ != null)\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
+        if(else_ != null)\r
+            else_ = else_.simplify(context);\r
         return this;\r
     }\r
 \r
@@ -98,7 +104,8 @@ public class EIf extends Expression {
     public Expression resolve(TranslationContext context) {\r
         condition = condition.resolve(context);\r
         then_ = then_.resolve(context);\r
-        else_ = else_.resolve(context);\r
+        if(else_ != null)\r
+            else_ = else_.resolve(context);\r
         return this;\r
     }\r
 \r
@@ -106,14 +113,17 @@ public class EIf extends Expression {
     public Expression replace(ReplaceContext context) {\r
         return new EIf(condition.replace(context), \r
                 then_.replace(context), \r
-                else_.replace(context));\r
+                else_ == null ? null : 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
+        if(else_ != null)\r
+            else_ = else_.checkType(context, requiredType);\r
+        else\r
+            context.getErrorLog().log(location, "Else branch is required because the return value of the if expression is used.");\r
         return this;\r
     }\r
     \r
@@ -121,7 +131,8 @@ public class EIf extends Expression {
     public Expression checkIgnoredType(TypingContext context) {\r
         condition = condition.checkType(context, Types.BOOLEAN);\r
         then_ = then_.checkIgnoredType(context);\r
-        else_ = else_.checkIgnoredType(context);\r
+        if(else_ != null)\r
+            else_ = else_.checkIgnoredType(context);\r
         return this;\r
     }\r
     \r
@@ -129,20 +140,22 @@ public class EIf extends Expression {
     public Expression decorate(ExpressionDecorator decorator) {\r
         condition = condition.decorate(decorator);\r
         then_ = then_.decorate(decorator);\r
-        else_ = else_.decorate(decorator);        \r
+        if(else_ != null)\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
+       return condition.isEffectful() || then_.isEffectful() || (else_ != null && 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
+        if(else_ != null)\r
+            else_.collectEffects(effects);\r
     }\r
     \r
     @Override\r
@@ -151,7 +164,8 @@ public class EIf extends Expression {
             location = loc;\r
             condition.setLocationDeep(loc);\r
             then_.setLocationDeep(loc);\r
-            else_.setLocationDeep(loc);\r
+            if(else_ != null)\r
+                else_.setLocationDeep(loc);\r
         }\r
     }\r
     \r
@@ -162,26 +176,16 @@ public class EIf extends Expression {
     \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
+        return new IIf(condition.toIExpression(target), then_.toIExpression(target), \r
+                else_ != null ? else_.toIExpression(target) : new IConstant(Tuple0.INSTANCE));\r
     }\r
 \r
     @Override\r
     public void forVariables(VariableProcedure procedure) {\r
         condition.forVariables(procedure);\r
         then_.forVariables(procedure);\r
-        else_.forVariables(procedure);\r
+        if(else_ != null)\r
+            else_.forVariables(procedure);\r
     }\r
     @Override\r
     public Expression accept(ExpressionTransformer transformer) {\r
index 101e00b840fc67c1e37c3d7f7f32d82d5092d158..0834c49053a76813ee1cc0683d7d5098769972c7 100755 (executable)
@@ -2,6 +2,7 @@ package org.simantics.scl.compiler.elaboration.expressions;
 \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
@@ -90,7 +91,7 @@ public class EIntegerLiteral extends SimplifiableExpression {
             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
index 15201e7f0f19e935f825ffff57f974c5c1ae957e..0d00a65d2cf3fffdd921efa963f7a8ee1d8ca812 100755 (executable)
@@ -140,4 +140,12 @@ public class ELiteral extends Expression {
         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
index 50e4edd6a3068efd0130abe2f40766e7df089b34..2eaa5a208e361a4261d0af532fc6758fd136d43d 100755 (executable)
@@ -1,6 +1,6 @@
 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
@@ -13,14 +13,12 @@ public class ERange extends ASTExpression {
         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
index f2e17aa00cf6b78f418d993e6615149acb171ff3..bbc9d52ba7620add7859dccaf6b82c19d83b68a0 100755 (executable)
@@ -2,6 +2,7 @@ package org.simantics.scl.compiler.elaboration.expressions;
 \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
@@ -84,7 +85,7 @@ public class ERealLiteral extends SimplifiableExpression {
         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
index 02b8c9ddc0c4922765cbbf5ff321726e4d05ff86..9e863a7a6e1f42fe3eccfee067593d547a3c1a5e 100644 (file)
@@ -21,7 +21,7 @@ import java.util.ArrayList;
 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
@@ -36,7 +36,6 @@ import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator
 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
@@ -191,15 +190,6 @@ public class ERuleset extends SimplifiableExpression {
         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
@@ -284,7 +274,7 @@ public class ERuleset extends SimplifiableExpression {
             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
@@ -305,7 +295,7 @@ public class ERuleset extends SimplifiableExpression {
         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
@@ -349,7 +339,7 @@ public class ERuleset extends SimplifiableExpression {
             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
@@ -361,7 +351,7 @@ public class ERuleset extends SimplifiableExpression {
                         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
@@ -376,7 +366,7 @@ public class ERuleset extends SimplifiableExpression {
         // 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
@@ -384,7 +374,7 @@ public class ERuleset extends SimplifiableExpression {
         // 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
index 1e92952330fba5b4626eac399021349c31b84688..6c45daa87c21d44af38d49b3515b3a27c9056e3b 100644 (file)
@@ -10,7 +10,7 @@ import static org.simantics.scl.compiler.elaboration.expressions.Expressions.tup
 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
@@ -119,10 +119,10 @@ public class ESelect extends SimplifiableExpression {
         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
@@ -134,7 +134,7 @@ public class ESelect extends SimplifiableExpression {
                 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
index 79d464b7b459a35cd3fc921b8f745f3b487bce57..f15e62cbf14b312e57eacd7b194a1353e90bfd55 100644 (file)
@@ -1,6 +1,6 @@
 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
@@ -19,7 +19,7 @@ public class EStringLiteral extends ASTExpression {
     @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
@@ -38,6 +38,17 @@ public class EStringLiteral extends ASTExpression {
     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
index ca87d72c4e8d878ac3cb30c445758578b43a9295..666bc2aca1783b209f2ee3caf47157deb96e9bb4 100755 (executable)
@@ -149,7 +149,7 @@ public class EVariable extends Expression {
             return this;\r
         }\r
         else\r
-            return applyPUnit(context);\r
+            return applyPUnit(context.getCompilationContext());\r
     }\r
     \r
     @Override\r
@@ -202,5 +202,13 @@ public class EVariable extends Expression {
     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
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EViewPattern.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EViewPattern.java
new file mode 100644 (file)
index 0000000..268ee8e
--- /dev/null
@@ -0,0 +1,137 @@
+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
index e01098c12df762eb3e32c43caaff6baaee3f36c6..9a5fefb9f95cc64f55f2ec36eb7aa8e54ad89313 100755 (executable)
@@ -207,6 +207,8 @@ public abstract class Expression extends Symbol implements Typed {
     public abstract void collectFreeVariables(THashSet<Variable> vars);\r
     \r
     public Expression simplify(SimplificationContext context) {\r
+        System.out.println("#############################");\r
+        System.out.println(this);\r
         throw new InternalCompilerError(location, getClass().getSimpleName() + " does not support simplify method.");\r
     }\r
 \r
@@ -376,4 +378,9 @@ public abstract class Expression extends Symbol implements Typed {
     }\r
     \r
     public abstract Expression accept(ExpressionTransformer transformer);\r
+\r
+    // TODO implement for all expressions\r
+    public boolean equalsExpression(Expression expression) {\r
+        return false;\r
+    }\r
 }\r
index baeedd0f00a51df1e8308dfb737dd77886cb81af..50f08149989d140099073f96674a80f274bba457 100644 (file)
@@ -9,7 +9,9 @@ public interface ExpressionTransformer {
     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);
@@ -29,7 +31,6 @@ public interface ExpressionTransformer {
     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);
@@ -42,6 +43,7 @@ public interface ExpressionTransformer {
     Expression transform(ETypeAnnotation expression);
     Expression transform(EVar expression);
     Expression transform(EVariable expression);
+    Expression transform(EViewPattern expression);
     Expression transform(EWhen expression);
     Expression transform(GuardedExpressionGroup expression);
     
index 4fa4efaeaeb418107c5e56494422aee8ae245e8a..34f45dd0a5ba58c16e8be9ef312ae90e2f2f5f46 100644 (file)
@@ -6,6 +6,7 @@ public interface ExpressionVisitor {
     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
@@ -32,6 +33,7 @@ public interface ExpressionVisitor {
     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
index 10d9bcb630e3fa6c68b350ecfa30f0b06fa6fa04..e8fd80d7c68dd5bc97157df7ad3d30f2af4d3648 100644 (file)
@@ -234,7 +234,7 @@ public class Expressions {
     }\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
index 1a2f451eeab205b8aff61a0ae5d655a2750660f4..2fc6d1e7eb4d93ea1f224dc214650eae6c766a14 100644 (file)
@@ -1,5 +1,7 @@
 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;
@@ -79,6 +81,13 @@ EquationVisitor {
         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)
@@ -109,6 +118,20 @@ EquationVisitor {
         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;
@@ -158,7 +181,8 @@ EquationVisitor {
     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;
     }
 
index 93ddf6fa54e4887d63ac432a0704334b9fea2b2c..7a562a83c2c56f47ed3b1c50fbecb09e893f3d48 100644 (file)
@@ -1,5 +1,7 @@
 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
@@ -90,7 +92,8 @@ EquationVisitor {
     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
@@ -104,6 +107,12 @@ EquationVisitor {
         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
@@ -334,4 +343,17 @@ EquationVisitor {
             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
index 00eb220ab75ef4cdac0da5d784dff4bbe6f0119e..b0f3116b32de85cf5533c795ca9edab28a03317d 100755 (executable)
@@ -51,4 +51,9 @@ public class BindStatement extends Statement {
     public void accept(StatementVisitor visitor) {\r
         visitor.visit(this);\r
     }\r
+\r
+    @Override\r
+    public StatementGroup getStatementGroup() {\r
+        return null;\r
+    }\r
 }\r
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/block/CHRStatement.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/block/CHRStatement.java
new file mode 100644 (file)
index 0000000..20078e6
--- /dev/null
@@ -0,0 +1,55 @@
+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
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/block/ConstraintStatement.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/block/ConstraintStatement.java
new file mode 100644 (file)
index 0000000..54437c9
--- /dev/null
@@ -0,0 +1,54 @@
+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
index 59aa3ebe2b2e777e2ba614477712de1b695d4e75..4dda0d307c9f67e7d7b8ca1ce75163c3730ecc49 100755 (executable)
@@ -53,4 +53,9 @@ public class GuardStatement extends Statement {
     public void accept(StatementVisitor visitor) {\r
         visitor.visit(this);\r
     }\r
+\r
+    @Override\r
+    public StatementGroup getStatementGroup() {\r
+        return null;\r
+    }\r
 }\r
index 537ec303b89eec93ce6c71defb145e6a23868d9b..88dcc0ac9f3005c2588bd8abdfdab79560fa4ded 100755 (executable)
@@ -56,4 +56,12 @@ public class LetStatement extends Statement {
     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
index 620176d1187beb05cca0136a6f17971328e59b37..c6f3b5c4f81d70158319d91800c3b68148156f5f 100644 (file)
@@ -51,4 +51,9 @@ public class RuleStatement extends Statement {
     public void accept(StatementVisitor visitor) {\r
         visitor.visit(this);\r
     }\r
+\r
+    @Override\r
+    public StatementGroup getStatementGroup() {\r
+        return StatementGroup.Rule;\r
+    }\r
 }\r
index 19fba69cb0ab41cb02f19d3c95f827a634235b5f..1697959186415c1b449e0acd94b49d2b20e4cbe8 100755 (executable)
@@ -23,5 +23,6 @@ public abstract class Statement extends Symbol {
     }\r
     \r
     public abstract void accept(StatementVisitor visitor);\r
+    public abstract StatementGroup getStatementGroup();\r
     \r
 }\r
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/block/StatementGroup.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/block/StatementGroup.java
new file mode 100644 (file)
index 0000000..da7a621
--- /dev/null
@@ -0,0 +1,7 @@
+package org.simantics.scl.compiler.elaboration.expressions.block;\r
+\r
+public enum StatementGroup {\r
+    Rule,\r
+    CHR,\r
+    LetFunction\r
+}\r
index 6cbdb6f6b19aedef68bf8f69321650fca39123dd..ce2af3b929a4f3a53d62d19c622df926a35f4920 100644 (file)
@@ -2,12 +2,17 @@ package org.simantics.scl.compiler.elaboration.expressions.printing;
 \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
@@ -34,6 +39,7 @@ import org.simantics.scl.compiler.elaboration.expressions.ESimpleLet;
 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
@@ -169,14 +175,16 @@ public class ExpressionToStringVisitor implements ExpressionVisitor, QueryVisito
     @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
@@ -216,6 +224,15 @@ public class ExpressionToStringVisitor implements ExpressionVisitor, QueryVisito
         }\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
@@ -494,4 +511,38 @@ public class ExpressionToStringVisitor implements ExpressionVisitor, QueryVisito
     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
index 0dee9f9cefedd95aced7c457902a232c49dcae4b..7935257ace56ba7db959cb6b2d985225a42f74d8 100755 (executable)
@@ -4,6 +4,9 @@ import org.cojen.classfile.TypeDesc;
 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;
@@ -56,6 +59,8 @@ public class Builtins extends ConcreteModule {
     public static SCLValue Nothing;
     public static SCLValue Just;
     
+    public static SCLValue EQUALS;
+    
     private Builtins() {      
         super(Types.BUILTIN);
         
@@ -63,45 +68,45 @@ public class Builtins extends ConcreteModule {
         
         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 ***
         
@@ -114,7 +119,7 @@ public class Builtins extends ConcreteModule {
                 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;
@@ -181,12 +186,12 @@ public class Builtins extends ConcreteModule {
                 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));
@@ -219,7 +224,7 @@ public class Builtins extends ConcreteModule {
                     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",
@@ -267,18 +272,18 @@ public class Builtins extends ConcreteModule {
                     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)
@@ -311,7 +316,7 @@ public class Builtins extends ConcreteModule {
             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)
@@ -328,13 +333,18 @@ public class Builtins extends ConcreteModule {
             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);
         }
index 3a4087c893024e5a076da8b5a0f468744cde9804..c2d3e6d0f1bbf666089919b305f5b6495b45967a 100644 (file)
@@ -2,7 +2,9 @@ package org.simantics.scl.compiler.elaboration.java;
 \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
@@ -11,7 +13,7 @@ import org.simantics.scl.compiler.types.Type;
 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
@@ -43,4 +45,32 @@ public class EqualsFunction extends FunctionValue {
             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
index 0f3f8f2d3905d81e8af813e7e0d0c683a244cd21..b67416eb6682a5d3f4413d807647b08133b068b6 100644 (file)
@@ -95,7 +95,7 @@ public class ListConstructor extends FunctionValue {
     
     @Override
     public String toString() {
-        return "[...]";
+        return "[.." + arity + "..]";
     }
 
 }
index 6c22babec4264fcd5b8cd290e65eae96c2fce294..a022d1b37e7488d58181b4aa0542081cc04ac328 100644 (file)
@@ -1,6 +1,6 @@
 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;
@@ -65,9 +65,8 @@ public class MemberRelation extends AbstractRelation {
         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])
                             }
index 3276e0f2213e5d0d52415c48bda698b9ea381890..ef30deb435ca36318350ccfb8c5fdceb06577f60 100644 (file)
@@ -1,6 +1,6 @@
 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;
@@ -65,9 +65,8 @@ public class OptionalRelation extends AbstractRelation {
         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])
                             }
index ce888324ce2bda26efc182a97e9ea388d2a328b5..f0d852b1c41677a5185f5adf740c052d9796c121 100644 (file)
@@ -1,25 +1,37 @@
 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
index e3adf5ba8eaa4c680076489a5cad6f300dabdd4b..016a0b780b158990e38eaf1618b5451495d320e3 100644 (file)
@@ -13,10 +13,9 @@ import org.simantics.scl.compiler.types.kinds.KArrow;
 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
@@ -30,11 +29,12 @@ public abstract class TypeConstructor {
     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
@@ -48,6 +48,7 @@ public abstract class TypeConstructor {
     }\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
@@ -60,14 +61,25 @@ public abstract class TypeConstructor {
         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
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/modules/TypeDescriptor.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/modules/TypeDescriptor.java
new file mode 100644 (file)
index 0000000..d9e6615
--- /dev/null
@@ -0,0 +1,14 @@
+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
index 373efa413ddbb09a6e5d7ec302f8e823f866c858..030d419f7e6153cdc2bc0cce90c8b830c20ac57d 100644 (file)
@@ -1,6 +1,6 @@
 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;
@@ -60,7 +60,7 @@ public class QNegation extends QAbstractModifier {
             @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()));
             }
         });
index 66f8070a97745213691277dd5ab941fe79b878fe..384deeeea27ac8a199292c963e7d6b1629d8e3cd 100644 (file)
@@ -1,5 +1,6 @@
 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;
@@ -26,4 +27,8 @@ public class EnforcingContext {
         context.addConstraintDemand(evidence);
         return evidence;
     }
+
+    public CompilationContext getCompilationContext() {
+        return context.getCompilationContext();
+    }
 }
index f0f5b12271678932bf10908aee2ea1ca94870927..d454c63eb256dfbb92470e0ec7c2e03d5b27712c 100644 (file)
@@ -8,8 +8,9 @@ import static org.simantics.scl.compiler.elaboration.expressions.Expressions.var
 
 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;
@@ -23,16 +24,13 @@ 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.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;
@@ -72,7 +70,7 @@ public class QueryCompilationContext implements EnvironmentalContext {
         }
         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();
@@ -96,9 +94,8 @@ public class QueryCompilationContext implements EnvironmentalContext {
         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
                 }
@@ -132,7 +129,7 @@ public class QueryCompilationContext implements EnvironmentalContext {
                 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
@@ -143,7 +140,7 @@ public class QueryCompilationContext implements EnvironmentalContext {
                 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
@@ -154,7 +151,7 @@ public class QueryCompilationContext implements EnvironmentalContext {
                 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), 
@@ -166,7 +163,7 @@ public class QueryCompilationContext implements EnvironmentalContext {
                 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), 
@@ -188,7 +185,7 @@ public class QueryCompilationContext implements EnvironmentalContext {
                 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
@@ -199,7 +196,7 @@ public class QueryCompilationContext implements EnvironmentalContext {
                 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
@@ -210,7 +207,7 @@ public class QueryCompilationContext implements EnvironmentalContext {
                 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), 
@@ -222,7 +219,7 @@ public class QueryCompilationContext implements EnvironmentalContext {
                 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), 
@@ -237,20 +234,17 @@ public class QueryCompilationContext implements EnvironmentalContext {
         }
     }
     
-    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
@@ -270,7 +264,7 @@ public class QueryCompilationContext implements EnvironmentalContext {
     }
     
     public Expression getConstant(Name name, Type[] typeParameters) {
-        return context.getConstant(name, typeParameters);
+        return context.getCompilationContext().getConstant(name, typeParameters);
     }
     
     public QueryCompilationContext createCheckContext() {
@@ -316,8 +310,7 @@ public class QueryCompilationContext implements EnvironmentalContext {
         return evidence;
     }
 
-    @Override
-    public SCLValue getValue(Name name) {
-        return context.getValue(name);
+    public CompilationContext getCompilationContext() {
+        return context.getCompilationContext();
     }
 }
index 3d2a1e4e892f70093e570ed17a0ed34d72f15d02..54acd32f3f923edc1ef41189d762735dbe77db0d 100644 (file)
@@ -1,8 +1,10 @@
 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 {
@@ -16,4 +18,15 @@ 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.");
+    }
 }
index 83714f26ba78c7eaf8342f87c0cb7a88e11527ea..a38df0bcdeff22132f03868585d292319b9d9ef3 100644 (file)
@@ -3,6 +3,7 @@ package org.simantics.scl.compiler.elaboration.relations;
 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;
@@ -12,6 +13,7 @@ import org.simantics.scl.compiler.elaboration.query.Query;
 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;
@@ -147,4 +149,14 @@ public class ConcreteRelation extends Symbol implements SCLRelation {
         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.");
+    }
 }
index 0a193d6c1e89806b0daff39a8b2ffc7c87ea2622..3fbeef75525671c41daee45dbd80e8b9213015f2 100644 (file)
@@ -7,8 +7,7 @@ import static org.simantics.scl.compiler.elaboration.expressions.Expressions.var
 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;
@@ -39,7 +38,7 @@ public class LocalRelation extends AbstractRelation {
     
     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() {
@@ -74,8 +73,6 @@ public class LocalRelation extends AbstractRelation {
         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,
@@ -83,8 +80,8 @@ public class LocalRelation extends AbstractRelation {
         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))
                     ));
@@ -98,9 +95,8 @@ public class LocalRelation extends AbstractRelation {
             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])
                             ));
index 7b2f2a19e840e6f8dbde246e8631f99925ae3353..9642762cb220cfa5a247ea7a2a3119e1aadb33aa 100644 (file)
@@ -1,9 +1,11 @@
 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;
 
@@ -40,4 +42,16 @@ public interface SCLRelation {
             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);
 }
index c9fa469d28f748fbea80fdfbd623399118437466..42eb9530d3717401b427b78f7c951c99620f8675 100644 (file)
@@ -9,6 +9,7 @@ import static org.simantics.scl.compiler.elaboration.expressions.Expressions.tup
 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;
@@ -67,9 +68,13 @@ public class TransitiveClosureRelation extends AbstractRelation implements Compo
             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)
@@ -91,14 +96,14 @@ public class TransitiveClosureRelation extends AbstractRelation implements Compo
                 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);
         
index e91e39444281479ba9fc0655464d63b669d5e774..d6929232a99f1563d6f97d2b6982e27e453580da 100644 (file)
@@ -6,10 +6,9 @@ import java.util.Collections;
 \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
@@ -45,11 +44,11 @@ public abstract class AbstractEnvironment implements Environment {
     }\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
@@ -60,14 +59,6 @@ public abstract class AbstractEnvironment implements Environment {
         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
index ed08b7b690864191f88cec3baf47cfd5d84c2ef9..f40221eb57cb79717ef93bc7a51f07fdeffc7de5 100644 (file)
@@ -3,7 +3,6 @@ package org.simantics.scl.compiler.environment;
 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;
@@ -39,10 +38,9 @@ public enum EmptyNamespace implements Namespace {
             throws AmbiguousNameException {
         return null;
     }
-
+    
     @Override
-    public TypeConstructor getTypeConstructor(String name)
-            throws AmbiguousNameException {
+    public TypeConstructor getTypeDescriptor(String name) throws AmbiguousNameException {
         return null;
     }
 
@@ -57,11 +55,6 @@ public enum EmptyNamespace implements Namespace {
         return null;
     }
 
-    @Override
-    public TypeAlias getTypeAlias(String name) throws AmbiguousNameException {
-        return null;
-    }
-
     @Override
     public MappingRelation getMappingRelation(String name)
             throws AmbiguousNameException {
index 70c62062dcbdd0ee7b66923e682ddc74f6f327b6..b25fc72091a8bf23d0046c2901ae9bba258b72c5 100644 (file)
@@ -5,10 +5,9 @@ import java.util.Collection;
 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;
@@ -21,9 +20,8 @@ public interface Environment extends EnvironmentalContext {
     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);
index 5a55a6ca130f81132d59a9ccf5dbe51884c9e346..4328d15e0b02535dfe695e06602702c19ea41218 100644 (file)
@@ -6,17 +6,16 @@ import java.util.List;
 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;
@@ -80,8 +79,8 @@ public class Environments {
      * @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);
     }
     
     /**
@@ -107,18 +106,6 @@ public class Environments {
     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.
@@ -144,12 +131,12 @@ public class Environments {
      * @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;
     }
     
     /**
@@ -193,19 +180,20 @@ public class Environments {
      */
     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());
     }
 
     /**
@@ -324,10 +312,10 @@ public class Environments {
                }               
        };
     
-    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);
                }               
        };
     
@@ -345,13 +333,6 @@ public class Environments {
                }               
        };
     
-    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;
@@ -359,9 +340,10 @@ public class Environments {
             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;
         }
     }
index 921b9029d2d2e7e028e8a1a746908f5305ef6324..3253931feb4dcb396167418c5b07b6d89f3af5c6 100644 (file)
@@ -3,9 +3,8 @@ package org.simantics.scl.compiler.environment;
 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;
@@ -52,13 +51,13 @@ public interface Namespace {
     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.
@@ -78,15 +77,6 @@ public interface Namespace {
      */
     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;
 
index 98666c11a16bab50cf93723f2fdb26f5af413b95..6dac77acf029d54aa3dc9f641de6bd5c0fc006af 100644 (file)
@@ -4,9 +4,8 @@ import java.util.ArrayList;
 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;
@@ -33,13 +32,6 @@ public class NamespaceImpl implements Namespace {
             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,
@@ -138,14 +130,14 @@ public class NamespaceImpl implements Namespace {
     }
 
     @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) {
@@ -220,33 +212,6 @@ public class NamespaceImpl implements Namespace {
         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;
index 853f316eef342c12223faf57626c00d610b2d3b4..34f6578e33e847619a4ed6c3c62c090d9f0d2399 100644 (file)
@@ -1,6 +1,7 @@
 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
@@ -58,8 +59,6 @@ public class LoopAnalysis {
             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
@@ -70,7 +69,7 @@ public class LoopAnalysis {
         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
index e580c7c790ffb41e6a77bf6d6921c86228298668..8de2c37c8f1925fa33f156a4b4fb9c34425dad56 100644 (file)
@@ -2,6 +2,7 @@ package org.simantics.scl.compiler.internal.codegen.analysis;
 \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
@@ -147,10 +148,8 @@ public abstract class StatementBrowser {
         }\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
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/chr/CHRCodeGenerator.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/chr/CHRCodeGenerator.java
new file mode 100644 (file)
index 0000000..bd7059e
--- /dev/null
@@ -0,0 +1,648 @@
+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
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/chr/ExampleStore.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/chr/ExampleStore.java
new file mode 100644 (file)
index 0000000..197fefe
--- /dev/null
@@ -0,0 +1,93 @@
+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
index 4b287fafa91f397626ec30b358df626182758e0f..6535bb6efc5b2ec945b84f0afc9200cec4c86661 100644 (file)
@@ -1,6 +1,7 @@
 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
@@ -13,8 +14,6 @@ import org.simantics.scl.compiler.internal.codegen.utils.SSASimplificationContex
 \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
@@ -65,7 +64,7 @@ public enum FoldlBuildFusion implements Optimization {
             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
index 75429d9aee4a8b7691790231397d1156ecdf7d34..6aae58e666f97eeda7c37aef43eeed48df102541 100644 (file)
@@ -1,6 +1,7 @@
 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
@@ -9,7 +10,7 @@ public class OptimizationMap {
     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
index 9837fdb77a30ddd2f8cfee1372b3aa90f336453b..fa3663244c853108a84b1c8c68b69604d8faab5e 100644 (file)
@@ -44,7 +44,7 @@ public abstract class Val implements IVal {
         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
index 3c6c114cb67909ff793eefc305d83aec8defbabd..405e31ddd083be4451d77f0d93c6bcb2a0e7d1d2 100644 (file)
@@ -22,6 +22,7 @@ import org.simantics.scl.compiler.internal.codegen.utils.PrintingContext;
 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
@@ -533,5 +534,12 @@ public final class SSABlock extends Cont implements Printable, BoundVarBinder {
             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
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/SSAClosure.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/SSAClosure.java
new file mode 100644 (file)
index 0000000..6559788
--- /dev/null
@@ -0,0 +1,108 @@
+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
index 5727f8eafbd464d453569e148ed9c6a3ecb29db2..a8e1f20004dd2c130d067c82f65472f07a5411a2 100644 (file)
@@ -14,6 +14,7 @@ import org.simantics.scl.compiler.internal.codegen.utils.Printable;
 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
@@ -68,4 +69,6 @@ public abstract class SSAExit implements Printable {
 \r
     public void prepare(MethodBuilder mb) {\r
     }\r
+\r
+    public abstract void forValRefs(ValRefVisitor visitor);\r
 }
\ No newline at end of file
index c812db7c4476a3b8078847ad045d359cf618afc3..68dd82f15f4bb1c76d5b68c07f58cfc501e3f66c 100644 (file)
@@ -11,35 +11,27 @@ import org.simantics.scl.compiler.internal.codegen.continuations.ReturnCont;
 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));
@@ -51,21 +43,6 @@ public final class SSAFunction implements Printable, BoundVarBinder {
         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;
@@ -116,6 +93,10 @@ public final class SSAFunction implements Printable, BoundVarBinder {
         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);
@@ -188,10 +169,8 @@ public final class SSAFunction implements Printable, BoundVarBinder {
         //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 &&
@@ -202,7 +181,9 @@ public final class SSAFunction implements Printable, BoundVarBinder {
     
     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();
@@ -233,54 +214,6 @@ public final class SSAFunction implements Printable, BoundVarBinder {
         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)
@@ -309,12 +242,14 @@ public final class SSAFunction implements Printable, BoundVarBinder {
         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;
@@ -322,11 +257,8 @@ public final class SSAFunction implements Printable, BoundVarBinder {
             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;
@@ -338,6 +270,7 @@ public final class SSAFunction implements Printable, BoundVarBinder {
         this.typeParameters = typeParameters;
     }
 
+    @Override
     public Type getType() {
         Type type = returnCont.getType();
         type = Types.functionE(
@@ -361,73 +294,29 @@ public final class SSAFunction implements Printable, BoundVarBinder {
         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);
@@ -481,11 +370,16 @@ public final class SSAFunction implements Printable, BoundVarBinder {
         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);
     }
 
 }
index 9ca2303c00be9a349984721707ebd7d46144491d..e0dbf214f3a8a9a32c2adcec8c2feb98ab7ae225 100644 (file)
@@ -23,8 +23,6 @@ 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.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;
@@ -32,7 +30,8 @@ import gnu.trove.procedure.TObjectProcedure;
 
 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);
@@ -169,14 +168,17 @@ public class SSAModule {
         });
 
         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);
     }
     
     /**
@@ -193,7 +195,7 @@ public class SSAModule {
         });        
     }
     
-    public void addStaticField(Tuple2 tuple) {
+    public void addStaticField(StaticField tuple) {
        staticFields.add(tuple);
     }
 
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/SSAObject.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/SSAObject.java
new file mode 100644 (file)
index 0000000..8735b76
--- /dev/null
@@ -0,0 +1,147 @@
+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
index 25d5734c7fb6581e2a059101e42c127c5b8d4f44..26471c4347927d5253132e069729fbd0c470df8b 100644 (file)
@@ -13,6 +13,7 @@ import org.simantics.scl.compiler.internal.codegen.utils.PrintingContext;
 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
@@ -120,4 +121,6 @@ public abstract class SSAStatement implements Printable {
 \r
     public void prepare(MethodBuilder mb) {        \r
     }\r
+\r
+    public abstract void forValRefs(ValRefVisitor visitor);\r
 }\r
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/StaticField.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/StaticField.java
new file mode 100644 (file)
index 0000000..7e2f83c
--- /dev/null
@@ -0,0 +1,13 @@
+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
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/binders/ClosureBinder.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/binders/ClosureBinder.java
new file mode 100644 (file)
index 0000000..429f738
--- /dev/null
@@ -0,0 +1,10 @@
+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
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/binders/FunctionBinder.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/binders/FunctionBinder.java
deleted file mode 100644 (file)
index 4d4a8fa..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-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
index 0f4673aada2d4a30738710c55d7b293e7e861d62..296ec6d1f461545c72222ff8ad49cde1310ef267 100644 (file)
@@ -5,19 +5,23 @@ import java.util.ArrayList;
 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;
@@ -50,6 +54,20 @@ public class If extends SSAExit implements ValRefBinder {
 
     @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, "==");
@@ -200,4 +218,9 @@ public class If extends SSAExit implements ValRefBinder {
                 return SSABlock.EMPTY_ARRAY;
         }
     }
+
+    @Override
+    public void forValRefs(ValRefVisitor visitor) {
+        visitor.visit(condition);
+    }
 }
index d271dc00b1ca39768bef31ff046941c384daaf3f..b0340f89db04e6b359457805b2b96c081e0b406d 100644 (file)
@@ -15,6 +15,7 @@ import org.simantics.scl.compiler.internal.codegen.utils.CopyContext;
 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
@@ -139,4 +140,10 @@ public class Jump extends SSAExit implements ValRefBinder {
         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
index a6674eb1b3b265233062becd15d11a19ece2a829..0bcb3dd596e3bc03cbc91779d40232ce3d787c02 100644 (file)
@@ -5,6 +5,7 @@ import java.util.ArrayList;
 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;
@@ -19,6 +20,7 @@ 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;
@@ -43,24 +45,59 @@ public class Switch extends SSAExit implements ValRefBinder {
     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);
-            }
         }
     }
 
@@ -80,16 +117,16 @@ public class Switch extends SSAExit implements ValRefBinder {
                 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);
@@ -224,4 +261,9 @@ public class Switch extends SSAExit implements ValRefBinder {
         }
         return result.toArray(new SSABlock[result.size()]);
     }
+
+    @Override
+    public void forValRefs(ValRefVisitor visitor) {
+        visitor.visit(scrutinee);
+    }
 }
index 730463ab25d1ca6016be54533714fe6112bfe65c..b0391b96581cbe0df97d498589a862a23fe8b775 100644 (file)
@@ -15,6 +15,7 @@ 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.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;
@@ -88,4 +89,8 @@ public class Throw extends SSAExit {
     public SSABlock[] getSuccessors() {
         return SSABlock.EMPTY_ARRAY;
     }
+
+    @Override
+    public void forValRefs(ValRefVisitor visitor) {
+    }
 }
index 83b1e0cb67a81afe13249ace83f230097b2ed892..d3f22196b4058abe550f7060df723bbce4ff5f19 100644 (file)
@@ -5,6 +5,7 @@ import java.util.Arrays;
 \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
@@ -22,6 +23,7 @@ import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder;
 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
@@ -157,6 +159,26 @@ public class LetApply extends LetStatement implements ValRefBinder {
             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
@@ -459,4 +481,11 @@ public class LetApply extends LetStatement implements ValRefBinder {
     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
index 25d9c2544bffd4ab6bb8470ead45408e0900d683..ee5dcc7148533bfcaf8a8e44ee7d426b794ce1ca 100644 (file)
@@ -3,57 +3,61 @@ package org.simantics.scl.compiler.internal.codegen.ssa.statements;
 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
@@ -63,52 +67,52 @@ public class LetFunctions extends SSAStatement implements FunctionBinder {
 \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
@@ -132,16 +136,46 @@ public class LetFunctions extends SSAStatement implements FunctionBinder {
         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
@@ -157,40 +191,32 @@ public class LetFunctions extends SSAStatement implements FunctionBinder {
             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
@@ -199,19 +225,19 @@ public class LetFunctions extends SSAStatement implements FunctionBinder {
                     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
@@ -233,7 +259,7 @@ public class LetFunctions extends SSAStatement implements FunctionBinder {
     \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
@@ -242,4 +268,10 @@ public class LetFunctions extends SSAStatement implements FunctionBinder {
     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
index 2e2dcef2f5778685e9022f6020a610fb64fea8b5..c528d83a65436addac291ab7f40ce54a3e1aadf0 100644 (file)
@@ -2,7 +2,9 @@ package org.simantics.scl.compiler.internal.codegen.types;
 
 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;
@@ -33,16 +35,20 @@ public class JavaTypeTranslator {
             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) {
@@ -51,7 +57,7 @@ public class JavaTypeTranslator {
                     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)
                         ;
index 09923c3a52338f0740550429a4a856d0e65ea3ef..bbcd370bbc19cef0401a155e44b9270b35ae9f88 100644 (file)
@@ -3,6 +3,7 @@ package org.simantics.scl.compiler.internal.codegen.types;
 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;
 
@@ -24,6 +25,11 @@ public class StandardTypeConstructor extends TypeConstructor {
         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;
index 42df431810b630cdaf35d7b1d2cebfb75b280aa9..5518cb4878fec54a1d384b406f4d767e169427be 100644 (file)
@@ -138,4 +138,8 @@ public class ClassBuilder {
             System.out.println();
         }*/
     }
+    
+    public ModuleBuilder getModuleBuilder() {
+        return moduleBuilder;
+    }
 }
index ec44be75a1531adf48204c4d78653c09c87cb340..cc8f3e0c5ab5a7f5dfefb8cf43b77b28b76c756e 100644 (file)
@@ -128,23 +128,7 @@ public class CodeBuilderUtils {
                     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
@@ -169,36 +153,7 @@ public class CodeBuilderUtils {
                     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);
@@ -207,6 +162,62 @@ public class CodeBuilderUtils {
         }
     }
     
+    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) {
index 009eec2e24468fa015422bbc3ba1db8dd3818057..bd07654743acb86028727928b5d70c704d15b756 100644 (file)
@@ -71,6 +71,10 @@ public class JavaNamingPolicy {
         return NameMangling.mangle(name);
     }
 
+    public String getFreshClosureClassNameSuffix() {
+        return "$" + (++closureCount);
+    }
+    
     public String getFreshClosureClassName() {
         return moduleClassName + "$" + (++closureCount);
     }
index d740de293824b33e9241c6addd9bc66eebad46a6..56b5c8e6767141bfae285180962016409a7ed975 100644 (file)
@@ -208,6 +208,9 @@ public class MethodBuilder extends MethodBuilderBase {
         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);
@@ -221,4 +224,16 @@ public class MethodBuilder extends MethodBuilderBase {
     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;
+    }
 }
index 0f56aba8e2fbeae1c22c8b8893d3091a8921326c..7fb83fb49e3fd210dddd0ed7228a9febdaa792da 100644 (file)
@@ -429,6 +429,10 @@ public class MethodBuilderBase {
     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);
@@ -576,4 +580,30 @@ public class MethodBuilderBase {
     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);
+    }
 }
index 9b556ee7a4759e561695d0ca689d37d6c42b86d8..bdb56f4787d6df83f0f9121fb5d44c2d346bc9fb 100644 (file)
@@ -3,6 +3,7 @@ package org.simantics.scl.compiler.internal.codegen.utils;
 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
@@ -36,4 +37,8 @@ public class SSALambdaLiftingContext {
     public ErrorLog getErrorLog() {\r
         return errorLog;\r
     }\r
+    \r
+    public void addClosure(SSAClosure closure) {\r
+        module.closuresToGenerate.add(closure);\r
+    }\r
 }\r
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/ValRefVisitor.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/ValRefVisitor.java
new file mode 100644 (file)
index 0000000..17e0c9f
--- /dev/null
@@ -0,0 +1,8 @@
+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
index 6bed9f0661fc854b86afa24738bc3eb6dc032f91..1125a4bde9f41c52f372adcd22c9c627dc6f9010 100644 (file)
@@ -10,6 +10,7 @@ import org.simantics.scl.compiler.internal.codegen.references.IVal;
 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;
@@ -28,12 +29,12 @@ public class CodeWriter {
     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,
@@ -45,7 +46,7 @@ public class CodeWriter {
         }
     }
     
-    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))
@@ -69,6 +70,12 @@ public class CodeWriter {
         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);
@@ -120,6 +127,24 @@ public class CodeWriter {
                 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);
@@ -143,5 +168,13 @@ public class CodeWriter {
 
     public SSAFunction getFunction() {
         return block.getParent();
-    }        
+    }
+
+    public boolean isUnfinished() {
+        return block != null;
+    }
+
+    public void defineObject(SSAObject object) {
+        this.block.addStatement(new LetFunctions(object));
+    }
 }
index a0484176556009b895484aae50c526598d3a625d..da986195b51000d091ed1f622b3b4c021b97ab68 100644 (file)
@@ -9,6 +9,7 @@ import org.simantics.scl.compiler.constants.SCLConstant;
 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;
@@ -59,7 +60,7 @@ public class ModuleWriter {
                        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;
                }
        }
index 9dba1dba7006ced62957e1f6583b1d7ff7b6301a..7e95885bb4fce01f7ffdab6714f45ea6abc6ce74 100644 (file)
@@ -22,7 +22,7 @@ public class RecursiveDefinitionWriter {
         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
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/deriving/EqDeriver.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/deriving/EqDeriver.java
deleted file mode 100644 (file)
index 31c1837..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-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));
-    }
-
-}
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/deriving/HashableDeriver.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/deriving/HashableDeriver.java
deleted file mode 100644 (file)
index 0464a67..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-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));
-    }
-
-}
index 1726d7d02127792da3842bf8ce8541b8b05bf5f4..9eaff6a68919f8aa4a7cb9af4bc507e64aa96274 100644 (file)
@@ -3,7 +3,7 @@ package org.simantics.scl.compiler.internal.deriving;
 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;
@@ -18,7 +18,9 @@ import org.simantics.scl.compiler.elaboration.expressions.EVar;
 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;
@@ -33,10 +35,6 @@ import org.simantics.scl.compiler.internal.parsing.types.TVarAst;
 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(
@@ -56,7 +54,7 @@ class IODeriver implements InstanceDeriver {
         }
         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;
@@ -65,11 +63,16 @@ class IODeriver implements InstanceDeriver {
             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;
@@ -78,9 +81,9 @@ class IODeriver implements InstanceDeriver {
         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) {
index 0267692548c25aba1121f32d17cb88f5cc16d7b1..4ffe26b9d33fc534733b29bf273791ddb0651245 100644 (file)
@@ -10,8 +10,6 @@ public class InstanceDerivers {
             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
index de9f08845fb2bc84e27e5b65adcf96347cb93d90..257462bac3af5d42c38e8e525e1bb743be9a54d7 100644 (file)
@@ -9,7 +9,9 @@ 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.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;
@@ -43,7 +45,7 @@ class OrdDeriver implements InstanceDeriver {
         }
         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;
@@ -52,11 +54,16 @@ class OrdDeriver implements InstanceDeriver {
             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;
index e06a117e9cb20b4ecfc6ee03ed93a6f0a06eda09..afd2a4f8943dfe3d5aa711a611ac3a6827f7eae1 100644 (file)
@@ -10,7 +10,9 @@ 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.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;
@@ -46,7 +48,7 @@ class ShowDeriver implements InstanceDeriver {
         }
         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;
@@ -55,11 +57,16 @@ class ShowDeriver implements InstanceDeriver {
             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;
index ba982b1c6ab14c8fe886e318e471e42d4af54594..72aa1ea9e09e627c441125cfb16048c91d0d7993 100644 (file)
@@ -1,5 +1,7 @@
 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;
@@ -92,19 +94,25 @@ public class ConstraintEnvironment {
             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];
@@ -118,10 +126,15 @@ public class ConstraintEnvironment {
                         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;
     }
index 15ac6d664210a2b032c72011816d514678aab9d0..35f916ec0ed6290ee0c06ad1c97d96f95414efb6 100644 (file)
@@ -29,7 +29,6 @@ public class ConstraintSolver {
         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
index 7f200a11c40167e48875f48ddc97d614ffeb33af..9bf056bef825fe3a6c3db4e0cbef0fed1572c6eb 100644 (file)
@@ -1,6 +1,7 @@
 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;
@@ -12,6 +13,7 @@ import org.simantics.scl.compiler.elaboration.expressions.EConstant;
 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;
@@ -52,7 +54,7 @@ public class PatternMatchingCompiler {
         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>();
@@ -87,19 +89,34 @@ public class PatternMatchingCompiler {
                 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;
@@ -160,7 +177,7 @@ public class PatternMatchingCompiler {
             } 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)
@@ -172,21 +189,76 @@ public class PatternMatchingCompiler {
         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) {
index 20298b45c3e5ff080488c037a113a0f3f791b19f..12bd628fbd26543dcc443a43bcacc7a120e4e86a 100644 (file)
@@ -1,6 +1,8 @@
 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
@@ -23,4 +25,9 @@ public class Row {
             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
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/matching2/PatternMatchingCompiler2.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/matching2/PatternMatchingCompiler2.java
new file mode 100644 (file)
index 0000000..7849300
--- /dev/null
@@ -0,0 +1,264 @@
+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
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/matching2/Row2.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/matching2/Row2.java
new file mode 100644 (file)
index 0000000..2040f50
--- /dev/null
@@ -0,0 +1,34 @@
+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
index dff4622215473df74bced2f8bcebca7da746dc9a..3d7350f9f7863bc1cd7e63313d5767ab0505e269 100644 (file)
@@ -10,6 +10,7 @@ import org.simantics.scl.compiler.elaboration.expressions.EAsPattern;
 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;
@@ -120,7 +121,8 @@ public class BranchPointInjector extends StandardExpressionTransformer {
         ++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;
     }
     
@@ -196,6 +198,12 @@ public class BranchPointInjector extends StandardExpressionTransformer {
         return super.transform(expression);
     }
     
+    @Override
+    public Expression transform(ECHRRuleset expression) {
+        ++codeCounter;
+        return super.transform(expression);
+    }
+    
     @Override
     public Expression transform(EConstant expression) {
         ++codeCounter;
index dcb212488972f04954a6e9e13b05e734894040ea..6060315c4d3103f34933dc9e6fcee61ab2ea7233 100644 (file)
@@ -4,7 +4,7 @@ import java.util.ArrayList;
 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;
@@ -33,7 +33,6 @@ import org.simantics.scl.compiler.errors.Locations;
 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;
 
@@ -43,12 +42,6 @@ import gnu.trove.map.hash.TObjectIntHashMap;
 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;
@@ -80,11 +73,11 @@ public class TransformationBuilder {
                     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())));
@@ -252,10 +245,10 @@ public class TransformationBuilder {
             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);
@@ -298,7 +291,7 @@ public class TransformationBuilder {
                     new QAtom(decomposed.ruleMatchingRelation,
                             Type.EMPTY_ARRAY,
                             Expressions.vars(sourceVariables)),
-                            statementsToExpression(context, phase2Actions),
+                            statementsToExpression(context.getCompilationContext(), phase2Actions),
                             sourceVariables).compile(context)));
 
         // Enforcing statement
@@ -314,7 +307,7 @@ public class TransformationBuilder {
             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,
@@ -349,8 +342,8 @@ public class TransformationBuilder {
             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(
index 7b3face61c962d3b89dbe54c4c0361914762d311..75b083f0c9fbadc3a138e77b0b8a7a65b613bed4 100644 (file)
@@ -3,7 +3,7 @@ package org.simantics.scl.compiler.internal.elaboration.transformations;
 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;
@@ -34,26 +34,6 @@ import gnu.trove.map.hash.THashMap;
 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.
@@ -93,7 +73,7 @@ public class UnifiableFactory {
         }
         @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);
         }
     }
@@ -116,7 +96,7 @@ public class UnifiableFactory {
                         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));
         }
     }
@@ -148,7 +128,7 @@ public class UnifiableFactory {
             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) {
@@ -189,7 +169,7 @@ public class UnifiableFactory {
                 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));
             }
@@ -276,14 +256,14 @@ public class UnifiableFactory {
             
             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(contextunsafeCoerce, mfun.returnType, tupleType);
+                destructor = Expressions.constant(context.getCompilationContext(), Names.JavaBuiltin_unsafeCoerce, mfun.returnType, tupleType);
             }
             else {
                 Variable[] parameters = new Variable[arity];
@@ -292,7 +272,7 @@ public class UnifiableFactory {
                 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);
@@ -312,9 +292,9 @@ public class UnifiableFactory {
                 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);
         }
@@ -322,7 +302,7 @@ public class UnifiableFactory {
     }
     
     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);
     }
     
@@ -347,13 +327,13 @@ public class UnifiableFactory {
         //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) == '(') { // (), (,), (,,),...
@@ -369,7 +349,7 @@ public class UnifiableFactory {
                 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 + ".")));
     }
         
@@ -378,8 +358,8 @@ public class UnifiableFactory {
     }
     
     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),
@@ -390,8 +370,8 @@ public class UnifiableFactory {
     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,
@@ -400,8 +380,8 @@ public class UnifiableFactory {
     }
 
     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);
index 500cf3b20d5a148ed92ad0775ce0d0f487c54c7f..0312cf6f8819658e0a88b41a88e86565e63acc71 100644 (file)
@@ -129,7 +129,7 @@ bexp
     ;
 
 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,
@@ -152,15 +152,16 @@ accessor
 
 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
@@ -169,6 +170,7 @@ aexp
     | 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
@@ -195,6 +197,17 @@ statement
     | 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
index ecae4e5a54a36b288e0bc6cfff737aec8f16cc8e..b064a07aea9fb0a47e01c2010c2d6e50d47a56cc 100644 (file)
@@ -40,7 +40,7 @@ letter          = [a-zA-Z_]
 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}* "."
@@ -116,6 +116,7 @@ char_literal    = "'" ([^'\\\ufffd] | "\\" [^\ufffd]) "'"
 //  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); }
@@ -143,7 +144,7 @@ char_literal    = "'" ([^'\\\ufffd] | "\\" [^\ufffd]) "'"
   {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); }
@@ -151,6 +152,7 @@ char_literal    = "'" ([^'\\\ufffd] | "\\" [^\ufffd]) "'"
   "="             { 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); }
index e3111279029743dda253292caf2b37508c5440fc..028fd160d36e94d419afff3d3d3451825ae8dcde 100644 (file)
@@ -1,12 +1,12 @@
 /* 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
@@ -62,29 +62,31 @@ public class SCLLexer {
 \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
@@ -112,41 +114,43 @@ public class SCLLexer {
     "\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
@@ -182,261 +186,272 @@ public class SCLLexer {
     "\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
@@ -477,16 +492,17 @@ public class SCLLexer {
     "\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
@@ -562,20 +578,20 @@ public class SCLLexer {
   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
@@ -894,13 +910,13 @@ public class SCLLexer {
             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
@@ -909,392 +925,400 @@ public class SCLLexer {
           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
index fe5dac3c46f78e291d2ee254261596d2fdb25b19..e6534c5527cdbda79d88ba7cd2e43c9815041c62 100644 (file)
Binary files a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCLParser.dat and b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCLParser.dat differ
index ac61c901002bf20854505ed3f45419576468210e..1679a019ea267c266466369e77a724403b61817e 100644 (file)
@@ -13,18 +13,18 @@ public abstract class SCLParser {
     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
@@ -79,6 +79,7 @@ public abstract class SCLParser {
         "SEPARATED_DOT",\r
         "ESCAPED_ID",\r
         "LAMBDA",\r
+        "LAMBDA_MATCH",\r
         "LET",\r
         "IF",\r
         "MATCH",\r
@@ -107,9 +108,11 @@ public abstract class SCLParser {
         "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
@@ -154,6 +157,8 @@ public abstract class SCLParser {
         "symbolWithoutMinus",\r
         "listQualifier",\r
         "field",\r
+        "chrQuery",\r
+        "verboseChrQuery",\r
         "caseRhs",\r
         "guardedExpArrow",\r
         "equation",\r
@@ -362,19 +367,19 @@ public abstract class SCLParser {
         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
@@ -442,184 +447,196 @@ public abstract class SCLParser {
         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
@@ -760,6 +777,18 @@ public abstract class SCLParser {
      * 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&#42;\r
+     */\r
+    protected abstract Object reduceConstraintStatement();\r
     /**\r
      * declarations ::= LBRACE (declaration (SEMICOLON (declaration SEMICOLON)&#42; declaration)?)? RBRACE\r
      */\r
@@ -828,12 +857,16 @@ public abstract class SCLParser {
      * aexp ::= LAMBDA aexp aexp&#42; ARROW exp\r
      */\r
     protected abstract Object reduceLambda();\r
+    /**\r
+     * aexp ::= LAMBDA_MATCH LBRACE case (SEMICOLON case)&#42; 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
@@ -852,10 +885,6 @@ public abstract class SCLParser {
      * 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
@@ -888,6 +917,10 @@ public abstract class SCLParser {
      * aexp ::= LPAREN (exp (COMMA (exp COMMA)&#42; 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
@@ -1056,6 +1089,14 @@ public abstract class SCLParser {
      * field ::= ID\r
      */\r
     protected abstract Object reduceFieldShorthand();\r
+    /**\r
+     * chrQuery ::= (listQualifier COMMA)&#42; listQualifier\r
+     */\r
+    protected abstract Object reduceCHRQuery();\r
+    /**\r
+     * verboseChrQuery ::= LBRACE listQualifier (SEMICOLON listQualifier)&#42; RBRACE\r
+     */\r
+    protected abstract Object reduceVerboseCHRQuery();\r
     /**\r
      * caseRhs ::= ARROW exp (WHERE statements)?\r
      */\r
index bbf944f1e28b8c84cf78b00895fbca516158e8e4..7477c38900b7f7c05e8eef4dcc3c4757c64a8755 100644 (file)
@@ -41,7 +41,7 @@ import org.simantics.scl.compiler.elaboration.expressions.ETransformation;
 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;
@@ -51,6 +51,8 @@ import org.simantics.scl.compiler.elaboration.expressions.accessor.FieldAccessor
 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;
@@ -220,6 +222,7 @@ public class SCLParserImpl extends SCLParser {
                 );
     }
 
+    @SuppressWarnings("unchecked")
     @Override
     protected Object reduceClassDefinition() {
         int i=1;
@@ -273,6 +276,7 @@ public class SCLParserImpl extends SCLParser {
         return fundeps;
     }
 
+    @SuppressWarnings("unchecked")
     @Override
     protected Object reduceInstanceDefinition() {
         int i=1;
@@ -298,6 +302,7 @@ public class SCLParserImpl extends SCLParser {
                 declarations);
     }
 
+    @SuppressWarnings("unchecked")
     @Override
     protected Object reduceDerivingInstanceDefinition() {
         int i=2;
@@ -381,6 +386,7 @@ public class SCLParserImpl extends SCLParser {
         return get(0);
     }
 
+    @SuppressWarnings("unchecked")
     @Override
     protected Object reduceImportJava() {
         return new DImportJavaAst(((Token)get(2)).text, (ArrayList<DeclarationAst>)get(4));
@@ -686,6 +692,14 @@ public class SCLParserImpl extends SCLParser {
         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() {
@@ -704,7 +718,7 @@ public class SCLParserImpl extends SCLParser {
         return new EIf(
                 (Expression)get(1),
                 (Expression)get(3),
-                (Expression)get(5));
+                length() == 6 ? (Expression)get(5) : null);
     }
 
     @Override
@@ -728,14 +742,7 @@ public class SCLParserImpl extends SCLParser {
     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)));
@@ -880,6 +887,7 @@ public class SCLParserImpl extends SCLParser {
         throw new UnsupportedOperationException();
     }
 
+    @SuppressWarnings("unchecked")
     @Override
     protected void postReduce(Object reduced) {
         if(!(reduced instanceof Symbol))
@@ -887,6 +895,20 @@ public class SCLParserImpl extends SCLParser {
         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) {
@@ -901,7 +923,7 @@ public class SCLParserImpl extends SCLParser {
                     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);
@@ -1078,6 +1100,7 @@ public class SCLParserImpl extends SCLParser {
 
     private static final String[] EMPTY_STRING_ARRAY = new String[0];
     
+    @SuppressWarnings("unchecked")
     @Override
     protected Object reduceRuleDefinition() {
         String[] extendsNames = EMPTY_STRING_ARRAY;
@@ -1134,6 +1157,7 @@ public class SCLParserImpl extends SCLParser {
                 );
     }
 
+    @SuppressWarnings("unchecked")
     @Override
     protected Object reduceRelationDefinition() {
         return new DRelationAst((Expression)get(0), 
@@ -1207,4 +1231,52 @@ public class SCLParserImpl extends SCLParser {
     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));
+    }
+
 }
index 866fb8c985c4126b6e368746b83c767953c66cda..3d3b7b2f512033d90e13119b8edbfa8960cbaafd 100644 (file)
@@ -31,15 +31,17 @@ public class SCLPostLexer {
         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.THEN);
-        NO_SEMICOLON_BEFORE.add(SCLTerminals.ELSE);
         NO_SEMICOLON_BEFORE.add(SCLTerminals.IN);
         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);
@@ -49,6 +51,7 @@ public class SCLPostLexer {
     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;
@@ -56,6 +59,7 @@ public class SCLPostLexer {
             
     {
         indentations.add(0);
+        indentationTokens.add(SCLTerminals.EOF);
     }
     
     public SCLPostLexer(SCLLexer lexer) {
@@ -125,6 +129,7 @@ public class SCLPostLexer {
             int symbolIndentation = symbolStart-lineStart;
             //System.out.println("symbolIndentation = " + symbolIndentation);
             indentations.add(symbolIndentation);
+            indentationTokens.add(prevTokenId);
             firstTokenOfLine = false;
         }
         else if(firstTokenOfLine) {
@@ -135,11 +140,12 @@ public class SCLPostLexer {
                 //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 }"));
                     }
-                    if(indentations.get(indentations.size()-1) == level)
+                    if(indentations.get(indentations.size()-1) == level && symbolId != SCLTerminals.ELSE)
                         push(new Token(SCLTerminals.SEMICOLON, symbolStart, symbolStart, "implicit ;"));
                 }
             }
@@ -151,37 +157,48 @@ public class SCLPostLexer {
         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.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 }"));
+            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 && removedToken == SCLTerminals.WHEN)
+                curToken = symbol = new Token(SCLTerminals.THEN_AFTER_WHEN, symbol.location, 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 }"));
-            }
-            if(indentations.isEmpty())
-                throw error(symbolStart, symbolEnd, "No corresponding opening parenthesis for '" + symbol.text + "'.");
-            push(symbol);
-            indentations.add(-1);
+            //if(symbolId == SCLTerminals.THEN)
+            //    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)
index 8417100f4bc13b0c07d1c5e3fb1ea1648457f24c..f542d31d5351eb813efe908f2bd21489e961cafd 100644 (file)
@@ -45,39 +45,42 @@ public interface SCLTerminals {
     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
index c1b2d43723e744f780983627d7d1f3480db55897..3c77000757f67b96d56a2f4f6a5125888a4a8300 100644 (file)
@@ -4,6 +4,7 @@ import java.util.Arrays;
 
 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;
@@ -38,9 +39,11 @@ public class TApplyAst extends TypeAst {
     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);
index 9633d8619daed76b35f66ccc75d7b36b5a416ea8..e95b3ad9a9a4cdf21aab2abafa835b6457d013ad 100644 (file)
@@ -2,6 +2,7 @@ package org.simantics.scl.compiler.internal.parsing.types;
 
 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;
@@ -40,7 +41,7 @@ public class TVarAst extends TypeAst {
                 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);
@@ -56,14 +57,19 @@ public class TVarAst extends TypeAst {
             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.");
@@ -71,16 +77,7 @@ public class TVarAst extends TypeAst {
                     }
                     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;
             }
         }
         
index d971f7d0faf8735fe1bb8377432e1de0fa34ff1b..bec138283039b19b42582922c70cf9aec23a717f 100644 (file)
@@ -7,6 +7,7 @@ import org.simantics.scl.compiler.common.datatypes.Constructor;
 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;
@@ -279,11 +280,10 @@ public class SCLDocumentationExtensionNodeHandler implements ExtensionNodeHandle
     }
     
     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;
         }
@@ -292,10 +292,12 @@ public class SCLDocumentationExtensionNodeHandler implements ExtensionNodeHandle
         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)) {
@@ -304,17 +306,19 @@ public class SCLDocumentationExtensionNodeHandler implements ExtensionNodeHandle
         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>"));
     }
index 8edd9f7019b3f1d01992a2471414b900d21fcd3f..2f6d52bdba63298ad51c6de3e4f2c8fe3c5b6b89 100644 (file)
@@ -11,10 +11,9 @@ import org.simantics.scl.compiler.common.names.Name;
 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;
@@ -31,8 +30,7 @@ import gnu.trove.procedure.TObjectProcedure;
 
 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>>();
@@ -53,12 +51,8 @@ public class ConcreteModule implements Module {
         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) {
@@ -169,8 +163,8 @@ public class ConcreteModule implements Module {
     }
 
     @Override
-    public TypeConstructor getTypeConstructor(String name) {
-        return typeConstructors.get(name);
+    public TypeDescriptor getTypeDescriptor(String name) {
+        return typeDescriptors.get(name);
     }
 
     @Override
@@ -199,11 +193,6 @@ public class ConcreteModule implements Module {
         return documentation;
     }
 
-    @Override
-    public TypeAlias getTypeAlias(String name) {
-        return typeAliases.get(name);
-    }
-
     public void setClasses(Map<String, byte[]> classes) {
         this.classes = classes;
     }
@@ -260,16 +249,11 @@ public class ConcreteModule implements Module {
 
     @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) {
index a5399e88f1f642c2212ee7004b8d60f8757df441..00871dcdf377aebd7b1d77051d70182033906841 100644 (file)
@@ -8,7 +8,7 @@ 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;
@@ -101,7 +101,7 @@ public abstract class LazyModule implements Module {
     }
 
     @Override
-    public TypeConstructor getTypeConstructor(String name) {
+    public TypeDescriptor getTypeDescriptor(String name) {
         return null;
     }
 
@@ -125,11 +125,6 @@ public abstract class LazyModule implements Module {
         return null;
     }
     
-    @Override
-    public TypeAlias getTypeAlias(String name) {
-        return null;
-    }
-    
     @Override
     public Collection<TransformationRule> getRules() {
         return Collections.emptyList();
index beda6d53419f722f6e082008dd617e5461c1df25..e8a1113367be7a9acde195e7e0b9e33629da9f57 100644 (file)
@@ -6,10 +6,9 @@ import java.util.function.Consumer;
 
 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;
@@ -29,11 +28,12 @@ public interface Module {
     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();
index 86b1ba7663d472b722bd313136e019f7e5475a6a..1e43e755be4d79f5ce5933b157765e98203035bf 100644 (file)
-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&ouml;
- */
-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&ouml;\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
index c91daab91147480b6437b32a52be87a261b50261..0c134ee5c1130b5e9e730dd9552e01401f367c43 100644 (file)
@@ -60,6 +60,34 @@ public class ExpressionClassLoader extends ClassLoader implements MutableClassLo
         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);
         
index c5904b3c44fdb8f35427aa548e4c7165e877c932..2415e652074384c500ee8a0cc0914f0eb22f568a 100644 (file)
@@ -1,7 +1,5 @@
 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;
@@ -15,17 +13,8 @@ import org.simantics.scl.compiler.internal.codegen.types.JavaTypeTranslator;
 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 {
@@ -117,32 +106,7 @@ 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);
         }
         
index 9df29e95815e7b892fdbc6ebfd91b6a5d1de2a09..f4e9c7de048cc6347c1c685a60a4777a1aaaf107 100644 (file)
@@ -17,8 +17,12 @@ import org.simantics.scl.compiler.module.Module;
 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", "")
@@ -89,8 +93,8 @@ public abstract class TextualModuleSource implements ModuleSource {
             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) {
index 39f0ac721ee2a2bd32d366a9e17123e6c9ab6e74..d87beec65a7380361a2c45961fa41c2c886b8c18 100644 (file)
@@ -8,6 +8,7 @@ import java.util.Map;
 
 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;
@@ -178,11 +179,13 @@ public class ExpressionEvaluator {
     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: {
@@ -248,8 +251,7 @@ public class ExpressionEvaluator {
         
         // 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());
@@ -265,7 +267,7 @@ public class ExpressionEvaluator {
         
         // Type checking
         {
-            TypingContext context = new TypingContext(errorLog, environment);
+            TypingContext context = new TypingContext(compilationContext);
 
             context.pushEffectUpperBound(expression.location, expectedEffect);
             expression = expression.checkType(context, expectedType);
@@ -306,14 +308,15 @@ public class ExpressionEvaluator {
         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())
index d7b896a98ff90edd0f2d60e917f8779c6537cb2e..763bc9d9cdfdb35562474fc43f3cd1d8c03082a1 100755 (executable)
@@ -10,7 +10,6 @@ public interface SCLCompilerConfiguration {
     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;
@@ -33,6 +32,6 @@ public interface SCLCompilerConfiguration {
     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;
     
 }
index 56325d513e58d6f32e244d6ff2adb2515f649bbe..5a3c39e60a3fcecd9f56bf68cc6a2a8f32cf85d1 100644 (file)
@@ -3,6 +3,7 @@ package org.simantics.scl.compiler.top;
 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;
@@ -72,7 +73,7 @@ public class ToplevelEffectDecorator implements ExpressionDecorator {
         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);
@@ -82,7 +83,7 @@ public class ToplevelEffectDecorator implements ExpressionDecorator {
             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);
@@ -92,7 +93,7 @@ public class ToplevelEffectDecorator implements ExpressionDecorator {
             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);
@@ -102,7 +103,7 @@ public class ToplevelEffectDecorator implements ExpressionDecorator {
             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);
index 81dec240335e408bdb55514b1d1a4dde2c8f0121..b7266ef7efb7514a6de9adadba17b2c65392af13 100644 (file)
@@ -4,6 +4,7 @@ import org.simantics.scl.compiler.environment.Environment;
 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;
@@ -289,4 +290,64 @@ public class Skeletons {
                 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
+    }
 }
index 88d80882e67312989f945ee6a81524b79418fcad..bd58949a6309918eb1ee0fce39425231c4056149 100644 (file)
@@ -218,6 +218,22 @@ public class TApply extends Type {
         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();
@@ -240,4 +256,9 @@ public class TApply extends Type {
         return getCanonicalFunction().equalsCanonical(apply.getCanonicalFunction())
                 && getCanonicalParameter().equalsCanonical(apply.getCanonicalParameter());
     }
+    
+    @Override
+    public Type[] skeletonCanonicalChildren() {
+        return new Type[] {Skeletons.canonicalSkeleton(function), Skeletons.canonicalSkeleton(parameter)};
+    }
 }
index 16e0c29eb5b962634cce80b8fe82f904f612461d..675047ae8510a8c583ddcd8a6c3c80bfdee9e7df 100644 (file)
@@ -71,11 +71,6 @@ public final class TCon extends Type {
         return this == obj;
     }
     
-    @Override
-    public int hashCode() {
-        return System.identityHashCode(this);
-    }
-    
     @Override
     public void updateHashCode(TypeHashCodeContext context) {
         context.append(System.identityHashCode(this));        
@@ -103,11 +98,11 @@ public final class TCon extends Type {
     }
 
        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
@@ -153,6 +148,11 @@ public final class TCon extends Type {
     public Type copySkeleton(THashMap<TMetaVar, TMetaVar> metaVarMap) {
         return this;
     }
+    
+    @Override
+    public int hashCode() {
+        return System.identityHashCode(this);
+    }
 
     @Override
     public int hashCode(int hash) {
@@ -164,8 +164,28 @@ public final class TCon extends Type {
         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;
+    }
 }
index 98b4578af676642e54288a161037eda249314150..b4b1af8196486fc14e2209983d425e8279d83edc 100644 (file)
@@ -203,6 +203,56 @@ public class TForAll extends Type {
         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();
@@ -222,6 +272,11 @@ public class TForAll extends Type {
     @Override
     public Kind getKind(Environment context) {
         return Kinds.STAR;
+    }
+
+    @Override
+    public Type[] skeletonCanonicalChildren() {
+        return new Type[] { Skeletons.canonicalSkeleton(type) };
     } 
     
 }
index e26c5b07ac923922a8c4e4270ede948b3b1f3cbb..6fc9b42b22bb165481e7cb0da6f8c1e0122c3ce2 100644 (file)
@@ -209,6 +209,22 @@ public class TFun extends 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();
@@ -243,4 +259,9 @@ public class TFun extends Type {
     public Kind getKind(Environment context) {
         return Kinds.STAR;
     }
+    
+    @Override
+    public Type[] skeletonCanonicalChildren() {
+        return new Type[] {Skeletons.canonicalSkeleton(domain), Skeletons.canonicalSkeleton(range)};
+    }
 }
index 0d3114fc5765b0bad9a3ad11df5aaef8dc803bf1..d78d745eb670c0ccb99719c2690e314e6a610488 100644 (file)
@@ -97,14 +97,6 @@ public class TMetaVar extends Type {
             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)
@@ -142,6 +134,10 @@ public class TMetaVar extends Type {
     }
 
     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)
@@ -280,6 +276,14 @@ public class TMetaVar extends Type {
         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)
@@ -296,6 +300,36 @@ public class TMetaVar extends Type {
             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;
@@ -343,4 +377,10 @@ public class TMetaVar extends Type {
     public Kind getKind(Environment context) {
         return kind;
     }
+
+    @Override
+    public Type[] skeletonCanonicalChildren() {
+        // Assumes that this is already canonical skeleton
+        return EMPTY_ARRAY;
+    }
 }
index e8a0469c5d996f428c205c13018fe1e6e009707c..c28e62093abb249896adf6689135b1ac787296d2 100644 (file)
@@ -191,6 +191,24 @@ public class TPred extends Type {
             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) {
@@ -211,4 +229,12 @@ public class TPred extends Type {
     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;
+    }
 }
index c3d88b00d1c826416e2d6af8144db9cddacde6b6..9b2449aa706c31a07e510157bfd0ec2127a6214e 100644 (file)
@@ -185,6 +185,22 @@ public class TUnion extends Type {
         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)
@@ -228,4 +244,9 @@ public class TUnion extends Type {
     public Kind getKind(Environment context) {
         return Kinds.EFFECT;
     }
+    
+    @Override
+    public Type[] skeletonCanonicalChildren() {
+        return EMPTY_ARRAY;
+    }
 }
index aeb9711453800ff1fce03878743880e613092d9b..df342dd5fb2e9074e9da1e3a3b3c9a76a6ff80a7 100644 (file)
@@ -59,11 +59,6 @@ public final class TVar extends Type {
         return this == obj;
     }
     
-    @Override
-    public int hashCode() {
-        return System.identityHashCode(this);
-    }
-    
     @Override
     public void updateHashCode(TypeHashCodeContext context) {
         TObjectIntHashMap<TVar> varHashCode = context.getVarHashCode();
@@ -141,6 +136,11 @@ public final class TVar extends Type {
         return this;
     }
     
+    @Override
+    public int hashCode() {
+        return System.identityHashCode(this);
+    }
+    
     @Override
     public int hashCode(int hash) {
         return HashCodeUtils.update(hash, System.identityHashCode(this));
@@ -156,6 +156,26 @@ public final class TVar extends Type {
         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;
@@ -165,4 +185,9 @@ public final class TVar extends Type {
     public Kind getKind(Environment context) {
         return kind;
     }
+    
+    @Override
+    public Type[] skeletonCanonicalChildren() {
+        return EMPTY_ARRAY;
+    }
 }
index 386accc4ff5e1e941d84a1b84768740d81558877..c158cb31bc8b99b42d4b390c09bce0df0aef396b 100644 (file)
@@ -119,6 +119,13 @@ public abstract class Type {
     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);
     
@@ -175,4 +182,6 @@ public abstract class Type {
 
     public abstract Kind getKind(Environment context);
 
+    public abstract Type[] skeletonCanonicalChildren(); 
+            
 }
\ No newline at end of file
index e6454fc0c22fcc6561fbe82cb6f96dc651b21b3c..b20ee9f121ba4890be21b58e53540de72b4a1a6a 100644 (file)
@@ -98,9 +98,7 @@ public class Types {
     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");
@@ -1034,6 +1032,10 @@ public class Types {
         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)
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/util/SkeletonKeyMap.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/util/SkeletonKeyMap.java
new file mode 100644 (file)
index 0000000..9db48b2
--- /dev/null
@@ -0,0 +1,18 @@
+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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/ActiveTests.java b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/ActiveTests.java
deleted file mode 100644 (file)
index f9533ef..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-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(); }
-}
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/FindAllowedChars.java b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/FindAllowedChars.java
deleted file mode 100644 (file)
index 1e40786..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/ModuleRegressionTests.java b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/ModuleRegressionTests.java
deleted file mode 100644 (file)
index b6bc901..0000000
+++ /dev/null
@@ -1,290 +0,0 @@
-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);
-        }
-    }
-
-}
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/RegressionTests.java b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/RegressionTests.java
deleted file mode 100644 (file)
index 1f397fe..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-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 {
-}
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/ScriptTestBase.java b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/ScriptTestBase.java
deleted file mode 100644 (file)
index 9e4401d..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-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();
-    }
-    
-}
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/ScriptTests.java b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/ScriptTests.java
deleted file mode 100644 (file)
index a462f53..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-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(); }
-    
-}
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/TestAll.java b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/TestAll.java
deleted file mode 100644 (file)
index 38d4ae3..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-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 {
-}
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/TestBase.java b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/TestBase.java
deleted file mode 100644 (file)
index 466c097..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-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();
-        }
-    }
-}
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/TestClassNaming.java b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/TestClassNaming.java
deleted file mode 100644 (file)
index 283e0e1..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/TestCommandParsing.java b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/TestCommandParsing.java
deleted file mode 100644 (file)
index f8b8eb9..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/TestCommandSession.java b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/TestCommandSession.java
deleted file mode 100644 (file)
index a93f706..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-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) [(),(),()]");
-    }
-
-}
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/TestExpressionEvaluator.java b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/TestExpressionEvaluator.java
deleted file mode 100644 (file)
index 7afa678..0000000
+++ /dev/null
@@ -1,201 +0,0 @@
-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);
-        }
-    }
-}
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/TestTypeDesc.java b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/TestTypeDesc.java
deleted file mode 100644 (file)
index 451dca8..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-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());
-
-    }
-}
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/UnimplementedTests.java b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/UnimplementedTests.java
deleted file mode 100644 (file)
index 612a3ab..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-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(); }
-    
-}
-
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/experimentation/RecursiveInitialization.java b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/experimentation/RecursiveInitialization.java
deleted file mode 100644 (file)
index 5f5d20d..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/experimentation/TestEquals.java b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/experimentation/TestEquals.java
deleted file mode 100644 (file)
index 022ae57..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/experimentation/TestTypeDesc.java b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/experimentation/TestTypeDesc.java
deleted file mode 100644 (file)
index 7153889..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-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());
-
-    }
-}
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/imports/Maybe4Imports.java b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/imports/Maybe4Imports.java
deleted file mode 100644 (file)
index 30fe627..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/markdown/spec.txt b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/markdown/spec.txt
deleted file mode 100644 (file)
index bdaed43..0000000
+++ /dev/null
@@ -1,9252 +0,0 @@
----
-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>&lt;a title=&quot;a lot</h2>
-<p>of dashes&quot;/&gt;</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>&gt; 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>&lt;a/&gt;
-*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>&lt;
- &gt;
-</code></pre>
-````````````````````````````````
-
-
-With tildes:
-
-```````````````````````````````` example
-~~~
-<
- >
-~~~
-.
-<pre><code>&lt;
- &gt;
-</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>&lt;!-- foo --&gt;
-</code></pre>
-````````````````````````````````
-
-
-```````````````````````````````` example
-  <div>
-
-    <div>
-.
-  <div>
-<pre><code>&lt;div&gt;
-</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>&lt;td&gt;
-  Hi
-&lt;/td&gt;
-</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&quot;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 &quot;title&quot; ok</p>
-````````````````````````````````
-
-
-This is a link reference definition, but it has no title:
-
-```````````````````````````````` example
-[foo]: /url
-"title" ok
-.
-<p>&quot;title&quot; ok</p>
-````````````````````````````````
-
-
-This is not a link reference definition, because it is indented
-four spaces:
-
-```````````````````````````````` example
-    [foo]: /url "title"
-
-[foo]
-.
-<pre><code>[foo]: /url &quot;title&quot;
-</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>&gt; # Foo
-&gt; bar
-&gt; 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
-
-    &gt; 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>!&quot;#$%&amp;'()*+,-./:;&lt;=&gt;?@[\]^_`{|}~</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*
-&lt;br/&gt; not a tag
-[not a link](/foo)
-`not code`
-1. not a list
-* not a list
-# not a heading
-[foo]: /url &quot;not a reference&quot;</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
-&nbsp; &amp; &copy; &AElig; &Dcaron;
-&frac34; &HilbertSpace; &DifferentialD;
-&ClockwiseContourIntegral; &ngE;
-.
-<p>  &amp; © Æ Ď
-¾ ℋ ⅆ
-∲ ≧̸</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
-&#35; &#1234; &#992; &#98765432; &#0;
-.
-<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
-&#X22; &#XD06; &#xcab;
-.
-<p>&quot; ആ ಫ</p>
-````````````````````````````````
-
-
-Here are some nonentities:
-
-```````````````````````````````` example
-&nbsp &x; &#; &#x;
-&ThisIsNotDefined; &hi?;
-.
-<p>&amp;nbsp &amp;x; &amp;#; &amp;#x;
-&amp;ThisIsNotDefined; &amp;hi?;</p>
-````````````````````````````````
-
-
-Although HTML5 does accept some entity references
-without a trailing semicolon (such as `&copy`), these are not
-recognized here, because it makes the grammar too ambiguous:
-
-```````````````````````````````` example
-&copy
-.
-<p>&amp;copy</p>
-````````````````````````````````
-
-
-Strings that are not on the list of HTML5 named entities are not
-recognized as entity references either:
-
-```````````````````````````````` example
-&MadeUpEntity;
-.
-<p>&amp;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="&ouml;&ouml;.html">
-.
-<a href="&ouml;&ouml;.html">
-````````````````````````````````
-
-
-```````````````````````````````` example
-[foo](/f&ouml;&ouml; "f&ouml;&ouml;")
-.
-<p><a href="/f%C3%B6%C3%B6" title="föö">foo</a></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-[foo]
-
-[foo]: /f&ouml;&ouml; "f&ouml;&ouml;"
-.
-<p><a href="/f%C3%B6%C3%B6" title="föö">foo</a></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-``` f&ouml;&ouml;
-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&ouml;&ouml;`
-.
-<p><code>f&amp;ouml;&amp;ouml;</code></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-    f&ouml;f&ouml;
-.
-<pre><code>f&amp;ouml;f&amp;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>&lt;a href=&quot;</code>&quot;&gt;`</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>&lt;http://foo.bar.</code>baz&gt;`</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*&quot;foo&quot;*</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_&quot;foo&quot;_</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_&quot;bb&quot;_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**&quot;foo&quot;**</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__&quot;foo&quot;__</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 &quot;<em>bar</em>&quot; 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](&lt;/my uri&gt;)</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&auml;)
-.
-<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 \"&quot;")
-.
-<p><a href="/url" title="title &quot;&quot;">link</a></p>
-````````````````````````````````
-
-
-Nested balanced quotes are not allowed without escaping:
-
-```````````````````````````````` example
-[link](/url "title "and" title")
-.
-<p>[link](/url &quot;title &quot;and&quot; title&quot;)</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 &quot;and&quot; 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 &amp; 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 &amp; tracks" /></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-![foo *bar*][foobar]
-
-[FOOBAR]: train.jpg "train & tracks"
-.
-<p><img src="train.jpg" alt="foo bar" title="train &amp; 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 &quot;title&quot;</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&amp;id=22&amp;boolean">http://foo.bar.baz/test?q=hello&amp;id=22&amp;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>&lt;http://foo.bar/baz bim&gt;</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>&lt;foo+@bar.example.com&gt;</p>
-````````````````````````````````
-
-
-These are not autolinks:
-
-```````````````````````````````` example
-<>
-.
-<p>&lt;&gt;</p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-< http://foo.bar >
-.
-<p>&lt; http://foo.bar &gt;</p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-<m:abc>
-.
-<p>&lt;m:abc&gt;</p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-<foo.bar.baz>
-.
-<p>&lt;foo.bar.baz&gt;</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>&lt;33&gt; &lt;__&gt;</p>
-````````````````````````````````
-
-
-Illegal attribute names:
-
-```````````````````````````````` example
-<a h*#ref="hi">
-.
-<p>&lt;a h*#ref=&quot;hi&quot;&gt;</p>
-````````````````````````````````
-
-
-Illegal attribute values:
-
-```````````````````````````````` example
-<a href="hi'> <a href=hi'>
-.
-<p>&lt;a href=&quot;hi'&gt; &lt;a href=hi'&gt;</p>
-````````````````````````````````
-
-
-Illegal [whitespace]:
-
-```````````````````````````````` example
-< a><
-foo><bar/ >
-.
-<p>&lt; a&gt;&lt;
-foo&gt;&lt;bar/ &gt;</p>
-````````````````````````````````
-
-
-Missing [whitespace]:
-
-```````````````````````````````` example
-<a href='bar'title=title>
-.
-<p>&lt;a href='bar'title=title&gt;</p>
-````````````````````````````````
-
-
-Closing tags:
-
-```````````````````````````````` example
-</a></foo >
-.
-<p></a></foo ></p>
-````````````````````````````````
-
-
-Illegal attributes in closing tag:
-
-```````````````````````````````` example
-</a href="foo">
-.
-<p>&lt;/a href=&quot;foo&quot;&gt;</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 &lt;!-- not a comment -- two hyphens --&gt;</p>
-````````````````````````````````
-
-
-Not comments:
-
-```````````````````````````````` example
-foo <!--> foo -->
-
-foo <!-- foo--->
-.
-<p>foo &lt;!--&gt; foo --&gt;</p>
-<p>foo &lt;!-- foo---&gt;</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="&ouml;">
-.
-<p>foo <a href="&ouml;"></p>
-````````````````````````````````
-
-
-Backslash escapes do not work in HTML attributes:
-
-```````````````````````````````` example
-foo <a href="\*">
-.
-<p>foo <a href="\*"></p>
-````````````````````````````````
-
-
-```````````````````````````````` example
-<a href="\"">
-.
-<p>&lt;a href=&quot;&quot;&quot;&gt;</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.
-
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/performance/SumOfInverses.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/performance/SumOfInverses.scl
deleted file mode 100644 (file)
index a3f9407..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/performance/SumOfInverses2.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/performance/SumOfInverses2.scl
deleted file mode 100644 (file)
index 7745029..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-import "Prelude"\r
-\r
-main :: Integer -> Double\r
-main m = sum [1/(fromInteger x) | x <- [1..m]]\r
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/AmbiguousType.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/AmbiguousType.scl
deleted file mode 100644 (file)
index f4871d7..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-\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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ApplicationOfNunfunction.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ApplicationOfNunfunction.scl
deleted file mode 100644 (file)
index 13167be..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-main = "Hello" "world!"\r
---\r
-1:8-1:24: Application of non-function.\r
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Arity1.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Arity1.scl
deleted file mode 100644 (file)
index fa48e47..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-\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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/AsPattern.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/AsPattern.scl
deleted file mode 100644 (file)
index 0e33370..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/BigContext.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/BigContext.scl
deleted file mode 100644 (file)
index fc70cc2..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/BigFunction.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/BigFunction.scl
deleted file mode 100644 (file)
index 102bc1d..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/BigInstances.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/BigInstances.scl
deleted file mode 100644 (file)
index c64b1b7..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-\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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/BinaryOperators1.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/BinaryOperators1.scl
deleted file mode 100644 (file)
index 86263c9..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/BlankExpression.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/BlankExpression.scl
deleted file mode 100644 (file)
index f31e144..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-main = _\r
---\r
-???
\ No newline at end of file
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/BooleanId.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/BooleanId.scl
deleted file mode 100644 (file)
index 2044c1c..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-@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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Bug4450.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Bug4450.scl
deleted file mode 100644 (file)
index 54e65c2..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Character1.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Character1.scl
deleted file mode 100644 (file)
index b08d2ae..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-import "Prelude"\r
-\r
-main = subChar '6' '0'\r
---\r
-6\r
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ClashingClass.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ClashingClass.scl
deleted file mode 100644 (file)
index dee1e8d..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-\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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ClashingData.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ClashingData.scl
deleted file mode 100644 (file)
index 60245db..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-\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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ClashingInstance.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ClashingInstance.scl
deleted file mode 100644 (file)
index 72178db..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ClashingValueDefinition.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ClashingValueDefinition.scl
deleted file mode 100644 (file)
index f7ec72a..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-a = 1\r
-a = 2\r
-main = "Should not be executed."\r
---\r
-???
\ No newline at end of file
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ClashingValueType.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ClashingValueType.scl
deleted file mode 100644 (file)
index d248d20..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-\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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Collaz.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Collaz.scl
deleted file mode 100644 (file)
index 2e4552d..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Compose.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Compose.scl
deleted file mode 100644 (file)
index fad8b9b..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Composition.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Composition.scl
deleted file mode 100644 (file)
index 80b1c06..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ConjunctionMacro.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ConjunctionMacro.scl
deleted file mode 100644 (file)
index 99188f8..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-(&&) :: 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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Constant.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Constant.scl
deleted file mode 100644 (file)
index 7ea0367..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-\r
-a = 14 :: Integer\r
-\r
-main = a\r
---\r
-14
\ No newline at end of file
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ConstructorNameClash.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ConstructorNameClash.scl
deleted file mode 100644 (file)
index 52826a5..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-\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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/DefaultMethods1.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/DefaultMethods1.scl
deleted file mode 100644 (file)
index 142dd30..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Deriving3.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Deriving3.scl
deleted file mode 100644 (file)
index ec2f5b7..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Deriving4.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Deriving4.scl
deleted file mode 100644 (file)
index 03ea0d6..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/DifferentBranchTypes.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/DifferentBranchTypes.scl
deleted file mode 100644 (file)
index 2a0925f..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Div.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Div.scl
deleted file mode 100644 (file)
index 4a8e1ca..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-import "Prelude"\r
-\r
-main = 7 `div` 3\r
---\r
-2
\ No newline at end of file
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/DoubleConversion.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/DoubleConversion.scl
deleted file mode 100644 (file)
index 31e95ed..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/DoubleEffect.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/DoubleEffect.scl
deleted file mode 100644 (file)
index b061510..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Effects1.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Effects1.scl
deleted file mode 100644 (file)
index 11a3303..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Effects2.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Effects2.scl
deleted file mode 100644 (file)
index d595ee9..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Effects3.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Effects3.scl
deleted file mode 100644 (file)
index 7184829..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Effects4.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Effects4.scl
deleted file mode 100644 (file)
index 85138a6..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Effects5.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Effects5.scl
deleted file mode 100644 (file)
index 595b634..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Effects6.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Effects6.scl
deleted file mode 100644 (file)
index e99dd4f..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/EmptyLet.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/EmptyLet.scl
deleted file mode 100644 (file)
index 68c6623..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Equality.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Equality.scl
deleted file mode 100644 (file)
index acf00e9..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Equations1.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Equations1.scl
deleted file mode 100644 (file)
index 613d56b..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-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)]
-
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ExistentialData.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ExistentialData.scl
deleted file mode 100644 (file)
index 62130b4..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ExistentialData2.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ExistentialData2.scl
deleted file mode 100644 (file)
index b029969..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ExpressionParsing.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ExpressionParsing.scl
deleted file mode 100644 (file)
index 6719bf9..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/FaultyRecursion.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/FaultyRecursion.scl
deleted file mode 100644 (file)
index 523b408..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-fib n = fib\r
---\r
-1:9-1:12: Expected <a> got <b -> <c> a>.
\ No newline at end of file
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Fibonacci.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Fibonacci.scl
deleted file mode 100644 (file)
index b7b56f5..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Fibonacci2.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Fibonacci2.scl
deleted file mode 100644 (file)
index 229145f..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Fibonacci3.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Fibonacci3.scl
deleted file mode 100644 (file)
index d5ce91c..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/FingerTree.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/FingerTree.scl
deleted file mode 100644 (file)
index b81f642..0000000
+++ /dev/null
@@ -1,173 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/FoldMissingInitialValue.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/FoldMissingInitialValue.scl
deleted file mode 100644 (file)
index affa2e6..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/FoldlBuild1.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/FoldlBuild1.scl
deleted file mode 100644 (file)
index 21dfdea..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/FoldlBuild2.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/FoldlBuild2.scl
deleted file mode 100644 (file)
index 2078fb7..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Forall1.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Forall1.scl
deleted file mode 100644 (file)
index 32e51a7..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-     \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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Forall2.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Forall2.scl
deleted file mode 100644 (file)
index 97d1c35..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-\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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Forall3.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Forall3.scl
deleted file mode 100644 (file)
index 018a2a0..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-\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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Formula.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Formula.scl
deleted file mode 100644 (file)
index 10eafb0..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/FromDynamic.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/FromDynamic.scl
deleted file mode 100644 (file)
index 1ac2e77..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-import "Prelude"\r
-\r
-main = (fromDynamic (toDynamic 42) :: String) + "foo"\r
---\r
-42foo
\ No newline at end of file
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/FromDynamic2.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/FromDynamic2.scl
deleted file mode 100644 (file)
index 1b6c1d9..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-import "Prelude"\r
-\r
-main = (fromDynamic (toDynamic "42") :: Integer) - 2\r
---\r
-40
\ No newline at end of file
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/FromDynamic3.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/FromDynamic3.scl
deleted file mode 100644 (file)
index a3318d4..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-import "Prelude"\r
-\r
-main = arrayToList (fromDynamic (toDynamic ["42"]) :: (Array Integer))\r
---\r
-[42]
\ No newline at end of file
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/FromDynamic4.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/FromDynamic4.scl
deleted file mode 100644 (file)
index fb4c320..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-import "Prelude"\r
-import "Vector"\r
-\r
-main = (fromDynamic (toDynamic ["42"]) :: (Vector Double))!0\r
---\r
-42.0
\ No newline at end of file
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/FromDynamic5.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/FromDynamic5.scl
deleted file mode 100644 (file)
index d0d0fd3..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-import "Prelude"\r
-import "Vector"\r
-\r
-main = (fromDynamic (toDynamic (mvector [42.0]))) :: [Integer]\r
---\r
-[42]
\ No newline at end of file
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/FunctionFunctor.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/FunctionFunctor.scl
deleted file mode 100644 (file)
index f634810..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/FunctionalDependencies1.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/FunctionalDependencies1.scl
deleted file mode 100644 (file)
index 203de1d..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/FunctionalDependencies2.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/FunctionalDependencies2.scl
deleted file mode 100644 (file)
index 707bb9e..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Functor.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Functor.scl
deleted file mode 100644 (file)
index 6bbd359..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/FunctorM1.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/FunctorM1.scl
deleted file mode 100644 (file)
index 5e1874e..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Generalization.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Generalization.scl
deleted file mode 100644 (file)
index e550334..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/GenericMutualRecursion.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/GenericMutualRecursion.scl
deleted file mode 100644 (file)
index 24c5858..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-// 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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/GlobalVariables.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/GlobalVariables.scl
deleted file mode 100644 (file)
index c6dc99e..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/GraphPrelude.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/GraphPrelude.scl
deleted file mode 100644 (file)
index ddb2d58..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-\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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/GuardedExpressionBug.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/GuardedExpressionBug.scl
deleted file mode 100644 (file)
index c0d45f1..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-tableIndex :: Double -> Double
-tableIndex x
-    | True = x
-  where
-    f _ = x
-
-main = "Foo"
---
-Foo
\ No newline at end of file
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Guards1.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Guards1.scl
deleted file mode 100644 (file)
index db3b438..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Guards2.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Guards2.scl
deleted file mode 100644 (file)
index 88734c1..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/IdAsOperator.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/IdAsOperator.scl
deleted file mode 100644 (file)
index 576ff86..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/IllegalChar.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/IllegalChar.scl
deleted file mode 100644 (file)
index 371492b..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-a = ¤\r
---\r
-1:5-1:6: Illegal character '¤'.\r
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ImportJavaConstructor.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ImportJavaConstructor.scl
deleted file mode 100644 (file)
index 8c45e43..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-\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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ImportRef.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ImportRef.scl
deleted file mode 100644 (file)
index 9fb6f62..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InconsistentArity.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InconsistentArity.scl
deleted file mode 100644 (file)
index 82a9668..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InconsistentIndentation.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InconsistentIndentation.scl
deleted file mode 100644 (file)
index bd732cf..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/IndentationAndParenthesis.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/IndentationAndParenthesis.scl
deleted file mode 100644 (file)
index 3a8dc3d..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-// 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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Index.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Index.scl
deleted file mode 100644 (file)
index 8a98aec..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Inline1.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Inline1.scl
deleted file mode 100644 (file)
index 118abc4..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-main = id "Foo" \r
-  where\r
-    id x = x\r
---\r
-Foo
\ No newline at end of file
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InlineLoop.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InlineLoop.scl
deleted file mode 100644 (file)
index df8433c..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InstanceHierarchy.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InstanceHierarchy.scl
deleted file mode 100644 (file)
index 1c751f3..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InstanceIsTypoedAsClass.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InstanceIsTypoedAsClass.scl
deleted file mode 100644 (file)
index f3973cc..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InstanceTypeVariables.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InstanceTypeVariables.scl
deleted file mode 100644 (file)
index e4ee646..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InvalidClass1.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InvalidClass1.scl
deleted file mode 100644 (file)
index 796f92c..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-class Foo a where\r
-    infix 3 (+)\r
---\r
-2:5-2:16: Invalid declaration under class definition.    
\ No newline at end of file
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InvalidEncoding.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InvalidEncoding.scl
deleted file mode 100644 (file)
index 513b36f..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-main = "Hello w�rld!"\r
---\r
-1:16-1:17: Character does not conform to UTF-8 encoding.
\ No newline at end of file
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InvalidInstance1.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InvalidInstance1.scl
deleted file mode 100644 (file)
index 35064c6..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InvalidJavaTypeAnnotation.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InvalidJavaTypeAnnotation.scl
deleted file mode 100644 (file)
index 9f7270c..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-@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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InvalidKinds.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InvalidKinds.scl
deleted file mode 100644 (file)
index a18c062..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-\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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InvalidKinds2.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InvalidKinds2.scl
deleted file mode 100644 (file)
index ffdf0a9..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InvalidKinds3.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InvalidKinds3.scl
deleted file mode 100644 (file)
index 445dd7e..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-\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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InvalidLambda.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InvalidLambda.scl
deleted file mode 100644 (file)
index 8897d43..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-
-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.
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InvalidModule.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InvalidModule.scl
deleted file mode 100644 (file)
index 7cf5f95..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InvalidPattern1.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InvalidPattern1.scl
deleted file mode 100644 (file)
index 5ba56cf..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InvalidPattern2.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InvalidPattern2.scl
deleted file mode 100644 (file)
index 2bf9613..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InvalidPattern3.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InvalidPattern3.scl
deleted file mode 100644 (file)
index 460a9bd..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InvalidPattern4.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InvalidPattern4.scl
deleted file mode 100644 (file)
index 11dfd07..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InvalidRuleset1.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InvalidRuleset1.scl
deleted file mode 100644 (file)
index e53520b..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InvalidRuleset2.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InvalidRuleset2.scl
deleted file mode 100644 (file)
index 675ee49..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InvalidTypeClassInstance1.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InvalidTypeClassInstance1.scl
deleted file mode 100644 (file)
index 8860c3b..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-\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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/JavaAccess1.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/JavaAccess1.scl
deleted file mode 100644 (file)
index 0576f43..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/JavaConstructors.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/JavaConstructors.scl
deleted file mode 100644 (file)
index d3ee020..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-\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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/JavaMethods.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/JavaMethods.scl
deleted file mode 100644 (file)
index d51bd4b..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/JavaTypes.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/JavaTypes.scl
deleted file mode 100644 (file)
index 830c5a4..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Kinds1.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Kinds1.scl
deleted file mode 100644 (file)
index 2f2f0d1..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/LP.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/LP.scl
deleted file mode 100644 (file)
index 0c3ddc1..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Lambda.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Lambda.scl
deleted file mode 100644 (file)
index 2316b30..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-\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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Layout1.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Layout1.scl
deleted file mode 100644 (file)
index f68e9a6..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/List.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/List.scl
deleted file mode 100644 (file)
index b746c31..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-\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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ListError1.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ListError1.scl
deleted file mode 100644 (file)
index 0fece99..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ListError2.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ListError2.scl
deleted file mode 100644 (file)
index 135e270..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ListSyntax.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ListSyntax.scl
deleted file mode 100644 (file)
index 1747a6f..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ListSyntax10.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ListSyntax10.scl
deleted file mode 100644 (file)
index 726dba5..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ListSyntax11.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ListSyntax11.scl
deleted file mode 100644 (file)
index 15f0441..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ListSyntax12.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ListSyntax12.scl
deleted file mode 100644 (file)
index 8b18eb3..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-import "Prelude"\r
-              \r
-main = foldl (+) 0 [x | y <- [1..10], x <- [1..y]]\r
---            \r
-220
\ No newline at end of file
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ListSyntax2.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ListSyntax2.scl
deleted file mode 100644 (file)
index e020731..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ListSyntax3.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ListSyntax3.scl
deleted file mode 100644 (file)
index c6cbbca..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-import "Prelude"\r
-\r
-main = [1,2,3,4]\r
---\r
-[1, 2, 3, 4]
\ No newline at end of file
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ListSyntax4.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ListSyntax4.scl
deleted file mode 100644 (file)
index a950635..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ListSyntax5.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ListSyntax5.scl
deleted file mode 100644 (file)
index 6ba8330..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ListSyntax6.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ListSyntax6.scl
deleted file mode 100644 (file)
index a3e08c4..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ListSyntax7.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ListSyntax7.scl
deleted file mode 100644 (file)
index 54cf21c..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ListSyntax8.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ListSyntax8.scl
deleted file mode 100644 (file)
index ac5ce57..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ListSyntax9.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ListSyntax9.scl
deleted file mode 100644 (file)
index 83de255..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ListSyntaxWithoutPrelude.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ListSyntaxWithoutPrelude.scl
deleted file mode 100644 (file)
index 8806f93..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-main = [1 :: Integer,2 :: Integer,3 :: Integer]\r
---\r
-[1, 2, 3]
\ No newline at end of file
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/LocalDefinitions.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/LocalDefinitions.scl
deleted file mode 100644 (file)
index 0e4690a..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-\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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/LocalDefinitions2.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/LocalDefinitions2.scl
deleted file mode 100644 (file)
index f17a8be..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-\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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/LocalDefinitions3.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/LocalDefinitions3.scl
deleted file mode 100644 (file)
index 71a193f..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-\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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/LocalDefinitions4.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/LocalDefinitions4.scl
deleted file mode 100644 (file)
index fe07e47..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-\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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/LocalDefinitions5.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/LocalDefinitions5.scl
deleted file mode 100644 (file)
index 97cf72c..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Macros1.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Macros1.scl
deleted file mode 100644 (file)
index 37b4e05..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-@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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Macros2.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Macros2.scl
deleted file mode 100644 (file)
index d1379cd..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Macros3.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Macros3.scl
deleted file mode 100644 (file)
index ec1571d..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Macros4.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Macros4.scl
deleted file mode 100644 (file)
index 87e41e0..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-@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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Map1.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Map1.scl
deleted file mode 100644 (file)
index 5d9f38c..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/MarketModel.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/MarketModel.scl
deleted file mode 100644 (file)
index da27b04..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/MarketModel2.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/MarketModel2.scl
deleted file mode 100644 (file)
index bcd576b..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Matching.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Matching.scl
deleted file mode 100644 (file)
index f240a1c..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-\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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Matching2.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Matching2.scl
deleted file mode 100644 (file)
index c71b98b..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-\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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Matching3.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Matching3.scl
deleted file mode 100644 (file)
index 904a843..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-\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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Matching3b.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Matching3b.scl
deleted file mode 100644 (file)
index 4864345..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Matching4.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Matching4.scl
deleted file mode 100644 (file)
index 8c8812b..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Matching5.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Matching5.scl
deleted file mode 100644 (file)
index 61723e8..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-main = do \r
-    match () with\r
-        () -> "Hello"\r
---\r
-Hello
\ No newline at end of file
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/MatchingWithMissingParameter.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/MatchingWithMissingParameter.scl
deleted file mode 100644 (file)
index 33a681f..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-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.
-
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/MatchingWithoutTypeAnnotations.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/MatchingWithoutTypeAnnotations.scl
deleted file mode 100644 (file)
index 80d1477..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-\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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/MaximumBy.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/MaximumBy.scl
deleted file mode 100644 (file)
index c70c9da..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Maybe1.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Maybe1.scl
deleted file mode 100644 (file)
index 98a7d71..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-a = Nothing\r
-main = match a with\r
-    Nothing -> "Correct"\r
-    Just x -> "Incorrect"\r
---\r
-Correct
\ No newline at end of file
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Maybe2.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Maybe2.scl
deleted file mode 100644 (file)
index 0bc50fb..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-a = Just True\r
-main = match a with\r
-    Nothing -> False\r
-    Just x -> x\r
---\r
-true
\ No newline at end of file
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Maybe3.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Maybe3.scl
deleted file mode 100644 (file)
index 8a0f120..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-a = Just "ABC"\r
-main = match a with\r
-    Nothing -> "Incorrect"\r
-    Just x -> x\r
---\r
-ABC
\ No newline at end of file
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Maybe4.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Maybe4.scl
deleted file mode 100644 (file)
index 53e3ed3..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/MissingEffect.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/MissingEffect.scl
deleted file mode 100644 (file)
index 9a5ea98..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/MissingMethod.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/MissingMethod.scl
deleted file mode 100644 (file)
index d5b1b27..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/MissingTypeParameter.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/MissingTypeParameter.scl
deleted file mode 100644 (file)
index fc40ab9..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ModuleInitialization.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ModuleInitialization.scl
deleted file mode 100644 (file)
index bd3dfa1..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/MonadBug1.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/MonadBug1.scl
deleted file mode 100644 (file)
index 44ddf00..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/MonadSyntax1.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/MonadSyntax1.scl
deleted file mode 100644 (file)
index 94774a4..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/MonadSyntax2.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/MonadSyntax2.scl
deleted file mode 100644 (file)
index 6244a61..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Monads1.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Monads1.scl
deleted file mode 100644 (file)
index 90115d3..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/NoDefinitionErrorMessage.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/NoDefinitionErrorMessage.scl
deleted file mode 100644 (file)
index 8597a78..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-// 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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/NoInstance.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/NoInstance.scl
deleted file mode 100644 (file)
index 4bc5cab..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-\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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/NoInstance2.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/NoInstance2.scl
deleted file mode 100644 (file)
index 9490a82..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-\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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/NonassociativeOperator.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/NonassociativeOperator.scl
deleted file mode 100644 (file)
index f2b473a..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/NonexistentTypeClassInAnnotation.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/NonexistentTypeClassInAnnotation.scl
deleted file mode 100644 (file)
index 4030639..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/NonexistingEffect.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/NonexistingEffect.scl
deleted file mode 100644 (file)
index 8ed51f9..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/OneLineMatch.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/OneLineMatch.scl
deleted file mode 100644 (file)
index 3f16b07..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-// 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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/OpenString1.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/OpenString1.scl
deleted file mode 100644 (file)
index e8a7c4c..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-"asd \r
---\r
-1:1-1:6: Unclosed string literal.
\ No newline at end of file
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/OpenString2.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/OpenString2.scl
deleted file mode 100644 (file)
index 31953cc..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-"asd \r
-\r
-\r
-asd\r
---\r
-1:1-1:6: Unclosed string literal.
\ No newline at end of file
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/OverloadedArithmetic1.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/OverloadedArithmetic1.scl
deleted file mode 100644 (file)
index de083e8..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/OverloadedArithmetic2.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/OverloadedArithmetic2.scl
deleted file mode 100644 (file)
index 1619f58..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/OverloadedArithmetic3.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/OverloadedArithmetic3.scl
deleted file mode 100644 (file)
index 230e486..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/OverloadedLiterals2.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/OverloadedLiterals2.scl
deleted file mode 100644 (file)
index c167097..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Overloading1.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Overloading1.scl
deleted file mode 100644 (file)
index dfb6079..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-// 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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Overloading2.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Overloading2.scl
deleted file mode 100644 (file)
index e7a28de..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-// 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
-
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Overloading3.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Overloading3.scl
deleted file mode 100644 (file)
index 9385ce7..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-// 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
-
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Parsing.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Parsing.scl
deleted file mode 100644 (file)
index 0ca342a..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/PatternError.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/PatternError.scl
deleted file mode 100644 (file)
index ce417af..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/PolymorphicRecursion.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/PolymorphicRecursion.scl
deleted file mode 100644 (file)
index ed84193..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-// 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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/PolymorphicRecursion2.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/PolymorphicRecursion2.scl
deleted file mode 100644 (file)
index 44738e0..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-\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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Polynomials.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Polynomials.scl
deleted file mode 100644 (file)
index 5e35b94..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/PrecedenceOfNonoperators.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/PrecedenceOfNonoperators.scl
deleted file mode 100644 (file)
index 3321e89..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Primes.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Primes.scl
deleted file mode 100644 (file)
index 830186b..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Proc1.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Proc1.scl
deleted file mode 100644 (file)
index b91eed3..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Proc2.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Proc2.scl
deleted file mode 100644 (file)
index bd8021b..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Proc3.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Proc3.scl
deleted file mode 100644 (file)
index 4a17fe4..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Pythagoras.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Pythagoras.scl
deleted file mode 100644 (file)
index 95a5b9b..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Random1.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Random1.scl
deleted file mode 100644 (file)
index 66922ea..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/RangeSyntax.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/RangeSyntax.scl
deleted file mode 100644 (file)
index 6622552..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-import "Prelude"\r
-\r
-main = [5..9]\r
---\r
-[5, 6, 7, 8, 9]
\ No newline at end of file
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Record1.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Record1.scl
deleted file mode 100644 (file)
index fcfbf6a..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/RecordShorthand.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/RecordShorthand.scl
deleted file mode 100644 (file)
index d3af73e..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/RecursiveContext.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/RecursiveContext.scl
deleted file mode 100644 (file)
index 7412862..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/RecursiveValues.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/RecursiveValues.scl
deleted file mode 100644 (file)
index 5548520..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-a = b\r
-b = a\r
-\r
-main = a\r
---\r
-???: Variables defined recursively must all be functions.
\ No newline at end of file
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/RecursiveValues2.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/RecursiveValues2.scl
deleted file mode 100644 (file)
index 7291bb9..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/RecursiveValues3.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/RecursiveValues3.scl
deleted file mode 100644 (file)
index 020a967..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/RecursiveValues4.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/RecursiveValues4.scl
deleted file mode 100644 (file)
index 0315be3..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-(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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/RedBlackTrees.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/RedBlackTrees.scl
deleted file mode 100644 (file)
index 6f47bd0..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Relations1.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Relations1.scl
deleted file mode 100644 (file)
index b15c1b8..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Relations2.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Relations2.scl
deleted file mode 100644 (file)
index 825685e..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-import "StandardLibrary"
-
-MyExecute ?procedure :-
-    @enforce
-    Execute (?procedure "Foo")
-
-main = do
-    v = ref ""
-    enforce MyExecute (v :=)
-    getRef v 
---
-Foo
\ No newline at end of file
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/RepeatedVariableInPattern.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/RepeatedVariableInPattern.scl
deleted file mode 100644 (file)
index 8e5cf08..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/SSATypingBug.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/SSATypingBug.scl
deleted file mode 100644 (file)
index 15ff012..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Scanl.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Scanl.scl
deleted file mode 100644 (file)
index 67821dd..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Search.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Search.scl
deleted file mode 100644 (file)
index 352e92c..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Sections.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Sections.scl
deleted file mode 100644 (file)
index 2d7e576..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Select1.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Select1.scl
deleted file mode 100644 (file)
index f8d0359..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Select2.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Select2.scl
deleted file mode 100644 (file)
index a492823..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-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]
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Select3.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Select3.scl
deleted file mode 100644 (file)
index a3e4f44..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-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]
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Select4.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Select4.scl
deleted file mode 100644 (file)
index 3199e95..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-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]
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Select5.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Select5.scl
deleted file mode 100644 (file)
index 1817247..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Select6.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Select6.scl
deleted file mode 100644 (file)
index 84e4df3..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-import "StandardLibrary"
-
-main = select ?x where
-    (?x,?y) = (1,2)
---
-[1]
\ No newline at end of file
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Select7.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Select7.scl
deleted file mode 100644 (file)
index b0be01a..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-import "StandardLibrary"
-
-main = select ?x where
-    (?x, 3) <- [(1,2),(2,3),(3,4)]
---
-[2]
\ No newline at end of file
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Select8.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Select8.scl
deleted file mode 100644 (file)
index 7877044..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Select9.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Select9.scl
deleted file mode 100644 (file)
index 5680679..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/SelfReferringContextInTypeClass.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/SelfReferringContextInTypeClass.scl
deleted file mode 100644 (file)
index d2f1bd7..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Serialization.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Serialization.scl
deleted file mode 100644 (file)
index e0d44e3..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Serialization2.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Serialization2.scl
deleted file mode 100644 (file)
index 8384527..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Serialization3.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Serialization3.scl
deleted file mode 100644 (file)
index d883dfe..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Set1.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Set1.scl
deleted file mode 100644 (file)
index b868ecf..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/SharedTypeVariable.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/SharedTypeVariable.scl
deleted file mode 100644 (file)
index 19fd565..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-// 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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ShortcutFusion.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ShortcutFusion.scl
deleted file mode 100644 (file)
index 6423ecb..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Show1.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Show1.scl
deleted file mode 100644 (file)
index 649f3cb..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Signals.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Signals.scl
deleted file mode 100644 (file)
index 726a3f5..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/SinConst1.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/SinConst1.scl
deleted file mode 100644 (file)
index 66621b1..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-import "Prelude"\r
-\r
-main = (sin + const 1) 0\r
---\r
-1.0
\ No newline at end of file
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Sort.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Sort.scl
deleted file mode 100644 (file)
index 7efdf89..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Sort2.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Sort2.scl
deleted file mode 100644 (file)
index 8518264..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/SpecConstr1.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/SpecConstr1.scl
deleted file mode 100644 (file)
index 4ff7d47..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/StackTrace.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/StackTrace.scl
deleted file mode 100644 (file)
index fe30fa3..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-main = fail "badly"
---
-???
\ No newline at end of file
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/StreamFusion.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/StreamFusion.scl
deleted file mode 100644 (file)
index 6d1864a..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/StringEscape.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/StringEscape.scl
deleted file mode 100644 (file)
index 51a75d3..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/StringInterpolation1.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/StringInterpolation1.scl
deleted file mode 100644 (file)
index eabad78..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/StringInterpolation2.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/StringInterpolation2.scl
deleted file mode 100644 (file)
index 9d21943..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/StringMatching1.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/StringMatching1.scl
deleted file mode 100644 (file)
index 5865926..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-main :: Integer\r
-main = match "Bar" with\r
-  "Foo" -> 1\r
-  "Bar" -> 2\r
-  _ -> 3\r
---\r
-2
\ No newline at end of file
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/SumOfInverses2.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/SumOfInverses2.scl
deleted file mode 100644 (file)
index d3cacba..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Timing.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Timing.scl
deleted file mode 100644 (file)
index deb6d50..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/TooManyParametersToSin.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/TooManyParametersToSin.scl
deleted file mode 100644 (file)
index bfaf3db..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Transformation1.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Transformation1.scl
deleted file mode 100644 (file)
index 144b031..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Transformation2.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Transformation2.scl
deleted file mode 100644 (file)
index dbb1609..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-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
---
-()
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Transformation3.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Transformation3.scl
deleted file mode 100644 (file)
index f9b995c..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-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
---
-()
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Transformation4.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Transformation4.scl
deleted file mode 100644 (file)
index 5a889e1..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-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
---
-()
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Transformation5.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Transformation5.scl
deleted file mode 100644 (file)
index e041430..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-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
---
-()
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Transformation6.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Transformation6.scl
deleted file mode 100644 (file)
index 74aed46..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Transformation7.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Transformation7.scl
deleted file mode 100644 (file)
index cce48f6..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-import "StandardLibrary"
-
-Foo ?x :- 
-    @enforce
-    Execute (iterList printString [?x :: String])
-
-    
-rule DoIt where
-    @to
-    Foo "Hello world!"
-
-main = transformation OneShotForward where
---
-()
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/TransformationOrder.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/TransformationOrder.scl
deleted file mode 100644 (file)
index 36c08c7..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-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
---
-()
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Tuples.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Tuples.scl
deleted file mode 100644 (file)
index 5f70e4b..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Tuples2.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Tuples2.scl
deleted file mode 100644 (file)
index 75b4785..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-// This is just a restricted version of Tuples test\r
-id0 () = ()\r
-\r
-main = id0 ()\r
---\r
-()
\ No newline at end of file
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/TypeAlias1.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/TypeAlias1.scl
deleted file mode 100644 (file)
index 3aad9bf..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-\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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/TypeAlias2.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/TypeAlias2.scl
deleted file mode 100644 (file)
index 6192515..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/TypeAlias3.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/TypeAlias3.scl
deleted file mode 100644 (file)
index b25a8ab..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/TypeAliasRefsToTypeAlias.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/TypeAliasRefsToTypeAlias.scl
deleted file mode 100644 (file)
index 7ebb606..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/TypeAnnotation1.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/TypeAnnotation1.scl
deleted file mode 100644 (file)
index 5ba565f..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/TypeAnnotation2.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/TypeAnnotation2.scl
deleted file mode 100644 (file)
index ab855f8..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/TypeClass.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/TypeClass.scl
deleted file mode 100644 (file)
index 540d44e..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-\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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/TypeClass2.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/TypeClass2.scl
deleted file mode 100644 (file)
index 5bd0935..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/TypeClassBug1.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/TypeClassBug1.scl
deleted file mode 100644 (file)
index 2ea51be..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/TypeClassBug2.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/TypeClassBug2.scl
deleted file mode 100644 (file)
index a341ba6..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/TypeInferenceBug2.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/TypeInferenceBug2.scl
deleted file mode 100644 (file)
index 4fa08a5..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/TypeOf1.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/TypeOf1.scl
deleted file mode 100644 (file)
index 933a29b..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-import "Prelude"\r
-\r
-main = typeOf (\(a,b) -> a+b :: Double)\r
---\r
-(Double, Double) -> Double
\ No newline at end of file
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/TypingBug1.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/TypingBug1.scl
deleted file mode 100644 (file)
index 3e69ebf..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-id x = x\r
-main = id id (5 :: Integer)\r
---\r
-5
\ No newline at end of file
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/TypingError1.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/TypingError1.scl
deleted file mode 100644 (file)
index 9f39243..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/TypingError2.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/TypingError2.scl
deleted file mode 100644 (file)
index 7632ffc..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/UnaryMinus.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/UnaryMinus.scl
deleted file mode 100644 (file)
index ff0e512..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-import "Prelude"\r
-\r
-main = -5\r
---\r
--5
\ No newline at end of file
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/UndefinedValue.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/UndefinedValue.scl
deleted file mode 100644 (file)
index 02de8b6..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-\r
-foo :: Integer\r
-// foo = 0\r
-\r
---\r
-2:1-2:15: foo is not defined.
\ No newline at end of file
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/UnexpectedToken.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/UnexpectedToken.scl
deleted file mode 100644 (file)
index 270d575..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Unification1.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Unification1.scl
deleted file mode 100644 (file)
index a174362..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/UnknownAnnotation.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/UnknownAnnotation.scl
deleted file mode 100644 (file)
index c1b5ef8..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-\r
-@sdlfkmsdlfkm\r
-main = "Not to be executed"\r
---\r
-2:1-2:14: Unknown annotation.
\ No newline at end of file
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/UnresolvedClass.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/UnresolvedClass.scl
deleted file mode 100644 (file)
index 0e1765c..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-\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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/UnresolvedTypeInAnnotation.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/UnresolvedTypeInAnnotation.scl
deleted file mode 100644 (file)
index 18e0751..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-main :: List Integer\r
-main = 13\r
---\r
-1:9-1:13: Didn't find type constructor List.
\ No newline at end of file
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/UnresolvedTypeInInstance.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/UnresolvedTypeInInstance.scl
deleted file mode 100644 (file)
index 1b5400c..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/UnresolvedVariable.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/UnresolvedVariable.scl
deleted file mode 100644 (file)
index ad28907..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-a = b\r
-\r
---\r
-1:5-1:6: Couldn't resolve variable b.
\ No newline at end of file
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/UnresolvedVariable2.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/UnresolvedVariable2.scl
deleted file mode 100644 (file)
index 32438cd..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-\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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ValueAsOperator.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ValueAsOperator.scl
deleted file mode 100644 (file)
index 3723537..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-\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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ValueConversion.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/ValueConversion.scl
deleted file mode 100644 (file)
index 3afda1b..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-import "Prelude"\r
-import "Vector"\r
-\r
-main = fromDynamic (toDynamic (vector [3 :: Double])) :: [Double]\r
---\r
-[3.0]
\ No newline at end of file
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Vector1.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Vector1.scl
deleted file mode 100644 (file)
index 33b6c86..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Vector2.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Vector2.scl
deleted file mode 100644 (file)
index 43c0c53..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Void1.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Void1.scl
deleted file mode 100644 (file)
index 40a710f..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Void2.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Void2.scl
deleted file mode 100644 (file)
index f953aaf..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Void3.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Void3.scl
deleted file mode 100644 (file)
index 0530c8a..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/While.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/While.scl
deleted file mode 100644 (file)
index 3e45043..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-\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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/While2.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/While2.scl
deleted file mode 100644 (file)
index 6567c22..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/While3.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/While3.scl
deleted file mode 100644 (file)
index 0520769..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/WrongDefaultMethod.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/WrongDefaultMethod.scl
deleted file mode 100644 (file)
index d94046b..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-\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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/WrongInstanceMethod.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/WrongInstanceMethod.scl
deleted file mode 100644 (file)
index 2cdc4e8..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-\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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scripts/Arithmetic.sts b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scripts/Arithmetic.sts
deleted file mode 100644 (file)
index e8f7dce..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-> 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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scripts/Functions.sts b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scripts/Functions.sts
deleted file mode 100644 (file)
index 76348b8..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-> 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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scripts/Functions2.sts b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scripts/Functions2.sts
deleted file mode 100644 (file)
index 9879931..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-> f x = x + 1
-> f 3
-4
-> f 4.5
-5.5
\ No newline at end of file
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scripts/Lists.sts b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scripts/Lists.sts
deleted file mode 100644 (file)
index 024db24..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-> [1,2,3]
-[1, 2, 3]
-
-> [5..9]
-[5, 6, 7, 8, 9]
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/unit/TestConstraintSolver.java b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/unit/TestConstraintSolver.java
deleted file mode 100644 (file)
index a6aad45..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-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();
-    }
-    
-}
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/unit/TestNamespaceFilter.java b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/unit/TestNamespaceFilter.java
deleted file mode 100644 (file)
index fa3bd9f..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/unit/TestSubSolver.java b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/unit/TestSubSolver.java
deleted file mode 100644 (file)
index 87b9eeb..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-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
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/unit/TestTypeParser.java b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/unit/TestTypeParser.java
deleted file mode 100644 (file)
index 5ce3690..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-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
index fb034cd57886311de41b4aa8253689ce957c0105..63c51a56bf1637a3d56a90521aa74ed3c5b50522 100644 (file)
@@ -52,8 +52,6 @@ importJava "com.fasterxml.jackson.core.JsonToken" where
     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
@@ -301,9 +299,7 @@ data Json =
 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
@@ -366,7 +362,7 @@ makeTypeEqual :: a -> a -> ()
 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
index 05fef9c99812a9e2832ab445f2e1471e575d3eb6..b49f6a6c1771ca696541f20a3ebc00844d7d6092 100644 (file)
@@ -51,12 +51,6 @@ importJava "org.jdom2.Element" where
     \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
index 74bc4220436dbe2d7a991012d9385a8eab08e136..ae092cfa8d62aafe6cd203d29e20e9a7f9885903 100644 (file)
@@ -22,21 +22,9 @@ importJava "org.simantics.db.Resource" where
 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
index bcfd43a6400bbc06b0112d82846102c3dca25d22..473f4431a0b9419493346685681461e434ba24ea 100644 (file)
@@ -2,32 +2,6 @@ include "Simantics/Model"
 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
index 3735620b870b46f95c50d353e65154e45a375891..a1033a4a4b710589241eda12510c2403fd6ea1a6 100755 (executable)
@@ -6,13 +6,13 @@ Bundle-Version: 1.0.4.qualifier
 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
index 52b72c35ddd349f8f90bb9098202eb23bc5196ff..6825bb4482d119495b3d8fc7edea4dd4dde6e7e3 100755 (executable)
@@ -3,7 +3,7 @@ output.. = bin/
 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
index 975dd57fd843548bc8433c5e19d80feca1bdc9d9..a4dce2101eff9d427f23cbf08e2b9d23a0aabe05 100644 (file)
@@ -1,6 +1,5 @@
 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
index 7274b0bf2dde4515d4667f6138a2a3f24be814fb..32ac1e0a691afcc357e632057561211436dd83f6 100755 (executable)
@@ -5,6 +5,7 @@ Bundle-SymbolicName: org.simantics.scl.runtime;singleton:=true
 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,
index 17a6ec65fcd7237c2db9a7542ef65afd753bf2ac..a19f7eb5b0f0db2a9972777602d748e2b9174c58 100644 (file)
@@ -77,7 +77,7 @@ randomIdentifierCharacter = let p = randomN 100
 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))
@@ -86,7 +86,7 @@ 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 ()
index be42bc93185c80d383b957543cfbfb33c6e79f72..290d7a667383445a5c9cf1c860b2ea9bfd6b4e31 100644 (file)
@@ -32,7 +32,7 @@ importJava "java.util.ArrayList" where
     @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
index af9093701d51186c4059b30685b42024c41e5fc9..cdc0ad102d5b65e353791922104a823e4c275f67 100644 (file)
@@ -42,9 +42,6 @@ importJava "java.math.BigInteger" where
     @JavaName intValue
     toIntegerBigInteger :: BigInteger -> Integer
 
-instance Eq BigInteger where
-    (==) = equalsBigInteger
-
 instance Show BigInteger where
     show = showBigInteger
 
@@ -53,9 +50,6 @@ instance Ord BigInteger where
     min = minBigInteger
     max = maxBigInteger
 
-instance Hashable BigInteger where
-    hashP v x = hashBigInteger v + 31*x
-
 instance Additive BigInteger where
     zero = zeroBigInteger
     (+) = addBigInteger
index 63df233239d7d82ab00351e14d8ce80dc24cba0d..418e8f03b81c6c1f387b5d4b57845eff3a80cb0b 100644 (file)
@@ -12,7 +12,7 @@ class Collection a where
     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]
@@ -37,9 +37,9 @@ class (Collection a) => Sequence a where
     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]
index f8137662182f42b751b0654bd5175f540f1cd87e..87afb8e53b5058aed3a7de745bedab468a08e090 100644 (file)
@@ -56,17 +56,11 @@ importJava "org.simantics.databoard.type.Datatype" where
     "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
@@ -81,10 +75,6 @@ importJava "org.simantics.databoard.binding.Binding" where
     @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
@@ -105,13 +95,6 @@ importJava "org.simantics.databoard.binding.Binding" where
     @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
index 21658862db66f34262c1852603872ff5f25291ef..c2307014a51ceec23d4c4e7d059667d0a414a015 100644 (file)
@@ -39,10 +39,6 @@ binding :: Serializable a => Binding a
 ***********************************************************/
 
 importJava "java.util.Arrays" where
-    @private    
-    @JavaName equals
-    equalsDoubleArray :: DoubleArray -> DoubleArray -> Boolean
-    
     @private
     @JavaName toString
     showDoubleArray :: DoubleArray -> String
@@ -56,8 +52,6 @@ importJava "java.util.List" where
     @JavaName toArray
     listToArray :: [a] -> Array a
 
-instance Eq DoubleArray where
-    (==) = equalsDoubleArray
 instance Show DoubleArray where
     show = showDoubleArray
 
@@ -77,7 +71,7 @@ infixr 8  (^)
 infixl 7  (*), (/), div, mod
 infixl 6  (+), (-)
 infixl 5  (\\), (<<), (<+)
-infix  4  (==), (!=), (<), (<=), (>=), (>)
+infix  4  (!=), (<), (<=), (>=), (>)
 infixr 3  (&&), (&<&)
 infixr 2  (||), orElse, morelse
 infixr 1  (>>=), (>>), (:=)
@@ -134,23 +128,15 @@ swap (x,y) = (y,x)
 
 /// 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. 
@@ -220,17 +206,6 @@ minimumBy f l = snd $ foldl1 minF $ map (\x -> (f x, x)) l
   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
@@ -566,10 +541,6 @@ importJava "java.lang.Byte" where
     @JavaName parseByte
     readByte :: String -> Byte
 
-instance Eq Byte where
-    (==) = Java.bcmpeq
-    (!=) = Java.bcmpne
-
 instance Ord Byte where
     (<) = Java.bcmplt
     (<=) = Java.bcmple
@@ -603,10 +574,6 @@ importJava "java.lang.Short" where
     @JavaName parseShort
     readShort :: String -> Short
 
-instance Eq Short where
-    (==) = Java.scmpeq
-    (!=) = Java.scmpne
-
 instance Ord Short where
     (<) = Java.scmplt
     (<=) = Java.scmple
@@ -641,18 +608,11 @@ importJava "java.lang.Integer" where
     @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
@@ -690,18 +650,11 @@ importJava "java.lang.Long" where
     @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
@@ -747,10 +700,6 @@ importJava "java.lang.Float" where
     "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
@@ -758,9 +707,6 @@ instance Ord Float where
     (>) = 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
@@ -828,19 +774,12 @@ importJava "java.lang.Double" where
     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
@@ -899,10 +838,6 @@ importJava "java.lang.Character" where
     "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
@@ -1213,10 +1148,6 @@ guard patterns:
 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
@@ -1269,10 +1200,8 @@ not a = if a then False else True
 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
@@ -1346,10 +1275,8 @@ is used to hold an error value and the `Right` constructor is used to hold a cor
 """
 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
@@ -1384,12 +1311,6 @@ importJava "java.lang.String" where
     @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
 
@@ -1456,12 +1377,6 @@ importJava "java.lang.String" where
     @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
     
@@ -1490,15 +1405,9 @@ split pattern text = arrayToList $ splitString_ text pattern
 
 /// Tuple0 ///
 
-instance Eq () where
-    () == () = True
-
 instance Ord () where
     compare () () = 0
 
-instance Hashable () where
-    hashP () x = x
-
 instance Additive () where
     zero = ()
     () + () = ()
@@ -1518,15 +1427,9 @@ fst (x,y) = x
 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)
@@ -1539,15 +1442,9 @@ instance (Show a, Show b) => Show (a, b) where
 
 /// 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)
@@ -1560,16 +1457,10 @@ instance (Show a, Show b, Show c) => Show (a, b, c) where
 
 /// 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)
@@ -1582,17 +1473,9 @@ instance (Show a, Show b, Show c, Show d) => Show (a, b, c, d) where
     
 /// 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)
@@ -1603,13 +1486,6 @@ instance Functor ((,,,,) a b c d) where
 
 /// 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
@@ -1621,14 +1497,6 @@ instance (Ord a) => Ord [a] 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
 
@@ -1995,7 +1863,7 @@ importJava "org.simantics.scl.runtime.Lists" where
     //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
@@ -2005,7 +1873,7 @@ elem el l = loop 0
            | 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
@@ -2013,7 +1881,7 @@ elemMaybe el m = match m with
 """
 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
@@ -2044,7 +1912,7 @@ tail l = if len < 2 then emptyList else subList l 1 len
     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 
@@ -2118,37 +1986,37 @@ sortBy f l = sortWith (\x y -> compare (f x) (f y)) l
 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 ///
index 6622598c744e6c48eb9126637ee93ab0dced96e3..5233955feeaf60fd47efa441663a0be6451fe13e 100644 (file)
@@ -2,9 +2,7 @@ import "Prelude"
 
 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
index 51ec078b62126f48a646842d6a416a5106462db4..8583875e0ce80ff2e4f7d28ea84575aa9eede96e 100644 (file)
@@ -165,7 +165,7 @@ mapFirstVector :: (a -> <e> Maybe b) -> Vector a -> <e> Maybe b
 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
diff --git a/bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/chr/CHRHashIndex.java b/bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/chr/CHRHashIndex.java
new file mode 100644 (file)
index 0000000..d8102b7
--- /dev/null
@@ -0,0 +1,1616 @@
+/*\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
diff --git a/bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/chr/CHRHashOverflowException.java b/bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/chr/CHRHashOverflowException.java
new file mode 100644 (file)
index 0000000..3975d28
--- /dev/null
@@ -0,0 +1,28 @@
+/*\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
diff --git a/bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/chr/Fact.java b/bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/chr/Fact.java
new file mode 100644 (file)
index 0000000..f61d307
--- /dev/null
@@ -0,0 +1,11 @@
+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
diff --git a/bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/chr/FactActivationQueue.java b/bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/chr/FactActivationQueue.java
new file mode 100644 (file)
index 0000000..05b410d
--- /dev/null
@@ -0,0 +1,120 @@
+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
diff --git a/bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/chr/PriorityContainer.java b/bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/chr/PriorityContainer.java
new file mode 100644 (file)
index 0000000..a19658e
--- /dev/null
@@ -0,0 +1,42 @@
+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
diff --git a/bundles/org.simantics.scl.runtime/tests/org/simantics/scl/runtime/tests/TestCHRHashIndex.java b/bundles/org.simantics.scl.runtime/tests/org/simantics/scl/runtime/tests/TestCHRHashIndex.java
new file mode 100644 (file)
index 0000000..87c7194
--- /dev/null
@@ -0,0 +1,163 @@
+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
diff --git a/bundles/org.simantics.scl.runtime/tests/org/simantics/scl/runtime/tests/TestFactActivationQueue.java b/bundles/org.simantics.scl.runtime/tests/org/simantics/scl/runtime/tests/TestFactActivationQueue.java
new file mode 100644 (file)
index 0000000..aecd8de
--- /dev/null
@@ -0,0 +1,58 @@
+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
index da620c7926e7bdc84e29e32430e4410c1dbb687f..931ae92cdc710f1b675f7eb343a21389103142b8 100755 (executable)
@@ -12,7 +12,7 @@ Require-Bundle: org.eclipse.ui.editors;bundle-version="3.6.0",
  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,
index 981d16b18c66cbee35fce4b9be3c116e6aa6125c..4cf521e6543133c984fa0c8912cf82a0c5a36108 100644 (file)
@@ -1,43 +1,27 @@
 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
@@ -86,83 +70,13 @@ public class SCLSourceViewerConfigurationNew extends SourceViewerConfiguration {
        }\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
index 2e2c60eef85cec02f1fa66c69a747b9ceb2de3a6..1aebc06e817b52364cfe2794140a3e349ac37cd2 100644 (file)
@@ -2,7 +2,6 @@ package org.simantics.scl.ui.editor.completion;
 \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
@@ -21,7 +20,6 @@ import org.simantics.scl.compiler.internal.parsing.parser.SCLParserImpl;
 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
@@ -47,7 +45,7 @@ public class SCLTextEditorEnvironment {
         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
diff --git a/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/DebugPartionTokenScanner.java b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/DebugPartionTokenScanner.java
new file mode 100644 (file)
index 0000000..2a69dc8
--- /dev/null
@@ -0,0 +1,48 @@
+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
index b92818aa5e33f3cc0f8cf256b353e3cd72afd95c..f1bb9b54f2a41904b3983c754e9726cac3d54d41 100644 (file)
@@ -8,6 +8,8 @@ import org.eclipse.core.runtime.Status;
 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
@@ -52,6 +54,9 @@ public class SCLModuleEditor2DocumentProvider extends AbstractDocumentProvider {
                     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
diff --git a/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/SCLPartitionScanner.java b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/SCLPartitionScanner.java
new file mode 100644 (file)
index 0000000..98e9a46
--- /dev/null
@@ -0,0 +1,33 @@
+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
diff --git a/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/SCLPresentationReconciler.java b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/SCLPresentationReconciler.java
new file mode 100644 (file)
index 0000000..e45252e
--- /dev/null
@@ -0,0 +1,106 @@
+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
diff --git a/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/SingleTokenScanner.java b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/SingleTokenScanner.java
new file mode 100644 (file)
index 0000000..4a7c396
--- /dev/null
@@ -0,0 +1,22 @@
+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
diff --git a/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/StringTokenScanner.java b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/StringTokenScanner.java
new file mode 100644 (file)
index 0000000..ec8237a
--- /dev/null
@@ -0,0 +1,22 @@
+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
index 8be82db9a3f8857a18d138fbbe042ecafa09db9f..dba5c0cb7c309990a95faba7776c709f1c610003 100755 (executable)
@@ -38,6 +38,7 @@ public class SCLInfo {
         "select",\r
         "enforce",\r
         "transformation",\r
+        "when"\r
     };\r
     \r
 }\r
index 5caaeecbd97e44f677a82c9dec4a9d1a7676f7e7..710abbf56c92c3e98a40ff18a4973e7af8ec9cd6 100644 (file)
@@ -6,7 +6,10 @@ Bundle-Version: 1.0.0.qualifier
 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"
diff --git a/tests/org.simantics.scl.compiler.tests/logback.xml b/tests/org.simantics.scl.compiler.tests/logback.xml
new file mode 100644 (file)
index 0000000..dfa60de
--- /dev/null
@@ -0,0 +1,18 @@
+<?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
index f9533efeee64222052a7e27ecc8a6c318d66a8f3..7a4f8cda2ac62e860b7e5f056bfc0b890c9f4c27 100644 (file)
@@ -1,6 +1,5 @@
 package org.simantics.scl.compiler.tests;
 
-import org.junit.Ignore;
 import org.junit.Test;
 
 public class ActiveTests extends TestBase {
@@ -20,5 +19,4 @@ public class ActiveTests extends TestBase {
   */  
     
     //@Test public void CityoptSetup() { test(); }
-    @Test public void EmptyLet() { test(); }
 }
similarity index 51%
rename from bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/TestActive.java
rename to tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/AllTestsForCoverage.java
index 8a22ba9dbfafed1e6c547cadbc2ce6d493042fb3..1e640c64d8523753f77e2f74f3f5963b4b4b4df1 100644 (file)
@@ -1,12 +1,16 @@
-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
index 44d05ac08c0d12fd067bf567125747776f72e56b..527744c00fbd8fbbac58a0b60896d49b1e311975 100644 (file)
@@ -1,14 +1,7 @@
 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 {
 
@@ -28,6 +21,7 @@ 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(); }
@@ -47,6 +41,7 @@ public class ModuleRegressionTests extends TestBase {
     @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[]{""});
@@ -60,14 +55,12 @@ public class ModuleRegressionTests extends TestBase {
     @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(); }
@@ -83,7 +76,8 @@ public class ModuleRegressionTests extends TestBase {
     @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(); }
@@ -114,10 +108,11 @@ public class ModuleRegressionTests extends TestBase {
     @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(); }
@@ -139,8 +134,8 @@ public class ModuleRegressionTests extends TestBase {
     @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(); }
@@ -149,35 +144,34 @@ public class ModuleRegressionTests extends TestBase {
     @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(); }
@@ -193,9 +187,8 @@ public class ModuleRegressionTests extends TestBase {
     @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(); }
@@ -211,16 +204,20 @@ public class ModuleRegressionTests extends TestBase {
     @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(); }
@@ -239,8 +236,8 @@ public class ModuleRegressionTests extends TestBase {
     @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(); }
@@ -252,23 +249,25 @@ public class ModuleRegressionTests extends TestBase {
     @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");
@@ -289,6 +288,6 @@ public class ModuleRegressionTests extends TestBase {
             System.out.println(bp.getCodeSize());
             printCoverageTree(bp.getChildren(), ind+1);
         }
-    }
+    }*/
 
 }
index 05ffd759fe19751e977668613d964e150644d94d..2dfaafee3660907b6b493e86e9ded837379ce17f 100644 (file)
@@ -16,9 +16,7 @@ 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 {
index 283e0e14e4b76c368efe479afc13bd27de12c836..edd7df6450a138349f88f43220a1498835fd2521 100644 (file)
@@ -1,5 +1,6 @@
 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
@@ -13,8 +14,6 @@ import org.simantics.scl.compiler.source.repository.MapModuleSourceRepository;
 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
index b86f097b84bf0445542619cfb30eef76ecce838e..4a9bffd093c0b0737804008a4f7f148e63e3c058 100644 (file)
@@ -4,8 +4,6 @@ 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;
 
index e143c6ab92afcf1a3eadb12d310f092c2b8b556c..2e887ca1a420b04a0ed1dda7cc702f64bdd9b728 100644 (file)
@@ -2,6 +2,7 @@ package org.simantics.scl.compiler.tests;
 
 import java.util.Arrays;
 
+import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.simantics.scl.compiler.elaboration.expressions.EVariable;
@@ -25,8 +26,6 @@ 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;
similarity index 92%
rename from bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/markdown/RunMarkdownTests.java
rename to tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/markdown/MarkdownTests.java
index 9971a020b879cd7d2e848967ca5e7bc6ee3bdac8..5c4e120bf5931be43c865d42465826040973cd5b 100644 (file)
-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
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/markdown/RunMarkdownTests.java b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/markdown/RunMarkdownTests.java
deleted file mode 100644 (file)
index 9971a02..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-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;
-    }
-    
-}
index bdaed436dd9e20ae200ea1e49be4b10c679c730f..92faa7302258e797e2519f906d035d534f58567f 100644 (file)
@@ -1,8 +1,8 @@
 ---
 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/)'
 ...
 
@@ -13,12 +13,90 @@ 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?
 
@@ -258,9 +336,14 @@ 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.
+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
@@ -269,7 +352,6 @@ by spaces with a tab stop of 4 characters.
 </code></pre>
 ````````````````````````````````
 
-
 ```````````````````````````````` example
   →foo→baz→→bim
 .
@@ -277,7 +359,6 @@ by spaces with a tab stop of 4 characters.
 </code></pre>
 ````````````````````````````````
 
-
 ```````````````````````````````` example
     a→a
     ὐ→a
@@ -287,6 +368,9 @@ by spaces with a tab stop of 4 characters.
 </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
@@ -315,6 +399,15 @@ by spaces with a tab stop of 4 characters.
 </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
 .
@@ -363,6 +456,17 @@ bar
 </ul>
 ````````````````````````````````
 
+```````````````````````````````` example
+#→Foo
+.
+<h1>Foo</h1>
+````````````````````````````````
+
+```````````````````````````````` example
+*→*→*→
+.
+<hr />
+````````````````````````````````
 
 
 ## Insecure characters
@@ -701,15 +805,6 @@ headings:
 ````````````````````````````````
 
 
-A tab will not work:
-
-```````````````````````````````` example
-#→foo
-.
-<p>#→foo</p>
-````````````````````````````````
-
-
 This is not a heading, because the first `#` is escaped:
 
 ```````````````````````````````` example
@@ -1890,7 +1985,7 @@ 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
+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.
 
@@ -1920,7 +2015,8 @@ 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`,
+`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`,
@@ -2224,6 +2320,7 @@ import Text.HTML.TagSoup
 main :: IO ()
 main = print $ parseTags tags
 </code></pre>
+okay
 .
 <pre language="haskell"><code>
 import Text.HTML.TagSoup
@@ -2231,6 +2328,7 @@ import Text.HTML.TagSoup
 main :: IO ()
 main = print $ parseTags tags
 </code></pre>
+<p>okay</p>
 ````````````````````````````````
 
 
@@ -2242,12 +2340,14 @@ A script tag (type 1):
 
 document.getElementById("demo").innerHTML = "Hello JavaScript!";
 </script>
+okay
 .
 <script type="text/javascript">
 // JavaScript example
 
 document.getElementById("demo").innerHTML = "Hello JavaScript!";
 </script>
+<p>okay</p>
 ````````````````````````````````
 
 
@@ -2260,6 +2360,7 @@ h1 {color:red;}
 
 p {color:blue;}
 </style>
+okay
 .
 <style
   type="text/css">
@@ -2267,6 +2368,7 @@ h1 {color:red;}
 
 p {color:blue;}
 </style>
+<p>okay</p>
 ````````````````````````````````
 
 
@@ -2355,11 +2457,13 @@ A comment (type 2):
 
 bar
    baz -->
+okay
 .
 <!-- Foo
 
 bar
    baz -->
+<p>okay</p>
 ````````````````````````````````
 
 
@@ -2372,12 +2476,14 @@ A processing instruction (type 3):
   echo '>';
 
 ?>
+okay
 .
 <?php
 
   echo '>';
 
 ?>
+<p>okay</p>
 ````````````````````````````````
 
 
@@ -2405,6 +2511,7 @@ function matchwo(a,b)
   }
 }
 ]]>
+okay
 .
 <![CDATA[
 function matchwo(a,b)
@@ -2418,6 +2525,7 @@ function matchwo(a,b)
   }
 }
 ]]>
+<p>okay</p>
 ````````````````````````````````
 
 
@@ -3162,8 +3270,8 @@ Four spaces gives us a code block:
 ````````````````````````````````
 
 
-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
@@ -3269,8 +3377,8 @@ 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
@@ -3292,7 +3400,7 @@ To see why, note that in
 
 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:
 
@@ -3521,7 +3629,7 @@ 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
+    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
@@ -3529,6 +3637,12 @@ The following rules define [list items]:
     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
@@ -3703,66 +3817,20 @@ any following content, so these are not list items:
 ````````````````````````````````
 
 
-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>
 ````````````````````````````````
 
@@ -3795,15 +3863,14 @@ A list item may contain any kind of block:
 
 
 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>
@@ -3811,33 +3878,13 @@ blank lines end the list):
 <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
@@ -4164,6 +4211,20 @@ A list may start or end with an empty list item:
 </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
@@ -4361,13 +4422,18 @@ So, in this case we need two spaces indent:
 - 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>
@@ -4382,11 +4448,13 @@ One is not enough:
 - foo
  - bar
   - baz
+   - boo
 .
 <ul>
 <li>foo</li>
 <li>bar</li>
 <li>baz</li>
+<li>boo</li>
 </ul>
 ````````````````````````````````
 
@@ -4663,8 +4731,7 @@ takes four spaces (a common case), but diverge in other cases.
 
 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.
@@ -4739,33 +4806,28 @@ Foo
 </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
 
@@ -4777,37 +4839,61 @@ 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
@@ -4824,36 +4910,12 @@ a list:
 <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
@@ -4867,26 +4929,28 @@ Indeed, two blank lines will end *all* containing lists:
 <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
@@ -4895,6 +4959,7 @@ item:
 <li>foo</li>
 <li>bar</li>
 </ul>
+<!-- -->
 <ul>
 <li>baz</li>
 <li>bim</li>
@@ -4909,6 +4974,7 @@ item:
 
 -   foo
 
+<!-- -->
 
     code
 .
@@ -4921,6 +4987,7 @@ item:
 <p>foo</p>
 </li>
 </ul>
+<!-- -->
 <pre><code>code
 </code></pre>
 ````````````````````````````````
@@ -5611,6 +5678,16 @@ single spaces, just as they would be by a browser:
 ````````````````````````````````
 
 
+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.
@@ -5867,18 +5944,22 @@ The following rules define emphasis and strong emphasis:
 
 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
@@ -5902,9 +5983,7 @@ the following principles resolve ambiguity:
     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
@@ -6077,10 +6156,8 @@ A newline also counts as whitespace:
 *foo bar
 *
 .
-<p>*foo bar</p>
-<ul>
-<li></li>
-</ul>
+<p>*foo bar
+*</p>
 ````````````````````````````````
 
 
@@ -6484,18 +6561,30 @@ __foo_ bar_
 <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*
@@ -6511,18 +6600,13 @@ The difference is that in the preceding case, the internal delimiters
 ````````````````````````````````
 
 
-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
@@ -6615,18 +6699,13 @@ ____foo__ bar__
 ````````````````````````````````
 
 
-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**
 .
@@ -6941,13 +7020,6 @@ Rule 15:
 ````````````````````````````````
 
 
-```````````````````````````````` example
-**foo*bar**
-.
-<p><em><em>foo</em>bar</em>*</p>
-````````````````````````````````
-
-
 ```````````````````````````````` example
 *foo __bar *baz bim__ bam*
 .
@@ -7300,6 +7372,16 @@ may be used in titles:
 ````````````````````````````````
 
 
+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
@@ -7878,7 +7960,7 @@ 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
+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][]`.
 
@@ -7964,7 +8046,8 @@ following closing bracket:
 ````````````````````````````````
 
 
-Full references take precedence over shortcut references:
+Full and compact references take precedence over shortcut
+references:
 
 ```````````````````````````````` example
 [foo][bar]
@@ -7975,6 +8058,31 @@ Full references take precedence over shortcut references:
 <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:
@@ -8853,7 +8961,7 @@ foo
 
 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.)
 
@@ -8984,7 +9092,7 @@ 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.
+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.
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/CHR1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/CHR1.scl
new file mode 100644 (file)
index 0000000..90ea90a
--- /dev/null
@@ -0,0 +1,159 @@
+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
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/CHR2.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/CHR2.scl
new file mode 100644 (file)
index 0000000..35fb724
--- /dev/null
@@ -0,0 +1,49 @@
+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
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/CHR3.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/CHR3.scl
new file mode 100644 (file)
index 0000000..0bba541
--- /dev/null
@@ -0,0 +1,11 @@
+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
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ClosingBrace.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ClosingBrace.scl
new file mode 100644 (file)
index 0000000..ef75644
--- /dev/null
@@ -0,0 +1,11 @@
+)\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
index affa2e66ff924b36b1b1667f87a64f91f95425f1..569335a0af7e7ab8e4008af574515215f2b93982 100644 (file)
@@ -2,5 +2,4 @@ import "Prelude"
 \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
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/IfWithoutElse.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/IfWithoutElse.scl
new file mode 100644 (file)
index 0000000..6659033
--- /dev/null
@@ -0,0 +1,11 @@
+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
index 8897d43ddd063b8b71e25a5d674aa9d3196a6de2..95d8b03dab09dfae641969b8a7be876a11d35132 100644 (file)
@@ -1,4 +1,4 @@
 
 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
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/LambdaMatch.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/LambdaMatch.scl
new file mode 100644 (file)
index 0000000..7e9103a
--- /dev/null
@@ -0,0 +1,10 @@
+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
index d1379cd8e3e72cb672da6dc12d97a5cef0519bd8..582dc71d110e67fccf5ae62151945be2a586495c 100644 (file)
@@ -1,7 +1,5 @@
 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
index 5e35b9424ac456dd7d61baa7d0c8c59f6df47293..f4cd212932fba4c78726d67d64b68c7f2f73a71c 100644 (file)
@@ -8,7 +8,7 @@ normalize l = go (length l)
            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
@@ -23,7 +23,7 @@ instance (Eq a, Additive a) => Additive (Poly a) where
             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
index 830186ba779ac5904acecfc892b3ac190fb325c6..854512752a584cd33173eefae075e2dd921a142a 100644 (file)
@@ -2,12 +2,11 @@ import "JavaBuiltin" as Java
 \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
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Serialization4.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Serialization4.scl
new file mode 100644 (file)
index 0000000..530f422
--- /dev/null
@@ -0,0 +1,13 @@
+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
index 726a3f5be6901db69e97143328aa001a60070a6d..afb4840d25c77c58712ca6a578bf1b45523e6b31 100644 (file)
@@ -8,8 +8,6 @@ data Signal =
   | 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
index 9d219430b9520594f56ee97327d09a09bbeaf009..e6ad8e114f28ffb26d1a4c171c5948d07f6050d1 100644 (file)
@@ -1,6 +1,9 @@
-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
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/StringInterpolation3.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/StringInterpolation3.scl
new file mode 100644 (file)
index 0000000..73be214
--- /dev/null
@@ -0,0 +1,12 @@
+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
index dbb1609a9c79e1f6c16e256085dafd1a7e0e2597..45ad0658afc17f8bced0682d0e1fb25262b77e0f 100644 (file)
@@ -10,14 +10,14 @@ rule FibRecurrence where
     
     @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
index 270d5751b12a559597f6385fea282838840286ee..85637b16be7595d0d13159799e3c81da0a518a29 100644 (file)
@@ -1,4 +1,4 @@
 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
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ViewPatterns1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ViewPatterns1.scl
new file mode 100644 (file)
index 0000000..092ce48
--- /dev/null
@@ -0,0 +1,10 @@
+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
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/unit/TestCHRCodeGenerator.java b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/unit/TestCHRCodeGenerator.java
new file mode 100644 (file)
index 0000000..afc9a44
--- /dev/null
@@ -0,0 +1,110 @@
+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
index fa3bd9f65988011ca71f8fa7f46fdeec2f7dd4cb..3f9c9e4e90e9ff96e2bcd1f468f63e08fadcd42e 100644 (file)
@@ -2,6 +2,7 @@ package org.simantics.scl.compiler.tests.unit;
 \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
@@ -10,7 +11,6 @@ import org.simantics.scl.compiler.environment.filter.NegativeNamespaceFilter;
 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