]> gerrit.simantics Code Review - simantics/platform.git/commitdiff
Automatic execution of SCL tests in Maven 88/88/1
authorHannu Niemistö <hannu.niemisto@semantum.fi>
Fri, 23 Sep 2016 12:14:20 +0000 (15:14 +0300)
committerHannu Niemistö <hannu.niemisto@semantum.fi>
Fri, 23 Sep 2016 12:14:20 +0000 (15:14 +0300)
This includes both compiler tests (in
tests/org.simantics.scl.compiler.tests) and a test that checks that all
SCL modules in org.simantics.sdk feature compile (in
tests/org.simantics.scl.osgi.tests).

This commit contains also some modifications to make all SCL
modules compile:
* Disabled Data/Json, because it does not compile (missing jackson)
* Committed away Simantics/Image/linkImage

Change-Id: I22a460d756f65139971f1e7d2cc8624a7a6b8ffb

327 files changed:
.gitignore
bundles/org.simantics.image.ui/scl/Simantics/Image.scl
bundles/org.simantics.scl.compiler/META-INF/MANIFEST.MF
bundles/org.simantics.scl.data/META-INF/MANIFEST.MF
bundles/org.simantics.scl.data/scl/Data/Json.scl.skip [moved from bundles/org.simantics.scl.data/scl/Data/Json.scl with 100% similarity]
pom.xml
tests/org.simantics.scl.compiler.tests/.classpath [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/.project [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/.settings/org.eclipse.jdt.core.prefs [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/META-INF/MANIFEST.MF [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/build.properties [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/ActiveTests.java [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/FindAllowedChars.java [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/InitialRepository.java [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/ModuleRegressionTests.java [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/ScriptTestBase.java [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/ScriptTests.java [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/TestBase.java [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/TestClassNaming.java [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/TestCommandParsing.java [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/TestCommandSession.java [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/TestExpressionEvaluator.java [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/TestRegression.java [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/TestTypeDesc.java [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/UnimplementedTests.java [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/experimentation/RecursiveInitialization.java [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/experimentation/TestEquals.java [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/experimentation/TestTypeDesc.java [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/imports/Maybe4Imports.java [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/markdown/RunMarkdownTests.java [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/markdown/spec.txt [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/performance/SumOfInverses.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/performance/SumOfInverses2.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/AmbiguousType.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ApplicationOfNunfunction.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Arity1.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/AsPattern.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/BigContext.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/BigFunction.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/BigInstances.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/BinaryOperators1.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/BlankExpression.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/BooleanId.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Bug4450.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Character1.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ClashingClass.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ClashingData.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ClashingInstance.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ClashingValueDefinition.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ClashingValueType.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Collaz.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Compose.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Composition.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ConjunctionMacro.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Constant.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ConstructorNameClash.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/DefaultMethods1.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Deriving3.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Deriving4.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/DifferentBranchTypes.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Div.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/DoubleConversion.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/DoubleEffect.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Effects1.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Effects2.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Effects3.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Effects4.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Effects5.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Effects6.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/EmptyLet.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Equality.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Equations1.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ExistentialData.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ExistentialData2.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ExpressionParsing.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/FaultyRecursion.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Fibonacci.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Fibonacci2.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Fibonacci3.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/FingerTree.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/FoldMissingInitialValue.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/FoldlBuild1.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/FoldlBuild2.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Forall1.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Forall2.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Forall3.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Formula.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/FromDynamic.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/FromDynamic2.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/FromDynamic3.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/FromDynamic4.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/FromDynamic5.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/FunctionFunctor.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/FunctionalDependencies1.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/FunctionalDependencies2.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Functor.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/FunctorM1.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Generalization.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/GenericMutualRecursion.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/GlobalVariables.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/GraphPrelude.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/GuardedExpressionBug.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Guards1.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Guards2.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/IdAsOperator.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/IllegalChar.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ImportJavaConstructor.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ImportRef.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InconsistentArity.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InconsistentIndentation.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/IndentationAndParenthesis.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Index.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Inline1.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InlineLoop.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InstanceHierarchy.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InstanceIsTypoedAsClass.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InstanceTypeVariables.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InvalidClass1.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InvalidEncoding.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InvalidInstance1.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InvalidJavaTypeAnnotation.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InvalidKinds.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InvalidKinds2.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InvalidKinds3.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InvalidLambda.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InvalidModule.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InvalidPattern1.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InvalidPattern2.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InvalidPattern3.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InvalidPattern4.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InvalidRuleset1.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InvalidRuleset2.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InvalidTypeClassInstance1.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/JavaAccess1.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/JavaConstructors.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/JavaMethods.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/JavaTypes.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Kinds1.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/LP.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Lambda.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Layout1.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/List.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ListError1.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ListError2.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ListSyntax.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ListSyntax10.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ListSyntax11.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ListSyntax12.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ListSyntax2.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ListSyntax3.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ListSyntax4.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ListSyntax5.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ListSyntax6.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ListSyntax7.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ListSyntax8.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ListSyntax9.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ListSyntaxWithoutPrelude.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/LocalDefinitions.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/LocalDefinitions2.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/LocalDefinitions3.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/LocalDefinitions4.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/LocalDefinitions5.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Macros1.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Macros2.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Macros3.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Macros4.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Map1.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/MarketModel.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/MarketModel2.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Matching.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Matching2.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Matching3.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Matching3b.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Matching4.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Matching5.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/MatchingWithMissingParameter.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/MatchingWithoutTypeAnnotations.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/MaximumBy.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Maybe1.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Maybe2.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Maybe3.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Maybe4.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/MissingEffect.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/MissingMethod.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/MissingTypeParameter.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ModuleInitialization.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/MonadBug1.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/MonadSyntax1.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/MonadSyntax2.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Monads1.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/NoDefinitionErrorMessage.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/NoInstance.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/NoInstance2.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/NonassociativeOperator.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/NonexistentTypeClassInAnnotation.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/NonexistingEffect.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/OneLineMatch.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/OpenString1.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/OpenString2.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/OverloadedArithmetic1.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/OverloadedArithmetic2.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/OverloadedArithmetic3.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/OverloadedLiterals2.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Overloading1.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Overloading2.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Overloading3.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Parsing.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/PatternError.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/PolymorphicRecursion.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/PolymorphicRecursion2.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Polynomials.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/PrecedenceOfNonoperators.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Primes.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Proc1.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Proc2.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Proc3.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Pythagoras.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Random1.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/RangeSyntax.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Record1.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/RecordShorthand.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/RecursiveContext.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/RecursiveValues.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/RecursiveValues2.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/RecursiveValues3.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/RecursiveValues4.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/RedBlackTrees.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Relations1.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Relations2.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/RepeatedVariableInPattern.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/SSATypingBug.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Scanl.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Search.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Sections.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Select1.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Select2.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Select3.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Select4.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Select5.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Select6.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Select7.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Select8.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Select9.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/SelfReferringContextInTypeClass.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Serialization.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Serialization2.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Serialization3.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Set1.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/SharedTypeVariable.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ShortcutFusion.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Show1.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Signals.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/SinConst1.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Sort.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Sort2.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/SpecConstr1.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/StackTrace.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/StreamFusion.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/StringEscape.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/StringInterpolation1.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/StringInterpolation2.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/StringMatching1.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/SumOfInverses2.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Timing.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/TooManyParametersToSin.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Transformation1.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Transformation2.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Transformation3.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Transformation4.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Transformation5.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Transformation6.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Transformation7.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/TransformationOrder.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Tuples.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Tuples2.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/TypeAlias1.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/TypeAlias2.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/TypeAlias3.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/TypeAliasRefsToTypeAlias.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/TypeAnnotation1.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/TypeAnnotation2.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/TypeClass.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/TypeClass2.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/TypeClassBug1.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/TypeClassBug2.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/TypeInferenceBug2.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/TypeOf1.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/TypingBug1.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/TypingError1.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/TypingError2.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/UnaryMinus.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/UndefinedValue.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/UnexpectedToken.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Unification1.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/UnknownAnnotation.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/UnresolvedClass.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/UnresolvedTypeInAnnotation.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/UnresolvedTypeInInstance.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/UnresolvedVariable.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/UnresolvedVariable2.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ValueAsOperator.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ValueConversion.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Vector1.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Vector2.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Void1.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Void2.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Void3.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/While.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/While2.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/While3.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/WrongDefaultMethod.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/WrongInstanceMethod.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scripts/Arithmetic.sts [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scripts/Functions.sts [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scripts/Functions2.sts [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scripts/Lists.sts [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/unit/TestNamespaceFilter.java [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/unit/TestSubSolver.java [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/unit/TestTypeParser.java [new file with mode: 0644]
tests/org.simantics.scl.osgi.tests/.classpath [new file with mode: 0644]
tests/org.simantics.scl.osgi.tests/.project [new file with mode: 0644]
tests/org.simantics.scl.osgi.tests/.settings/org.eclipse.jdt.core.prefs [new file with mode: 0644]
tests/org.simantics.scl.osgi.tests/META-INF/MANIFEST.MF [new file with mode: 0644]
tests/org.simantics.scl.osgi.tests/build.properties [new file with mode: 0644]
tests/org.simantics.scl.osgi.tests/pom.xml [new file with mode: 0644]
tests/org.simantics.scl.osgi.tests/src/org/simantics/scl/osgi/tests/TestSCLOsgi.java [new file with mode: 0644]
tests/pom.xml [new file with mode: 0644]

index 7d388077123ad5154301acda4f9f48eaa2f2e41d..d61db6ef2e0d54014af784e8c5a757435bb313df 100644 (file)
@@ -1,4 +1,6 @@
 /**/bin/\r
 /features/*/target/\r
 /bundles/*/target/\r
+/releng/**/target/\r
+/tests/*/target/\r
 /**/.polyglot.build.properties
index 74d197f2fbdd3ba5050294b30fe10da0e3b3ffa0..df9ba836019a09c8b5a12aa43d8d9b4a29be4e4f 100644 (file)
@@ -8,6 +8,7 @@ type Image = Resource
 importJava "org.simantics.image.ui.SCLImage" where\r
     @JavaName importImageFromFile\r
     importImage :: File -> Library -> <WriteGraph> Image\r
-    \r
-    @JavaName linkImage\r
-    linkImage :: SVGImage -> Image -> <WriteGraph> ()
\ No newline at end of file
+  \r
+//  HN: does not exist  \r
+//    @JavaName linkImage\r
+//    linkImage :: SVGImage -> Image -> <WriteGraph> ()
\ No newline at end of file
index 389381c96d6703cb19e870c56de5fadb7c3a7244..916e66cfd22f510b5c8ac238454a1e277015fc74 100755 (executable)
@@ -10,7 +10,8 @@ Require-Bundle: gnu.trove3;bundle-version="3.0.0",
  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)"
-Export-Package: org.simantics.scl.compiler.commands,
+Export-Package: org.cojen.classfile,
+ org.simantics.scl.compiler.commands,
  org.simantics.scl.compiler.common.datatypes,
  org.simantics.scl.compiler.common.exceptions,
  org.simantics.scl.compiler.common.names,
@@ -38,12 +39,15 @@ Export-Package: org.simantics.scl.compiler.commands,
  org.simantics.scl.compiler.environment.filter,
  org.simantics.scl.compiler.environment.specification,
  org.simantics.scl.compiler.errors,
+ org.simantics.scl.compiler.internal.elaboration.constraints2,
+ org.simantics.scl.compiler.internal.elaboration.subsumption,
  org.simantics.scl.compiler.internal.parsing,
  org.simantics.scl.compiler.internal.parsing.exceptions,
  org.simantics.scl.compiler.internal.parsing.parser,
  org.simantics.scl.compiler.markdown.html,
  org.simantics.scl.compiler.markdown.inlines,
  org.simantics.scl.compiler.markdown.internal,
+ org.simantics.scl.compiler.markdown.nodes,
  org.simantics.scl.compiler.module,
  org.simantics.scl.compiler.module.coverage,
  org.simantics.scl.compiler.module.options,
index 52095a10169c88160aac11f4b9d3392cc79806e4..950e59b42ff0238825f5f0037490c67dd021d843 100644 (file)
@@ -7,6 +7,5 @@ Bundle-RequiredExecutionEnvironment: JavaSE-1.7
 Require-Bundle: org.simantics.scl.runtime;bundle-version="0.4.0",
  org.simantics.scl.osgi;bundle-version="1.0.4",
  org.jdom2;bundle-version="2.0.6",
- org.junit;bundle-version="4.12.0";resolution:=optional,
- com.fasterxml.jackson.core.jackson-core;bundle-version="2.8.2"
+ org.junit;bundle-version="4.12.0";resolution:=optional
 Bundle-ClassPath: .
diff --git a/pom.xml b/pom.xml
index eeebff8e9448faa8439d2fa6205dbedaebe75cd0..85a794381bb42ff579a05cf65d29db14a794b878 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -17,6 +17,7 @@
                <module>bundles</module>\r
                <module>features</module>\r
                <module>releng</module>\r
+               <module>tests</module>\r
        </modules>\r
 \r
        <build>\r
diff --git a/tests/org.simantics.scl.compiler.tests/.classpath b/tests/org.simantics.scl.compiler.tests/.classpath
new file mode 100644 (file)
index 0000000..b862a29
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<classpath>\r
+       <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="output" path="bin"/>\r
+</classpath>\r
diff --git a/tests/org.simantics.scl.compiler.tests/.project b/tests/org.simantics.scl.compiler.tests/.project
new file mode 100644 (file)
index 0000000..9fa2ae1
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<projectDescription>\r
+       <name>org.simantics.scl.compiler.tests</name>\r
+       <comment></comment>\r
+       <projects>\r
+       </projects>\r
+       <buildSpec>\r
+               <buildCommand>\r
+                       <name>org.eclipse.jdt.core.javabuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+               <buildCommand>\r
+                       <name>org.eclipse.pde.ManifestBuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+               <buildCommand>\r
+                       <name>org.eclipse.pde.SchemaBuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+       </buildSpec>\r
+       <natures>\r
+               <nature>org.eclipse.pde.PluginNature</nature>\r
+               <nature>org.eclipse.jdt.core.javanature</nature>\r
+       </natures>\r
+</projectDescription>\r
diff --git a/tests/org.simantics.scl.compiler.tests/.settings/org.eclipse.jdt.core.prefs b/tests/org.simantics.scl.compiler.tests/.settings/org.eclipse.jdt.core.prefs
new file mode 100644 (file)
index 0000000..295926d
--- /dev/null
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1\r
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled\r
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8\r
+org.eclipse.jdt.core.compiler.compliance=1.8\r
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error\r
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error\r
+org.eclipse.jdt.core.compiler.source=1.8\r
diff --git a/tests/org.simantics.scl.compiler.tests/META-INF/MANIFEST.MF b/tests/org.simantics.scl.compiler.tests/META-INF/MANIFEST.MF
new file mode 100644 (file)
index 0000000..5caaeec
--- /dev/null
@@ -0,0 +1,12 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Tests
+Bundle-SymbolicName: org.simantics.scl.compiler.tests
+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.objectweb.asm.util,
+ org.eclipse.equinox.ds;bundle-version="1.4.300"
diff --git a/tests/org.simantics.scl.compiler.tests/build.properties b/tests/org.simantics.scl.compiler.tests/build.properties
new file mode 100644 (file)
index 0000000..41eb6ad
--- /dev/null
@@ -0,0 +1,4 @@
+source.. = src/\r
+output.. = bin/\r
+bin.includes = META-INF/,\\r
+               .\r
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/ActiveTests.java b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/ActiveTests.java
new file mode 100644 (file)
index 0000000..f9533ef
--- /dev/null
@@ -0,0 +1,24 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/FindAllowedChars.java b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/FindAllowedChars.java
new file mode 100644 (file)
index 0000000..1e40786
--- /dev/null
@@ -0,0 +1,66 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/InitialRepository.java b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/InitialRepository.java
new file mode 100644 (file)
index 0000000..e1d0d59
--- /dev/null
@@ -0,0 +1,21 @@
+package org.simantics.scl.compiler.tests;\r
+\r
+import org.simantics.scl.compiler.module.repository.ModuleRepository;\r
+import org.simantics.scl.compiler.source.repository.CompositeModuleSourceRepository;\r
+import org.simantics.scl.compiler.source.repository.SourceRepositories;\r
+import org.simantics.scl.osgi.SCLOsgi;\r
+\r
+public class InitialRepository {\r
+    private static ModuleRepository MODULE_REPOSITORY1 = new ModuleRepository(\r
+            new CompositeModuleSourceRepository(\r
+                    SourceRepositories.BUILTIN_SOURCE_REPOSITORY,\r
+                    SourceRepositories.PRELUDE_SOURCE_REPOSITORY\r
+                    ));\r
+    \r
+    public static ModuleRepository getInitialRepository() {\r
+        if(MODULE_REPOSITORY1.getModule("Prelude").didSucceed())\r
+            return MODULE_REPOSITORY1;\r
+        else\r
+            return SCLOsgi.MODULE_REPOSITORY;\r
+    }\r
+}\r
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/ModuleRegressionTests.java b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/ModuleRegressionTests.java
new file mode 100644 (file)
index 0000000..34d7a33
--- /dev/null
@@ -0,0 +1,294 @@
+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 {
+
+    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(); }
+    @Ignore
+    @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(); }
+    @Ignore
+    @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(); }
+    @Ignore
+    @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.codeSize);
+            printCoverageTree(bp.children, ind+1);
+        }
+    }
+
+}
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/ScriptTestBase.java b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/ScriptTestBase.java
new file mode 100644 (file)
index 0000000..9e4401d
--- /dev/null
@@ -0,0 +1,45 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/ScriptTests.java b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/ScriptTests.java
new file mode 100644 (file)
index 0000000..a462f53
--- /dev/null
@@ -0,0 +1,16 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/TestBase.java b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/TestBase.java
new file mode 100644 (file)
index 0000000..05ffd75
--- /dev/null
@@ -0,0 +1,138 @@
+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 = InitialRepository.getInitialRepository();
+    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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/TestClassNaming.java b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/TestClassNaming.java
new file mode 100644 (file)
index 0000000..283e0e1
--- /dev/null
@@ -0,0 +1,46 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/TestCommandParsing.java b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/TestCommandParsing.java
new file mode 100644 (file)
index 0000000..f8b8eb9
--- /dev/null
@@ -0,0 +1,29 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/TestCommandSession.java b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/TestCommandSession.java
new file mode 100644 (file)
index 0000000..b86f097
--- /dev/null
@@ -0,0 +1,78 @@
+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 = InitialRepository.getInitialRepository();
+    }
+    
+    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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/TestExpressionEvaluator.java b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/TestExpressionEvaluator.java
new file mode 100644 (file)
index 0000000..e143c6a
--- /dev/null
@@ -0,0 +1,197 @@
+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 = InitialRepository.getInitialRepository();
+        
+        // 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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/TestRegression.java b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/TestRegression.java
new file mode 100644 (file)
index 0000000..fcf31dd
--- /dev/null
@@ -0,0 +1,14 @@
+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 TestRegression {
+}
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/TestTypeDesc.java b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/TestTypeDesc.java
new file mode 100644 (file)
index 0000000..451dca8
--- /dev/null
@@ -0,0 +1,12 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/UnimplementedTests.java b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/UnimplementedTests.java
new file mode 100644 (file)
index 0000000..612a3ab
--- /dev/null
@@ -0,0 +1,29 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/experimentation/RecursiveInitialization.java b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/experimentation/RecursiveInitialization.java
new file mode 100644 (file)
index 0000000..5f5d20d
--- /dev/null
@@ -0,0 +1,60 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/experimentation/TestEquals.java b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/experimentation/TestEquals.java
new file mode 100644 (file)
index 0000000..022ae57
--- /dev/null
@@ -0,0 +1,15 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/experimentation/TestTypeDesc.java b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/experimentation/TestTypeDesc.java
new file mode 100644 (file)
index 0000000..7153889
--- /dev/null
@@ -0,0 +1,12 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/imports/Maybe4Imports.java b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/imports/Maybe4Imports.java
new file mode 100644 (file)
index 0000000..30fe627
--- /dev/null
@@ -0,0 +1,15 @@
+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/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
new file mode 100644 (file)
index 0000000..9971a02
--- /dev/null
@@ -0,0 +1,100 @@
+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;
+    }
+    
+}
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/markdown/spec.txt b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/markdown/spec.txt
new file mode 100644 (file)
index 0000000..bdaed43
--- /dev/null
@@ -0,0 +1,9252 @@
+---
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/performance/SumOfInverses.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/performance/SumOfInverses.scl
new file mode 100644 (file)
index 0000000..a3f9407
--- /dev/null
@@ -0,0 +1,8 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/performance/SumOfInverses2.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/performance/SumOfInverses2.scl
new file mode 100644 (file)
index 0000000..7745029
--- /dev/null
@@ -0,0 +1,4 @@
+import "Prelude"\r
+\r
+main :: Integer -> Double\r
+main m = sum [1/(fromInteger x) | x <- [1..m]]\r
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/AmbiguousType.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/AmbiguousType.scl
new file mode 100644 (file)
index 0000000..f4871d7
--- /dev/null
@@ -0,0 +1,12 @@
+\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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ApplicationOfNunfunction.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ApplicationOfNunfunction.scl
new file mode 100644 (file)
index 0000000..13167be
--- /dev/null
@@ -0,0 +1,3 @@
+main = "Hello" "world!"\r
+--\r
+1:8-1:24: Application of non-function.\r
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Arity1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Arity1.scl
new file mode 100644 (file)
index 0000000..fa48e47
--- /dev/null
@@ -0,0 +1,9 @@
+\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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/AsPattern.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/AsPattern.scl
new file mode 100644 (file)
index 0000000..0e33370
--- /dev/null
@@ -0,0 +1,8 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/BigContext.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/BigContext.scl
new file mode 100644 (file)
index 0000000..fc70cc2
--- /dev/null
@@ -0,0 +1,28 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/BigFunction.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/BigFunction.scl
new file mode 100644 (file)
index 0000000..102bc1d
--- /dev/null
@@ -0,0 +1,7 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/BigInstances.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/BigInstances.scl
new file mode 100644 (file)
index 0000000..c64b1b7
--- /dev/null
@@ -0,0 +1,16 @@
+\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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/BinaryOperators1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/BinaryOperators1.scl
new file mode 100644 (file)
index 0000000..86263c9
--- /dev/null
@@ -0,0 +1,25 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/BlankExpression.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/BlankExpression.scl
new file mode 100644 (file)
index 0000000..f31e144
--- /dev/null
@@ -0,0 +1,3 @@
+main = _\r
+--\r
+???
\ No newline at end of file
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/BooleanId.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/BooleanId.scl
new file mode 100644 (file)
index 0000000..2044c1c
--- /dev/null
@@ -0,0 +1,12 @@
+@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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Bug4450.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Bug4450.scl
new file mode 100644 (file)
index 0000000..54e65c2
--- /dev/null
@@ -0,0 +1,15 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Character1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Character1.scl
new file mode 100644 (file)
index 0000000..b08d2ae
--- /dev/null
@@ -0,0 +1,5 @@
+import "Prelude"\r
+\r
+main = subChar '6' '0'\r
+--\r
+6\r
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ClashingClass.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ClashingClass.scl
new file mode 100644 (file)
index 0000000..dee1e8d
--- /dev/null
@@ -0,0 +1,8 @@
+\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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ClashingData.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ClashingData.scl
new file mode 100644 (file)
index 0000000..60245db
--- /dev/null
@@ -0,0 +1,5 @@
+\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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ClashingInstance.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ClashingInstance.scl
new file mode 100644 (file)
index 0000000..72178db
--- /dev/null
@@ -0,0 +1,14 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ClashingValueDefinition.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ClashingValueDefinition.scl
new file mode 100644 (file)
index 0000000..f7ec72a
--- /dev/null
@@ -0,0 +1,5 @@
+a = 1\r
+a = 2\r
+main = "Should not be executed."\r
+--\r
+???
\ No newline at end of file
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ClashingValueType.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ClashingValueType.scl
new file mode 100644 (file)
index 0000000..d248d20
--- /dev/null
@@ -0,0 +1,6 @@
+\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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Collaz.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Collaz.scl
new file mode 100644 (file)
index 0000000..2e4552d
--- /dev/null
@@ -0,0 +1,16 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Compose.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Compose.scl
new file mode 100644 (file)
index 0000000..fad8b9b
--- /dev/null
@@ -0,0 +1,20 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Composition.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Composition.scl
new file mode 100644 (file)
index 0000000..80b1c06
--- /dev/null
@@ -0,0 +1,17 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ConjunctionMacro.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ConjunctionMacro.scl
new file mode 100644 (file)
index 0000000..99188f8
--- /dev/null
@@ -0,0 +1,6 @@
+(&&) :: 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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Constant.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Constant.scl
new file mode 100644 (file)
index 0000000..7ea0367
--- /dev/null
@@ -0,0 +1,6 @@
+\r
+a = 14 :: Integer\r
+\r
+main = a\r
+--\r
+14
\ No newline at end of file
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ConstructorNameClash.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ConstructorNameClash.scl
new file mode 100644 (file)
index 0000000..52826a5
--- /dev/null
@@ -0,0 +1,7 @@
+\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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/DefaultMethods1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/DefaultMethods1.scl
new file mode 100644 (file)
index 0000000..142dd30
--- /dev/null
@@ -0,0 +1,13 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Deriving3.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Deriving3.scl
new file mode 100644 (file)
index 0000000..ec2f5b7
--- /dev/null
@@ -0,0 +1,29 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Deriving4.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Deriving4.scl
new file mode 100644 (file)
index 0000000..03ea0d6
--- /dev/null
@@ -0,0 +1,9 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/DifferentBranchTypes.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/DifferentBranchTypes.scl
new file mode 100644 (file)
index 0000000..2a0925f
--- /dev/null
@@ -0,0 +1,19 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Div.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Div.scl
new file mode 100644 (file)
index 0000000..4a8e1ca
--- /dev/null
@@ -0,0 +1,5 @@
+import "Prelude"\r
+\r
+main = 7 `div` 3\r
+--\r
+2
\ No newline at end of file
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/DoubleConversion.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/DoubleConversion.scl
new file mode 100644 (file)
index 0000000..31e95ed
--- /dev/null
@@ -0,0 +1,17 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/DoubleEffect.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/DoubleEffect.scl
new file mode 100644 (file)
index 0000000..b061510
--- /dev/null
@@ -0,0 +1,8 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Effects1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Effects1.scl
new file mode 100644 (file)
index 0000000..11a3303
--- /dev/null
@@ -0,0 +1,18 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Effects2.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Effects2.scl
new file mode 100644 (file)
index 0000000..d595ee9
--- /dev/null
@@ -0,0 +1,21 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Effects3.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Effects3.scl
new file mode 100644 (file)
index 0000000..7184829
--- /dev/null
@@ -0,0 +1,12 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Effects4.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Effects4.scl
new file mode 100644 (file)
index 0000000..85138a6
--- /dev/null
@@ -0,0 +1,12 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Effects5.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Effects5.scl
new file mode 100644 (file)
index 0000000..595b634
--- /dev/null
@@ -0,0 +1,13 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Effects6.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Effects6.scl
new file mode 100644 (file)
index 0000000..e99dd4f
--- /dev/null
@@ -0,0 +1,13 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/EmptyLet.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/EmptyLet.scl
new file mode 100644 (file)
index 0000000..68c6623
--- /dev/null
@@ -0,0 +1,9 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Equality.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Equality.scl
new file mode 100644 (file)
index 0000000..acf00e9
--- /dev/null
@@ -0,0 +1,41 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Equations1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Equations1.scl
new file mode 100644 (file)
index 0000000..613d56b
--- /dev/null
@@ -0,0 +1,13 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ExistentialData.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ExistentialData.scl
new file mode 100644 (file)
index 0000000..62130b4
--- /dev/null
@@ -0,0 +1,23 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ExistentialData2.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ExistentialData2.scl
new file mode 100644 (file)
index 0000000..b029969
--- /dev/null
@@ -0,0 +1,7 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ExpressionParsing.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ExpressionParsing.scl
new file mode 100644 (file)
index 0000000..6719bf9
--- /dev/null
@@ -0,0 +1,27 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/FaultyRecursion.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/FaultyRecursion.scl
new file mode 100644 (file)
index 0000000..523b408
--- /dev/null
@@ -0,0 +1,3 @@
+fib n = fib\r
+--\r
+1:9-1:12: Expected <a> got <b -> <c> a>.
\ No newline at end of file
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Fibonacci.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Fibonacci.scl
new file mode 100644 (file)
index 0000000..b7b56f5
--- /dev/null
@@ -0,0 +1,14 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Fibonacci2.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Fibonacci2.scl
new file mode 100644 (file)
index 0000000..229145f
--- /dev/null
@@ -0,0 +1,11 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Fibonacci3.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Fibonacci3.scl
new file mode 100644 (file)
index 0000000..d5ce91c
--- /dev/null
@@ -0,0 +1,20 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/FingerTree.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/FingerTree.scl
new file mode 100644 (file)
index 0000000..b81f642
--- /dev/null
@@ -0,0 +1,173 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/FoldMissingInitialValue.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/FoldMissingInitialValue.scl
new file mode 100644 (file)
index 0000000..affa2e6
--- /dev/null
@@ -0,0 +1,6 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/FoldlBuild1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/FoldlBuild1.scl
new file mode 100644 (file)
index 0000000..21dfdea
--- /dev/null
@@ -0,0 +1,18 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/FoldlBuild2.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/FoldlBuild2.scl
new file mode 100644 (file)
index 0000000..2078fb7
--- /dev/null
@@ -0,0 +1,16 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Forall1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Forall1.scl
new file mode 100644 (file)
index 0000000..32e51a7
--- /dev/null
@@ -0,0 +1,8 @@
+     \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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Forall2.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Forall2.scl
new file mode 100644 (file)
index 0000000..97d1c35
--- /dev/null
@@ -0,0 +1,9 @@
+\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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Forall3.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Forall3.scl
new file mode 100644 (file)
index 0000000..018a2a0
--- /dev/null
@@ -0,0 +1,11 @@
+\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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Formula.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Formula.scl
new file mode 100644 (file)
index 0000000..10eafb0
--- /dev/null
@@ -0,0 +1,131 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/FromDynamic.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/FromDynamic.scl
new file mode 100644 (file)
index 0000000..1ac2e77
--- /dev/null
@@ -0,0 +1,5 @@
+import "Prelude"\r
+\r
+main = (fromDynamic (toDynamic 42) :: String) + "foo"\r
+--\r
+42foo
\ No newline at end of file
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/FromDynamic2.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/FromDynamic2.scl
new file mode 100644 (file)
index 0000000..1b6c1d9
--- /dev/null
@@ -0,0 +1,5 @@
+import "Prelude"\r
+\r
+main = (fromDynamic (toDynamic "42") :: Integer) - 2\r
+--\r
+40
\ No newline at end of file
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/FromDynamic3.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/FromDynamic3.scl
new file mode 100644 (file)
index 0000000..a3318d4
--- /dev/null
@@ -0,0 +1,5 @@
+import "Prelude"\r
+\r
+main = arrayToList (fromDynamic (toDynamic ["42"]) :: (Array Integer))\r
+--\r
+[42]
\ No newline at end of file
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/FromDynamic4.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/FromDynamic4.scl
new file mode 100644 (file)
index 0000000..fb4c320
--- /dev/null
@@ -0,0 +1,6 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/FromDynamic5.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/FromDynamic5.scl
new file mode 100644 (file)
index 0000000..d0d0fd3
--- /dev/null
@@ -0,0 +1,6 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/FunctionFunctor.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/FunctionFunctor.scl
new file mode 100644 (file)
index 0000000..f634810
--- /dev/null
@@ -0,0 +1,9 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/FunctionalDependencies1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/FunctionalDependencies1.scl
new file mode 100644 (file)
index 0000000..203de1d
--- /dev/null
@@ -0,0 +1,11 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/FunctionalDependencies2.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/FunctionalDependencies2.scl
new file mode 100644 (file)
index 0000000..707bb9e
--- /dev/null
@@ -0,0 +1,12 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Functor.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Functor.scl
new file mode 100644 (file)
index 0000000..6bbd359
--- /dev/null
@@ -0,0 +1,23 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/FunctorM1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/FunctorM1.scl
new file mode 100644 (file)
index 0000000..5e1874e
--- /dev/null
@@ -0,0 +1,11 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Generalization.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Generalization.scl
new file mode 100644 (file)
index 0000000..e550334
--- /dev/null
@@ -0,0 +1,13 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/GenericMutualRecursion.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/GenericMutualRecursion.scl
new file mode 100644 (file)
index 0000000..24c5858
--- /dev/null
@@ -0,0 +1,12 @@
+// 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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/GlobalVariables.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/GlobalVariables.scl
new file mode 100644 (file)
index 0000000..c6dc99e
--- /dev/null
@@ -0,0 +1,14 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/GraphPrelude.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/GraphPrelude.scl
new file mode 100644 (file)
index 0000000..ddb2d58
--- /dev/null
@@ -0,0 +1,41 @@
+\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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/GuardedExpressionBug.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/GuardedExpressionBug.scl
new file mode 100644 (file)
index 0000000..c0d45f1
--- /dev/null
@@ -0,0 +1,9 @@
+tableIndex :: Double -> Double
+tableIndex x
+    | True = x
+  where
+    f _ = x
+
+main = "Foo"
+--
+Foo
\ No newline at end of file
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Guards1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Guards1.scl
new file mode 100644 (file)
index 0000000..db3b438
--- /dev/null
@@ -0,0 +1,9 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Guards2.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Guards2.scl
new file mode 100644 (file)
index 0000000..88734c1
--- /dev/null
@@ -0,0 +1,10 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/IdAsOperator.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/IdAsOperator.scl
new file mode 100644 (file)
index 0000000..576ff86
--- /dev/null
@@ -0,0 +1,9 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/IllegalChar.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/IllegalChar.scl
new file mode 100644 (file)
index 0000000..371492b
--- /dev/null
@@ -0,0 +1,3 @@
+a = ¤\r
+--\r
+1:5-1:6: Illegal character '¤'.\r
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ImportJavaConstructor.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ImportJavaConstructor.scl
new file mode 100644 (file)
index 0000000..8c45e43
--- /dev/null
@@ -0,0 +1,18 @@
+\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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ImportRef.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ImportRef.scl
new file mode 100644 (file)
index 0000000..9fb6f62
--- /dev/null
@@ -0,0 +1,18 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InconsistentArity.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InconsistentArity.scl
new file mode 100644 (file)
index 0000000..82a9668
--- /dev/null
@@ -0,0 +1,4 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InconsistentIndentation.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InconsistentIndentation.scl
new file mode 100644 (file)
index 0000000..bd732cf
--- /dev/null
@@ -0,0 +1,5 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/IndentationAndParenthesis.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/IndentationAndParenthesis.scl
new file mode 100644 (file)
index 0000000..3a8dc3d
--- /dev/null
@@ -0,0 +1,16 @@
+// 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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Index.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Index.scl
new file mode 100644 (file)
index 0000000..8a98aec
--- /dev/null
@@ -0,0 +1,8 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Inline1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Inline1.scl
new file mode 100644 (file)
index 0000000..118abc4
--- /dev/null
@@ -0,0 +1,5 @@
+main = id "Foo" \r
+  where\r
+    id x = x\r
+--\r
+Foo
\ No newline at end of file
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InlineLoop.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InlineLoop.scl
new file mode 100644 (file)
index 0000000..df8433c
--- /dev/null
@@ -0,0 +1,9 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InstanceHierarchy.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InstanceHierarchy.scl
new file mode 100644 (file)
index 0000000..1c751f3
--- /dev/null
@@ -0,0 +1,26 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InstanceIsTypoedAsClass.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InstanceIsTypoedAsClass.scl
new file mode 100644 (file)
index 0000000..f3973cc
--- /dev/null
@@ -0,0 +1,9 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InstanceTypeVariables.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InstanceTypeVariables.scl
new file mode 100644 (file)
index 0000000..e4ee646
--- /dev/null
@@ -0,0 +1,10 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InvalidClass1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InvalidClass1.scl
new file mode 100644 (file)
index 0000000..796f92c
--- /dev/null
@@ -0,0 +1,4 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InvalidEncoding.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InvalidEncoding.scl
new file mode 100644 (file)
index 0000000..513b36f
--- /dev/null
@@ -0,0 +1,3 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InvalidInstance1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InvalidInstance1.scl
new file mode 100644 (file)
index 0000000..35064c6
--- /dev/null
@@ -0,0 +1,8 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InvalidJavaTypeAnnotation.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InvalidJavaTypeAnnotation.scl
new file mode 100644 (file)
index 0000000..9f7270c
--- /dev/null
@@ -0,0 +1,6 @@
+@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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InvalidKinds.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InvalidKinds.scl
new file mode 100644 (file)
index 0000000..a18c062
--- /dev/null
@@ -0,0 +1,7 @@
+\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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InvalidKinds2.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InvalidKinds2.scl
new file mode 100644 (file)
index 0000000..ffdf0a9
--- /dev/null
@@ -0,0 +1,9 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InvalidKinds3.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InvalidKinds3.scl
new file mode 100644 (file)
index 0000000..445dd7e
--- /dev/null
@@ -0,0 +1,5 @@
+\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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InvalidLambda.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InvalidLambda.scl
new file mode 100644 (file)
index 0000000..8897d43
--- /dev/null
@@ -0,0 +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.
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InvalidModule.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InvalidModule.scl
new file mode 100644 (file)
index 0000000..7cf5f95
--- /dev/null
@@ -0,0 +1,3 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InvalidPattern1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InvalidPattern1.scl
new file mode 100644 (file)
index 0000000..5ba56cf
--- /dev/null
@@ -0,0 +1,7 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InvalidPattern2.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InvalidPattern2.scl
new file mode 100644 (file)
index 0000000..2bf9613
--- /dev/null
@@ -0,0 +1,5 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InvalidPattern3.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InvalidPattern3.scl
new file mode 100644 (file)
index 0000000..460a9bd
--- /dev/null
@@ -0,0 +1,8 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InvalidPattern4.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InvalidPattern4.scl
new file mode 100644 (file)
index 0000000..11dfd07
--- /dev/null
@@ -0,0 +1,7 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InvalidRuleset1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InvalidRuleset1.scl
new file mode 100644 (file)
index 0000000..e53520b
--- /dev/null
@@ -0,0 +1,10 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InvalidRuleset2.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InvalidRuleset2.scl
new file mode 100644 (file)
index 0000000..675ee49
--- /dev/null
@@ -0,0 +1,11 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InvalidTypeClassInstance1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InvalidTypeClassInstance1.scl
new file mode 100644 (file)
index 0000000..8860c3b
--- /dev/null
@@ -0,0 +1,9 @@
+\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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/JavaAccess1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/JavaAccess1.scl
new file mode 100644 (file)
index 0000000..0576f43
--- /dev/null
@@ -0,0 +1,8 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/JavaConstructors.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/JavaConstructors.scl
new file mode 100644 (file)
index 0000000..d3ee020
--- /dev/null
@@ -0,0 +1,11 @@
+\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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/JavaMethods.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/JavaMethods.scl
new file mode 100644 (file)
index 0000000..d51bd4b
--- /dev/null
@@ -0,0 +1,9 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/JavaTypes.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/JavaTypes.scl
new file mode 100644 (file)
index 0000000..830c5a4
--- /dev/null
@@ -0,0 +1,14 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Kinds1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Kinds1.scl
new file mode 100644 (file)
index 0000000..2f2f0d1
--- /dev/null
@@ -0,0 +1,15 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/LP.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/LP.scl
new file mode 100644 (file)
index 0000000..0c3ddc1
--- /dev/null
@@ -0,0 +1,86 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Lambda.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Lambda.scl
new file mode 100644 (file)
index 0000000..2316b30
--- /dev/null
@@ -0,0 +1,13 @@
+\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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Layout1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Layout1.scl
new file mode 100644 (file)
index 0000000..f68e9a6
--- /dev/null
@@ -0,0 +1,12 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/List.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/List.scl
new file mode 100644 (file)
index 0000000..b746c31
--- /dev/null
@@ -0,0 +1,7 @@
+\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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ListError1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ListError1.scl
new file mode 100644 (file)
index 0000000..0fece99
--- /dev/null
@@ -0,0 +1,7 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ListError2.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ListError2.scl
new file mode 100644 (file)
index 0000000..135e270
--- /dev/null
@@ -0,0 +1,7 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ListSyntax.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ListSyntax.scl
new file mode 100644 (file)
index 0000000..1747a6f
--- /dev/null
@@ -0,0 +1,7 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ListSyntax10.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ListSyntax10.scl
new file mode 100644 (file)
index 0000000..726dba5
--- /dev/null
@@ -0,0 +1,12 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ListSyntax11.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ListSyntax11.scl
new file mode 100644 (file)
index 0000000..15f0441
--- /dev/null
@@ -0,0 +1,8 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ListSyntax12.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ListSyntax12.scl
new file mode 100644 (file)
index 0000000..8b18eb3
--- /dev/null
@@ -0,0 +1,5 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ListSyntax2.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ListSyntax2.scl
new file mode 100644 (file)
index 0000000..e020731
--- /dev/null
@@ -0,0 +1,7 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ListSyntax3.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ListSyntax3.scl
new file mode 100644 (file)
index 0000000..c6cbbca
--- /dev/null
@@ -0,0 +1,5 @@
+import "Prelude"\r
+\r
+main = [1,2,3,4]\r
+--\r
+[1, 2, 3, 4]
\ No newline at end of file
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ListSyntax4.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ListSyntax4.scl
new file mode 100644 (file)
index 0000000..a950635
--- /dev/null
@@ -0,0 +1,6 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ListSyntax5.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ListSyntax5.scl
new file mode 100644 (file)
index 0000000..6ba8330
--- /dev/null
@@ -0,0 +1,8 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ListSyntax6.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ListSyntax6.scl
new file mode 100644 (file)
index 0000000..a3e08c4
--- /dev/null
@@ -0,0 +1,6 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ListSyntax7.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ListSyntax7.scl
new file mode 100644 (file)
index 0000000..54cf21c
--- /dev/null
@@ -0,0 +1,6 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ListSyntax8.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ListSyntax8.scl
new file mode 100644 (file)
index 0000000..ac5ce57
--- /dev/null
@@ -0,0 +1,12 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ListSyntax9.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ListSyntax9.scl
new file mode 100644 (file)
index 0000000..83de255
--- /dev/null
@@ -0,0 +1,12 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ListSyntaxWithoutPrelude.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ListSyntaxWithoutPrelude.scl
new file mode 100644 (file)
index 0000000..8806f93
--- /dev/null
@@ -0,0 +1,3 @@
+main = [1 :: Integer,2 :: Integer,3 :: Integer]\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/LocalDefinitions.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/LocalDefinitions.scl
new file mode 100644 (file)
index 0000000..0e4690a
--- /dev/null
@@ -0,0 +1,12 @@
+\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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/LocalDefinitions2.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/LocalDefinitions2.scl
new file mode 100644 (file)
index 0000000..f17a8be
--- /dev/null
@@ -0,0 +1,14 @@
+\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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/LocalDefinitions3.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/LocalDefinitions3.scl
new file mode 100644 (file)
index 0000000..71a193f
--- /dev/null
@@ -0,0 +1,10 @@
+\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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/LocalDefinitions4.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/LocalDefinitions4.scl
new file mode 100644 (file)
index 0000000..fe07e47
--- /dev/null
@@ -0,0 +1,8 @@
+\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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/LocalDefinitions5.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/LocalDefinitions5.scl
new file mode 100644 (file)
index 0000000..97cf72c
--- /dev/null
@@ -0,0 +1,13 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Macros1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Macros1.scl
new file mode 100644 (file)
index 0000000..37b4e05
--- /dev/null
@@ -0,0 +1,8 @@
+@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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Macros2.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Macros2.scl
new file mode 100644 (file)
index 0000000..d1379cd
--- /dev/null
@@ -0,0 +1,13 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Macros3.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Macros3.scl
new file mode 100644 (file)
index 0000000..ec1571d
--- /dev/null
@@ -0,0 +1,16 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Macros4.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Macros4.scl
new file mode 100644 (file)
index 0000000..87e41e0
--- /dev/null
@@ -0,0 +1,12 @@
+@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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Map1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Map1.scl
new file mode 100644 (file)
index 0000000..5d9f38c
--- /dev/null
@@ -0,0 +1,18 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/MarketModel.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/MarketModel.scl
new file mode 100644 (file)
index 0000000..da27b04
--- /dev/null
@@ -0,0 +1,11 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/MarketModel2.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/MarketModel2.scl
new file mode 100644 (file)
index 0000000..bcd576b
--- /dev/null
@@ -0,0 +1,12 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Matching.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Matching.scl
new file mode 100644 (file)
index 0000000..f240a1c
--- /dev/null
@@ -0,0 +1,19 @@
+\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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Matching2.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Matching2.scl
new file mode 100644 (file)
index 0000000..c71b98b
--- /dev/null
@@ -0,0 +1,9 @@
+\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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Matching3.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Matching3.scl
new file mode 100644 (file)
index 0000000..904a843
--- /dev/null
@@ -0,0 +1,10 @@
+\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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Matching3b.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Matching3b.scl
new file mode 100644 (file)
index 0000000..4864345
--- /dev/null
@@ -0,0 +1,8 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Matching4.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Matching4.scl
new file mode 100644 (file)
index 0000000..8c8812b
--- /dev/null
@@ -0,0 +1,11 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Matching5.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Matching5.scl
new file mode 100644 (file)
index 0000000..61723e8
--- /dev/null
@@ -0,0 +1,5 @@
+main = do \r
+    match () with\r
+        () -> "Hello"\r
+--\r
+Hello
\ No newline at end of file
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/MatchingWithMissingParameter.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/MatchingWithMissingParameter.scl
new file mode 100644 (file)
index 0000000..33a681f
--- /dev/null
@@ -0,0 +1,10 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/MatchingWithoutTypeAnnotations.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/MatchingWithoutTypeAnnotations.scl
new file mode 100644 (file)
index 0000000..80d1477
--- /dev/null
@@ -0,0 +1,10 @@
+\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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/MaximumBy.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/MaximumBy.scl
new file mode 100644 (file)
index 0000000..c70c9da
--- /dev/null
@@ -0,0 +1,10 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Maybe1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Maybe1.scl
new file mode 100644 (file)
index 0000000..98a7d71
--- /dev/null
@@ -0,0 +1,6 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Maybe2.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Maybe2.scl
new file mode 100644 (file)
index 0000000..0bc50fb
--- /dev/null
@@ -0,0 +1,6 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Maybe3.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Maybe3.scl
new file mode 100644 (file)
index 0000000..8a0f120
--- /dev/null
@@ -0,0 +1,6 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Maybe4.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Maybe4.scl
new file mode 100644 (file)
index 0000000..53e3ed3
--- /dev/null
@@ -0,0 +1,18 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/MissingEffect.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/MissingEffect.scl
new file mode 100644 (file)
index 0000000..9a5ea98
--- /dev/null
@@ -0,0 +1,15 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/MissingMethod.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/MissingMethod.scl
new file mode 100644 (file)
index 0000000..d5b1b27
--- /dev/null
@@ -0,0 +1,12 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/MissingTypeParameter.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/MissingTypeParameter.scl
new file mode 100644 (file)
index 0000000..fc40ab9
--- /dev/null
@@ -0,0 +1,6 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ModuleInitialization.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ModuleInitialization.scl
new file mode 100644 (file)
index 0000000..bd3dfa1
--- /dev/null
@@ -0,0 +1,11 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/MonadBug1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/MonadBug1.scl
new file mode 100644 (file)
index 0000000..44ddf00
--- /dev/null
@@ -0,0 +1,10 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/MonadSyntax1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/MonadSyntax1.scl
new file mode 100644 (file)
index 0000000..94774a4
--- /dev/null
@@ -0,0 +1,11 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/MonadSyntax2.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/MonadSyntax2.scl
new file mode 100644 (file)
index 0000000..6244a61
--- /dev/null
@@ -0,0 +1,12 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Monads1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Monads1.scl
new file mode 100644 (file)
index 0000000..90115d3
--- /dev/null
@@ -0,0 +1,8 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/NoDefinitionErrorMessage.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/NoDefinitionErrorMessage.scl
new file mode 100644 (file)
index 0000000..8597a78
--- /dev/null
@@ -0,0 +1,7 @@
+// 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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/NoInstance.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/NoInstance.scl
new file mode 100644 (file)
index 0000000..4bc5cab
--- /dev/null
@@ -0,0 +1,9 @@
+\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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/NoInstance2.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/NoInstance2.scl
new file mode 100644 (file)
index 0000000..9490a82
--- /dev/null
@@ -0,0 +1,10 @@
+\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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/NonassociativeOperator.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/NonassociativeOperator.scl
new file mode 100644 (file)
index 0000000..f2b473a
--- /dev/null
@@ -0,0 +1,7 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/NonexistentTypeClassInAnnotation.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/NonexistentTypeClassInAnnotation.scl
new file mode 100644 (file)
index 0000000..4030639
--- /dev/null
@@ -0,0 +1,9 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/NonexistingEffect.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/NonexistingEffect.scl
new file mode 100644 (file)
index 0000000..8ed51f9
--- /dev/null
@@ -0,0 +1,6 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/OneLineMatch.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/OneLineMatch.scl
new file mode 100644 (file)
index 0000000..3f16b07
--- /dev/null
@@ -0,0 +1,6 @@
+// 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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/OpenString1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/OpenString1.scl
new file mode 100644 (file)
index 0000000..e8a7c4c
--- /dev/null
@@ -0,0 +1,3 @@
+"asd \r
+--\r
+1:1-1:6: Unclosed string literal.
\ No newline at end of file
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/OpenString2.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/OpenString2.scl
new file mode 100644 (file)
index 0000000..31953cc
--- /dev/null
@@ -0,0 +1,6 @@
+"asd \r
+\r
+\r
+asd\r
+--\r
+1:1-1:6: Unclosed string literal.
\ No newline at end of file
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/OverloadedArithmetic1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/OverloadedArithmetic1.scl
new file mode 100644 (file)
index 0000000..de083e8
--- /dev/null
@@ -0,0 +1,17 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/OverloadedArithmetic2.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/OverloadedArithmetic2.scl
new file mode 100644 (file)
index 0000000..1619f58
--- /dev/null
@@ -0,0 +1,20 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/OverloadedArithmetic3.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/OverloadedArithmetic3.scl
new file mode 100644 (file)
index 0000000..230e486
--- /dev/null
@@ -0,0 +1,27 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/OverloadedLiterals2.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/OverloadedLiterals2.scl
new file mode 100644 (file)
index 0000000..c167097
--- /dev/null
@@ -0,0 +1,9 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Overloading1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Overloading1.scl
new file mode 100644 (file)
index 0000000..dfb6079
--- /dev/null
@@ -0,0 +1,19 @@
+// 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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Overloading2.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Overloading2.scl
new file mode 100644 (file)
index 0000000..e7a28de
--- /dev/null
@@ -0,0 +1,20 @@
+// 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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Overloading3.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Overloading3.scl
new file mode 100644 (file)
index 0000000..9385ce7
--- /dev/null
@@ -0,0 +1,23 @@
+// 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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Parsing.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Parsing.scl
new file mode 100644 (file)
index 0000000..0ca342a
--- /dev/null
@@ -0,0 +1,62 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/PatternError.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/PatternError.scl
new file mode 100644 (file)
index 0000000..ce417af
--- /dev/null
@@ -0,0 +1,22 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/PolymorphicRecursion.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/PolymorphicRecursion.scl
new file mode 100644 (file)
index 0000000..ed84193
--- /dev/null
@@ -0,0 +1,16 @@
+// 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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/PolymorphicRecursion2.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/PolymorphicRecursion2.scl
new file mode 100644 (file)
index 0000000..44738e0
--- /dev/null
@@ -0,0 +1,12 @@
+\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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Polynomials.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Polynomials.scl
new file mode 100644 (file)
index 0000000..5e35b94
--- /dev/null
@@ -0,0 +1,50 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/PrecedenceOfNonoperators.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/PrecedenceOfNonoperators.scl
new file mode 100644 (file)
index 0000000..3321e89
--- /dev/null
@@ -0,0 +1,9 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Primes.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Primes.scl
new file mode 100644 (file)
index 0000000..830186b
--- /dev/null
@@ -0,0 +1,24 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Proc1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Proc1.scl
new file mode 100644 (file)
index 0000000..b91eed3
--- /dev/null
@@ -0,0 +1,8 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Proc2.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Proc2.scl
new file mode 100644 (file)
index 0000000..bd8021b
--- /dev/null
@@ -0,0 +1,29 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Proc3.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Proc3.scl
new file mode 100644 (file)
index 0000000..4a17fe4
--- /dev/null
@@ -0,0 +1,16 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Pythagoras.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Pythagoras.scl
new file mode 100644 (file)
index 0000000..95a5b9b
--- /dev/null
@@ -0,0 +1,24 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Random1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Random1.scl
new file mode 100644 (file)
index 0000000..66922ea
--- /dev/null
@@ -0,0 +1,19 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/RangeSyntax.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/RangeSyntax.scl
new file mode 100644 (file)
index 0000000..6622552
--- /dev/null
@@ -0,0 +1,5 @@
+import "Prelude"\r
+\r
+main = [5..9]\r
+--\r
+[5, 6, 7, 8, 9]
\ No newline at end of file
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Record1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Record1.scl
new file mode 100644 (file)
index 0000000..fcfbf6a
--- /dev/null
@@ -0,0 +1,9 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/RecordShorthand.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/RecordShorthand.scl
new file mode 100644 (file)
index 0000000..d3af73e
--- /dev/null
@@ -0,0 +1,11 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/RecursiveContext.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/RecursiveContext.scl
new file mode 100644 (file)
index 0000000..7412862
--- /dev/null
@@ -0,0 +1,23 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/RecursiveValues.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/RecursiveValues.scl
new file mode 100644 (file)
index 0000000..5548520
--- /dev/null
@@ -0,0 +1,6 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/RecursiveValues2.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/RecursiveValues2.scl
new file mode 100644 (file)
index 0000000..7291bb9
--- /dev/null
@@ -0,0 +1,5 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/RecursiveValues3.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/RecursiveValues3.scl
new file mode 100644 (file)
index 0000000..020a967
--- /dev/null
@@ -0,0 +1,12 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/RecursiveValues4.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/RecursiveValues4.scl
new file mode 100644 (file)
index 0000000..0315be3
--- /dev/null
@@ -0,0 +1,5 @@
+(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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/RedBlackTrees.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/RedBlackTrees.scl
new file mode 100644 (file)
index 0000000..6f47bd0
--- /dev/null
@@ -0,0 +1,101 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Relations1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Relations1.scl
new file mode 100644 (file)
index 0000000..b15c1b8
--- /dev/null
@@ -0,0 +1,18 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Relations2.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Relations2.scl
new file mode 100644 (file)
index 0000000..825685e
--- /dev/null
@@ -0,0 +1,12 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/RepeatedVariableInPattern.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/RepeatedVariableInPattern.scl
new file mode 100644 (file)
index 0000000..8e5cf08
--- /dev/null
@@ -0,0 +1,6 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/SSATypingBug.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/SSATypingBug.scl
new file mode 100644 (file)
index 0000000..15ff012
--- /dev/null
@@ -0,0 +1,11 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Scanl.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Scanl.scl
new file mode 100644 (file)
index 0000000..67821dd
--- /dev/null
@@ -0,0 +1,14 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Search.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Search.scl
new file mode 100644 (file)
index 0000000..352e92c
--- /dev/null
@@ -0,0 +1,47 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Sections.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Sections.scl
new file mode 100644 (file)
index 0000000..2d7e576
--- /dev/null
@@ -0,0 +1,5 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Select1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Select1.scl
new file mode 100644 (file)
index 0000000..f8d0359
--- /dev/null
@@ -0,0 +1,11 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Select2.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Select2.scl
new file mode 100644 (file)
index 0000000..a492823
--- /dev/null
@@ -0,0 +1,20 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Select3.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Select3.scl
new file mode 100644 (file)
index 0000000..a3e4f44
--- /dev/null
@@ -0,0 +1,18 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Select4.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Select4.scl
new file mode 100644 (file)
index 0000000..3199e95
--- /dev/null
@@ -0,0 +1,18 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Select5.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Select5.scl
new file mode 100644 (file)
index 0000000..1817247
--- /dev/null
@@ -0,0 +1,11 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Select6.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Select6.scl
new file mode 100644 (file)
index 0000000..84e4df3
--- /dev/null
@@ -0,0 +1,6 @@
+import "StandardLibrary"
+
+main = select ?x where
+    (?x,?y) = (1,2)
+--
+[1]
\ No newline at end of file
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Select7.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Select7.scl
new file mode 100644 (file)
index 0000000..b0be01a
--- /dev/null
@@ -0,0 +1,6 @@
+import "StandardLibrary"
+
+main = select ?x where
+    (?x, 3) <- [(1,2),(2,3),(3,4)]
+--
+[2]
\ No newline at end of file
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Select8.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Select8.scl
new file mode 100644 (file)
index 0000000..7877044
--- /dev/null
@@ -0,0 +1,10 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Select9.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Select9.scl
new file mode 100644 (file)
index 0000000..5680679
--- /dev/null
@@ -0,0 +1,12 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/SelfReferringContextInTypeClass.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/SelfReferringContextInTypeClass.scl
new file mode 100644 (file)
index 0000000..d2f1bd7
--- /dev/null
@@ -0,0 +1,6 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Serialization.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Serialization.scl
new file mode 100644 (file)
index 0000000..e0d44e3
--- /dev/null
@@ -0,0 +1,14 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Serialization2.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Serialization2.scl
new file mode 100644 (file)
index 0000000..8384527
--- /dev/null
@@ -0,0 +1,14 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Serialization3.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Serialization3.scl
new file mode 100644 (file)
index 0000000..d883dfe
--- /dev/null
@@ -0,0 +1,22 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Set1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Set1.scl
new file mode 100644 (file)
index 0000000..b868ecf
--- /dev/null
@@ -0,0 +1,9 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/SharedTypeVariable.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/SharedTypeVariable.scl
new file mode 100644 (file)
index 0000000..19fd565
--- /dev/null
@@ -0,0 +1,8 @@
+// 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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ShortcutFusion.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ShortcutFusion.scl
new file mode 100644 (file)
index 0000000..6423ecb
--- /dev/null
@@ -0,0 +1,25 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Show1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Show1.scl
new file mode 100644 (file)
index 0000000..649f3cb
--- /dev/null
@@ -0,0 +1,5 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Signals.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Signals.scl
new file mode 100644 (file)
index 0000000..726a3f5
--- /dev/null
@@ -0,0 +1,34 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/SinConst1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/SinConst1.scl
new file mode 100644 (file)
index 0000000..66621b1
--- /dev/null
@@ -0,0 +1,5 @@
+import "Prelude"\r
+\r
+main = (sin + const 1) 0\r
+--\r
+1.0
\ No newline at end of file
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Sort.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Sort.scl
new file mode 100644 (file)
index 0000000..7efdf89
--- /dev/null
@@ -0,0 +1,6 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Sort2.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Sort2.scl
new file mode 100644 (file)
index 0000000..8518264
--- /dev/null
@@ -0,0 +1,19 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/SpecConstr1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/SpecConstr1.scl
new file mode 100644 (file)
index 0000000..4ff7d47
--- /dev/null
@@ -0,0 +1,25 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/StackTrace.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/StackTrace.scl
new file mode 100644 (file)
index 0000000..fe30fa3
--- /dev/null
@@ -0,0 +1,3 @@
+main = fail "badly"
+--
+???
\ No newline at end of file
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/StreamFusion.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/StreamFusion.scl
new file mode 100644 (file)
index 0000000..6d1864a
--- /dev/null
@@ -0,0 +1,139 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/StringEscape.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/StringEscape.scl
new file mode 100644 (file)
index 0000000..51a75d3
--- /dev/null
@@ -0,0 +1,12 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/StringInterpolation1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/StringInterpolation1.scl
new file mode 100644 (file)
index 0000000..eabad78
--- /dev/null
@@ -0,0 +1,9 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/StringInterpolation2.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/StringInterpolation2.scl
new file mode 100644 (file)
index 0000000..9d21943
--- /dev/null
@@ -0,0 +1,6 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/StringMatching1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/StringMatching1.scl
new file mode 100644 (file)
index 0000000..5865926
--- /dev/null
@@ -0,0 +1,7 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/SumOfInverses2.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/SumOfInverses2.scl
new file mode 100644 (file)
index 0000000..d3cacba
--- /dev/null
@@ -0,0 +1,8 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Timing.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Timing.scl
new file mode 100644 (file)
index 0000000..deb6d50
--- /dev/null
@@ -0,0 +1,10 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/TooManyParametersToSin.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/TooManyParametersToSin.scl
new file mode 100644 (file)
index 0000000..bfaf3db
--- /dev/null
@@ -0,0 +1,6 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Transformation1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Transformation1.scl
new file mode 100644 (file)
index 0000000..144b031
--- /dev/null
@@ -0,0 +1,59 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Transformation2.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Transformation2.scl
new file mode 100644 (file)
index 0000000..dbb1609
--- /dev/null
@@ -0,0 +1,25 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Transformation3.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Transformation3.scl
new file mode 100644 (file)
index 0000000..f9b995c
--- /dev/null
@@ -0,0 +1,32 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Transformation4.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Transformation4.scl
new file mode 100644 (file)
index 0000000..5a889e1
--- /dev/null
@@ -0,0 +1,27 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Transformation5.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Transformation5.scl
new file mode 100644 (file)
index 0000000..e041430
--- /dev/null
@@ -0,0 +1,22 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Transformation6.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Transformation6.scl
new file mode 100644 (file)
index 0000000..74aed46
--- /dev/null
@@ -0,0 +1,15 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Transformation7.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Transformation7.scl
new file mode 100644 (file)
index 0000000..cce48f6
--- /dev/null
@@ -0,0 +1,14 @@
+import "StandardLibrary"
+
+Foo ?x :- 
+    @enforce
+    Execute (iterList printString [?x :: String])
+
+    
+rule DoIt where
+    @to
+    Foo "Hello world!"
+
+main = transformation OneShotForward where
+--
+()
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/TransformationOrder.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/TransformationOrder.scl
new file mode 100644 (file)
index 0000000..36c08c7
--- /dev/null
@@ -0,0 +1,17 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Tuples.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Tuples.scl
new file mode 100644 (file)
index 0000000..5f70e4b
--- /dev/null
@@ -0,0 +1,18 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Tuples2.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Tuples2.scl
new file mode 100644 (file)
index 0000000..75b4785
--- /dev/null
@@ -0,0 +1,6 @@
+// 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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/TypeAlias1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/TypeAlias1.scl
new file mode 100644 (file)
index 0000000..3aad9bf
--- /dev/null
@@ -0,0 +1,9 @@
+\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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/TypeAlias2.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/TypeAlias2.scl
new file mode 100644 (file)
index 0000000..6192515
--- /dev/null
@@ -0,0 +1,8 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/TypeAlias3.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/TypeAlias3.scl
new file mode 100644 (file)
index 0000000..b25a8ab
--- /dev/null
@@ -0,0 +1,9 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/TypeAliasRefsToTypeAlias.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/TypeAliasRefsToTypeAlias.scl
new file mode 100644 (file)
index 0000000..7ebb606
--- /dev/null
@@ -0,0 +1,22 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/TypeAnnotation1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/TypeAnnotation1.scl
new file mode 100644 (file)
index 0000000..5ba565f
--- /dev/null
@@ -0,0 +1,5 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/TypeAnnotation2.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/TypeAnnotation2.scl
new file mode 100644 (file)
index 0000000..ab855f8
--- /dev/null
@@ -0,0 +1,5 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/TypeClass.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/TypeClass.scl
new file mode 100644 (file)
index 0000000..540d44e
--- /dev/null
@@ -0,0 +1,10 @@
+\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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/TypeClass2.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/TypeClass2.scl
new file mode 100644 (file)
index 0000000..5bd0935
--- /dev/null
@@ -0,0 +1,28 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/TypeClassBug1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/TypeClassBug1.scl
new file mode 100644 (file)
index 0000000..2ea51be
--- /dev/null
@@ -0,0 +1,19 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/TypeClassBug2.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/TypeClassBug2.scl
new file mode 100644 (file)
index 0000000..a341ba6
--- /dev/null
@@ -0,0 +1,54 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/TypeInferenceBug2.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/TypeInferenceBug2.scl
new file mode 100644 (file)
index 0000000..4fa08a5
--- /dev/null
@@ -0,0 +1,9 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/TypeOf1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/TypeOf1.scl
new file mode 100644 (file)
index 0000000..933a29b
--- /dev/null
@@ -0,0 +1,5 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/TypingBug1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/TypingBug1.scl
new file mode 100644 (file)
index 0000000..3e69ebf
--- /dev/null
@@ -0,0 +1,4 @@
+id x = x\r
+main = id id (5 :: Integer)\r
+--\r
+5
\ No newline at end of file
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/TypingError1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/TypingError1.scl
new file mode 100644 (file)
index 0000000..9f39243
--- /dev/null
@@ -0,0 +1,9 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/TypingError2.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/TypingError2.scl
new file mode 100644 (file)
index 0000000..7632ffc
--- /dev/null
@@ -0,0 +1,9 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/UnaryMinus.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/UnaryMinus.scl
new file mode 100644 (file)
index 0000000..ff0e512
--- /dev/null
@@ -0,0 +1,5 @@
+import "Prelude"\r
+\r
+main = -5\r
+--\r
+-5
\ No newline at end of file
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/UndefinedValue.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/UndefinedValue.scl
new file mode 100644 (file)
index 0000000..02de8b6
--- /dev/null
@@ -0,0 +1,6 @@
+\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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/UnexpectedToken.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/UnexpectedToken.scl
new file mode 100644 (file)
index 0000000..270d575
--- /dev/null
@@ -0,0 +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
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Unification1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Unification1.scl
new file mode 100644 (file)
index 0000000..a174362
--- /dev/null
@@ -0,0 +1,28 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/UnknownAnnotation.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/UnknownAnnotation.scl
new file mode 100644 (file)
index 0000000..c1b5ef8
--- /dev/null
@@ -0,0 +1,5 @@
+\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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/UnresolvedClass.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/UnresolvedClass.scl
new file mode 100644 (file)
index 0000000..0e1765c
--- /dev/null
@@ -0,0 +1,8 @@
+\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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/UnresolvedTypeInAnnotation.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/UnresolvedTypeInAnnotation.scl
new file mode 100644 (file)
index 0000000..18e0751
--- /dev/null
@@ -0,0 +1,4 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/UnresolvedTypeInInstance.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/UnresolvedTypeInInstance.scl
new file mode 100644 (file)
index 0000000..1b5400c
--- /dev/null
@@ -0,0 +1,9 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/UnresolvedVariable.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/UnresolvedVariable.scl
new file mode 100644 (file)
index 0000000..ad28907
--- /dev/null
@@ -0,0 +1,4 @@
+a = b\r
+\r
+--\r
+1:5-1:6: Couldn't resolve variable b.
\ No newline at end of file
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/UnresolvedVariable2.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/UnresolvedVariable2.scl
new file mode 100644 (file)
index 0000000..32438cd
--- /dev/null
@@ -0,0 +1,7 @@
+\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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ValueAsOperator.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ValueAsOperator.scl
new file mode 100644 (file)
index 0000000..3723537
--- /dev/null
@@ -0,0 +1,8 @@
+\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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ValueConversion.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/ValueConversion.scl
new file mode 100644 (file)
index 0000000..3afda1b
--- /dev/null
@@ -0,0 +1,6 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Vector1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Vector1.scl
new file mode 100644 (file)
index 0000000..33b6c86
--- /dev/null
@@ -0,0 +1,8 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Vector2.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Vector2.scl
new file mode 100644 (file)
index 0000000..43c0c53
--- /dev/null
@@ -0,0 +1,8 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Void1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Void1.scl
new file mode 100644 (file)
index 0000000..40a710f
--- /dev/null
@@ -0,0 +1,16 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Void2.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Void2.scl
new file mode 100644 (file)
index 0000000..f953aaf
--- /dev/null
@@ -0,0 +1,13 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Void3.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Void3.scl
new file mode 100644 (file)
index 0000000..0530c8a
--- /dev/null
@@ -0,0 +1,12 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/While.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/While.scl
new file mode 100644 (file)
index 0000000..3e45043
--- /dev/null
@@ -0,0 +1,10 @@
+\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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/While2.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/While2.scl
new file mode 100644 (file)
index 0000000..6567c22
--- /dev/null
@@ -0,0 +1,12 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/While3.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/While3.scl
new file mode 100644 (file)
index 0000000..0520769
--- /dev/null
@@ -0,0 +1,11 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/WrongDefaultMethod.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/WrongDefaultMethod.scl
new file mode 100644 (file)
index 0000000..d94046b
--- /dev/null
@@ -0,0 +1,8 @@
+\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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/WrongInstanceMethod.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/WrongInstanceMethod.scl
new file mode 100644 (file)
index 0000000..2cdc4e8
--- /dev/null
@@ -0,0 +1,11 @@
+\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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scripts/Arithmetic.sts b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scripts/Arithmetic.sts
new file mode 100644 (file)
index 0000000..e8f7dce
--- /dev/null
@@ -0,0 +1,12 @@
+> 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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scripts/Functions.sts b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scripts/Functions.sts
new file mode 100644 (file)
index 0000000..76348b8
--- /dev/null
@@ -0,0 +1,20 @@
+> 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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scripts/Functions2.sts b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scripts/Functions2.sts
new file mode 100644 (file)
index 0000000..9879931
--- /dev/null
@@ -0,0 +1,5 @@
+> f x = x + 1
+> f 3
+4
+> f 4.5
+5.5
\ No newline at end of file
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scripts/Lists.sts b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scripts/Lists.sts
new file mode 100644 (file)
index 0000000..024db24
--- /dev/null
@@ -0,0 +1,5 @@
+> [1,2,3]
+[1, 2, 3]
+
+> [5..9]
+[5, 6, 7, 8, 9]
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/unit/TestNamespaceFilter.java b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/unit/TestNamespaceFilter.java
new file mode 100644 (file)
index 0000000..fa3bd9f
--- /dev/null
@@ -0,0 +1,89 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/unit/TestSubSolver.java b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/unit/TestSubSolver.java
new file mode 100644 (file)
index 0000000..87b9eeb
--- /dev/null
@@ -0,0 +1,37 @@
+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/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/unit/TestTypeParser.java b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/unit/TestTypeParser.java
new file mode 100644 (file)
index 0000000..5ce3690
--- /dev/null
@@ -0,0 +1,25 @@
+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
diff --git a/tests/org.simantics.scl.osgi.tests/.classpath b/tests/org.simantics.scl.osgi.tests/.classpath
new file mode 100644 (file)
index 0000000..b862a29
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<classpath>\r
+       <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="output" path="bin"/>\r
+</classpath>\r
diff --git a/tests/org.simantics.scl.osgi.tests/.project b/tests/org.simantics.scl.osgi.tests/.project
new file mode 100644 (file)
index 0000000..d9af653
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<projectDescription>\r
+       <name>org.simantics.scl.osgi.tests</name>\r
+       <comment></comment>\r
+       <projects>\r
+       </projects>\r
+       <buildSpec>\r
+               <buildCommand>\r
+                       <name>org.eclipse.jdt.core.javabuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+               <buildCommand>\r
+                       <name>org.eclipse.pde.ManifestBuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+               <buildCommand>\r
+                       <name>org.eclipse.pde.SchemaBuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+       </buildSpec>\r
+       <natures>\r
+               <nature>org.eclipse.pde.PluginNature</nature>\r
+               <nature>org.eclipse.jdt.core.javanature</nature>\r
+       </natures>\r
+</projectDescription>\r
diff --git a/tests/org.simantics.scl.osgi.tests/.settings/org.eclipse.jdt.core.prefs b/tests/org.simantics.scl.osgi.tests/.settings/org.eclipse.jdt.core.prefs
new file mode 100644 (file)
index 0000000..295926d
--- /dev/null
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1\r
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled\r
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8\r
+org.eclipse.jdt.core.compiler.compliance=1.8\r
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error\r
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error\r
+org.eclipse.jdt.core.compiler.source=1.8\r
diff --git a/tests/org.simantics.scl.osgi.tests/META-INF/MANIFEST.MF b/tests/org.simantics.scl.osgi.tests/META-INF/MANIFEST.MF
new file mode 100644 (file)
index 0000000..da7e1c6
--- /dev/null
@@ -0,0 +1,16 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Tests
+Bundle-SymbolicName: org.simantics.scl.osgi.tests
+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.objectweb.asm.util,
+ org.eclipse.equinox.ds;bundle-version="1.4.300",
+ org.simantics;bundle-version="1.0.0",
+ org.simantics.acorn;bundle-version="1.1.2",
+ org.simantics.workbench;bundle-version="1.5.1",
+ org.simantics.application
diff --git a/tests/org.simantics.scl.osgi.tests/build.properties b/tests/org.simantics.scl.osgi.tests/build.properties
new file mode 100644 (file)
index 0000000..41eb6ad
--- /dev/null
@@ -0,0 +1,4 @@
+source.. = src/\r
+output.. = bin/\r
+bin.includes = META-INF/,\\r
+               .\r
diff --git a/tests/org.simantics.scl.osgi.tests/pom.xml b/tests/org.simantics.scl.osgi.tests/pom.xml
new file mode 100644 (file)
index 0000000..f22ff33
--- /dev/null
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
+    <modelVersion>4.0.0</modelVersion>\r
+    <groupId>org.simantics</groupId>\r
+    <artifactId>org.simantics.scl.osgi.tests</artifactId>\r
+    <version>1.0.0-SNAPSHOT</version>\r
+    <packaging>eclipse-test-plugin</packaging>\r
+\r
+    <parent>\r
+        <groupId>org.simantics</groupId>\r
+        <artifactId>org.simantics.root.tests</artifactId>\r
+        <version>1.0.0-SNAPSHOT</version>\r
+    </parent>\r
+\r
+    <build>\r
+        <plugins>\r
+            <plugin>\r
+                <groupId>org.eclipse.tycho</groupId>\r
+                <artifactId>target-platform-configuration</artifactId>\r
+                <configuration>\r
+                    <dependency-resolution>\r
+                        <extraRequirements>\r
+                            <requirement>\r
+                                <type>eclipse-feature</type>\r
+                                <id>org.simantics.sdk</id>\r
+                                <versionRange>0.0.0</versionRange>\r
+                            </requirement>\r
+                        </extraRequirements>\r
+                    </dependency-resolution>\r
+                </configuration>\r
+            </plugin>\r
+            <plugin>\r
+                <groupId>org.eclipse.tycho</groupId>\r
+                <artifactId>tycho-surefire-plugin</artifactId>\r
+                <version>${tycho.version}</version>\r
+                <configuration>\r
+                </configuration>\r
+            </plugin>\r
+        </plugins>\r
+    </build>\r
+</project>\r
diff --git a/tests/org.simantics.scl.osgi.tests/src/org/simantics/scl/osgi/tests/TestSCLOsgi.java b/tests/org.simantics.scl.osgi.tests/src/org/simantics/scl/osgi/tests/TestSCLOsgi.java
new file mode 100644 (file)
index 0000000..35a74c4
--- /dev/null
@@ -0,0 +1,75 @@
+package org.simantics.scl.osgi.tests;\r
+\r
+import java.util.ArrayList;\r
+import java.util.concurrent.atomic.AtomicInteger;\r
+\r
+import org.eclipse.core.runtime.IProgressMonitor;\r
+import org.eclipse.core.runtime.NullProgressMonitor;\r
+import org.junit.AfterClass;\r
+import org.junit.Assert;\r
+import org.junit.BeforeClass;\r
+import org.junit.Test;\r
+import org.simantics.PlatformException;\r
+import org.simantics.Simantics;\r
+import org.simantics.application.arguments.Arguments;\r
+import org.simantics.application.arguments.IArgumentFactory;\r
+import org.simantics.application.arguments.IArguments;\r
+import org.simantics.application.arguments.SimanticsArguments;\r
+import org.simantics.scl.compiler.errors.DoesNotExist;\r
+import org.simantics.scl.compiler.errors.Failable;\r
+import org.simantics.scl.compiler.module.Module;\r
+import org.simantics.scl.osgi.SCLOsgi;\r
+\r
+import gnu.trove.procedure.TObjectProcedure;\r
+\r
+\r
+public class TestSCLOsgi {\r
+    private static IProgressMonitor progress = new NullProgressMonitor();\r
+    \r
+    @BeforeClass\r
+    public static void setupDatabase() throws PlatformException {\r
+        String[] args = new String[0];\r
+        IArgumentFactory<?>[] accepted = {\r
+                SimanticsArguments.RECOVERY_POLICY_FIX_ERRORS,\r
+                SimanticsArguments.ONTOLOGY_RECOVERY_POLICY_REINSTALL,\r
+                SimanticsArguments.SERVER,\r
+                SimanticsArguments.LOCAL_SERVER_PORT,\r
+        };\r
+        IArguments arguments = Arguments.parse(args, accepted);\r
+        Simantics.startUpHeadless(arguments, progress);\r
+    }\r
+    \r
+    @AfterClass\r
+    public static void teardownDatabase() throws PlatformException {\r
+        Simantics.shutdown(progress);\r
+    }\r
+    \r
+    @Test\r
+    public void testDataJsonExists() {\r
+        ArrayList<String> modulesWithErrors = new ArrayList<String>(); \r
+        SCLOsgi.SOURCE_REPOSITORY.forAllModules(new TObjectProcedure<String>() {\r
+            @Override\r
+            public boolean execute(String moduleName) {\r
+                System.out.print(moduleName);\r
+                System.out.print(" - ");\r
+                Failable<Module> module = SCLOsgi.MODULE_REPOSITORY.getModule(moduleName);\r
+                if(module.didSucceed())\r
+                    System.out.println("succeeded");\r
+                else if(module == DoesNotExist.INSTANCE)\r
+                    System.out.println("does not exist"); // should not happen\r
+                else {\r
+                    System.out.println("error");\r
+                    modulesWithErrors.add(moduleName);\r
+                }\r
+                return true;\r
+            }\r
+        });\r
+        if(!modulesWithErrors.isEmpty()) {\r
+            StringBuilder b = new StringBuilder();\r
+            b.append("Some SCL modules failed to compile:");\r
+            for(String module : modulesWithErrors)\r
+                b.append(' ').append(module);\r
+            Assert.fail(b.toString());\r
+        }\r
+    }\r
+}\r
diff --git a/tests/pom.xml b/tests/pom.xml
new file mode 100644 (file)
index 0000000..20d4c48
--- /dev/null
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
+    <modelVersion>4.0.0</modelVersion>\r
+    <groupId>org.simantics</groupId>\r
+    <artifactId>org.simantics.root.tests</artifactId>\r
+    <version>1.0.0-SNAPSHOT</version>\r
+    <packaging>pom</packaging>\r
+\r
+    <parent>\r
+        <groupId>org.simantics</groupId>\r
+        <artifactId>org.simantics.root</artifactId>\r
+        <version>1.0.0-SNAPSHOT</version>\r
+    </parent>\r
+\r
+    <build>\r
+        <plugins>\r
+            <plugin>\r
+                <groupId>org.eclipse.tycho</groupId>\r
+                <artifactId>tycho-compiler-plugin</artifactId>\r
+                <version>${tycho.version}</version>\r
+                <configuration>\r
+                    <compilerArgument>-err:-forbidden</compilerArgument>\r
+                </configuration>\r
+            </plugin>\r
+        </plugins>\r
+    </build>\r
+\r
+    <modules>\r
+        <module>org.simantics.scl.compiler.tests</module>\r
+        <module>org.simantics.scl.osgi.tests</module>\r
+    </modules>\r
+</project>\r