├── .gitattributes
├── .github
└── workflows
│ └── nix.yml
├── .gitignore
├── .vscode
└── settings.json
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── bin
└── mlscript-opt.js
├── build.sbt
├── compiler
└── shared
│ ├── main
│ └── scala
│ │ └── mlscript
│ │ └── compiler
│ │ ├── ClassLifter.scala
│ │ ├── Document.scala
│ │ ├── PrettyPrinter.scala
│ │ ├── codegen
│ │ ├── CppAst.scala
│ │ ├── CppCodeGen.scala
│ │ └── CppCompilerHost.scala
│ │ ├── debug
│ │ ├── Debug.scala
│ │ ├── DebutOutput.scala
│ │ ├── DummyDebug.scala
│ │ ├── Printable.scala
│ │ ├── RainbowDebug.scala
│ │ └── TreeDebug.scala
│ │ ├── ir
│ │ ├── Builder.scala
│ │ ├── Fresh.scala
│ │ ├── IR.scala
│ │ ├── Interp.scala
│ │ ├── RefResolver.scala
│ │ └── Validator.scala
│ │ ├── optimizer
│ │ ├── Analysis.scala
│ │ └── TailRecOpt.scala
│ │ ├── printer
│ │ └── BlockPrinter.scala
│ │ └── simpledef
│ │ ├── Simpledef.scala
│ │ └── Uid.scala
│ └── test
│ ├── diff-ir
│ ├── Class.mls
│ ├── Currying.mls
│ ├── IR.mls
│ ├── IRComplex.mls
│ ├── IRRec.mls
│ ├── IRTailRec.mls
│ ├── LiftClass.mls
│ ├── LiftFun.mls
│ ├── LiftLambda.mls
│ ├── NuScratch.mls
│ ├── Override.mls
│ ├── cpp
│ │ ├── Makefile
│ │ └── mlsprelude.h
│ └── gcd.mls
│ ├── diff
│ ├── CompilerScratch.mls
│ ├── Defunctionalize
│ │ ├── ClassConstructor.mls
│ │ ├── Classes.mls
│ │ ├── ClosureCapture.mls
│ │ ├── Constructor.mls
│ │ ├── DelayedEvaluation.mls
│ │ ├── Differentiation.mls
│ │ ├── FreeVariables.mls
│ │ ├── FuncsWithParams.mls
│ │ ├── Inheritance.mls
│ │ ├── Lambda.mls
│ │ ├── Lambdas.mls
│ │ ├── ListConstruction.mls
│ │ ├── Modules.mls
│ │ ├── MonoNonLambda.mls
│ │ ├── MonoTupSelect.mls
│ │ ├── MutableParams.mls
│ │ ├── MutualRec.mls
│ │ ├── NewOperator.mls
│ │ ├── NuMono.mls
│ │ ├── ObjFieldAccess.mls
│ │ ├── ObjFields.mls
│ │ ├── ObjMultiFields.mls
│ │ ├── ObjsSelection.mls
│ │ ├── OldMonoList.mls
│ │ ├── Polymorphic.mls
│ │ ├── Record.mls
│ │ ├── RecursiveFunc.mls
│ │ ├── SelfReference.mls
│ │ ├── SimpleClasses.mls
│ │ ├── SimpleConditionals.mls
│ │ ├── SimpleFunc.mls
│ │ ├── Simpledef.mls
│ │ └── TupleSelect.mls
│ └── Lifter
│ │ ├── FunctionTypeAnnotations.mls
│ │ ├── LambLift.mls
│ │ ├── LiftNew.mls
│ │ ├── LiftType.mls
│ │ ├── Lifter.mls
│ │ ├── LifterBlks.mls
│ │ ├── NestedClasses.mls
│ │ ├── NestedFuncs.mls
│ │ ├── ParameterizedInheritance.mls
│ │ └── TypedClassParams.mls
│ └── scala
│ └── mlscript
│ └── compiler
│ ├── Test.scala
│ └── TestIR.scala
├── doc
├── Parsing.md
└── mls-codebase-doc.md
├── flake.lock
├── flake.nix
├── index.css
├── index.html
├── js
└── src
│ └── main
│ └── scala
│ ├── Main.scala
│ └── fansi
│ └── Str.scala
├── local_testing.html
├── package-lock.json
├── package.json
├── project
├── build.properties
└── plugins.sbt
├── shared
└── src
│ ├── main
│ └── scala
│ │ └── mlscript
│ │ ├── ConstraintSolver.scala
│ │ ├── Diagnostic.scala
│ │ ├── JSBackend.scala
│ │ ├── Lexer.scala
│ │ ├── MLParser.scala
│ │ ├── Message.scala
│ │ ├── NewLexer.scala
│ │ ├── NewParser.scala
│ │ ├── NormalForms.scala
│ │ ├── NuTypeDefs.scala
│ │ ├── Parser.scala
│ │ ├── Token.scala
│ │ ├── TypeDefs.scala
│ │ ├── TypeSimplifier.scala
│ │ ├── Typer.scala
│ │ ├── TyperDatatypes.scala
│ │ ├── TyperHelpers.scala
│ │ ├── codegen
│ │ ├── Codegen.scala
│ │ ├── Error.scala
│ │ ├── Polyfill.scala
│ │ ├── QQHelper.scala
│ │ ├── Scope.scala
│ │ ├── Symbol.scala
│ │ └── typescript
│ │ │ └── TsTypegen.scala
│ │ ├── helpers.scala
│ │ ├── package.scala
│ │ ├── pretyper
│ │ ├── Diagnosable.scala
│ │ ├── PreTyper.scala
│ │ ├── Scope.scala
│ │ ├── Symbol.scala
│ │ └── Traceable.scala
│ │ ├── syntax.scala
│ │ ├── ucs
│ │ ├── Desugarer.scala
│ │ ├── context
│ │ │ ├── Context.scala
│ │ │ ├── Matchable.scala
│ │ │ ├── Pattern.scala
│ │ │ └── Scrutinee.scala
│ │ ├── display.scala
│ │ ├── package.scala
│ │ ├── stages
│ │ │ ├── CoverageChecking.scala
│ │ │ ├── Desugaring.scala
│ │ │ ├── Normalization.scala
│ │ │ ├── PartialTerm.scala
│ │ │ ├── PostProcessing.scala
│ │ │ ├── Transformation.scala
│ │ │ └── package.scala
│ │ └── syntax
│ │ │ ├── core.scala
│ │ │ └── source.scala
│ │ └── utils
│ │ ├── FastParseHelpers.scala
│ │ ├── Identity.scala
│ │ ├── Lazy.scala
│ │ ├── algorithms.scala
│ │ ├── package.scala
│ │ └── shorthands.scala
│ └── test
│ ├── diff
│ ├── analysis
│ │ ├── Variance.mls
│ │ └── Weird.mls
│ ├── basics
│ │ ├── AsBindings.fun
│ │ ├── Blocks.fun
│ │ ├── Data.fun
│ │ ├── Datatypes.fun
│ │ ├── Either.fun
│ │ ├── Errors.fun
│ │ ├── ExplicitDatatypes.fun
│ │ ├── Flow.fun
│ │ ├── Intersections.fun
│ │ ├── Iso.fun
│ │ ├── Lambdas.fun
│ │ ├── Literals.fun
│ │ ├── Negations.fun
│ │ ├── Operators.fun
│ │ ├── RecFuns.fun
│ │ ├── Records.fun
│ │ ├── Simplesub1.fun
│ │ ├── Simplesub2.fun
│ │ ├── Slashes.fun
│ │ ├── Tuples.fun
│ │ ├── Twice.fun
│ │ ├── Unions.fun
│ │ └── VerboseErrors.fun
│ ├── codegen
│ │ ├── AuxiliaryConstructors.mls
│ │ ├── Classes.mls
│ │ ├── ConstructorStmt.mls
│ │ ├── Declare.mls
│ │ ├── Escape.mls
│ │ ├── FieldOverride.mls
│ │ ├── IndirectRecursion.mls
│ │ ├── Inheritance.mls
│ │ ├── LogInfo.mls
│ │ ├── MemberInitShadowing.mls
│ │ ├── Mixin.mls
│ │ ├── MixinCapture.mls
│ │ ├── Modules.mls
│ │ ├── MutFields.mls
│ │ ├── NamedArgsCurry.mls
│ │ ├── Nested.mls
│ │ ├── New.mls
│ │ ├── NewClasses.mls
│ │ ├── NewMatching.mls
│ │ ├── NewMutualRef.mls
│ │ ├── NuClasses.mls
│ │ ├── NuFuns.mls
│ │ ├── NuParentheses.mls
│ │ ├── NuReplHost.mls
│ │ ├── ParameterPattern.mls
│ │ ├── Parentheses.mls
│ │ ├── PatternMatch.mls
│ │ ├── Polyfill.mls
│ │ ├── Recursion.mls
│ │ ├── ReplHost.mls
│ │ ├── Res.mls
│ │ ├── Shadowing.mls
│ │ ├── SortClass.mls
│ │ ├── Super.mls
│ │ ├── SymbolicOps.mls
│ │ ├── Terms.mls
│ │ ├── TraitMethods.mls
│ │ ├── TrickyShadowing.mls
│ │ ├── TrickyTerms.mls
│ │ ├── TrickyWiths.mls
│ │ ├── Unicode.mls
│ │ ├── ValLet.mls
│ │ └── While.mls
│ ├── contys
│ │ ├── AbstractBounds.mls
│ │ └── ExplicitConstraints.mls
│ ├── ecoop23
│ │ ├── ComparePointPoly.mls
│ │ ├── ExpressionProblem.mls
│ │ ├── Intro.mls
│ │ ├── PolymorphicVariants.mls
│ │ ├── SimpleRegionDSL_annot.mls
│ │ └── SimpleRegionDSL_raw.mls
│ ├── ex
│ │ ├── RepMin.mls
│ │ └── UnboxedOptions.mls
│ ├── fcp-lit
│ │ ├── Boxy.mls
│ │ ├── CPS_LB.mls
│ │ ├── FreezeML.mls
│ │ ├── GHC-rank-n.mls
│ │ ├── HMF.mls
│ │ ├── HML.mls
│ │ ├── Jim.mls
│ │ ├── Leijen.mls
│ │ ├── MLF.mls
│ │ ├── Misc.mls
│ │ ├── PolyML.mls
│ │ ├── QML.mls
│ │ ├── Stability.mls
│ │ └── variations_PolyML.mls
│ ├── fcp
│ │ ├── AA.mls
│ │ ├── Aleks.mls
│ │ ├── Aliases.mls
│ │ ├── Basics.mls
│ │ ├── Church_CT.mls
│ │ ├── Church_ST.mls
│ │ ├── ConstrainedTypes1.mls
│ │ ├── ConstrainedTypes2.mls
│ │ ├── Demo.mls
│ │ ├── Distrib.mls
│ │ ├── Distrib2.mls
│ │ ├── DistribRight.mls
│ │ ├── DistribUnionInter.mls
│ │ ├── DistribWorsening.mls
│ │ ├── FCPTony.mls
│ │ ├── FCPTony3.mls
│ │ ├── Fiota.mls
│ │ ├── ForallTerms.mls
│ │ ├── FunnyId.mls
│ │ ├── Inst.mls
│ │ ├── InvariantPolyContainer.mls
│ │ ├── ListBuild.mls
│ │ ├── Min1_ex_shallow.mls
│ │ ├── MoreChurch.mls
│ │ ├── NestedDataTypes.mls
│ │ ├── NestedDataTypesGADT.mls
│ │ ├── NoRecursiveTypes.mls
│ │ ├── OCamlList.mls
│ │ ├── OverloadSimplif.mls
│ │ ├── Overloads.mls
│ │ ├── Overloads_Precise.mls
│ │ ├── Paper.mls
│ │ ├── PaperTable.mls
│ │ ├── PolyParams.mls
│ │ ├── PolymorphicTypeAliases.mls
│ │ ├── Proofs.mls
│ │ ├── QML_exist_Classes.mls
│ │ ├── QML_exist_Classes_min.mls
│ │ ├── QML_exist_Records_D.mls
│ │ ├── QML_exist_Records_ND.mls
│ │ ├── QML_exist_Records_min_1.mls
│ │ ├── QML_exist_Records_min_2.mls
│ │ ├── QML_exist_Records_min_3.mls
│ │ ├── QML_exist_nu.mls
│ │ ├── Rank2.mls
│ │ ├── RecExtr.mls
│ │ ├── SelfAppMin.mls
│ │ ├── Simplif.mls
│ │ ├── SkolemErrors.mls
│ │ ├── Skolems.mls
│ │ ├── Skolems2.mls
│ │ ├── Skolems3.mls
│ │ ├── SystemF.mls
│ │ ├── SystemF_2.mls
│ │ ├── ToChurchSimplif_CT.mls
│ │ ├── ToChurchSimplif_ST.mls
│ │ ├── Vec.mls
│ │ └── YicongFCP.mls
│ ├── gadt
│ │ ├── Exp1.mls
│ │ ├── Exp2.mls
│ │ └── ThisMatching.mls
│ ├── gen
│ │ └── genTests_v1-0.14-15-x2.fun
│ ├── mlf-examples
│ │ ├── ex_casparticuliers.mls
│ │ ├── ex_concrete.mls
│ │ ├── ex_demo.mls
│ │ ├── ex_hashtbl.mls
│ │ ├── ex_predicative.mls
│ │ ├── ex_propagate.mls
│ │ ├── ex_rvr_validate.mls
│ │ ├── ex_selfapp.mls
│ │ ├── ex_shallow.mls
│ │ ├── ex_validate.mls
│ │ ├── ex_voir.mls
│ │ ├── ex_vr_validate.mls
│ │ ├── merge_regression_min.mls
│ │ └── variations_ex_hashtbl.mls
│ ├── mlscript
│ │ ├── ADTs.mls
│ │ ├── ADTsRepro.mls
│ │ ├── Addable.mls
│ │ ├── AdtStyle.mls
│ │ ├── AlexJ.mls
│ │ ├── Annoying.mls
│ │ ├── Arrays.mls
│ │ ├── Arrays2.mls
│ │ ├── Ascribe.mls
│ │ ├── Baber.mls
│ │ ├── BadAlias.mls
│ │ ├── BadClasses.mls
│ │ ├── BadInherit.mls
│ │ ├── BadInherit2.mls
│ │ ├── BadInherit2Co.mls
│ │ ├── BadMethods.mls
│ │ ├── BadPolym.mls
│ │ ├── BadTraits.mls
│ │ ├── BadTypes.mls
│ │ ├── Basics.mls
│ │ ├── Boolean.mls
│ │ ├── BooleanFail.mls
│ │ ├── ByNameByValue.mls
│ │ ├── David.mls
│ │ ├── David2.mls
│ │ ├── DavidB.mls
│ │ ├── Didier.mls
│ │ ├── Dmitry.mls
│ │ ├── EitherClasses.mls
│ │ ├── ExplicitVariance.mls
│ │ ├── ExprProb.mls
│ │ ├── ExprProb2.mls
│ │ ├── ExprProb_Inv.mls
│ │ ├── FatNegs.mls
│ │ ├── FunnySubsumptions.mls
│ │ ├── GenericClasses.mls
│ │ ├── GenericClasses2.mls
│ │ ├── Group_2021_12_02.mls
│ │ ├── Group_2022_05_10.mls
│ │ ├── Group_2022_06_09.mls
│ │ ├── HeadOption.mls
│ │ ├── Huawei2.mls
│ │ ├── Inherit.mls
│ │ ├── InheritSimple.mls
│ │ ├── JetBrains.mls
│ │ ├── LetPolym.mls
│ │ ├── LineComments.mls
│ │ ├── Lists.mls
│ │ ├── Luyu.mls
│ │ ├── MLList.mls
│ │ ├── MLTuples.mls
│ │ ├── Match1.mls
│ │ ├── Match2.mls
│ │ ├── Match3.mls
│ │ ├── MatchBool.mls
│ │ ├── MethodAndMatches.mls
│ │ ├── Methods.mls
│ │ ├── Methods2.mls
│ │ ├── Misc.mls
│ │ ├── MiscExtrusion.mls
│ │ ├── Mohammad.mls
│ │ ├── MultiArgs.mls
│ │ ├── Mut.mls
│ │ ├── Mut2.mls
│ │ ├── MutArray.mls
│ │ ├── Neg.mls
│ │ ├── NestedClassArgs.mls
│ │ ├── NestedClassArgs_Co.mls
│ │ ├── NestedMatch.mls
│ │ ├── NestedRecursiveMatch.mls
│ │ ├── OccursCheck.mls
│ │ ├── Ops.mls
│ │ ├── OtherErrors.mls
│ │ ├── Paper.mls
│ │ ├── PolyVariant.mls
│ │ ├── PolyVariantCodeReuse.mls
│ │ ├── Polym.mls
│ │ ├── PolymExtrusion.mls
│ │ ├── PolymorphicExtension.mls
│ │ ├── PreservationFail.mls
│ │ ├── ProvFlows.mls
│ │ ├── Random1.mls
│ │ ├── Random2.mls
│ │ ├── RecDefs.mls
│ │ ├── RecErrors.mls
│ │ ├── RecursiveTypes.mls
│ │ ├── RecursiveTypes2.mls
│ │ ├── References.mls
│ │ ├── Repro.mls
│ │ ├── RigidVariables.mls
│ │ ├── SafeDiv.mls
│ │ ├── Scratch.mls
│ │ ├── SelfNeg.mls
│ │ ├── SelfNegs.mls
│ │ ├── Seqs.mls
│ │ ├── Sequence.mls
│ │ ├── Signatures.mls
│ │ ├── Simple.mls
│ │ ├── SimpleErrors.mls
│ │ ├── SimpleMethods.mls
│ │ ├── Splice.mls
│ │ ├── Stress.mls
│ │ ├── StressDNF.mls
│ │ ├── StressTraits.mls
│ │ ├── StressUgly.mls
│ │ ├── Subsume.mls
│ │ ├── Test.mls
│ │ ├── This.mls
│ │ ├── Ticks.mls
│ │ ├── Tony.mls
│ │ ├── TraitMatching.mls
│ │ ├── Traits.mls
│ │ ├── Trans.mls
│ │ ├── TrickyExtrusion.mls
│ │ ├── TrickySimplif.mls
│ │ ├── Trio.mls
│ │ ├── TupleArray.mls
│ │ ├── TupleArray2.mls
│ │ ├── TypeClasses.mls
│ │ ├── TypeDefs.mls
│ │ ├── TypeRanges.mls
│ │ ├── TypeRefs.mls
│ │ ├── TypeTags.mls
│ │ ├── Undef.mls
│ │ ├── Undefined.mls
│ │ ├── Under.mls
│ │ ├── VarCycles.mls
│ │ ├── Variant-sub-ad-hoc.mls
│ │ ├── Variant-sub.mls
│ │ ├── Weird.mls
│ │ ├── Wildcards.mls
│ │ ├── With.mls
│ │ ├── Yicong.mls
│ │ ├── Yuheng.mls
│ │ ├── i26.mls
│ │ ├── i56.mls
│ │ └── i65.mls
│ ├── nu
│ │ ├── AbstractClasses.mls
│ │ ├── Andong.mls
│ │ ├── Annotations.mls
│ │ ├── ArrayProg.mls
│ │ ├── Ascription.mls
│ │ ├── AuxCtors.mls
│ │ ├── BadAliases.mls
│ │ ├── BadBlocks.mls
│ │ ├── BadClassInherit.mls
│ │ ├── BadClassSignatures.mls
│ │ ├── BadClasses.mls
│ │ ├── BadFieldInit.mls
│ │ ├── BadLets.mls
│ │ ├── BadMixins.mls
│ │ ├── BadScopes.mls
│ │ ├── BadSignatures.mls
│ │ ├── BadSuper.mls
│ │ ├── BadTraits.mls
│ │ ├── BadUCS.mls
│ │ ├── BasicClassInheritance.mls
│ │ ├── BasicClasses.mls
│ │ ├── BasicMixins.mls
│ │ ├── CallByName.mls
│ │ ├── CaseExpr.mls
│ │ ├── ClassField.mls
│ │ ├── ClassInstantiation.mls
│ │ ├── ClassSignatures.mls
│ │ ├── ClassesInMixins.mls
│ │ ├── CommaOperator.mls
│ │ ├── CtorSubtraction.mls
│ │ ├── CycleTypeDefErrors.mls
│ │ ├── Darin.mls
│ │ ├── Dates.mls
│ │ ├── DecLit.mls
│ │ ├── Declarations.mls
│ │ ├── DiamondInherit.mls
│ │ ├── DidierNu.mls
│ │ ├── Eduardo.mls
│ │ ├── EncodedLists.mls
│ │ ├── Eql.mls
│ │ ├── EqlClasses.mls
│ │ ├── Eval.mls
│ │ ├── EvalNegNeg.mls
│ │ ├── ExplicitVariance.mls
│ │ ├── ExpressionProblem_repro.mls
│ │ ├── ExpressionProblem_small.mls
│ │ ├── Extrusion.mls
│ │ ├── FieldRefinement.mls
│ │ ├── FilterMap.mls
│ │ ├── FlatIfThenElse.mls
│ │ ├── FlatIndentFuns.mls
│ │ ├── FlatMonads.mls
│ │ ├── FlatMonads_repro.mls
│ │ ├── FunPatterns.mls
│ │ ├── FunPoly.mls
│ │ ├── FunSigs.mls
│ │ ├── FunnyIndet.mls
│ │ ├── FunnyPoly.mls
│ │ ├── GADTMono.mls
│ │ ├── GenericClassInheritance.mls
│ │ ├── GenericClasses.mls
│ │ ├── GenericMethods.mls
│ │ ├── GenericMixins.mls
│ │ ├── GenericModules.mls
│ │ ├── HeungTung.mls
│ │ ├── Huawei1.mls
│ │ ├── ImplicitMethodPolym.mls
│ │ ├── InferredInheritanceTypeArgs.mls
│ │ ├── InheritanceLevelMismatches.mls
│ │ ├── IntLit.mls
│ │ ├── InterfaceGeneric.mls
│ │ ├── InterfaceMono.mls
│ │ ├── Interfaces.mls
│ │ ├── IntraBlockPolymorphism.mls
│ │ ├── Jonathan.mls
│ │ ├── LamPatterns.mls
│ │ ├── LetRec.mls
│ │ ├── ListConsNil.mls
│ │ ├── LitMatch.mls
│ │ ├── LocalLets.mls
│ │ ├── MIscPoly.mls
│ │ ├── MemberConfusion.mls
│ │ ├── MemberIntersections.mls
│ │ ├── MetaWrap.mls
│ │ ├── Metaprog.mls
│ │ ├── MethodSignatures.mls
│ │ ├── Misc.mls
│ │ ├── MissingImplBug.mls
│ │ ├── MissingTypeArg.mls
│ │ ├── Mixin42.mls
│ │ ├── MixinParameters.mls
│ │ ├── ModuleParameters.mls
│ │ ├── Mut.mls
│ │ ├── MutLet.mls
│ │ ├── MutualRec.mls
│ │ ├── NamedArgs.mls
│ │ ├── NestedClasses.mls
│ │ ├── NestedRecords.mls
│ │ ├── New.mls
│ │ ├── NewNew.mls
│ │ ├── NoThisCtor.mls
│ │ ├── NuAlexJ.mls
│ │ ├── NuForallTerms.mls
│ │ ├── NuPolymorphicTypeAliases.mls
│ │ ├── NuScratch.mls
│ │ ├── Numbers.mls
│ │ ├── Object.mls
│ │ ├── OpLam.mls
│ │ ├── OptionFilter.mls
│ │ ├── OverrideShorthand.mls
│ │ ├── ParamImplementing.mls
│ │ ├── ParamOverride.mls
│ │ ├── ParamOverriding.mls
│ │ ├── ParamPassing.mls
│ │ ├── Parens.mls
│ │ ├── PartialApp.mls
│ │ ├── PolymorphicVariants_Alt.mls
│ │ ├── PostHocMixinSignature.mls
│ │ ├── PrivateMemberOverriding.mls
│ │ ├── RawUnionTraitSignatures.mls
│ │ ├── Ref.mls
│ │ ├── RefinedPattern.mls
│ │ ├── Refinements.mls
│ │ ├── Res.mls
│ │ ├── RightAssocOps.mls
│ │ ├── RigidVariables.mls
│ │ ├── SelfAppMethods.mls
│ │ ├── SelfRec.mls
│ │ ├── Sidney.mls
│ │ ├── SimpleSymbolicOps.mls
│ │ ├── SimpleTraitImpl.mls
│ │ ├── Splices.mls
│ │ ├── StupidJS.mls
│ │ ├── Subscripts.mls
│ │ ├── TODO_Classes.mls
│ │ ├── ThisRefinedClasses.mls
│ │ ├── TraitParameters.mls
│ │ ├── TraitSignatures.mls
│ │ ├── TrickyExtrusion2.mls
│ │ ├── TrickyGenericInheritance.mls
│ │ ├── TupleParamBlunder.mls
│ │ ├── Tuples.mls
│ │ ├── TypeAliases.mls
│ │ ├── TypeOps.mls
│ │ ├── TypeSelections.mls
│ │ ├── TypeVariables.mls
│ │ ├── TypingUnitTerms.mls
│ │ ├── TypreMembers.mls
│ │ ├── Unapply.mls
│ │ ├── UnaryMinus.mls
│ │ ├── UndefMatching.mls
│ │ ├── Uninstantiable.mls
│ │ ├── UnionReordering.mls
│ │ ├── Unit.mls
│ │ ├── UserDefinedAnnotations.mls
│ │ ├── ValSigs.mls
│ │ ├── Vals.mls
│ │ ├── Varargs.mls
│ │ ├── Virtual.mls
│ │ ├── WeirdDefs.mls
│ │ ├── WeirdUnions.mls
│ │ ├── With.mls
│ │ ├── i180.mls
│ │ ├── i191.mls
│ │ ├── repro0.mls
│ │ ├── repro1.mls
│ │ ├── repro_EvalNegNeg.mls
│ │ └── repro_PolymorphicVariants.mls
│ ├── parser
│ │ ├── Annot.mls
│ │ ├── Arrays.mls
│ │ ├── BasicSyntax.mls
│ │ ├── Binds.mls
│ │ ├── Blocks.mls
│ │ ├── Brackets.mls
│ │ ├── Classes.mls
│ │ ├── Comments.mls
│ │ ├── ControversialIfSplits.mls
│ │ ├── FatArrows.mls
│ │ ├── FlatMultiArgLams.mls
│ │ ├── Forall.mls
│ │ ├── Fun.mls
│ │ ├── IfThenElse.mls
│ │ ├── Lambdas.mls
│ │ ├── Lets.mls
│ │ ├── Misc.mls
│ │ ├── MultiLineCalls.mls
│ │ ├── MultilineFun.mls
│ │ ├── NamedArrays.mls
│ │ ├── NegativeLits.mls
│ │ ├── New.mls
│ │ ├── Ops.mls
│ │ ├── Records.mls
│ │ ├── Select.mls
│ │ ├── SpecParams.mls
│ │ ├── Subscripts.mls
│ │ ├── TypeParams.mls
│ │ ├── UserDefinedOpsMaybe.mls
│ │ ├── WeirdIfs.mls
│ │ ├── Where.mls
│ │ ├── Whitespace.mls
│ │ └── boolops.mls
│ ├── pretyper
│ │ ├── Errors.mls
│ │ ├── Repro.mls
│ │ ├── SymbolKind.mls
│ │ └── ucs
│ │ │ ├── DualOption.mls
│ │ │ ├── NamePattern.mls
│ │ │ ├── RecordPattern.mls
│ │ │ ├── Refinement.mls
│ │ │ ├── SpecilizationCollision.mls
│ │ │ ├── Symbol.mls
│ │ │ ├── Unapply.mls
│ │ │ ├── Unconditional.mls
│ │ │ ├── coverage
│ │ │ ├── ConflictedCoveredCases.mls
│ │ │ ├── ConflictedPatterns.mls
│ │ │ ├── CoveredCases.mls
│ │ │ ├── DuplicatedCases.mls
│ │ │ ├── MissingCases.mls
│ │ │ ├── Refinement.mls
│ │ │ ├── SealedClasses.mls
│ │ │ ├── Tautology.mls
│ │ │ └── Unreachable.mls
│ │ │ ├── examples
│ │ │ ├── AVLTree.mls
│ │ │ ├── BinarySearchTree.mls
│ │ │ ├── Calculator.mls
│ │ │ ├── EitherOrBoth.mls
│ │ │ ├── JSON.mls
│ │ │ ├── LeftistTree.mls
│ │ │ ├── LispInterpreter.mls
│ │ │ ├── List.mls
│ │ │ ├── ListFold.mls
│ │ │ ├── Option.mls
│ │ │ ├── Permutations.mls
│ │ │ ├── STLC.mls
│ │ │ ├── SimpleLisp.mls
│ │ │ ├── SimpleList.mls
│ │ │ ├── SimpleTree.mls
│ │ │ └── ULC.mls
│ │ │ ├── patterns
│ │ │ ├── AliasPattern.mls
│ │ │ ├── Literals.mls
│ │ │ └── SimpleTuple.mls
│ │ │ └── stages
│ │ │ ├── Normalization.mls
│ │ │ ├── PostProcessing.mls
│ │ │ └── Transformation.mls
│ ├── qq
│ │ ├── BadConst.mls
│ │ ├── Basic.mls
│ │ ├── Basic2.mls
│ │ ├── Codegen.mls
│ │ ├── EffectfulLetInsertion.mls
│ │ ├── Extrusions.mls
│ │ ├── Hygiene.mls
│ │ ├── LetInsertion.mls
│ │ ├── LetInsertion_repro.mls
│ │ ├── Multiline.mls
│ │ ├── Nested.mls
│ │ ├── NuSyntax.mls
│ │ ├── PEPM.mls
│ │ ├── PEPM2.mls
│ │ ├── PseudoCod.mls
│ │ ├── QQFlag.mls
│ │ ├── ScopeTypes.mls
│ │ ├── Triple.mls
│ │ ├── Unquote.mls
│ │ ├── Weird.mls
│ │ └── WillfulExtrusion.mls
│ ├── scalac
│ │ └── i13162.mls
│ ├── tricky
│ │ ├── IrregularSubtypes.mls
│ │ ├── IrregularSubtypes2.mls
│ │ └── Pottier.fun
│ ├── typegen
│ │ ├── TypegenTerms.mls
│ │ └── TypegenTypedefs.mls
│ └── ucs
│ │ ├── AppSplits.mls
│ │ ├── CrossBranchCapture.mls
│ │ ├── DirectLines.mls
│ │ ├── ElseIf.mls
│ │ ├── ErrorMessage.mls
│ │ ├── Exhaustiveness.mls
│ │ ├── Humiliation.mls
│ │ ├── Hygiene.mls
│ │ ├── HygienicBindings.mls
│ │ ├── InterleavedLet.mls
│ │ ├── LeadingAnd.mls
│ │ ├── LitUCS.mls
│ │ ├── MultiwayIf.mls
│ │ ├── NestedBranches.mls
│ │ ├── NestedOpSplits.mls
│ │ ├── NestedPattern.mls
│ │ ├── NuPlainConditionals.mls
│ │ ├── Or.mls
│ │ ├── OverlappedBranches.mls
│ │ ├── ParseFailures.mls
│ │ ├── ParserFailures.mls
│ │ ├── PlainConditionals.mls
│ │ ├── SimpleUCS.mls
│ │ ├── SplitAfterOp.mls
│ │ ├── SplitAnd.mls
│ │ ├── SplitAroundOp.mls
│ │ ├── SplitBeforeOp.mls
│ │ ├── SplitOps.mls
│ │ ├── SplitScrutinee.mls
│ │ ├── ThenIndent.mls
│ │ ├── Tree.mls
│ │ ├── TrivialIf.mls
│ │ ├── WeirdIf.mls
│ │ ├── WeirdSplit.mls
│ │ ├── Wildcard.mls
│ │ └── zipWith.mls
│ └── scala
│ └── mlscript
│ ├── CodeGenTestHelpers.scala
│ ├── DiffTests.scala
│ ├── NodeTest.scala
│ └── ReplHost.scala
├── ts
└── dummy.ts
├── ts2mls
├── js
│ └── src
│ │ ├── main
│ │ └── scala
│ │ │ └── ts2mls
│ │ │ ├── JSWriter.scala
│ │ │ ├── TSCompilerInfo.scala
│ │ │ ├── TSData.scala
│ │ │ ├── TSNamespace.scala
│ │ │ ├── TSProgram.scala
│ │ │ ├── TSSourceFile.scala
│ │ │ └── types
│ │ │ ├── Converter.scala
│ │ │ └── TSType.scala
│ │ └── test
│ │ ├── diff
│ │ ├── Array.d.mls
│ │ ├── BasicFunctions.d.mls
│ │ ├── ClassMember.d.mls
│ │ ├── Dec.d.mls
│ │ ├── Enum.d.mls
│ │ ├── Heritage.d.mls
│ │ ├── HighOrderFunc.d.mls
│ │ ├── InterfaceMember.d.mls
│ │ ├── Intersection.d.mls
│ │ ├── Literal.d.mls
│ │ ├── MultiFiles.d.mls
│ │ ├── Namespace.d.mls
│ │ ├── Optional.d.mls
│ │ ├── Overload.d.mls
│ │ ├── Tuple.d.mls
│ │ ├── Type.d.mls
│ │ ├── TypeParameter.d.mls
│ │ ├── Union.d.mls
│ │ └── Variables.d.mls
│ │ ├── scala
│ │ └── ts2mls
│ │ │ └── TSTypeGenerationTests.scala
│ │ └── typescript
│ │ ├── Array.ts
│ │ ├── BasicFunctions.ts
│ │ ├── ClassMember.ts
│ │ ├── Dec.d.ts
│ │ ├── Enum.ts
│ │ ├── Heritage.ts
│ │ ├── HighOrderFunc.ts
│ │ ├── InterfaceMember.ts
│ │ ├── Intersection.ts
│ │ ├── Literal.ts
│ │ ├── Multi1.ts
│ │ ├── Multi2.ts
│ │ ├── Multi3.ts
│ │ ├── Namespace.ts
│ │ ├── Optional.ts
│ │ ├── Overload.ts
│ │ ├── Tuple.ts
│ │ ├── Type.ts
│ │ ├── TypeParameter.ts
│ │ ├── Union.ts
│ │ └── Variables.ts
└── jvm
│ └── src
│ └── test
│ └── scala
│ └── ts2mls
│ └── TsTypeDiffTests.scala
└── tsconfig.json
/.gitattributes:
--------------------------------------------------------------------------------
1 | * eol=lf
2 | bin/mlscript-opt.js linguist-vendored
3 |
--------------------------------------------------------------------------------
/.github/workflows/nix.yml:
--------------------------------------------------------------------------------
1 | name: Cpp Backend CI with Nix
2 |
3 | on:
4 | pull_request:
5 | push:
6 | branches: [ mlscript ]
7 |
8 | jobs:
9 | build:
10 | runs-on: ubuntu-latest
11 | steps:
12 | - uses: actions/checkout@v3
13 | - name: Install Nix
14 | uses: DeterminateSystems/nix-installer-action@main
15 | - uses: rrbutani/use-nix-shell-action@v1
16 | with:
17 | devShell: .#default
18 | - name: Install TypeScript
19 | run: npm ci
20 | - name: Run test
21 | run: sbt -J-Xmx4096M -J-Xss4M test
22 | - name: Check no changes
23 | run: git diff-files -p --exit-code
24 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 | .bloop/
3 | .metals/
4 | .bsp/
5 | node_modules/
6 | metals.sbt
7 | project/Dependencies.scala
8 | project/metals.sbt
9 | **.worksheet.sc
10 | .DS_Store
11 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "files.associations": {
3 | "*.fun": "typescript",
4 | "*.mls": "mlscript"
5 | },
6 | "typescript.validate.enable": false,
7 | "files.watcherExclude": {
8 | "**/target": true
9 | },
10 | "[typescript]": {
11 | "editor.quickSuggestions": {
12 | "comments": "off",
13 | "other": "off",
14 | "strings": "off"
15 | }
16 | },
17 | "files.autoSave": "off"
18 | }
19 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 Lionel Parreaux
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/compiler/shared/main/scala/mlscript/compiler/debug/Debug.scala:
--------------------------------------------------------------------------------
1 | package mlscript.compiler
2 |
3 | abstract class Debug:
4 | def trace[T](name: String, pre: Any*)
5 | (thunk: => T)
6 | (post: T => Any = Debug.noPostTrace): T
7 | def log(msg: => String): Unit
8 | def writeLine(line: String): Unit
9 | def indent(): Unit
10 | def outdent(): Unit
11 |
12 | object Debug:
13 | val noPostTrace: Any => Any = _ => ""
14 |
--------------------------------------------------------------------------------
/compiler/shared/main/scala/mlscript/compiler/debug/DummyDebug.scala:
--------------------------------------------------------------------------------
1 | package mlscript.compiler
2 |
3 | object DummyDebug extends Debug:
4 | def trace[T](name: String, pre: Any*)
5 | (thunk: => T)
6 | (post: T => Any = Debug.noPostTrace): T = thunk
7 | inline def log(msg: => String): Unit = ()
8 | def writeLine(line: String): Unit = ()
9 | def indent(): Unit = ()
10 | def outdent(): Unit = ()
11 |
--------------------------------------------------------------------------------
/compiler/shared/main/scala/mlscript/compiler/debug/Printable.scala:
--------------------------------------------------------------------------------
1 | package mlscript.compiler
2 |
3 | trait Printable:
4 | def getDebugOutput: DebugOutput
5 |
--------------------------------------------------------------------------------
/compiler/shared/main/scala/mlscript/compiler/debug/TreeDebug.scala:
--------------------------------------------------------------------------------
1 | package mlscript.compiler
2 |
3 | import scala.collection.mutable.ArrayBuffer
4 |
5 | class TreeDebug(output: String => Unit) extends RainbowDebug(false):
6 | private val lines = ArrayBuffer[String]()
7 | private var indentation: Int = 0
8 |
9 | override inline def writeLine(line: String): Unit =
10 | output("║"*indentation ++ line)
11 | lines += line
12 |
13 | override def indent(): Unit =
14 | indentation += 1
15 | override def outdent(): Unit =
16 | indentation -= 1
17 |
18 | def getLines: List[String] = lines.toList
19 |
--------------------------------------------------------------------------------
/compiler/shared/main/scala/mlscript/compiler/ir/Fresh.scala:
--------------------------------------------------------------------------------
1 | package mlscript.compiler.ir
2 |
3 | import collection.mutable.{HashMap => MutHMap}
4 | import mlscript.utils.shorthands._
5 |
6 | final class Fresh(div : Char = '$'):
7 | private val counter = MutHMap[Str, Int]()
8 | private def gensym(s: Str) = {
9 | val n = s.lastIndexOf(div)
10 | val (ts, suffix) = s.splitAt(if n == -1 then s.length() else n)
11 | var x = if suffix.stripPrefix(div.toString).forall(_.isDigit) then ts else s
12 | val count = counter.getOrElse(x, 0)
13 | val tmp = s"$x$div$count"
14 | counter.update(x, count + 1)
15 | Name(tmp)
16 | }
17 |
18 | def make(s: Str) = gensym(s)
19 | def make = gensym("x")
20 |
21 | final class FreshInt:
22 | private var counter = 0
23 | def make: Int = {
24 | val tmp = counter
25 | counter += 1
26 | tmp
27 | }
28 |
29 |
30 |
--------------------------------------------------------------------------------
/compiler/shared/main/scala/mlscript/compiler/simpledef/Uid.scala:
--------------------------------------------------------------------------------
1 | package mlscript
2 | package compiler
3 | package simpledef
4 |
5 | opaque type Uid[T] = Int
6 |
7 | object Uid:
8 | class Handler[T]:
9 | class State:
10 | private val uidStore = scala.collection.mutable.Map.empty[String, Uid[T]]
11 | def nextUid: Uid[T] = nextUid("")
12 | def nextUid(key: String): Uid[T] =
13 | uidStore.updateWith(key) {
14 | case None => Some(0)
15 | case Some(v) => Some(v + 1)
16 | }.get
17 | object TypeVar extends Handler[TypeVar]
18 | object Term extends Handler[Term]
--------------------------------------------------------------------------------
/compiler/shared/test/diff-ir/NuScratch.mls:
--------------------------------------------------------------------------------
1 | :NewParser
2 | :ParseOnly
3 | :UseIR
4 |
--------------------------------------------------------------------------------
/compiler/shared/test/diff-ir/Override.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 | :ParseOnly
3 | :UseIR
4 | :NoTailRec
5 |
6 | :genCpp
7 | :runCpp
8 | :interpIR
9 | module Base {
10 | fun f() = 1
11 | }
12 | module Child extends Base {
13 | fun f() = 2
14 | }
15 | fun main() =
16 | let c = Child()
17 | Base.f(c)
18 | Child.f(c)
19 | main()
20 | //│ |#module| |Base| |{|→|#fun| |f|(||)| |#=| |1|←|↵|}|↵|#module| |Child| |#extends| |Base| |{|→|#fun| |f|(||)| |#=| |2|←|↵|}|↵|#fun| |main|(||)| |#=|→|#let| |c| |#=| |Child|(||)|↵|Base|.f|(|c|)|↵|Child|.f|(|c|)|←|↵|main|(||)|
21 | //│ Parsed: {module Base {fun f = () => 1}; module Child: Base {fun f = () => 2}; fun main = () => {let c = Child(); (Base).f(c,); (Child).f(c,)}; main()}
22 | //│
23 | //│
24 | //│ IR:
25 | //│ Program:
26 | //│ class Base() {
27 | //│ def f() =
28 | //│ 1 -- #16
29 | //│ }
30 | //│ class Child() extends Base {
31 | //│ def f() =
32 | //│ 2 -- #17
33 | //│ }
34 | //│ def main() =
35 | //│ let x$1 = Child() in -- #15
36 | //│ let x$2 = Base.f(x$1) in -- #14
37 | //│ let x$3 = Child.f(x$1) in -- #13
38 | //│ x$3 -- #12
39 | //│ let* (x$0) = main() in -- #2
40 | //│ x$0 -- #1
41 | //│
42 | //│ Interpreted:
43 | //│ 2
44 | //│
45 | //│
46 | //│ Execution succeeded:
47 | //│ 2
48 | //│
49 |
--------------------------------------------------------------------------------
/compiler/shared/test/diff-ir/cpp/Makefile:
--------------------------------------------------------------------------------
1 | CXX := g++
2 | CFLAGS := $(CFLAGS) -O3 -Wall -Wextra -std=c++20 -I. -Wno-inconsistent-missing-override
3 | LDFLAGS := $(LDFLAGS) -lmimalloc -lgmp
4 | SRC :=
5 | INCLUDES = mlsprelude.h
6 | DST :=
7 | DEFAULT_TARGET := mls
8 | TARGET := $(or $(DST),$(DEFAULT_TARGET))
9 |
10 | .PHONY: pre all run clean auto
11 |
12 | all: $(TARGET)
13 |
14 | run: $(TARGET)
15 | ./$(TARGET)
16 |
17 | pre: $(SRC)
18 | sed -i '' 's#^//│ ##g' $(SRC)
19 |
20 | clean:
21 | rm -r $(TARGET) $(TARGET).dSYM
22 |
23 | auto: $(TARGET)
24 |
25 | $(TARGET): $(SRC) $(INCLUDES)
26 | $(CXX) $(CFLAGS) $(LDFLAGS) $(SRC) -o $(TARGET)
27 |
--------------------------------------------------------------------------------
/compiler/shared/test/diff/CompilerScratch.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 |
--------------------------------------------------------------------------------
/compiler/shared/test/diff/Defunctionalize/Classes.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 | class Bar(val x: Int) {
4 | fun foo(x) = x
5 | fun FooMinus(y: Int) = x + y
6 | fun car = foo(2)
7 | }
8 | class Car() {
9 | fun da(b: Bar) = b.foo(2)
10 | }
11 | fun baz(b: Bar) = b.foo(2)
12 | let bar = Bar(42)
13 | baz(bar)
14 | (Car()).da(Bar(1337))
15 | bar.car
16 | //│ class Bar(x: Int) {
17 | //│ fun FooMinus: (y: Int) -> Int
18 | //│ fun car: 2
19 | //│ fun foo: forall 'a. 'a -> 'a
20 | //│ }
21 | //│ class Car() {
22 | //│ fun da: (b: Bar) -> 2
23 | //│ }
24 | //│ fun baz: (b: Bar) -> 2
25 | //│ let bar: Bar
26 | //│ 2
27 | //│
28 | //│ Simpledef:
29 | //│ {class Bar(val x: Int,) {fun foo = (x::0,) => x
30 | //│ fun FooMinus = (y: Int,) => +(x, y,)
31 | //│ fun car = foo(2,)}
32 | //│ class Car() {fun da = (b: Bar,) => let selRes$34 = b in case selRes$34 of { Bar => (selRes$34).foo(2,) }}
33 | //│ fun baz = (b: Bar,) => let selRes$48 = b in case selRes$48 of { Bar => (selRes$48).foo(2,) }
34 | //│ let bar = Bar(42,)
35 | //│ baz(bar,)
36 | //│ let selRes$76 = '(' Car() ')' in case selRes$76 of { Car => (selRes$76).da(Bar(1337,),) }
37 | //│ let selRes$98 = bar in case selRes$98 of { Bar => (selRes$98).car }}
38 | //│ End simpledef
39 | //│
40 | //│ bar
41 | //│ = Bar {}
42 | //│ res
43 | //│ = 2
44 | //│ res
45 | //│ = 2
46 | //│ res
47 | //│ = 2
48 |
--------------------------------------------------------------------------------
/compiler/shared/test/diff/Defunctionalize/ClosureCapture.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 | :AllowRuntimeErrors
3 |
4 | fun foo(x) =
5 | (f => f(x))(z => z+1)
6 | foo(2)
7 | //│ fun foo: Int -> Int
8 | //│ Int
9 | //│
10 | //│ Simpledef:
11 | //│ {fun foo = (x::0,) => {'(' (f::1,) => f(x,) ')'((z::2,) => +(z, 1,),)}
12 | //│ foo(2,)}
13 | //│ End simpledef
14 | //│
15 | //│ res
16 | //│ = 3
17 |
18 | fun f(x) =
19 | (y => f(x+y))(x+1)
20 | f(1)
21 | //│ fun f: Int -> nothing
22 | //│ nothing
23 | //│
24 | //│ Simpledef:
25 | //│ {fun f = (x::3,) => {'(' (y::4,) => f(+(x, y,),) ')'(+(x, 1,),)}
26 | //│ f(1,)}
27 | //│ End simpledef
28 | //│
29 | //│ res
30 | //│ Runtime error:
31 | //│ RangeError: Maximum call stack size exceeded
32 |
--------------------------------------------------------------------------------
/compiler/shared/test/diff/Defunctionalize/Constructor.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 | class X() {
4 | val a =
5 | log("ok")
6 | 6
7 | }
8 | val object = X()
9 | (new X()).a
10 | (new X()).a
11 | object.a
12 | object.a
13 | //│ class X() {
14 | //│ val a: 6
15 | //│ }
16 | //│ val object: X
17 | //│ 6
18 | //│
19 | //│ Simpledef:
20 | //│ {class X() {let a = {log("ok",)
21 | //│ 6}}
22 | //│ let object = X()
23 | //│ let selRes$20 = '(' (new X)() ')' in case selRes$20 of { X => (selRes$20).a }
24 | //│ let selRes$30 = '(' (new X)() ')' in case selRes$30 of { X => (selRes$30).a }
25 | //│ let selRes$40 = object in case selRes$40 of { X => (selRes$40).a }
26 | //│ let selRes$44 = object in case selRes$44 of { X => (selRes$44).a }}
27 | //│ End simpledef
28 | //│
29 | //│ object
30 | //│ = X {}
31 | //│ // Output
32 | //│ ok
33 | //│ res
34 | //│ = 6
35 | //│ // Output
36 | //│ ok
37 | //│ res
38 | //│ = 6
39 | //│ // Output
40 | //│ ok
41 | //│ res
42 | //│ = 6
43 | //│ res
44 | //│ = 6
45 |
--------------------------------------------------------------------------------
/compiler/shared/test/diff/Defunctionalize/DelayedEvaluation.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 | class G(val num: Int) {
4 | val x =
5 | log("once on construction")
6 | num+2
7 | val y() =
8 | log("once every call")
9 | num+2
10 | }
11 | val g = new G(6)
12 | g.y()
13 | g.x
14 | g.y()
15 | g.x
16 | //│ class G(num: Int) {
17 | //│ val x: Int
18 | //│ val y: () -> Int
19 | //│ }
20 | //│ val g: G
21 | //│ Int
22 | //│
23 | //│ Simpledef:
24 | //│ {class G(val num: Int,) {let x = {log("once on construction",)
25 | //│ +(num, 2,)}
26 | //│ let y = () => {log("once every call",)
27 | //│ +(num, 2,)}}
28 | //│ let g = (new G)(6,)
29 | //│ let selRes$56 = g in case selRes$56 of { G => (selRes$56).y() }
30 | //│ let selRes$64 = g in case selRes$64 of { G => (selRes$64).x }
31 | //│ let selRes$68 = g in case selRes$68 of { G => (selRes$68).y() }
32 | //│ let selRes$76 = g in case selRes$76 of { G => (selRes$76).x }}
33 | //│ End simpledef
34 | //│
35 | //│ g
36 | //│ = G {}
37 | //│ // Output
38 | //│ once on construction
39 | //│ res
40 | //│ = 8
41 | //│ // Output
42 | //│ once every call
43 | //│ res
44 | //│ = 8
45 | //│ res
46 | //│ = 8
47 | //│ // Output
48 | //│ once every call
49 | //│ res
50 | //│ = 8
51 |
--------------------------------------------------------------------------------
/compiler/shared/test/diff/Defunctionalize/FreeVariables.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 | class X() {
4 | val num = 5
5 | fun get() = num
6 | }
7 | X().get()
8 | //│ class X() {
9 | //│ fun get: () -> 5
10 | //│ val num: 5
11 | //│ }
12 | //│ 5
13 | //│
14 | //│ Simpledef:
15 | //│ {class X() {let num = 5
16 | //│ fun get = () => num}
17 | //│ let selRes$10 = X() in case selRes$10 of { X => (selRes$10).get() }}
18 | //│ End simpledef
19 | //│
20 | //│ res
21 | //│ = 5
22 |
--------------------------------------------------------------------------------
/compiler/shared/test/diff/Defunctionalize/FuncsWithParams.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | abstract class Arithmetic() {
5 | virtual fun use(num1: Int, num2: Int): Int
6 | }
7 | class Add() extends Arithmetic {
8 | fun use(num1, num2) = num1+num2
9 | }
10 | class Sub() extends Arithmetic {
11 | fun use(num1, num2) = num1-num2
12 | }
13 | fun getArith(choice) = if choice == 1 then Add() else Sub()
14 | getArith(1).use(4,6)
15 | getArith(2).use(4,6)
16 | //│ abstract class Arithmetic() {
17 | //│ fun use: (num1: Int, num2: Int) -> Int
18 | //│ }
19 | //│ class Add() extends Arithmetic {
20 | //│ fun use: (Int, Int) -> Int
21 | //│ }
22 | //│ class Sub() extends Arithmetic {
23 | //│ fun use: (Int, Int) -> Int
24 | //│ }
25 | //│ fun getArith: Num -> (Add | Sub)
26 | //│ Int
27 | //│
28 | //│ Simpledef:
29 | //│ {class Arithmetic() {fun use: (num1: Int, num2: Int) -> Int}
30 | //│ class Add(): Arithmetic {fun use = (num1::0, num2::1,) => +(num1, num2,)}
31 | //│ class Sub(): Arithmetic {fun use = (num1::2, num2::3,) => -(num1, num2,)}
32 | //│ fun getArith = (choice::4,) => if (==(choice, 1,)) then Add() else Sub()
33 | //│ let selRes$58 = getArith(1,) in case selRes$58 of { Sub => (selRes$58).use(4, 6,)
34 | //│ Add => (selRes$58).use(4, 6,) }
35 | //│ let selRes$76 = getArith(2,) in case selRes$76 of { Sub => (selRes$76).use(4, 6,)
36 | //│ Add => (selRes$76).use(4, 6,) }}
37 | //│ End simpledef
38 | //│
39 | //│ res
40 | //│ = 10
41 | //│ res
42 | //│ = -2
43 |
--------------------------------------------------------------------------------
/compiler/shared/test/diff/Defunctionalize/Inheritance.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 | // FIXME: Pattern matches on superclass instead of subclass
4 | class Sup() {
5 | fun add(num1, num2) = num1+num2
6 | }
7 | class Sub1() extends Sup() {}
8 | class Sub2() extends Sub1() {}
9 | Sub1().add(3,4)
10 | Sub2().add(5,6)
11 | //│ class Sup() {
12 | //│ fun add: (Int, Int) -> Int
13 | //│ }
14 | //│ class Sub1() extends Sup {
15 | //│ fun add: (Int, Int) -> Int
16 | //│ }
17 | //│ class Sub2() extends Sub1, Sup {
18 | //│ fun add: (Int, Int) -> Int
19 | //│ }
20 | //│ Int
21 | //│
22 | //│ Simpledef:
23 | //│ {class Sup() {fun add = (num1::0, num2::1,) => +(num1, num2,)}
24 | //│ class Sub1(): Sup() {}
25 | //│ class Sub2(): Sub1() {}
26 | //│ let selRes$16 = Sub1() in case selRes$16 of { Sup => (selRes$16).add(3, 4,) }
27 | //│ let selRes$32 = Sub2() in case selRes$32 of { Sup => (selRes$32).add(5, 6,) }}
28 | //│ End simpledef
29 | //│
30 | //│ res
31 | //│ = 7
32 | //│ res
33 | //│ = 11
34 |
--------------------------------------------------------------------------------
/compiler/shared/test/diff/Defunctionalize/Lambda.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | class X(val foo: Int => Int){}
5 | class Y(val foo: Int => Bool){}
6 | fun x(pred) = if pred then X(x => x+1) else Y(x => true)
7 | x(true).foo(5)
8 | //│ class X(foo: Int -> Int)
9 | //│ class Y(foo: Int -> Bool)
10 | //│ fun x: Bool -> (X | Y)
11 | //│ Int | false | true
12 | //│
13 | //│ Simpledef:
14 | //│ {class X(val foo: (Int,) => Int,) {}
15 | //│ class Y(val foo: (Int,) => Bool,) {}
16 | //│ fun x = (pred::0,) => if (pred) then X((x::1,) => +(x, 1,),) else Y((x::2,) => true,)
17 | //│ let selRes$46 = x(true,) in case selRes$46 of { Y => (selRes$46).foo(5,)
18 | //│ X => (selRes$46).foo(5,) }}
19 | //│ End simpledef
20 | //│
21 | //│ res
22 | //│ = 6
23 |
--------------------------------------------------------------------------------
/compiler/shared/test/diff/Defunctionalize/Lambdas.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 | ((f, g) => f(g))(f => f, true)
4 | //│ true
5 | //│
6 | //│ Simpledef:
7 | //│ {'(' (f::0, g::1,) => f(g,) ')'((f::2,) => f, true,)}
8 | //│ End simpledef
9 | //│
10 | //│ res
11 | //│ = true
12 |
13 | (b => if b then true else false) (true)
14 | //│ Bool
15 | //│
16 | //│ Simpledef:
17 | //│ {'(' (b::3,) => if (b) then true else false ')'(true,)}
18 | //│ End simpledef
19 | //│
20 | //│ res
21 | //│ = true
22 |
23 |
--------------------------------------------------------------------------------
/compiler/shared/test/diff/Defunctionalize/Modules.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | class Foo() {fun f = 0}
5 | module x { val y = Foo() }
6 | x.y.f
7 | //│ class Foo() {
8 | //│ fun f: 0
9 | //│ }
10 | //│ module x {
11 | //│ val y: Foo
12 | //│ }
13 | //│ 0
14 | //│
15 | //│ Simpledef:
16 | //│ {class Foo() {fun f = 0}
17 | //│ module x {let y = Foo()}
18 | //│ let selRes$10 = let selRes$12 = x in case selRes$12 of { x => (selRes$12).y } in case selRes$10 of { Foo => (selRes$10).f }}
19 | //│ End simpledef
20 | //│
21 | //│ res
22 | //│ = 0
23 |
--------------------------------------------------------------------------------
/compiler/shared/test/diff/Defunctionalize/MonoNonLambda.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 | class A() {
4 | val x = 2
5 | val y() = 3
6 | fun z = 4
7 | fun w() = 5
8 | }
9 | val a = A()
10 | a.x
11 | a.y()
12 | a.z
13 | a.w()
14 | //│ class A() {
15 | //│ fun w: () -> 5
16 | //│ val x: 2
17 | //│ val y: () -> 3
18 | //│ fun z: 4
19 | //│ }
20 | //│ val a: A
21 | //│ 5
22 | //│
23 | //│ Simpledef:
24 | //│ {class A() {let x = 2
25 | //│ let y = () => 3
26 | //│ fun z = 4
27 | //│ fun w = () => 5}
28 | //│ let a = A()
29 | //│ let selRes$24 = a in case selRes$24 of { A => (selRes$24).x }
30 | //│ let selRes$28 = a in case selRes$28 of { A => (selRes$28).y() }
31 | //│ let selRes$36 = a in case selRes$36 of { A => (selRes$36).z }
32 | //│ let selRes$40 = a in case selRes$40 of { A => (selRes$40).w() }}
33 | //│ End simpledef
34 | //│
35 | //│ a
36 | //│ = A {}
37 | //│ res
38 | //│ = 2
39 | //│ res
40 | //│ = 3
41 | //│ res
42 | //│ = 4
43 | //│ res
44 | //│ = 5
45 |
--------------------------------------------------------------------------------
/compiler/shared/test/diff/Defunctionalize/MonoTupSelect.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 | class Foo() {fun f() = 0}
4 | class Bar() {fun f = 0}
5 | [Foo(), Bar()].0.f()
6 | [Foo(), Bar()].1.f
7 | //│ class Foo() {
8 | //│ fun f: () -> 0
9 | //│ }
10 | //│ class Bar() {
11 | //│ fun f: 0
12 | //│ }
13 | //│ 0
14 | //│
15 | //│ Simpledef:
16 | //│ {class Foo() {fun f = () => 0}
17 | //│ class Bar() {fun f = 0}
18 | //│ let selRes$10 = ([Foo(), Bar(),]).0 in case selRes$10 of { Foo => (selRes$10).f() }
19 | //│ let selRes$32 = ([Foo(), Bar(),]).1 in case selRes$32 of { Bar => (selRes$32).f }}
20 | //│ End simpledef
21 | //│
22 | //│ res
23 | //│ = 0
24 | //│ res
25 | //│ = 0
26 |
--------------------------------------------------------------------------------
/compiler/shared/test/diff/Defunctionalize/MutableParams.mls:
--------------------------------------------------------------------------------
1 | :NewDefs // TODO: Mutable Parameters
2 |
3 | //class Bar(#x)
4 | //fun foo(#b) = b
5 | //let a = foo(new Bar(1))
6 | //let b = foo(new Bar(2))
7 |
8 | //class OneInt(#a){
9 | // fun inc() = a+1
10 | //}
11 | //(new OneInt(1)).inc()
12 |
13 | //class OneInt(#a){
14 | // fun add(x) =
15 | // new OneInt(a+x.a)
16 | //}
17 | //(new OneInt(1)).add(new OneInt(2))
18 |
19 | //trait AnyFoo {
20 | //}
21 | //class FooPlus(#a): AnyFoo {
22 | // fun bar(b) = a + b
23 | //}
24 | //class FooMinus(#a): AnyFoo {
25 | // fun bar(b) = a - b
26 | //}
27 | //fun f(x) = x.bar(42)
28 | //f(new FooPlus(1))
29 | //f(new FooMinus(2))
30 |
--------------------------------------------------------------------------------
/compiler/shared/test/diff/Defunctionalize/MutualRec.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 | :AllowRuntimeErrors
3 |
4 | val any = -20
5 | fun f(x) =
6 | if x > any then 0
7 | else g(x - 1)
8 | fun g(x) =
9 | if x > any then g(x - 1)
10 | else f(x - 2)
11 | g(1)
12 | //│ val any: -20
13 | //│ fun f: Int -> 0
14 | //│ fun g: Int -> 0
15 | //│ 0
16 | //│
17 | //│ Simpledef:
18 | //│ {let any = -20
19 | //│ fun f = (x::0,) => {if (>(x, any,)) then 0 else g(-(x, 1,),)}
20 | //│ fun g = (x::1,) => {if (>(x, any,)) then g(-(x, 1,),) else f(-(x, 2,),)}
21 | //│ g(1,)}
22 | //│ End simpledef
23 | //│
24 | //│ any
25 | //│ = -20
26 | //│ res
27 | //│ Runtime error:
28 | //│ RangeError: Maximum call stack size exceeded
29 |
--------------------------------------------------------------------------------
/compiler/shared/test/diff/Defunctionalize/NewOperator.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 | class Foo(val x: Int) {
4 | }
5 | new Foo(5).x
6 | //│ class Foo(x: Int)
7 | //│ Int
8 | //│
9 | //│ Simpledef:
10 | //│ {class Foo(val x: Int,) {}
11 | //│ let selRes$4 = (new Foo)(5,) in case selRes$4 of { Foo => (selRes$4).x }}
12 | //│ End simpledef
13 | //│
14 | //│ res
15 | //│ = 5
16 |
--------------------------------------------------------------------------------
/compiler/shared/test/diff/Defunctionalize/ObjFields.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | class X(val bar: Int) {}
5 | class Y(val bar: Str) {}
6 | class A(val foo: X) {}
7 | class B(val foo: Y) {}
8 | fun getObj(pred) = if pred then A(X(1)) else B(Y("abc"))
9 | val x = getObj(true)
10 | x.foo.bar
11 | //│ class X(bar: Int)
12 | //│ class Y(bar: Str)
13 | //│ class A(foo: X)
14 | //│ class B(foo: Y)
15 | //│ fun getObj: Bool -> (A | B)
16 | //│ val x: A | B
17 | //│ Int | Str
18 | //│
19 | //│ Simpledef:
20 | //│ {class X(val bar: Int,) {}
21 | //│ class Y(val bar: Str,) {}
22 | //│ class A(val foo: X,) {}
23 | //│ class B(val foo: Y,) {}
24 | //│ fun getObj = (pred::0,) => if (pred) then A(X(1,),) else B(Y("abc",),)
25 | //│ let x = getObj(true,)
26 | //│ let selRes$54 = let selRes$56 = x in case selRes$56 of { A => (selRes$56).foo
27 | //│ B => (selRes$56).foo } in case selRes$54 of { Y => (selRes$54).bar
28 | //│ X => (selRes$54).bar }}
29 | //│ End simpledef
30 | //│
31 | //│ x
32 | //│ = A {}
33 | //│ res
34 | //│ = 1
35 |
--------------------------------------------------------------------------------
/compiler/shared/test/diff/Defunctionalize/ObjMultiFields.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | class X(val foo: Int, val bar: Bool) {}
5 | class Y(val foo: Str, val bar: Int) {}
6 | class A(val foo: X) {}
7 | class B(val foo: Y) {}
8 | fun foo(pred) = if pred then A(X(1, false)) else B(Y("abc", 5))
9 | val x = foo(true)
10 | x.foo.bar
11 | foo(false).foo.bar
12 | //│ class X(foo: Int, bar: Bool)
13 | //│ class Y(foo: Str, bar: Int)
14 | //│ class A(foo: X)
15 | //│ class B(foo: Y)
16 | //│ fun foo: Bool -> (A | B)
17 | //│ val x: A | B
18 | //│ Int | false | true
19 | //│
20 | //│ Simpledef:
21 | //│ {class X(val foo: Int, val bar: Bool,) {}
22 | //│ class Y(val foo: Str, val bar: Int,) {}
23 | //│ class A(val foo: X,) {}
24 | //│ class B(val foo: Y,) {}
25 | //│ fun foo = (pred::0,) => if (pred) then A(X(1, false,),) else B(Y("abc", 5,),)
26 | //│ let x = foo(true,)
27 | //│ let selRes$58 = let selRes$60 = x in case selRes$60 of { A => (selRes$60).foo
28 | //│ B => (selRes$60).foo } in case selRes$58 of { Y => (selRes$58).bar
29 | //│ X => (selRes$58).bar }
30 | //│ let selRes$64 = let selRes$66 = foo(false,) in case selRes$66 of { B => (selRes$66).foo
31 | //│ A => (selRes$66).foo } in case selRes$64 of { X => (selRes$64).bar
32 | //│ Y => (selRes$64).bar }}
33 | //│ End simpledef
34 | //│
35 | //│ x
36 | //│ = A {}
37 | //│ res
38 | //│ = false
39 | //│ res
40 | //│ = 5
41 |
--------------------------------------------------------------------------------
/compiler/shared/test/diff/Defunctionalize/ObjsSelection.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 | class X() {
4 | val num = 6
5 | }
6 | class Y() {
7 | val num = true
8 | }
9 | fun foo(pred) = if pred then X() else Y()
10 | fun id(x) = x
11 | val a = foo(true)
12 | val b = id(a)
13 | b.num
14 | //│ class X() {
15 | //│ val num: 6
16 | //│ }
17 | //│ class Y() {
18 | //│ val num: true
19 | //│ }
20 | //│ fun foo: Bool -> (X | Y)
21 | //│ fun id: forall 'a. 'a -> 'a
22 | //│ val a: X | Y
23 | //│ val b: X | Y
24 | //│ 6 | true
25 | //│
26 | //│ Simpledef:
27 | //│ {class X() {let num = 6}
28 | //│ class Y() {let num = true}
29 | //│ fun foo = (pred::0,) => if (pred) then X() else Y()
30 | //│ fun id = (x::1,) => x
31 | //│ let a = foo(true,)
32 | //│ let b = id(a,)
33 | //│ let selRes$48 = b in case selRes$48 of { Y => (selRes$48).num
34 | //│ X => (selRes$48).num }}
35 | //│ End simpledef
36 | //│
37 | //│ a
38 | //│ = X {}
39 | //│ b
40 | //│ = X {}
41 | //│ res
42 | //│ = 6
43 |
--------------------------------------------------------------------------------
/compiler/shared/test/diff/Defunctionalize/Polymorphic.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 | let b = true
4 | class OneInt(val a: Int){
5 | fun get = () -> a
6 | }
7 | class OneBool(val b: Bool){
8 | fun get = () -> b
9 | }
10 | (if b then OneInt(1) else OneBool(true)).get()
11 | //│ let b: true
12 | //│ class OneInt(a: Int) {
13 | //│ fun get: () -> Int
14 | //│ }
15 | //│ class OneBool(b: Bool) {
16 | //│ fun get: () -> Bool
17 | //│ }
18 | //│ Int | false | true
19 | //│
20 | //│ Simpledef:
21 | //│ {let b = true
22 | //│ class OneInt(val a: Int,) {fun get = () => a}
23 | //│ class OneBool(val b: Bool,) {fun get = () => b}
24 | //│ let selRes$20 = '(' if (b) then OneInt(1,) else OneBool(true,) ')' in case selRes$20 of { OneInt => (selRes$20).get()
25 | //│ OneBool => (selRes$20).get() }}
26 | //│ End simpledef
27 | //│
28 | //│ b
29 | //│ = true
30 | //│ res
31 | //│ = 1
32 |
--------------------------------------------------------------------------------
/compiler/shared/test/diff/Defunctionalize/Record.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | class K() {
5 | val f = true
6 | }
7 | val x = {
8 | 5: "five",
9 | 7: "seven",
10 | f: 6
11 | }
12 | fun muddle(pred) = if pred then K() else x
13 | muddle(false).f
14 | //│ class K() {
15 | //│ val f: true
16 | //│ }
17 | //│ val x: {5: "five", 7: "seven", f: 6}
18 | //│ fun muddle: Bool -> (K | {5: "five", 7: "seven", f: 6})
19 | //│ 6 | true
20 | //│
21 | //│ Simpledef:
22 | //│ {class K() {let f = true}
23 | //│ let x = '{' {5: "five", 7: "seven", f: 6} '}'
24 | //│ fun muddle = (pred::0,) => if (pred) then K() else x
25 | //│ (muddle(false,)).f}
26 | //│ End simpledef
27 | //│
28 | //│ x
29 | //│ = { '5': 'five', '7': 'seven', f: 6 }
30 | //│ res
31 | //│ = 6
32 |
--------------------------------------------------------------------------------
/compiler/shared/test/diff/Defunctionalize/RecursiveFunc.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 | fun fac(n) =
4 | if (n > 1) then fac(n - 1) * n else 1
5 | fac(5)
6 | //│ fun fac: Int -> Int
7 | //│ Int
8 | //│
9 | //│ Simpledef:
10 | //│ {fun fac = (n::0,) => {if ('(' >(n, 1,) ')') then *(fac(-(n, 1,),), n,) else 1}
11 | //│ fac(5,)}
12 | //│ End simpledef
13 | //│
14 | //│ res
15 | //│ = 120
16 |
17 | // TODO: Support for specialized pattern matching types
18 | // In this example, the type of l in count(l) would need to be constrained to
19 | // object & ~(), which requires implementing neg types, intersections, etc.
20 | class List(val l: List | Nil | undefined, val hasTail: Bool) {}
21 | class Nil(val l: List | Nil | undefined, val hasTail: Bool) {}
22 | fun count(lst) =
23 | if lst.hasTail then
24 | let l = lst.l
25 | if l is undefined then 1 else count(l)+1
26 | else 0
27 | count(new List(new List(new Nil(undefined, false), true), true))
28 | //│ class List(l: List | Nil | (), hasTail: Bool)
29 | //│ class Nil(l: List | Nil | (), hasTail: Bool)
30 | //│ fun count: forall 'a. 'a -> Int
31 | //│ Int
32 | //│ where
33 | //│ 'a <: {hasTail: Bool, l: Object & 'a & ~() | ()}
34 | //│
35 | //│ Simpledef:
36 | //│ /!!!\ Uncaught error: java.lang.Exception: Internal Error: Could not constrain (ProdObj(Some(Var(prim$Unit)),List(),List()),ConsObj(None,List((Var(l),ConsVar(15,13_selres)))))
37 |
--------------------------------------------------------------------------------
/compiler/shared/test/diff/Defunctionalize/SelfReference.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 | :AllowRuntimeErrors
3 |
4 | fun f(x) = f(x)
5 | f(0)
6 | f(1)
7 | //│ fun f: anything -> nothing
8 | //│ nothing
9 | //│
10 | //│ Simpledef:
11 | //│ {fun f = (x::0,) => f(x,)
12 | //│ f(0,)
13 | //│ f(1,)}
14 | //│ End simpledef
15 | //│
16 | //│ res
17 | //│ Runtime error:
18 | //│ RangeError: Maximum call stack size exceeded
19 | //│ res
20 | //│ Runtime error:
21 | //│ RangeError: Maximum call stack size exceeded
22 |
--------------------------------------------------------------------------------
/compiler/shared/test/diff/Defunctionalize/SimpleClasses.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 | class Foo(val x: Int){
4 | fun bar(y) = x+y
5 | fun boo(z) = bar(z)+x
6 | }
7 | (Foo(1)).boo(2)
8 | //│ class Foo(x: Int) {
9 | //│ fun bar: Int -> Int
10 | //│ fun boo: Int -> Int
11 | //│ }
12 | //│ Int
13 | //│
14 | //│ Simpledef:
15 | //│ {class Foo(val x: Int,) {fun bar = (y::0,) => +(x, y,)
16 | //│ fun boo = (z::1,) => +(bar(z,), x,)}
17 | //│ let selRes$38 = '(' Foo(1,) ')' in case selRes$38 of { Foo => (selRes$38).boo(2,) }}
18 | //│ End simpledef
19 | //│
20 | //│ res
21 | //│ = 4
22 |
23 | class OneInt(val a: Int){
24 | fun fac: () -> Int
25 | fun fac = () ->
26 | if(a > 0) then (OneInt(a - 1)).fac() else 1
27 | }
28 | (OneInt(10)).fac()
29 | //│ class OneInt(a: Int) {
30 | //│ fun fac: () -> Int
31 | //│ }
32 | //│ Int
33 | //│
34 | //│ Simpledef:
35 | //│ {class OneInt(val a: Int,) {fun fac: () -> Int
36 | //│ fun fac = () => {if ('(' >(a, 0,) ')') then let selRes$20 = '(' OneInt(-(a, 1,),) ')' in case selRes$20 of { OneInt => (selRes$20).fac() } else 1}}
37 | //│ let selRes$50 = '(' OneInt(10,) ')' in case selRes$50 of { OneInt => (selRes$50).fac() }}
38 | //│ End simpledef
39 | //│
40 | //│ res
41 | //│ = 1
42 |
--------------------------------------------------------------------------------
/compiler/shared/test/diff/Defunctionalize/SimpleConditionals.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 | if true then 1 else 0
3 | if 1+1 > 1 then 1 - 1 else 1*1
4 | //│ Int
5 | //│
6 | //│ Simpledef:
7 | //│ {if (true) then 1 else 0
8 | //│ if (>(+(1, 1,), 1,)) then -(1, 1,) else *(1, 1,)}
9 | //│ End simpledef
10 | //│
11 | //│ res
12 | //│ = 1
13 | //│ res
14 | //│ = 0
15 |
16 | let b = true
17 | if(b) then 1 else 2
18 | //│ let b: true
19 | //│ 1 | 2
20 | //│
21 | //│ Simpledef:
22 | //│ {let b = true
23 | //│ if ('(' b ')') then 1 else 2}
24 | //│ End simpledef
25 | //│
26 | //│ b
27 | //│ = true
28 | //│ res
29 | //│ = 1
30 |
--------------------------------------------------------------------------------
/compiler/shared/test/diff/Defunctionalize/SimpleFunc.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 | fun f(x: Bool) = if x then 42 else 1337
4 | //│ fun f: (x: Bool) -> (1337 | 42)
5 | //│
6 | //│ Simpledef:
7 | //│ {fun f = (x: Bool,) => if (x) then 42 else 1337}
8 | //│ End simpledef
9 | //│
10 |
11 | fun foo() = 42
12 | //│ fun foo: () -> 42
13 | //│
14 | //│ Simpledef:
15 | //│ {fun foo = () => 42}
16 | //│ End simpledef
17 | //│
18 |
19 | fun f(x) =
20 | if(x > 0) then x+1 else x - 1
21 | f(2)+3
22 | //│ fun f: Int -> Int
23 | //│ Int
24 | //│
25 | //│ Simpledef:
26 | //│ {fun f = (x::0,) => {if ('(' >(x, 0,) ')') then +(x, 1,) else -(x, 1,)}
27 | //│ +(f(2,), 3,)}
28 | //│ End simpledef
29 | //│
30 | //│ res
31 | //│ = 6
32 |
33 | fun foo(x, #b) = if b then x else 1337
34 | let a = foo(42, true)
35 | let b = foo(23, false)
36 | //│ fun foo: forall 'a. ('a, Bool) -> (1337 | 'a)
37 | //│ let a: 1337 | 42
38 | //│ let b: 1337 | 23
39 | //│
40 | //│ Simpledef:
41 | //│ {fun foo = (x::1, #b::2,) => if (b) then x else 1337
42 | //│ let a = foo(42, true,)
43 | //│ let b = foo(23, false,)}
44 | //│ End simpledef
45 | //│
46 | //│ a
47 | //│ = 42
48 | //│ b
49 | //│ = 1337
50 |
--------------------------------------------------------------------------------
/compiler/shared/test/diff/Defunctionalize/TupleSelect.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | [0,"abc",()].2
5 | //│ ()
6 | //│
7 | //│ Simpledef:
8 | //│ {([0, "abc", undefined,]).2}
9 | //│ End simpledef
10 | //│
11 | //│ res
12 | //│ = undefined
13 |
--------------------------------------------------------------------------------
/compiler/shared/test/diff/Lifter/FunctionTypeAnnotations.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 | :ParseOnly
3 |
4 | :lift
5 | fun foo(x) =
6 | (y) => x+y
7 | foo(1)(2)
8 | foo(2)(2)
9 | //│ |#fun| |foo|(|x|)| |#=|→|(|y|)| |#=>| |x|+|y|←|↵|foo|(|1|)|(|2|)|↵|foo|(|2|)|(|2|)|
10 | //│ Parsed: {fun foo = (x,) => {('(' y ')',) => +(x, y,)}; foo(1,)(2,); foo(2,)(2,)}
11 | //│ Lifted:
12 | //│ TypingUnit {
13 | //│ class Lambda1$2$1([x,]) {fun apply = ('(' y ')',) => +((this).x, y,)}
14 | //│ fun foo$1 = (x,) => {{Lambda1$2$1(x,)}}
15 | //│ Code(List(foo$1(1,)(2,)))
16 | //│ Code(List(foo$1(2,)(2,)))
17 | //│ }
18 | //│
19 |
--------------------------------------------------------------------------------
/compiler/shared/test/diff/Lifter/LiftNew.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 | :lift
4 | class A(num: Int) {
5 | }
6 | new A(5)
7 | //│ Lifted:
8 | //│ TypingUnit {
9 | //│ class A$1([num: Int,]) {}
10 | //│ Code(List((new A$1)(5,)))
11 | //│ }
12 | //│ class A$1(num: Int)
13 | //│ A$1
14 | //│ res
15 | //│ = A$1 {}
16 |
--------------------------------------------------------------------------------
/compiler/shared/test/diff/Lifter/NestedClasses.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 | :e // FIXME: Nested class references not updated
4 | :lift
5 | class X() {
6 | class Y() {}
7 | }
8 | X.Y()
9 | //│ Lifted:
10 | //│ TypingUnit {
11 | //│ class X$1_Y$2([par$X$1,]) {}
12 | //│ class X$1([]) {}
13 | //│ Code(List((X$1).Y()))
14 | //│ }
15 | //│ ╔══[ERROR] Class parameters currently need type annotations
16 | //│ ╙──
17 | //│ ╔══[ERROR] Type mismatch in field selection:
18 | //│ ║ l.8: X.Y()
19 | //│ ║ ^^
20 | //│ ╙── expression of type `() -> X$1` does not have field 'Y'
21 | //│ class X$1_Y$2(par$X$1: error)
22 | //│ class X$1()
23 | //│ error
24 | //│ res
25 | //│ Runtime error:
26 | //│ TypeError: X$1.Y is not a function
27 |
--------------------------------------------------------------------------------
/compiler/shared/test/diff/Lifter/NestedFuncs.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 | :e // FIXME: Incorrect lifting
4 | :lift
5 | fun test(a) =
6 | let f(x) = a + x
7 | f
8 | test(6)(4)
9 | //│ Lifted:
10 | //│ TypingUnit {
11 | //│ let f$2 = (x, a,) => +(a, x,)
12 | //│ fun test$1 = (a,) => {f$2}
13 | //│ Code(List(test$1(6,)(4,)))
14 | //│ }
15 | //│ ╔══[ERROR] Type mismatch in application:
16 | //│ ║ l.8: test(6)(4)
17 | //│ ║ ^^^^
18 | //│ ╟── argument of type `[4]` does not match type `[?a, ?b]`
19 | //│ ║ l.8: test(6)(4)
20 | //│ ║ ^
21 | //│ ╟── Note: constraint arises from tuple literal:
22 | //│ ║ l.6: let f(x) = a + x
23 | //│ ╙── ^^^^^^
24 | //│ val f$2: (Int, Int) -> Int
25 | //│ fun test$1: anything -> (Int, Int) -> Int
26 | //│ Int | error
27 | //│ f$2
28 | //│ = [Function: f$2]
29 | //│ res
30 | //│ = NaN
31 |
--------------------------------------------------------------------------------
/compiler/shared/test/diff/Lifter/ParameterizedInheritance.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 | // FIXME: correctly lift parameterized inheritance
4 | :lift
5 | val c = 5
6 | class Sup(val a: Int){
7 | virtual fun foo = () -> a
8 | }
9 | class Sub(b: Int) extends Sup(b+b){
10 | }
11 | class Sub2(c: Int) extends Sub(c+c){
12 | fun foo = () -> c+c
13 | }
14 | (Sub(10)).foo()
15 | (Sub2(c)).foo()
16 | //│ Lifted:
17 | //│ TypingUnit {
18 | //│ class Sup$1([val a: Int,]) {fun foo = () => (this).a}
19 | //│ class Sub$2([b: Int,]): Sup$1(+((this).b, (this).b,),) {}
20 | //│ class Sub2$3([c: Int,]): Sub$2(+(c$1, c$1,),) {fun foo = () => +(c$1, c$1,)}
21 | //│ let c$1 = 5
22 | //│ Code(List(('(' Sub$2(10,) ')').foo()))
23 | //│ Code(List(('(' Sub2$3(c$1,) ')').foo()))
24 | //│ }
25 | //│ ╔══[ERROR] identifier not found: this
26 | //│ ╙──
27 | //│ ╔══[ERROR] identifier not found: this
28 | //│ ╙──
29 | //│ class Sup$1(a: Int) {
30 | //│ fun foo: () -> Int
31 | //│ }
32 | //│ class Sub$2(b: Int) extends Sup$1 {
33 | //│ fun foo: () -> Int
34 | //│ }
35 | //│ class Sub2$3(c: Int) extends Sub$2, Sup$1 {
36 | //│ fun foo: () -> Int
37 | //│ }
38 | //│ val c$1: 5
39 | //│ Int
40 | //│ Code generation encountered an error:
41 | //│ unguarded recursive use of by-value binding c$1
42 |
--------------------------------------------------------------------------------
/compiler/shared/test/diff/Lifter/TypedClassParams.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 | :lift
4 | class A() {}
5 | class B(foo: A) {}
6 | //│ Lifted:
7 | //│ TypingUnit {class A$1([]) {}; class B$2([foo: A$1,]) {}}
8 | //│ class A$1()
9 | //│ class B$2(foo: A$1)
10 |
--------------------------------------------------------------------------------
/flake.nix:
--------------------------------------------------------------------------------
1 | {
2 | description = "mlscript";
3 |
4 | inputs.nixpkgs.url = "github:NixOS/nixpkgs";
5 | inputs.flake-utils.url = "github:numtide/flake-utils";
6 | inputs.sbt-deriv.url = "github:zaninime/sbt-derivation";
7 | inputs.sbt-deriv.inputs.nixpkgs.follows = "nixpkgs";
8 |
9 | outputs = { self, nixpkgs, flake-utils, sbt-deriv }:
10 | flake-utils.lib.eachDefaultSystem
11 | (system:
12 | let
13 | sbtOverlay = self: super: {
14 | sbt = super.sbt.override { jre = super.jdk8_headless; };
15 | };
16 | pkgs = import nixpkgs {
17 | inherit system;
18 | overlays = [ sbtOverlay ];
19 | };
20 | in with pkgs; {
21 | devShells.default = mkShell {
22 | buildInputs = [
23 | clang
24 | gcc
25 | gnumake
26 | boost
27 | gmp
28 | mimalloc
29 | sbt
30 | nodejs_22
31 | ];
32 | };
33 | });
34 | }
--------------------------------------------------------------------------------
/js/src/main/scala/fansi/Str.scala:
--------------------------------------------------------------------------------
1 | // Temporary shims since fansi doesn't seem to be released for this Scala version yet
2 |
3 | package fansi
4 |
5 | import scala.language.implicitConversions
6 |
7 | class Str(underlying: CharSequence) {
8 | def plainText(): String = s"$underlying"
9 | override def toString(): String = s"$underlying"
10 | }
11 | object Str {
12 | implicit def implicitApply(x: CharSequence): Str = new Str(x)
13 | def join(args: Str*): Str = args.foldLeft("")(_ ++ _.plainText())
14 | }
15 |
--------------------------------------------------------------------------------
/local_testing.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | MLscript demonstration
7 |
8 |
9 | MLscript demonstration
10 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "mlscript",
3 | "lockfileVersion": 2,
4 | "requires": true,
5 | "packages": {
6 | "": {
7 | "dependencies": {
8 | "typescript": "^4.7.4"
9 | }
10 | },
11 | "node_modules/typescript": {
12 | "version": "4.7.4",
13 | "resolved": "https://registry.npmmirror.com/typescript/-/typescript-4.7.4.tgz",
14 | "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==",
15 | "bin": {
16 | "tsc": "bin/tsc",
17 | "tsserver": "bin/tsserver"
18 | },
19 | "engines": {
20 | "node": ">=4.2.0"
21 | }
22 | }
23 | },
24 | "dependencies": {
25 | "typescript": {
26 | "version": "4.7.4",
27 | "resolved": "https://registry.npmmirror.com/typescript/-/typescript-4.7.4.tgz",
28 | "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ=="
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": {
3 | "typescript": "^4.7.4"
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/project/build.properties:
--------------------------------------------------------------------------------
1 | sbt.version=1.10.1
2 |
--------------------------------------------------------------------------------
/project/plugins.sbt:
--------------------------------------------------------------------------------
1 | addSbtPlugin("org.wartremover" % "sbt-wartremover" % "3.2.0")
2 | addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.16.0")
3 | addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "1.2.0")
4 |
--------------------------------------------------------------------------------
/shared/src/main/scala/mlscript/codegen/Error.scala:
--------------------------------------------------------------------------------
1 | package mlscript.codegen
2 |
3 | import scala.collection.mutable.ArrayBuffer
4 |
5 | final case class CodeGenError(message: String) extends Exception(message)
6 |
7 | final case class UnimplementedError(symbol: StubValueSymbol)
8 | extends Exception({
9 | val names = new ArrayBuffer[String]()
10 | var current: Option[StubValueSymbol] = Some(symbol)
11 | while (
12 | current match {
13 | case Some(sym) =>
14 | names += sym.lexicalName
15 | current = sym.previous
16 | true
17 | case None => false
18 | }
19 | ) ()
20 | val sep = ", "
21 | val concat = {
22 | val joined = names.mkString(sep)
23 | val pos = joined.lastIndexOf(sep)
24 | if (pos > -1) {
25 | joined.substring(0, pos) + " and " + joined.substring(pos + sep.length)
26 | } else {
27 | joined
28 | }
29 | }
30 | val be = if (names.lengthIs > 1) "are" else "is"
31 | s"$concat $be not implemented"
32 | })
33 |
--------------------------------------------------------------------------------
/shared/src/main/scala/mlscript/package.scala:
--------------------------------------------------------------------------------
1 | import mlscript.utils._
2 | import mlscript.utils.shorthands._
3 |
4 | package object mlscript {
5 |
6 | type Raise = Diagnostic => Unit
7 |
8 | val ExtrusionPrefix: Str = "??"
9 |
10 | }
11 |
--------------------------------------------------------------------------------
/shared/src/main/scala/mlscript/pretyper/Diagnosable.scala:
--------------------------------------------------------------------------------
1 | package mlscript
2 | package pretyper
3 |
4 | import scala.collection.mutable.Buffer
5 | import Diagnostic.Source, Message.MessageContext
6 | import mlscript.utils._, shorthands._
7 |
8 | /**
9 | * A trait containing a mutable buffer of diagnostics.
10 | */
11 | trait Diagnosable {
12 | private val diagnosticBuffer = Buffer.empty[Diagnostic]
13 |
14 | protected def raise(diagnostics: Diagnostic): Unit =
15 | diagnosticBuffer += diagnostics
16 |
17 | protected def raiseMany(diagnostics: IterableOnce[Diagnostic]): Unit =
18 | diagnosticBuffer ++= diagnostics
19 |
20 | protected def raiseError(source: Source, messages: (Message -> Opt[Loc])*): Unit =
21 | raise(ErrorReport(messages.toList, newDefs = true, source))
22 |
23 | protected def raiseWarning(source: Source, messages: (Message -> Opt[Loc])*): Unit =
24 | raise(WarningReport(messages.toList, newDefs = true, source))
25 |
26 | @inline final def filterDiagnostics(f: Diagnostic => Bool): Ls[Diagnostic] =
27 | diagnosticBuffer.iterator.filter(f).toList
28 |
29 | @inline final def getDiagnostics: Ls[Diagnostic] = diagnosticBuffer.toList
30 | }
31 |
--------------------------------------------------------------------------------
/shared/src/main/scala/mlscript/utils/FastParseHelpers.scala:
--------------------------------------------------------------------------------
1 | package mlscript
2 |
3 | import mlscript.utils._, shorthands._
4 |
5 | class FastParseHelpers(val blockStr: Str, val lines: collection.IndexedSeq[Str]) {
6 | def this(lines: IndexedSeq[Str]) = this(lines.mkString("\n"), lines)
7 | def this(blockStr: Str) = this(blockStr, blockStr.splitSane('\n'))
8 |
9 | // this line-parsing logic was copied from fastparse internals:
10 | val lineNumberLookup: Array[Int] = fastparse.internal.Util.lineNumberLookup(blockStr)
11 | def getLineColAt(index: Int): (Int, String, Int) = {
12 | val lineNum = lineNumberLookup.indexWhere(_ > index) match {
13 | case -1 => lineNumberLookup.length
14 | case n => math.max(1, n)
15 | }
16 | val idx = lineNum.min(lines.length) - 1
17 | val colNum = index - lineNumberLookup(idx) + 1
18 | val lineStr = lines(idx)
19 | (lineNum, lineStr, colNum)
20 | }
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/shared/src/main/scala/mlscript/utils/Identity.scala:
--------------------------------------------------------------------------------
1 | package mlscript.utils
2 |
3 |
4 | class Identity[T <: AnyRef](val value: T) {
5 |
6 | override def equals(other: Any): Boolean = other match {
7 | case that: Identity[_] => (that.value: Any) is this.value
8 | case _ => false
9 | }
10 |
11 | override def hashCode(): Int = System.identityHashCode(value)
12 |
13 | }
14 |
15 |
--------------------------------------------------------------------------------
/shared/src/main/scala/mlscript/utils/Lazy.scala:
--------------------------------------------------------------------------------
1 | package mlscript.utils
2 |
3 | import shorthands._
4 |
5 | abstract class Box[+A] {
6 | def get: Opt[A]
7 | def get_! : A
8 | def isComputing: Bool
9 | }
10 |
11 | class Eager[+A](val value: A) extends Box[A] {
12 | def isComputing = false
13 | lazy val get = S(value)
14 | def get_! = value
15 | }
16 |
17 | class Lazy[A](thunk: => A) extends Box[A] {
18 | def isComputing = _isComputing
19 | private var _isComputing = false
20 | private var _value: Opt[A] = N
21 | def get = if (_isComputing) N else S(get_!)
22 | def get_! = {
23 | assert(!_isComputing)
24 | _compute
25 | }
26 | private def _compute = {
27 | _isComputing = true
28 | try {
29 | val v = thunk
30 | _value = S(v)
31 | v
32 | } finally {
33 | _isComputing = false
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/shared/src/main/scala/mlscript/utils/algorithms.scala:
--------------------------------------------------------------------------------
1 | package mlscript.utils
2 |
3 | import scala.annotation.tailrec
4 | import scala.collection.immutable.SortedMap
5 |
6 | object algorithms {
7 | final class CyclicGraphError(message: String) extends Exception(message)
8 |
9 | /**
10 | * Sort a graph topologically.
11 | *
12 | * @param edges edges (target, source) in the directed acyclic graph
13 | * @param nodes provide if you want to include some isolated nodes in the result
14 | * @return
15 | */
16 | def topologicalSort[A: Ordering](edges: Iterable[(A, A)], nodes: Iterable[A] = Nil): Iterable[A] = {
17 | @tailrec
18 | def sort(toPreds: SortedMap[A, Set[A]], done: Iterable[A]): Iterable[A] = {
19 | val (noPreds, hasPreds) = toPreds.partition { _._2.isEmpty }
20 | if (noPreds.isEmpty) {
21 | if (hasPreds.isEmpty) done else throw new CyclicGraphError(hasPreds.toString)
22 | } else {
23 | val found = noPreds.map { _._1 }
24 | sort(SortedMap.from(hasPreds.view.mapValues(_ -- found)), done ++ found)
25 | }
26 | }
27 | val toPred = edges.foldLeft(SortedMap.from(nodes.map { _ -> Set.empty[A] })) { (acc, e) =>
28 | acc + (e._1 -> (acc.getOrElse(e._1, Set()) + e._2)) + (e._2 -> acc.getOrElse(e._2, Set()))
29 | }
30 | sort(toPred, Seq())
31 | }
32 | }
--------------------------------------------------------------------------------
/shared/src/test/diff/basics/AsBindings.fun:
--------------------------------------------------------------------------------
1 |
2 | let f x =
3 | discard / x as { v: (y) } // TODO accept plain `y`
4 | log / v
5 | log / y + 1
6 | //│ f: {v: int} -> unit
7 |
8 | let f x =
9 | discard / x as { v: (y) } // TODO accept plain `y`
10 | log / v + 1
11 | log / y
12 | //│ f: {v: int} -> unit
13 |
14 |
15 |
--------------------------------------------------------------------------------
/shared/src/test/diff/basics/ExplicitDatatypes.fun:
--------------------------------------------------------------------------------
1 |
2 | data Left v
3 | data Right v
4 | //│ Defined class Left[+v]
5 | //│ Defined class Right[+v]
6 | //│ Left: 'a -> Left['a]
7 | //│ Right: 'a -> Right['a]
8 |
9 | let Either l r = Left l | Right r // TODO actual type parameters
10 | //│ Either: 'a -> 'b -> (Left['a] | Right['b])
11 |
12 | Either 1 2
13 | //│ res: Left[1] | Right[2]
14 |
15 | res.v
16 | //│ res: 1 | 2
17 |
18 |
--------------------------------------------------------------------------------
/shared/src/test/diff/basics/Flow.fun:
--------------------------------------------------------------------------------
1 |
2 | :p
3 | data L x
4 | data R x
5 | //│ Parsed: data L(...x); data R(...x);
6 | //│ Desugared: class L[x]: {x: x}
7 | //│ Desugared: class R[x]: {x: x}
8 | //│ Desugared: def L: forall x. (...x) -> L[x]
9 | //│ AST: Def(false,Var(L),Right(PolyType(List(Left(TypeName(x))),Function(TypeName(x),AppliedType(TypeName(L),List(TypeName(x)))))),true)
10 | //│ Desugared: def R: forall x. (...x) -> R[x]
11 | //│ AST: Def(false,Var(R),Right(PolyType(List(Left(TypeName(x))),Function(TypeName(x),AppliedType(TypeName(R),List(TypeName(x)))))),true)
12 | //│ Defined class L[+x]
13 | //│ Defined class R[+x]
14 | //│ L: 'a -> L['a]
15 | //│ R: 'a -> R['a]
16 |
17 | // TODO flow-type
18 | :e
19 | let f x = if x is L y then y else 0
20 | //│ ╔══[ERROR] Unsupported pattern shape:
21 | //│ ║ l.19: let f x = if x is L y then y else 0
22 | //│ ╙── ^^^
23 | //│ ╔══[ERROR] identifier not found: y
24 | //│ ║ l.19: let f x = if x is L y then y else 0
25 | //│ ╙── ^
26 | //│ f: error -> (0 | error)
27 |
28 | // TODO
29 | // true and false
30 | // :e
31 | // 1 and 2
32 |
33 |
--------------------------------------------------------------------------------
/shared/src/test/diff/basics/Iso.fun:
--------------------------------------------------------------------------------
1 | // A file to isolating tests for easier debugging
2 |
3 |
4 |
--------------------------------------------------------------------------------
/shared/src/test/diff/basics/RecFuns.fun:
--------------------------------------------------------------------------------
1 |
2 | // From a comment on the Simple-sub blog post:
3 |
4 | let rec r a = r
5 | //│ r: 'r
6 | //│ where
7 | //│ 'r :> anything -> 'r
8 |
9 | let join a b = if true then a else b
10 | //│ join: 'a -> 'a -> 'a
11 |
12 | // "Lateral" hash consing
13 | let s = join r r
14 | //│ s: 'r
15 | //│ where
16 | //│ 'r :> anything -> 'r
17 |
18 |
--------------------------------------------------------------------------------
/shared/src/test/diff/basics/Twice.fun:
--------------------------------------------------------------------------------
1 |
2 | let twice f x = f / f x
3 | //│ twice: ('a -> 'b & 'b -> 'c) -> 'a -> 'c
4 | // Note: the pretty-printed type of `twice` *used to be* simplified to ('a -> ('a & 'b)) -> 'a -> 'b
5 | // (another equivalent simplification is ('a | 'b -> 'a) -> 'b -> 'a);
6 | // this simplification lost some information in the context of first-class polymorphism
7 | // because function types effectively become non-mergeable without losing precsion...
8 | // (Also see this HN thread: https://news.ycombinator.com/item?id=13783237)
9 |
10 | twice(x => x + 1)
11 | //│ res: int -> int
12 |
13 | twice twice
14 | //│ res: ('a -> 'b & 'b -> ('a & 'c)) -> 'a -> 'c
15 |
16 | let f = x => 1, x
17 | //│ f: 'a -> (1, 'a,)
18 |
19 | // Note: now that we instantiate during constraint solving instead of on variable reference,
20 | // we get the more useful type: 'a -> (1, (1, 'a,),).
21 | // Previously, we were getting: 'a -> ((1, 'c | 'b | 'a,) as 'b)
22 | twice f
23 | //│ res: 'a -> (1, (1, 'a,),)
24 |
25 | twice / x => x, x
26 | //│ res: 'a -> (('a, 'a,), ('a, 'a,),)
27 |
28 | let one = twice (o => o.x) { x: { x: 1 } }
29 | //│ one: 1
30 |
31 |
32 |
--------------------------------------------------------------------------------
/shared/src/test/diff/codegen/Escape.mls:
--------------------------------------------------------------------------------
1 | ()
2 | //│ res: ()
3 | //│ = []
4 |
5 | :js
6 | :escape
7 | def console: nothing
8 | //│ // Query 1 is empty
9 | //│ // End of generated code
10 | //│ console: nothing
11 | //│ =
12 |
13 | :js
14 | console.log "hello"
15 | //│ // Query 1
16 | //│ res = console.log("hello");
17 | //│ // End of generated code
18 | //│ res: nothing
19 | //│ = undefined
20 |
21 | :js
22 | 0
23 | //│ // Query 1
24 | //│ res = 0;
25 | //│ // End of generated code
26 | //│ res: 0
27 | //│ = 0
28 |
--------------------------------------------------------------------------------
/shared/src/test/diff/codegen/LogInfo.mls:
--------------------------------------------------------------------------------
1 |
2 | :js
3 | log 1
4 | //│ // Prelude
5 | //│ function log(x) {
6 | //│ return console.info(x);
7 | //│ }
8 | //│ let res;
9 | //│ // Query 1
10 | //│ res = log(1);
11 | //│ // End of generated code
12 | //│ = undefined
13 | //│ // Output
14 | //│ 1
15 |
16 | :escape
17 | def console: nothing
18 | //│ console: nothing
19 | //│ =
20 |
21 | console.log 1
22 | //│ res: nothing
23 | //│ = undefined
24 |
25 | console.info(1)
26 | //│ res: nothing
27 | //│ = undefined
28 | //│ // Output
29 | //│ 1
30 |
31 |
--------------------------------------------------------------------------------
/shared/src/test/diff/codegen/NewClasses.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | class C[A](n: A) {
5 | fun f = g
6 | fun g = 0
7 | }
8 | //│ class C[A](n: A) {
9 | //│ fun f: 0
10 | //│ fun g: 0
11 | //│ }
12 |
13 |
14 |
--------------------------------------------------------------------------------
/shared/src/test/diff/codegen/NuFuns.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | :js
5 | fun foo =
6 | let bar(x) = x + 1
7 | bar(10)
8 | //│ fun foo: Int
9 | //│ // Prelude
10 | //│ let res;
11 | //│ class TypingUnit {}
12 | //│ const typing_unit = new TypingUnit;
13 | //│ // Query 1
14 | //│ globalThis.foo = function foo() {
15 | //│ return ((() => {
16 | //│ let bar = (x) => x + 1;
17 | //│ return bar(10);
18 | //│ })());
19 | //│ };
20 | //│ // End of generated code
21 |
22 | fun foo =
23 | class C(a: Int) { fun bar(x) = a + x + 1 }
24 | C(100).bar(10)
25 | foo
26 | //│ fun foo: Int
27 | //│ Int
28 | //│ res
29 | //│ = 111
30 |
31 |
32 | fun main =
33 | log("Hello")
34 | main
35 | //│ fun main: ()
36 | //│ ()
37 | //│ res
38 | //│ = undefined
39 | //│ // Output
40 | //│ Hello
41 |
42 | fun main =
43 | log("Hello")
44 | //│ fun main: ()
45 |
46 | main
47 | //│ ()
48 | //│ res
49 | //│ = undefined
50 | //│ // Output
51 | //│ Hello
52 |
53 |
54 | fun main =
55 | mixin B { log(1) }
56 | log(0)
57 | module M extends B
58 | log(2)
59 | main
60 | //│ fun main: ()
61 | //│ ()
62 | //│ res
63 | //│ = undefined
64 | //│ // Output
65 | //│ 0
66 | //│ 1
67 | //│ 2
68 |
69 |
--------------------------------------------------------------------------------
/shared/src/test/diff/codegen/NuParentheses.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | :js
5 | 16 / (2 / 2)
6 | //│ Num
7 | //│ // Prelude
8 | //│ let res;
9 | //│ class TypingUnit {}
10 | //│ const typing_unit = new TypingUnit;
11 | //│ // Query 1
12 | //│ res = 16 / (2 / 2);
13 | //│ // End of generated code
14 | //│ res
15 | //│ = 16
16 |
17 | :js
18 | 1 - (3 - 5)
19 | //│ Int
20 | //│ // Prelude
21 | //│ class TypingUnit1 {}
22 | //│ const typing_unit1 = new TypingUnit1;
23 | //│ // Query 1
24 | //│ res = 1 - (3 - 5);
25 | //│ // End of generated code
26 | //│ res
27 | //│ = 3
28 |
29 |
30 | fun (--) minusminus(a, b) = a - b
31 | //│ fun (--) minusminus: (Int, Int) -> Int
32 |
33 | :js
34 | 1 -- (3 -- 5)
35 | //│ Int
36 | //│ // Prelude
37 | //│ class TypingUnit3 {}
38 | //│ const typing_unit3 = new TypingUnit3;
39 | //│ // Query 1
40 | //│ res = minusminus(1, minusminus(3, 5));
41 | //│ // End of generated code
42 | //│ res
43 | //│ = 3
44 |
45 |
46 | fun (-+-) complex(a, b) = a - 2*b
47 | //│ fun (-+-) complex: (Int, Int) -> Int
48 |
49 | :js
50 | 1 -+- (3 -+- 5)
51 | //│ Int
52 | //│ // Prelude
53 | //│ class TypingUnit5 {}
54 | //│ const typing_unit5 = new TypingUnit5;
55 | //│ // Query 1
56 | //│ res = complex(1, complex(3, 5));
57 | //│ // End of generated code
58 | //│ res
59 | //│ = 15
60 |
61 |
62 |
--------------------------------------------------------------------------------
/shared/src/test/diff/codegen/NuReplHost.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | // * This should crash due to `error`,
5 | // * but the crash is somehow swallowed and we get the result of the previous statement instead!
6 | // * The same happens with any other side effect, like `log(...)`
7 | // * Note: this doesn't happen if the last line is in a spearate diff-test block
8 | :showRepl
9 | :re
10 | fun foo(x) = error
11 | let r = foo(1)
12 | //│ fun foo: anything -> nothing
13 | //│ let r: nothing
14 | //│ ┌ Block at NuReplHost.mls:10
15 | //│ ├─┬ Prelude
16 | //│ │ ├── Code
17 | //│ │ │ function error() {
18 | //│ │ │ throw new Error("an error was thrown");
19 | //│ │ │ }
20 | //│ │ │ let res;
21 | //│ │ │ class TypingUnit {}
22 | //│ │ │ const typing_unit = new TypingUnit;
23 | //│ │ └── Reply
24 | //│ │ undefined
25 | //│ ├─┬ Query 1/2
26 | //│ │ ├── Prelude:
27 | //│ │ ├── Code:
28 | //│ │ ├── globalThis.foo = function foo(x) {
29 | //│ │ ├── return error();
30 | //│ │ ├── };
31 | //│ │ ├── Intermediate: [Function: foo]
32 | //│ │ └── Reply: [success] [Function: foo]
33 | //│ └─┬ Query 2/2
34 | //│ ├── Prelude:
35 | //│ ├── Code:
36 | //│ ├── globalThis.r = foo(1);
37 | //│ └── Reply: [runtime error] Error: an error was thrown
38 | //│ r
39 | //│ Runtime error:
40 | //│ Error: an error was thrown
41 |
42 | :re
43 | r
44 | //│ nothing
45 | //│ res
46 | //│ Runtime error:
47 | //│ ReferenceError: r is not defined
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/shared/src/test/diff/codegen/ParameterPattern.mls:
--------------------------------------------------------------------------------
1 | // This test file ensures that parameter destruction patterns are translated correctly.
2 | ()
3 | //│ res: ()
4 | //│ = []
5 |
6 | :js
7 | def volatile ((this, break)) = this + break
8 | //│ // Query 1
9 | //│ globalThis.volatile1 = function volatile1([
10 | //│ this$,
11 | //│ break$
12 | //│ ]) {
13 | //│ return this$ + break$;
14 | //│ };
15 | //│ // End of generated code
16 | //│ volatile: ((int, int,),) -> int
17 | //│ = [Function: volatile1]
18 |
19 | :js
20 | def volatile1 { debugger; continue } = debugger + continue
21 | //│ // Query 1
22 | //│ globalThis.volatile11 = function volatile11({
23 | //│ "debugger": debugger$,
24 | //│ "continue": continue$
25 | //│ }) {
26 | //│ return debugger$ + continue$;
27 | //│ };
28 | //│ // End of generated code
29 | //│ volatile1: {continue: int, debugger: int} -> int
30 | //│ = [Function: volatile11]
31 |
32 | :js
33 | def volatile2 export = export + 2
34 | //│ // Query 1
35 | //│ globalThis.volatile2 = function volatile2(export$) {
36 | //│ return export$ + 2;
37 | //│ };
38 | //│ // End of generated code
39 | //│ volatile2: int -> int
40 | //│ = [Function: volatile2]
41 |
--------------------------------------------------------------------------------
/shared/src/test/diff/codegen/PatternMatch.mls:
--------------------------------------------------------------------------------
1 | trait T
2 | //│ Defined trait T
3 |
4 | // Traits with Primitives
5 |
6 | t = T 1
7 | //│ t: 1 & #T
8 | //│ = [Number: 1]
9 |
10 | t + 1
11 | //│ res: int
12 | //│ = 2
13 |
14 | case t of { T -> 0 }
15 | //│ res: 0
16 | //│ = 0
17 |
--------------------------------------------------------------------------------
/shared/src/test/diff/codegen/Res.mls:
--------------------------------------------------------------------------------
1 | // This test tracks how `res` works.
2 |
3 | 0
4 | //│ res: 0
5 | //│ = 0
6 |
7 | :js
8 | res + 1
9 | //│ // Query 1
10 | //│ res = res + 1;
11 | //│ // End of generated code
12 | //│ res: int
13 | //│ = 1
14 |
15 | :js
16 | res + 1
17 | //│ // Query 1
18 | //│ res = res + 1;
19 | //│ // End of generated code
20 | //│ res: int
21 | //│ = 2
22 |
23 | :js
24 | res + 1
25 | //│ // Query 1
26 | //│ res = res + 1;
27 | //│ // End of generated code
28 | //│ res: int
29 | //│ = 3
30 |
31 | :js
32 | res + 1
33 | //│ // Query 1
34 | //│ res = res + 1;
35 | //│ // End of generated code
36 | //│ res: int
37 | //│ = 4
38 |
39 | :js
40 | res + 1
41 | //│ // Query 1
42 | //│ res = res + 1;
43 | //│ // End of generated code
44 | //│ res: int
45 | //│ = 5
46 |
47 | :js
48 | res == 4
49 | //│ // Query 1
50 | //│ res = res == 4;
51 | //│ // End of generated code
52 | //│ res: bool
53 | //│ = false
54 |
55 | :js
56 | def res = 0
57 | //│ // Query 1
58 | //│ globalThis.res1 = function res1() {
59 | //│ return 0;
60 | //│ };
61 | //│ // End of generated code
62 | //│ res: 0
63 | //│ = [Function: res1]
64 |
65 | // However, we can shadow `res`!
66 |
67 | :js
68 | res + 1
69 | //│ // Query 1
70 | //│ res = res1() + 1;
71 | //│ // End of generated code
72 | //│ res: int
73 | //│ = 1
74 |
75 | :js
76 | res + 1
77 | //│ // Query 1
78 | //│ res = res + 1;
79 | //│ // End of generated code
80 | //│ res: int
81 | //│ = 2
82 |
--------------------------------------------------------------------------------
/shared/src/test/diff/codegen/Shadowing.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | :js
5 | x =>
6 | x =>
7 | x + 1
8 | //│ anything -> Int -> Int
9 | //│ // Prelude
10 | //│ let res;
11 | //│ class TypingUnit {}
12 | //│ const typing_unit = new TypingUnit;
13 | //│ // Query 1
14 | //│ res = ((x) => (() => {
15 | //│ return ((x) => (() => {
16 | //│ return x + 1;
17 | //│ })());
18 | //│ })());
19 | //│ // End of generated code
20 | //│ res
21 | //│ = [Function: res]
22 |
23 |
24 |
--------------------------------------------------------------------------------
/shared/src/test/diff/codegen/Unicode.mls:
--------------------------------------------------------------------------------
1 |
2 | :js
3 | "τ → π"
4 | //│ // Prelude
5 | //│ let res;
6 | //│ // Query 1
7 | //│ res = "\u03C4 \u2192 \u03C0";
8 | //│ // End of generated code
9 | //│ res: "τ → π"
10 | //│ = 'τ → π'
11 |
12 | :js
13 | "🌮"
14 | //│ // Query 1
15 | //│ res = "\uD83C\uDF2E";
16 | //│ // End of generated code
17 | //│ res: "🌮"
18 | //│ = '🌮'
19 |
--------------------------------------------------------------------------------
/shared/src/test/diff/codegen/While.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | // * TODO improve code-gen (no immediately-applied lambdas)
5 | :js
6 | mut let i = 0
7 | while i < 10 do
8 | log(i)
9 | set i = i + 1
10 | i
11 | //│ mut let i: Int
12 | //│ Int
13 | //│ // Prelude
14 | //│ function log(x) {
15 | //│ return console.info(x);
16 | //│ }
17 | //│ let res;
18 | //│ class TypingUnit {}
19 | //│ const typing_unit = new TypingUnit;
20 | //│ // Query 1
21 | //│ globalThis.i = 0;
22 | //│ // Query 2
23 | //│ res = (() => {
24 | //│ while (i < 10) {
25 | //│ (() => {
26 | //│ log(i);
27 | //│ return void(i = i + 1);
28 | //│ })()
29 | //│ }
30 | //│ })();
31 | //│ // Query 3
32 | //│ res = i;
33 | //│ // End of generated code
34 | //│ i
35 | //│ = 0
36 | //│ res
37 | //│ = undefined
38 | //│ // Output
39 | //│ 0
40 | //│ 1
41 | //│ 2
42 | //│ 3
43 | //│ 4
44 | //│ 5
45 | //│ 6
46 | //│ 7
47 | //│ 8
48 | //│ 9
49 | //│ res
50 | //│ = 10
51 |
52 | i
53 | //│ Int
54 | //│ res
55 | //│ = 10
56 |
57 |
58 | let foo =
59 | if true then (set i = 0), () else ()
60 | ()
61 | //│ let foo: ()
62 | //│ foo
63 | //│ = undefined
64 |
65 | mut let min = 123
66 | let go =
67 | if true then set min = 0 else ()
68 | 1
69 | //│ mut let min: 0 | 123
70 | //│ let go: 1
71 | //│ min
72 | //│ = 123
73 | //│ go
74 | //│ = 1
75 |
76 |
77 |
--------------------------------------------------------------------------------
/shared/src/test/diff/fcp-lit/Jim.mls:
--------------------------------------------------------------------------------
1 | :NoRecursiveTypes
2 |
3 |
4 | // TODO also try stuff from his intersection type systems
5 |
6 |
7 | // ============ A Polar Type System (System P) ============
8 |
9 | // λf. f (λx. x)
10 | fun f -> f (fun x -> x)
11 | //│ res: ((forall 'a. 'a -> 'a) -> 'b) -> 'b
12 | //│ = [Function: res]
13 |
14 | // λy. y y
15 | fun y -> y y
16 | //│ res: ('a -> 'b & 'a) -> 'b
17 | //│ = [Function: res]
18 |
19 | // Typeable in P; not in ML nor I2:
20 | // (λf. f (λx. x)) (λy. y y)
21 | (fun f -> f (fun x -> x)) (fun y -> y y)
22 | //│ res: 'a -> 'a
23 | //│ = [Function (anonymous)]
24 |
25 |
26 |
--------------------------------------------------------------------------------
/shared/src/test/diff/fcp/AA.mls:
--------------------------------------------------------------------------------
1 |
2 | // https://github.com/cliffclick/aa/issues/28
3 | pair x y = (x, y)
4 | I = (fun x->x);
5 | K = (fun x->(fun y->x));
6 | W = (fun x->(x x));
7 | term = (fun z->(fun y ->((y (z I))(z K))));
8 | test = (term W);
9 | (test (fun x -> (fun y -> (pair (x 3) (((y "a") "b") "c")) ) ))
10 | //│ pair: 'a -> 'b -> ('a, 'b,)
11 | //│ = [Function: pair]
12 | //│ I: 'a -> 'a
13 | //│ = [Function: I]
14 | //│ K: 'a -> anything -> 'a
15 | //│ = [Function: K]
16 | //│ W: ('a -> 'b & 'a) -> 'b
17 | //│ = [Function: W]
18 | //│ term: ((forall 'a. 'a -> 'a) -> 'b & (forall 'c. 'c -> anything -> 'c) -> 'd) -> ('b -> 'd -> 'e) -> 'e
19 | //│ = [Function: term]
20 | //│ test: ((forall 'a. 'a -> 'a) -> (forall 'b. anything -> 'b -> anything -> 'b) -> 'c) -> 'c
21 | //│ = [Function (anonymous)]
22 | //│ res: (3, "b",)
23 | //│ = [ 3, 'b' ]
24 |
25 |
--------------------------------------------------------------------------------
/shared/src/test/diff/fcp/Aliases.mls:
--------------------------------------------------------------------------------
1 | :NoJS
2 |
3 |
4 | type Sid = forall 'A. 'A -> 'A
5 | //│ Defined type alias Sid
6 |
7 | type Sid2 = 'B -> 'B
8 | //│ Defined type alias Sid2
9 |
10 | type A1 = forall 'S. 'S -> ('S | Sid)
11 | //│ Defined type alias A1
12 |
13 |
14 |
15 | def a: Sid -> Sid
16 | //│ a: Sid -> Sid
17 |
18 | a : Sid2 -> Sid2 : Sid -> Sid
19 | //│ res: Sid -> Sid
20 |
21 | a = error : A1
22 | //│ A1
23 | //│ <: a:
24 | //│ Sid -> Sid
25 |
26 |
27 | // def f: A1 -> Sid
28 | def f: A1 -> A1
29 | //│ f: A1 -> A1
30 |
31 | def f (x: A1) = x id
32 | //│ A1 -> ('a -> 'a | Sid)
33 | //│ <: f:
34 | //│ A1 -> A1
35 |
36 | // def f: A1 -> Sid
37 | def f: A1 -> A1
38 | //│ f: A1 -> A1
39 |
40 | def f (x: Sid -> Sid) = x (fun y -> y)
41 | //│ (Sid -> Sid) -> Sid
42 | //│ <: f:
43 | //│ A1 -> A1
44 |
45 |
46 | type A2 = forall 'a. (('a | Sid) -> 'a) -> 'a -> ('a | Sid)
47 | type A3 = (Sid -> Sid) -> Sid -> Sid
48 | //│ Defined type alias A2
49 | //│ Defined type alias A3
50 |
51 | error : A2 : A3
52 | //│ res: A3
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/shared/src/test/diff/fcp/NoRecursiveTypes.mls:
--------------------------------------------------------------------------------
1 | :NoRecursiveTypes
2 |
3 |
4 | :e
5 | foo =
6 | let rec f x = f x.a in 0
7 | //│ ╔══[ERROR] Inferred recursive type: 'a
8 | //│ where
9 | //│ 'a <: {a: 'a}
10 | //│ ║ l.6: let rec f x = f x.a in 0
11 | //│ ╙── ^^^
12 | //│ foo: 0
13 | //│ = 0
14 |
15 |
16 |
--------------------------------------------------------------------------------
/shared/src/test/diff/fcp/OverloadSimplif.mls:
--------------------------------------------------------------------------------
1 | :NoJS
2 |
3 |
4 | def foo f x =
5 | if true then f x
6 | else f (id x)
7 | //│ foo: ('a -> 'b) -> 'a -> 'b
8 |
9 | def foo k f x =
10 | if true then f x
11 | else f (k x)
12 | //│ foo: ('a -> 'b) -> (('a | 'b) -> 'c) -> 'a -> 'c
13 |
14 | // * Not ethe simplified type, similar to the one above, as expected
15 | foo id
16 | //│ res: ('a -> 'b) -> 'a -> 'b
17 |
18 |
19 | def f: ('a -> 'b & 'c -> 'b & 'a -> 'c) -> 'a -> 'b
20 | //│ f: (('a | 'c) -> 'b & 'a -> 'c) -> 'a -> 'b
21 |
22 | def f: int -> int & nothing -> string
23 | //│ f: int -> int
24 |
25 | def f: int -> int & string -> anything
26 | //│ f: int -> int & string -> anything
27 |
28 | def f: int -> int & 1 -> number
29 | //│ f: int -> int
30 |
31 | def f: int -> int & 'a -> 'a
32 | //│ f: int -> int & 'a -> 'a
33 |
34 |
35 |
--------------------------------------------------------------------------------
/shared/src/test/diff/fcp/PolyParams.mls:
--------------------------------------------------------------------------------
1 | :NoRecursiveTypes
2 |
3 |
4 | def foo(f: forall 'a. 'a -> 'a) =
5 | (f 1, f true)
6 | //│ foo: (forall 'a. 'a -> 'a) -> (1, true,)
7 | //│ = [Function: foo]
8 |
9 | fooid = foo id
10 | //│ fooid: (1, true,)
11 | //│ = [ 1, true ]
12 |
13 | fooid.0
14 | fooid.1
15 | //│ res: 1
16 | //│ = 1
17 | //│ res: true
18 | //│ = true
19 |
20 | def foo(f: (forall 'A. 'A -> 'A) -> (forall 'B. 'B -> 'B)) =
21 | id f id (f id)
22 | //│ foo: ((forall 'A. 'A -> 'A) -> (forall 'B. 'B -> 'B)) -> 'B0 -> 'B0
23 | //│ = [Function: foo1]
24 |
25 | foo id
26 | //│ res: 'B -> 'B
27 | //│ = [Function: id]
28 |
29 | foo id id
30 | //│ res: 'a -> 'a
31 | //│ = [Function: id]
32 |
33 |
34 |
35 | def bui_ty: forall 'a. (forall 'b. 'a -> 'b) -> ()
36 | //│ bui_ty: (nothing -> nothing) -> ()
37 | //│ =
38 |
39 | // :d
40 | bui_ty = bui_ty
41 | //│ (nothing -> nothing) -> ()
42 | //│ <: bui_ty:
43 | //│ (nothing -> nothing) -> ()
44 | //│ =
45 | //│ bui_ty is not implemented
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/shared/src/test/diff/fcp/QML_exist_Records_min_3.mls:
--------------------------------------------------------------------------------
1 | :NoRecursiveTypes
2 | :DontDistributeForalls
3 | :NoJS
4 |
5 |
6 | type ArraysImpl[A] = { sub: A -> A }
7 | //│ Defined type alias ArraysImpl[=A]
8 |
9 | type ArraysImplConsumer[A] = ArraysImpl[A] -> int
10 | //│ Defined type alias ArraysImplConsumer[=A]
11 |
12 | def stepImpl_ty: ArraysImpl['a] -> ArraysImpl['a]
13 | //│ stepImpl_ty: ArraysImpl['a] -> ArraysImpl['a]
14 |
15 |
16 | // * There used to be a wrongly-simplified `'a <: nothing` bound here
17 | def s arr (k: ArraysImplConsumer['a]) = arr (fun impl -> k (stepImpl_ty impl))
18 | //│ s: ((ArraysImpl['a] -> int) -> 'b) -> ArraysImplConsumer['a] -> 'b
19 |
20 | // * ...although we could see that it shouldn't be simplified to nothing:
21 | :ns
22 | s
23 | //│ res: forall 'b 'a 'a0 'c. 'b -> (forall 'a1 'd. ArraysImplConsumer['a1] -> 'd)
24 | //│ where
25 | //│ 'd :> 'c
26 | //│ 'a1 :> 'a0
27 | //│ <: 'a
28 | //│ 'b <: (forall 'e 'a2 'f. 'e -> 'f) -> 'c
29 | //│ 'f :> int
30 | //│ 'e <: ArraysImpl['a2]
31 | //│ 'a2 :> 'a
32 | //│ <: 'a0
33 | //│ 'a <: 'a0
34 | //│ 'a0 <: 'a
35 |
36 |
37 |
--------------------------------------------------------------------------------
/shared/src/test/diff/fcp/SkolemErrors.mls:
--------------------------------------------------------------------------------
1 |
2 | :NoJS
3 |
4 |
5 | def k: (forall 'a. 'a -> 'a) -> int
6 | //│ k: (forall 'a. 'a -> 'a) -> int
7 |
8 |
9 | fun x -> k x
10 | //│ res: (forall 'a. 'a -> 'a) -> int
11 |
12 | fun x -> k (fun y -> x y)
13 | //│ res: (??a -> ??a0) -> int
14 |
15 |
16 |
17 |
18 | :ShowRelativeLineNums
19 | :AllowTypeErrors
20 |
21 | :e
22 | k (fun x -> x + 1)
23 | //│ ╔══[ERROR] Type mismatch in application:
24 | //│ ║ l.+1: k (fun x -> x + 1)
25 | //│ ║ ^^^^^^^^^^^^^^^^^^
26 | //│ ╟── type `'a` is not an instance of type `int`
27 | //│ ║ l.5: def k: (forall 'a. 'a -> 'a) -> int
28 | //│ ║ ^^
29 | //│ ╟── Note: constraint arises from reference:
30 | //│ ║ l.+1: k (fun x -> x + 1)
31 | //│ ║ ^
32 | //│ ╟── Note: quantified type variable 'a is defined at:
33 | //│ ║ l.5: def k: (forall 'a. 'a -> 'a) -> int
34 | //│ ╙── ^^
35 | //│ res: error | int
36 |
37 |
38 |
--------------------------------------------------------------------------------
/shared/src/test/diff/mlf-examples/ex_rvr_validate.mls:
--------------------------------------------------------------------------------
1 | :NoRecursiveTypes
2 |
3 | // (* Value restriction. *)
4 | // let id x = x
5 | // let x = id id in x 1, x true
6 | // let x = (id id:'a) in x 1, x true
7 | // ;;
8 | def id x = x
9 | let x = id id in (x 1, x true)
10 | let x = id id : 'a in (x 1, x true)
11 | //│ id: 'a -> 'a
12 | //│ = [Function: id]
13 | //│ res: (1, true,)
14 | //│ = [ 1, true ]
15 | //│ res: (1, true,)
16 | //│ = [ 1, true ]
17 |
18 | // type sid = ['a] 'a -> 'a
19 | // ;;
20 | type Sid = forall 'a. 'a -> 'a
21 | //│ Defined type alias Sid
22 |
23 | // let annot x = (x:sid)
24 | // ;;
25 | def annot x = x : Sid
26 | //│ annot: Sid -> Sid
27 | //│ = [Function: annot]
28 |
29 | // let delta x = let y = (x:sid) in y y
30 | // ;;
31 | def delta x = let y = x : Sid in y y
32 | //│ delta: Sid -> Sid
33 | //│ = [Function: delta]
34 |
35 | // let delta x = let y = (annot x) in y y
36 | // ;;
37 | def delta x = let y = annot x in y y
38 | //│ delta: Sid -> Sid
39 | //│ = [Function: delta1]
40 |
41 |
--------------------------------------------------------------------------------
/shared/src/test/diff/mlf-examples/ex_vr_validate.mls:
--------------------------------------------------------------------------------
1 | :NoRecursiveTypes
2 |
3 | // (* Value restriction. *)
4 | // let id x = x
5 | def id x = x
6 | //│ id: 'a -> 'a
7 | //│ = [Function: id]
8 |
9 | // untype let x = id id in x 1, x true
10 | // untype let x = (id id:'a) in x 1, x true
11 | // ;;
12 | let x = id id in (x 1, x true)
13 | let x = (id id : 'a) in (x 1, x true)
14 | //│ res: (1, true,)
15 | //│ = [ 1, true ]
16 | //│ res: (1, true,)
17 | //│ = [ 1, true ]
18 |
19 | // type sid = ['a] 'a -> 'a
20 | // ;;
21 | type Sid = forall 'a. 'a -> 'a
22 | //│ Defined type alias Sid
23 |
24 | // let annot x = (x:sid)
25 | // ;;
26 | def annot x = x : Sid
27 | //│ annot: Sid -> Sid
28 | //│ = [Function: annot]
29 |
30 | // let delta x = let y = (x:sid) in y y
31 | // ;;
32 | def delta x = let y = (x : Sid) in y y
33 | //│ delta: Sid -> Sid
34 | //│ = [Function: delta]
35 |
36 | // untype fun x -> let y = (annot x) in y y
37 | // ;;
38 | fun x -> let y = annot x in y y
39 | //│ res: Sid -> Sid
40 | //│ = [Function: res]
41 |
42 |
--------------------------------------------------------------------------------
/shared/src/test/diff/mlscript/ADTsRepro.mls:
--------------------------------------------------------------------------------
1 |
2 | type Add[E] = { x: E -> E }
3 | //│ Defined type alias Add[=E]
4 |
5 | def e2: Add['e] as 'e
6 | //│ e2: 'e
7 | //│ where
8 | //│ 'e := Add['e]
9 | //│ =
10 |
11 | e2 : Add['e] as 'e
12 | //│ res: 'e
13 | //│ where
14 | //│ 'e := Add['e]
15 | //│ =
16 | //│ e2 is not implemented
17 |
18 |
19 | def f0: ('a -> int) as 'a
20 | //│ f0: 'a
21 | //│ where
22 | //│ 'a := 'a -> int
23 | //│ =
24 |
25 | // :e // * Did not work before when added subtype checking to constraining...
26 | f0 = f0
27 | //│ 'a
28 | //│ where
29 | //│ 'a := 'a -> int
30 | //│ <: f0:
31 | //│ 'a
32 | //│ where
33 | //│ 'a := 'a -> int
34 | //│ =
35 | //│ f0 is not implemented
36 |
37 |
38 | type F1 = F1 -> int
39 | //│ Defined type alias F1
40 |
41 | def f1: F1
42 | //│ f1: F1
43 | //│ =
44 |
45 | f1 = f1
46 | //│ F1
47 | //│ <: f1:
48 | //│ F1
49 | //│ =
50 | //│ f1 is not implemented
51 |
52 |
53 | type F2[A] = F2[A] -> A
54 | //│ Defined type alias F2[=A]
55 |
56 | def f1: F2[int]
57 | //│ f1: F2[int]
58 | //│ =
59 |
60 | f1 = f1
61 | //│ F2[int]
62 | //│ <: f1:
63 | //│ F2[int]
64 | //│ =
65 | //│ f1 is not implemented
66 |
67 |
68 |
--------------------------------------------------------------------------------
/shared/src/test/diff/mlscript/Baber.mls:
--------------------------------------------------------------------------------
1 |
2 | class Foo[A]: { x: A }
3 | class Bar
4 | //│ Defined class Foo[+A]
5 | //│ Defined class Bar
6 |
7 | def f e = case e of
8 | Foo -> e.y,
9 | Foo -> e.z,
10 | _ -> e
11 | //│ f: (Foo[?] & {y: 'y} | 'y & ~#Foo) -> 'y
12 | //│ = [Function: f]
13 |
14 | :ns
15 | f
16 | //│ res: forall 'a 'b 'y 'c 'z 'd. 'a -> ('y | 'z | 'd)
17 | //│ where
18 | //│ 'a <: #Foo & 'b | (#Foo & 'c | 'd & ~#Foo) & ~#Foo
19 | //│ 'c <: {z: 'z}
20 | //│ 'b <: {y: 'y}
21 | //│ = [Function: f]
22 |
23 | class Foo2: Foo[int] & { y: int }
24 | //│ Defined class Foo2
25 |
26 | f (Foo2{x=1;y=2})
27 | //│ res: 2
28 | //│ = 2
29 |
30 | // #Foo
31 |
32 | def f e = case e of
33 | Foo2 -> e.y,
34 | Foo -> e.z,
35 | //│ f: (Foo[?] & {z: 'y} & ~#Foo2 | (Foo2\x with {y: 'y})) -> 'y
36 | //│ = [Function: f1]
37 |
38 |
--------------------------------------------------------------------------------
/shared/src/test/diff/mlscript/BadClasses.mls:
--------------------------------------------------------------------------------
1 | :AllowTypeErrors
2 |
3 |
4 | class Box[T]: { inner: T }
5 | method Get = this.inner
6 | method Get2 = this.x
7 | //│ ╔══[ERROR] Type mismatch in field selection:
8 | //│ ║ l.6: method Get2 = this.x
9 | //│ ║ ^^^^^^
10 | //│ ╟── reference of type `Box[T] & this` does not have field 'x'
11 | //│ ║ l.6: method Get2 = this.x
12 | //│ ╙── ^^^^
13 | //│ Defined class Box[+T]
14 | //│ Defined Box.Get: Box['T] -> 'T
15 | //│ Defined Box.Get2: Box[?] -> error
16 |
17 |
18 | class Box2[T]: { inner: T }
19 | method Test = this.inner + 1
20 | //│ ╔══[ERROR] Type mismatch in operator application:
21 | //│ ║ l.19: method Test = this.inner + 1
22 | //│ ║ ^^^^^^^^^^^^
23 | //│ ╟── field selection of type `T` is not an instance of type `int`
24 | //│ ║ l.19: method Test = this.inner + 1
25 | //│ ║ ^^^^^^^^^^
26 | //│ ╟── Note: class type parameter T is defined at:
27 | //│ ║ l.18: class Box2[T]: { inner: T }
28 | //│ ╙── ^
29 | //│ Defined class Box2[+T]
30 | //│ Defined Box2.Test: Box2[?] -> (error | int)
31 |
--------------------------------------------------------------------------------
/shared/src/test/diff/mlscript/Boolean.mls:
--------------------------------------------------------------------------------
1 | type Boolean = Tru | Fals
2 | class Tru
3 | class Fals
4 | def Tru: Tru
5 | def Fals: Fals
6 | //│ Defined type alias Boolean
7 | //│ Defined class Tru
8 | //│ Defined class Fals
9 | //│ Tru: Tru
10 | //│ =
11 | //│ Fals: Fals
12 | //│ =
13 |
14 | :js
15 | Tru: Boolean
16 | //│ // Query 1 aborted: Tru is not implemented
17 | //│ // End of generated code
18 | //│ res: Boolean
19 | //│ =
20 | //│ Tru is not implemented
21 |
22 | :e
23 | :ge
24 | Boolean
25 | //│ ╔══[ERROR] identifier not found: Boolean
26 | //│ ║ l.24: Boolean
27 | //│ ╙── ^^^^^^^
28 | //│ res: error
29 | //│ Code generation encountered an error:
30 | //│ type alias Boolean is not a valid expression
31 |
32 |
--------------------------------------------------------------------------------
/shared/src/test/diff/mlscript/EitherClasses.mls:
--------------------------------------------------------------------------------
1 | class Left[A]: { value: A }
2 | //│ Defined class Left[+A]
3 |
4 | Left{value=1}
5 | //│ res: Left[1]
6 | //│ = Left { value: 1 }
7 |
8 | def Left value = Left{ value }
9 | //│ Left: 'value -> Left['value]
10 | //│ = [Function: Left1]
11 |
12 | class Right[A]: { value: A }
13 | def Right value = Right{ value }
14 | //│ Defined class Right[+A]
15 | //│ Right: 'value -> Right['value]
16 | //│ = [Function: Right1]
17 |
18 | testVal = if true then Left 1 else Right 2
19 | //│ testVal: Left[1] | Right[2]
20 | //│ = Left { value: 1 }
21 |
22 | testVal.value
23 | //│ res: 1 | 2
24 | //│ = 1
25 |
26 | res = case testVal of
27 | { Left -> testVal.value
28 | | Right -> 1
29 | }
30 | //│ res: 1
31 | //│ = 1
32 |
33 | res: 1
34 | //│ res: 1
35 | //│ = 1
36 |
37 | case res of { 1 -> "ok" }
38 | //│ res: "ok"
39 | //│ = 'ok'
40 |
41 | res = case testVal of
42 | { Left -> testVal
43 | | Right -> 1
44 | }
45 | //│ res: 1 | Left[1]
46 | //│ = Left { value: 1 }
47 |
48 |
--------------------------------------------------------------------------------
/shared/src/test/diff/mlscript/Group_2022_05_10.mls:
--------------------------------------------------------------------------------
1 |
2 | def f x = (x 1, x "ok")
3 | //│ f: (1 -> 'a & "ok" -> 'b) -> ('a, 'b,)
4 | //│ = [Function: f]
5 |
6 | f (fun x -> (x, x))
7 | //│ res: ((1, 1,), ("ok", "ok",),)
8 | //│ = [ [ 1, 1 ], [ 'ok', 'ok' ] ]
9 |
10 | (fun id -> id id 0) (fun x -> x)
11 | //│ res: 0
12 | //│ = 0
13 |
14 | fun id -> id id 0
15 | //│ res: ('a -> 0 -> 'b & 'a) -> 'b
16 | //│ = [Function: res]
17 |
18 | fun x -> x
19 | //│ res: 'a -> 'a
20 | //│ = [Function: res]
21 |
22 | // forall 'a. 'a -> 'a <: 'a1 -> 0 -> 'b1 & 'a1
23 | // i.e.
24 | // forall 'a. 'a -> 'a <: 'a1 -> 0 -> 'b1
25 | // forall 'a. 'a -> 'a <: 'a1
26 | // i.e.
27 | // 'a2 -> 'a2 <: 'a1 -> 0 -> 'b1
28 | // 'a3 -> 'a3 <: 'a1
29 |
30 |
31 | def g x = x (fun x -> x)
32 | //│ g: ((forall 'a. 'a -> 'a) -> 'b) -> 'b
33 | //│ = [Function: g]
34 |
35 |
36 | def g x y = x (fun x -> y x)
37 | //│ g: (('a -> 'b) -> 'c) -> ('a -> 'b) -> 'c
38 | //│ = [Function: g1]
39 |
40 |
41 | self x = x x
42 | //│ self: ('a -> 'b & 'a) -> 'b
43 | //│ = [Function: self]
44 |
45 | :re
46 | self self!
47 | //│ res: nothing
48 | //│ Runtime error:
49 | //│ RangeError: Maximum call stack size exceeded
50 |
51 |
--------------------------------------------------------------------------------
/shared/src/test/diff/mlscript/Huawei2.mls:
--------------------------------------------------------------------------------
1 |
2 | class C[A]: { a: A -> A }
3 | //│ Defined class C[=A]
4 |
5 | class D: C[int] & { b: int }
6 | //│ Defined class D
7 |
8 | d = D{a = id; b = if true then 0 else 1}
9 | //│ d: D with {a: forall 'a. 'a -> 'a, b: 0 | 1}
10 | //│ = D { a: [Function: id], b: 0 }
11 |
12 | d.a true
13 | //│ res: true
14 | //│ = true
15 |
16 | d.a 0
17 | //│ res: 0
18 | //│ = 0
19 |
20 | d : #D
21 | //│ res: D
22 | //│ = D { a: [Function: id], b: 0 }
23 |
24 | def foo x = case x of D -> x.b, _ -> 0
25 | //│ foo: ((D\a with {b: 'b}) | ~D) -> (0 | 'b)
26 | //│ = [Function: foo]
27 |
28 | // Overloading through intersections: not supported
29 | // foo: ((D\a with {b: 'b}) -> 'b) & (~D -> 0)
30 |
31 | foo d
32 | //│ res: 0 | 1
33 | //│ = 0
34 |
35 |
--------------------------------------------------------------------------------
/shared/src/test/diff/mlscript/InheritSimple.mls:
--------------------------------------------------------------------------------
1 |
2 | class Parent: {}
3 | //│ Defined class Parent
4 |
5 | class Child: Parent
6 | //│ Defined class Child
7 |
8 | p = Parent{}
9 | //│ p: Parent
10 | //│ = Parent {}
11 |
12 | c = Child(p)
13 | //│ c: Child
14 | //│ = Child {}
15 |
16 | :e
17 | c.name
18 | //│ ╔══[ERROR] Type mismatch in field selection:
19 | //│ ║ l.17: c.name
20 | //│ ║ ^^^^^^
21 | //│ ╟── application of type `Child` does not have field 'name'
22 | //│ ║ l.12: c = Child(p)
23 | //│ ║ ^^^^^^^^
24 | //│ ╟── but it flows into reference with expected type `{name: ?name}`
25 | //│ ║ l.17: c.name
26 | //│ ║ ^
27 | //│ ╟── Note: class Child is defined at:
28 | //│ ║ l.5: class Child: Parent
29 | //│ ╙── ^^^^^
30 | //│ res: error
31 | //│ = undefined
32 |
33 | c: Child
34 | //│ res: Child
35 | //│ = Child {}
36 |
37 | c: Parent
38 | //│ res: Parent
39 | //│ = Child {}
40 |
41 | c: Parent & Child
42 | //│ res: Child & Parent
43 | //│ = Child {}
44 |
45 | c: Parent & Child & {}
46 | //│ res: Child & Parent
47 | //│ = Child {}
48 |
49 | c: Parent & anything & Child & {}
50 | //│ res: Child & Parent
51 | //│ = Child {}
52 |
53 |
--------------------------------------------------------------------------------
/shared/src/test/diff/mlscript/LineComments.mls:
--------------------------------------------------------------------------------
1 |
2 | 1
3 | 2
4 | //│ res: 1
5 | //│ = 1
6 | //│ res: 2
7 | //│ = 2
8 |
9 | 1
10 | // A
11 | 2
12 | //│ res: 1
13 | //│ = 1
14 | //│ res: 2
15 | //│ = 2
16 |
17 |
--------------------------------------------------------------------------------
/shared/src/test/diff/mlscript/MatchBool.mls:
--------------------------------------------------------------------------------
1 |
2 | def absImpl lt x =
3 | case lt of
4 | { true -> x
5 | | false -> 0 - x }
6 | //│ absImpl: Bool -> int -> int
7 | //│ = [Function: absImpl]
8 |
9 | // * TODO support this
10 | :e
11 | def abs x =
12 | let r = x < 0 in absImpl r x
13 | //│ ╔══[ERROR] Type mismatch in application:
14 | //│ ║ l.12: let r = x < 0 in absImpl r x
15 | //│ ║ ^^^^^^^^^
16 | //│ ╟── operator application of type `bool` does not match type `false & ?a | true & ?b`
17 | //│ ║ l.12: let r = x < 0 in absImpl r x
18 | //│ ║ ^^^^^
19 | //│ ╟── but it flows into reference with expected type `false & ?a | true & ?b`
20 | //│ ║ l.12: let r = x < 0 in absImpl r x
21 | //│ ║ ^
22 | //│ ╟── Note: constraint arises from reference:
23 | //│ ║ l.3: case lt of
24 | //│ ╙── ^^
25 | //│ abs: int -> (error | int)
26 | //│ = [Function: abs]
27 |
28 |
29 | def neg b = case b of
30 | { true -> false
31 | | false -> true }
32 | //│ neg: Bool -> Bool
33 | //│ = [Function: neg]
34 |
35 |
--------------------------------------------------------------------------------
/shared/src/test/diff/mlscript/NestedMatch.mls:
--------------------------------------------------------------------------------
1 |
2 | def f x = case x of {
3 | | 0 -> 0
4 | | _ -> case x of {
5 | | 1 -> 1
6 | | 2 -> 2
7 | }
8 | }
9 | //│ f: (0 | 1 | 2) -> (0 | 1 | 2)
10 | //│ = [Function: f]
11 |
12 | def f x = case x of {
13 | | 0 -> 0
14 | | _ -> case x of {
15 | | 1 -> 1
16 | | _ -> 2
17 | }
18 | }
19 | //│ f: anything -> (0 | 1 | 2)
20 | //│ = [Function: f1]
21 |
22 | def f x = case x of {
23 | | 0 -> 0
24 | | _ -> case x of {
25 | | 1 -> 1
26 | | _ -> x
27 | }
28 | }
29 | //│ f: (0 | 1 | 'a & ~0 & ~1) -> (0 | 1 | 'a)
30 | //│ = [Function: f2]
31 |
32 | def f x = case x of {
33 | | 0 -> x
34 | | _ -> case x of {
35 | | 1 -> 1
36 | | _ -> x
37 | }
38 | }
39 | //│ f: (1 | 'a & (0 | ~0 & ~1)) -> (1 | 'a)
40 | //│ = [Function: f3]
41 |
42 |
--------------------------------------------------------------------------------
/shared/src/test/diff/mlscript/Polym.mls:
--------------------------------------------------------------------------------
1 |
2 | def foo f =
3 | f (fun x -> x)
4 | //│ foo: ((forall 'a. 'a -> 'a) -> 'b) -> 'b
5 | //│ = [Function: foo]
6 |
7 | def bar h =
8 | (h 0, h true)
9 | //│ bar: (0 -> 'a & true -> 'b) -> ('a, 'b,)
10 | //│ = [Function: bar]
11 |
12 | bar id
13 | //│ res: (0, true,)
14 | //│ = [ 0, true ]
15 |
16 | foo bar
17 | //│ res: (0, true,)
18 | //│ = [ 0, true ]
19 |
20 |
21 | def foo2 f =
22 | f id
23 | //│ foo2: ((forall 'a. 'a -> 'a) -> 'b) -> 'b
24 | //│ = [Function: foo2]
25 |
26 | foo2 bar
27 | //│ res: (0, true,)
28 | //│ = [ 0, true ]
29 |
30 |
31 |
32 | def foo x f = f (fun a -> (x, a))
33 | //│ foo: 'a -> ((forall 'b. 'b -> ('a, 'b,)) -> 'c) -> 'c
34 | //│ = [Function: foo1]
35 |
36 | // Swapping the parameters givesa an isomorphic type:
37 |
38 | def foo f x = f (fun a -> (x, a))
39 | //│ foo: ((forall 'a. 'a -> ('b, 'a,)) -> 'c) -> 'b -> 'c
40 | //│ = [Function: foo3]
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/shared/src/test/diff/mlscript/RecDefs.mls:
--------------------------------------------------------------------------------
1 |
2 | rec def f x = x
3 | //│ f: 'a -> 'a
4 | //│ = [Function: f]
5 |
6 | f 1
7 | //│ res: 1
8 | //│ = 1
9 |
10 | f 2
11 | //│ res: 2
12 | //│ = 2
13 |
14 |
15 |
16 | rec def f = if true then fun (x: 'a) -> 32 else let tmp = f f + 1 in error
17 | //│ f: anything -> 32
18 | //│ = [Function: f1]
19 |
20 |
21 | :e
22 | rec def f = forall 'a. (fun (x: 'a) -> 32) : 'a
23 | //│ ╔══[ERROR] Type mismatch in type ascription:
24 | //│ ║ l.22: rec def f = forall 'a. (fun (x: 'a) -> 32) : 'a
25 | //│ ║ ^^^^^^^^^^^^^^^^^^^
26 | //│ ╟── function of type `'a -> 32` does not match type `'a`
27 | //│ ║ l.22: rec def f = forall 'a. (fun (x: 'a) -> 32) : 'a
28 | //│ ║ ^^^^^^^^^^^^^^^^^
29 | //│ ╟── Note: constraint arises from rigid type variable:
30 | //│ ║ l.22: rec def f = forall 'a. (fun (x: 'a) -> 32) : 'a
31 | //│ ╙── ^^
32 | //│ f: nothing
33 | //│ = [Function: f2]
34 |
35 |
36 |
--------------------------------------------------------------------------------
/shared/src/test/diff/mlscript/Repro.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
--------------------------------------------------------------------------------
/shared/src/test/diff/mlscript/Scratch.mls:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hkust-taco/mlscript/a7504bb818f21a802f2fc8a338888b67a7c87da5/shared/src/test/diff/mlscript/Scratch.mls
--------------------------------------------------------------------------------
/shared/src/test/diff/mlscript/SelfNegs.mls:
--------------------------------------------------------------------------------
1 |
2 | // * Here the two occurrences of `'a` in different types are separate:
3 | def foo(f: (~'a) -> 'a, a: 'a) =
4 | f a
5 | //│ foo: (~'a -> 'a, ~'a,) -> 'a
6 | //│ = [Function: foo]
7 |
8 | def foo(fa: ((~'a) -> 'a, 'a)) =
9 | fa.0 fa.1
10 | //│ foo: ((~'a -> 'a, 'a,),) -> 'a
11 | //│ = [Function: foo1]
12 |
13 | :ns
14 | foo
15 | //│ res: forall 'a 'b 'c. ((~'a -> 'a, 'a,),) -> 'c
16 | //│ where
17 | //│ 'a <: 'c & 'b
18 | //│ 'b <: ~'a
19 | //│ = [Function: foo1]
20 |
21 |
--------------------------------------------------------------------------------
/shared/src/test/diff/mlscript/Signatures.mls:
--------------------------------------------------------------------------------
1 |
2 | def foo: int -> (string -> anything)
3 | //│ foo: int -> string -> anything
4 | //│ =
5 |
6 | def foo: int -> string -> anything
7 | //│ foo: int -> string -> anything
8 | //│ =
9 |
10 | def foo: (int -> string) -> anything
11 | //│ foo: (int -> string) -> anything
12 | //│ =
13 |
14 |
--------------------------------------------------------------------------------
/shared/src/test/diff/mlscript/TrickySimplif.mls:
--------------------------------------------------------------------------------
1 | :NoJS
2 |
3 |
4 | // * This is fine
5 | def f: 'a -> 'b -> ('a, 'b)
6 | //│ f: 'a -> 'b -> ('a, 'b,)
7 |
8 | // * This is fine
9 | def f: ('b -> 'a) -> 'b
10 | //│ f: (nothing -> anything) -> nothing
11 |
12 | // * This could be simplified to `anything -> nothing`
13 | def foo: ('a | 'b) -> ('a & 'b)
14 | //│ foo: ('a | 'b) -> ('a & 'b)
15 |
16 | // * Case in point
17 | (foo 1) : bool
18 | //│ res: bool
19 |
20 | rec def foo x = foo x
21 | //│ anything -> nothing
22 | //│ <: foo:
23 | //│ ('a | 'b) -> ('a & 'b)
24 |
25 |
26 | def f: MutArray['a & 'b]
27 | //│ f: MutArray['a]
28 |
29 | def f: MutArray[('a & 'b, 'a)]
30 | //│ f: MutArray[('a & 'b, 'a,)]
31 |
32 | def f: MutArray[('a & 'b, 'a | 'b)]
33 | //│ f: MutArray[('a, 'a,)]
34 |
35 | def f: MutArray[('a & 'b, ('a | 'b) -> int)]
36 | //│ f: MutArray[('b, 'b -> int,)]
37 |
38 | def f: MutArray[('a & 'b, ('a & 'b) -> int)]
39 | //│ f: MutArray[('a, 'a -> int,)]
40 |
41 | def f: MutArray[('a & 'b) -> ('a & 'b)]
42 | //│ f: MutArray['a -> 'a]
43 |
44 | def f: MutArray[('a & 'b) -> ('a | 'b)]
45 | //│ f: MutArray[('a & 'b) -> ('a | 'b)]
46 |
47 | def f: MutArray[('a | 'b) -> ('a | 'b)]
48 | //│ f: MutArray['a -> 'a]
49 |
50 |
51 |
--------------------------------------------------------------------------------
/shared/src/test/diff/mlscript/TypeRefs.mls:
--------------------------------------------------------------------------------
1 | :NoJS
2 |
3 | class Foo[A]
4 | method Inv: A -> A
5 | //│ Defined class Foo[=A]
6 | //│ Declared Foo.Inv: Foo['A] -> 'A -> 'A
7 |
8 | trait Bar[A]
9 | method Inv: A -> A
10 | //│ Defined trait Bar[=A]
11 | //│ Declared Bar.Inv: Bar['A] -> 'A -> 'A
12 |
13 | type Baz[A] = Bar[A -> A]
14 | //│ Defined type alias Baz[=A]
15 |
16 | def foo: Foo[int] & Bar[int] & Baz[string]
17 | //│ foo: Foo[int] & Bar[int] & Baz[string]
18 |
19 | foo: Foo['res]
20 | //│ res: Foo[int]
21 |
22 | foo: Baz['res]
23 | //│ res: Baz[string]
24 |
25 | // * Note that we don't get a `'res :> string -> string & int` upper bound because it's simplified to bottom:
26 | foo: Bar['res]
27 | //│ res: Bar['res]
28 | //│ where
29 | //│ 'res <: int | string -> string
30 |
31 |
--------------------------------------------------------------------------------
/shared/src/test/diff/mlscript/Undef.mls:
--------------------------------------------------------------------------------
1 |
2 | class Undef
3 | //│ Defined class Undef
4 |
5 | undef = Undef{}
6 | //│ undef: Undef
7 | //│ = Undef {}
8 |
9 |
10 | def example: int | Undef
11 | //│ example: Undef | int
12 | //│ =
13 |
14 | example = if true then undef else 42
15 | //│ 42 | Undef
16 | //│ <: example:
17 | //│ Undef | int
18 | //│ = Undef {}
19 |
20 | def qmrk_qmrk lhs rhs = case lhs of { Undef -> rhs | _ -> lhs }
21 | //│ qmrk_qmrk: (Undef | 'a & ~#Undef) -> 'a -> 'a
22 | //│ = [Function: qmrk_qmrk]
23 |
24 | qmrk_qmrk example 0
25 | //│ res: int
26 | //│ = 0
27 |
28 | qmrk_qmrk example "123"
29 | //│ res: "123" | int
30 | //│ = '123'
31 |
32 | qmrk_qmrk undef "123"
33 | //│ res: "123"
34 | //│ = '123'
35 |
36 | qmrk_qmrk 42 "123"
37 | //│ res: "123" | 42
38 | //│ = 42
39 |
40 |
--------------------------------------------------------------------------------
/shared/src/test/diff/mlscript/VarCycles.mls:
--------------------------------------------------------------------------------
1 |
2 | :RecursiveTypes
3 |
4 |
5 | def foo: ('a,) as 'a
6 | //│ foo: 'a
7 | //│ where
8 | //│ 'a :> ('a,)
9 | //│ =
10 |
11 | def bar: (('b,) as 'b) -> ()
12 | //│ bar: 'b -> ()
13 | //│ where
14 | //│ 'b <: ('b,)
15 | //│ =
16 |
17 |
18 | bar foo
19 | //│ res: ()
20 | //│ =
21 | //│ bar is not implemented
22 |
23 |
24 | :ns
25 | id1 = id
26 | //│ id1: forall 'a. 'a -> 'a
27 | //│ = [Function: id]
28 |
29 | :ns
30 | // def f x = id x
31 | def f = id : 'c -> 'c
32 | //│ f: forall 'c 'a. 'c -> 'c
33 | //│ where
34 | //│ 'c <: 'a
35 | //│ 'a <: 'c
36 | //│ = [Function: f]
37 |
38 | f 1 + 2
39 | //│ res: int
40 | //│ = 3
41 |
42 |
43 |
44 | :NoRecursiveTypes
45 |
46 |
47 | :e
48 | bar foo
49 | //│ ╔══[ERROR] Inferred recursive type: 'b
50 | //│ where
51 | //│ 'b :> ('b,)
52 | //│ ║ l.11: def bar: (('b,) as 'b) -> ()
53 | //│ ╙── ^^^^^^^^^^^^^
54 | //│ ╔══[ERROR] Cyclic-looking constraint while typing application; a type annotation may be required
55 | //│ ║ l.48: bar foo
56 | //│ ║ ^^^^^^^
57 | //│ ╙── Note: use flag `:ex` to see internal error info.
58 | //│ res: error | ()
59 | //│ =
60 | //│ bar is not implemented
61 |
62 |
63 | f 1 + 2
64 | //│ res: int
65 | //│ = 3
66 |
67 |
68 |
--------------------------------------------------------------------------------
/shared/src/test/diff/mlscript/Weird.mls:
--------------------------------------------------------------------------------
1 | // * Weird features to eventually remove
2 |
3 | :AllowRuntimeErrors
4 |
5 |
6 | :ge
7 | anything
8 | //│ res: anything
9 | //│ Code generation encountered an error:
10 | //│ type alias anything is not a valid expression
11 |
12 | :ge
13 | nothing
14 | //│ res: nothing
15 | //│ Code generation encountered an error:
16 | //│ type alias nothing is not a valid expression
17 |
18 | :ge
19 | Nothing
20 | //│ res: nothing
21 | //│ Code generation encountered an error:
22 | //│ unresolved symbol Nothing
23 |
24 | :ge
25 | int
26 | //│ res: int
27 | //│ Code generation encountered an error:
28 | //│ type alias int is not a valid expression
29 |
30 | :ge
31 | int + 1
32 | //│ res: int
33 | //│ Code generation encountered an error:
34 | //│ type alias int is not a valid expression
35 |
36 |
37 | class C
38 | //│ Defined class C
39 |
40 | :p
41 | def n: C{}
42 | //│ Parsed: rec def n: C; {};
43 | //│ Desugared: rec def n: C
44 | //│ AST: Def(true,Var(n),Right(PolyType(List(),TypeName(C))),true)
45 | //│ Desugared: {}
46 | //│ AST: Rcd(List())
47 | //│ n: C
48 | //│ =
49 | //│ res: anything
50 | //│ = {}
51 |
52 |
--------------------------------------------------------------------------------
/shared/src/test/diff/mlscript/i26.mls:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hkust-taco/mlscript/a7504bb818f21a802f2fc8a338888b67a7c87da5/shared/src/test/diff/mlscript/i26.mls
--------------------------------------------------------------------------------
/shared/src/test/diff/mlscript/i65.mls:
--------------------------------------------------------------------------------
1 | :js
2 | 42
3 | //│ // Prelude
4 | //│ let res;
5 | //│ // Query 1
6 | //│ res = 42;
7 | //│ // End of generated code
8 | //│ res: 42
9 | //│ = 42
10 |
11 | :js
12 | foo = "oops"
13 | //│ // Query 1
14 | //│ globalThis.foo = "oops";
15 | //│ // End of generated code
16 | //│ foo: "oops"
17 | //│ = 'oops'
18 |
19 | :js
20 | res
21 | //│ // Query 1
22 | //│ res = res;
23 | //│ // End of generated code
24 | //│ res: 42
25 | //│ = 42
26 |
27 | :js
28 | res = 5
29 | //│ // Query 1
30 | //│ globalThis.res1 = 5;
31 | //│ // End of generated code
32 | //│ res: 5
33 | //│ = 5
34 |
35 | res
36 | //│ res: 5
37 | //│ = 5
38 |
39 | :js
40 | foo
41 | //│ // Query 1
42 | //│ res = foo;
43 | //│ // End of generated code
44 | //│ res: "oops"
45 | //│ = 'oops'
46 |
47 | :js
48 | res
49 | //│ // Query 1
50 | //│ res = res;
51 | //│ // End of generated code
52 | //│ res: "oops"
53 | //│ = 'oops'
54 |
55 | def res: bool
56 | //│ res: bool
57 | //│ =
58 |
59 | 42
60 | //│ res: 42
61 | //│ = 42
62 |
63 | res
64 | //│ res: 42
65 | //│ = 42
66 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/Andong.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | class Union(a: Region, b: Region)
5 | //│ class Union[Region](a: Region, b: Region)
6 |
7 | fun hmm(x) =
8 | if x is Union(x, y) then x
9 | //│ fun hmm: forall 'a. Union['a] -> 'a
10 |
11 | fun hmm(x) =
12 | if x is Union(z, y) then x
13 | //│ fun hmm: forall 'Region. Union['Region] -> Union['Region]
14 |
15 |
16 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/Ascription.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 | 1: Int
4 | //│ Int
5 | //│ res
6 | //│ = 1
7 |
8 | 1 : Int
9 | //│ Int
10 | //│ res
11 | //│ = 1
12 |
13 | // TODO?
14 | :pe
15 | 1 : Int : Int
16 | //│ ╔══[PARSE ERROR] Not a recognized type
17 | //│ ║ l.15: 1 : Int : Int
18 | //│ ╙── ^^^
19 | //│ anything
20 | //│ res
21 | //│ = 1
22 |
23 | fun foo(x: Int) = x + 1
24 | //│ fun foo: (x: Int) -> Int
25 |
26 | fun foo(x : Int) = x + 1
27 | //│ fun foo: Int -> Int
28 |
29 | foo(123 : Int) : Int
30 | //│ Int
31 | //│ res
32 | //│ = 124
33 |
34 | :e
35 | foo(123: Int): Int
36 | //│ ╔══[ERROR] Cannot use named arguments as the function type has untyped arguments
37 | //│ ║ l.35: foo(123: Int): Int
38 | //│ ╙── ^^^^^^^^^^
39 | //│ Int
40 | //│ Code generation encountered an error:
41 | //│ unresolved symbol Int
42 |
43 | :e
44 | foo(123:Int):Int
45 | //│ ╔══[ERROR] Cannot use named arguments as the function type has untyped arguments
46 | //│ ║ l.44: foo(123:Int):Int
47 | //│ ╙── ^^^^^^^^^
48 | //│ Int
49 | //│ Code generation encountered an error:
50 | //│ unresolved symbol Int
51 |
52 | fun foo(f) =
53 | let g = (x => f(x)): forall 'a : 'a -> 'a in g(123)
54 | //│ fun foo: (??a -> ??a0) -> 123
55 |
56 | fun foo(f) =
57 | let g: forall 'a : 'a -> 'a = x => f(x) in g(123)
58 | //│ fun foo: (??a -> ??a0) -> 123
59 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/BadMixins.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | :e
5 | mixin M0
6 | M0
7 | //│ ╔══[ERROR] mixin M0 cannot be used in term position
8 | //│ ║ l.6: M0
9 | //│ ╙── ^^
10 | //│ mixin M0()
11 | //│ error
12 | //│ res
13 | //│ = [Function (anonymous)]
14 |
15 | :e
16 | M0
17 | //│ ╔══[ERROR] mixin M0 cannot be used in term position
18 | //│ ║ l.16: M0
19 | //│ ╙── ^^
20 | //│ error
21 | //│ res
22 | //│ = [Function (anonymous)]
23 |
24 |
25 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/BadScopes.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | :e
5 | mixin Foo(x: Int)
6 | x
7 | //│ ╔══[ERROR] identifier not found: x
8 | //│ ║ l.6: x
9 | //│ ╙── ^
10 | //│ mixin Foo(x: Int)
11 | //│ error
12 | //│ Code generation encountered an error:
13 | //│ unresolved symbol x
14 |
15 |
16 | :e
17 | class Foo(x: Int)
18 | x
19 | //│ ╔══[ERROR] identifier not found: x
20 | //│ ║ l.18: x
21 | //│ ╙── ^
22 | //│ class Foo(x: Int)
23 | //│ error
24 | //│ Code generation encountered an error:
25 | //│ unresolved symbol x
26 |
27 |
28 | :e
29 | class Bar { x }
30 | //│ ╔══[ERROR] identifier not found: x
31 | //│ ║ l.29: class Bar { x }
32 | //│ ╙── ^
33 | //│ class Bar {
34 | //│ constructor()
35 | //│ }
36 | //│ Code generation encountered an error:
37 | //│ unresolved symbol x
38 |
39 |
40 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/BadSuper.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | mixin M0 {
5 | fun f = 42
6 | }
7 | //│ mixin M0() {
8 | //│ fun f: 42
9 | //│ }
10 |
11 | :e
12 | mixin M1 {
13 | fun g = super
14 | }
15 | //│ ╔══[ERROR] Illegal use of `super`
16 | //│ ║ l.13: fun g = super
17 | //│ ╙── ^^^^^
18 | //│ mixin M1() {
19 | //│ super: 'super
20 | //│ fun g: 'super
21 | //│ }
22 | //│ Syntax error:
23 | //│ 'super' keyword unexpected here
24 |
25 | :re
26 | module C0 extends M0, M1
27 | C0.g
28 | //│ module C0 {
29 | //│ fun f: 42
30 | //│ fun g: {f: 42}
31 | //│ }
32 | //│ {f: 42}
33 | //│ res
34 | //│ Runtime error:
35 | //│ ReferenceError: M1 is not defined
36 |
37 |
38 | :e
39 | class Foo {
40 | fun f = super
41 | }
42 | //│ ╔══[ERROR] Illegal use of `super`
43 | //│ ║ l.40: fun f = super
44 | //│ ╙── ^^^^^
45 | //│ class Foo {
46 | //│ constructor()
47 | //│ fun f: Foo
48 | //│ }
49 | //│ Syntax error:
50 | //│ 'super' keyword unexpected here
51 |
52 |
53 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/BadTraits.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | trait Foo
5 | //│ trait Foo
6 |
7 | :e
8 | Foo
9 | //│ ╔══[ERROR] trait Foo cannot be used in term position
10 | //│ ║ l.8: Foo
11 | //│ ╙── ^^^
12 | //│ error
13 | //│ Code generation encountered an error:
14 | //│ trait used in term position
15 |
16 |
17 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/CallByName.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | let x = log("ok")
5 | //│ let x: ()
6 | //│ x
7 | //│ = undefined
8 | //│ // Output
9 | //│ ok
10 |
11 | x
12 | //│ ()
13 | //│ res
14 | //│ = undefined
15 |
16 | x
17 | //│ ()
18 | //│ res
19 | //│ = undefined
20 |
21 |
22 | fun x = log("ok")
23 | //│ fun x: ()
24 |
25 | x
26 | //│ ()
27 | //│ res
28 | //│ = undefined
29 | //│ // Output
30 | //│ ok
31 |
32 | x
33 | //│ ()
34 | //│ res
35 | //│ = undefined
36 | //│ // Output
37 | //│ ok
38 |
39 |
40 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/ClassInstantiation.mls:
--------------------------------------------------------------------------------
1 | // *** Class instantiation tests *** //
2 |
3 | :NewDefs
4 |
5 |
6 | class C
7 | //│ class C {
8 | //│ constructor()
9 | //│ }
10 |
11 | new C
12 | //│ C
13 | //│ res
14 | //│ = C {}
15 |
16 | // * TODO decide: forbid?
17 | new C()
18 | //│ C
19 | //│ res
20 | //│ = C {}
21 |
22 | :e
23 | C()
24 | //│ ╔══[ERROR] Construction of unparameterized class C should use the `new` keyword
25 | //│ ║ l.23: C()
26 | //│ ╙── ^
27 | //│ C
28 | //│ res
29 | //│ Runtime error:
30 | //│ TypeError: Class constructor C cannot be invoked without 'new'
31 |
32 |
33 | class D(x: Int)
34 | //│ class D(x: Int)
35 |
36 | :js
37 | D(0)
38 | //│ D
39 | //│ // Prelude
40 | //│ class TypingUnit5 {}
41 | //│ const typing_unit5 = new TypingUnit5;
42 | //│ // Query 1
43 | //│ res = D(0);
44 | //│ // End of generated code
45 | //│ res
46 | //│ = D {}
47 |
48 | // * TODO decide: reject or accept?
49 | :js
50 | new D(0)
51 | //│ D
52 | //│ // Prelude
53 | //│ class TypingUnit6 {}
54 | //│ const typing_unit6 = new TypingUnit6;
55 | //│ // Query 1
56 | //│ res = new D.class(0);
57 | //│ // End of generated code
58 | //│ res
59 | //│ = D {}
60 |
61 |
62 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/CtorSubtraction.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | class Cls
5 | //│ class Cls {
6 | //│ constructor()
7 | //│ }
8 |
9 | fun x: ('a & Object) -> ('a \ Cls)
10 | fun x = case
11 | Cls then error
12 | y then y
13 | //│ fun x: forall 'b. (Cls | Object & 'b & ~#Cls) -> 'b
14 | //│ fun x: forall 'a. (Object & 'a) -> ('a & ~Cls)
15 |
16 | x : Int -> Int
17 | //│ Int -> Int
18 | //│ res
19 | //│ = [Function: x]
20 |
21 | x : Cls -> nothing
22 | //│ Cls -> nothing
23 | //│ res
24 | //│ = [Function: x]
25 |
26 |
27 | fun x: (Int | Str | Cls) \ Cls
28 | fun x = 42
29 | //│ fun x: 42
30 | //│ fun x: Int & ~Cls | Str & ~Cls
31 |
32 | x : Int | Str
33 | //│ Int | Str
34 | //│ res
35 | //│ = 42
36 |
37 |
38 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/CycleTypeDefErrors.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 | // * These type definitions should be checked for cyclicity, like we did in the old frontend,
4 | // * but this is currently not implemented.
5 |
6 |
7 | type Foo = Foo
8 | //│ type Foo = Foo
9 |
10 | (f: Foo) => f : Str
11 | //│ (f: Foo) -> Str
12 | //│ res
13 | //│ = [Function: res]
14 |
15 |
16 | type Foo = Foo & Int
17 | //│ type Foo = Foo & Int
18 |
19 | // FIXME
20 | (f: Foo) => f : Str
21 | //│ /!!!\ Uncaught error: java.lang.StackOverflowError
22 |
23 |
24 | abstract class Foo: Foo
25 | //│ abstract class Foo: Foo
26 |
27 | // FIXME
28 | (f: Foo) => f : Str
29 | //│ /!!!\ Uncaught error: java.lang.StackOverflowError
30 |
31 |
32 | abstract class Foo[T]: Foo[Int]
33 | //│ abstract class Foo[T]: Foo[Int]
34 |
35 | // FIXME
36 | fun test(f: Foo['a]) = f : Str
37 | //│ /!!!\ Uncaught error: java.lang.StackOverflowError
38 |
39 |
40 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/Dates.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | declare class Date {
5 | constructor(date: Num)
6 | fun toString(): Str
7 | fun toLocaleString(locales: Str | Array[Str], options: anything): Str
8 | }
9 | //│ declare class Date {
10 | //│ constructor(date: Num)
11 | //│ fun toLocaleString: (locales: Str | Array[Str], options: anything) -> Str
12 | //│ fun toString: () -> Str
13 | //│ }
14 |
15 | let date1 = new Date(12345678)
16 | //│ let date1: Date
17 | //│ date1
18 | //│ = 1970-01-01T03:25:45.678Z
19 |
20 | date1.toLocaleString("en-US", { timeZone: "America/New_York" })
21 | //│ Str
22 | //│ res
23 | //│ = '12/31/1969, 10:25:45 PM'
24 |
25 |
26 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/DidierNu.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | // val k x y = y
5 | // val unify : A. B. A -> A -> B -> B
6 | // = fun x y z -> k (fun z -> k (z x) (k (z y))) z
7 | // val a0 = (fun z -> z) (id : A. A -> A) 1
8 | // val a1 x = (fun z -> unify x (fst z) (snd z)) (id, (id : A. A -> A)) 1
9 |
10 |
11 | fun k(x, y) = y
12 | //│ fun k: forall 'a. (anything, 'a) -> 'a
13 |
14 | fun unify : 'A -> 'A -> 'B -> 'B
15 | //│ fun unify: forall 'B. anything -> anything -> 'B -> 'B
16 |
17 | fun unify = x => y => z => k(z => k(z(x), y => k(z(y), y)), z)
18 | //│ fun unify: forall 'a. anything -> anything -> 'a -> 'a
19 |
20 | fun unify = x => y => z => k of z => k(z(x), y => k of z(y), y), z
21 | //│ fun unify: forall 'a. anything -> anything -> 'a -> 'a
22 |
23 |
24 | fun a0 = (z => z) (id : forall 'A: 'A -> 'A) of 1
25 | //│ fun a0: 1
26 |
27 | fun fst([a, _]) = a
28 | fun snd([_, b]) = b
29 | //│ fun fst: forall 'a. (['a, anything]) -> 'a
30 | //│ fun snd: forall 'b. ([anything, 'b]) -> 'b
31 |
32 | fun a1(x) = (z => unify(x)(fst of z)(snd of z))([id, (id : forall 'A: 'A -> 'A)]) of 1
33 | //│ fun a1: anything -> 1
34 |
35 |
36 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/Eduardo.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 | // https://twitter.com/LParreaux/status/1762843603804770408
4 |
5 |
6 | type f = forall 'a: ('a ) -> 'a where 'a : Int
7 | //│ type f = forall 'a. (Int & 'a) -> 'a
8 |
9 | type f = (forall 'a: ('a ) -> 'a where 'a : Int)
10 | //│ type f = forall 'a. (Int & 'a) -> 'a
11 |
12 | type g = forall 'a: ('a & Int) -> 'a
13 | //│ type g = forall 'a. (Int & 'a) -> 'a
14 |
15 | (id : f) : g
16 | //│ g
17 | //│ res
18 | //│ = [Function: id]
19 |
20 |
21 | type f = (forall 'a: ('a ) -> 'a where 'a : Int)
22 | type g = forall 'a: ('a & Int) -> 'a
23 | //│ type f = forall 'a. (Int & 'a) -> 'a
24 | //│ type g = forall 'a0. (Int & 'a0) -> 'a0
25 |
26 | (id : f) : g
27 | (id : g) : f
28 | //│ f
29 | //│ res
30 | //│ = [Function: id]
31 | //│ res
32 | //│ = [Function: id]
33 |
34 | x => (id : f)(x) : Int
35 | //│ Int -> Int
36 | //│ res
37 | //│ = [Function: res]
38 |
39 |
40 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/EncodedLists.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 | :NoJS
3 |
4 |
5 | class List {
6 | fun match: forall 'res: (ifNil: () => 'res, ifCons: ('res, List[A]) => 'res) => 'res
7 | fun match = error // TODO use self-type...
8 | }
9 | val Nil: List
10 | val Cons: (head: 'a, tail: List<'a>) => List<'a>
11 | //│ class List[A] {
12 | //│ constructor()
13 | //│ fun match: forall 'res. (ifNil: () -> 'res, ifCons: ('res, List[A]) -> 'res) -> 'res
14 | //│ }
15 | //│ val Nil: List[nothing]
16 | //│ val Cons: forall 'a. (head: 'a, tail: List['a]) -> List['a]
17 |
18 | val x: List
19 | //│ val x: List[Int]
20 |
21 | // FIXME
22 | x: List
23 | //│ ╔══[ERROR] Type mismatch in type ascription:
24 | //│ ║ l.22: x: List
25 | //│ ║ ^
26 | //│ ╙── expression of type `anything` is not an instance of type `Int`
27 | //│ List[anything]
28 |
29 |
30 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/Extrusion.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | fun f(y) =
5 | let local = forall 'A: (x: 'A) =>
6 | discard of y(x) + 1
7 | x
8 | y
9 | //│ fun f: forall 'a. (??A -> Int & 'a) -> 'a
10 |
11 | :e
12 | f(id)
13 | //│ ╔══[ERROR] Type error in application
14 | //│ ║ l.12: f(id)
15 | //│ ║ ^^^^^
16 | //│ ╟── type variable `'A` leaks out of its scope
17 | //│ ║ l.5: let local = forall 'A: (x: 'A) =>
18 | //│ ║ ^^
19 | //│ ╟── into application of type `Int`
20 | //│ ║ l.6: discard of y(x) + 1
21 | //│ ║ ^^^^
22 | //│ ╟── adding a type annotation to any of the following terms may help resolve the problem
23 | //│ ╟── • this reference:
24 | //│ ║ l.6: discard of y(x) + 1
25 | //│ ╙── ^
26 | //│ forall 'a. error | 'a -> 'a
27 | //│ res
28 | //│ = [Function: id]
29 |
30 |
31 | fun f(y) =
32 | let local = forall 'A: (x: 'A) =>
33 | discard of (y : forall 'a: 'a -> 'a)(x)
34 | x
35 | y
36 | //│ fun f: forall 'b. (forall 'a. 'a -> 'a & 'b) -> 'b
37 |
38 | f(id)
39 | //│ forall 'a. 'a -> 'a
40 | //│ res
41 | //│ = [Function: id]
42 |
43 |
44 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/FieldRefinement.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 | :NoJS
3 |
4 |
5 | class Foo(val x: Int) {
6 | fun bar = x
7 | fun baz: 1 | 2 = 1
8 | }
9 | //│ class Foo(x: Int) {
10 | //│ fun bar: Int
11 | //│ fun baz: 1 | 2
12 | //│ }
13 |
14 | val foo: Foo & { x: 0 | 1, bar: 0 | 1, baz: 0 | 1, y: Bool }
15 | //│ val foo: Foo & {y: Bool, bar: 0 | 1, baz: 0 | 1, x: 0 | 1}
16 |
17 | foo.x
18 | //│ 0 | 1
19 |
20 | foo.bar
21 | //│ 0 | 1
22 |
23 | foo.baz
24 | //│ 1
25 |
26 | foo.y
27 | //│ Bool
28 |
29 | :e
30 | foo.z
31 | //│ ╔══[ERROR] Type `Foo & {y: Bool, bar: 0 | 1, baz: 0 | 1, x: 0 | 1}` does not contain member `z`
32 | //│ ║ l.30: foo.z
33 | //│ ╙── ^^
34 | //│ error
35 |
36 |
37 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/FlatIndentFuns.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | x =>
5 | y =>
6 | x + y
7 | //│ Int -> Int -> Int
8 | //│ res
9 | //│ = [Function: res]
10 |
11 | id of x =>
12 | y =>
13 | x + y
14 | //│ Int -> Int -> Int
15 | //│ res
16 | //│ = [Function (anonymous)]
17 |
18 | let r = x =>
19 | y =>
20 | x + y
21 | //│ let r: Int -> Int -> Int
22 | //│ r
23 | //│ = [Function: r]
24 |
25 | r(1)(2)
26 | //│ Int
27 | //│ res
28 | //│ = 3
29 |
30 | (r of 1) of 2
31 | //│ Int
32 | //│ res
33 | //│ = 3
34 |
35 | :e
36 | r of 1 of 2
37 | //│ ╔══[ERROR] Type mismatch in application:
38 | //│ ║ l.36: r of 1 of 2
39 | //│ ║ ^^^^^^
40 | //│ ╟── integer literal of type `1` is not a function
41 | //│ ║ l.36: r of 1 of 2
42 | //│ ╙── ^
43 | //│ Int -> Int
44 | //│ res
45 | //│ Runtime error:
46 | //│ TypeError: 1 is not a function
47 |
48 |
49 | // * Could support this too...
50 | :pe
51 | let r =
52 | x =>
53 | y =>
54 | x + y
55 | //│ ╔══[PARSE ERROR] Unexpected newline in expression position
56 | //│ ║ l.51: let r =
57 | //│ ║ ^
58 | //│ ║ l.52: x =>
59 | //│ ╙──
60 | //│ let r: Int -> Int -> Int
61 | //│ r
62 | //│ = [Function: r1]
63 |
64 |
65 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/FunPatterns.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 | :NoJS
3 |
4 |
5 | fun f(x, y) = x + y
6 | //│ fun f: (Int, Int) -> Int
7 |
8 | // FIXME array pattern...?!
9 | fun f1([x, y]) = x + y
10 | fun f2([x, y],) = x + y
11 | fun f3([[x, y,],],) = x + y
12 | //│ fun f1: ([Int, Int]) -> Int
13 | //│ fun f2: ([Int, Int]) -> Int
14 | //│ fun f3: ([[Int, Int]]) -> Int
15 |
16 | :e
17 | fun f3([(x, y,),],) = x + y
18 | //│ ╔══[ERROR] Unsupported pattern shape:
19 | //│ ║ l.17: fun f3([(x, y,),],) = x + y
20 | //│ ╙── ^^^^^^^
21 | //│ ╔══[ERROR] identifier not found: x
22 | //│ ║ l.17: fun f3([(x, y,),],) = x + y
23 | //│ ╙── ^
24 | //│ ╔══[ERROR] identifier not found: y
25 | //│ ║ l.17: fun f3([(x, y,),],) = x + y
26 | //│ ╙── ^
27 | //│ fun f3: ([error]) -> Int
28 |
29 |
30 | class Pair(lhs: Int, rhs: Int)
31 | //│ class Pair(lhs: Int, rhs: Int)
32 |
33 | :e // * TODO
34 | fun f(Pair(x, y)) = x + y
35 | //│ ╔══[ERROR] Unsupported pattern shape:
36 | //│ ║ l.34: fun f(Pair(x, y)) = x + y
37 | //│ ╙── ^^^^^^^^^^
38 | //│ ╔══[ERROR] identifier not found: x
39 | //│ ║ l.34: fun f(Pair(x, y)) = x + y
40 | //│ ╙── ^
41 | //│ ╔══[ERROR] identifier not found: y
42 | //│ ║ l.34: fun f(Pair(x, y)) = x + y
43 | //│ ╙── ^
44 | //│ fun f: error -> Int
45 |
46 |
47 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/FunnyIndet.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | 2 +
5 | 2 *
6 | 3
7 | //│ Int
8 | //│ res
9 | //│ = 8
10 |
11 | 2 -
12 | 3 -
13 | 4
14 | //│ Int
15 | //│ res
16 | //│ = 3
17 |
18 | 2 +
19 | 2
20 | //│ Int
21 | //│ res
22 | //│ = 4
23 |
24 | 2 +
25 | 2
26 | //│ Int
27 | //│ res
28 | //│ = 4
29 |
30 |
31 | 2 is
32 | 2
33 | //│ Bool
34 | //│ res
35 | //│ = true
36 |
37 | if 2 is 2 then true
38 | //│ true
39 | //│ res
40 | //│ = true
41 |
42 | 2 is
43 | 2
44 | //│ Bool
45 | //│ res
46 | //│ = true
47 |
48 |
49 | if 2 is
50 | 2 then true
51 | //│ true
52 | //│ res
53 | //│ = true
54 |
55 | :pe // TODO support
56 | if 2 is
57 | 2 then true
58 | 1 then false
59 | //│ ╔══[PARSE ERROR] Unexpected 'then'/'else' clause
60 | //│ ║ l.58: 1 then false
61 | //│ ╙── ^^^^^^^^^^^^
62 | //│ ()
63 | //│ res
64 | //│ = true
65 | //│ res
66 | //│ = undefined
67 |
68 |
69 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/Huawei1.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | class C[out A](x: A) {
5 | fun foo = x
6 | }
7 | //│ class C[A](x: A) {
8 | //│ fun foo: A
9 | //│ }
10 |
11 | let c = C(123)
12 | //│ let c: C[123]
13 | //│ c
14 | //│ = C {}
15 |
16 | class B
17 | //│ class B {
18 | //│ constructor()
19 | //│ }
20 |
21 | fun bar(c) = if c is
22 | C(y) then y
23 | B then 0
24 | //│ fun bar: forall 'a. (B | C['a]) -> (0 | 'a)
25 |
26 | bar(c)
27 | //│ 0 | 123
28 | //│ res
29 | //│ = 123
30 |
31 | fun bar(c) = if c is
32 | C(y) then y + 1
33 | B then 0
34 | else 1
35 | //│ fun bar: (C[Int] | Object & ~#C) -> Int
36 |
37 | bar(c)
38 | //│ Int
39 | //│ res
40 | //│ = 124
41 |
42 | :e
43 | bar(C(true))
44 | //│ ╔══[ERROR] Type mismatch in application:
45 | //│ ║ l.43: bar(C(true))
46 | //│ ║ ^^^^^^^^^^^^
47 | //│ ╟── reference of type `true` is not an instance of `Int`
48 | //│ ║ l.43: bar(C(true))
49 | //│ ║ ^^^^
50 | //│ ╟── Note: constraint arises from reference:
51 | //│ ║ l.32: C(y) then y + 1
52 | //│ ║ ^
53 | //│ ╟── from field selection:
54 | //│ ║ l.4: class C[out A](x: A) {
55 | //│ ║ ^
56 | //│ ╟── Note: type parameter A is defined at:
57 | //│ ║ l.4: class C[out A](x: A) {
58 | //│ ╙── ^
59 | //│ Int | error
60 | //│ res
61 | //│ = 2
62 |
63 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/InheritanceLevelMismatches.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 | :NoJS // TODO
4 |
5 |
6 | trait T1 { fun x: 0 | 1 }
7 | //│ trait T1 {
8 | //│ fun x: 0 | 1
9 | //│ }
10 |
11 | module Foo {
12 | trait T2 { fun x: 1 | 2 }
13 | class C extends T1, T2 { fun x = 1 }
14 | }
15 | //│ module Foo {
16 | //│ class C extends T1, T2 {
17 | //│ constructor()
18 | //│ fun x: 1
19 | //│ }
20 | //│ trait T2 {
21 | //│ fun x: 1 | 2
22 | //│ }
23 | //│ }
24 |
25 |
26 | mixin Foo { fun f = this.x }
27 | //│ mixin Foo() {
28 | //│ this: {x: 'x}
29 | //│ fun f: 'x
30 | //│ }
31 |
32 | module Bar {
33 | class C(val x: Int) extends Foo
34 | }
35 | //│ module Bar {
36 | //│ class C(x: Int) {
37 | //│ fun f: Int
38 | //│ }
39 | //│ }
40 |
41 |
42 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/IntraBlockPolymorphism.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | // * Note: eventually we should progressively type check every mutually-recursive group
5 | // * in topological order, to maximize polymorphism.
6 | // * But currently we just type check them in srouce code order.
7 | // * So the following inferred types differ:
8 |
9 | fun i(x) = x
10 | let a = i(0)
11 | let b = i(true)
12 | //│ fun i: forall 'a. 'a -> 'a
13 | //│ let a: 0
14 | //│ let b: true
15 | //│ a
16 | //│ = 0
17 | //│ b
18 | //│ = true
19 |
20 | :re // FIXME shouldn't be a reference error
21 | let a = i(0)
22 | fun i(x) = x
23 | let b = i(true)
24 | //│ let a: 0 | true | 'a
25 | //│ fun i: forall 'b. ('a & 'b) -> (0 | 'b)
26 | //│ let b: 0 | true
27 | //│ a
28 | //│ Runtime error:
29 | //│ ReferenceError: i1 is not defined
30 | //│ b
31 | //│ = true
32 |
33 | :re // FIXME shouldn't be a reference error
34 | let a = i(0)
35 | let b = i(true)
36 | fun i(x) = x
37 | //│ let a: 0 | true | 'a
38 | //│ let b: 0 | true | 'a
39 | //│ fun i: forall 'b. ('a & 'b) -> (0 | true | 'b)
40 | //│ a
41 | //│ Runtime error:
42 | //│ ReferenceError: i2 is not defined
43 | //│ b
44 | //│ Runtime error:
45 | //│ ReferenceError: i2 is not defined
46 |
47 |
48 | module Test {
49 | fun i(x) = x
50 | let a = i(0)
51 | let b = i(true)
52 | }
53 | //│ module Test {
54 | //│ let a: 0
55 | //│ let b: true
56 | //│ fun i: forall 'a. 'a -> 'a
57 | //│ }
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/LamPatterns.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | class Some(value: Int)
5 | //│ class Some(value: Int)
6 |
7 | :e // TODO
8 | Some(x) => x
9 | //│ ╔══[ERROR] Unsupported pattern shape:
10 | //│ ║ l.8: Some(x) => x
11 | //│ ╙── ^^^^^^^
12 | //│ ╔══[ERROR] identifier not found: x
13 | //│ ║ l.8: Some(x) => x
14 | //│ ╙── ^
15 | //│ error -> error
16 | //│ Code generation encountered an error:
17 | //│ term App(Var(Some),Tup(List((None,Fld(_,Var(x)))))) is not a valid pattern
18 |
19 | :js
20 | // FIXME type
21 | let f = Some => 0
22 | //│ let f: ((value: Int) -> Some) -> 0
23 | //│ // Prelude
24 | //│ class TypingUnit2 {}
25 | //│ const typing_unit2 = new TypingUnit2;
26 | //│ // Query 1
27 | //│ globalThis.f = function f(Some) {
28 | //│ return 0;
29 | //│ };
30 | //│ // End of generated code
31 | //│ f
32 | //│ = [Function: f]
33 |
34 | // :e // TODO
35 | f(Some)
36 | //│ 0
37 | //│ res
38 | //│ = 0
39 |
40 | // :e // TODO
41 | f(_ => error)
42 | //│ 0
43 | //│ res
44 | //│ = 0
45 |
46 | :e // TODO
47 | f(Some(0))
48 | //│ ╔══[ERROR] Type mismatch in application:
49 | //│ ║ l.47: f(Some(0))
50 | //│ ║ ^^^^^^^^^^
51 | //│ ╟── application of type `Some` is not a function
52 | //│ ║ l.47: f(Some(0))
53 | //│ ║ ^^^^^^^
54 | //│ ╟── Note: constraint arises from reference:
55 | //│ ║ l.21: let f = Some => 0
56 | //│ ╙── ^^^^
57 | //│ 0 | error
58 | //│ res
59 | //│ = 0
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/LitMatch.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | let r = false : Bool
5 | //│ let r: Bool
6 | //│ r
7 | //│ = false
8 |
9 | let b = (if r then true else false) : Bool
10 | //│ let b: Bool
11 | //│ b
12 | //│ = false
13 |
14 | let b = false : Bool
15 | //│ let b: Bool
16 | //│ b
17 | //│ = false
18 |
19 | b : true | false
20 | //│ Bool
21 | //│ res
22 | //│ = false
23 |
24 | if false is false then 0
25 | //│ 0
26 | //│ res
27 | //│ = 0
28 |
29 | fun foo(x) = if x is
30 | false then 0
31 | //│ fun foo: false -> 0
32 |
33 | fun foo(x) = if x is
34 | false then 0
35 | true then 1
36 | //│ fun foo: Bool -> (0 | 1)
37 |
38 | fun foo(x) = if x is
39 | 0 then "zero"
40 | true then "true"
41 | //│ fun foo: (0 | true) -> ("true" | "zero")
42 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/LocalLets.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | let f =
5 | let tmp = "ok"
6 | 123
7 | //│ let f: 123
8 | //│ f
9 | //│ = 123
10 |
11 |
12 | :e
13 | let x : Int | string
14 | let x = 1
15 | //│ ╔══[ERROR] `let` bindings must have a right-hand side
16 | //│ ║ l.13: let x : Int | string
17 | //│ ╙── ^^^^^^^^^^^^^^^^^^^^
18 | //│ let x: 1
19 | //│ let x: Int | string
20 | //│ x
21 | //│ =
22 | //│ x
23 | //│ = 1
24 |
25 | val x : Int | string
26 | val x = 1
27 | //│ val x: 1
28 | //│ val x: Int | string
29 | //│ x
30 | //│ =
31 | //│ x
32 | //│ = 1
33 |
34 |
35 | class E(x: Int)
36 | //│ class E(x: Int)
37 |
38 | :e // TODO support (currently parsed as a function definition named E)
39 | let E(x) = new E(1)
40 | //│ ╔══[ERROR] value E cannot be used as a type
41 | //│ ║ l.39: let E(x) = new E(1)
42 | //│ ╙── ^
43 | //│ ╔══[ERROR] type identifier not found: E
44 | //│ ║ l.39: let E(x) = new E(1)
45 | //│ ╙── ^
46 | //│ let E: anything -> error
47 | //│ E
48 | //│ = [Function: E1]
49 |
50 |
51 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/MissingImplBug.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | declare fun String: nothing
5 | //│ fun String: nothing
6 |
7 | let makeString: anything => { length: Int, charCodeAt: Int => Int } = String
8 | let StringInstance: { fromCharCode: Int => Str } = String
9 | //│ let makeString: anything -> {charCodeAt: Int -> Int, length: Int}
10 | //│ let StringInstance: {fromCharCode: Int -> Str}
11 | //│ makeString
12 | //│ = [Function: String]
13 | //│ StringInstance
14 | //│ = [Function: String]
15 |
16 | // * Why do we get below and not above??
17 |
18 | declare fun String: nothing
19 | let makeString: anything => { length: Int, charCodeAt: Int => Int } = String
20 | let StringInstance: { fromCharCode: Int => Str } = String
21 | //│ let makeString: anything -> {charCodeAt: Int -> Int, length: Int}
22 | //│ let StringInstance: {fromCharCode: Int -> Str}
23 | //│ fun String: nothing
24 | //│ makeString
25 | //│ = [Function: String]
26 | //│ StringInstance
27 | //│ = [Function: String]
28 |
29 |
30 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/MixinParameters.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | mixin BaseTest(x: Int) {
5 | fun test = x
6 | }
7 | //│ mixin BaseTest(x: Int) {
8 | //│ fun test: Int
9 | //│ }
10 |
11 | module Test extends BaseTest(42)
12 | //│ module Test {
13 | //│ fun test: Int
14 | //│ }
15 |
16 | Test.test
17 | //│ Int
18 | //│ res
19 | //│ = 42
20 |
21 | :e
22 | Test.x
23 | //│ ╔══[ERROR] Type `Test` does not contain member `x`
24 | //│ ║ l.22: Test.x
25 | //│ ╙── ^^
26 | //│ error
27 | //│ res
28 | //│ = undefined
29 |
30 |
31 | mixin BaseTest(val x: Int -> Int)
32 | //│ mixin BaseTest(x: Int -> Int)
33 |
34 | module Test extends BaseTest(id)
35 | //│ module Test
36 |
37 | Test.x(1)
38 | //│ 1
39 | //│ res
40 | //│ = 1
41 |
42 |
43 | :e // TODO support
44 | mixin BaseTest(x) {
45 | fun test = x
46 | }
47 | //│ ╔══[ERROR] Mixin parameters currently need type annotations
48 | //│ ║ l.44: mixin BaseTest(x) {
49 | //│ ╙── ^
50 | //│ mixin BaseTest(x: error) {
51 | //│ fun test: error
52 | //│ }
53 |
54 |
55 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/NestedClasses.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | class C0() {
5 | class NC0()
6 | }
7 | //│ class C0() {
8 | //│ class NC0()
9 | //│ }
10 |
11 | let c = C0()
12 | //│ let c: C0
13 | //│ c
14 | //│ = C0 {}
15 |
16 | :e
17 | c.NC0
18 | //│ ╔══[ERROR] Access to class member not yet supported
19 | //│ ║ l.17: c.NC0
20 | //│ ╙── ^^^^
21 | //│ error
22 | //│ res
23 | //│ = [Function (anonymous)] {
24 | //│ class: [class NC0],
25 | //│ unapply: [Function: unapply]
26 | //│ }
27 |
28 |
29 | module M0 {
30 | class NC0
31 | }
32 | //│ module M0 {
33 | //│ class NC0 {
34 | //│ constructor()
35 | //│ }
36 | //│ }
37 |
38 | :e
39 | M0.NC0
40 | //│ ╔══[ERROR] Access to class member not yet supported
41 | //│ ║ l.39: M0.NC0
42 | //│ ╙── ^^^^
43 | //│ error
44 | //│ res
45 | //│ = [class NC0]
46 |
47 |
48 | module M1 {
49 | module NM1
50 | }
51 | //│ module M1 {
52 | //│ module NM1
53 | //│ }
54 |
55 | :e
56 | M1.NM1
57 | //│ ╔══[ERROR] Access to module member not yet supported
58 | //│ ║ l.56: M1.NM1
59 | //│ ╙── ^^^^
60 | //│ error
61 | //│ res
62 | //│ = NM1 { class: [class NM1] }
63 |
64 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/New.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | class Foo[A](x: A)
5 | //│ class Foo[A](x: A)
6 |
7 | let f = Foo(1)
8 | //│ let f: Foo['A]
9 | //│ where
10 | //│ 'A :> 1
11 | //│ f
12 | //│ = Foo {}
13 |
14 | // let f = new Foo(1)
15 |
16 | if f is Foo then 1 else 0
17 | //│ 0 | 1
18 | //│ res
19 | //│ = 1
20 |
21 | if f is Foo(a) then a else 0
22 | //│ 0 | 1
23 | //│ res
24 | //│ = 1
25 |
26 | // case f of
27 | // { Foo ->
28 | // let a = f.x
29 | // a
30 | // | _ -> 0
31 | // }
32 |
33 | // Foo(A) =:= Foo & { x: A }
34 |
35 |
36 | fun test(x) = if x is Foo(a) then a
37 | //│ fun test: forall 'a. Foo['a] -> 'a
38 |
39 | test(f)
40 | //│ 1
41 | //│ res
42 | //│ = 1
43 |
44 | class PoInt(x: Int, y: Int)
45 | //│ class PoInt(x: Int, y: Int)
46 |
47 | let origin = new PoInt(0, 0)
48 | //│ let origin: PoInt
49 | //│ origin
50 | //│ = PoInt {}
51 |
52 |
53 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/NuAlexJ.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | fun foo(x) = [x, x]
5 | //│ fun foo: forall 'a. 'a -> ['a, 'a]
6 |
7 | id
8 | //│ forall 'a. 'a -> 'a
9 | //│ res
10 | //│ = [Function: id]
11 |
12 | let r = foo(id)
13 | //│ let r: [forall 'a. 'a -> 'a, forall 'a. 'a -> 'a]
14 | //│ r
15 | //│ = [ [Function: id], [Function: id] ]
16 |
17 |
18 | fun fst(x, _) = x
19 | fun snd(_, x) = x
20 | //│ fun fst: forall 'a. ('a, anything) -> 'a
21 | //│ fun snd: forall 'b. (anything, 'b) -> 'b
22 |
23 | fst(1, 2)
24 | //│ 1
25 | //│ res
26 | //│ = 1
27 |
28 | :e
29 | fst([1, 2])
30 | //│ ╔══[ERROR] Type mismatch in application:
31 | //│ ║ l.29: fst([1, 2])
32 | //│ ║ ^^^^^^^^^^^
33 | //│ ╟── argument of type `[[1, 2]]` does not match type `[?a, ?b]`
34 | //│ ║ l.29: fst([1, 2])
35 | //│ ║ ^^^^^^^^
36 | //│ ╟── Note: constraint arises from tuple literal:
37 | //│ ║ l.18: fun fst(x, _) = x
38 | //│ ╙── ^^^^^^
39 | //│ error
40 | //│ res
41 | //│ = [ 1, 2 ]
42 |
43 |
44 | fun fst([x, _]) = x
45 | fun snd([_, x]) = x
46 | //│ fun fst: forall 'a. (['a, anything]) -> 'a
47 | //│ fun snd: forall 'b. ([anything, 'b]) -> 'b
48 |
49 | let s = fst(r)
50 | //│ let s: forall 'a. 'a -> 'a
51 | //│ s
52 | //│ = [Function: id]
53 |
54 | s("hello")
55 | //│ "hello"
56 | //│ res
57 | //│ = 'hello'
58 |
59 | s(123)
60 | //│ 123
61 | //│ res
62 | //│ = 123
63 |
64 | fst(r)("hello")
65 | //│ "hello"
66 | //│ res
67 | //│ = 'hello'
68 |
69 |
70 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/NuForallTerms.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | forall 'a: (x: 'a) => x
5 | //│ forall 'a. (x: 'a) -> 'a
6 | //│ res
7 | //│ = [Function: res]
8 |
9 |
10 | forall 'a:
11 | (x: 'a) => x
12 | //│ forall 'a. (x: 'a) -> 'a
13 | //│ res
14 | //│ = [Function (anonymous)]
15 |
16 |
17 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/NuScratch.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/Numbers.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | let n = 123
5 | let m = n : Int
6 | let o = m : Num
7 | let p = o : Object
8 | let o = n : Num
9 | let p = n : Object
10 | let p = m : Object
11 | //│ let n: 123
12 | //│ let m: Int
13 | //│ let o: Num
14 | //│ let p: Object
15 | //│ let o: Num
16 | //│ let p: Object
17 | //│ let p: Object
18 | //│ n
19 | //│ = 123
20 | //│ m
21 | //│ = 123
22 | //│ o
23 | //│ = 123
24 | //│ p
25 | //│ = 123
26 | //│ o
27 | //│ = 123
28 | //│ p
29 | //│ = 123
30 | //│ p
31 | //│ = 123
32 |
33 |
34 | let x = NaN
35 | //│ let x: Num
36 | //│ x
37 | //│ = NaN
38 |
39 | // TODO polymorphic Num operations
40 | x + 1
41 | //│ ╔══[ERROR] Type mismatch in operator application:
42 | //│ ║ l.40: x + 1
43 | //│ ║ ^^^^^
44 | //│ ╟── reference of type `Num` is not an instance of type `Int`
45 | //│ ║ l.34: let x = NaN
46 | //│ ║ ^^^
47 | //│ ╟── but it flows into reference with expected type `Int`
48 | //│ ║ l.40: x + 1
49 | //│ ╙── ^
50 | //│ Int | error
51 | //│ res
52 | //│ = NaN
53 |
54 |
55 | true : Bool
56 | //│ Bool
57 | //│ res
58 | //│ = true
59 |
60 | true : Bool | Str
61 | //│ Str | false | true
62 | //│ res
63 | //│ = true
64 |
65 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/ParamOverriding.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | mixin Over {
5 | fun p = "hi"
6 | }
7 | //│ mixin Over() {
8 | //│ fun p: "hi"
9 | //│ }
10 |
11 |
12 | class Base1(val p: Int) extends Over {
13 | fun test = [p, this.p]
14 | fun test2 = super.p
15 | }
16 | //│ class Base1(p: Int) {
17 | //│ fun p: "hi"
18 | //│ fun test: [Int, Int]
19 | //│ fun test2: Int
20 | //│ }
21 |
22 |
23 | Base1(123).test
24 | //│ [Int, Int]
25 | //│ res
26 | //│ = [ 123, 123 ]
27 |
28 | Base1(123).test2
29 | //│ Int
30 | //│ res
31 | //│ = 'hi'
32 |
33 |
34 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/PartialApp.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 | // TODO support partial application syntax
4 | :AllowTypeErrors
5 |
6 |
7 | fun foo(x, y) = x + y
8 | //│ fun foo: (Int, Int) -> Int
9 |
10 |
11 | foo(2, _)
12 | //│ ╔══[ERROR] Widlcard in expression position.
13 | //│ ║ l.11: foo(2, _)
14 | //│ ╙── ^
15 | //│ Int
16 |
17 | // * ie
18 | tmp => foo(2, tmp)
19 | //│ Int -> Int
20 |
21 |
22 | _.foo(1)
23 | //│ ╔══[ERROR] Widlcard in expression position.
24 | //│ ║ l.22: _.foo(1)
25 | //│ ╙── ^
26 | //│ error
27 |
28 | // * ie
29 | x => x.foo(1)
30 | //│ forall 'a. {foo: 1 -> 'a} -> 'a
31 |
32 |
33 | _ + _
34 | //│ ╔══[ERROR] Widlcard in expression position.
35 | //│ ║ l.33: _ + _
36 | //│ ╙── ^
37 | //│ ╔══[ERROR] Widlcard in expression position.
38 | //│ ║ l.33: _ + _
39 | //│ ╙── ^
40 | //│ Int
41 |
42 | // * ie
43 | (x, y) => x + y
44 | //│ (Int, Int) -> Int
45 |
46 |
47 | _2 + _1
48 | //│ ╔══[ERROR] identifier not found: _2
49 | //│ ║ l.47: _2 + _1
50 | //│ ╙── ^^
51 | //│ ╔══[ERROR] identifier not found: _1
52 | //│ ║ l.47: _2 + _1
53 | //│ ╙── ^^
54 | //│ Int
55 |
56 | // * ie
57 | (x, y) => y + x
58 | //│ (Int, Int) -> Int
59 |
60 |
61 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/PrivateMemberOverriding.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | class Foo(x: Int)
5 | //│ class Foo(x: Int)
6 |
7 | class Bar() extends Foo(123) { fun x = true }
8 | //│ class Bar() extends Foo {
9 | //│ fun x: true
10 | //│ }
11 |
12 | Bar().x
13 | //│ true
14 | //│ res
15 | //│ = true
16 |
17 | if Bar() is Foo(a) then a
18 | //│ Int
19 | //│ res
20 | //│ = 123
21 |
22 |
23 | class Bar(val x: Bool) extends Foo(123)
24 | //│ class Bar(x: Bool) extends Foo
25 |
26 | Bar(true).x
27 | //│ Bool
28 | //│ res
29 | //│ = true
30 |
31 | if Bar(true) is Foo(a) then a
32 | //│ Int
33 | //│ res
34 | //│ = 123
35 |
36 |
37 | class Bar(x: Bool) extends Foo(123)
38 | //│ class Bar(x: Bool) extends Foo
39 |
40 | :e // * Expected
41 | Bar(true).x
42 | //│ ╔══[ERROR] Parameter 'x' cannot be accessed as a field
43 | //│ ║ l.41: Bar(true).x
44 | //│ ║ ^^
45 | //│ ╟── Either make the parameter a `val` or access it through destructuring
46 | //│ ║ l.37: class Bar(x: Bool) extends Foo(123)
47 | //│ ╙── ^
48 | //│ error | false | true
49 | //│ res
50 | //│ = undefined
51 |
52 | if Bar(true) is Foo(a) then a
53 | //│ Int
54 | //│ res
55 | //│ = 123
56 |
57 |
58 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/RefinedPattern.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | class C
5 | //│ class C {
6 | //│ constructor()
7 | //│ }
8 |
9 |
10 | :e
11 | fun test(x) = if x is
12 | C then x.a
13 | //│ ╔══[ERROR] Type `C` does not contain member `a`
14 | //│ ║ l.12: C then x.a
15 | //│ ╙── ^^
16 | //│ fun test: C -> error
17 |
18 | fun test(x) = if x is
19 | refined(C) then x.a
20 | //│ fun test: forall 'a. (C & {a: 'a}) -> 'a
21 |
22 | class D(val a: Int) extends C
23 | //│ class D(a: Int) extends C
24 |
25 | test(D(123))
26 | //│ Int
27 | //│ res
28 | //│ = 123
29 |
30 |
31 | :e
32 | refined
33 | //│ ╔══[ERROR] Illegal use of reserved operator: refined
34 | //│ ║ l.32: refined
35 | //│ ╙── ^^^^^^^
36 | //│ ╔══[ERROR] identifier not found: refined
37 | //│ ║ l.32: refined
38 | //│ ╙── ^^^^^^^
39 | //│ error
40 | //│ Code generation encountered an error:
41 | //│ unresolved symbol refined
42 |
43 |
44 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/Res.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | x => x + 2
5 | //│ Int -> Int
6 | //│ res
7 | //│ = [Function: res]
8 |
9 | :e
10 | res(1)
11 | //│ ╔══[ERROR] identifier not found: res
12 | //│ ║ l.10: res(1)
13 | //│ ╙── ^^^
14 | //│ error
15 | //│ res
16 | //│ = 3
17 |
18 |
19 | let res = x => x + 2
20 | //│ let res: Int -> Int
21 | //│ res
22 | //│ = [Function: res1]
23 |
24 | res(1)
25 | //│ Int
26 | //│ res
27 | //│ = 3
28 |
29 | // FIXME `res` not accounted in type context
30 | :re
31 | res(1)
32 | //│ Int
33 | //│ res
34 | //│ Runtime error:
35 | //│ TypeError: res is not a function
36 |
37 |
38 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/RigidVariables.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | // * Flexible
5 |
6 | fun f(x: 'test) = [x.b, x]
7 | //│ fun f: forall 'b 'test. (x: {b: 'b} & 'test) -> ['b, 'test]
8 |
9 |
10 | // * Rigid
11 |
12 | :e
13 | fun f[A](x: A) = x.b
14 | //│ ╔══[ERROR] Type `A` does not contain member `b`
15 | //│ ║ l.13: fun f[A](x: A) = x.b
16 | //│ ╙── ^^
17 | //│ fun f: (x: anything) -> error
18 |
19 | fun f[A](x: A & { b: ' }) = x.b
20 | //│ fun f: forall 'b. (x: {b: 'b}) -> 'b
21 |
22 | :e
23 | module Foo {
24 | fun f[A](x: A) = x.b
25 | }
26 | //│ ╔══[ERROR] Type `A` does not contain member `b`
27 | //│ ║ l.24: fun f[A](x: A) = x.b
28 | //│ ╙── ^^
29 | //│ module Foo {
30 | //│ fun f: (x: anything) -> error
31 | //│ }
32 |
33 | :e
34 | class Foo[A](x: A) {
35 | fun f = x.b
36 | }
37 | //│ ╔══[ERROR] Type `A` does not contain member `b`
38 | //│ ║ l.35: fun f = x.b
39 | //│ ╙── ^^
40 | //│ class Foo[A](x: A) {
41 | //│ fun f: error
42 | //│ }
43 |
44 |
45 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/SimpleSymbolicOps.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | fun (-) i(x, y) = x
5 | //│ fun (-) i: forall 'a. ('a, anything) -> 'a
6 |
7 | 1 - 1
8 | //│ 1
9 | //│ res
10 | //│ = 1
11 |
12 |
13 | fun (-) i(x, y) = x
14 | [i(1,1), i(2,1), 1 - 1, 2 - 1]
15 | //│ fun (-) i: forall 'a. ('a, anything) -> 'a
16 | //│ [1, 2, 1, 2]
17 | //│ res
18 | //│ = [ 1, 2, 1, 2 ]
19 |
20 |
21 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/StupidJS.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | module C { fun f() = this }
5 | //│ module C {
6 | //│ fun f: () -> C
7 | //│ }
8 |
9 | C.f()
10 | //│ C
11 | //│ res
12 | //│ = C { class: [class C] }
13 |
14 |
15 | // * In JS semantics, C.f will return a plain method **without capturing `this`**!!
16 | // * This is very dumb. In Python for example, one gets a closure that captures `this`.
17 | // * We can't easily work around this without incurring either bad performance overhead
18 | // * or JS/TS interoperability woes.
19 | // * Therefore, we'll make sure to reflecy the wonky semantics in the typer
20 | // * (or maybe just make it fail type checking altogether.)
21 |
22 | // :e // TODO prevent unapplied method selections in the type system...
23 | let r = id(C.f)()
24 | //│ let r: C
25 | //│ r
26 | //│ = undefined
27 |
28 | :re
29 | r.f
30 | //│ () -> C
31 | //│ res
32 | //│ Runtime error:
33 | //│ TypeError: Cannot read properties of undefined (reading 'f')
34 |
35 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/Subscripts.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | let xs = [0, 1, 2]
5 | //│ let xs: [0, 1, 2]
6 | //│ xs
7 | //│ = [ 0, 1, 2 ]
8 |
9 | if xs.[0] is
10 | undefined then 0
11 | x then x
12 | //│ 0 | 1 | 2
13 | //│ res
14 | //│ = 0
15 |
16 |
17 | :e
18 | xs.[0] + 1
19 | //│ ╔══[ERROR] Type mismatch in operator application:
20 | //│ ║ l.18: xs.[0] + 1
21 | //│ ║ ^^^^^^^^
22 | //│ ╟── possibly-undefined array access of type `()` is not an instance of type `Int`
23 | //│ ║ l.18: xs.[0] + 1
24 | //│ ╙── ^^^^
25 | //│ Int | error
26 | //│ res
27 | //│ = 1
28 |
29 |
30 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/TraitParameters.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | :e
5 | trait Base1(x: Int)
6 | //│ ╔══[ERROR] trait parameters are not yet supported
7 | //│ ║ l.5: trait Base1(x: Int)
8 | //│ ╙── ^^^^^^^^
9 | //│ trait Base1
10 |
11 |
12 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/TupleParamBlunder.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | // * TODO fix the parsing of this tuple-taking function signature!
5 | fun f: [Int, Int] -> Int
6 | fun f(a, b) = a + b // should not be a valid implementation
7 | //│ fun f: (Int, Int) -> Int
8 | //│ fun f: (Int, Int) -> Int
9 |
10 | fun f: (Int, Int) -> Int
11 | fun f(a, b) = a + b
12 | //│ fun f: (Int, Int) -> Int
13 | //│ fun f: (Int, Int) -> Int
14 |
15 | :e
16 | fun f: [Int, Int] => Int
17 | fun f(a, b) = a + b
18 | //│ ╔══[ERROR] Type mismatch in definition:
19 | //│ ║ l.17: fun f(a, b) = a + b
20 | //│ ║ ^^^^^^^^^^^^^^^
21 | //│ ╟── type `[[Int, Int]]` does not match type `[?a, ?b]`
22 | //│ ║ l.16: fun f: [Int, Int] => Int
23 | //│ ║ ^^^^^^^^^^
24 | //│ ╟── Note: constraint arises from tuple literal:
25 | //│ ║ l.17: fun f(a, b) = a + b
26 | //│ ╙── ^^^^^^
27 | //│ fun f: (Int, Int) -> Int
28 | //│ fun f: ([Int, Int]) -> Int
29 |
30 | fun f: (Int, Int) => Int
31 | fun f(a, b) = a + b
32 | //│ fun f: (Int, Int) -> Int
33 | //│ fun f: (Int, Int) -> Int
34 |
35 |
36 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/TypeAliases.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | type I = Int
5 | //│ type I = Int
6 |
7 | class CI1
8 | //│ class CI1 {
9 | //│ constructor()
10 | //│ }
11 |
12 | // :e
13 | type AI1 = Array[Int]
14 | //│ type AI1 = Array[Int]
15 |
16 | type AI2 = Array
17 | //│ type AI2 = Array[Int]
18 |
19 | :e
20 | type AI3(n) = Array[Int]
21 | //│ ╔══[ERROR] Type alias definitions cannot have value parameters
22 | //│ ║ l.20: type AI3(n) = Array[Int]
23 | //│ ╙── ^^^
24 | //│ type AI3 = Array[Int]
25 |
26 | // :e
27 | type AI3[A] = Array
28 | //│ type AI3[A] = Array[A]
29 |
30 | type AI4 = Array
31 | //│ type AI4[A] = Array[A]
32 |
33 | let r = 123
34 | //│ let r: 123
35 | //│ r
36 | //│ = 123
37 |
38 | r: I
39 | //│ I
40 | //│ res
41 | //│ = 123
42 |
43 | let a = [r, r, r]
44 | //│ let a: [123, 123, 123]
45 | //│ a
46 | //│ = [ 123, 123, 123 ]
47 |
48 | a : AI1
49 | //│ AI1
50 | //│ res
51 | //│ = [ 123, 123, 123 ]
52 |
53 | a : AI2
54 | //│ AI2
55 | //│ res
56 | //│ = [ 123, 123, 123 ]
57 |
58 | a : AI3[Int]
59 | //│ AI3[Int]
60 | //│ res
61 | //│ = [ 123, 123, 123 ]
62 |
63 | a : AI4
64 | //│ AI4[Int]
65 | //│ res
66 | //│ = [ 123, 123, 123 ]
67 |
68 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/TypeOps.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | type *[A, B] = [A, B]
5 | //│ type *[A, B] = [A, B]
6 |
7 |
8 | fun x : Int * Int
9 | fun x = [0, 1]
10 | //│ fun x: [0, 1]
11 | //│ fun x: *[Int, Int]
12 |
13 | fun x : Int * [Int]
14 | fun x = [0, [1]]
15 | //│ fun x: [0, [1]]
16 | //│ fun x: *[Int, [Int]]
17 |
18 | fun x : [Int] * Int
19 | fun x = [[0], 1]
20 | //│ fun x: [[0], 1]
21 | //│ fun x: *[[Int], Int]
22 |
23 |
24 | type Id[A] = A
25 | //│ type Id[A] = A
26 |
27 | :e
28 | fun x: Id[Int, Int]
29 | //│ ╔══[ERROR] Wrong number of type arguments – expected 1, found 2
30 | //│ ║ l.28: fun x: Id[Int, Int]
31 | //│ ╙── ^^^^^^^^^^^^
32 | //│ fun x: Id[Int]
33 |
34 | fun x: Id[[Int, Int]]
35 | //│ fun x: Id[[Int, Int]]
36 |
37 | fun x: Id[[[Int, Int]]]
38 | //│ fun x: Id[[[Int, Int]]]
39 |
40 |
41 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/TypeSelections.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | module M {
5 | type T = Int -> Int
6 | class C(n: Int)
7 | fun mkC = C
8 | }
9 | //│ module M {
10 | //│ class C(n: Int)
11 | //│ type T = Int -> Int
12 | //│ fun mkC: (n: Int) -> C
13 | //│ }
14 |
15 | let x: M.T = id
16 | //│ let x: Int -> Int
17 | //│ x
18 | //│ = [Function: id]
19 |
20 | fun foo(x: M.C) = x
21 | //│ fun foo: (x: C) -> C
22 |
23 |
24 | foo(M.mkC(42))
25 | //│ C
26 | //│ res
27 | //│ = C {}
28 |
29 |
30 | :e
31 | 42 : M.mkC
32 | //│ ╔══[ERROR] Illegal selection of value member in type position
33 | //│ ║ l.31: 42 : M.mkC
34 | //│ ╙── ^^^^
35 | //│ error
36 | //│ res
37 | //│ = 42
38 |
39 |
40 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/TypeVariables.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | fun x: 'a -> 'a = succ
5 | //│ fun x: Int -> Int
6 |
7 | :e
8 | fun x: forall 'a: 'a -> 'a = succ
9 | //│ ╔══[ERROR] Type mismatch in type ascription:
10 | //│ ║ l.8: fun x: forall 'a: 'a -> 'a = succ
11 | //│ ║ ^^^^
12 | //│ ╟── type `'a` is not an instance of type `Int`
13 | //│ ║ l.8: fun x: forall 'a: 'a -> 'a = succ
14 | //│ ║ ^^
15 | //│ ╟── Note: quantified type variable 'a is defined at:
16 | //│ ║ l.8: fun x: forall 'a: 'a -> 'a = succ
17 | //│ ╙── ^^
18 | //│ fun x: forall 'a. 'a -> 'a
19 |
20 | fun x: [Int -> Int] = [id : forall 'a: 'a -> 'a]
21 | //│ fun x: [Int -> Int]
22 |
23 | :pe
24 | :e
25 | fun x: [Int -> Int] = [id : forall 'a: 'a -> 'a,]
26 | //│ ╔══[PARSE ERROR] Unexpected end of square bracket section; an expression was expected here
27 | //│ ║ l.25: fun x: [Int -> Int] = [id : forall 'a: 'a -> 'a,]
28 | //│ ╙── ^
29 | //│ ╔══[ERROR] type identifier not found: ,
30 | //│ ║ l.25: fun x: [Int -> Int] = [id : forall 'a: 'a -> 'a,]
31 | //│ ╙── ^^^^^^^^^
32 | //│ fun x: [Int -> Int]
33 |
34 | fun x: [Int -> Int,] = [id : forall 'a: 'a -> 'a]
35 | //│ fun x: [Int -> Int]
36 |
37 |
38 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/TypingUnitTerms.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | :e
5 | fun test =
6 | let x = 0(0)
7 | 1
8 | //│ ╔══[ERROR] Type mismatch in application:
9 | //│ ║ l.6: let x = 0(0)
10 | //│ ║ ^^^^
11 | //│ ╟── integer literal of type `0` is not a function
12 | //│ ║ l.6: let x = 0(0)
13 | //│ ╙── ^
14 | //│ fun test: 1
15 |
16 |
17 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/TypreMembers.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | class Test { type T = Int }
5 | //│ class Test {
6 | //│ constructor()
7 | //│ type T = Int
8 | //│ }
9 |
10 | 1 : Test.T
11 | //│ Int
12 | //│ res
13 | //│ = 1
14 |
15 |
16 | trait Test { type T = Int }
17 | //│ trait Test {
18 | //│ type T = Int
19 | //│ }
20 |
21 | :e
22 | 1 : Test.T
23 | //│ ╔══[ERROR] Illegal prefix of type selection: Test
24 | //│ ║ l.22: 1 : Test.T
25 | //│ ╙── ^^^^
26 | //│ error
27 | //│ res
28 | //│ = 1
29 |
30 |
31 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/UnaryMinus.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 | -1
4 | //│ -1
5 | //│ res
6 | //│ = -1
7 |
8 | - 1
9 | //│ -1
10 | //│ res
11 | //│ = -1
12 |
13 | 1+1
14 | //│ Int
15 | //│ res
16 | //│ = 2
17 |
18 | 1-3
19 | //│ Int
20 | //│ res
21 | //│ = -2
22 |
23 | 3-1
24 | //│ Int
25 | //│ res
26 | //│ = 2
27 |
28 | 1 - (3 - 5)
29 | //│ Int
30 | //│ res
31 | //│ = 3
32 |
33 | 3 - 1
34 | //│ Int
35 | //│ res
36 | //│ = 2
37 |
38 | 1 -1
39 | //│ Int
40 | //│ res
41 | //│ = 0
42 |
43 | 1-1
44 | //│ Int
45 | //│ res
46 | //│ = 0
47 |
48 | 1+ -1
49 | //│ Int
50 | //│ res
51 | //│ = 0
52 |
53 | 1 - (1 - 1)
54 | //│ Int
55 | //│ res
56 | //│ = 1
57 |
58 | 1 - 1
59 | //│ Int
60 | //│ res
61 | //│ = 0
62 |
63 | 1 - - 1
64 | //│ Int
65 | //│ res
66 | //│ = 2
67 |
68 | 1 - - - - 1
69 | //│ Int
70 | //│ res
71 | //│ = 2
72 |
73 | fun f() = 6
74 | -f()
75 | //│ fun f: () -> 6
76 | //│ Int
77 | //│ res
78 | //│ = -6
79 |
80 | fun inv(x: Int) = -x
81 | inv(15)
82 | inv(inv(15))
83 | //│ fun inv: (x: Int) -> Int
84 | //│ Int
85 | //│ res
86 | //│ = -15
87 | //│ res
88 | //│ = 15
89 |
90 | inv(f())
91 | //│ Int
92 | //│ res
93 | //│ = -6
94 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/Uninstantiable.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | :e
5 | Int
6 | //│ ╔══[ERROR] Class Int is abstract and cannot be instantiated
7 | //│ ║ l.5: Int
8 | //│ ╙── ^^^
9 | //│ ╔══[ERROR] Class Int cannot be instantiated as it exposes no constructor
10 | //│ ║ l.5: Int
11 | //│ ╙── ^^^
12 | //│ error
13 | //│ Code generation encountered an error:
14 | //│ unresolved symbol Int
15 |
16 | :e
17 | Int()
18 | //│ ╔══[ERROR] Class Int is abstract and cannot be instantiated
19 | //│ ║ l.17: Int()
20 | //│ ╙── ^^^
21 | //│ ╔══[ERROR] Class Int cannot be instantiated as it exposes no constructor
22 | //│ ║ l.17: Int()
23 | //│ ╙── ^^^
24 | //│ error
25 | //│ Code generation encountered an error:
26 | //│ unresolved symbol Int
27 |
28 | :e
29 | new Int
30 | //│ ╔══[ERROR] Class Int is abstract and cannot be instantiated
31 | //│ ║ l.29: new Int
32 | //│ ╙── ^^^
33 | //│ Int
34 | //│ Code generation encountered an error:
35 | //│ unresolved symbol Int
36 |
37 |
38 | // FIXME forbid statically
39 | module A extends Int
40 | //│ module A extends Int, Num
41 | //│ Code generation encountered an error:
42 | //│ unresolved parent Int.
43 |
44 |
45 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/ValSigs.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | val x: Int
5 | //│ val x: Int
6 | //│ x
7 | //│ =
8 |
9 | // * Note that this counts as a completely new `val` since it's in a new block
10 | val x = "hi"
11 | //│ val x: "hi"
12 | //│ x
13 | //│ = 'hi'
14 |
15 |
16 | val x: Int
17 | val x = 1
18 | //│ val x: 1
19 | //│ val x: Int
20 | //│ x
21 | //│ =
22 | //│ x
23 | //│ = 1
24 | val x = 1
25 | //│ val x: 1
26 | //│ x
27 | //│ = 1
28 |
29 | x
30 | //│ 1
31 | //│ res
32 | //│ = 1
33 |
34 |
35 | :e
36 | val x: Int
37 | val x = "oops"
38 | //│ ╔══[ERROR] Type mismatch in definition:
39 | //│ ║ l.37: val x = "oops"
40 | //│ ║ ^^^^^^^^^^
41 | //│ ╟── string literal of type `"oops"` is not an instance of type `Int`
42 | //│ ║ l.37: val x = "oops"
43 | //│ ║ ^^^^^^
44 | //│ ╟── but it flows into definition of value x with expected type `Int`
45 | //│ ║ l.37: val x = "oops"
46 | //│ ║ ^^^^^^^^^^
47 | //│ ╟── Note: constraint arises from type reference:
48 | //│ ║ l.36: val x: Int
49 | //│ ╙── ^^^
50 | //│ val x: "oops"
51 | //│ val x: Int
52 | //│ x
53 | //│ =
54 | //│ x
55 | //│ = 'oops'
56 |
57 |
58 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/Vals.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | val a = 1
5 | val b = a + 1
6 | //│ val a: 1
7 | //│ val b: Int
8 | //│ a
9 | //│ = 1
10 | //│ b
11 | //│ = 2
12 |
13 |
14 | // :e // FIXME should not type check
15 | :ge
16 | val c = d + 1
17 | val d = 1
18 | //│ val c: Int
19 | //│ val d: 1
20 | //│ Code generation encountered an error:
21 | //│ unguarded recursive use of by-value binding d
22 |
23 |
24 | // :e // FIXME should not type check
25 | :ge
26 | val a = a
27 | //│ val a: nothing
28 | //│ Code generation encountered an error:
29 | //│ unguarded recursive use of by-value binding a
30 |
31 |
32 | val f(x) = x
33 | //│ val f: forall 'a. 'a -> 'a
34 | //│ f
35 | //│ = [Function: f]
36 |
37 | f(123)
38 | //│ 123
39 | //│ res
40 | //│ = 123
41 |
42 |
43 | module M {
44 | let tmp = 2
45 | val f(x) = x + tmp
46 | }
47 | //│ module M {
48 | //│ val f: Int -> Int
49 | //│ let tmp: 2
50 | //│ }
51 |
52 | M.f(123)
53 | //│ Int
54 | //│ res
55 | //│ = 125
56 |
57 |
58 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/Varargs.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | // * Built-in vararg
5 |
6 | :js
7 | join
8 | //│ (...Array[Str]) -> Str
9 | //│ // Prelude
10 | //│ function join(...xs) {
11 | //│ return xs.join("");
12 | //│ }
13 | //│ let res;
14 | //│ class TypingUnit {}
15 | //│ const typing_unit = new TypingUnit;
16 | //│ // Query 1
17 | //│ res = join;
18 | //│ // End of generated code
19 | //│ res
20 | //│ = [Function: join]
21 |
22 | join("Hello", ",", " ", "World", "!")
23 | //│ Str
24 | //│ res
25 | //│ = 'Hello, World!'
26 |
27 |
28 | // * TODO It's currently not possible to define vararg-taking functions manually...
29 |
30 | :pe
31 | :e
32 | fun test(...xs) = xs.length
33 | //│ ╔══[PARSE ERROR] Unexpected operator here
34 | //│ ║ l.32: fun test(...xs) = xs.length
35 | //│ ╙── ^^^
36 | //│ ╔══[ERROR] identifier not found: xs
37 | //│ ║ l.32: fun test(...xs) = xs.length
38 | //│ ╙── ^^
39 | //│ fun test: () -> error
40 | //│ Code generation encountered an error:
41 | //│ unresolved symbol xs
42 |
43 |
44 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/WeirdDefs.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | fun fst[x, _] = error : x -> x
5 | //│ fun fst: forall 'x. 'x -> 'x
6 |
7 | :e
8 | fun fst[x, _] = x
9 | //│ ╔══[ERROR] identifier not found: x
10 | //│ ║ l.8: fun fst[x, _] = x
11 | //│ ╙── ^
12 | //│ fun fst: error
13 | //│ Code generation encountered an error:
14 | //│ unresolved symbol x
15 |
16 |
17 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/With.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | {} with {}
5 | //│ anything
6 | //│ res
7 | //│ = {}
8 |
9 | {x: 1} with {y: 2}
10 | //│ {x: 1, y: 2}
11 | //│ res
12 | //│ = { x: 1, y: 2 }
13 |
14 | {x: 1} with {x: 2}
15 | //│ {x: 2}
16 | //│ res
17 | //│ = { x: 2 }
18 |
19 |
20 | :pe
21 | {x: 1} with 123
22 | //│ ╔══[PARSE ERROR] record literal expected here; found integer literal
23 | //│ ║ l.21: {x: 1} with 123
24 | //│ ╙── ^^^
25 | //│ {x: 1}
26 | //│ res
27 | //│ = { x: 1 }
28 |
29 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/repro0.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 | :NoJS
3 |
4 |
5 | class Add[out E](val lhs: E)
6 | val add11 = Add(add11)
7 | module EvalAddLit {
8 | fun eval(e: Add['A]) =
9 | if e is Add then eval(e.lhs)
10 | }
11 | let res = EvalAddLit.eval(add11)
12 | //│ class Add[E](lhs: E)
13 | //│ val add11: 'E
14 | //│ module EvalAddLit {
15 | //│ fun eval: forall 'A. (e: 'A) -> nothing
16 | //│ }
17 | //│ let res: nothing
18 | //│ where
19 | //│ 'A <: Add['A]
20 | //│ 'E :> Add['E]
21 |
22 |
23 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/repro1.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 | :NoJS
3 |
4 |
5 | class Union[out Region](val a: Region)
6 | // class Union[Region](a: Region)
7 | //│ class Union[Region](a: Region)
8 |
9 | fun go(x) = Union(go(x))
10 | let circles = go(2)
11 | //│ fun go: forall 'Region. anything -> 'Region
12 | //│ let circles: forall 'Region0. 'Region0
13 | //│ where
14 | //│ 'Region0 :> Union['Region0]
15 | //│ 'Region :> Union['Region]
16 |
17 |
18 | fun contains(a) =
19 | if a is Union then contains(a.a)
20 | //│ fun contains: forall 'a. 'a -> nothing
21 | //│ where
22 | //│ 'a <: Union['a]
23 |
24 | contains(circles)
25 | //│ nothing
26 |
27 |
28 | mixin Contains {
29 | fun contains(a) =
30 | if a is Union then this.contains(a.a)
31 | }
32 | //│ mixin Contains() {
33 | //│ this: {contains: 'a -> 'b}
34 | //│ fun contains: Union['a] -> 'b
35 | //│ }
36 |
37 | module TestContains extends Contains
38 | //│ module TestContains {
39 | //│ fun contains: 'a -> nothing
40 | //│ }
41 | //│ where
42 | //│ 'a <: Union['a]
43 |
44 | TestContains.contains(circles)
45 | //│ nothing
46 |
47 |
48 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/repro_EvalNegNeg.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | class Add(lhs: E, rhs: E)
5 | class Lit(n: Int)
6 | class Neg(expr: A)
7 | //│ class Add[E](lhs: E, rhs: E)
8 | //│ class Lit(n: Int)
9 | //│ class Neg[A](expr: A)
10 |
11 |
12 | // Note the inferred type because of current UCS limitation
13 | mixin EvalBase {
14 | fun eval(e) =
15 | if e is Neg(Neg(d)) then this.eval(d)
16 | else if e is Neg(d) then 0 - this.eval(d)
17 | else if e is
18 | Lit(n) then n
19 | Add(l, r) then this.eval(l) + this.eval(r)
20 | }
21 | //│ mixin EvalBase() {
22 | //│ this: {eval: 'a -> 'b & 'c -> Int}
23 | //│ fun eval: (Add['c] | Lit | Neg['c & (Neg['a] | Object & ~#Neg)]) -> (Int | 'b)
24 | //│ }
25 |
26 | // module TestLang extends EvalBase, EvalNeg
27 | module TestLang extends EvalBase
28 | //│ module TestLang {
29 | //│ fun eval: 'a -> Int
30 | //│ }
31 | //│ where
32 | //│ 'a <: Add['a] | Lit | Neg['a & (Neg['a] | Object & ~#Neg)]
33 |
34 |
35 | fun mk(n) = if n is
36 | 0 then Lit(0)
37 | 1 then Neg(mk(n))
38 | _ then Add(mk(n), mk(n))
39 | //│ fun mk: forall 'a. Object -> (Lit | 'a)
40 | //│ where
41 | //│ 'a :> Add[Lit | 'a] | Neg[Lit | 'a]
42 |
43 | :stats
44 | TestLang.eval(mk(0))
45 | //│ Int
46 | //│ res
47 | //│ = 0
48 | //│ constrain calls : 254
49 | //│ annoying calls : 106
50 | //│ subtyping calls : 1430
51 |
52 |
53 |
--------------------------------------------------------------------------------
/shared/src/test/diff/nu/repro_PolymorphicVariants.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 | // Test that reprduces subtle type simplification bug
4 |
5 | class Cons[out A](head: A, tail: Cons[A] | Nil)
6 | module Nil
7 | //│ class Cons[A](head: A, tail: Cons[A] | Nil)
8 | //│ module Nil
9 |
10 | class Abs[A](x: string, t: A)
11 | class App[A](s: A, t: A)
12 | //│ class Abs[A](x: string, t: A)
13 | //│ class App[A](s: A, t: A)
14 |
15 | fun eval(sub, v) =
16 | if v is
17 | Abs(x, t) then
18 | eval(Cons([error, error], Nil), error)
19 | eval(Cons(error, sub), error)
20 | error
21 | //│ fun eval: (Cons[anything] | Nil, Abs[anything]) -> nothing
22 |
23 | mixin EvalLambda {
24 | fun eval(sub, v) =
25 | if v is
26 | Abs(x, t) then
27 | this.eval(Cons([error, error], Nil), error)
28 | this.eval(Cons([x, error], sub), error)
29 | error
30 | }
31 | //│ mixin EvalLambda() {
32 | //│ this: {eval: (Cons[[string, nothing] | 'A], nothing) -> ()}
33 | //│ fun eval: (Cons['A] | Nil, Abs[anything]) -> nothing
34 | //│ }
35 |
36 | // * Note: this used to crash because of a current type simplification bug: analyze2 does not traverse TVs witht he correct PolMap
37 | // * The original unreduced version in PolymorphicVariants.mls still crashes...
38 | // :ds
39 | module Test1 extends EvalLambda
40 | //│ module Test1 {
41 | //│ fun eval: (Cons[anything] | Nil, Abs[anything]) -> nothing
42 | //│ }
43 |
44 |
--------------------------------------------------------------------------------
/shared/src/test/diff/parser/Annot.mls:
--------------------------------------------------------------------------------
1 |
2 | :p
3 | @hello
4 | fun hello(x) =
5 | @a
6 | @b
7 | let rec x = @hello 2
8 | //│ |@|hello|↵|#fun| |hello|(|x|)| |#=| |→|@|a|↵|@|b|↵|#let| |#rec| |x| |#=| |@|hello| |2|←|
9 | //│ Parsed: {fun hello = (x,) => {let rec x = @hello 2}}
10 | //│ AST: TypingUnit(List(NuFunDef(None,Var(hello),None,List(),Left(Lam(Tup(List((None,Fld(_,Var(x))))),Blk(List(NuFunDef(Some(true),Var(x),None,List(),Left(Ann(Var(hello),IntLit(2)))))))))))
11 | //│ Parsed:
12 |
13 | :p
14 | @tailrec 2
15 | //│ |@|tailrec| |2|
16 | //│ Parsed: {@tailrec 2}
17 | //│ AST: TypingUnit(List(Ann(Var(tailrec),IntLit(2))))
18 | //│ Parsed:
19 |
20 | :p
21 | if @hello true then 2 else 3
22 | //│ |#if| |@|hello| |true| |#then| |2| |#else| |3|
23 | //│ Parsed: {if (@hello true) then 2 else 3}
24 | //│ AST: TypingUnit(List(If(IfThen(Ann(Var(hello),Var(true)),IntLit(2)),Some(IntLit(3)))))
25 | //│ Parsed:
26 |
27 | :pe
28 | if @test x
29 | is Foo then 2
30 | //│ |#if| |@|test| |x|→|is| |Foo| |#then| |2|←|
31 | //│ ╔══[PARSE ERROR] Unexpected annotation
32 | //│ ║ l.28: if @test x
33 | //│ ╙── ^^^^
34 | //│ Parsed: {if x ‹· is (Foo) then 2›}
35 |
36 |
--------------------------------------------------------------------------------
/shared/src/test/diff/parser/Binds.mls:
--------------------------------------------------------------------------------
1 | :AllowParseErrors
2 |
3 |
4 | f(x) is True
5 | //│ |f|(|x|)| |is| |True|
6 | //│ Parsed: {is(f(x,),)(True,)}
7 |
8 | // Precedence of 'of'/'is' may be surprising!
9 | f of x is True
10 | //│ |f| |#of| |x| |is| |True|
11 | //│ Parsed: {f(is(x,)(True,),)}
12 |
13 |
14 |
--------------------------------------------------------------------------------
/shared/src/test/diff/parser/Brackets.mls:
--------------------------------------------------------------------------------
1 |
2 | ()
3 | //│ |(||)|
4 | //│ Parsed: {undefined}
5 |
6 | []
7 | //│ |[||]|
8 | //│ Parsed: {[]}
9 |
10 | {}
11 | //│ |{||}|
12 | //│ Parsed: {'{' {} '}'}
13 |
14 | :pe
15 | (}
16 | //│ ╔══[PARSE ERROR] Mistmatched closing curly brace
17 | //│ ║ l.15: (}
18 | //│ ║ ^
19 | //│ ╟── does not correspond to opening parenthesis
20 | //│ ║ l.15: (}
21 | //│ ╙── ^
22 | //│ |(||)|
23 | //│ Parsed: {undefined}
24 |
25 | (([{}]))
26 | //│ |(|(|[|{||}|]|)|)|
27 | //│ Parsed: {'(' '(' ['{' {} '}',] ')' ')'}
28 |
29 | :pe
30 | (([{})])
31 | //│ ╔══[PARSE ERROR] Mistmatched closing parenthesis
32 | //│ ║ l.30: (([{})])
33 | //│ ║ ^
34 | //│ ╟── does not correspond to opening square bracket
35 | //│ ║ l.30: (([{})])
36 | //│ ╙── ^
37 | //│ ╔══[PARSE ERROR] Mistmatched closing square bracket
38 | //│ ║ l.30: (([{})])
39 | //│ ║ ^
40 | //│ ╟── does not correspond to opening parenthesis
41 | //│ ║ l.30: (([{})])
42 | //│ ╙── ^
43 | //│ |(|(|[|{||}|]|)|)|
44 | //│ Parsed: {'(' '(' ['{' {} '}',] ')' ')'}
45 |
46 |
47 | fun f = ()
48 | //│ |#fun| |f| |#=| |(||)|
49 | //│ Parsed: {fun f = undefined}
50 |
51 |
--------------------------------------------------------------------------------
/shared/src/test/diff/parser/Comments.mls:
--------------------------------------------------------------------------------
1 |
2 | 1 // whoops
3 | //│ |1| |/* whoops*/|
4 | //│ Parsed: {1}
5 |
6 | 2 /* whoops */
7 | //│ |2| |/* whoops */|
8 | //│ Parsed: {2}
9 |
10 | 1
11 | // A
12 | 2
13 | //│ |1|↵|/* A*/|↵|2|
14 | //│ Parsed: {1; 2}
15 |
16 | :w
17 | 1
18 | // A
19 | 2
20 | //│ |1|→|/* A*/|←|↵|2|
21 | //│ ╔══[WARNING] Paren-less applications should use the 'of' keyword
22 | //│ ║ l.17: 1
23 | //│ ╙── ^
24 | //│ Parsed: {1(); 2}
25 |
26 |
--------------------------------------------------------------------------------
/shared/src/test/diff/parser/FlatMultiArgLams.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | // Extracted frrom JSON.mls
5 |
6 | parseNegative(state).flatMap of (negative, state) =>
7 | parseIntegral(state).flatMap of (integral, state) =>
8 | parseFraction(state).flatMap of (fraction, state) =>
9 | parseExponent(state).flatMap of (exponent, state) =>
10 | let value = (integral +. fraction) *. exponent
11 | Success of (if negative then (0 -. value) else value), state
12 | //│ |parseNegative|(|state|)|.flatMap| |#of| |(|negative|,| |state|)| |#=>|↵|parseIntegral|(|state|)|.flatMap| |#of| |(|integral|,| |state|)| |#=>|↵|parseFraction|(|state|)|.flatMap| |#of| |(|fraction|,| |state|)| |#=>|↵|parseExponent|(|state|)|.flatMap| |#of| |(|exponent|,| |state|)| |#=>|↵|#let| |value| |#=| |(|integral| |+.| |fraction|)| |*.| |exponent|↵|Success| |#of| |(|#if| |negative| |#then| |(|0| |-.| |value|)| |#else| |value|)|,| |state|
13 | //│ Parsed: {(parseNegative(state,)).flatMap((negative, state,) => {(parseIntegral(state,)).flatMap((integral, state,) => {(parseFraction(state,)).flatMap((fraction, state,) => {(parseExponent(state,)).flatMap((exponent, state,) => {let value = *.('(' +.(integral, fraction,) ')', exponent,); Success('(' if (negative) then '(' -.(0, value,) ')' else value ')', state,)},)},)},)},)}
14 | //│
15 |
16 |
17 |
--------------------------------------------------------------------------------
/shared/src/test/diff/parser/Forall.mls:
--------------------------------------------------------------------------------
1 |
2 | forall 'a: 'a => 'a
3 | //│ |#forall| |'a|#:| |'a| |#=>| |'a|
4 | //│ Parsed: {forall 'a. ('a,) => 'a}
5 |
6 | forall 'a, 'b: ['a, 'b] => ['b, 'a]
7 | //│ |#forall| |'a|,| |'b|#:| |[|'a|,| |'b|]| |#=>| |[|'b|,| |'a|]|
8 | //│ Parsed: {forall 'a, 'b. (['a, 'b,],) => ['b, 'a,]}
9 |
10 | fun f: forall 'a: 'a => 'a
11 | //│ |#fun| |f|#:| |#forall| |'a|#:| |'a| |#=>| |'a|
12 | //│ Parsed: {fun f: forall 'a. 'a -> 'a}
13 |
14 | fun f: forall 'a, 'b: ['a, 'b] => ['b, 'a]
15 | //│ |#fun| |f|#:| |#forall| |'a|,| |'b|#:| |[|'a|,| |'b|]| |#=>| |[|'b|,| |'a|]|
16 | //│ Parsed: {fun f: forall 'a 'b. (['a, 'b]) -> ['b, 'a]}
17 |
18 |
--------------------------------------------------------------------------------
/shared/src/test/diff/parser/MultilineFun.mls:
--------------------------------------------------------------------------------
1 | :AllowParseErrors
2 |
3 |
4 | fun f(
5 | x
6 | ) = x
7 | //│ |#fun| |f|(|→|x|←|↵|)| |#=| |x|
8 | //│ Parsed: {fun f = (x,) => x}
9 |
10 | fun f(x
11 | ) = x
12 | //│ |#fun| |f|(|x|↵|)| |#=| |x|
13 | //│ Parsed: {fun f = (x,) => x}
14 |
15 | fun f(
16 | x) = x
17 | //│ |#fun| |f|(|→|x|←|)| |#=| |x|
18 | //│ Parsed: {fun f = (x,) => x}
19 |
20 | fun f(
21 | x) = x
22 | //│ |#fun| |f|(|↵|x|)| |#=| |x|
23 | //│ ╔══[PARSE ERROR] Unexpected identifier here
24 | //│ ║ l.21: x) = x
25 | //│ ╙── ^
26 | //│ Parsed: {fun f = () => x}
27 |
28 | fun f(x,
29 | y) = x + y
30 | //│ |#fun| |f|(|x|,|→|y|←|)| |#=| |x| |+| |y|
31 | //│ Parsed: {fun f = (x, {y},) => +(x,)(y,)}
32 |
33 | fun f(
34 | x,
35 | y) = x + y
36 | //│ |#fun| |f|(|→|x|,|↵|y|←|)| |#=| |x| |+| |y|
37 | //│ Parsed: {fun f = (x, y,) => +(x,)(y,)}
38 |
39 | fun f(
40 | x,
41 | y
42 | ) = x + y
43 | //│ |#fun| |f|(|→|x|,|↵|y|←|↵|)| |#=| |x| |+| |y|
44 | //│ Parsed: {fun f = (x, y,) => +(x,)(y,)}
45 |
46 |
--------------------------------------------------------------------------------
/shared/src/test/diff/parser/NegativeLits.mls:
--------------------------------------------------------------------------------
1 | :NewParser
2 | :ParseOnly
3 |
4 | type MinusOne = -1
5 | //│ |#type| |MinusOne| |#=| |-|1|
6 | //│ Parsed: {type alias MinusOne: -1 {}}
7 |
8 | fun f(x: MinusOne) = x
9 | //│ |#fun| |f|(|x|#:| |MinusOne|)| |#=| |x|
10 | //│ Parsed: {fun f = (x: MinusOne,) => x}
11 |
12 | f(-1)
13 | //│ |f|(|-|1|)|
14 | //│ Parsed: {f(-1,)}
15 |
--------------------------------------------------------------------------------
/shared/src/test/diff/parser/SpecParams.mls:
--------------------------------------------------------------------------------
1 | :ParseOnly
2 |
3 |
4 | fun Foo(#x, y) = x + y
5 | //│ |#fun| |Foo|(|##|x|,| |y|)| |#=| |x| |+| |y|
6 | //│ Parsed: {fun Foo = (#x, y,) => +(x,)(y,)}
7 |
8 | fun Foo(x, #y) = x + y
9 | //│ |#fun| |Foo|(|x|,| |##|y|)| |#=| |x| |+| |y|
10 | //│ Parsed: {fun Foo = (x, #y,) => +(x,)(y,)}
11 |
12 | fun Foo(#x, #y, #z) = if z then x + y else z
13 | //│ |#fun| |Foo|(|##|x|,| |##|y|,| |##|z|)| |#=| |#if| |z| |#then| |x| |+| |y| |#else| |z|
14 | //│ Parsed: {fun Foo = (#x, #y, #z,) => if (z) then +(x,)(y,) else z}
15 |
16 |
17 | class Foo(x, #y, z)
18 | //│ |#class| |Foo|(|x|,| |##|y|,| |z|)|
19 | //│ Parsed: {class Foo(x, #y, z,) {}}
20 |
21 |
22 |
--------------------------------------------------------------------------------
/shared/src/test/diff/parser/Where.mls:
--------------------------------------------------------------------------------
1 |
2 | 1 + 1 where 1
3 | //│ |1| |+| |1| |#where| |1|
4 | //│ Parsed: {+(1,)(1,) where {1}}
5 |
6 | a => a + 1 where foo
7 | //│ |a| |#=>| |a| |+| |1| |#where| |foo|
8 | //│ Parsed: {(a,) => +(a,)(1,) where {foo}}
9 |
10 | a + 1 where let a = 1
11 | //│ |a| |+| |1| |#where| |#let| |a| |#=| |1|
12 | //│ Parsed: {+(a,)(1,) where {let a = 1}}
13 |
14 | fun foo: 'a => 'a => 'a where 'a : int
15 | //│ |#fun| |foo|#:| |'a| |#=>| |'a| |#=>| |'a| |#where| |'a| |#:| |int|
16 | //│ Parsed: {fun foo: 'a -> 'a -> ('a
17 | //│ where
18 | //│ 'a <: int)}
19 |
20 | :pe
21 | fun foo: 'a + 'a + 'a where 'a : int
22 | //│ |#fun| |foo|#:| |'a| |+| |'a| |+| |'a| |#where| |'a| |#:| |int|
23 | //│ ╔══[PARSE ERROR] Not a recognized type
24 | //│ ║ l.21: fun foo: 'a + 'a + 'a where 'a : int
25 | //│ ╙── ^^^^^^^
26 | //│ Parsed: {fun foo: anything}
27 |
28 | :pe
29 | fun foo: 'a -> 'a -> 'a where 'a : int
30 | //│ |#fun| |foo|#:| |'a| |->| |'a| |->| |'a| |#where| |'a| |#:| |int|
31 | //│ ╔══[PARSE ERROR] Not a recognized type
32 | //│ ║ l.29: fun foo: 'a -> 'a -> 'a where 'a : int
33 | //│ ╙── ^^^^^^^^^^^^^^
34 | //│ Parsed: {fun foo: anything}
35 |
36 |
--------------------------------------------------------------------------------
/shared/src/test/diff/parser/Whitespace.mls:
--------------------------------------------------------------------------------
1 | :AllowParseErrors
2 |
3 |
4 | //│ | |
5 | //│ Parsed: {}
6 |
7 |
8 | //│ | |
9 | //│ Parsed: {}
10 |
11 |
12 |
13 | //│ | |
14 | //│ Parsed: {}
15 |
16 |
17 | false(1 , 2 , 3)
18 | //│ |false|(|1| |,| |2| |,| |3|)|
19 | //│ Parsed: {false(1, 2, 3,)}
20 |
21 | false (1 ,2 ,3)
22 | //│ |false| |(|1| |,|2| |,|3|)|
23 | //│ Parsed: {false(1, 2, 3,)}
24 |
25 | false( 1 , 2 , 3 )
26 | //│ |false|(| |1| |,| |2| |,| |3| |)|
27 | //│ Parsed: {false(1, 2, 3,)}
28 |
29 |
--------------------------------------------------------------------------------
/shared/src/test/diff/parser/boolops.mls:
--------------------------------------------------------------------------------
1 |
2 | true and false
3 | //│ |true| |and| |false|
4 | //│ Parsed: {and(true,)(false,)}
5 |
6 | a and b or c
7 | //│ |a| |and| |b| |or| |c|
8 | //│ Parsed: {or(and(a,)(b,),)(c,)}
9 |
10 | a or b and c
11 | //│ |a| |or| |b| |and| |c|
12 | //│ Parsed: {or(a,)(and(b,)(c,),)}
13 |
14 | a + 1 or b + 2 and c + 3
15 | //│ |a| |+| |1| |or| |b| |+| |2| |and| |c| |+| |3|
16 | //│ Parsed: {or(+(a,)(1,),)(and(+(b,)(2,),)(+(c,)(3,),),)}
17 |
18 |
19 | any of a, b, c
20 | //│ |any| |#of| |a|,| |b|,| |c|
21 | //│ Parsed: {any(a, b, c,)}
22 |
23 | any of
24 | a
25 | b
26 | c
27 | //│ |any| |#of|→|a|↵|b|↵|c|←|
28 | //│ Parsed: {any({a; b; c},)}
29 |
30 | all of
31 | x
32 | any of
33 | a
34 | b
35 | c
36 | y
37 | //│ |all| |#of|→|x|↵|any| |#of|→|a|↵|b|↵|c|←|↵|y|←|
38 | //│ Parsed: {all({x; any({a; b; c},); y},)}
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/shared/src/test/diff/pretyper/Repro.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 | :ShowPreTyperErrors
3 |
--------------------------------------------------------------------------------
/shared/src/test/diff/pretyper/ucs/NamePattern.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 | fun id(x) = x
4 | //│ fun id: forall 'a. 'a -> 'a
5 |
6 | if id(0) is t then t
7 | //│ 0
8 | //│ res
9 | //│ = 0
10 |
--------------------------------------------------------------------------------
/shared/src/test/diff/pretyper/ucs/RecordPattern.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 | :e
4 | :w
5 | fun take_1(p) =
6 | if p is
7 | { x, y } then x + y
8 | else 0
9 | //│ ╔══[ERROR] unknown pattern '{' {x: x, y: y} '}'
10 | //│ ║ l.7: { x, y } then x + y
11 | //│ ╙── ^^^^^^^^
12 | //│ ╔══[WARNING] this case is unreachable
13 | //│ ║ l.8: else 0
14 | //│ ║ ^
15 | //│ ╟── because it is subsumed by the branch
16 | //│ ║ l.7: { x, y } then x + y
17 | //│ ╙── ^^^^^
18 | //│ ╔══[ERROR] identifier not found: x
19 | //│ ║ l.7: { x, y } then x + y
20 | //│ ╙── ^
21 | //│ ╔══[ERROR] identifier not found: y
22 | //│ ║ l.7: { x, y } then x + y
23 | //│ ╙── ^
24 | //│ fun take_1: anything -> Int
25 | //│ Code generation encountered an error:
26 | //│ unresolved symbol x
27 |
--------------------------------------------------------------------------------
/shared/src/test/diff/pretyper/ucs/Symbol.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 | type List[A] = Cons[A] | Nil
4 | class Cons[A](head: A, tail: List[A])
5 | module Nil
6 | //│ type List[A] = Cons[A] | Nil
7 | //│ class Cons[A](head: A, tail: List[A])
8 | //│ module Nil
9 |
10 | fun (::) cons(head, tail) = Cons(head, tail)
11 | //│ fun (::) cons: forall 'A. ('A, List['A]) -> Cons['A]
12 |
13 | fun map(f, xs) = if xs is
14 | Cons(head, tail) then f(head) :: map(f, tail)
15 | Nil then Nil
16 | //│ fun map: forall 'A 'A0. ('A -> 'A0, Cons['A] | Nil) -> (Cons['A0] | Nil)
17 |
18 | // fun main$$5 = () =>
19 | // let obj =
20 | // let obj = '(' (new List$1)(1, (new List$1)(2, (new Nil$2)(),),) ')' in
21 | // if obj is ‹(List$1) then map$List$1(obj, {Lambda1$2$3()},); else error›
22 | // in
23 | // if obj is ‹(List$1) then map$List$1(obj, {Lambda1$3$4()},); else error›
24 | // Got: Internal Error: Symbol already set for obj
25 | fun main(f) =
26 | let obj = (let obj = Cons(1, Cons(2, Nil)) in (if obj is Cons(head, tail) then f(head) :: tail else Nil)) in
27 | if obj is Cons(head, tail) then f(head) :: tail else Nil
28 | //│ fun main: forall 'A 'A0. ((1 | 2 | 'A) -> 'A) -> (Cons['A0] | Nil)
29 | //│ where
30 | //│ 'A <: 'A0
31 | //│ 'A0 :> 1 | 2
32 | //│ <: 'A
33 |
--------------------------------------------------------------------------------
/shared/src/test/diff/pretyper/ucs/Unapply.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 | class Point(x: Int, y: Int, z: Int)
4 | //│ class Point(x: Int, y: Int, z: Int)
5 |
6 | fun f_0(p) = if p is Point(x, _, z) then x + z
7 | //│ fun f_0: Point -> Int
8 |
9 | f_0(Point(1, 2, 3))
10 | //│ Int
11 | //│ res
12 | //│ = 4
13 |
--------------------------------------------------------------------------------
/shared/src/test/diff/pretyper/ucs/Unconditional.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 | class Point(x: Int, y: Int)
4 | class Rectangle(x: Int, y: Int, width: Int, height: Int)
5 | //│ class Point(x: Int, y: Int)
6 | //│ class Rectangle(x: Int, y: Int, width: Int, height: Int)
7 |
8 | fun sum(p) = if p is Point(x, y) then x + y
9 | //│ fun sum: Point -> Int
10 |
11 | sum(Point(1, 2))
12 | //│ Int
13 | //│ res
14 | //│ = 3
15 |
16 | fun abs(x) = if x < 0 then -x else x
17 | //│ fun abs: Int -> Int
18 |
19 | fun dist(p, q) = if p is Point(x1, y1) and q is Point(x2, y2) then
20 | abs(x1 - x2) + abs(y1 - y2)
21 | //│ fun dist: (Point, Point) -> Int
22 |
23 | dist(Point(1, 2), Point(3, 4))
24 | //│ Int
25 | //│ res
26 | //│ = 4
27 |
--------------------------------------------------------------------------------
/shared/src/test/diff/pretyper/ucs/coverage/Tautology.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 | class Some[T](value: T)
4 | module None
5 | type Option[T] = Some[T] | None
6 | class Pair[A, B](x: A, y: B)
7 | //│ class Some[T](value: T)
8 | //│ module None
9 | //│ type Option[T] = None | Some[T]
10 | //│ class Pair[A, B](x: A, y: B)
11 |
12 | fun useless_negate_1(x) =
13 | if
14 | x is Some(y) and x is Some(z) then y + z
15 | //│ fun useless_negate_1: Some[Int] -> Int
16 |
17 | useless_negate_1(Some(1))
18 | //│ Int
19 | //│ res
20 | //│ = 2
21 |
--------------------------------------------------------------------------------
/shared/src/test/diff/pretyper/ucs/examples/List.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 | // TODO
4 | abstract class List[out A]: (Cons[A] | Nil) {
5 | fun isEmpty: Bool
6 | fun map[B]: (A -> B) -> List[B]
7 | }
8 | class Cons[out A](head: A, tail: List[A]) extends List[A] {
9 | fun isEmpty: Bool = false
10 | fun map(f) = Cons(f(head), tail.map(f))
11 | }
12 | module Nil extends List {
13 | fun isEmpty: Bool = true
14 | fun map(f) = Nil
15 | }
16 | //│ ╔══[ERROR] Indirectly-recursive member should have a type signature
17 | //│ ║ l.10: fun map(f) = Cons(f(head), tail.map(f))
18 | //│ ╙── ^^^^
19 | //│ abstract class List[A]: Cons[A] | Nil {
20 | //│ fun isEmpty: Bool
21 | //│ fun map: forall 'B. (A -> 'B) -> List['B]
22 | //│ }
23 | //│ class Cons[A](head: A, tail: List[A]) extends List {
24 | //│ fun isEmpty: Bool
25 | //│ fun map: forall 'A. (A -> 'A) -> Cons['A]
26 | //│ }
27 | //│ module Nil extends List {
28 | //│ fun isEmpty: Bool
29 | //│ fun map: anything -> Nil
30 | //│ }
31 |
--------------------------------------------------------------------------------
/shared/src/test/diff/pretyper/ucs/examples/SimpleList.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 | abstract class List[T]: (Cons[T] | Nil)
4 | class Cons[T](val head: T, val tail: List[T]) extends List[T]
5 | module Nil extends List
6 | //│ abstract class List[T]: Cons[T] | Nil
7 | //│ class Cons[T](head: T, tail: List[T]) extends List
8 | //│ module Nil extends List
9 |
10 | fun (::) cons(head, tail) = Cons(head, tail)
11 | //│ fun (::) cons: forall 'T. ('T, List['T]) -> Cons['T]
12 |
13 | 1 :: 2 :: 3 :: 4 :: 5 :: 6 :: 7 :: 8 :: Nil
14 | //│ Cons['T]
15 | //│ where
16 | //│ 'T :> 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8
17 | //│ res
18 | //│ = Cons {}
19 |
--------------------------------------------------------------------------------
/shared/src/test/diff/pretyper/ucs/examples/SimpleTree.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 | // abstract class Tree[out A]: (Empty | Node[A])
4 | // class Node[out A](value: A, left: Tree[A], right: Tree[A]) extends Tree[A]
5 | // module Empty extends Tree
6 | // //│ abstract class Tree[A]: Empty | Node[A]
7 | // //│ class Node[A](value: A, left: Tree[A], right: Tree[A]) extends Tree
8 | // //│ module Empty extends Tree
9 |
10 | // fun insert(t, v) = if t is
11 | // Node(v', l, r) and
12 | // v < v' then Node(v', insert(l, v), r)
13 | // v > v' then Node(v', l, insert(r, v))
14 | // _ then t
15 | // Empty then Node(v, Empty, Empty)
16 | // //│ fun insert: forall 'A. (Empty | Node[Num & 'A], Num & 'A) -> (Node[nothing] | Node['A])
17 |
18 | abstract class List[out T]: (Cons[T] | Nil)
19 | class Cons[out T](val head: T, val tail: List[T]) extends List[T]
20 | module Nil extends List
21 | //│ abstract class List[T]: Cons[T] | Nil
22 | //│ class Cons[T](head: T, tail: List[T]) extends List
23 | //│ module Nil extends List
24 |
25 | fun (::) cons(head, tail) = Cons(head, tail)
26 | //│ fun (::) cons: forall 'T. ('T, List['T]) -> Cons['T]
27 |
28 | 1 :: 2 :: 3 :: 4 :: Nil
29 | //│ Cons[1 | 2 | 3 | 4]
30 | //│ res
31 | //│ = Cons {}
32 |
--------------------------------------------------------------------------------
/shared/src/test/diff/qq/BadConst.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 | :NoJS
3 |
4 |
5 | :e
6 | // :ge
7 | code"x => y => 100 + ${Const(x + y)}"
8 | //│ ╔══[ERROR] Type mismatch in operator application:
9 | //│ ║ l.7: code"x => y => 100 + ${Const(x + y)}"
10 | //│ ║ ^^^^^
11 | //│ ╟── reference of type `Var[?a, ?x]` is not an instance of type `Int`
12 | //│ ║ l.7: code"x => y => 100 + ${Const(x + y)}"
13 | //│ ╙── ^
14 | //│ Code[anything -> anything -> Int, nothing]
15 |
16 | :e
17 | code"x => y => 100 + code"${Const(x + y)}""
18 | //│ ╔══[ERROR] Nested quotation is not allowed.
19 | //│ ║ l.17: code"x => y => 100 + code"${Const(x + y)}""
20 | //│ ╙── ^^^^^^^^^^^^^^^^^^^^^
21 | //│ Code[anything -> anything -> Int, nothing]
22 |
23 | :e
24 | let res = code"x => code"${x}""
25 | //│ ╔══[ERROR] Nested quotation is not allowed.
26 | //│ ║ l.24: let res = code"x => code"${x}""
27 | //│ ╙── ^^^^^^^^^^
28 | //│ let res: Code[anything -> error, nothing]
29 |
--------------------------------------------------------------------------------
/shared/src/test/diff/qq/Multiline.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 | :NoJS
3 |
4 |
5 | code"let arr = [
6 | 1
7 | ] in arr"
8 | //│ Code[[1], nothing]
9 |
10 | let res = code"let foo = (x, y) => x * y
11 | foo(
12 | 2,
13 | 3
14 | )"
15 | run(res)
16 | //│ let res: Code[Int, nothing]
17 | //│ Int
18 |
19 |
20 | let res = code"let a = 0
21 | let b = 1
22 | if a == 0
23 | then true
24 | else false
25 | "
26 | run(res)
27 | //│ let res: Code[Bool, nothing]
28 | //│ Bool
29 |
30 | let res = code"if 1 == 0
31 | then false
32 | else true
33 | "
34 | run(res)
35 | //│ let res: Code[Bool, nothing]
36 | //│ Bool
37 |
38 | let res = code"if 1 == 0
39 | then false
40 | else true
41 | "
42 | run(res)
43 | //│ let res: Code[Bool, nothing]
44 | //│ Bool
45 |
46 | let res = code"{
47 | x: 1,
48 | y: 2,
49 | z: 3,
50 | }
51 | "
52 | run(res)
53 | //│ let res: Code[{x: 1, y: 2, z: 3}, nothing]
54 | //│ {x: 1, y: 2, z: 3}
55 |
56 |
57 | let res = code"let x = {a: 100}
58 | x
59 | .a
60 | "
61 | run(res)
62 | //│ let res: Code[100, nothing]
63 | //│ 100
64 |
--------------------------------------------------------------------------------
/shared/src/test/diff/qq/WillfulExtrusion.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 | :NoJS
3 |
4 |
5 | fun foo(dbg) =
6 | code"x => ${let c = code"x + 1" in dbg(c), c}"
7 | //│ fun foo: (Code[Int, ??x] -> anything) -> Code[Int -> Int, nothing]
8 |
9 | foo(log)
10 | //│ Code[Int -> Int, nothing]
11 |
12 |
13 | fun (>>) compose(f, g) = x => g(f(x))
14 | fun show: Code[anything, anything] -> Str
15 | //│ fun (>>) compose: forall 'a 'b 'c. ('a -> 'b, 'b -> 'c) -> 'a -> 'c
16 | //│ fun show: Code[anything, anything] -> Str
17 |
18 | foo(show >> log)
19 | //│ Code[Int -> Int, nothing]
20 |
21 |
22 |
--------------------------------------------------------------------------------
/shared/src/test/diff/tricky/IrregularSubtypes.mls:
--------------------------------------------------------------------------------
1 | :IrregularTypes
2 |
3 |
4 | type Foo[A] = A -> Foo[Foo[A]]
5 | //│ Defined type alias Foo[=A]
6 |
7 | type Bar[A] = A -> Bar[Bar[A]]
8 | //│ Defined type alias Bar[=A]
9 |
10 |
11 | :e
12 | error: Foo[int]: Bar[int]
13 | //│ ╔══[ERROR] Subtyping constraint of the form `Foo[int] <: Bar[int]` exceeded recursion depth limit (250)
14 | //│ ║ l.12: error: Foo[int]: Bar[int]
15 | //│ ║ ^^^^^
16 | //│ ╙── Note: use flag `:ex` to see internal error info.
17 | //│ res: Bar[int]
18 | //│ Runtime error:
19 | //│ Error: an error was thrown
20 |
21 |
22 | // * Interestingly, this is caught by the cycle checker when rectypes are disabled:
23 | :NoRecursiveTypes
24 |
25 | :e
26 | error: Foo[int]: Bar[int]
27 | //│ ╔══[ERROR] Cyclic-looking constraint while typing type ascription; a type annotation may be required
28 | //│ ║ l.26: error: Foo[int]: Bar[int]
29 | //│ ║ ^^^^^
30 | //│ ╙── Note: use flag `:ex` to see internal error info.
31 | //│ res: Bar[int]
32 | //│ Runtime error:
33 | //│ Error: an error was thrown
34 |
35 |
36 |
--------------------------------------------------------------------------------
/shared/src/test/diff/tricky/IrregularSubtypes2.mls:
--------------------------------------------------------------------------------
1 | :NoRecursiveTypes
2 | :IrregularTypes
3 |
4 |
5 | type Lol = forall 'a. int -> ('a, Lol)
6 | //│ Defined type alias Lol
7 |
8 | def lol: Lol
9 | //│ lol: Lol
10 | //│ =
11 |
12 | :w
13 | type Oops[A] = int -> (anything, Oops[Oops[A]])
14 | //│ Defined type alias Oops[±A]
15 | //│ ╔══[WARNING] Type definition Oops has bivariant type parameters:
16 | //│ ║ l.13: type Oops[A] = int -> (anything, Oops[Oops[A]])
17 | //│ ║ ^^^^
18 | //│ ╟── A is irrelevant and may be removed
19 | //│ ║ l.13: type Oops[A] = int -> (anything, Oops[Oops[A]])
20 | //│ ╙── ^
21 |
22 | // * The cycle is due to irregular types, which are not yet shadowed
23 | :e
24 | lol: Oops[int]
25 | //│ ╔══[ERROR] Subtyping constraint of the form `Lol <: Oops[?]` exceeded recursion depth limit (250)
26 | //│ ║ l.24: lol: Oops[int]
27 | //│ ║ ^^^
28 | //│ ╙── Note: use flag `:ex` to see internal error info.
29 | //│ res: Oops[?]
30 | //│ =
31 | //│ lol is not implemented
32 |
33 |
34 |
--------------------------------------------------------------------------------
/shared/src/test/diff/ucs/ErrorMessage.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 | class Point(x: Int, y: Int)
4 | //│ class Point(x: Int, y: Int)
5 |
6 | :e
7 | fun f(p) =
8 | if p is
9 | Point(x, y, z) then x + y + z
10 | //│ ╔══[ERROR] Type mismatch in field selection:
11 | //│ ╟── tuple literal of type `{0: ?#x, 1: ?#y}` does not have field '2'
12 | //│ ║ l.3: class Point(x: Int, y: Int)
13 | //│ ║ ^^^^^^^^^
14 | //│ ╟── but it flows into operator application with expected type `{2: ?a}`
15 | //│ ║ l.8: if p is
16 | //│ ║ ^^^^
17 | //│ ║ l.9: Point(x, y, z) then x + y + z
18 | //│ ╙── ^^^^^^^^^
19 | //│ fun f: Point -> Int
20 |
21 | :e
22 | :ge
23 | fun g(xs) =
24 | if xs is
25 | head :: _ then head
26 | //│ ╔══[ERROR] type identifier `::` not found
27 | //│ ║ l.25: head :: _ then head
28 | //│ ╙── ^^
29 | //│ ╔══[ERROR] type identifier not found: ::
30 | //│ ║ l.25: head :: _ then head
31 | //│ ╙── ^^
32 | //│ fun g: nothing -> error
33 | //│ Code generation encountered an error:
34 | //│ unresolved symbol ::
35 |
--------------------------------------------------------------------------------
/shared/src/test/diff/ucs/Hygiene.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 | class Some[out T](value: T)
4 | class Left[out T](value: T)
5 | class Right[out T](value: T)
6 | //│ class Some[T](value: T)
7 | //│ class Left[T](value: T)
8 | //│ class Right[T](value: T)
9 |
10 | :ducs:postprocess.result
11 | fun foo(x) = if x is
12 | Some(Left(y)) then x
13 | Some(x) then x
14 | //│ Post-processed UCS term:
15 | //│ case x*‡ of
16 | //│ Some*◊ ->
17 | //│ let ucs$args_x$Some*† = (Some).unapply(x,)
18 | //│ let x$Some_0*‡ = (ucs$args_x$Some).0
19 | //│ case x$Some_0*‡ of
20 | //│ Left*◊ ->
21 | //│ let ucs$args_x$Some_0$Left*† = (Left).unapply(x$Some_0,)
22 | //│ let y*‡ = (ucs$args_x$Some_0$Left).0
23 | //│ x
24 | //│ _ ->
25 | //│ let x*‡ = (ucs$args_x$Some).0
26 | //│ x
27 | //│ fun foo: forall 'T. Some[(Left[anything] | Object & ~#Left) & 'T] -> (Some['T] | 'T)
28 |
29 | foo(Some(Left(1)))
30 | //│ Left[1] | Some[Left[1]]
31 | //│ res
32 | //│ = Some {}
33 |
34 | foo(Some(2))
35 | //│ 2 | Some[2]
36 | //│ res
37 | //│ = 2
38 |
--------------------------------------------------------------------------------
/shared/src/test/diff/ucs/LeadingAnd.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 |
5 | class Some[T](value: T)
6 | //│ class Some[T](value: T)
7 |
8 |
9 |
10 | fun f(a, b) = if a is
11 | Some(av)
12 | and b is Some(bv) then av + bv
13 | //│ fun f: (Some[Int], Some[Int]) -> Int
14 |
15 | fun f(a, b) = if a is Some(av)
16 | and b is Some(bv)
17 | then av + bv
18 | //│ fun f: (Some[Int], Some[Int]) -> Int
19 |
20 | fun f(a, b) = if a is
21 | Some(av)
22 | and b is Some(bv)
23 | then av + bv
24 | //│ fun f: (Some[Int], Some[Int]) -> Int
25 |
26 |
27 |
28 | // FIXME (parser)
29 | fun f(a, b) = if a is
30 | Some(av)
31 | and b is Some(bv) then av + bv
32 |
33 | //│ fun f: (Some[Int], Some[Int]) -> Int
34 |
35 |
--------------------------------------------------------------------------------
/shared/src/test/diff/ucs/MultiwayIf.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | fun f(x) =
5 | if
6 | x > 0 then 0
7 | x == 0 then 1
8 | _ then 2
9 | //│ fun f: Num -> (0 | 1 | 2)
10 |
11 |
12 | fun f(x) =
13 | if
14 | x > 0 and
15 | x % 2 === 0 then true
16 | _ then false
17 | x == 0 then true
18 | _ then false
19 | //│ fun f: Int -> Bool
20 |
21 | f(0)
22 | f(2)
23 | f(3)
24 | f(0 - 1)
25 | f(0 - 2)
26 | //│ Bool
27 | //│ res
28 | //│ = true
29 | //│ res
30 | //│ = true
31 | //│ res
32 | //│ = false
33 | //│ res
34 | //│ = false
35 | //│ res
36 | //│ = false
37 |
38 | fun f(x) =
39 | if
40 | x > 0 and
41 | x % 2 === 0 then true
42 | else false
43 | x == 0 then true
44 | else false
45 | //│ fun f: Int -> Bool
46 |
47 | f(0)
48 | f(2)
49 | f(1)
50 | f(0 - 1)
51 | //│ Bool
52 | //│ res
53 | //│ = true
54 | //│ res
55 | //│ = true
56 | //│ res
57 | //│ = false
58 | //│ res
59 | //│ = false
60 |
--------------------------------------------------------------------------------
/shared/src/test/diff/ucs/NestedOpSplits.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | // * Note that this always to the left
5 | :e
6 | fun f(x) =
7 | if x ==
8 | 1 +
9 | 2 then 0
10 | _ then 1
11 | //│ ╔══[ERROR] Type mismatch in application:
12 | //│ ║ l.8: 1 +
13 | //│ ║ ^
14 | //│ ║ l.9: 2 then 0
15 | //│ ║ ^^^^^^^
16 | //│ ╟── operator application of type `Bool` is not an instance of type `Int`
17 | //│ ║ l.7: if x ==
18 | //│ ║ ^^^^
19 | //│ ║ l.8: 1 +
20 | //│ ╙── ^^^^^^
21 | //│ ╔══[ERROR] Type mismatch in type ascription:
22 | //│ ║ l.8: 1 +
23 | //│ ║ ^
24 | //│ ║ l.9: 2 then 0
25 | //│ ║ ^^^^^^^
26 | //│ ╙── application of type `Int` is not an instance of type `Bool`
27 | //│ fun f: Num -> (0 | 1)
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/shared/src/test/diff/ucs/Or.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | class Some[T](value: T)
5 | //│ class Some[T](value: T)
6 |
7 |
8 | // TODO support `or` in UCS
9 | fun f(a, b) = if a is
10 | Some(v)
11 | and b is Some(v') then v + v'
12 | or b is Some(v) then v
13 | else 0
14 | //│ ╔══[ERROR] cannot transform due to an illegal split operator or
15 | //│ ║ l.12: or b is Some(v) then v
16 | //│ ║ ^^
17 | //│ ╟── the following branch will be discarded
18 | //│ ║ l.12: or b is Some(v) then v
19 | //│ ╙── ^^^^^^^^^^^^^^^^^^^^
20 | //│ fun f: (Object & ~#Some | Some[Int], Object & ~#Some | Some[Int]) -> Int
21 |
22 |
23 |
--------------------------------------------------------------------------------
/shared/src/test/diff/ucs/ParseFailures.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 | :NoJS
3 |
4 | type Tree[A] = Node[A] | Empty
5 | module Empty
6 | class Node[A](value: Int, left: Tree[A], right: Tree[A])
7 | //│ type Tree[A] = Empty | Node[A]
8 | //│ module Empty
9 | //│ class Node[A](value: Int, left: Tree[A], right: Tree[A])
10 |
11 | fun contains(node, wanted) =
12 | if node is
13 | Node(value, left, right) and wanted
14 | <= value then contains(left, wanted)
15 | >= value then contains(right, wanted)
16 | else true
17 | Empty then false
18 | //│ fun contains: forall 'A. (Empty | Node['A], Num) -> Bool
19 |
20 | fun contains'(node, wanted) =
21 | if node is
22 | Node(value, left, right) and wanted
23 | <= value then contains'(left, wanted)
24 | >= value then contains'(right, wanted)
25 | _ then true
26 | Empty then false
27 | //│ fun contains': forall 'A. (Empty | Node['A], Num) -> Bool
28 |
29 | :pe
30 | class Z()
31 | class O()
32 | fun foo(x, y) = if x is
33 | Z() and y is O() then 0 else 1
34 | //│ ╔══[PARSE ERROR] Unexpected 'else' keyword here
35 | //│ ║ l.33: Z() and y is O() then 0 else 1
36 | //│ ╙── ^^^^
37 | //│ class Z()
38 | //│ class O()
39 | //│ fun foo: (Z, O) -> 0
40 |
--------------------------------------------------------------------------------
/shared/src/test/diff/ucs/ParserFailures.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 | :NoJS
3 |
4 | // FIXME: Interleaved let bindings are not implemented in `IfOpsApp`.
5 | if x
6 | == 0 then "bad"
7 | let y = f(z)
8 | == y * y then 0
9 | //│ ╔══[PARSE ERROR] expect an operator
10 | //│ ║ l.7: let y = f(z)
11 | //│ ╙── ^^^
12 | //│ ╔══[PARSE ERROR] Unexpected 'let' keyword here
13 | //│ ║ l.7: let y = f(z)
14 | //│ ╙── ^^^
15 | //│ ╔══[ERROR] missing else branch
16 | //│ ║ l.6: == 0 then "bad"
17 | //│ ╙── ^^^^^
18 | //│ ╔══[ERROR] identifier not found: x
19 | //│ ║ l.5: if x
20 | //│ ╙── ^
21 | //│ ╔══[ERROR] Type mismatch in `case` expression:
22 | //│ ║ l.6: == 0 then "bad"
23 | //│ ║ ^^^^^
24 | //│ ╙── expression of type `Bool` is not an instance of type `true`
25 | //│ "bad"
26 |
27 | // FIXME: Interleaved let bindings are not implemented in `IfOpsApp`.
28 | fun tt(x) =
29 | if x
30 | is A() then "A"
31 | let y = 0
32 | is B() then "B"
33 | //│ ╔══[PARSE ERROR] expect an operator
34 | //│ ║ l.31: let y = 0
35 | //│ ╙── ^^^
36 | //│ ╔══[PARSE ERROR] Unexpected 'let' keyword here
37 | //│ ║ l.31: let y = 0
38 | //│ ╙── ^^^
39 | //│ ╔══[ERROR] type identifier `A` not found
40 | //│ ║ l.30: is A() then "A"
41 | //│ ╙── ^
42 | //│ ╔══[ERROR] type identifier not found: A
43 | //│ ║ l.30: is A() then "A"
44 | //│ ╙── ^
45 | //│ fun tt: nothing -> error
46 |
47 |
--------------------------------------------------------------------------------
/shared/src/test/diff/ucs/SplitScrutinee.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 | fun f(x) =
4 | if x +
5 | 1 is
6 | 2 then 1
7 | 3 then 2
8 | _ then "I don't know."
9 | //│ fun f: Int -> ("I don't know." | 1 | 2)
10 |
11 | [f(0), f(1), f(2), f(3)]
12 | //│ ["I don't know." | 1 | 2, "I don't know." | 1 | 2, "I don't know." | 1 | 2, "I don't know." | 1 | 2]
13 | //│ res
14 | //│ = [ "I don't know.", 1, 2, "I don't know." ]
15 |
--------------------------------------------------------------------------------
/shared/src/test/diff/ucs/ThenIndent.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 |
4 | // FIXME
5 | x => if x ==
6 | 0
7 | then "a"
8 | _ then "b"
9 | //│ ╔══[PARSE ERROR] Unexpected indented block here
10 | //│ ║ l.7: then "a"
11 | //│ ║ ^^^^^^^^^^^^
12 | //│ ║ l.8: _ then "b"
13 | //│ ╙── ^^
14 | //│ ╔══[PARSE ERROR] Expected 'then'/'else' clause after 'if'; found operator application instead
15 | //│ ║ l.5: x => if x ==
16 | //│ ║ ^^^^
17 | //│ ║ l.6: 0
18 | //│ ║ ^^^
19 | //│ ╟── Note: 'if' expression starts here:
20 | //│ ║ l.5: x => if x ==
21 | //│ ╙── ^^
22 | //│ ╔══[ERROR] missing else branch
23 | //│ ║ l.6: 0
24 | //│ ╙── ^
25 | //│ ╔══[ERROR] Type mismatch in `case` expression:
26 | //│ ║ l.6: 0
27 | //│ ║ ^
28 | //│ ╙── expression of type `Bool` is not an instance of type `true`
29 | //│ Num -> ()
30 | //│ res
31 | //│ = [Function: res]
32 |
33 |
34 |
--------------------------------------------------------------------------------
/shared/src/test/diff/ucs/Tree.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 | type Option[out A] = Some[A] | None
4 | class Some[out A](value: A)
5 | module None
6 | //│ type Option[A] = None | Some[A]
7 | //│ class Some[A](value: A)
8 | //│ module None
9 |
10 | type Tree[out A] = Node[A] | Empty
11 | module Empty
12 | class Node[out A](value: A, left: Tree[A], right: Tree[A])
13 | //│ type Tree[A] = Empty | Node[A]
14 | //│ module Empty
15 | //│ class Node[A](value: A, left: Tree[A], right: Tree[A])
16 |
17 | fun find(t, v) = if t is
18 | Node(v', l, r) and
19 | v < v' then find(l, v)
20 | v > v' then find(r, v)
21 | _ then Some(v)
22 | Empty then None
23 | //│ fun find: forall 'A. (Empty | Node[Num], Num & 'A) -> (None | Some['A])
24 |
25 | fun insert(t, v) = if t is
26 | Node(v', l, r) and
27 | v < v' then Node(v', insert(l, v), r)
28 | v > v' then Node(v', l, insert(r, v))
29 | _ then t
30 | Empty then Node(v, Empty, Empty)
31 | //│ fun insert: forall 'A. (Empty | Node[Num & 'A], Num & 'A) -> (Node[nothing] | Node['A])
32 |
33 | find(Empty, 0)
34 | find(Node(0, Empty, Empty), 0)
35 | find(Node(1, Empty, Empty), 0)
36 | //│ None | Some[0]
37 | //│ res
38 | //│ = None { class: [class None] }
39 | //│ res
40 | //│ = Some {}
41 | //│ res
42 | //│ = None { class: [class None] }
43 |
--------------------------------------------------------------------------------
/shared/src/test/diff/ucs/WeirdSplit.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 |
3 | class A()
4 | class B()
5 | //│ class A()
6 | //│ class B()
7 |
8 | fun f(x) =
9 | if x
10 | is
11 | A then 0
12 | B then 1
13 | //│ fun f: (A | B) -> (0 | 1)
14 |
15 | // Precedence problem: should we restruct terms when push them to the stack?
16 | :e
17 | fun f(x) =
18 | if x ==
19 | 1
20 | + 2 then 0
21 | + _ then 1
22 | //│ ╔══[ERROR] Type mismatch in application:
23 | //│ ║ l.20: + 2 then 0
24 | //│ ║ ^^^
25 | //│ ╟── operator application of type `Bool` is not an instance of type `Int`
26 | //│ ║ l.18: if x ==
27 | //│ ║ ^^^^
28 | //│ ║ l.19: 1
29 | //│ ╙── ^^^^^^
30 | //│ ╔══[ERROR] Type mismatch in type ascription:
31 | //│ ║ l.20: + 2 then 0
32 | //│ ║ ^^^
33 | //│ ╙── application of type `Int` is not an instance of type `Bool`
34 | //│ fun f: Num -> (0 | 1)
35 |
36 | fun f(x, s, t) =
37 | if x
38 | is A()
39 | and t then 0
40 | and s then 0
41 | is _ then 1
42 | //│ fun f: (Object, Bool, Bool) -> (0 | 1)
43 |
--------------------------------------------------------------------------------
/shared/src/test/scala/mlscript/NodeTest.scala:
--------------------------------------------------------------------------------
1 | package mlscript
2 |
3 | class NodeTests extends org.scalatest.funsuite.AnyFunSuite {
4 |
5 | test("node version") {
6 |
7 | val v = os.proc("node", "-v").call().out.lines().head
8 |
9 | println(s"Detected node version: " + v)
10 |
11 | assert(
12 | v.startsWith("v16.14")
13 | || v.startsWith("v16.15")
14 | || v.startsWith("v16.16")
15 | || v.startsWith("v16.17")
16 | || v.startsWith("v17")
17 | || v.startsWith("v18")
18 | || v.startsWith("v19")
19 | || v.startsWith("v20")
20 | || v.startsWith("v21")
21 | || v.startsWith("v22")
22 | )
23 |
24 | }
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/ts/dummy.ts:
--------------------------------------------------------------------------------
1 | // This is just to work around vscode being overly needy (it reports errors in 'tsconfig.json' otherwise).
2 |
--------------------------------------------------------------------------------
/ts2mls/js/src/main/scala/ts2mls/TSProgram.scala:
--------------------------------------------------------------------------------
1 | package ts2mls
2 |
3 | import scala.scalajs.js
4 | import js.DynamicImplicits._
5 | import ts2mls.types._
6 |
7 | class TSProgram(filenames: Seq[String]) {
8 | private val program = TypeScript.createProgram(filenames)
9 |
10 | // check if files exist
11 | filenames.foreach((fn) => if (!program.fileExists(fn)) throw new Exception(s"file ${fn} doesn't exist."))
12 |
13 | val globalNamespace = TSNamespace()
14 |
15 | implicit val checker: TSTypeChecker = TSTypeChecker(program.getTypeChecker())
16 | filenames.foreach(filename => TSSourceFile(program.getSourceFile(filename), globalNamespace))
17 |
18 | def generate(writer: JSWriter): Unit = globalNamespace.generate(writer, "")
19 | }
20 |
21 | object TSProgram {
22 | def apply(filenames: Seq[String]) = new TSProgram(filenames)
23 | }
24 |
--------------------------------------------------------------------------------
/ts2mls/js/src/test/diff/Dec.d.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 | :ParseOnly
3 | fun getName(id: (string) | (number)): string
4 | fun render(callback: (unit => unit) | (undefined)): string
5 | trait Get() {
6 | fun __call(id: string): string
7 | }
8 | class Person(name: string, age: number) {
9 | fun getName(id: number): string
10 | }
11 | module OOO {
12 | }
13 | //│ |#fun| |getName|(|id|#:| |(|string|)| ||| |(|number|)|)|#:| |string|↵|#fun| |render|(|callback|#:| |(|unit| |#=>| |unit|)| ||| |(|#undefined|)|)|#:| |string|↵|#trait| |Get|(||)| |{|→|#fun| |__call|(|id|#:| |string|)|#:| |string|←|↵|}|↵|#class| |Person|(|name|#:| |string|,| |age|#:| |number|)| |{|→|#fun| |getName|(|id|#:| |number|)|#:| |string|←|↵|}|↵|#module| |OOO| |{|↵|}|
14 | //│ Parsed: {fun getName: (id: string | number) -> string; fun render: (callback: unit -> unit | ()) -> string; trait Get() {fun __call: (id: string) -> string}; class Person(name: string, age: number,) {fun getName: (id: number) -> string}; module OOO {}}
15 | //│
16 |
--------------------------------------------------------------------------------
/ts2mls/js/src/test/diff/Enum.d.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 | :ParseOnly
3 | fun pass(c: int): (false) | (true)
4 | fun stop(): int
5 | fun g(x: int): int
6 | //│ |#fun| |pass|(|c|#:| |int|)|#:| |(|false|)| ||| |(|true|)|↵|#fun| |stop|(||)|#:| |int|↵|#fun| |g|(|x|#:| |int|)|#:| |int|
7 | //│ Parsed: {fun pass: (c: int) -> bool; fun stop: () -> int; fun g: (x: int) -> int}
8 | //│
9 |
--------------------------------------------------------------------------------
/ts2mls/js/src/test/diff/HighOrderFunc.d.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 | :ParseOnly
3 | fun h1(inc: (number) => number, num: number): number
4 | fun h2(hint: string): unit => string
5 | fun h3(f: (number) => number, g: (number) => number): (number) => number
6 | //│ |#fun| |h1|(|inc|#:| |(|number|)| |#=>| |number|,| |num|#:| |number|)|#:| |number|↵|#fun| |h2|(|hint|#:| |string|)|#:| |unit| |#=>| |string|↵|#fun| |h3|(|f|#:| |(|number|)| |#=>| |number|,| |g|#:| |(|number|)| |#=>| |number|)|#:| |(|number|)| |#=>| |number|
7 | //│ Parsed: {fun h1: (inc: number -> number, num: number) -> number; fun h2: (hint: string) -> unit -> string; fun h3: (f: number -> number, g: number -> number) -> number -> number}
8 | //│
9 |
--------------------------------------------------------------------------------
/ts2mls/js/src/test/diff/Literal.d.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 | :ParseOnly
3 | let a: {a: "A",b: "B",}
4 | let num: {y: 114,}
5 | fun foo(x: {xx: "X",}): {yy: "Y",}
6 | //│ |#let| |a|#:| |{|a|#:| |"A"|,|b|#:| |"B"|,|}|↵|#let| |num|#:| |{|y|#:| |114|,|}|↵|#fun| |foo|(|x|#:| |{|xx|#:| |"X"|,|}|)|#:| |{|yy|#:| |"Y"|,|}|
7 | //│ Parsed: {let a: {a: "A", b: "B"}; let num: {y: 114}; fun foo: (x: {xx: "X"}) -> {yy: "Y"}}
8 | //│
9 |
--------------------------------------------------------------------------------
/ts2mls/js/src/test/diff/MultiFiles.d.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 | :ParseOnly
3 | fun multi1(x: number): number
4 | fun multi3(): unit
5 | class Foo(): Base {}
6 | trait AnotherBase() {
7 | let y: string
8 | }
9 | module N {
10 | fun f(): unit
11 | fun g(): unit
12 | fun h(): unit
13 | }
14 | fun multi2(x: string): string
15 | fun multi4(): unit
16 | trait Base() {
17 | let a: number
18 | }
19 | class AnotherFoo(): AnotherBase {}
20 | fun multi5(): unit
21 | //│ |#fun| |multi1|(|x|#:| |number|)|#:| |number|↵|#fun| |multi3|(||)|#:| |unit|↵|#class| |Foo|(||)|#:| |Base| |{||}|↵|#trait| |AnotherBase|(||)| |{|→|#let| |y|#:| |string|←|↵|}|↵|#module| |N| |{|→|#fun| |f|(||)|#:| |unit|↵|#fun| |g|(||)|#:| |unit|↵|#fun| |h|(||)|#:| |unit|←|↵|}|↵|#fun| |multi2|(|x|#:| |string|)|#:| |string|↵|#fun| |multi4|(||)|#:| |unit|↵|#trait| |Base|(||)| |{|→|#let| |a|#:| |number|←|↵|}|↵|#class| |AnotherFoo|(||)|#:| |AnotherBase| |{||}|↵|#fun| |multi5|(||)|#:| |unit|
22 | //│ Parsed: {fun multi1: (x: number) -> number; fun multi3: () -> unit; class Foo(): Base {}; trait AnotherBase() {let y: string}; module N {fun f: () -> unit; fun g: () -> unit; fun h: () -> unit}; fun multi2: (x: string) -> string; fun multi4: () -> unit; trait Base() {let a: number}; class AnotherFoo(): AnotherBase {}; fun multi5: () -> unit}
23 | //│
24 |
--------------------------------------------------------------------------------
/ts2mls/js/src/test/diff/Variables.d.mls:
--------------------------------------------------------------------------------
1 | :NewDefs
2 | :ParseOnly
3 | let URI: string
4 | let URI2: string
5 | let foo: number
6 | let bar: false
7 | class FooBar() {}
8 | let fb: FooBar
9 | module ABC {
10 | class DEF() {}
11 | }
12 | let d: ABC.DEF
13 | module DD {
14 | let foo: number
15 | let bar: number
16 | }
17 | //│ |#let| |URI|#:| |string|↵|#let| |URI2|#:| |string|↵|#let| |foo|#:| |number|↵|#let| |bar|#:| |false|↵|#class| |FooBar|(||)| |{||}|↵|#let| |fb|#:| |FooBar|↵|#module| |ABC| |{|→|#class| |DEF|(||)| |{||}|←|↵|}|↵|#let| |d|#:| |ABC|.DEF|↵|#module| |DD| |{|→|#let| |foo|#:| |number|↵|#let| |bar|#:| |number|←|↵|}|
18 | //│ Parsed: {let URI: string; let URI2: string; let foo: number; let bar: false; class FooBar() {}; let fb: FooBar; module ABC {class DEF() {}}; let d: ABC.DEF; module DD {let foo: number; let bar: number}}
19 | //│
20 |
--------------------------------------------------------------------------------
/ts2mls/js/src/test/typescript/Array.ts:
--------------------------------------------------------------------------------
1 | function first(x: string[]) {
2 | return x[0];
3 | }
4 |
5 | function getZero3() : number[] {
6 | return [0, 0, 0];
7 | }
8 |
9 | function first2(fs: ((x: number) => number)[]): ((x: number) => number) {
10 | return fs[0];
11 | }
12 |
13 | enum E {
14 | E, EE, EEE
15 | }
16 |
17 | function doEs(e: E[]): E[] {
18 | return e;
19 | }
20 |
21 | class C {}
22 | interface I {i: number}
23 |
24 | function doCs(c: C[]): C[] {
25 | return c;
26 | }
27 |
28 | function doIs(i: I[]): I[] {
29 | return i;
30 | }
31 |
32 | function inter(x: (U & T)[]): (U & T)[] {
33 | return x;
34 | }
35 |
36 | function clean(x: [string, number][]): [string, number][] {
37 | return [];
38 | }
39 |
40 | function translate(x: T[]): U[] {
41 | return [];
42 | }
43 |
44 | function uu(x: (number | boolean)[]): (number | boolean)[] {
45 | return x;
46 | }
47 |
48 | class Temp {
49 | x: T
50 | }
51 |
52 | function ta(ts: Temp[]): Temp[] {
53 | return [];
54 | }
55 |
56 | function tat(ts: Temp[]): Temp[] {
57 | return [];
58 | }
59 |
--------------------------------------------------------------------------------
/ts2mls/js/src/test/typescript/BasicFunctions.ts:
--------------------------------------------------------------------------------
1 | function hello() {
2 | console.log("hello")
3 | }
4 |
5 | function add(x: number, y: number): number {
6 | return x + y
7 | }
8 |
9 | function sub(x: number, y: number) {
10 | return x - y
11 | }
12 |
13 | function foo() {
14 | return 42;
15 | }
16 |
17 | function id(x) {
18 | return x;
19 | }
20 |
21 | function odd(x: number) {
22 | return (x % 2) !== 0;
23 | }
24 |
25 | function isnull(x) {
26 | return x == null;
27 | }
28 |
29 | function bar() {
30 | return undefined;
31 | }
32 |
33 | function nu(n: null): null {
34 | return n;
35 | }
36 |
37 | function un(n: undefined): undefined {
38 | return n;
39 | }
40 |
41 | function fail() : never {
42 | throw new Error("wuwuwu");
43 | }
44 |
45 | function create(): object {
46 | return {v: 0};
47 | }
48 |
49 | function pa(x: ((number))): number {
50 | return x + 42;
51 | }
52 |
53 | function wtf(x: unknown) {}
54 |
55 | class Foooooo {
56 | ooooooo: number
57 | }
58 |
59 | function inn(f: Foooooo) {
60 | console.log(f.ooooooo)
61 | }
62 |
63 | function out1(): Foooooo {
64 | return new Foooooo();
65 | }
66 |
67 | interface Barrrrrrrrr {
68 | rrrrrrr: number
69 | }
70 |
71 | function inn2(b: Barrrrrrrrr) {
72 | console.log(b.rrrrrrr)
73 | }
74 |
75 | function out2(): Barrrrrrrrr {
76 | return {rrrrrrr: 42};
77 | }
78 |
--------------------------------------------------------------------------------
/ts2mls/js/src/test/typescript/ClassMember.ts:
--------------------------------------------------------------------------------
1 | class Student {
2 | name: string
3 |
4 | constructor(s: string, age: number) {}
5 |
6 |
7 | getID() { return 114514; }
8 |
9 | addScore(sub: string, score: number) {}
10 | isFriend(other: Student) { return true; }
11 |
12 | private a: number
13 | protected b: string
14 | }
15 |
16 | class Foo {
17 | constructor() {}
18 |
19 | bar(x: T) {}
20 | }
21 |
22 | class EZ {
23 | inc(x: number) {
24 | return x + 1;
25 | }
26 |
27 | private foo() {}
28 | protected bar: undefined
29 | }
30 |
31 | class Outer {
32 | static Inner = class Inner {
33 | a: number
34 | }
35 | }
36 |
37 | class TTT {
38 | ttt(x: T): T {
39 | return x;
40 | }
41 |
42 | ttt2: (x: T) => T
43 | }
44 |
--------------------------------------------------------------------------------
/ts2mls/js/src/test/typescript/Dec.d.ts:
--------------------------------------------------------------------------------
1 | decalre function getName(id: number | string): string
2 | declare function render(callback?: ()=>void): string
3 |
4 | declare interface Get{
5 | (id: string): string
6 | }
7 |
8 | declare class Person {
9 | constructor(name: string, age: number)
10 | getName(id: number): string
11 | }
12 |
13 | declare namespace OOO{
14 | }
15 |
--------------------------------------------------------------------------------
/ts2mls/js/src/test/typescript/Enum.ts:
--------------------------------------------------------------------------------
1 | enum Color {Red, Yellow, Green}
2 |
3 | function pass(c: Color): boolean {
4 | return c == Color.Green;
5 | }
6 |
7 | function stop(): Color {
8 | return Color.Red;
9 | }
10 |
11 | enum Empty {}
12 |
13 | function g(x: Empty): Empty {
14 | return x;
15 | }
16 |
--------------------------------------------------------------------------------
/ts2mls/js/src/test/typescript/Heritage.ts:
--------------------------------------------------------------------------------
1 | class A {
2 | constructor() {}
3 |
4 | foo() {
5 | console.log("foo")
6 | }
7 | }
8 |
9 | class B extends A {}
10 |
11 | class C {
12 | constructor() {}
13 |
14 | private t: T
15 |
16 | sett(x: T) { this.t = x; } // FIXME support `set` methods...
17 | get() { return this.t; }
18 | }
19 |
20 | class D extends C {
21 | }
22 |
23 | interface Wu {
24 | x: boolean
25 | }
26 |
27 | class WuWu extends Wu {
28 | y: boolean
29 | }
30 |
31 | interface WuWuWu extends WuWu {
32 | z: boolean
33 | }
34 |
35 | interface Never extends WuWuWu {
36 | w: () => never
37 | }
38 |
39 | class VG {
40 | x: T
41 | }
42 |
43 | class Home extends VG {
44 | y: T
45 | }
46 |
47 | interface O {
48 | xx: (x: I) => I
49 | }
50 |
51 | class OR implements O {
52 | xx(x: R): R {
53 | return x;
54 | }
55 | }
56 |
57 | namespace Five {
58 | export class ROTK {
59 | wu: string
60 | }
61 |
62 | export class Y extends Five.ROTK {}
63 | }
64 |
65 | class Y extends Five.ROTK {}
66 |
--------------------------------------------------------------------------------
/ts2mls/js/src/test/typescript/HighOrderFunc.ts:
--------------------------------------------------------------------------------
1 | function h1(inc: (n: number) => number, num: number) {
2 | return inc(num)
3 | }
4 |
5 | function h2(hint: string) {
6 | return function() {
7 | return "hint: " + hint
8 | }
9 | }
10 |
11 | function h3(f: (x: number) => number, g: (x: number) => number) {
12 | return function(x: number) {
13 | return f(g(x))
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/ts2mls/js/src/test/typescript/InterfaceMember.ts:
--------------------------------------------------------------------------------
1 | interface IFoo {
2 | a: string
3 | b: (x: number) => number
4 | c: () => boolean
5 | d: (x: string) => void
6 | }
7 |
8 | interface II {
9 | test: (x: T) => number
10 | }
11 |
12 | function create() {
13 | return {v: 114};
14 | }
15 |
16 | function get(x: {t: string}): string {
17 | return x.t;
18 | }
19 |
20 | interface IEvent {
21 | callback(this: IEvent): (x: number) => void;
22 | }
23 |
24 | interface SearchFunc {
25 | (source: string, subString: string): boolean;
26 | }
27 |
28 | interface StringArray {
29 | [index: number]: string;
30 | }
31 |
32 | interface Counter {
33 | (start: number): string;
34 | interval: number;
35 | reset(): void;
36 | }
37 |
38 | interface Simple {
39 | a: number
40 | b: (x: boolean) => string
41 | }
42 |
43 | interface Simple2 {
44 | abc: T
45 | }
46 |
47 | interface Next extends Simple {}
48 |
49 | interface TTT {
50 | ttt: (x: T) => T
51 | }
52 |
--------------------------------------------------------------------------------
/ts2mls/js/src/test/typescript/Intersection.ts:
--------------------------------------------------------------------------------
1 | function extend(first: T, second: U): T & U {
2 | let result = {};
3 | return result;
4 | }
5 |
6 | function foo(x: T & U) {
7 | console.log(x)
8 | }
9 |
10 | function over(f: ((x: number) => string) & ((x: object) => string)): string {
11 | return f(42);
12 | }
13 |
14 | interface IA{
15 | x: number
16 | }
17 |
18 | interface IB{
19 | y: number
20 | }
21 |
22 | function iii(x: IA & IB): IA & IB {
23 | return x;
24 | }
25 |
26 | function uu(x: (U | V) & (T | P)): (U | V) & (T | P) {
27 | return x;
28 | }
29 |
30 | function iiii(x: U & (T & V)): U & (T & V) {
31 | return x;
32 | }
33 |
34 | function arr(a: U[] & T[]): U[] & T[] {
35 | return a;
36 | }
37 |
38 | function tt(x: [U, T] & [V, V]): [U, T] & [V, V] {
39 | return x;
40 | }
41 |
42 | class A{}
43 | class B{}
44 |
45 | function inter(c: A & B): A & B {
46 | return c;
47 | }
48 |
--------------------------------------------------------------------------------
/ts2mls/js/src/test/typescript/Literal.ts:
--------------------------------------------------------------------------------
1 | const a = { a: "A", b: "B" }
2 | const num = { y: 114 }
3 |
4 | function foo(x: {xx: "X"}): {yy: "Y"} {
5 | const y = {yy: "Y"}
6 | return y
7 | }
8 |
--------------------------------------------------------------------------------
/ts2mls/js/src/test/typescript/Multi1.ts:
--------------------------------------------------------------------------------
1 | function multi1(x: number) {
2 | return x;
3 | }
4 |
5 | function multi3() {}
6 |
7 | class Foo extends Base {}
8 |
9 | interface AnotherBase {
10 | y: string
11 | }
12 |
13 | namespace N {
14 | export function f() {}
15 | }
16 |
--------------------------------------------------------------------------------
/ts2mls/js/src/test/typescript/Multi2.ts:
--------------------------------------------------------------------------------
1 | function multi2(x: string) {
2 | return x;
3 | }
4 |
5 | function multi4() {
6 | multi3()
7 | }
8 |
9 | interface Base {
10 | a: number
11 | }
12 |
13 | class AnotherFoo extends AnotherBase {}
14 |
15 | namespace N {
16 | export function g() {}
17 | }
18 |
--------------------------------------------------------------------------------
/ts2mls/js/src/test/typescript/Multi3.ts:
--------------------------------------------------------------------------------
1 | function multi5() {
2 | console.log("wuwuwu")
3 | }
4 |
5 | namespace N {
6 | export function h() {}
7 | }
8 |
--------------------------------------------------------------------------------
/ts2mls/js/src/test/typescript/Namespace.ts:
--------------------------------------------------------------------------------
1 | namespace N1 {
2 | export function f(x) {
3 | return 42;
4 | }
5 |
6 | function ff(y) {
7 | return 42;
8 | }
9 |
10 | export class C {
11 | f() {}
12 | }
13 |
14 | interface I {
15 | f: () => number
16 | }
17 |
18 | export namespace N2 {
19 | export function fff(x: boolean) {
20 | return 42;
21 | }
22 |
23 | class BBB extends C {}
24 |
25 | function gg(c: C): C {
26 | return new C;
27 | }
28 | }
29 | }
30 |
31 | namespace AA {
32 | export function f(x) {
33 | return "42";
34 | }
35 |
36 | export class C {
37 | f() {}
38 | }
39 |
40 | export interface I {
41 | f: () => number
42 | }
43 |
44 | export namespace N2 {}
45 | }
46 |
47 | function f1(x: N1.C): N1.C {
48 | return x;
49 | }
50 |
51 | function f2(x: AA.C): AA.C {
52 | return x;
53 | }
54 |
--------------------------------------------------------------------------------
/ts2mls/js/src/test/typescript/Optional.ts:
--------------------------------------------------------------------------------
1 | function buildName(firstName: string, lastName?: string) {
2 | return firstName + lastName;
3 | }
4 |
5 | function buildName2(firstName: string, lastName = "DIO") {
6 | return firstName + lastName;
7 | }
8 |
9 | function buildName3(firstName: string, ...lastName: string[]) {
10 | console.log(lastName)
11 | return firstName;
12 | }
13 |
14 | function buildName4(firstName: string, ...lastName) {
15 | console.log(lastName)
16 | return firstName;
17 | }
18 |
19 | interface SquareConfig {
20 | color?: string;
21 | width?: number;
22 | }
23 |
24 | function did(x: number, f?: (x: number) => number): number {
25 | if (f === undefined) return x;
26 | else return f(x);
27 | }
28 |
29 | function getOrElse(arr?: object[]): object {
30 | if (arr === undefined) return {};
31 | else return arr[0];
32 | }
33 |
34 | class ABC {}
35 | function testABC(abc?: ABC) {}
36 |
37 | function testSquareConfig(conf?: SquareConfig) {}
38 |
39 | function err(msg?: [number, string]): void {
40 | if (msg === undefined) return;
41 | else throw msg;
42 | }
43 |
44 | function toStr(x?: number | boolean): string {
45 | if (x === undefined) return "undefined";
46 | else return x.toString();
47 | }
48 |
49 | function boo(x?: T & U) {}
50 |
51 | class B {
52 | b: T
53 | }
54 |
55 | function boom(b?: B): any {}
56 |
--------------------------------------------------------------------------------
/ts2mls/js/src/test/typescript/Tuple.ts:
--------------------------------------------------------------------------------
1 | function key(x: [string, boolean]): string {
2 | return x[0];
3 | }
4 |
5 | function value(x: [string, boolean]): boolean {
6 | return x[1];
7 | }
8 |
9 | function third(x: [number, number, number]): number {
10 | return x[2];
11 | }
12 |
13 | function vec2(x: number, y: number): [number, number] {
14 | return [x, y];
15 | }
16 |
17 | function twoFunctions(ff: [(x: number) => number, (x: number) => number], x: number): number {
18 | return ff[0](x) + ff[1](x);
19 | }
20 |
21 | function tupleIt(x: string): [() => string] {
22 | return [function() { return x }]
23 | }
24 |
25 | function s(flag: boolean): [string | number, number | boolean] {
26 | if (flag) {
27 | return ["abc", 12];
28 | }
29 | else {
30 | return [24, false];
31 | }
32 | }
33 |
34 | function s2(t: [boolean, string | number]): string | number {
35 | if (t[0]) return t[1]
36 | else return 0
37 | }
38 |
39 | function ex(x: T, y: U): [T, U, T & U] {
40 | return [x, y , {}];
41 | }
42 |
43 | function foo(x: [T & U]) {}
44 |
45 | function conv(x: {y: number}): [{y: number}, {z: string}] {
46 | return [x, {z: x.y.toString()}];
47 | }
48 |
49 | class A {
50 | x: number
51 | }
52 | class B {}
53 |
54 | function swap(x: [A, B]): [B, A] {
55 | return [x[1], x[0]];
56 | }
57 |
--------------------------------------------------------------------------------
/ts2mls/js/src/test/typescript/Type.ts:
--------------------------------------------------------------------------------
1 | interface None {
2 | readonly _tag: 'None'
3 | }
4 |
5 | interface Some {
6 | readonly _tag: 'Some'
7 | readonly value: A
8 | }
9 |
10 | type Option = None | Some
11 | type Func = (x: number) => number
12 | type S2 = [string, string]
13 |
14 | interface I1 {}
15 | interface I2 {}
16 |
17 | type I3 = I1 & I2
18 | type StringArray = string[]
19 | type SomeInterface = { x: number, y: number }
20 |
21 | class ABC {}
22 | type DEF = ABC
23 | type TP = [A, B, C]
24 |
25 | namespace NA {
26 | export type B = string
27 | function fb(b: B) {}
28 | }
29 |
30 | class NC {
31 | constructor() {}
32 | b: NA.B
33 | }
34 |
35 | type G = DEF
36 |
37 | const none: Option = { _tag: 'None' }
38 | const some = (a: A): Option => ({ _tag: 'Some', value: a })
39 |
--------------------------------------------------------------------------------
/ts2mls/js/src/test/typescript/TypeParameter.ts:
--------------------------------------------------------------------------------
1 | function inc(x: T) {
2 | return x + 1
3 | }
4 |
5 | class CC {
6 | constructor() {}
7 |
8 | print(s: T) { console.log(s) }
9 | }
10 |
11 | function con(t: T): U {
12 | return t;
13 | }
14 |
15 | class Printer {
16 | constructor() {}
17 |
18 | print(t: T) { console.log(t) }
19 | }
20 |
21 | function setStringPrinter(p: Printer) {}
22 |
23 | function getStringPrinter(): Printer { return new Printer(); }
24 |
25 | function foo(p: Printer, x: T): T {
26 | return null;
27 | }
28 |
29 | // TODO: `extends` is still not supported yet.
30 | function foo2(p: Printer, x: T): T {
31 | return null;
32 | }
33 |
34 | class F {
35 | x: T
36 |
37 | GG(y: U): T {
38 | return this.x;
39 | }
40 | }
41 |
42 | interface I {
43 | x: T
44 | GG(y: U): T
45 | }
46 |
47 | class FFF {
48 | constructor() {}
49 | fff(x: T) {}
50 | }
51 |
52 | function fff(p: FFF, s: string) {
53 | p.fff(s);
54 | }
55 |
56 | function getFFF(): FFF {
57 | return new FFF();
58 | }
59 |
--------------------------------------------------------------------------------
/ts2mls/js/src/test/typescript/Union.ts:
--------------------------------------------------------------------------------
1 | function getString(x: string | number | boolean): string {
2 | return x.toString()
3 | }
4 |
5 | function test(x: boolean): (string | number) {
6 | if (x) return "foo";
7 | else return 42;
8 | }
9 |
10 | function run(f: ((x: number) => number) | ((x: number) => string)): any {
11 | return f(42);
12 | }
13 |
14 | function get(arr: number[] | string[]) {
15 | console.log(arr[0])
16 | }
17 |
18 | function get2(t: [string, string] | [number, string]): string {
19 | return t[1];
20 | }
21 |
22 | function typeVar(x: T | U): T | U {
23 | return x
24 | }
25 |
26 | function uuuu(x: string | (number | boolean)): string | (number | boolean) {
27 | return x;
28 | }
29 |
--------------------------------------------------------------------------------
/ts2mls/js/src/test/typescript/Variables.ts:
--------------------------------------------------------------------------------
1 | const URI: string = "Option"
2 | let URI2: string = "Option"
3 | let foo: number
4 | const bar = false
5 |
6 | class FooBar {}
7 | const fb = new FooBar
8 |
9 | namespace ABC {
10 | export class DEF {}
11 | }
12 |
13 | const d = new ABC.DEF
14 |
15 | namespace DD {
16 | export const foo: number = 42
17 | const bar = 42
18 | }
19 |
--------------------------------------------------------------------------------
/ts2mls/jvm/src/test/scala/ts2mls/TsTypeDiffTests.scala:
--------------------------------------------------------------------------------
1 | package ts2mls
2 |
3 | import mlscript.DiffTests
4 |
5 | class TsTypeDiffTests extends DiffTests {
6 | override protected lazy val files =
7 | os.walk(os.pwd/"ts2mls"/"js"/"src"/"test"/"diff").filter(_.toIO.isFile)
8 | }
9 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "commonjs",
4 | "target": "es2016",
5 | "jsx": "preserve",
6 | "sourceMap": true
7 | },
8 | "include": [
9 | "ts"
10 | ],
11 | "exclude": [
12 | "node_modules",
13 | "**/node_modules/*"
14 | ],
15 | "[typescript]": {
16 | "editor.showUnused": false
17 | },
18 | "[typescriptreact]": {
19 | "editor.showUnused": false
20 | },
21 | }
22 |
--------------------------------------------------------------------------------