Full Code of finkel-lang/finkel for AI

master 17f1cfc35a55 cached
541 files
1.2 MB
380.1k tokens
7 symbols
1 requests
Download .txt
Showing preview only (1,413K chars total). Download the full file or copy to clipboard to get everything.
Repository: finkel-lang/finkel
Branch: master
Commit: 17f1cfc35a55
Files: 541
Total size: 1.2 MB

Directory structure:
gitextract_w18apfhd/

├── .appveyor.yml
├── .circleci/
│   └── config.yml
├── .codecov.yml
├── .dir-locals.el
├── .gitattributes
├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   └── bug_report.md
│   ├── dependabot.yml
│   └── workflows/
│       ├── cabal-install.yml
│       ├── ci.yml
│       ├── nix-build.yml
│       ├── pre-job.yml
│       ├── sdist.yml
│       └── stack.yml
├── .gitignore
├── .hlint.yaml
├── .readthedocs.yaml
├── .stylish-haskell.yaml
├── .travis.yml
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── cabal.project
├── default.nix
├── doc/
│   ├── LICENSE
│   ├── Makefile
│   ├── Setup.hs
│   ├── conf.py
│   ├── contents/
│   │   ├── building-package.rst
│   │   ├── finkel-executable.rst
│   │   ├── install.rst
│   │   ├── language-syntax.rst
│   │   └── macros.rst
│   ├── doc.cabal
│   ├── include/
│   │   ├── building-package/
│   │   │   ├── my-first-package/
│   │   │   │   ├── Setup.hs
│   │   │   │   ├── my-first-package.cabal
│   │   │   │   ├── package.yaml
│   │   │   │   ├── src/
│   │   │   │   │   └── MyFirstPackage.hs
│   │   │   │   ├── stack.git.yaml
│   │   │   │   └── stack.template.yaml
│   │   │   ├── my-new-package/
│   │   │   │   ├── LICENSE
│   │   │   │   ├── README.md
│   │   │   │   ├── Setup.hs
│   │   │   │   ├── app/
│   │   │   │   │   └── Main.hs
│   │   │   │   ├── my-new-package.cabal
│   │   │   │   ├── src/
│   │   │   │   │   └── Lib.hs
│   │   │   │   ├── stack.yaml
│   │   │   │   └── test/
│   │   │   │       └── Spec.hs
│   │   │   └── my-second-package/
│   │   │       ├── LICENSE
│   │   │       ├── README.md
│   │   │       ├── Setup.hs
│   │   │       ├── app/
│   │   │       │   └── Main.hs
│   │   │       ├── my-second-package.cabal
│   │   │       ├── src/
│   │   │       │   ├── FnkCodes.hs
│   │   │       │   ├── HsCodes.hs
│   │   │       │   └── Lib.hs
│   │   │       └── test/
│   │   │           ├── FactorialTest.hs
│   │   │           └── Spec.hs
│   │   ├── finkel-executable/
│   │   │   ├── finkel-help-make.console
│   │   │   ├── hello-prof.console
│   │   │   ├── hello.console
│   │   │   ├── hello.hs
│   │   │   └── hello904.console
│   │   ├── language-syntax/
│   │   │   ├── decl/
│   │   │   │   ├── bind-pat.fnk
│   │   │   │   ├── bind-pat.hs
│   │   │   │   ├── bind-simpl.fnk
│   │   │   │   ├── bind-simpl.hs
│   │   │   │   ├── bind-where.fnk
│   │   │   │   ├── bind-where.hs
│   │   │   │   ├── class.fnk
│   │   │   │   ├── class.hs
│   │   │   │   ├── data-d1.fnk
│   │   │   │   ├── data-d1.hs
│   │   │   │   ├── data-d2.fnk
│   │   │   │   ├── data-d2.hs
│   │   │   │   ├── default.fnk
│   │   │   │   ├── default.hs
│   │   │   │   ├── fixity.fnk
│   │   │   │   ├── fixity.hs
│   │   │   │   ├── instance.fnk
│   │   │   │   ├── instance.hs
│   │   │   │   ├── newtype.fnk
│   │   │   │   ├── newtype.hs
│   │   │   │   ├── tysig-constraints.fnk
│   │   │   │   ├── tysig-constraints.hs
│   │   │   │   ├── tysig-many.fnk
│   │   │   │   ├── tysig-many.hs
│   │   │   │   ├── tysig-one.fnk
│   │   │   │   ├── tysig-one.hs
│   │   │   │   ├── tysym.fnk
│   │   │   │   └── tysym.hs
│   │   │   ├── expr/
│   │   │   │   ├── block-comment.fnk
│   │   │   │   ├── block-comment.hs
│   │   │   │   ├── case.fnk
│   │   │   │   ├── case.hs
│   │   │   │   ├── char-a.fnk
│   │   │   │   ├── char-a.hs
│   │   │   │   ├── char-escape.fnk
│   │   │   │   ├── char-escape.hs
│   │   │   │   ├── char-ncode.fnk
│   │   │   │   ├── char-ncode.hs
│   │   │   │   ├── char-special.fnk
│   │   │   │   ├── char-special.hs
│   │   │   │   ├── discard-prefix.fnk
│   │   │   │   ├── discard-prefix.hs
│   │   │   │   ├── do.fnk
│   │   │   │   ├── do.hs
│   │   │   │   ├── fieldlabels.fnk
│   │   │   │   ├── fieldlabels.hs
│   │   │   │   ├── funapp-pars.fnk
│   │   │   │   ├── funapp-pars.hs
│   │   │   │   ├── funapp.fnk
│   │   │   │   ├── funapp.hs
│   │   │   │   ├── guard.fnk
│   │   │   │   ├── guard.hs
│   │   │   │   ├── if.fnk
│   │   │   │   ├── if.hs
│   │   │   │   ├── lambda.fnk
│   │   │   │   ├── lambda.hs
│   │   │   │   ├── let.fnk
│   │   │   │   ├── let.hs
│   │   │   │   ├── line-comment.fnk
│   │   │   │   ├── line-comment.hs
│   │   │   │   ├── list-comp.fnk
│   │   │   │   ├── list-comp.hs
│   │   │   │   ├── list-const.fnk
│   │   │   │   ├── list-const.hs
│   │   │   │   ├── list-range.fnk
│   │   │   │   ├── list-range.hs
│   │   │   │   ├── map-mul2.fnk
│   │   │   │   ├── map-mul2.hs
│   │   │   │   ├── map-unary.fnk
│   │   │   │   ├── map-unary.hs
│   │   │   │   ├── muladd.fnk
│   │   │   │   ├── muladd.hs
│   │   │   │   ├── numeric.fnk
│   │   │   │   ├── numeric.hs
│   │   │   │   ├── opexp-add.fnk
│   │   │   │   ├── opexp-add.hs
│   │   │   │   ├── opexp-app.fnk
│   │   │   │   ├── opexp-app.hs
│   │   │   │   ├── pat-as.fnk
│   │   │   │   ├── pat-as.hs
│   │   │   │   ├── pat-irf.fnk
│   │   │   │   ├── pat-irf.hs
│   │   │   │   ├── pat-maybe.fnk
│   │   │   │   ├── pat-maybe.hs
│   │   │   │   ├── pat-opexp.fnk
│   │   │   │   ├── pat-opexp.hs
│   │   │   │   ├── sige.fnk
│   │   │   │   ├── sige.hs
│   │   │   │   ├── string.fnk
│   │   │   │   ├── string.hs
│   │   │   │   ├── tup2.fnk
│   │   │   │   ├── tup2.hs
│   │   │   │   ├── tup5.fnk
│   │   │   │   ├── tup5.hs
│   │   │   │   ├── tupfn.fnk
│   │   │   │   ├── tupfn.hs
│   │   │   │   ├── unit.fnk
│   │   │   │   ├── unit.hs
│   │   │   │   ├── varid.fnk
│   │   │   │   └── varid.hs
│   │   │   ├── ffi/
│   │   │   │   ├── export.fnk
│   │   │   │   ├── export.hs
│   │   │   │   ├── import.fnk
│   │   │   │   └── import.hs
│   │   │   ├── import/
│   │   │   │   ├── altogether.fnk
│   │   │   │   ├── altogether.hs
│   │   │   │   ├── entity-list.fnk
│   │   │   │   ├── entity-list.hs
│   │   │   │   ├── hiding.fnk
│   │   │   │   ├── hiding.hs
│   │   │   │   ├── qualified-as.fnk
│   │   │   │   ├── qualified-as.hs
│   │   │   │   ├── simpl.fnk
│   │   │   │   └── simpl.hs
│   │   │   └── module/
│   │   │       ├── export-list.fnk
│   │   │       ├── export-list.hs
│   │   │       ├── simpl.fnk
│   │   │       └── simpl.hs
│   │   └── macros/
│   │       ├── RequireMe.fnk
│   │       ├── arglist.console
│   │       ├── arglist.fnk
│   │       ├── begin.console
│   │       ├── begin.fnk
│   │       ├── eval-when-compile.console
│   │       ├── eval-when-compile.fnk
│   │       ├── eval-when.console
│   │       ├── eval-when.fnk
│   │       ├── fib-macro.console
│   │       ├── fib-macro.fnk
│   │       ├── macrolet.console
│   │       ├── macrolet.fnk
│   │       ├── quasiquote.console
│   │       ├── quasiquote.fnk
│   │       ├── quasiquote904.console
│   │       ├── quote.console
│   │       ├── quote.fnk
│   │       ├── raw-require.console
│   │       ├── raw-require.fnk
│   │       ├── require.console
│   │       ├── require.fnk
│   │       ├── unquote-splice.console
│   │       ├── unquote-splice.fnk
│   │       ├── unquote.console
│   │       └── unquote.fnk
│   ├── index.rst
│   ├── make.bat
│   ├── requirements.txt
│   └── test/
│       ├── Doc/
│       │   ├── BuildingPackage.hs
│       │   ├── FinkelExecutable.hs
│       │   ├── LanguageSyntax.hs
│       │   ├── Macros.hs
│       │   └── TestAux.hs
│       ├── Doc.hs
│       └── Spec.hs
├── finkel/
│   ├── CHANGELOG.md
│   ├── LICENSE
│   ├── Main.hs
│   ├── README.md
│   ├── Setup.hs
│   └── finkel.cabal
├── finkel-core/
│   ├── LICENSE
│   ├── README.md
│   ├── Setup.hs
│   ├── finkel-core.cabal
│   ├── src/
│   │   └── Finkel/
│   │       ├── Core/
│   │       │   ├── Functions.hs
│   │       │   ├── Internal/
│   │       │   │   ├── Ghc/
│   │       │   │   │   ├── Compat.hs
│   │       │   │   │   └── Version.hs
│   │       │   │   ├── Ghc.hs
│   │       │   │   ├── Stage0.hs
│   │       │   │   ├── Stage1.hs
│   │       │   │   └── Stage2.hs
│   │       │   ├── Internal.hs
│   │       │   └── Plugin.hs
│   │       ├── Core.hs
│   │       └── Prelude.hs
│   └── test/
│       ├── CoreTest.hs
│       ├── FunctionTest.hs
│       ├── Orphan.hs
│       ├── PluginTest.hs
│       ├── Spec.hs
│       ├── TestAux.hs
│       └── data/
│           └── plugin/
│               ├── ImportMe.hs
│               └── c01.hs
├── finkel-kernel/
│   ├── LICENSE
│   ├── README.md
│   ├── Setup.hs
│   ├── exec/
│   │   ├── fnkc.hs
│   │   └── profile.hs
│   ├── finkel-kernel.cabal
│   ├── include/
│   │   ├── ghc_modules.h
│   │   └── hooks.c
│   ├── src/
│   │   └── Language/
│   │       ├── Finkel/
│   │       │   ├── Builder.hs
│   │       │   ├── Data/
│   │       │   │   ├── FastString.hs
│   │       │   │   ├── Fractional.hs
│   │       │   │   └── SourceText.hs
│   │       │   ├── Emit.hs
│   │       │   ├── Error.hs
│   │       │   ├── Eval.hs
│   │       │   ├── Exception.hs
│   │       │   ├── Expand.hs
│   │       │   ├── Fnk.hs
│   │       │   ├── Form.hs
│   │       │   ├── Homoiconic.hs
│   │       │   ├── Hooks.hs
│   │       │   ├── Lexer.x
│   │       │   ├── Main.hs
│   │       │   ├── Make/
│   │       │   │   ├── Cache.hs
│   │       │   │   ├── Recompile.hs
│   │       │   │   ├── Session.hs
│   │       │   │   ├── Summary.hs
│   │       │   │   ├── TargetSource.hs
│   │       │   │   └── Trace.hs
│   │       │   ├── Make.hs
│   │       │   ├── Options.hs
│   │       │   ├── ParsedResult.hs
│   │       │   ├── Plugin.hs
│   │       │   ├── Preprocess.hs
│   │       │   ├── Reader.y
│   │       │   ├── SpecialForms.hs
│   │       │   ├── Syntax/
│   │       │   │   ├── Extension.hs
│   │       │   │   ├── HBind.hs
│   │       │   │   ├── HDecl.hs
│   │       │   │   ├── HExpr.hs
│   │       │   │   ├── HImpExp.hs
│   │       │   │   ├── HPat.hs
│   │       │   │   ├── HType.hs
│   │       │   │   ├── Location.hs
│   │       │   │   └── Utils.hs
│   │       │   └── Syntax.y
│   │       └── Finkel.hs
│   └── test/
│       ├── EmitTest.hs
│       ├── EvalTest.hs
│       ├── ExceptionTest.hs
│       ├── FnkTest.hs
│       ├── FormTest.hs
│       ├── Main.hs
│       ├── MainTest.hs
│       ├── MakeTest.hs
│       ├── Orphan.hs
│       ├── PluginTest.hs
│       ├── PreprocessTest.hs
│       ├── SyntaxTest.hs
│       ├── TestAux.hs
│       └── data/
│           ├── eval/
│           │   ├── 0001-simple.fnk
│           │   ├── 0002-shadowing-macro.fnk
│           │   ├── 0003-expand1.fnk
│           │   └── 0004-unquote-unquote-splice.fnk
│           ├── exception/
│           │   ├── 0001-invalid-unquote-splice.hs
│           │   ├── 0002-invalid-string-literal.hs
│           │   └── 0003-malformed-qq.hs
│           ├── main/
│           │   ├── MyMain.hs
│           │   ├── m001.hs
│           │   ├── m002.hs
│           │   └── m003.c
│           ├── make/
│           │   ├── E01.hs
│           │   ├── E02.hs
│           │   ├── M1.hs
│           │   ├── M2.hs
│           │   ├── M3.hs
│           │   ├── M4/
│           │   │   ├── A.hs
│           │   │   └── B.hs
│           │   ├── M4.hs
│           │   ├── M5.hs
│           │   ├── M6/
│           │   │   ├── A.hs
│           │   │   └── B.hs
│           │   ├── P1.hs
│           │   ├── P2.hs
│           │   ├── P3.hs
│           │   ├── R01.hs.1
│           │   ├── R01.hs.2
│           │   ├── R02.hs
│           │   ├── R03.hs
│           │   ├── R04.hs
│           │   ├── R05.hs
│           │   ├── R05a.hs
│           │   ├── R06.hs
│           │   ├── R06a.hs
│           │   ├── R07.hs
│           │   ├── R07a.hs
│           │   ├── R07b.hs
│           │   ├── R08.hs
│           │   ├── R08a.hs
│           │   ├── R08b.hs
│           │   ├── R09.hs
│           │   ├── R09a.hs
│           │   ├── R09b.hs
│           │   ├── R10.hs
│           │   ├── R10a.hs
│           │   ├── R10b.hs
│           │   ├── R11.hs
│           │   ├── R11a.hs
│           │   ├── R11b.hs
│           │   ├── cbits1.c
│           │   ├── cbits2.c
│           │   ├── cbits3.c
│           │   ├── main1.hs
│           │   ├── main2.hs
│           │   ├── main3.hs
│           │   ├── main4.hs
│           │   ├── main5.hs
│           │   ├── main6.hs
│           │   ├── main7.hs
│           │   ├── main8.hs
│           │   └── main9.hs
│           ├── plugin/
│           │   ├── M01.hs
│           │   ├── M02.hs
│           │   ├── M03.hs
│           │   ├── M04.hs
│           │   ├── M04b.hs
│           │   ├── p01.hs
│           │   ├── p02.hs
│           │   ├── p03.hs
│           │   ├── p04.hs
│           │   ├── p05.hs
│           │   ├── p06.hs
│           │   ├── p07.hs
│           │   ├── p08.hs
│           │   ├── p09.hs
│           │   ├── p10.hs
│           │   └── p11.hs
│           ├── preprocess/
│           │   ├── fnk01.hs
│           │   ├── fnk02.hs
│           │   ├── fnk03.hs
│           │   ├── fnk04.hs
│           │   ├── fnk05.hs
│           │   ├── fnk06.hs
│           │   ├── fnk11.hs
│           │   ├── fnk12.hs
│           │   ├── fnk13.hs
│           │   ├── fnk14.hs
│           │   ├── fnk15.hs
│           │   ├── hs01.hs
│           │   └── hs02.hs
│           └── syntax/
│               ├── 0001-hello.hs
│               ├── 0002-lexical.hs
│               ├── 0003-expressions-1.hs
│               ├── 0003-expressions-2.hs
│               ├── 0003-expressions-3.hs
│               ├── 0004-decls.hs
│               ├── 0005-modules-01.hs
│               ├── 0005-modules-02.hs
│               ├── 0005-modules-03.hs
│               ├── 0005-modules-04.hs
│               ├── 0005-modules-05.hs
│               ├── 0008-ffi.hs
│               ├── 0012-pragmas.hs
│               ├── 1000-comment.hs
│               ├── 1001-quote.hs
│               ├── 1002-macro.hs
│               ├── 1003-eval-when-compile.hs
│               ├── 1004-doccomment-01.hs
│               ├── 1004-doccomment-02.hs
│               ├── 1004-doccomment-03.hs
│               ├── 1005-begin.hs
│               ├── 2001-unpack.hs
│               ├── 2002-bang.hs
│               ├── 2003-derive.hs
│               ├── 2004-overloaded.hs
│               ├── 2005-gadts-01.hs
│               ├── 2005-gadts-02.hs
│               ├── 2006-existential.hs
│               ├── 2007-rankn.hs
│               ├── 2008-options.hs
│               ├── 2009-flexible.hs
│               ├── 2010-kindsig.hs
│               ├── 2011-scoped.hs
│               ├── 2012-typeop.hs
│               ├── 2013-undecidable.hs
│               ├── 2014-noprelude.hs
│               ├── 2015-typefam.hs
│               ├── 2016-datakinds.hs
│               ├── 2017-polykinds.hs
│               ├── 2018-typeapp.hs
│               ├── 2019-overlabel.hs
│               ├── 2020-emptyderiv.hs
│               ├── 2021-dfltsig.hs
│               ├── 2022-drvstrat.hs
│               ├── 2023-standalone.hs
│               ├── 2024-derivingvia.hs
│               ├── 2025-namedfieldpuns.hs
│               ├── 2026-recordwildcards.hs
│               ├── 2027-emptycase-1.hs
│               ├── 2027-emptycase-2.hs
│               ├── 2028-standalonekind.hs
│               └── 2029-impredicative.hs
├── finkel-setup/
│   ├── LICENSE
│   ├── README.md
│   ├── Setup.hs
│   ├── finkel-setup.cabal
│   ├── src/
│   │   └── Distribution/
│   │       └── Simple/
│   │           └── Finkel.hs
│   └── test/
│       ├── Main.hs
│       └── data/
│           ├── p01/
│           │   ├── LICENSE
│           │   ├── Setup.hs
│           │   ├── exec/
│           │   │   └── p01.hs
│           │   ├── p01.cabal
│           │   ├── src/
│           │   │   └── P01/
│           │   │       ├── A.fnk
│           │   │       ├── B.fnk
│           │   │       ├── C.fnk
│           │   │       ├── D.hs
│           │   │       ├── E.hs
│           │   │       ├── F.fnk
│           │   │       ├── G1.fnk
│           │   │       ├── G2.fnk
│           │   │       ├── H.fnk
│           │   │       ├── I.fnk
│           │   │       └── J.fnk
│           │   └── test/
│           │       ├── Spec.hs
│           │       └── TestAll.fnk
│           └── p02/
│               ├── CHANGELOG.md
│               ├── LICENSE
│               ├── Setup.hs
│               ├── app/
│               │   └── Main.hs
│               ├── p02.cabal
│               ├── src/
│               │   └── MyLib.hs
│               └── test/
│                   └── Main.hs
├── finkel-tool/
│   ├── LICENSE
│   ├── README.md
│   ├── Setup.hs
│   ├── finkel-tool.cabal
│   ├── finkel.hsfiles
│   ├── src/
│   │   └── Finkel/
│   │       └── Tool/
│   │           ├── Command/
│   │           │   ├── Eval.hs
│   │           │   ├── Help.hs
│   │           │   ├── Make.hs
│   │           │   ├── Repl.hs
│   │           │   ├── Run.hs
│   │           │   ├── Sdist.hs
│   │           │   └── Version.hs
│   │           ├── Command.hs
│   │           ├── Internal/
│   │           │   ├── CLI.hs
│   │           │   ├── Commit.hs
│   │           │   ├── Compat.hs
│   │           │   ├── Eval.hs
│   │           │   ├── Exception.hs
│   │           │   ├── IO.hs
│   │           │   ├── Listen.hs
│   │           │   ├── Loop.hs
│   │           │   ├── Macro/
│   │           │   │   ├── Ghc.hs
│   │           │   │   └── Repl.hs
│   │           │   └── Types.hs
│   │           └── Main.hs
│   └── test/
│       ├── CLITest.hs
│       ├── GhcTest.hs
│       ├── MainTest.hs
│       ├── ReplMacroTest.hs
│       ├── ReplTest.hs
│       ├── Spec.hs
│       ├── TestAux.hs
│       └── data/
│           ├── Err001.fnk
│           ├── LoadMe.hs
│           ├── RunMeToo.hs
│           ├── input01.txt
│           ├── m01.hs
│           ├── p02/
│           │   ├── LICENSE
│           │   ├── README.md
│           │   ├── Setup.hs
│           │   ├── app/
│           │   │   └── Main.hs
│           │   ├── p02.cabal
│           │   ├── src/
│           │   │   └── Lib.fnk
│           │   ├── stack.yaml
│           │   └── test/
│           │       └── Spec.hs
│           ├── print-int.hs
│           ├── print-load-me.hs
│           ├── run-me.hs
│           └── sleep-for-while.fnk
├── fkc/
│   ├── LICENSE
│   ├── Main.hs
│   ├── README.md
│   ├── Setup.hs
│   └── fkc.cabal
├── fnkpp/
│   ├── LICENSE
│   ├── Main.hs
│   ├── README.md
│   └── fnkpp.cabal
├── nix/
│   ├── docker.nix
│   └── finkel-packages.nix
├── scripts/
│   └── travis.sh
├── shell.nix
└── stack.yaml

================================================
FILE CONTENTS
================================================

================================================
FILE: .appveyor.yml
================================================
branches:
  only:
    - /appveyor-*/

environment:
  global:
    CABOPTS: "--store-dir=C:\\SR --http-transport=plain-http"
    GHCVER: 8.10.2
    CABALVER: 3.2.0.0

clone_folder: "C:\\WORK"
clone_depth: 5

cache:
  - C:\SR

install:
  - choco install -y cabal --version %CABALVER%
  - choco install -y ghc --version %GHCVER%
  - refreshenv

before_build:
  - cabal --version
  - ghc --version
  - cabal %CABOPTS% v2-update

build_script:
  - cabal %CABOPTS% v2-configure --disable-optimization --disable-library-profiling
  - cabal %CABOPTS% v2-build all -j --only-dependencies
  - cabal %CABOPTS% v2-build all
  - cabal %CABOPTS% v2-test all


================================================
FILE: .circleci/config.yml
================================================
# Use the latest 2.1 version of CircleCI pipeline process engine. See:
# https://circleci.com/docs/2.0/configuration-reference
version: 2.1

jobs:
  build-linux:
    docker:
      - image: fpco/stack-build:lts-15.4
    steps:
      - checkout
      - restore_cache:
          name: Restore Cached Dependencies
          keys:
            - stack-{{ checksum "stack.yaml" }}
            - kernel-{{ checksum "finkel-kernel/finkel-kernel.cabal" }}
            - kernel-{{ checksum "fkc/fkc.cabal" }}
            - setup-{{ checksum "finkel-setup/finkel-setup.cabal" }}
            - lang-{{ checksum "finkel-core/finkel-core.cabal" }}
            - tool-{{ checksum "finkel-tool/finkel-tool.cabal" }}
            - finkel-{{ checksum "finkel/finkel.cabal" }}
      - run:
          name: Resolve/Update Dependencies
          command: stack --no-terminal setup
      - run:
          name: Build Packages
          command: stack --no-terminal build --test --no-run-tests
      - run:
          name: Run tests
          command: RESOLVER=lts-15.4 stack --no-terminal build --test
      - save_cache:
          name: Cache dependencies
          key: stack-{{ checksum "stack.yaml" }}
          paths:
            - ~/.stack
            - ~/.stack-work

workflows:
  build:
    jobs:
      - build-linux:
          filters:
            branches:
              only:
                - /circleci-.*/


================================================
FILE: .codecov.yml
================================================
coverage:
  status:
    project:
      default:
        threshold: 5%


================================================
FILE: .dir-locals.el
================================================
;;; Directory Local Variables
;;; For more information see (info "(emacs) Directory Variables")

((nil
  (fill-column . 80)
  (indent-tabs-mode . nil))

 (finkel-mode
  (eval finkel-put-indent-method 'define-macro 'finkel-indent-multiargs)
  (eval finkel-put-doc-string-elt 'define-macro 2)

  (eval finkel-put-indent-method 'define-macro\' 'finkel-indent-multiargs)
  (eval finkel-put-doc-string-elt 'define-macro\' 2)

  (eval finkel-put-indent-method 'describe 1)
  (eval finkel-put-indent-method 'it 1)))


================================================
FILE: .gitattributes
================================================
*         text=auto


================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug Report
about: Report a bug in Finkel
---

Please follow the steps below for reporting a bug:

Make sure that you are using the latest source (currently git HEAD in
the master branch).

Please use the following schema for your bug report:

### General summary/comments (optional)

### Steps to reproduce

For example:

1. Remove directory *foo*.
2. Run command `finkel bar`.
3. Edit file buzz.
4. Run command `finkel quux`.

### Expected

What you expected to see and happen.

### Actual

What actually happened.

If you suspect that a finkel command misbehaved, please include the
output of that command in `debug` mode.  If the output is larger than
a page please paste the output in a [Gist](https://gist.github.com/).

```
$ FNK_DEBUG=1 finkel <your command here> <args>
<output>
```

### Finkel version and environment information

Finkel version could be obtained with below command.

```
$ finkel version
<output>
```

* OS name and version
* ... etc

### Method of installation

* Via cabal-install
* Via stack
* Other (please specify)


================================================
FILE: .github/dependabot.yml
================================================
version: 2

updates:
  - package-ecosystem: "github-actions"
    directory: "/"
    schedule:
      interval: "weekly"


================================================
FILE: .github/workflows/cabal-install.yml
================================================
name: cabal-install

on:
  workflow_call:
    inputs:
      cache-version:
        description: cache key version
        required: true
        type: string

defaults:
  run:
    shell: bash

jobs:
  cabal-install:
    name: ghc ${{ matrix.plan.ghc }} with ${{ matrix.plan.flags }}
    strategy:
      matrix:
        os:
          - ubuntu-latest
          # - macos-latest
          # - windows-latest
        plan:
          - ghc: "9.0.2"
            cabal: "3.10.3.0"
            flags: "-O0"

          - ghc: "9.2.8"
            cabal: "latest"
            flags: "-O0"

          # Running tests in ghc 9.4.8 was approximately 2x slower than 9.4.7
          - ghc: "9.4.7"
            cabal: "latest"
            flags: "-O0"

          - ghc: "9.6.5"
            cabal: "latest"
            flags: "-O0"

          - ghc: "9.8.2"
            cabal: "latest"
            flags: "-O0"

          - ghc: "9.10.1"
            cabal: "latest"
            flags: "-O0"

          - ghc: "9.10.1"
            cabal: "latest"
            flags: "-O2"

    runs-on:
      - ${{ matrix.os }}

    steps:
      - name: Checkout project repository
        uses: actions/checkout@v4

      - name: Cache cabal package database
        uses: actions/cache@v4
        with:
          path: ~/.cabal
          key: home-dot-cabal-${{ matrix.plan.ghc }}-${{ inputs.cache-version }}

      - name: Setup ghc and cabal-install
        uses: haskell-actions/setup@v2
        with:
          ghc-version: ${{ matrix.plan.ghc }}
          cabal-version: ${{ matrix.plan.cabal }}

      - name: Show version and paths
        run: |
          ghc --version
          cabal --version

      # # XXX: In Windows, use of profiling libraries are not yet supported.
      # - name: Write cabal.project.local with v2-configure (windows)
      #   if: matrix.os == 'windows-latest'
      #   run: cabal v2-configure --disable-library-profiling ${{ matrix.plan.flags }}

      - name: Write cabal.project.local with v2-configure
        run: cabal v2-configure ${{ matrix.plan.flags }} --test-show-details=streaming

      - name: Build dependency packages
        run: cabal v2-build all -j --only-dependencies

      - name: Build packages
        run: cabal v2-build all

      - name: Run tests
        run: cabal v2-test all

      - name: Run haddock
        run: cabal v2-haddock all


================================================
FILE: .github/workflows/ci.yml
================================================
name: ci

on:
  pull_request:
  push:
    paths-ignore:
      - '**.md'

defaults:
  run:
    shell: bash

jobs:
  pre-job:
    uses: ./.github/workflows/pre-job.yml

  stack:
    needs: pre-job
    if: ${{ needs.pre-job.outputs.run == 'true' }}
    uses: ./.github/workflows/stack.yml
    secrets: inherit
    with:
      cache-version: v16

  cabal-install:
    needs: pre-job
    if: ${{ needs.pre-job.outputs.run == 'true' }}
    uses: ./.github/workflows/cabal-install.yml
    with:
      cache-version: v18

  nix-build:
    needs: pre-job
    if: ${{ needs.pre-job.outputs.run == 'true' }}
    uses: ./.github/workflows/nix-build.yml
    secrets: inherit

  make-sdist-with-stack:
    needs: pre-job
    if: ${{ needs.pre-job.outputs.run == 'true' }}
    uses: ./.github/workflows/sdist.yml


================================================
FILE: .github/workflows/nix-build.yml
================================================
name: nix-build

on:
  workflow_call:

jobs:
  nix-build:
    name: Build with nix
    strategy:
      matrix:
        include:
          # - nixpkgs: "channel:nixos-20.03"
          #   compiler: "ghc865"
          # - nixpkgs: "channel:nixos-20.09"
          #   compiler: "ghc884"
          - nixpkgs: "channel:nixos-22.05"
            compiler: "ghc8107"
          # - nixpkgs: "channel:nixos-23.05"
          #   compiler: "ghc92"
          # - nixpkgs: "channel:nixos-unstable"
          #   compiler: "ghc8107"
          # - nixpkgs: "channel:nixos-unstable"
          #   compiler: "ghc901"

    runs-on:
      - ubuntu-latest

    steps:
      - name: Checkout git repository
        uses: actions/checkout@v4

      - name: Install nix
        uses: cachix/install-nix-action@v29
        with:
          nix_path: nixpkgs=${{ matrix.nixpkgs }}

      - name: Build with nix-build
        run: nix-build --argstr compiler ${{ matrix.compiler }}

      - name: Build container image stream
        # if: matrix.compiler == 'ghc8107' && github.ref == 'refs/heads/master'
        if: github.ref == 'refs/heads/master'
        run: |
          nix-build --argstr compiler ${{ matrix.compiler }} ./nix/docker.nix
          echo "image_stream=$(readlink result)" >> $GITHUB_ENV

      - name: Push image to ghcr.io
        # if: matrix.compiler == 'ghc8107' && github.ref == 'refs/heads/master'
        if: github.ref == 'refs/heads/master'
        env:
          # Below `CRED' was used for credentials for ghcr.io, but not any more
          # since logging in with GITHUB_TOKEN is working.  May be the
          # `GHCR_USER' and `GHCR_PAT' variables could be removed from the
          # secrets.
          #
          # CRED: ${{ secrets.GHCR_USER }}:${{ secrets.GHCR_PAT }}
          FROM: docker-archive:/dev/stdin
          TO: docker://ghcr.io/${{ github.repository }}:latest
        run: |
          echo ${{ secrets.GITHUB_TOKEN }} | skopeo login -u $ --password-stdin ghcr.io
          ${{ env.image_stream }} | gzip | skopeo --debug copy ${FROM} ${TO}


================================================
FILE: .github/workflows/pre-job.yml
================================================
name: pre-job

on:
  workflow_call:
    outputs:
      run:
        description: \"true\" if running other jobs
        value: ${{ jobs.pre-job.outputs.run }}

jobs:
  pre-job:
    name: Decide whether to run other jobs
    runs-on: ubuntu-latest
    outputs:
      run: >-
        ${{
        steps.skip-check.outputs.should_skip != 'true' ||
        github.ref_name == github.event.repository.default_branch
        }}
    steps:
      - id: skip-check
        uses: fkirc/skip-duplicate-actions@v5
        with:
          concurrent_skipping: same_content_newer


================================================
FILE: .github/workflows/sdist.yml
================================================
name: sdist

on:
  workflow_call:

jobs:
  make-sdist-with-stack:
    name: Build *.tar.gz made via sdist

    runs-on: ubuntu-latest

    env:
      STACK: stack --resolver=lts-20

    steps:
      - name: Checkout git repository
        uses: actions/checkout@v4

      - name: Show versions
        run: |
          stack --version
          ghc --version
          cabal --version

      - name: Build finkel-setup
        # The "finkel-setup" is used by other packages in custom-setup stanza of
        # cabal configuration, building before running sdist command.
        run: $STACK build --fast finkel-setup

      - name: Run stack sdist
        run: |
          $STACK sdist \
            finkel-kernel \
            fkc \
            fnkpp \
            finkel-setup \
            finkel-core \
            finkel-tool \
            finkel \
            --tar-dir sdist

      - name: Emit temporary stack.yaml
        run: |
          cd sdist
          echo 'resolver: lts-0.0' > stack.yaml
          echo 'packages:' >> stack.yaml
          ls *.tar.gz | sed -e 's/\(.*\)\.tar.gz/  - \1/' >> stack.yaml
          cat stack.yaml

      - name: Build from tarballs with stack
        run: |
          cd sdist
          for t in `ls *.tar.gz`; do tar zxvf $t; done
          $STACK build --fast

      - name: Emit temporary cabal.project
        run: |
          cd sdist
          echo 'packages:' >> cabal.project
          ls *.tar.gz | sed -e 's/\(.*\)\.tar.gz/  \1/' >> cabal.project
          cat cabal.project

      - name: Install and set ghc 9.2.8 via ghcup
        run: |
          ghcup install ghc 9.2.8
          ghcup set ghc 9.2.8

      - name: Build from tarballs with cabal-install
        run: |
          cd sdist
          cabal v2-update
          cabal v2-build all

      - name: Upload package tarballs
        uses: actions/upload-artifact@v4
        with:
          name: finkel-srcs
          path: |
            sdist/*.tar.gz
            sdist/stack.yaml
            sdist/cabal.project


================================================
FILE: .github/workflows/stack.yml
================================================
name: stack

on:
  workflow_call:
    inputs:
      cache-version:
        description: cache key version
        required: true
        type: string

defaults:
  run:
    shell: bash

jobs:
  stack:
    name: ${{ matrix.resolver }} under ${{ matrix.os }}
    strategy:
      matrix:
        include:
          # - os: ubuntu-latest
          #   resolver: lts-11
          # - os: ubuntu-latest
          #   resolver: lts-12

          # - os: ubuntu-latest
          #   resolver: lts-14
          # - os: ubuntu-latest
          #   resolver: lts-16
          # - os: ubuntu-latest
          #   resolver: lts-18

          - os: ubuntu-latest
            resolver: lts-22
          - os: macos-latest
            resolver: lts-22
          - os: windows-latest
            resolver: lts-22

    env:
      STACK: stack --resolver=${{ matrix.resolver }}

    runs-on:
      - ${{ matrix.os }}

    steps:
      - name: Checkout git repository
        uses: actions/checkout@v4

      - name: Cache stack related directories
        uses: 8c6794b6/playing-with-github/.github/actions/setup-stack-cache@main
        with:
          cache-key:
            ${{ matrix.os }}-${{ matrix.resolver }}-${{ inputs.cache-version }}

      - name: Setup haskell
        uses: haskell-actions/setup@v2.7.3
        with:
          enable-stack: true
          stack-no-global: true

      - name: Setup stack
        run: $STACK setup

      - name: Show versions
        run: |
          $STACK --version
          $STACK exec -- ghc --version

      - name: Install dependency packages
        run: $STACK build -j 2 --test --only-dependencies

      - name: Build packages
        run: $STACK build --fast --test --coverage --no-run-tests

      - name: Run tests
        run: |
          RESOLVER=${{ matrix.resolver }} $STACK --jobs 1 build \
          --fast --test --coverage

      - name: Generate coverage report
        uses: 8c6794b6/hpc-codecov-action@v4
        with:
          target: stack:all

      - name: Send coverage report
        uses: codecov/codecov-action@v4
        with:
          name: stack-${{ matrix.os }}-${{ matrix.resolver }}
          token: ${{ secrets.CODECOV_TOKEN }}


================================================
FILE: .gitignore
================================================
*~
*.hi
*.hie
*.hscpp
*.o
*.dyn_o
*.dyn_hi
*.p_o
*.p_hi
*.info
*.prof
*.html
*.hp
*.tix
*.yaml.lock
.ghc.environment.*
result*

TAGS
a.out
cabal.project.local

finkel-kernel/include/finkel_kernel_config.h
finkel-kernel/test/data/main/m00?
finkel-kernel/test/data/make/main?
finkel-kernel/test/data/make/gen
finkel-kernel/test/data/plugin/p??
finkel-kernel/test/data/syntax/*.h

.stack-work/
dist/
dist-newstyle/

doc/_build
doc/_static
doc/_templates

doc/include/finkel-executable/hello
doc/include/macros/quasiquote
doc/include/macros/require


================================================
FILE: .hlint.yaml
================================================
# HLint configuration file
# https://github.com/ndmitchell/hlint
##########################

# This file contains a template configuration file, which is typically
# placed as .hlint.yaml in the root of your project


# Specify additional command line arguments
#
# - arguments: [--color, --cpp-simple, -XQuasiQuotes]


# Control which extensions/flags/modules/functions can be used
#
# - extensions:
#   - default: false # all extension are banned by default
#   - name: [PatternGuards, ViewPatterns] # only these listed extensions can be used
#   - {name: CPP, within: CrossPlatform} # CPP can only be used in a given module
#
# - flags:
#   - {name: -w, within: []} # -w is allowed nowhere
#
# - modules:
#   - {name: [Data.Set, Data.HashSet], as: Set} # if you import Data.Set qualified, it must be as 'Set'
#   - {name: Control.Arrow, within: []} # Certain modules are banned entirely
#
# - functions:
#   - {name: unsafePerformIO, within: []} # unsafePerformIO can only appear in no modules


# Add custom hints for this project
#
# Will suggest replacing "wibbleMany [myvar]" with "wibbleOne myvar"
# - error: {lhs: "wibbleMany [x]", rhs: wibbleOne x}


# Turn on hints that are off by default
#
# Ban "module X(module X) where", to require a real export list
# - warn: {name: Use explicit module export list}
#
# Replace a $ b $ c with a . b $ c
# - group: {name: dollar, enabled: true}
#
# Generalise map to fmap, ++ to <>
# - group: {name: generalise, enabled: true}


# Ignore some builtin hints
# - ignore: {name: Use let}
# - ignore: {name: Use const, within: SpecialModule} # Only within certain modules
- ignore: {name: Use fewer imports}
- ignore: {
    name: Use camelCase,
    within: [
      Language.Finkel.Emit,
      Language.Finkel.Syntax.HBind,
      Language.Finkel.Syntax.HDecl,
      Language.Finkel.Syntax.HExpr,
      Language.Finkel.Syntax.HImpExp,
      Language.Finkel.Syntax.HPat,
      Language.Finkel.Syntax.HType,
      Language.Finkel.SpecialForms
    ]
  }


# Define some custom infix operators
# - fixity: infixr 3 ~^#^~


# To generate a suitable file for HLint do:
# $ hlint --default > .hlint.yaml


================================================
FILE: .readthedocs.yaml
================================================
version: 2

sphinx:
  configuration: doc/conf.py

python:
  version: 3.8
  install:
    - requirements: doc/requirements.txt


================================================
FILE: .stylish-haskell.yaml
================================================
# stylish-haskell configuration file
# ==================================

# The stylish-haskell tool is mainly configured by specifying steps. These steps
# are a list, so they have an order, and one specific step may appear more than
# once (if needed). Each file is processed by these steps in the given order.
steps:
  # Convert some ASCII sequences to their Unicode equivalents. This is disabled
  # by default.
  # - unicode_syntax:
  #     # In order to make this work, we also need to insert the UnicodeSyntax
  #     # language pragma. If this flag is set to true, we insert it when it's
  #     # not already present. You may want to disable it if you configure
  #     # language extensions using some other method than pragmas. Default:
  #     # true.
  #     add_language_pragma: true

  # Align the right hand side of some elements.  This is quite conservative
  # and only applies to statements where each element occupies a single
  # line. All default to true.
  - simple_align:
      cases: true
      top_level_patterns: true
      records: true

  # Import cleanup
  - imports:
      # There are different ways we can align names and lists.
      #
      # - global: Align the import names and import list throughout the entire
      #   file.
      #
      # - file: Like global, but don't add padding when there are no qualified
      #   imports in the file.
      #
      # - group: Only align the imports per group (a group is formed by adjacent
      #   import lines).
      #
      # - none: Do not perform any alignment.
      #
      # Default: global.
      align: file

      # The following options affect only import list alignment.
      #
      # List align has following options:
      #
      # - after_alias: Import list is aligned with end of import including
      #   'as' and 'hiding' keywords.
      #
      #   > import qualified Data.List      as List (concat, foldl, foldr, head,
      #   >                                          init, last, length)
      #
      # - with_alias: Import list is aligned with start of alias or hiding.
      #
      #   > import qualified Data.List      as List (concat, foldl, foldr, head,
      #   >                                 init, last, length)
      #
      # - with_module_name: Import list is aligned `list_padding` spaces after
      #   the module name.
      #
      #   > import qualified Data.List      as List (concat, foldl, foldr, head,
      #                          init, last, length)
      #
      #   This is mainly intended for use with `pad_module_names: false`.
      #
      #   > import qualified Data.List as List (concat, foldl, foldr, head,
      #                          init, last, length, scanl, scanr, take, drop,
      #                          sort, nub)
      #
      # - new_line: Import list starts always on new line.
      #
      #   > import qualified Data.List      as List
      #   >     (concat, foldl, foldr, head, init, last, length)
      #
      # Default: after_alias
      list_align: after_alias

      # Right-pad the module names to align imports in a group:
      #
      # - true: a little more readable
      #
      #   > import qualified Data.List       as List (concat, foldl, foldr,
      #   >                                           init, last, length)
      #   > import qualified Data.List.Extra as List (concat, foldl, foldr,
      #   >                                           init, last, length)
      #
      # - false: diff-safe
      #
      #   > import qualified Data.List as List (concat, foldl, foldr, init,
      #   >                                     last, length)
      #   > import qualified Data.List.Extra as List (concat, foldl, foldr,
      #   >                                           init, last, length)
      #
      # Default: true
      pad_module_names: true

      # Long list align style takes effect when import is too long. This is
      # determined by 'columns' setting.
      #
      # - inline: This option will put as much specs on same line as possible.
      #
      # - new_line: Import list will start on new line.
      #
      # - new_line_multiline: Import list will start on new line when it's
      #   short enough to fit to single line. Otherwise it'll be multiline.
      #
      # - multiline: One line per import list entry.
      #   Type with constructor list acts like single import.
      #
      #   > import qualified Data.Map as M
      #   >     ( empty
      #   >     , singleton
      #   >     , ...
      #   >     , delete
      #   >     )
      #
      # Default: inline
      long_list_align: inline

      # Align empty list (importing instances)
      #
      # Empty list align has following options
      #
      # - inherit: inherit list_align setting
      #
      # - right_after: () is right after the module name:
      #
      #   > import Vector.Instances ()
      #
      # Default: inherit
      empty_list_align: inherit

      # List padding determines indentation of import list on lines after import.
      # This option affects 'long_list_align'.
      #
      # - <integer>: constant value
      #
      # - module_name: align under start of module name.
      #   Useful for 'file' and 'group' align settings.
      #
      # Default: 4
      list_padding: 4

      # Separate lists option affects formatting of import list for type
      # or class. The only difference is single space between type and list
      # of constructors, selectors and class functions.
      #
      # - true: There is single space between Foldable type and list of it's
      #   functions.
      #
      #   > import Data.Foldable (Foldable (fold, foldl, foldMap))
      #
      # - false: There is no space between Foldable type and list of it's
      #   functions.
      #
      #   > import Data.Foldable (Foldable(fold, foldl, foldMap))
      #
      # Default: true
      separate_lists: true

      # Space surround option affects formatting of import lists on a single
      # line. The only difference is single space after the initial
      # parenthesis and a single space before the terminal parenthesis.
      #
      # - true: There is single space associated with the enclosing
      #   parenthesis.
      #
      #   > import Data.Foo ( foo )
      #
      # - false: There is no space associated with the enclosing parenthesis
      #
      #   > import Data.Foo (foo)
      #
      # Default: false
      space_surround: false

  # Language pragmas
  - language_pragmas:
      # We can generate different styles of language pragma lists.
      #
      # - vertical: Vertical-spaced language pragmas, one per line.
      #
      # - compact: A more compact style.
      #
      # - compact_line: Similar to compact, but wrap each line with
      #   `{-#LANGUAGE #-}'.
      #
      # Default: vertical.
      style: vertical

      # Align affects alignment of closing pragma brackets.
      #
      # - true: Brackets are aligned in same column.
      #
      # - false: Brackets are not aligned together. There is only one space
      #   between actual import and closing bracket.
      #
      # Default: true
      align: true

      # stylish-haskell can detect redundancy of some language pragmas. If this
      # is set to true, it will remove those redundant pragmas. Default: true.
      remove_redundant: true

  # Replace tabs by spaces. This is disabled by default.
  # - tabs:
  #     # Number of spaces to use for each tab. Default: 8, as specified by the
  #     # Haskell report.
  #     spaces: 8

  # Remove trailing whitespace
  - trailing_whitespace: {}

  # Squash multiple spaces between the left and right hand sides of some
  # elements into single spaces. Basically, this undoes the effect of
  # simple_align but is a bit less conservative.
  # - squash: {}

# A common setting is the number of columns (parts of) code will be wrapped
# to. Different steps take this into account. Default: 80.
columns: 80

# By default, line endings are converted according to the OS. You can override
# preferred format here.
#
# - native: Native newline format. CRLF on Windows, LF on other OSes.
#
# - lf: Convert to LF ("\n").
#
# - crlf: Convert to CRLF ("\r\n").
#
# Default: native.
newline: native

# Sometimes, language extensions are specified in a cabal file or from the
# command line instead of using language pragmas in the file. stylish-haskell
# needs to be aware of these, so it can parse the file correctly.
#
# No language extensions are enabled by default.
language_extensions:
  - TemplateHaskell
  # - QuasiQuotes

# Attempt to find the cabal file in ancestors of the current directory, and
# parse options (currently only language extensions) from that.
#
# Default: true
cabal: true


================================================
FILE: .travis.yml
================================================
language: c

branches:
  only:
    - /^travis-.*/

git:
  depth: 3

cache:
  directories:
    - $HOME/.stack
    - $HOME/.cabal/packages
    - $HOME/.cabal/store
    - $HOME/.ghcup
    - $HOME/AppData/Local/Programs/stack
    - $HOME/AppData/Roaming/stack

addons:
  apt:
    packages:
      - libgmp-dev
  homebrew:
    # Workaround for "Unknown command: bundle", see: https://bit.ly/32d3V2d
    update: true

jobs:
  include:
    - os: linux
      env: EXEC=stack RESOLVER=lts-11
    - os: linux
      env: EXEC=stack RESOLVER=lts-12
    - os: linux
      env: EXEC=stack RESOLVER=lts-14
    - os: linux
      env: EXEC=stack RESOLVER=lts-16
    - os: linux
      env: EXEC=cabal GHC=8.10.2 FLAGS="-O0"
    - os: linux
      env: EXEC=cabal GHC=8.10.2 FLAGS="-O2"
    - os: osx
      env: EXEC=stack RESOLVER=lts-16
    - os: windows
      env: EXEC=stack RESOLVER=lts-14
  allow_failures:
    - os: windows
      env: EXEC=stack RESOLVER=lts-16

before_install:
  - . scripts/travis.sh

install:
  - travis_install

script:
  - travis_script

after_success:
  - travis_after_success

notification:
  email: false


================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct

## Our Pledge

We as members, contributors, and leaders pledge to make participation
in our community a harassment-free experience for everyone, regardless
of age, body size, visible or invisible disability, ethnicity, sex
characteristics, gender identity and expression, level of experience,
education, socio-economic status, nationality, personal appearance,
race, religion, or sexual identity and orientation.

We pledge to act and interact in ways that contribute to an open,
welcoming, diverse, inclusive, and healthy community.

## Our Standards

Examples of behavior that contributes to a positive environment for
our community include:

* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our
  mistakes, and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
  overall community

Examples of unacceptable behavior include:

* The use of sexualized language or imagery, and sexual attention or
  advances of any kind
* Trolling, insulting or derogatory comments, and personal or
  political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
  address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
  professional setting

## Enforcement Responsibilities

Community leaders are responsible for clarifying and enforcing our
standards of acceptable behavior and will take appropriate and fair
corrective action in response to any behavior that they deem
inappropriate, threatening, offensive, or harmful.

Community leaders have the right and responsibility to remove, edit,
or reject comments, commits, code, wiki edits, issues, and other
contributions that are not aligned to this Code of Conduct, and will
communicate reasons for moderation decisions when appropriate.

## Scope

This Code of Conduct applies within all community spaces, and also
applies when an individual is officially representing the community in
public spaces. Examples of representing our community include using an
official e-mail address, posting via an official social media account,
or acting as an appointed representative at an online or offline
event.

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior
may be reported to the community leaders responsible for enforcement
at [INSERT CONTACT METHOD]. All complaints will be reviewed and
investigated promptly and fairly.

All community leaders are obligated to respect the privacy and
security of the reporter of any incident.

## Enforcement Guidelines

Community leaders will follow these Community Impact Guidelines in
determining the consequences for any action they deem in violation of
this Code of Conduct:

### 1. Correction

**Community Impact**: Use of inappropriate language or other behavior
deemed unprofessional or unwelcome in the community.

**Consequence**: A private, written warning from community leaders,
providing clarity around the nature of the violation and an
explanation of why the behavior was inappropriate. A public apology
may be requested.

### 2. Warning

**Community Impact**: A violation through a single incident or series
of actions.

**Consequence**: A warning with consequences for continued
behavior. No interaction with the people involved, including
unsolicited interaction with those enforcing the Code of Conduct, for
a specified period of time. This includes avoiding interactions in
community spaces as well as external channels like social
media. Violating these terms may lead to a temporary or permanent ban.

### 3. Temporary Ban

**Community Impact**: A serious violation of community standards,
including sustained inappropriate behavior.

**Consequence**: A temporary ban from any sort of interaction or
public communication with the community for a specified period of
time. No public or private interaction with the people involved,
including unsolicited interaction with those enforcing the Code of
Conduct, is allowed during this period. Violating these terms may lead
to a permanent ban.

### 4. Permanent Ban

**Community Impact**: Demonstrating a pattern of violation of
community standards, including sustained inappropriate behavior,
harassment of an individual, or aggression toward or disparagement of
classes of individuals.

**Consequence**: A permanent ban from any sort of public interaction
within the community.

## Attribution

This Code of Conduct is adapted from the [Contributor
Covenant][homepage], version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.

Community Impact Guidelines were inspired by [Mozilla's code of
conduct enforcement ladder](https://github.com/mozilla/diversity).

[homepage]: https://www.contributor-covenant.org

For answers to common questions about this code of conduct, see the
FAQ at https://www.contributor-covenant.org/faq. Translations are
available at https://www.contributor-covenant.org/translations.


================================================
FILE: CONTRIBUTING.md
================================================
# Contributing

First of all, thanks for your interest in contributing to Finkel!

We want to make contributing to this project as easy and transparent
as possible, whether it's:

- Reporting a bug
- Discussing the current state of the code
- Submitting a fix
- Proposing new features
- Becoming a maintainer

Finkel is an open source project. Following these guidelines helps to
communicate that you respect the time of the developers managing and
developing this open source project. In return, they should
reciprocate that respect in addressing your issue, assessing changes,
and helping you finalize your pull requests.


## Code of Conduct

All members of our community are expected to follow our [Code of
Conduct][coc]. Please make sure you are welcoming and friendly in all
of our spaces.

[coc]: https://github.com/finkel-lang/finkel/blob/master/CODE_OF_CONDUCT.md


## Getting started with Finkel source

Please see the [Building And Installing][doc-install] section of the
documentation for detailed instruction. In short:

```
$ git clone https://github.com/finkel-lang/finkel
$ cd finkel
$ stack build
```

[doc-install]: https://finkel.readthedocs.io/en/latest/contents/install.html


## Issues

We use the [github issue tracker][ghissue] to manage issues. Please do
some searches in the existing issues before creating a new one. When
sending a bug report, please make sure that you are using the latest
version of Finkel built from the source.

[ghissue]: https://github.com/finkel-lang/finkel/issues


## Pull Requests

### Style guide / Coding conventions

We believe every one has its taste in coding style. However, the
following provides some suggestions:

- By default, all source codes are written with max 80 characters per
  line, but there are some exceptions, e.g. use of long string
  constants in URL.

- For Haskell source code, use 2 spaces for indentations. We use
  [hlint][hlint] and [stylish-haskell][stylish-haskell] with the
  configuration files in the repository root directory. It is totally
  fine to make changes to the configuration files, just please tell us
  why.

- For Finkel source code, not much to say at the moment, since the
  language is still young. However, try to follow the style used in
  the file when you modify the existing file.

- Please consider writing [a good Git commit message][gitcommit].

[hlint]: https://github.com/ndmitchell/hlint
[stylish-haskell]: https://github.com/jaspervdj/stylish-haskell
[gitcommit]: https://chris.beams.io/posts/git-commit/#seven-rules

### Running tests

Please make sure that the tests are passing with your modifications.
For example, to test with [stack][stack], run:

```
$ stack build --test
```

[stack]: https://docs.haskellstack.org/en/stable/README/

### Trivial changes

Small contributions such as fixing spelling errors, can be also
submitted by a contributor as a pull request.

As a rule of thumb, changes are obvious fixes if they do not introduce
any new functionality or creative thinking. As long as the change does
not affect functionality, some likely examples include the following:

- Spelling/grammar fixes
- Typo correction, white space and formatting changes
- Comment clean up
- Changes to *metadata* files like ``.gitignore``, etc.

### License

In short, when you submit code changes, your submissions are
understood to be under the same [BSD 3-clause License][bsd3] that
covers the project.

[bsd3]: https://choosealicense.com/licenses/bsd-3-clause/


================================================
FILE: LICENSE
================================================
Copyright 8c6794b6 (c) 2017-2020

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.

    * Redistributions in binary form must reproduce the above
      copyright notice, this list of conditions and the following
      disclaimer in the documentation and/or other materials provided
      with the distribution.

    * Neither the name of the copyright holder nor the names of other
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

================================================
FILE: README.md
================================================
# Finkel

[![CI status][ci-badge]][ci]
[![Documentation][doc-badge]][doc]
[![Codecov][codecov-badge]][codecov]

Finkel is a statically typed, purely functional, and non-strict-by-default
[LISP][lisp] flavored programming language.

Or in other words, **[Haskell][haskell] in S-expression**.


## Features

- Integration with existing Haskell modules.
- Building Haskell-compatible [Cabal][cabal] packages.
- Documentation generation with [Haddock][haddock].
- Lisp style macro system.
- Tool executable, including interactive REPL.

## Example

### Sample code

```clojure
;;;; File: fib.hs

(:doc "Simple example module to show fibonacci number.

The compiled executable takes an integer argument from command line
input and print the fibonacci number of the argument.")

(defmodule Main
  (import
   (System.Environment [getArgs])))

(defn (:: main (IO ()))
  "The main entry point function."
  (>>= getArgs (. print fib read head)))

(defn (:: fib (-> Int Int))
  "Naive fibonacci function."
  [0] 0
  [1] 1
  [n] (+ (fib (- n 1))
         (fib (- n 2))))
```

### Compiling an executable

```console
$ finkel make -o fib fib.hs
[1 of 1] Compiling Main             ( fib.hs, fib.o )
Linking fib
$ ./fib 10
55
```

### Running REPL

```console
$ finkel repl
Hit `Ctrl-d' or type ,q to quit, type ,? for help.
> ,load fib.hs
[1 of 1] Compiling Main             ( fib.hs, interpreted )
; loaded fib.hs
> ,info fib
fib :: Int -> Int       -- Defined at fib.hs:16:11
> (map fib [1 .. 10])
[1,1,2,3,5,8,13,21,34,55]
> (System.Environment.withArgs ["10"] main)
55
> ,q
```

## Further resources

See the [documentation][doc] for more details.


## Contributing

Contributions are welcome. Please see the [CONTRIBUTING.md][contrib].

[ci-badge]: https://img.shields.io/github/actions/workflow/status/finkel-lang/finkel/ci.yml?logo=github&label=ci
[ci]: https://github.com/finkel-lang/finkel/actions/workflows/ci.yml
[doc-badge]: http://readthedocs.org/projects/finkel/badge/?version=latest
[doc]: https://finkel.readthedocs.io/en/latest/
[codecov-badge]: https://codecov.io/gh/finkel-lang/finkel/branch/master/graph/badge.svg
[codecov]: https://codecov.io/gh/finkel-lang/finkel

[cabal]: https://www.haskell.org/cabal/
[contrib]: https://github.com/finkel-lang/finkel/blob/master/CONTRIBUTING.md
[haddock]: https://www.haskell.org/haddock/
[haskell]: https://haskell.org
[lisp]: https://en.wikipedia.org/wiki/Lisp_(programming_language)


================================================
FILE: cabal.project
================================================
packages:
  -- Main components
  finkel-kernel/
  fkc/
  fnkpp/
  finkel-setup/
  finkel-core/
  finkel-tool/
  finkel/

  -- For test
  doc/
  doc/include/building-package/my-first-package
  doc/include/building-package/my-second-package
  doc/include/building-package/my-new-package

tests: True
benchmarks: True
library-profiling: True

package finkel-kernel
  flags: +dev


================================================
FILE: default.nix
================================================
{
  nixpkgs ? <nixpkgs>,
  compiler ? "ghc8106"
}:

let
  pkgs = import ./nix/finkel-packages.nix {
    inherit compiler nixpkgs;
  };
in pkgs.finkelPackages


================================================
FILE: doc/LICENSE
================================================
Copyright 8c6794b6 (c) 2020-2022

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.

    * Redistributions in binary form must reproduce the above
      copyright notice, this list of conditions and the following
      disclaimer in the documentation and/or other materials provided
      with the distribution.

    * Neither the name of the copyright holder nor the names of other
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

================================================
FILE: doc/Makefile
================================================
# Minimal makefile for Sphinx documentation
#

# You can set these variables from the command line.
SPHINXOPTS    =
SPHINXBUILD   = sphinx-build
SOURCEDIR     = .
BUILDDIR      = _build

# Put it first so that "make" without argument is like "make help".
help:
	@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

.PHONY: help Makefile

# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option.  $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
	@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

================================================
FILE: doc/Setup.hs
================================================
import Distribution.Simple (defaultMain)
main = defaultMain


================================================
FILE: doc/conf.py
================================================
# -*- coding: utf-8 -*-
#
# Configuration file for the Sphinx documentation builder.
#
# This file does only contain a selection of the most common options. For a
# full list see the documentation:
# http://www.sphinx-doc.org/en/master/config

# -- Path setup --------------------------------------------------------------

# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
# import os
# import sys
# sys.path.insert(0, os.path.abspath('.'))


# -- Project information -----------------------------------------------------

project = 'Finkel'
copyright = '2019-2022, 8c6794b6'
author = '8c6794b6'

# The short X.Y version
version = ''
# The full version, including alpha/beta/rc tags
release = ''


# -- General configuration ---------------------------------------------------

# If your documentation needs a minimal Sphinx version, state it here.
#
# needs_sphinx = '1.0'

# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
]

# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']

# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
#
# source_suffix = ['.rst', '.md']
source_suffix = '.rst'

# The master toctree document.
master_doc = 'index'

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = 'en'

# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']

# The name of the Pygments (syntax highlighting) style to use.
# pygments_style = None
# pygments_style = 'colorful'
# pygments_style = 'default'
# pygments_style = 'emacs'
pygments_style = 'friendly'


# -- Options for HTML output -------------------------------------------------

# The theme to use for HTML and HTML Help pages.  See the documentation for
# a list of builtin themes.
#
html_theme = 'sphinx_rtd_theme'
# html_theme = 'alabaster'
# html_theme = 'furo'
# html_theme = 'sphinx_material'
# html_theme = 'pydata_sphinx_theme'
# html_theme = 'sphinx_book_theme'
# html_theme = 'sphinx_typlog_theme'
# html_theme = 'insipid'

# Theme options are theme-specific and customize the look and feel of a theme
# further.  For a list of options available for each theme, see the
# documentation.
#
html_theme_options = {}

# For 'alabaster' theme
# html_theme_options = {
#     'fixed_sidebar': True,
#     'show_relbars': True,
# }

# For 'rtd' theme
# html_theme_options = {
#     'display_version': True,
#     'prev_next_buttons_location': 'bottom',
#     'style_nav_header_background': '#2980b9',
# }

# For 'sphinx_material' theme
# html_theme_options = {
#     'base_url': 'http://finkel.readthedocs.io/',
#     'repo_url': 'https://github.com/finkel-lang/finkel/',
#     'repo_name': 'Finkel',
#     # 'google_analytics_account': 'UA-XXXXX',
#     # 'html_minify': True,
#     # 'css_minify': True,
#     # 'nav_title': 'The Finkel Documentation',
#     # 'logo_icon': '&#xe869',
#     # 'logo_icon': '&#xe91d',
#     'logo_icon': '&#xe86f',
#     'globaltoc_depth': 1,
#     'globaltoc_collapse': True,
#     'color_primary': 'teal',
# }

# For furo
# html_theme_options = {
#     "light_css_variables": {
#         "font-stack": "Arial, sans-serif",
#         "font-stack--monospace": "Courier, monospace",
#     },
# }

# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']

# Custom sidebar templates, must be a dictionary that maps document names
# to template names.
#
# The default sidebars (for documents that don't match any pattern) are
# defined by theme itself.  Builtin themes are using these templates by
# default: ``['localtoc.html', 'relations.html', 'sourcelink.html',
# 'searchbox.html']``.
#
# html_sidebars = {}

# html_sidebars = {
#     "**": [
#         "globaltoc.html",
#         "localtoc.html",
#         "searchbox.html",
#     ]
# }

# For material
# html_sidebars = {
#     "**": [
#         "logo-text.html",
#         "globaltoc.html",
#         "localtoc.html",
#         "searchbox.html",
#     ]
# }



# -- Options for HTMLHelp output ---------------------------------------------

# Output file base name for HTML help builder.
htmlhelp_basename = 'Finkeldoc'


# -- Options for LaTeX output ------------------------------------------------

latex_elements = {
    # The paper size ('letterpaper' or 'a4paper').
    #
    # 'papersize': 'letterpaper',

    # The font size ('10pt', '11pt' or '12pt').
    #
    # 'pointsize': '10pt',

    # Additional stuff for the LaTeX preamble.
    #
    # 'preamble': '',

    # Latex figure (float) alignment
    #
    # 'figure_align': 'htbp',
}

# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
#  author, documentclass [howto, manual, or own class]).
latex_documents = [
    (master_doc, 'Finkel.tex', 'Finkel Documentation',
     '8c6794b6', 'manual'),
]


# -- Options for manual page output ------------------------------------------

# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
    (master_doc, 'finkel', 'Finkel Documentation',
     [author], 1)
]


# -- Options for Texinfo output ----------------------------------------------

# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
#  dir menu entry, description, category)
texinfo_documents = [
    (master_doc, 'Finkel', 'Finkel Documentation',
     author, 'Finkel', 'Lisp Flavored Haskell',
     'Miscellaneous'),
]


# -- Options for Epub output -------------------------------------------------

# Bibliographic Dublin Core info.
epub_title = project

# The unique identifier of the text. This can be a ISBN number
# or the project homepage.
#
# epub_identifier = ''

# A unique identification for the text.
#
# epub_uid = ''

# A list of files that should not be packed into the epub file.
epub_exclude_files = ['search.html']


# -- Custom setup function

from pygments.lexer import RegexLexer, bygroups
from pygments import token
from pygments.token import Text, Comment, Number, String, Keyword, \
    Name, Operator, Punctuation
from pygments import unistring as uni
from sphinx.highlighting import lexers

import re

class FinkelLexer(RegexLexer):
    name = 'finkel'
    reserved = (
        # Haskell 2010
        'case', 'class', 'data', 'default', 'deriving', 'do',
        'family', 'if', 'infix', 'infixl', 'infixr', 'instance', 'let',
        'newtype', 'type', 'where',
        '_', '=', '=>', '<-', '->', '::',

        # Finkel kernel special forms
        ':begin', ':eval-when-compile', ':quote', ':quasiquote',
        ':unquote', ':unquote-splice',

        # Finkel core
        'eval-when', 'macrolet',
    )

    ascii = ('NUL', 'SOH', '[SE]TX', 'EOT', 'ENQ', 'ACK',
             'BEL', 'BS', 'HT', 'LF', 'VT', 'FF', 'CR', 'S[OI]', 'DLE',
             'DC[1-4]', 'NAK', 'SYN', 'ETB', 'CAN',
             'EM', 'SUB', 'ESC', '[FGRU]S', 'SP', 'DEL')

    tokens = {
        'root': [
            # Whitespace:
            (r'\s+', Text),

            # Pragma:
            (r'%p\(.*', token.Comment),

            # Comment:
            (r'{-', Comment.Multiline, 'multiline-comment'),
            (r';.*', Comment.Single),
            (r'%_', Comment.Single),

            # Numbers
            (r'-?\d+\.\d+', Number.Float),
            (r'-?\d(_*\d)*_*[eE][+-]?\d(_*\d)*', Number.Float),
            (r'0[oO]_*[0-7](_*[0-7])*', Number.Oct),
            (r'0[xX]_*[\da-fA-F](_*[\da-fA-F])*', Number.Hex),
            (r'-?\d+', Number.Integer),

            # Characters:
            (r"#'", String.Char, 'character'),

            # String literal
            (r'"', String, 'string'),

            # Core macros
            (r"(defn)(\s+\(?)(::)?(\s+)?([^\s]+)",
             bygroups(Keyword.Reserved, Text, Keyword.Reserved,
                      Text, Name.Function)),

            (r"(defmacro)(\s+)([^\s]+)",
             bygroups(Keyword.Reserved, Text, Name.Function)),

            (r"(defmodule)(\s+)([A-Z]\w+)",
             bygroups(Keyword.Reserved, Text, Name.Namespace),
             'defmodule'),

            # Module header
            (r"(module)(\s+)([^\s]+)",
             bygroups(Keyword.Reserved, Text, Name.Namespace)),

            # Macro specific keywords
            (r':compile', String),
            (r':load', String),

            # Keywords
            ('(%s)' % '|'.join(re.escape(e) + ' ' for e in reserved),
             Keyword.Reserved),

            # Import
            (r'(import|:require)(\s+)(qualified)?(\s+)?([A-Z][\w\.]+)(\s+)?(as|hiding)?',
             bygroups(Keyword.Reserved,
                      Text,
                      Keyword.Reserved,
                      Text,
                      Name.Namespace,
                      Text,
                      Keyword.Reserved),
             'funclist'),

            # Types
            (r'([A-Z][0-9a-zA-Z\-_]*)', Keyword.Type),

            # Operators
            (r'([!@$%^&*-=+?/<>\|~]+)', Operator),
            (r'(,@|,)', Operator),

            # Variable identifier
            (r'[_a-z][\w\']*', Name),

            # Lambda
            (r'\\', Keyword.Reserved),

            # Puctuation
            (r'(\(|\))', Punctuation),
            (r'(\[|\])', Punctuation),
            (r'(\{|\})', Punctuation),
            (r'`', Punctuation),
            (r"'", Punctuation),
        ],

        'character': [
            (r"[^\\]", String.Char, '#pop'),
            (r"\\", String.Escape, 'escape'),
            (r" ", String.Char, '#pop'),
        ],

        'string': [
            (r'[^\\"]+', String),
            (r"\\", String.Escape, 'escape'),
            ('"', String, '#pop'),
        ],

        'escape': [
            (r'[abfnrtv"\'&\\]', String.Escape, '#pop'),
            (r'\^[][' + uni.Lu + r'@^_]', String.Escape, '#pop'),
            ('|'.join(ascii), String.Escape, '#pop'),
            (r'o[0-7]+', String.Escape, '#pop'),
            (r'x[\da-fA-F]+', String.Escape, '#pop'),
            (r'\d+', String.Escape, '#pop'),
            (r'\s+\\', String.Escape, '#pop'),
            (r'', String.Escape, '#pop'),
        ],

        'defmodule': [
            (r'\s+', Text),
            (r'export', Keyword.Reserved, 'funclist'),
            (r'(import-when)(\s+)(\[)(:compile|:load)+(\])(\s+)',
             bygroups(Keyword.Reserved, Text, Punctuation,
                      String, Punctuation, Text),
             'import-body'),
            (r'import', Keyword.Reserved, 'import-body'),
            (r'require', Keyword.Reserved, 'import-body'),
            (r'\(', Punctuation, '#push'),
            (r'\)', Punctuation, '#pop'),
            (r'', Text, '#pop'),
        ],

        'import-body': [
            (r'\s+', Text),
            (r'(as|hiding)', Keyword.Reserved),
            (r'[A-Za-z_.]+', Name.Namespace, 'funclist'),
            (r'\(', Punctuation, '#push'),
            (r'\)', Punctuation, '#pop'),
            (r'', Text, '#pop'),
        ],

        'funclist': [
            (r'\s+', Text),
            (r'(_[\w\']+|[' + uni.Ll + r'][\w\'-]*)', Name.Function),
            (r'\(', Punctuation, '#push'),
            (r'\)', Punctuation, '#pop'),
            (r'', Text, '#pop'),
        ],

        'multiline-comment': [
            (r'{-', Comment.Multiline, '#push'),
            (r'-}', Comment.Multiline, '#pop'),
            (r'[^-}]+', Comment.Multiline),
            (r'[-}]', Comment.Multiline),
        ]
    }

def setup(sphinx):
    sphinx.add_lexer("finkel", FinkelLexer)


================================================
FILE: doc/contents/building-package.rst
================================================
Building Cabal Package
======================

To build a cabal package with Finkel, make a cabal configuration file as in the
Haskell cabal package, but with some build tool and package dependencies.

.. note::

   This documentation assumes the readers are using the `stack
   <https://docs.haskellstack.org/en/stable/README/>`_ build tool for
   building cabal packages. Those who prefer other tools such as
   `cabal-install <http://hackage.haskell.org/package/cabal-install>`_
   may translate the invoked commands and modify the file contents as
   necessary.


Building My First Package
-------------------------

Make a directory named ``my-first-package``, and create a file named
``package.yaml`` under the directory with following
contents:

.. literalinclude:: ../include/building-package/my-first-package/package.yaml
   :language: yaml

And a simple ``Setup.hs`` script:

.. literalinclude:: ../include/building-package/my-first-package/Setup.hs
   :language: haskell

And a Finkel source code ``src/MyFirstPackage.hs`` for exposed
module:

.. literalinclude:: ../include/building-package/my-first-package/src/MyFirstPackage.hs
   :language: finkel

And a ``stack.yaml``:

.. literalinclude:: ../include/building-package/my-first-package/stack.template.yaml
   :language: yaml

At this point the files under the ``my-first-project`` directory
should look like below:

::

   my-first-package
   ├── package.yaml
   ├── Setup.hs
   ├── src
   │   └── MyFirstPackage.hs
   └── stack.yaml

Now one can build the ``my-first-package`` package with ``stack``:

.. code-block:: console

   $ stack build my-first-package
   ... Output messages omitted ...
   [1 of 2] Compiling Main
   [2 of 2] Compiling StacksetupShim
   ... More output messages ...
   [1 of 1] Compiling MyFirstPackage

.. tip::

   To build a package containing Finkel source codes with the latest
   ``finkel`` built from source, one can specify the packages from
   `finkel git repository <https://github.com/finkel-lang/finkel>`_ as
   extra dependencies.

   For example, the following ``stack.yaml`` is set to build a package
   in the current directory with ``finkel`` from the git repository:

   .. literalinclude:: ../include/building-package/my-first-package/stack.git.yaml
      :language: yaml

   See the `stack documentation
   <https://docs.haskellstack.org/en/stable/yaml_configuration/#extra-deps>`_
   and the `Cabal User Guide
   <https://cabal.readthedocs.io/en/3.4/cabal-project.html#specifying-packages-from-remote-version-control-locations>`_
   for more information about using remote git repository for extra
   dependencies.


Mixing Finkel And Haskell Source Codes
--------------------------------------

One can mix Finkel source codes and Haskell source codes in a package.
This time, making a package ``my-second-package`` with ``stack new``
command using Finkel specific template:

.. code-block:: console

   $ stack new my-second-package https://raw.githubusercontent.com/finkel-lang/finkel/master/finkel-tool/finkel.hsfiles

.. warning::

   At the time of writing, one may encounter messages similar to the
   following when running ``stack new`` with the above template:

   .. code-block:: console

      Selecting the best among 17 snapshots...

      * Partially matches lts-15.7
          finkel-setup not found
              - my-second-pkg requires -any

      * Partially matches nightly-2020-03-04
          finkel-setup not found
              - my-second-pkg requires -any

      ...

      Selected resolver: lts-15.7
      Resolver 'lts-15.7' does not have all the packages to match your requirements.
          finkel-setup not found
              - my-second-pkg requires -any

      This may be resolved by:
          - Using '--omit-packages' to exclude mismatching package(s).
          - Using '--resolver' to specify a matching snapshot/resolver

   This is because the packages for ``finkel`` is not yet uploaded to
   `stackage <https://stackage.org>`_.

   As the message indicates, one can pass ``--omit-packages`` option
   or ``--resolver`` option to ``stack new`` until the ``finkel``
   dependency packages are uploaded to the upstream, and add the git
   repository to ``stack.yaml``.

The above command will make a directory named ``my-second-package``
with a cabal configuration file, ``Setup.hs`` script, and a stub
Finkel source code file. Directory contents of ``my-second-package``
should look like below:

::

   my-second-package
   ├── app
   │  └── Main.hs
   ├── LICENSE
   ├── my-second-package.cabal
   ├── README.md
   ├── Setup.hs
   ├── src
   │  └── Lib.hs
   └── test
      └── Spec.hs


Add a new file named ``my-second-package/src/FnkCodes.hs``, with
Finkel source codes:

.. literalinclude:: ../include/building-package/my-second-package/src/FnkCodes.hs
   :language: finkel

And another new file named ``my-second-package/src/HsCodes.hs``, with
Haskell source codes:

.. literalinclude:: ../include/building-package/my-second-package/src/HsCodes.hs
   :language: haskell

Modify the ``library`` stanza of the file ``my-second-package.cabal``
and add ``HsCodes`` and ``FnkCodes`` modules as shown below:

.. literalinclude:: ../include/building-package/my-second-package/my-second-package.cabal
   :lines: 22-29

The functions exported from ``HsCodes`` module could be used from
``Lib`` module, as in compilation of cabal package without Finkel
codes. Modify the file ``my-second-package/src/Lib.hs`` to import
``hsfactorial`` and ``fnkfactorial`` functions from ``HsCodes``:

.. literalinclude:: ../include/building-package/my-second-package/src/Lib.hs
  :language: finkel

One can build the ``my-second-package`` with ``stack build`` command, as
before:

.. code-block:: console

   $ stack build my-second-package

.. note::

   It is also possible to use a library package containing Finkel code
   from other Haskell packages as a build dependency since the
   resulting object codes are compiled by compatible ``ghc`` version.


Executable, Test, Coverage, And Haddock
---------------------------------------

The ``my-second-package`` cabal package contains an executable named
``my-second-package``. The executable simply invokes the
``Lib.someFunc`` function. To compile and run the executable:

.. code-block:: console

   $ stack run my-second-package:my-second-package
   From `Lib.someFunc':
     hsfactorial 10  : 3628800
     fnkfactorial 10 : 3628800

To run tests, invoke ``stack test`` or ``stack build --test``:

.. code-block:: console

   $ stack build --test my-second-package

To generate code coverage report, add ``--coverage`` option when running
test:

.. code-block:: console

   $ stack build --test --coverage my-second-package

And, to generate haddock documentation of the package, add ``--haddock``
option to ``stack build`` command:

.. code-block:: console

   $ stack build --haddock my-second-package


================================================
FILE: doc/contents/finkel-executable.rst
================================================
Using The Finkel Executable
===========================

The ``finkel`` executable from the ``finkel`` package contains
sub-commands to work with Finkel source codes.


Compiling with Finkel Make
--------------------------

To compile a Finkel source code file, one can use the ``make``
sub-command. Open a file named ``hello.hs`` with your favorite editor
and save the file with the following contents:

.. literalinclude:: ../include/finkel-executable/hello.hs
   :language: finkel

Then invoke ``finkel make`` to compile the file. The command shown in
the following line will compile the file as an executable named ``hello``:

.. literalinclude:: ../include/finkel-executable/hello.console
   :language: console

The ``make`` sub-command understands most of the options for the
``ghc`` executable ``--make`` mode:

.. literalinclude:: ../include/finkel-executable/hello-prof.console
   :language: console

The compiled executable understands RTS options:

.. code-block:: console

   $ ./hello +RTS -s -p
   Hello, World!
             56,992 bytes allocated in the heap
              4,864 bytes copied during GC
             46,040 bytes maximum residency (1 sample(s))
             23,592 bytes maximum slop
                  0 MB total memory in use (0 MB lost due to fragmentation)

                                        Tot time (elapsed)  Avg pause  Max pause
     Gen  0         0 colls,     0 par    0.000s   0.000s     0.0000s    0.0000s
     Gen  1         1 colls,     0 par    0.000s   0.000s     0.0001s    0.0001s

     INIT    time    0.000s  (  0.000s elapsed)
     MUT     time    0.000s  (  0.000s elapsed)
     GC      time    0.000s  (  0.000s elapsed)
     RP      time    0.000s  (  0.000s elapsed)
     PROF    time    0.000s  (  0.000s elapsed)
     EXIT    time    0.000s  (  0.000s elapsed)
     Total   time    0.000s  (  0.001s elapsed)

     %GC     time       0.0%  (0.0% elapsed)

     Alloc rate    0 bytes per MUT second

     Productivity 100.0% of total user, 22.7% of total elapsed


Running REPL
------------

From shell
^^^^^^^^^^

The ``finkel`` executable has ``repl`` sub-command to run an interactive
*read-eval-print-loop* (a.k.a. REPL). To start a REPL from a shell,
invoke ``finkel repl``:

.. code-block:: console

   $ finkel repl
   Hit `Ctrl-d' or type ,q to quit, type ,? for help.
   > (+ 41 1)
   42
   > ,type foldr
   foldr :: Foldable t => (a -> b -> b) -> b -> t a -> b
   > ,info Rational
   type Rational = GHC.Real.Ratio Integer  -- Defined in ‘GHC.Real’
   > ,load hello.hs
   [1 of 1] Compiling Main             ( hello.hs, interpreted )
   ; loaded hello.hs
   > main
   Hello, World!
   > ,q


From Emacs
^^^^^^^^^^

There is a major mode named ``finkel-mode`` for the `Emacs
<https://www.gnu.org/software/emacs/>`_ editor, with functionality to
run an interactive REPL session from Emacs.  See the README file in
the `finkel-mode repository
<https://github.com/finkel-lang/finkel-mode/#finkel-mode>`_ for more
details.


Getting More Help
-----------------

The ``finkel`` executable contains a ``help`` sub-command to show
brief usages of available commands:

.. literalinclude:: ../include/finkel-executable/finkel-help-make.console
   :language: console


================================================
FILE: doc/contents/install.rst
================================================
Building And Installing
=======================

.. note::

   At the time of writing, Finkel related packages are not yet uploaded to
   `hackage <https://hackage.haskell.org>`_ and `stackage
   <https://stackage.org>`_.


Container Image
---------------

There is a container image with the ``finkel`` executable built from the latest
source code with accompanying Haskell libraries and some development tools. The
main use case of the container image is to play with ``finkel`` without setting
up a working Haskell environment. For instance, one can run ``finkel`` with
``docker`` by followings:

.. code-block:: console

   $ docker pull ghcr.io/finkel-lang/finkel:latest
   $ docker run --rm -it ghcr.io/finkel-lang/finkel:latest
   / # finkel eval '(putStrLn "Hello, Finkel!")'
   Hello, Finkel!

See the `GitHub package page
<https://github.com/orgs/finkel-lang/packages/container/package/finkel>`_ for
more info.


Building From Source
--------------------

Getting The Latest Source
^^^^^^^^^^^^^^^^^^^^^^^^^

Clone the Finkel repository with ``git``:

.. code-block:: console

   $ git clone https://github.com/finkel-lang/finkel.git


Building With ``stack``
^^^^^^^^^^^^^^^^^^^^^^^

One can use ``stack`` to build the packages. To build and test with
``stack``:

.. code-block:: console

   $ cd finkel
   $ stack build --test

And to install the ``finkel`` executable:

.. code-block:: console

   $ stack build --copy-bins finkel


Building With ``cabal-install``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. note::

   As of ``cabal-install`` version 3.4.0.0, installing with ``cabal
   v2-install`` does not work. This is `a known issue
   <https://github.com/haskell/cabal/issues/6124>`_ related to the
   file extension used by Finkel. To install with ``cabal-install``,
   use the ``cabal v1-install`` command or the ``setup`` executable
   built under the ``dist-newstyle`` directory.

To build and test with ``cabal-install``:

.. code-block:: console

   $ cd finkel
   $ cabal v2-build all
   $ cabal v2-test all


Building With ``nix``
^^^^^^^^^^^^^^^^^^^^^

The git repository contains ``default.nix`` file. Building and testing with `nix
<https://nixos.org/>`_ could be done with:

.. code-block:: console

   $ nix-build


================================================
FILE: doc/contents/language-syntax.rst
================================================
Language Syntax
===============

The Finkel language is made from Finkel kernel keywords and Finkel
core keywords.

The Finkel kernel keywords are designed to be compatible with `Haskell
2010 <https://www.haskell.org/onlinereport/haskell2010/>`_, with few
exceptions.  The syntax for literal values and function applications
are also defined in the Finkel kernel.  The rest of this section will
go through the Finkel kernel language syntax with small example
codes. Each Finkel code is compared to an equivalent Haskell code.

The Finkel core keywords are implemented as macros.  Details of the
Finkel core keywords are described in the `haddock API documentation
<https://hackage.haskell.org>`_ of the ``finkel-core`` package.


Literals
--------

Comments
^^^^^^^^

Line contents after ``;`` are treated as comments.

.. literalinclude:: ../include/language-syntax/expr/line-comment.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/expr/line-comment.hs
   :language: haskell

Block style comment is supported with ``{-`` and ``-}``.

.. literalinclude:: ../include/language-syntax/expr/block-comment.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/expr/block-comment.hs
   :language: haskell

Form after ``%_`` is ignored:

.. literalinclude:: ../include/language-syntax/expr/discard-prefix.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/expr/discard-prefix.hs
   :language: haskell


Variable identifier
^^^^^^^^^^^^^^^^^^^

Finkel accepts valid variable identifiers defined in Haskell 2010, and
variable identifiers containing hyphens which starting with a
non-operator character. Hyphens in variable identifiers are internally
converted to underscores. For instance, ``foo-bar-buzz`` will be
converted to ``foo_bar_buzz``:

.. literalinclude:: ../include/language-syntax/expr/varid.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/expr/varid.hs
   :language: haskell

The hyphen conversion will be triggered only when the first letter of a
variable identifier was a non-operator character. Operators like
``-:-``, ``*+-``, ``$-$``, etc are kept as-is.


Numeric
^^^^^^^

As described in the `Numeric Literals
<https://www.haskell.org/onlinereport/haskell2010/haskellch2.html#x7-190002.5>`_
section of the Haskell 2010 report, decimal, octal, hexadecimal
integers and float with exponent are supported.

.. literalinclude:: ../include/language-syntax/expr/numeric.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/expr/numeric.hs
   :language: haskell


Character And String
^^^^^^^^^^^^^^^^^^^^

A character literal in Finkel starts with ``#'`` instead of
surrounding with single quotes. Other than that, Finkel mostly follows
the `Characters and String Literals
<https://www.haskell.org/onlinereport/haskell2010/haskellch2.html#x7-200002.6>`_
section in the Haskell 2010 report.

Following code prints single lower case character ``a``:

.. literalinclude:: ../include/language-syntax/expr/char-a.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/expr/char-a.hs
   :language: haskell

Following code prints backslash and single quote:

.. literalinclude:: ../include/language-syntax/expr/char-escape.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/expr/char-escape.hs
   :language: haskell

Some characters like newline, space, NUL, etc. are expressed with
escape character and specific character sequences.

.. literalinclude:: ../include/language-syntax/expr/char-special.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/expr/char-special.hs
   :language: haskell

Characters could be expressed with their numeric code in decimal, octal,
and hexadecimal:

.. literalinclude:: ../include/language-syntax/expr/char-ncode.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/expr/char-ncode.hs
   :language: haskell

String literals are written between double-quotes. Special characters are
escaped with ``\``. Finkel also supports the **gap** feature, to ignore the
string contents between two backslashes.

.. literalinclude:: ../include/language-syntax/expr/string.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/expr/string.hs
   :language: haskell


Expressions
-----------

Function Applications
^^^^^^^^^^^^^^^^^^^^^

Function application in Finkel is done with parentheses:

.. literalinclude:: ../include/language-syntax/expr/funapp.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/expr/funapp.hs
   :language: haskell

Unlike some other lisps, extra parentheses are ignored. For instance:

.. literalinclude:: ../include/language-syntax/expr/funapp-pars.fnk
   :language: finkel

is simplified to:

.. literalinclude:: ../include/language-syntax/expr/funapp-pars.hs
   :language: haskell


Operator Applications
^^^^^^^^^^^^^^^^^^^^^

Finkel does not have native support for infix operator
applications. However, a form applying operator function will be
expanded to a form taking all of its arguments, with two operands for
each. For example, adding numbers from 1 to 5 could be written as:

.. literalinclude:: ../include/language-syntax/expr/opexp-add.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/expr/opexp-add.hs
   :language: haskell

Operator expansion understands right and left associativity. Operator
precedence in Finkel is explicitly specified with parentheses.

.. literalinclude:: ../include/language-syntax/expr/opexp-app.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/expr/opexp-app.hs
   :language: haskell

The compiler treats the above expression as:

.. code-block:: haskell

  ((pure foldr <*> Just (+)) <*> pure 1) <*> pure [2, 3] -- Haskell

because the ``<*>`` operator is left-associative.

When a single argument has been passed to operator function, the resulting
expression is partial application:

.. literalinclude:: ../include/language-syntax/expr/map-mul2.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/expr/map-mul2.hs
   :language: haskell

To apply more than two arguments to an operator function, one needs to
explicitly surround the operator with parenthesis. Suppose that there
is an operator function ``*+`` which takes three arguments:

.. literalinclude:: ../include/language-syntax/expr/muladd.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/expr/muladd.hs
   :language: haskell


Unary Operator Application
^^^^^^^^^^^^^^^^^^^^^^^^^^

The operator ``-`` is always treated as a binary operator in
Finkel. In below Finkel example, ``(- 1)`` is a partially applied
function:

.. literalinclude:: ../include/language-syntax/expr/map-unary.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/expr/map-unary.hs
   :language: haskell


Lambda
^^^^^^

Lambda expression starts with ``\``. The last form in the lambda expression the
body expression of entire lambda abstraction, others forms are argument
patterns:

.. literalinclude:: ../include/language-syntax/expr/lambda.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/expr/lambda.hs
   :language: haskell


Conditionals
^^^^^^^^^^^^

An ``if`` expression does not take ``then`` and ``else``:

.. literalinclude:: ../include/language-syntax/expr/if.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/expr/if.hs
   :language: haskell

A guard starts with ``|``, and supports pattern, local declaration,
and boolean:

.. literalinclude:: ../include/language-syntax/expr/guard.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/expr/guard.hs
   :language: haskell

See also `cond <https://hackage.haskell.org>`_ in ``finkel-core``.


Tuples
^^^^^^

Tuple constructor expression uses single comma. At least one space
after the comma is required:

.. literalinclude:: ../include/language-syntax/expr/tup2.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/expr/tup2.hs
   :language: haskell

Single comma works for tuples with more than two elements:

.. literalinclude:: ../include/language-syntax/expr/tup5.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/expr/tup5.hs
   :language: haskell

To express tuple data and type constructor, use consecutive commas
without spaces:

.. literalinclude:: ../include/language-syntax/expr/tupfn.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/expr/tupfn.hs
   :language: haskell


Unit
^^^^

Unit is expressed with empty parentheses:

.. literalinclude:: ../include/language-syntax/expr/unit.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/expr/unit.hs
   :language: haskell

See also `nil <https://hackage.haskell.org>`_ to express an empty form.


Lists
^^^^^

List expression does not take commas:

.. literalinclude:: ../include/language-syntax/expr/list-const.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/expr/list-const.hs
   :language: haskell

Arithmetic sequences use ``..``. Space on each side of ``..`` are
required:

.. literalinclude:: ../include/language-syntax/expr/list-range.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/expr/list-range.hs
   :language: haskell

List comprehensions use ``|`` to separate the resulting expression.
Space between ``|`` and the result is required.

.. literalinclude:: ../include/language-syntax/expr/list-comp.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/expr/list-comp.hs
   :language: haskell


Let
^^^

A let expression is expressed with ``let`` without ``in``:

.. literalinclude:: ../include/language-syntax/expr/let.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/expr/let.hs
   :language: haskell


Case
^^^^

A case expression is expressed with ``case`` without ``of`` and ``->``:

.. literalinclude:: ../include/language-syntax/expr/case.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/expr/case.hs
   :language: haskell


Do
^^^

Do expression is expressed with ``do``, and bindings inside do-expressions are
expressed with ``<-``:

.. literalinclude:: ../include/language-syntax/expr/do.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/expr/do.hs
   :language: haskell


Datatypes with field labels
^^^^^^^^^^^^^^^^^^^^^^^^^^^

Field labels are enclosed with ``{`` and ``}``:

.. literalinclude:: ../include/language-syntax/expr/fieldlabels.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/expr/fieldlabels.hs
   :language: haskell


Expression Type-Signatures
^^^^^^^^^^^^^^^^^^^^^^^^^^

Type signature uses ``::``:

.. literalinclude:: ../include/language-syntax/expr/sige.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/expr/sige.hs
   :language: haskell


Pattern Matching
^^^^^^^^^^^^^^^^

A non-variable pattern requires parentheses, as in ``Just`` shown
below:

.. literalinclude:: ../include/language-syntax/expr/pat-maybe.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/expr/pat-maybe.hs
   :language: haskell


As pattern
""""""""""

As pattern uses ``@``:

.. literalinclude:: ../include/language-syntax/expr/pat-as.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/expr/pat-as.hs
   :language: haskell


Irrefutable pattern
"""""""""""""""""""

Irrefutable patterns are expressed with ``~``:

.. literalinclude:: ../include/language-syntax/expr/pat-irf.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/expr/pat-irf.hs
   :language: haskell


Operator expansion
""""""""""""""""""

The Operator expansion rule applies to patterns. For instance, the
``:`` constructor for a list is expanded with its pattern arguments:

.. literalinclude:: ../include/language-syntax/expr/pat-opexp.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/expr/pat-opexp.hs
   :language: haskell


Declarations And Bindings
-------------------------

Algebraic Datatype
^^^^^^^^^^^^^^^^^^

Algebraic datatype declaration uses ``data``. It does not use ``=``
and ``|``. Optional ``deriving`` form may appear at the last element
of the ``data`` form:

.. literalinclude:: ../include/language-syntax/decl/data-d1.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/decl/data-d1.hs
   :language: haskell

Constructor with labeled fields are supported with ``{`` and ``}``:

.. literalinclude:: ../include/language-syntax/decl/data-d2.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/decl/data-d2.hs
   :language: haskell


Type Synonym
^^^^^^^^^^^^

Type synonym declaration uses ``type``. It does not use ``=``:

.. literalinclude:: ../include/language-syntax/decl/tysym.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/decl/tysym.hs
   :language: haskell


Datatype Renamings
^^^^^^^^^^^^^^^^^^

Newtype declaration uses ``newtype``:

.. literalinclude:: ../include/language-syntax/decl/newtype.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/decl/newtype.hs
   :language: haskell


Class
^^^^^

Type class declaration uses ``class``:

.. literalinclude:: ../include/language-syntax/decl/class.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/decl/class.hs
   :language: haskell

Class instance declaration uses ``instance``:

.. literalinclude:: ../include/language-syntax/decl/instance.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/decl/instance.hs
   :language: haskell


Defaults for Overloaded Numeric Operations
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Default declaration is done with ``default``:

.. literalinclude:: ../include/language-syntax/decl/default.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/decl/default.hs
   :language: haskell


Type Signatures
^^^^^^^^^^^^^^^

Type signature uses ``::``:

.. literalinclude:: ../include/language-syntax/decl/tysig-one.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/decl/tysig-one.hs
   :language: haskell

Single type signature could be used for multiple variables:

.. literalinclude:: ../include/language-syntax/decl/tysig-many.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/decl/tysig-many.hs
   :language: haskell

Constraints in type signature are expressed with ``=>``. The last
element of the form ``=>`` should be a type:

.. literalinclude:: ../include/language-syntax/decl/tysig-constraints.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/decl/tysig-constraints.hs
   :language: haskell


Fixity
^^^^^^

It is possible to declare fixity and precedence with ``infix``, ``infixl``, and
``infixr``. Assuming ``$+$`` as a binary operator:

.. literalinclude:: ../include/language-syntax/decl/fixity.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/decl/fixity.hs
   :language: haskell

Note that Finkel syntax is affected by the left and right
associativity of operators, but not by the precedence of operators.


Bindings
^^^^^^^^

Function binding declaration uses ``=``. The form after ``=`` is the
function name, the last form is the expression body. Rest of the forms
are argument patterns:

.. literalinclude:: ../include/language-syntax/decl/bind-simpl.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/decl/bind-simpl.hs
   :language: haskell

Keyword ``where`` can appear in the right-hand side:

.. literalinclude:: ../include/language-syntax/decl/bind-where.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/decl/bind-where.hs
   :language: haskell

Pattern bindings are similarly done with ``=``:

.. literalinclude:: ../include/language-syntax/decl/bind-pat.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/decl/bind-pat.hs
   :language: haskell


Modules
-------

Top-level module definition does not use ``where``:

.. literalinclude:: ../include/language-syntax/module/simpl.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/module/simpl.hs
   :language: haskell

See also `defmodule <https://hackage.haskell.org>`_ in
``finkel-core``.


Export Lists
^^^^^^^^^^^^

Module definition can contain an explicit export list. Entities in the
export list can contain bindings, type and data constructors, type
classes, and modules:

.. literalinclude:: ../include/language-syntax/module/export-list.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/module/export-list.hs
   :language: haskell


Import Declarations
^^^^^^^^^^^^^^^^^^^

Module import declarations use ``import``:

.. literalinclude:: ../include/language-syntax/import/simpl.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/import/simpl.hs
   :language: haskell

Qualified import declarations use ``qualified`` and optional ``as``:

.. literalinclude:: ../include/language-syntax/import/qualified-as.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/import/qualified-as.hs
   :language: haskell

Entity lists use list:

.. literalinclude:: ../include/language-syntax/import/entity-list.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/import/entity-list.hs
   :language: haskell

Hiding specified entities with ``hiding``. Form after ``hiding`` is a
list of entity names to hide:

.. literalinclude:: ../include/language-syntax/import/hiding.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/import/hiding.hs
   :language: haskell

Altogether:

.. literalinclude:: ../include/language-syntax/import/altogether.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/import/altogether.hs
   :language: haskell


Foreign Function Interfaces
---------------------------

Foreign Import
^^^^^^^^^^^^^^

Foreign import declarations start with ``foreign`` ``import``:

.. literalinclude:: ../include/language-syntax/ffi/import.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/ffi/import.hs
   :language: haskell


Foreign Export
^^^^^^^^^^^^^^

Foreign export declarations start with ``foreign`` ``export``:

.. literalinclude:: ../include/language-syntax/ffi/export.fnk
   :language: finkel

.. literalinclude:: ../include/language-syntax/ffi/export.hs
   :language: haskell


Compiler Pragmas
----------------

All pragmas use ``%p(..)`` form.


Inlining
^^^^^^^^

Pragmas to control inlining of codes use ``INLINE`` and ``NOINLINE``:

.. code-block:: finkel

   %p(INLINE foo) ; Finkel

.. code-block:: haskell

   {-# INLINE foo #-} -- Haskell

GHC specific phase controls are also supported:

.. code-block:: finkel

   %p(INLINE [1] bar) ; Finkel
   %p(NOINLINE [~2] buzz)

.. code-block:: haskell

   {-# INLINE [1] bar #-} -- Haskell
   {-# NOINLINE [~2] buzz #-}


Specialization
^^^^^^^^^^^^^^

Pragmas to control specialization of overloaded function use
``SPECIALIZE``:

.. code-block:: finkel

   %p(SPECIALIZE (:: factorial (-> Int Int))) ; Finkel

.. code-block:: haskell

   {-# SPECIALIZE factorial :: Int -> Int #-} -- Haskell


Language extensions
^^^^^^^^^^^^^^^^^^^

Pragma for language extensions use ``LANGUAGE``:

.. code-block:: finkel

   %p(LANGUAGE GADTs OverloadedStrings) ; Finkel

.. code-block:: haskell

   {-# LANGUAGE GADTs, OverloadedStrings #-} -- Haskell

..
   Overlaps
   ^^^^^^^^

   This is GHC specific ...

..
   .. rubric:: Footnotes

   .. [#f1] With few exceptions. Perhaps the most notable exception is the
            lack of native infix function support, but has operator
            expansion instead.


================================================
FILE: doc/contents/macros.rst
================================================
Macros In Finkel
================

This section shows how to write and use macros. Macros in Finkel are
similar to macros in Common Lisp and Clojure. Macros in Finkel are
implemented as a function taking codes and returning a code.


Understanding Compilation Phases
--------------------------------

During compilation, the compiler executable parses the contents of the
source code. If the parsed code was a list, and the first element of
the list was a symbol of known macro name, the rest of the elements in
the list will be passed to the macro. Resulting forms will be replaced
with the original list form of the macro. This replacement of the code
with macro function is often called *macro expansion*. The expanded
result will again get expanded until it cannot be expanded anymore.
During macro expansion, the compiler can use predefined functions in
the executable. To add functions to use during macro expansion, one
needs to explicitly tell so.


Defining Macro With ``eval-when`` And ``defmacro``
--------------------------------------------------

One way to tell a new macro to the compiler is to define a macro
inside ``eval-when (compile)``. The ``eval-when`` is a macro that
specifies the phase of declaration in its body form. The phase
``compile`` will evaluate the contents while compiling the parsed
source code.

Open a new file and save following contents to a file named
``eval-when.fnk``:

.. literalinclude:: ../include/macros/eval-when.fnk
   :language: finkel

In the above example, ``(import-when [:compile] (Finkel.Prelude))`` is
added in the ``defmodule`` to import functions and data types for
writing while compiling the ``Main`` module.

The ``eval-when`` macro can take multiple forms. Two forms are passed
to ``eval-when`` in the above example, one to define a macro named
``say-hello`` , and another to define a macro named ``say-bye``.

The ``say-hello`` macro takes no argument, and the body of the macro
simply returns a quoted form with a single quote (i.e. ``'``).
Similarly, the ``say-bye`` macro takes no argument and returns a form
to prints out a message.

The ``main`` function contains the ``say-hello`` and ``say-bye``
macros. Unlike functions, macros taking no arguments need to be
surrounded by parentheses.

One can run the compiler with the ``-ddump-parsed`` option to observe
the parsed Haskell representation:

.. literalinclude:: ../include/macros/eval-when.console
   :language: console


Defining Macro With ``macrolet``
--------------------------------

One can add a temporary macro with the ``macrolet`` macro. Following
``macrolet.fnk`` example do similar work done in the previous example,
but using ``macrolet`` instead of ``eval-when`` and ``defmacro``.

.. literalinclude:: ../include/macros/macrolet.fnk
   :language: finkel

Note that single ``macrolet`` form can define multiple temporary
macros.

.. literalinclude:: ../include/macros/macrolet.console
   :language: console


Loading Macros With ``require``
-------------------------------

Another way to add macros to the current module is to ``require`` a
module containing macros. Open a file named ``RequireMe.fnk`` and save
the following code:

.. literalinclude:: ../include/macros/RequireMe.fnk
   :language: finkel

Note that the ``RequireMe`` module has the ``import`` of
``Finkel.Prelude`` inside ``defmodule``. This is because the macros
defined in ``RequireMe`` are not for itself, but other modules.

Next, open and edit another file named ``require.fnk`` to require the
``RequireMe`` module:

.. literalinclude:: ../include/macros/require.fnk
   :language: finkel

Compilation output:

.. literalinclude:: ../include/macros/require.console
   :language: console

Unlike the previous two examples, one needs to generate an object code
of the ``RequireMe`` module so that the macro functions defined in
``RequireMe`` could be used in the file ``require.fnk``.

.. note::

   As of finkel version 0.1, one may need to add ``-dynamic-too`` option to the
   ``finkel`` executable when compiling a source code file containing
   ``require``.


Quasiquote, Unquote, And Unquote-Splice
---------------------------------------

Macro can *unquote* and *unquote-splice* a form inside
*quasiquote*.

Open a new file named ``unquote.fnk`` and save the following contents:

.. literalinclude:: ../include/macros/unquote.fnk
   :language: finkel

The example defines two macros: ``uq1`` and ``uq2``. Both macros use
````` (back-tick) instead of ``'`` (single quote) in body expression.

In ``uq1``, the macro argument ``arg`` is unquoted with ``,``, and the
unquoted form is passed as the second argument of ``++`` function.  In
``uq2`` the expression ``(++ "uq2: arg = " (show arg))`` is unquoted
with ``,``.

Observing parsed result with ``-ddump-parsed``:

.. literalinclude:: ../include/macros/unquote.console
   :language: console

Parsed Haskell representation shows ``++`` in the expanded form of
``uq1`` macro. Expanded result of ``uq2`` evaluates ``++`` at the time
of macro expansion, so the resulting form of ``uq2`` is a literal
``String``.

Inside the quasi-quoted form, ``,@`` is used to unquote-splice a list
form. The ``,@`` can unquote-splice a quoted list and a Haskell list.

.. literalinclude:: ../include/macros/unquote-splice.fnk
   :language: finkel

Observing parsed Haskell code:

.. literalinclude:: ../include/macros/unquote-splice.console
   :language: console


Getting Macro Arguments As A List
---------------------------------

Macro can take its entire argument as a list form. Below example codes
show a macro which takes entire arguments passed to it as a list named
``args``:

.. literalinclude:: ../include/macros/arglist.fnk
   :language: finkel

Parsed Haskell code:

.. literalinclude:: ../include/macros/arglist.console
   :language: console


Getting Values From Macro Arguments
-----------------------------------

One can obtain Haskell values from arguments passed to macro:

.. literalinclude:: ../include/macros/fib-macro.fnk
   :language: finkel

The above example applies the ``fromCode`` function to the macro
argument to get an ``Int`` value from the code object. To return the
code object, the ``fib-macro`` applies ``toCode`` to the ``Int`` value
evaluated by the ``fib`` function. Note that the ``fib`` function
needs to be defined inside ``eval-when`` so that ``fib-macro`` can use
the function during macro expansion.

Sample compilation output:

.. literalinclude:: ../include/macros/fib-macro.console
   :language: console


Special forms
-------------

The Finkel core keywords are implemented as macros made from Finkel
kernel.  Details of Finkel core keywords are described in the `haddock
API documentation <https://hackage.haskell.org>`_ of the
``finkel-core`` package.

This section explains built-in macros in the Finkel kernel
language. These built-in macros are sometimes called *special
forms*. All special forms start with ``:``, followed by lower case
alphabetic character, to avoid name conflict with existing Haskell
functions.


:begin
^^^^^^

The ``:begin`` special form is basically for writing a macro returning
multiple top-level declarations. Following code shows an example use
of ``:begin``, to return type synonym declarations from the
``nat-types`` macro:

.. literalinclude:: ../include/macros/begin.fnk
   :language: finkel

Observing parsed Haskell code:

.. literalinclude:: ../include/macros/begin.console
   :language: console


:eval-when-compile
^^^^^^^^^^^^^^^^^^

The ``:eval-when-compile`` special form is used to implement
``eval-when`` macro in the core language. Basically,
``(:eval-when-compile BODY1 BODY2 ...)`` is the same as ``(eval-when
(compile) BODY1 BODY2 ...)``.

The following code shows sample use of ``:eval-when-compile``. The
function ``wrap-actions`` is defined inside ``:eval-when-compile``, so
that later the compiler can use the function in the ``doactions``
macro.

.. literalinclude:: ../include/macros/eval-when-compile.fnk
   :language: finkel

Parsed Haskell code:

.. literalinclude:: ../include/macros/eval-when-compile.console
   :language: console


:quote
^^^^^^

The ``:quote`` special form is used for quoting the given value as a
code object. The ``'`` is syntax sugar of this special
form. Internally, quoted values are passed to functions exported from
the ``finkel-kernel`` package.

Following code shows how underlying Finkel kernel functions are
applied to literal values in source code:

.. literalinclude:: ../include/macros/quote.fnk
   :language: finkel

Parsed Haskell source:

.. literalinclude:: ../include/macros/quote.console
   :language: console


:quasiquote
^^^^^^^^^^^

The ``:quasiquote`` is the underlying special form for the `````
syntax sugar. Inside a quasi-quoted form, ``:unquote`` and
``:unquote-splice`` could be used for getting the value from the
code. Indeed, ``,`` is a syntax sugar of ``:unquote``, and ``,@`` is a
syntax sugar of ``:unquote-splice``.

.. literalinclude:: ../include/macros/quasiquote.fnk
   :language: finkel

Above example prints ``True``:

.. literalinclude:: ../include/macros/quasiquote.console
   :language: console


:require
^^^^^^^^

The ``:require`` is for adding a module to the compiler during macro
expansion. It also adds macros defined in the required module to the
current compiler environment. This special form is used by the
``defmodule`` macro.

.. literalinclude:: ../include/macros/raw-require.fnk
   :language: finkel

Parsed Haskell code:

.. literalinclude:: ../include/macros/raw-require.console
   :language: console


:with-macro
^^^^^^^^^^^

The ``:with-macro`` is the underlying special form for ``macrolet``
macro. This special form is perhaps not useful unless one wants to
write an alternative implementation of the ``macrolet`` macro. See the
source code of ``Finkel.Core`` module for usage.


================================================
FILE: doc/doc.cabal
================================================
cabal-version:       2.0
name:                doc
version:             0.0.0
synopsis:            Internal test for Finkel documentation
license:             BSD3
license-file:        LICENSE
author:              8c6794b6
maintainer:          8c6794b6@gmail.com
copyright:           2020-2022 8c6794b6
category:            Language
build-type:          Simple

description:
  Internal package to test the codes in the Finkel documentation.

flag dynamic
  description:         Dynamically link executables (except Windows)
  default:             True
  manual:              True

test-suite test
  type:                exitcode-stdio-1.0
  hs-source-dirs:      test
  main-is:             Spec.hs
  other-modules:       Doc
                       Doc.TestAux
                       Doc.FinkelExecutable
                       Doc.BuildingPackage
                       Doc.Macros
                       Doc.LanguageSyntax
  build-depends:       base          >= 4.14   && < 5
                     , directory     >= 1.3    && < 1.4
                     , filepath      >= 1.4    && < 1.6
                     , ghc           >= 8.10.0 && < 9.11
                     , process       >= 1.6    && < 1.7
                     , hspec         >= 2.4.8  && < 2.12
                     , QuickCheck    >= 2.10.1 && < 2.16
                       --
                     , finkel-core   == 0.0.0
                     , finkel-kernel == 0.0.0
  build-tool-depends:  finkel:finkel == 0.0.0
                     , fnkpp:fnkpp   == 0.0.0
  default-language:    Haskell2010

  ghc-options:         -Wall -threaded -rtsopts

  -- Skipping the whole test under Windows, since it's too slow.
  if os(windows)
    buildable: False
  else
    if flag(dynamic)
      ghc-options:     -dynamic

  build-tool-depends:  fnkpp:fnkpp == 0.0.0
  ghc-options:         -F -pgmF fnkpp -optF --no-warn-interp
                       -fplugin Finkel.Core.Plugin
  if impl (ghc >= 9.6)
    ghc-options:       -keep-hscpp-files

source-repository head
  type:     git
  location: https://github.com/finkel-lang/doc.git
  subdir:   doc


================================================
FILE: doc/include/building-package/my-first-package/Setup.hs
================================================
-- File: my-first-package/Setup.hs
import Distribution.Simple (defaultMain)
main = defaultMain


================================================
FILE: doc/include/building-package/my-first-package/my-first-package.cabal
================================================
cabal-version: 1.12

-- This file has been generated from package.yaml by hpack version 0.36.0.
--
-- see: https://github.com/sol/hpack
--
-- hash: 5f8c819490edb2e9673637f8df651684d12bbc5294a98b1a63b820025e8792cd

name:           my-first-package
version:        0.1.0.0
build-type:     Simple

library
  exposed-modules:
      MyFirstPackage
  other-modules:
      Paths_my_first_package
  hs-source-dirs:
      src
  ghc-options: -F -pgmF fnkpp -optF --no-warn-interp -fplugin Finkel.Core.Plugin
  build-tool-depends:
      fnkpp:fnkpp
  build-depends:
      base
    , finkel-core
  default-language: Haskell2010


================================================
FILE: doc/include/building-package/my-first-package/package.yaml
================================================
# File: my-first-package/package.yaml

name: my-first-package
version: 0.1.0.0

library:
  source-dirs: src
  exposed-modules: MyFirstPackage
  ghc-options:
    - -F -pgmF fnkpp -optF --no-warn-interp
    - -fplugin Finkel.Core.Plugin
  build-tools:
    - fnkpp:fnkpp
  dependencies:
    - base
    - finkel-core


================================================
FILE: doc/include/building-package/my-first-package/src/MyFirstPackage.hs
================================================
;;;; File: my-first-package/src/MyFirstPackage.hs

(defmodule MyFirstPackage
  (export factorial))

(defn (:: factorial (-> Integer Integer))
  "Compute factorial of the given number.

This function does not support negative numbers. If the argument was
negative, constantly returns @-1@.

==== __Example__

>>> (factorial 10)
3628800
>>> (factorial -42)
1
"
  [n]
  (if (<= n 1)
      1
      (* n (factorial (- n 1)))))


================================================
FILE: doc/include/building-package/my-first-package/stack.git.yaml
================================================
resolver: lts-22.31
packages:
  - .
extra-deps:
  - git: https://github.com/finkel-lang/finkel
    commit: f7913be75db03beec66b9a029c538c95cdbb05a8
    subdirs:
      - finkel-kernel
      - fkc
      - finkel-setup
      - finkel-core
      - finkel-tool
      - finkel


================================================
FILE: doc/include/building-package/my-first-package/stack.template.yaml
================================================
resolver: lts-22.31
packages:
  - .


================================================
FILE: doc/include/building-package/my-new-package/LICENSE
================================================
Copyright Author name here (c) 2024

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.

    * Redistributions in binary form must reproduce the above
      copyright notice, this list of conditions and the following
      disclaimer in the documentation and/or other materials provided
      with the distribution.

    * Neither the name of the copyright holder nor the names of other
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

================================================
FILE: doc/include/building-package/my-new-package/README.md
================================================
# my-new-package


================================================
FILE: doc/include/building-package/my-new-package/Setup.hs
================================================
import Distribution.Simple (defaultMain)
main = defaultMain


================================================
FILE: doc/include/building-package/my-new-package/app/Main.hs
================================================
module Main where

import Lib

main :: IO ()
main = someFunc


================================================
FILE: doc/include/building-package/my-new-package/my-new-package.cabal
================================================
cabal-version:       3.0
name:                my-new-package
version:             0.1.0.0
-- synopsis:
-- description:
homepage:            http://www.example.org
license:             BSD-3-Clause
license-file:        LICENSE
author:              Author name here
maintainer:          example@example.com
copyright:           2024 Author name here
category:            Data
build-type:          Simple
extra-source-files:  README.md

common finkel
  build-depends:       finkel-core
  build-tool-depends:  fnkpp:fnkpp
  ghc-options:         -F -pgmF fnkpp -optF --no-warn-interp
                       -fplugin Finkel.Core.Plugin

library
  import:              finkel
  hs-source-dirs:      src
  exposed-modules:     Lib
  build-depends:       base >= 4.7 && < 5
  default-language:    Haskell2010

executable my-new-package
  hs-source-dirs:      app
  main-is:             Main.hs
  ghc-options:         -threaded -rtsopts -with-rtsopts=-N
  build-depends:       base
                     , my-new-package
  default-language:    Haskell2010

test-suite my-new-package-test
  import:              finkel
  type:                exitcode-stdio-1.0
  hs-source-dirs:      test
  main-is:             Spec.hs
  build-depends:       base
                     , my-new-package
  ghc-options:         -threaded -rtsopts -with-rtsopts=-N
  default-language:    Haskell2010

-- source-repository head
--   type:     git
--   location: https://github.com/githubuser/my-new-package


================================================
FILE: doc/include/building-package/my-new-package/src/Lib.hs
================================================
;;; -*- mode: finkel -*-
(defmodule Lib
  (export someFunc))

(defn (:: someFunc (IO ()))
  (putStrLn "Hello from my-new-package"))


================================================
FILE: doc/include/building-package/my-new-package/stack.yaml
================================================
# This file was automatically generated by 'stack init'
#
# Some commonly used options have been documented as comments in this file.
# For advanced use and comprehensive documentation of the format, please see:
# https://docs.haskellstack.org/en/stable/yaml_configuration/

# A warning or info to be displayed to the user on config load.
user-message: |
  Warning (added by new or init): Some packages were found to be incompatible with the resolver and have been left commented out in the packages section.
  You can omit this message by removing it from stack.yaml

# Resolver to choose a 'specific' stackage snapshot or a compiler version.
# A snapshot resolver dictates the compiler version and the set of packages
# to be used for project dependencies. For example:
#
# resolver: lts-3.5
# resolver: nightly-2015-09-21
# resolver: ghc-7.10.2
#
# The location of a snapshot can be provided as a file or url. Stack assumes
# a snapshot provided as a file might change, whereas a url resource does not.
#
# resolver: ./custom-snapshot.yaml
# resolver: https://example.com/snapshots/2018-01-01.yaml
resolver: lts-22.31

# User packages to be built.
# Various formats can be used as shown in the example below.
#
# packages:
# - some-directory
# - https://example.com/foo/bar/baz-0.0.2.tar.gz
#   subdirs:
#   - auto-update
#   - wai
packages: []
# The following packages have been ignored due to incompatibility with the
# resolver compiler, dependency conflicts with other packages
# or unsatisfied dependencies.
#- .

# Dependency packages to be pulled from upstream that are not in the resolver.
# These entries can reference officially published versions as well as
# forks / in-progress versions pinned to a git hash. For example:
#
# extra-deps:
# - acme-missiles-0.3
# - git: https://github.com/commercialhaskell/stack.git
#   commit: e7b331f14bcffb8367cd58fbfc8b40ec7642100a
#
# extra-deps: []

# Override default flag values for local packages and extra-deps
# flags: {}

# Extra package databases containing global packages
# extra-package-dbs: []

# Control whether we use the GHC we find on the path
# system-ghc: true
#
# Require a specific version of stack, using version ranges
# require-stack-version: -any # Default
# require-stack-version: ">=2.3"
#
# Override the architecture used by stack, especially useful on Windows
# arch: i386
# arch: x86_64
#
# Extra directories used by stack for building
# extra-include-dirs: [/path/to/dir]
# extra-lib-dirs: [/path/to/dir]
#
# Allow a newer minor version of GHC than the snapshot specifies
# compiler-check: newer-minor


================================================
FILE: doc/include/building-package/my-new-package/test/Spec.hs
================================================
main :: IO ()
main = putStrLn "Test suite not yet implemented"


================================================
FILE: doc/include/building-package/my-second-package/LICENSE
================================================
Copyright Author name here (c) 2019

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.

    * Redistributions in binary form must reproduce the above
      copyright notice, this list of conditions and the following
      disclaimer in the documentation and/or other materials provided
      with the distribution.

    * Neither the name of Author name here nor the names of other
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

================================================
FILE: doc/include/building-package/my-second-package/README.md
================================================
# my-second-package


================================================
FILE: doc/include/building-package/my-second-package/Setup.hs
================================================
import Distribution.Simple (defaultMain)
main = defaultMain


================================================
FILE: doc/include/building-package/my-second-package/app/Main.hs
================================================
module Main where

import Lib

main :: IO ()
main = someFunc


================================================
FILE: doc/include/building-package/my-second-package/my-second-package.cabal
================================================
cabal-version:       3.0
name:                my-second-package
version:             0.1.0.0
-- synopsis:
-- description:
homepage:            http://www.example.org
license:             BSD-3-Clause
license-file:        LICENSE
author:              Author name here
maintainer:          example@example.com
copyright:           2019 Author name here
category:            Data
build-type:          Simple
extra-source-files:  README.md

common finkel
  build-depends:       finkel-core
  build-tool-depends:  fnkpp:fnkpp
  ghc-options:         -F -pgmF fnkpp -optF --no-warn-interp
                       -fplugin Finkel.Core.Plugin

library
  import:              finkel
  hs-source-dirs:      src
  exposed-modules:     Lib
                       HsCodes
                       FnkCodes
  build-depends:       base >= 4.7 && < 5
  default-language:    Haskell2010

executable my-second-package
  hs-source-dirs:      app
  main-is:             Main.hs
  ghc-options:         -threaded -rtsopts -with-rtsopts=-N
  build-depends:       base
                     , my-second-package
  default-language:    Haskell2010

test-suite my-second-package-test
  import:              finkel
  type:                exitcode-stdio-1.0
  hs-source-dirs:      test
  main-is:             Spec.hs
  other-modules:       FactorialTest
  build-depends:       base
                     , my-second-package
  build-tool-depends:  fnkpp:fnkpp
  ghc-options:         -threaded -rtsopts -with-rtsopts=-N
  default-language:    Haskell2010

-- source-repository head
--   type:     git
--   location: https://github.com/githubuser/my-second-package


================================================
FILE: doc/include/building-package/my-second-package/src/FnkCodes.hs
================================================
;;;; File: my-second-package/src/FnkCodes.hs

(defmodule FnkCodes
  (export fnkfactorial))

(defn (:: fnkfactorial (-> Int Int))
  [n]
  (if (<= n 1)
      n
      (* n (fnkfactorial (- n 1)))))


================================================
FILE: doc/include/building-package/my-second-package/src/HsCodes.hs
================================================
-- File: my-second-package/src/HsCodes.hs

module HsCodes
  ( hsfactorial
  , fnkfactorial
  ) where

import FnkCodes

hsfactorial :: Int -> Int
hsfactorial = fnkfactorial


================================================
FILE: doc/include/building-package/my-second-package/src/Lib.hs
================================================
;;;; File: my-second-package/src/Lib.hs

(defmodule Lib
  (export someFunc)
  (import (HsCodes [hsfactorial fnkfactorial])))

(defn (:: someFunc (IO ()))
  (putStrLn
   (++ "From `Lib.someFunc':\n"
       "  hsfactorial 10  : " (show (hsfactorial 10)) "\n"
       "  fnkfactorial 10 : " (show (fnkfactorial 10)))))


================================================
FILE: doc/include/building-package/my-second-package/test/FactorialTest.hs
================================================
;;;; File: FactorialTest.hs

(defmodule FactorialTest
  (export test)
  (import
   (HsCodes)
   (System.Exit (exitFailure))))

(defn (:: test (IO ()))
  (if (== (fnkfactorial 10) (hsfactorial 10))
      (return ())
      exitFailure))


================================================
FILE: doc/include/building-package/my-second-package/test/Spec.hs
================================================
import FactorialTest

main :: IO ()
main = test


================================================
FILE: doc/include/finkel-executable/finkel-help-make.console
================================================
$ finkel help make
USAGE: finkel make [command-line-options-and-files]

HELP OPTIONS:

    --fnk-help       Show this help and exit.
    --fnk-languages  Show supported language extensions and exit.
    --fnk-version    Show Finkel version and exit.

DEBUG OPTIONS:

    --fnk-verbose=INT    Set verbosity level to INT.
    --fnk-hsdir=DIR      Set Haskell code output directory to DIR.
    --fnk-dump-dflags    Dump DynFlags settings.
    --fnk-dump-expand    Dump expanded code.
    --fnk-dump-hs        Dump Haskell source code.
    --fnk-dump-session   Dump session information.
    --fnk-trace-expand   Trace macro expansion.
    --fnk-trace-session  Trace session env.
    --fnk-trace-make     Trace make function.
    --fnk-trace-spf      Trace builtin special forms.

  Other options are passed to ghc.



================================================
FILE: doc/include/finkel-executable/hello-prof.console
================================================
$ finkel make -o hello -fforce-recomp -prof -fprof-auto hello.fnk
[1 of 1] Compiling Main             ( hello.hs, hello.o )
Linking hello ...


================================================
FILE: doc/include/finkel-executable/hello.console
================================================
$ finkel make -o hello hello.hs
[1 of 1] Compiling Main             ( hello.hs, hello.o )
Linking hello ...
$ ./hello
Hello, World!


================================================
FILE: doc/include/finkel-executable/hello.hs
================================================
;;;; File: hello.hs

(defn main
  (putStrLn "Hello, World!"))


================================================
FILE: doc/include/finkel-executable/hello904.console
================================================
$ finkel make -o hello hello.hs
[1 of 2] Compiling Main             ( hello.hs, hello.o )
[2 of 2] Linking hello
$ ./hello
Hello, World!


================================================
FILE: doc/include/language-syntax/decl/bind-pat.fnk
================================================
(= (Just x) (lookup k vs)) ; Finkel


================================================
FILE: doc/include/language-syntax/decl/bind-pat.hs
================================================
Just x = lookup k vs -- Haskell


================================================
FILE: doc/include/language-syntax/decl/bind-simpl.fnk
================================================
(= f1 x y z (+ x (* y z))) ; Finkel


================================================
FILE: doc/include/language-syntax/decl/bind-simpl.hs
================================================
f1 x y z = x + (y * z) -- Haskell


================================================
FILE: doc/include/language-syntax/decl/bind-where.fnk
================================================
(= f2 n ; Finkel
  (where body
    (= body (+ n 1))))


================================================
FILE: doc/include/language-syntax/decl/bind-where.hs
================================================
f2 n = body -- Haskell
  where
    body = n + 1


================================================
FILE: doc/include/language-syntax/decl/class.fnk
================================================
(class (=> (Ord a) (C1 a)) ; Finkel
  (:: m1 (-> a Int))
  (= m1 _ 0))


================================================
FILE: doc/include/language-syntax/decl/class.hs
================================================
class Ord a => C1 a where -- Haskell
  m1 :: a -> Int
  m1 _ = 0


================================================
FILE: doc/include/language-syntax/decl/data-d1.fnk
================================================
(data (D1 a b) ; Finkel
  C1
  (C2 a)
  (C3 b)
  (deriving Eq Show))


================================================
FILE: doc/include/language-syntax/decl/data-d1.hs
================================================
data D1 a b -- Haskell
  = C1
  | C2 a
  | C3 b
  deriving (Eq, Show)


================================================
FILE: doc/include/language-syntax/decl/data-d2.fnk
================================================
(data (D2 a b) ; Finkel
  (D2 {(:: f1 a)
       (:: f2 b)
       (:: f3 Int)}))


================================================
FILE: doc/include/language-syntax/decl/data-d2.hs
================================================
data D2 a b -- Haskell
 = D2 { f1 :: a
      , f2 :: b
      , f3 :: Int }


================================================
FILE: doc/include/language-syntax/decl/default.fnk
================================================
(default Int Double) ; Finkel


================================================
FILE: doc/include/language-syntax/decl/default.hs
================================================
default (Int, Double) -- Haskell


================================================
FILE: doc/include/language-syntax/decl/fixity.fnk
================================================
(infixr 6 $+$)


================================================
FILE: doc/include/language-syntax/decl/fixity.hs
================================================
infixr 6 $+$


================================================
FILE: doc/include/language-syntax/decl/instance.fnk
================================================
(instance (C1 Int) ; Finkel
  (= m1 n (+ n 1)))


================================================
FILE: doc/include/language-syntax/decl/instance.hs
================================================
instance C1 Int where -- Haskell
  m1 n = n + 1


================================================
FILE: doc/include/language-syntax/decl/newtype.fnk
================================================
(newtype N (N {(:: unN Int)})) ; Finkel


================================================
FILE: doc/include/language-syntax/decl/newtype.hs
================================================
newtype N = N {unN :: Int} -- Haskell


================================================
FILE: doc/include/language-syntax/decl/tysig-constraints.fnk
================================================
(:: f (=> (Eq a) (Ord a) (Show a) (Num a) (-> a a))) ; Finkel


================================================
FILE: doc/include/language-syntax/decl/tysig-constraints.hs
================================================
f :: (Eq a, Ord a, Show a, Num a) => a -> a -- Haskell


================================================
FILE: doc/include/language-syntax/decl/tysig-many.fnk
================================================
(:: f g h (-> Int Int)) ; Finkel


================================================
FILE: doc/include/language-syntax/decl/tysig-many.hs
================================================
f, g, h :: Int -> Int -- Haskell


================================================
FILE: doc/include/language-syntax/decl/tysig-one.fnk
================================================
(:: f (-> Int Int Int)) ; Finkel


================================================
FILE: doc/include/language-syntax/decl/tysig-one.hs
================================================
f :: Int -> Int -> Int -- Haskell


================================================
FILE: doc/include/language-syntax/decl/tysym.fnk
================================================
(type (T1 a) (Maybe (, a Bool String))) ; Finkel


================================================
FILE: doc/include/language-syntax/decl/tysym.hs
================================================
type T1 a = Maybe (a, Bool, String) -- Haskell


================================================
FILE: doc/include/language-syntax/expr/block-comment.fnk
================================================
(putStrLn {- Finkel block comment -} "bar")


================================================
FILE: doc/include/language-syntax/expr/block-comment.hs
================================================
putStrLn {- Haskell block comment -} "bar"


================================================
FILE: doc/include/language-syntax/expr/case.fnk
================================================
(case n ; Finkel
  0 "zero"
  1 "one"
  _ "many")


================================================
FILE: doc/include/language-syntax/expr/case.hs
================================================
case n of -- Haskell
  0 -> "zero"
  1 -> "one"
  _ -> "many"


================================================
FILE: doc/include/language-syntax/expr/char-a.fnk
================================================
(putChar #'a) ; Finkel


================================================
FILE: doc/include/language-syntax/expr/char-a.hs
================================================
putChar 'a'  -- Haskell


================================================
FILE: doc/include/language-syntax/expr/char-escape.fnk
================================================
(print [#'\ #'']) ; Finkel


================================================
FILE: doc/include/language-syntax/expr/char-escape.hs
================================================
print ['\\', '\''] -- Haskell


================================================
FILE: doc/include/language-syntax/expr/char-ncode.fnk
================================================
(print [#'\97 #'\o141 #'\x61]) ; Finkel, prints "aaa"


================================================
FILE: doc/include/language-syntax/expr/char-ncode.hs
================================================
print ['\97', '\o141', '\x61'] -- Haskell, prints "aaa"


================================================
FILE: doc/include/language-syntax/expr/char-special.fnk
================================================
(print [#'\n #'  #'\NUL #'\^L]) ; Finkel


================================================
FILE: doc/include/language-syntax/expr/char-special.hs
================================================
print ['\n', ' ', '\NUL', '\^L'] -- Haskell


================================================
FILE: doc/include/language-syntax/expr/discard-prefix.fnk
================================================
(do (print True) ; Finkel
    %_(this list (is ignored))
    (print %_ignored False %_ "ignored"))


================================================
FILE: doc/include/language-syntax/expr/discard-prefix.hs
================================================
do print True -- Haskell, ignored forms removed
   print False


================================================
FILE: doc/include/language-syntax/expr/do.fnk
================================================
(do (putStr "x: ") ; Finkel
    (<- l getLine)
    (return (words l)))


================================================
FILE: doc/include/language-syntax/expr/do.hs
================================================
do putStr "x: " -- Haskell
   l <- getLine
   return (words l)


================================================
FILE: doc/include/language-syntax/expr/fieldlabels.fnk
================================================
(Constr1 {(= field1 1) (= field2 True) (= field3 "abc")}) ; Finkel


================================================
FILE: doc/include/language-syntax/expr/fieldlabels.hs
================================================
Constr1 {field1=1, field2=True, field3="abc"} -- Haskell


================================================
FILE: doc/include/language-syntax/expr/funapp-pars.fnk
================================================
(((((putStrLn)) "hello"))) ; Finkel


================================================
FILE: doc/include/language-syntax/expr/funapp-pars.hs
================================================
putStrLn "hello" -- Haskell, redundant parentheses removed


================================================
FILE: doc/include/language-syntax/expr/funapp.fnk
================================================
(putStrLn "hello") ; Finkel


================================================
FILE: doc/include/language-syntax/expr/funapp.hs
================================================
putStrLn "hello" -- Haskell


================================================
FILE: doc/include/language-syntax/expr/guard.fnk
================================================
(case expr ; Finkel
  (Just y) (| ((even y) r1)
              ((odd y) (< y 10) r2)
              ((<- (Just z) (lookup y kvs))
               (let ((= z' (* z 2))))
               (r3 z'))
              (otherwise r4)))


================================================
FILE: doc/include/language-syntax/expr/guard.hs
================================================
case expr of -- Haskell
  Just y | even y -> r1
         | odd y, y < 10 -> r2
         | Just z <- lookup y kvs
         , let z' = z * 2
         -> r3 z'
         | otherwise -> r4


================================================
FILE: doc/include/language-syntax/expr/if.fnk
================================================
(if test true-expr false-expr) ; Finkel


================================================
FILE: doc/include/language-syntax/expr/if.hs
================================================
if test then true_expr else false_expr -- Haskell


================================================
FILE: doc/include/language-syntax/expr/lambda.fnk
================================================
(zipWith (\x y (* x (+ y 1))) [1 2 3] [4 5 6]) ; Finkel


================================================
FILE: doc/include/language-syntax/expr/lambda.hs
================================================
zipWith (\x y -> x * (y + 1)) [1, 2, 3] [4, 5, 6] -- Haskell


================================================
FILE: doc/include/language-syntax/expr/let.fnk
================================================
(let ((:: a Int) ; Finkel
      (:: b c Int)
      (= a 10)
      (= b 4)
      (= c 2))
  (print [a b c]))


================================================
FILE: doc/include/language-syntax/expr/let.hs
================================================
let a :: Int -- Haskell
    b, c :: Int
    a = 10
    b = 4
    c = 2
in  print [a, b, c]


================================================
FILE: doc/include/language-syntax/expr/line-comment.fnk
================================================
(putStrLn "foo") ; single-line comment in Finkel


================================================
FILE: doc/include/language-syntax/expr/line-comment.hs
================================================
putStrLn "foo" -- single-line comment in Haskell


================================================
FILE: doc/include/language-syntax/expr/list-comp.fnk
================================================
[x | (<- x [1 .. 10]) (even x)] ; Finkel


================================================
FILE: doc/include/language-syntax/expr/list-comp.hs
================================================
[x | x <- [1 .. 10], even x] -- Haskell


================================================
FILE: doc/include/language-syntax/expr/list-const.fnk
================================================
(print [1 2 3]) ; Finkel


================================================
FILE: doc/include/language-syntax/expr/list-const.hs
================================================
print [1, 2, 3] -- Haskell


================================================
FILE: doc/include/language-syntax/expr/list-range.fnk
================================================
(print [1 3 .. 9]) ; Finkel


================================================
FILE: doc/include/language-syntax/expr/list-range.hs
================================================
print [1, 3 .. 9] -- Haskell


================================================
FILE: doc/include/language-syntax/expr/map-mul2.fnk
================================================
(map (* 2) [1 2 3]) ; Finkel


================================================
FILE: doc/include/language-syntax/expr/map-mul2.hs
================================================
map ((*) 2) [1, 2, 3] -- Haskell


================================================
FILE: doc/include/language-syntax/expr/map-unary.fnk
================================================
(map (- 1) [1 2 3]) ; Finkel


================================================
FILE: doc/include/language-syntax/expr/map-unary.hs
================================================
map ((-) 1) [1, 2, 3] -- Haskell


================================================
FILE: doc/include/language-syntax/expr/muladd.fnk
================================================
((*+) 2 3 4) ; Finkel


================================================
FILE: doc/include/language-syntax/expr/muladd.hs
================================================
(*+) 2 3 4 -- Haskell


================================================
FILE: doc/include/language-syntax/expr/numeric.fnk
================================================
(do (print 1)     ; decimal integer in Finkel
    (print 0o77)  ; octal integer
    (print 0xff)  ; hexadecimal integer
    (print 2.34)  ; float
    (print 1e-2)) ; float with exponent


================================================
FILE: doc/include/language-syntax/expr/numeric.hs
================================================
do print 1    -- decimal integer in Haskell
   print 0o77 -- octal integer
   print 0xff -- hexadecimal integer
   print 2.34 -- float
   print 1e-2 -- float with exponent


================================================
FILE: doc/include/language-syntax/expr/opexp-add.fnk
================================================
(+ 1 2 3 4 5) ; Finkel


================================================
FILE: doc/include/language-syntax/expr/opexp-add.hs
================================================
1 + 2 + 3 + 4 + 5 -- Haskell


================================================
FILE: doc/include/language-syntax/expr/opexp-app.fnk
================================================
(<*> (pure foldr) (Just +) (pure 1) (pure [2 3])) ; Finkel


================================================
FILE: doc/include/language-syntax/expr/opexp-app.hs
================================================
pure foldr <*> Just (+) <*> pure 1 <*> pure [2, 3] -- Haskell


================================================
FILE: doc/include/language-syntax/expr/pat-as.fnk
================================================
(let ((= (@ x (Just n)) expr)) ; Finkel
  (+ n 1))


================================================
FILE: doc/include/language-syntax/expr/pat-as.hs
================================================
let x@(Just n) = expr -- Haskell
in  n + 1


================================================
FILE: doc/include/language-syntax/expr/pat-irf.fnk
================================================
(let ((= ~(, a ~(, b c)) expr)) ; Finkel
  (+ a (* b c)))


================================================
FILE: doc/include/language-syntax/expr/pat-irf.hs
================================================
let ~(a, ~(b, c)) = expr -- Haskell
in  a + (b * c)


================================================
FILE: doc/include/language-syntax/expr/pat-maybe.fnk
================================================
(case expr ; Finkel
  (Just x) (+ x 1)
  Nothing  0)


================================================
FILE: doc/include/language-syntax/expr/pat-maybe.hs
================================================
case expr of -- Haskell
  Just x -> x + 1
  Nothing -> 0


================================================
FILE: doc/include/language-syntax/expr/pat-opexp.fnk
================================================
(case expr ; Finkel
  (: a1 a2 _) (+ a1 a2)
  _ 0)


================================================
FILE: doc/include/language-syntax/expr/pat-opexp.hs
================================================
case expr of -- Haskell
  a1 : a2 : _ -> a1 + a2
  _ -> 0


================================================
FILE: doc/include/language-syntax/expr/sige.fnk
================================================
(:: 42 Int) ; Finkel


================================================
FILE: doc/include/language-syntax/expr/sige.hs
================================================
(42 :: Int) -- Haskell


================================================
FILE: doc/include/language-syntax/expr/string.fnk
================================================
"Here is a backslant \\ as well as \137, \
    \a numeric escape character, and \^X, a control character." ; Finkel


================================================
FILE: doc/include/language-syntax/expr/string.hs
================================================
"Here is a backslant \\ as well as \137, \
    \a numeric escape character, and \^X, a control character." -- Haskell


================================================
FILE: doc/include/language-syntax/expr/tup2.fnk
================================================
(print (, True #'x)) ; Finkel


================================================
FILE: doc/include/language-syntax/expr/tup2.hs
================================================
print (True, 'x') -- Haskell


================================================
FILE: doc/include/language-syntax/expr/tup5.fnk
================================================
(print (, True #'x 42 1.23 "foo")) ; Finkel


================================================
FILE: doc/include/language-syntax/expr/tup5.hs
================================================
print (True, 'x', 42, 1.23, "foo") -- Haskell


================================================
FILE: doc/include/language-syntax/expr/tupfn.fnk
================================================
(<*> (pure (,,,)) (Just 1) (Just 2) (Just 3) (Just 4)) ; Finkel


================================================
FILE: doc/include/language-syntax/expr/tupfn.hs
================================================
pure (,,,) <*> Just 1 <*> Just 2 <*> Just 3 <*> Just 4 -- Haskell


================================================
FILE: doc/include/language-syntax/expr/unit.fnk
================================================
(return ()) ; Finkel


================================================
FILE: doc/include/language-syntax/expr/unit.hs
================================================
return () -- Haskell


================================================
FILE: doc/include/language-syntax/expr/varid.fnk
================================================
(foo-bar-buzz quux) ; Finkel


================================================
FILE: doc/include/language-syntax/expr/varid.hs
================================================
foo_bar_buzz quux -- Haskell


================================================
FILE: doc/include/language-syntax/ffi/export.fnk
================================================
(foreign export ccall "addInt"
  (:: + (-> Int Int Int)))


================================================
FILE: doc/include/language-syntax/ffi/export.hs
================================================
foreign export ccall "addInt"
  (+) :: Int -> Int -> Int


================================================
FILE: doc/include/language-syntax/ffi/import.fnk
================================================
(foreign import ccall safe "string.h strlen" ; Finkel
  (:: cstrlen (-> (Ptr CChar) (IO CSize))))


================================================
FILE: doc/include/language-syntax/ffi/import.hs
================================================
foreign import ccall safe "string.h strlen" -- Haskell
  cstrlen :: Ptr CChar -> IO CSize


================================================
FILE: doc/include/language-syntax/import/altogether.fnk
================================================
(import qualified Data.Maybe as Mb hiding (fromJust)) ; Finkel


================================================
FILE: doc/include/language-syntax/import/altogether.hs
================================================
import qualified Data.Maybe as Mb hiding (fromJust) -- Haskell


================================================
FILE: doc/include/language-syntax/import/entity-list.fnk
================================================
(import Data.Maybe (catMaybes fromMaybe)) ; Finkel


================================================
FILE: doc/include/language-syntax/import/entity-list.hs
================================================
import Data.Maybe (catMaybes, fromMaybe) -- Haskell


================================================
FILE: doc/include/language-syntax/import/hiding.fnk
================================================
(import Data.Maybe hiding (fromJust fromMaybe)) ; Finkel


================================================
FILE: doc/include/language-syntax/import/hiding.hs
================================================
import Data.Maybe hiding (fromJust, fromMaybe) -- Haskell


================================================
FILE: doc/include/language-syntax/import/qualified-as.fnk
================================================
(import qualified Data.Maybe as Mb) ; Finkel


================================================
FILE: doc/include/language-syntax/import/qualified-as.hs
================================================
import qualified Data.Maybe as Mb -- Haskell


================================================
FILE: doc/include/language-syntax/import/simpl.fnk
================================================
(import Data.Maybe) ; Finkel


================================================
FILE: doc/include/language-syntax/import/simpl.hs
================================================
import Data.Maybe -- Haskell


================================================
FILE: doc/include/language-syntax/module/export-list.fnk
================================================
(module M2 ; Finkel
  f1           ; Value, field name, or class method
  T1           ; Type constructor only
  (T2 ..)      ; Type constructor and all of its data constructors
  (T3 T3a T3b) ; Type constructor and specified data constructors
  (T4 t4f1)    ; Type constructor and field label

  (module Data.Char)      ; Module reexport
  (Mb.Maybe Just Nothing) ; Reexport with a qualified name
  )

(import Data.Maybe as Mb)

;; ... more module contents ...


================================================
FILE: doc/include/language-syntax/module/export-list.hs
================================================
module M2 -- Haskell
  ( f1           -- Value, field name, or class method
  , T1           -- Type constructor only
  , T2(..)       -- Type constructor and all of its data constructors
  , T3(T3a, T3b) -- Type constructor and specified data constructors
  , T4(t4f1)     -- Type constructor and field label

  , module Data.Char        -- Module reexport
  , Mb.Maybe(Just, Nothing) -- Reexport with a qualified name
  ) where

import Data.Maybe as Mb

-- ... more module contents ...


================================================
FILE: doc/include/language-syntax/module/simpl.fnk
================================================
(module M1) ; Finkel
(= x 1)
(= y 2)


================================================
FILE: doc/include/language-syntax/module/simpl.hs
================================================
module M1 where -- Haskell
x = 1
y = 2


================================================
FILE: doc/include/macros/RequireMe.fnk
================================================
;;;; File: RequireMe.fnk

(defmodule RequireMe
  (export say-hello say-bye)
  (import (Finkel.Prelude)))

(defmacro say-hello []
  '(putStrLn "Hello macro!"))

(defmacro say-bye []
  '(putStrLn "Goodbye."))


================================================
FILE: doc/include/macros/arglist.console
================================================
$ finkel make -fno-code -ddump-parsed arglist.fnk

==================== Parser ====================
module Main where
main :: IO ()
main = putStrLn (unwords ["foo", "bar", "buzz"])


[1 of 1] Compiling Main             ( arglist.fnk, nothing )


================================================
FILE: doc/include/macros/arglist.fnk
================================================
;;;; File: arglist.fnk

(defmodule Main
  (import-when [:compile]
    (Finkel.Prelude)))

(eval-when [:compile]
  (defmacro puts args
    `(putStrLn (unwords [,@args]))))

(defn (:: main (IO ()))
  (puts "foo" "bar" "buzz"))


================================================
FILE: doc/include/macros/begin.console
================================================
$ finkel make -fno-code -ddump-parsed begin.fnk

==================== Parser ====================
module Main where
import Data.Proxy
data Nat = Zero | Succ Nat
type N0 = 'Zero
type N1 = 'Succ 'Zero
type N2 = 'Succ ('Succ 'Zero)
type N3 = 'Succ ('Succ ('Succ 'Zero))
type N4 = 'Succ ('Succ ('Succ ('Succ 'Zero)))
type N5 = 'Succ ('Succ ('Succ ('Succ ('Succ 'Zero))))
type N6 = 'Succ ('Succ ('Succ ('Succ ('Succ ('Succ 'Zero)))))
main :: IO ()
main = print (Proxy :: Proxy N6)


[1 of 1] Compiling Main             ( begin.fnk, nothing )


================================================
FILE: doc/include/macros/begin.fnk
================================================
;;;; File: begin.fnk

%p(LANGUAGE DataKinds)

(defmodule Main
  (import-when [:compile]
    (Finkel.Prelude))
  (import (Data.Proxy)))

(data Nat
  Zero
  (Succ Nat))

(macrolet ((nat-types [n]
             (let ((:: go (-> Int Code Int [Code]))
                   (= go stop body i
                     (if (< stop i)
                         []
                         (let ((= name (make-symbol (++ "N" (show i))))
                               (= next `('Succ ,body)))
                           (: `(type ,name ,body)
                              (go stop next (+ i 1)))))))
               (case (fromCode n)
                 (Just m) `(:begin
                             ,@(go m ''Zero 0))
                 Nothing (error "not an integer")))))
  (nat-types 6))

(defn (:: main (IO ()))
  (print (:: Proxy (Proxy N6))))


================================================
FILE: doc/include/macros/eval-when-compile.console
================================================
$ finkel make -fno-code -ddump-parsed eval-when-compile.fnk

==================== Parser ====================
module Main where
foo :: Int -> IO ()
foo n
  = do putStrLn "from foo"
       print (n + 1)
bar :: Int -> Int -> IO ()
bar a b
  = do putStrLn "from bar"
       print (a + (b * 2))
main :: IO ()
main
  = do foo 41
       bar 10 16


[1 of 1] Compiling Main             ( eval-when-compile.fnk, nothing )


================================================
FILE: doc/include/macros/eval-when-compile.fnk
================================================
;;;; File: eval-when-compile.fnk

(defmodule Main
  (import-when [:compile]
    (Finkel.Prelude)))

(:eval-when-compile
  (defn (:: wrap-actions (-> [Code] Code))
    [actions]
    `(do ,@actions)))

(macrolet ((doactions [xs]
             (case (unCode xs)
               (HsList actions) (wrap-actions actions)
               _ (error "doactions: expecting HsList"))))
  (defn (:: foo (-> Int (IO ())))
    [n]
    (doactions [(putStrLn "from foo")
                (print (+ n 1))]))
  (defn (:: bar (-> Int Int (IO ())))
    [a b]
    (doactions [(putStrLn "from bar")
                (print (+ a (* b 2)))])))

(defn (:: main (IO ()))
  (do (foo 41)
      (bar 10 16)))


================================================
FILE: doc/include/macros/eval-when.console
================================================
$ finkel make -fno-code -ddump-parsed eval-when.fnk

==================== Parser ====================
module Main where
main :: IO ()
main
  = do putStrLn ";;; eval-when ;;;"
       putStrLn "Hello macro!"
       putStrLn "Goodbye."


[1 of 1] Compiling Main             ( eval-when.fnk, nothing )


================================================
FILE: doc/include/macros/eval-when.fnk
================================================
;;; File: eval-when.fnk

(defmodule Main
  (import-when [:compile]
    (Finkel.Prelude)))

(eval-when [:compile]
  (defmacro say-hello []
    '(putStrLn "Hello macro!"))
  (defmacro say-bye []
    '(putStrLn "Goodbye.")))

(defn (:: main (IO ()))
  (do (putStrLn ";;; eval-when ;;;")
      (say-hello)
      (say-bye)))


================================================
FILE: doc/include/macros/fib-macro.console
================================================
$ finkel make -fno-code -ddump-parsed fib-macro.fnk

==================== Parser ====================
module Main where
main :: IO ()
main = print 55


[1 of 1] Compiling Main             ( fib-macro.fnk, nothing )


================================================
FILE: doc/include/macros/fib-macro.fnk
================================================
;;;; File: fib-macro.fnk

(defmodule Main
  (import-when [:compile]
    (Finkel.Prelude)))

(eval-when [:compile]
  (defn (:: fib (-> Int Int))
    [n]
    (if (< n 2)
        n
        (+ (fib (- n 1)) (fib (- n 2)))))

  (defmacro fib-macro [n]
    (case (fromCode n)
      (Just i) (toCode (fib i))
      Nothing (error "fib-macro: not an integer literal"))))

(defn (:: main (IO ()))
  (print (fib-macro 10)))


================================================
FILE: doc/include/macros/macrolet.console
================================================
$ finkel make -fno-code -ddump-parsed macrolet.fnk

==================== Parser ====================
module Main where
main :: IO ()
main
  = do putStrLn ";;; macrolet ;;;"
       putStrLn "Hello macro!"
       putStrLn "Goodbye."


[1 of 1] Compiling Main             ( macrolet.fnk, nothing )


================================================
FILE: doc/include/macros/macrolet.fnk
================================================
;;;; File: macrolet.fnk

(defmodule Main
  (import-when [:compile]
    (Finkel.Prelude)))

(macrolet ((say-hello []
             '(putStrLn "Hello macro!"))
           (say-bye []
             '(putStrLn "Goodbye.")))
  (defn (:: main (IO ()))
    (do (putStrLn ";;; macrolet ;;;")
        (say-hello)
        (say-bye))))


================================================
FILE: doc/include/macros/quasiquote.console
================================================
$ finkel make -o quasiquote quasiquote.fnk
[1 of 1] Compiling Main             ( quasiquote.fnk, quasiquote.o )
Linking quasiquote ...
$ ./quasiquote
True


================================================
FILE: doc/include/macros/quasiquote.fnk
================================================
;;;; File: quasiquote.fnk

(defmodule Main
  (import (Finkel.Prelude)))

(defn (:: with-sugar [Code])
  [`(foo ,(length "123") bar)
   `(foo ,@[True False] bar)])

(defn (:: without-sugar [Code])
  [(:quasiquote (foo (:unquote (length "123")) bar))
   (:quasiquote (foo (:unquote-splice [True False]) bar))])

(defn (:: main (IO ()))
  (print (== with-sugar without-sugar)))


================================================
FILE: doc/include/macros/quasiquote904.console
================================================
$ finkel make -o quasiquote quasiquote.fnk
[1 of 2] Compiling Main             ( quasiquote.fnk, quasiquote.o )
[2 of 2] Linking quasiquote
$ ./quasiquote
True


================================================
FILE: doc/include/macros/quote.console
================================================
$ finkel make -fno-code -ddump-parsed quote.fnk

==================== Parser ====================
module Main where
import Finkel.Prelude
main :: IO ()
main
  = do putStrLn ";;; quote ;;;"
       print (qSymbol "foo" "quote.fnk" 8 15 8 18)
       print (qSymbol "foo" "quote.fnk" 9 22 9 25)
       print (qInteger 42 "quote.fnk" 10 15 10 17)
       print (qInteger 42 "quote.fnk" 11 22 11 24)
       print (qString "string" "quote.fnk" 12 15 12 23)
       print (qString "string" "quote.fnk" 13 22 13 30)


[1 of 1] Compiling Main             ( quote.fnk, nothing )


================================================
FILE: doc/include/macros/quote.fnk
================================================
;;;; File: quote.fnk

(defmodule Main
  (import (Finkel.Prelude)))

(defn (:: main (IO ()))
  (do (putStrLn ";;; quote ;;;")
      (print 'foo)
      (print (:quote foo))
      (print '42)
      (print (:quote 42))
      (print '"string")
      (print (:quote "string"))))


================================================
FILE: doc/include/macros/raw-require.console
================================================
$ finkel make -fno-code -ddump-parsed raw-require.fnk

==================== Parser ====================
module Main where
main :: IO ()
main
  = do putStrLn ";;; raw-require.fnk ;;;"
       putStrLn "Hello macro!"
       putStrLn "Goodbye."


[1 of 1] Compiling Main             ( raw-require.fnk, nothing )


================================================
FILE: doc/include/macros/raw-require.fnk
================================================
;;;; File: raw-require.fnk

(:require Finkel.Prelude)

(defmodule Main)

(eval-when [:compile]
  (defmacro say-hello []
    '(putStrLn "Hello macro!"))
  (defmacro say-bye []
    '(putStrLn "Goodbye.")))

(defn (:: main (IO ()))
  (do (putStrLn ";;; raw-require.fnk ;;;")
      (say-hello)
      (say-bye)))


================================================
FILE: doc/include/macros/require.console
================================================
$ finkel make -no-link -fno-code require.fnk
(*) [1 of 1] Compiling RequireMe        ( RequireMe.fnk, interpreted )

==================== Parser ====================
module Main where
main :: IO ()
main
  = do putStrLn ";;; require ;;;"
       putStrLn "Hello macro!"
       putStrLn "Goodbye."


[1 of 1] Compiling Main             ( require.fnk, nothing )


================================================
FILE: doc/include/macros/require.fnk
================================================
;;;; File: require.fnk

%p(OPTIONS_GHC -ddump-parsed)

(defmodule Main
  (require
   (RequireMe (say-hello say-bye))))

(defn (:: main (IO ()))
  (do (putStrLn ";;; require ;;;")
      (say-hello)
      (say-bye)))


================================================
FILE: doc/include/macros/unquote-splice.console
================================================
$ finkel make -fno-code -ddump-parsed unquote-splice.fnk

==================== Parser ====================
module Main where
main :: IO ()
main
  = do putStrLn (concat ["foo", "bar", "buzz"])
       putStrLn (concat ["foo", "bar", "buzz"])


[1 of 1] Compiling Main             ( unquote-splice.fnk, nothing )


================================================
FILE: doc/include/macros/unquote-splice.fnk
================================================
;;;; File: unquote-splice.fnk

(defmodule Main
  (import-when [:compile]
    (Finkel.Prelude)))

(eval-when [:compile]
  (defmacro uqs [arg]
    `(putStrLn (concat [,@arg]))))

(defn (:: main (IO ()))
  (do (uqs ("foo" "bar" "buzz"))
      (uqs ["foo" "bar" "buzz"])))


================================================
FILE: doc/include/macros/unquote.console
================================================
$ finkel make -fno-code -ddump-parsed unquote.fnk

==================== Parser ====================
module Main where
main :: IO ()
main
  = do putStrLn ("uq1: arg = " ++ show "foo")
       putStrLn "uq2: arg = \"bar\""


[1 of 1] Compiling Main             ( unquote.fnk, nothing )


================================================
FILE: doc/include/macros/unquote.fnk
================================================
;;;; File: unquote.fnk

(defmodule Main
  (import-when [:compile]
    (Finkel.Prelude)))

(eval-when [:compile]
  (defmacro uq1 [arg]
    `(putStrLn (++ "uq1: arg = " (show ,arg))))

  (defmacro uq2 [arg]
    `(putStrLn ,(++ "uq2: arg = " (show arg)))))

(defn (:: main (IO ()))
  (do (uq1 "foo")
      (uq2 "bar")))


================================================
FILE: doc/index.rst
================================================
The Finkel Documentation
========================

Introduction
------------

Finkel is a statically typed, purely functional,
and non-strict-by-default `LISP
<https://en.wikipedia.org/wiki/Lisp_(programming_language)>`_
flavored programming language. Or in other words, `Haskell
<https://haskell.org>`_ **in S-expression**. [#f1]_

Finkel has the following features:

* Integration with existing Haskell modules.

* Building Haskell-compatible `Cabal
  <https://www.haskell.org/cabal/>`_ packages.

* Documentation generation with `Haddock
  <https://www.haskell.org/haddock/>`_.

* Lisp style macro system.

* Tool executable, including interactive REPL.

..
   And following anti-features:

   * CPP language extension

The capital lettered term Finkel is used to refer to the programming
language itself, and the quoted ``finkel`` is used to refer an
executable program to work with the language. This documentation
briefly introduces the ``finkel`` executable and the language, just
enough to get started.  Readers of this documentation are assumed to
have some basic knowledge of the Unix-like environment and have some
programming experiences with Haskell.


.. toctree::
   :maxdepth: 2
   :caption: Contents:

   contents/install.rst
   contents/finkel-executable.rst
   contents/building-package.rst
   contents/macros.rst
   contents/language-syntax.rst

..  ==================
    Indices and tables
    ==================
    * :ref:`genindex`
    * :ref:`search`


.. rubric:: Footnotes

.. [#f1] More precisely, `GHC <https://www.haskell.org/ghc/>`_ in
   S-expression.


================================================
FILE: doc/make.bat
================================================
@ECHO OFF

pushd %~dp0

REM Command file for Sphinx documentation

if "%SPHINXBUILD%" == "" (
	set SPHINXBUILD=sphinx-build
)
set SOURCEDIR=.
set BUILDDIR=_build

if "%1" == "" goto help

%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
	echo.
	echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
	echo.installed, then set the SPHINXBUILD environment variable to point
	echo.to the full path of the 'sphinx-build' executable. Alternatively you
	echo.may add the Sphinx directory to PATH.
	echo.
	echo.If you don't have Sphinx installed, grab it from
	echo.http://sphinx-doc.org/
	exit /b 1
)

%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
goto end

:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%

:end
popd


================================================
FILE: doc/requirements.txt
================================================
sphinx==3.5.3
sphinx_rtd_theme==0.5.2


================================================
FILE: doc/test/Doc/BuildingPackage.hs
================================================
;;; -*- mode: finkel -*-
;;;; Test codes for "building-package.rst".

(defmodule Doc.BuildingPackage
  (export spec)
  (import
   ;; base
   (Control.Exception [bracket])
   (Control.Monad [zipWithM_])
   (Data.Char (isSpace))
   (Data.Function [on])
   (Data.List [isPrefixOf sort])
   (System.Exit [(ExitCode ..)])
   (System.Process [(CreateProcess ..) createProcess proc waitForProcess])

   ;; directory
   (System.Directory
    [canonicalizePath doesDirectoryExist doesFileExist getTemporaryDirectory
     listDirectory removeDirectoryRecursive])

   ;; filepath
   (System.FilePath [</> takeExtension takeFileName])

   ;; hspec
   (Test.Hspec [(Spec) describe expectationFailure it pendingWith shouldBe])

   ;; Internal
   (Doc.TestAux)))


;;; Spec

(defn (:: spec Spec)
  (describe "building cabal package"
    (it "matches package made with hsfiles template"
      (case-do get-build-tool
        Cabal (pendingWith "not running with cabal-install")
        Raw (pendingWith "not running with raw build")
        Stack compare-new-package))))


;;; Auxiliary

(defn (:: compare-new-package (IO ()))
  (bracket make-tmp-dir
           remove-tmp-dir
           compare-package-dirs))

(defn (:: make-tmp-dir (IO (, FilePath String)))
  (fmap (flip (,) "my-new-package") getTemporaryDirectory))

(defn (:: remove-tmp-dir (-> (, FilePath String) (IO ())))
  (. removeDirectoryRecursive (uncurry </>)))

(defn (:: compare-package-dirs (-> (, FilePath String) (IO ())))
  [(, tmpdir pkgname)]
  (case-do (stack-new tmpdir pkgname)
    ;; Ignoring "stack.yaml", since the file contains version number of the
    ;; stack executable, which may change when the stack was upgraded.
    ;;
    ;; XXX: This approach will make the tests to pass. However, cannot detect
    ;; the validity of stack.yaml file, so consider taking different way to pass
    ;; the test.
    (Right ExitSuccess) (compare-directory-contents
                         ["stack.yaml"]
                         (</> "include" "building-package" pkgname)
                         (</> tmpdir pkgname))
    (Right ec) (expectationFailure (++ "stack new failed with " (show ec)))
    (Left msg) (expectationFailure msg)))

(defn (:: compare-directory-contents (-> [FilePath] FilePath FilePath (IO ())))
  "Recursively compare directory contents."
  [ignored path1 path2]
  (if (elem (takeFileName path1) ignored)
      (return ())
      (do (<- path1-is-file (doesFileExist path1))
          (<- path2-is-file (doesFileExist path2))
          (if (&& path1-is-file path2-is-file
                  (notElem (takeFileName path1) ignored))
              (do (<- contents1 (readFile path1))
                  (<- contents2 (readFile path2))
                  (on shouldBe trim contents1 contents2))
              (do (<- path1-is-dir (doesDirectoryExist path1))
                  (<- path2-is-dir (doesDirectoryExist path2))
                  (if (&& path1-is-dir path2-is-dir)
                      (do (<- ls1 (list-directory path1))
                          (<- ls2 (list-directory path2))
                          (lept [add-dir (. map </>)
                                 ls1' (add-dir path1 ls1)
                                 ls2' (add-dir path2 ls2)])
                          (zipWithM- (compare-directory-contents ignored)
                                     ls1' ls2'))
                      (expectationFailure
                       (++ "differed: " path1 ", " path2))))))))

(defn (:: trim (-> String String))
  "Trim white spaces at the beginning and end."
  (. (dropWhile isSpace) reverse (dropWhile isSpace) reverse))

(defn (:: list-directory (-> FilePath (IO [FilePath])))
  "List directory contents, filter outs some ignored files."
  (lefn [(ignored [path]
           (&& (/= ".stack-work" path)
               (/= ".tix" (takeExtension path))))]
    (. (fmap (. sort (filter ignored))) listDirectory)))

(defn (:: stack-new (-> FilePath String (IO (Either String ExitCode))))
  "Run stack new command to generate new package."
  [dir pkgname]
  (do (<- template get-template-path)
      (<- mb-resolver (get-resolver-version pkgname))
      (case mb-resolver
        (Just resolver) (fmap Right
                              (run (Just dir)
                                   "stack" ["--resolver" resolver "--silent"
                                            "new" pkgname
                                            "--omit-packages" template]))
        Nothing (return (Left "Failed to get the resolver version")))))

(defn (:: get-template-path (IO FilePath))
  "Get canonicalized template path."
  ;; XXX: May move template to separate repository to support
  ;; `github:finkel-lang/simple' style template argument.
  ;;
  ;; See: https://docs.haskellstack.org/en/stable/GUIDE/#templates
  ;;
  (canonicalizePath (</> ".." "finkel-tool" "finkel.hsfiles")))

(defn (:: get-resolver-version (-> String (IO (Maybe String))))
  "Get stack resolver version from YAML file used in `my-new-package'."
  [pkgname]
  (lept [yaml-path (</> "include" "building-package" pkgname "stack.yaml")
         resolver-line (. (concatMap words)
                          (filter (isPrefixOf "resolver:"))
                          lines)]
    (case-do (fmap resolver-line (readFile yaml-path))
      [_ version] (return (Just version))
      _ (return Nothing))))

(defn (:: run (-> (Maybe String) String [String] (IO ExitCode)))
  "Run command and wait."
  [mb-dir cmd args]
  (do (<- (, _mbin _mbout _mberr ph)
        (createProcess ((proc cmd args) {(= cwd mb-dir)})))
      (waitForProcess ph)))


================================================
FILE: doc/test/Doc/FinkelExecutable.hs
================================================
;;; -*- mode: finkel -*-
;;;; Test codes for "finkel-executable.rst".

(defmodule Doc.FinkelExecutable
  (export spec)
  (import
   ;; base
   (Data.Version [makeVersion])
   (System.Info [os])

   ;; filepath
   (System.FilePath [</>])

   ;; hspc
   (Test.Hspec [(Spec) before_ describe])

   ;; Internal
   (Doc.TestAux)))

(defn (:: spec Spec)
  (lept [dir (</> "include" "finkel-executable")
         const2 (\ x _ _ x)
         is-osx (== os "darwin")
         is-win (== os "mingw32")
         ghc904 (makeVersion [9 4 0])
         skips
         [(, "finkel-help-make.console" (const2 is-win))
          (, "hello.console"
             (\version _
               (|| is-osx is-win
                   (< ghc904 version))))
          (, "hello904.console"
             (\version _
               (|| is-osx is-win
                   (< version ghc904))))
          (, "hello-prof.console"
             (\ version _build-tool
               ;; XXX: Always skipping
               (|| is-win
                   ;; Skipping in ghc >= 9.0 ...
                   (<= (makeVersion [9 0]) version))))]]
    (before_
     (remove-compiled [(</> dir "hello")])
     (describe "using the finkel executable"
       (run-console-tests dir skips)))))


================================================
FILE: doc/test/Doc/LanguageSyntax.hs
================================================
;;; -*- mode: finkel -*-
;;;; Test codes for "language-syntax.rst"

;;; This module contains codes to tests the code snippets shown in the "Language
;;; Syntax" chapter of the documentation. The tests parses expressions and
;;; declarations from file, and parse the Haskell code and Finkel code, then
;;; compare the parsed results with `showPpr'.

(defmodule Doc.LanguageSyntax
  (export spec)
  (import-when [:compile]
    ;; finkel-lang
    (Finkel.Prelude))
  (import
   ;; base
   (Data.List [sort])

   ;; directory
   (System.Directory [listDirectory])

   ;; filepath
   (System.FilePath [</> <.> dropExtension takeExtension])

   ;; finkel-kernel
   (Language.Finkel.Builder [(Builder) evalBuilder])
   (Language.Finkel.Reader [parseSexprs])
   (qualified Language.Finkel.Syntax as FnkParser)

   ;; hspec
   (Test.Hspec [(Spec) (SpecWith) beforeAll describe expectationFailure it runIO
                shouldBe])

   ;; Internal
   (Doc.TestAux)))

;; ghc

(import GHC (DynFlags getSessionDynFlags runGhc))

(cond-expand
  [(<= 902 :ghc)
   (import GHC.Driver.Ppr (showPpr))]
  [(<= 900 :ghc)
   (import GHC.Utils.Outputable (showPpr))]
  [otherwise
   (import Outputable (showPpr))])

(cond-expand
  [(<= 900 :ghc)
   (:begin
     (import GHC.Data.FastString (fsLit))
     (import GHC.Utils.Outputable ((Outputable ..)))
     (import GHC.Parser.Lexer ((P ..) (ParseResult ..)))
     (import GHC.Types.SrcLoc ((GenLocated ..) mkRealSrcLoc interactiveSrcSpan))
     (import GHC.Data.StringBuffer (hGetStringBuffer))
     (import qualified GHC.Parser as GhcParser)
     (import qualified GHC.Parser.Lexer as GhcLexer))]
  [otherwise
   (:begin
     (import FastString (fsLit))
     (import Outputable ((Outputable ..)))
     (import Lexer ((P ..) (ParseResult ..)))
     (import SrcLoc ((GenLocated ..) mkRealSrcLoc interactiveSrcSpan))
     (import StringBuffer (hGetStringBuffer))
     (import qualified Parser as GhcParser)
     (import qualified Lexer as GhcLexer))])

(cond-expand
  [(<= 904 :ghc)
   (:begin
     (import GHC.Driver.Config.Parser (initParserOpts))
     (import GHC.Parser.PostProcess ((ECP ..) runPV)))]
  [(<= 902 :ghc)
   (:begin
     (import GHC.Driver.Config (initParserOpts))
     (import GHC.Parser.PostProcess ((ECP ..) runPV)))]
  [(<= 900 :ghc)
   (import GHC.Parser.PostProcess (runECP-P))]
  [otherwise
   (import RdrHsSyn (runECP-P))])


;;; Functions

(defn (:: spec Spec)
  (beforeAll
   ;; Running `runGhc' to set the `unsafeGlobalDynFlags' with `initGhcMonad'.
   (do (<- mb-ghc-lib get-ghc-lib)
       (runGhc mb-ghc-lib getSessionDynFlags))
   (describe "language syntax"
     (do (lept [expFromECP (cond-expand
                             ;; The function `runECP_P' was added in ghc 8.10.x,
                             ;; and removed in ghc 9.2.1. Using explicit lambda
                             ;; for `runPV' and `unECP' to make the type
                             ;; concrete.
                             [(<= 902 :ghc) (\p (runPV (unECP p)))]
                             [otherwise runECP-P])])
         (describe "expression"
           (parser-tests "expr" (Parsers (>>= GhcParser.parseExpression
                                              expFromECP)
                                         FnkParser.parseExpr)))
         (describe "declaration"
           (parser-tests "decl" (Parsers (fmap pure GhcParser.parseDeclaration)
                                         FnkParser.parseTopDecls)))
         (describe "module"
           (parser-tests "module" (Parsers GhcParser.parseModule
                                           (fmap (L interactiveSrcSpan)
                                                 FnkParser.parseModule))))
         (describe "import"
           (parser-tests "import" (Parsers (fmap pure GhcParser.parseImport)
                                           FnkParser.parseImports)))
         (describe "ffi"
           (parser-tests "ffi" (Parsers (fmap pure GhcParser.parseDeclaration)
                                        FnkParser.parseTopDecls)))))))

(defn (:: parser-tests
        (=> (Outputable a) (-> FilePath (Parsers a) (SpecWith DynFlags))))
  [subdir parsers]
  (do (lefn [(run-it [name]
               (it (++ "should parse tests in " name)
                 (\dflags
                   (parser-test dflags parsers (</> (language-dir subdir) name)))))])
      (<- files (runIO (list-base-names (language-dir subdir))))
      (mapM_ run-it files)))

(data (Parsers a)
  (Parsers {(:: hs-parser (P a))
            (:: fnk-parser (Builder a))}))

(defn (:: parser-test
        (=> (Outputable a) (-> DynFlags (Parsers a) FilePath (IO ()))))
  [dflags parsers basename]
  (do (lept [fnk (<.> basename "fnk")
             hs (<.> basename "hs")])
      (<- buf (hGetStringBuffer hs))
      (lept [loc (mkRealSrcLoc (fsLit "<test>") 1 1)
             ps (cond-expand
                  [(<= 902 :ghc)
                   (GhcLexer.initParserState (initParserOpts dflags) buf loc)]
                  [otherwise
                   (GhcLexer.mkPState dflags buf loc)]) ])
      (case (GhcLexer.unP (hs-parser parsers) ps)
        (POk _st hres) (do (<- fstr (parse-fnk dflags parsers fnk))
                           (shouldBe fstr (showPpr dflags hres)))
        _ (expectationFailure "failed to parse haskell code"))))

(defn (:: parse-fnk
        (=> (Outputable a)
            (-> DynFlags (Parsers a) FilePath (IO String))))
  [dflags parser path]
  (do (<- buf (hGetStringBuffer path))
      (<- (, forms _sp) (parseSexprs (Just path) buf))
      (case (evalBuilder dflags False (fnk-parser parser) forms)
        (Right fexp) (return (showPpr dflags fexp))
        (Left err) (return (show err)))))

(defn (:: language-dir (-> String FilePath))
  [subdir]
  (</> "include" "language-syntax" subdir))

(defn (:: list-base-names (-> FilePath (IO [FilePath])))
  [dir]
  (do (<- files (listDirectory dir))
      (return
       (sort [(dropExtension file)
              | (<- file files) (== ".fnk" (takeExtension file))]))))


================================================
FILE: doc/test/Doc/Macros.hs
================================================
;;; -*- mode: finkel -*-
;;;; Test codes for "macros.rst"

(defmodule Doc.Macros
  (export spec)
  (import
   ;; base
   (Data.Version [makeVersion])
   (System.Info [os])

   ;; filepath
   (System.FilePath [</>])

   ;; hspec
   (Test.Hspec [(Spec) beforeAll_ describe])

   ;; Internal
   (Doc.TestAux)))

(defn (:: spec Spec)
  (lept [dir (</> "include" "macros")
         is-osx-or-win (|| (== os "darwin") (== os "mingw32"))
         skips [(, "begin.console"
                   (\version _
                     (> (makeVersion [8 8 0]) version)))
                (, "quasiquote.console"
                   (\version _
                     (|| is-osx-or-win
                         (<= (makeVersion [9 4 0]) version))))
                (, "quasiquote904.console"
                   (\version _
                     (|| is-osx-or-win
                         (< version (makeVersion [9 4 0])))))]]
    (beforeAll_
     (remove-compiled [(</> dir "quasiquote")
                       (</> dir "require")
                       (</> dir "RequireMe")])
     (describe "macros in finkel"
       (run-console-tests dir skips)))))


================================================
FILE: doc/test/Doc/TestAux.hs
================================================
;;; -*- mode: finkel -*-
;;;; Auxiliary codes for tests.

(defmodule Doc.TestAux
  (export (BuildTool ..)
          get-build-tool
          get-stack-resolver
          get-ghc-lib
          run-console-tests
          run-console-test
          remove-compiled)
  (import-when [:compile]
   ;; finkel-core
   (Finkel.Prelude))
  (import
   ;; base
   (Control.Exception [catch throw])
   (Control.Monad [unless when])
   (Data.List [isSubsequenceOf isPrefixOf sort])
   (Data.Maybe [fromMaybe])
   (Data.Version [(Version ..) parseVersion])
   (System.Environment [getExecutablePath lookupEnv])
   (System.Exit [(ExitCode ..)])
   (System.IO [hGetContents hGetLine])
   (Text.ParserCombinators.ReadP [readP-to-S])

   ;; directory
   (System.Directory [listDirectory removeFile])
   (System.Directory.Internal.Prelude [isDoesNotExistError])

   ;; filepath
   (System.FilePath [</> <.> takeExtension])

   ;; hspc
   (Test.Hspec
    [(Expectation) (Spec) expectationFailure it pendingWith runIO shouldBe])

   ;; process
   (System.Process
    [(CreateProcess ..) (StdStream ..) createProcess proc waitForProcess])))

(cond-expand
  [(<= 900 :ghc)
   (import GHC.Settings.Config (cProjectVersion))]
  [otherwise
   (import Config (cProjectVersion))])

;;; Exported

(defn (:: remove-compiled (-> [String] (IO ())))
  "Remove given compiled files if exist.
Remove the given file @FILE@, @FILE.o@, and @FILE.hi@."
  [name]
  (lefn [(go0 [exe]
           (mapM go1 [exe
                      (<.> exe "o")
                      (<.> exe "hi")
                      (<.> exe "dyn_o")
                      (<.> exe "dyn_hi")]))
         (go1 [file]
           (catch (removeFile file)
             (\e
               (unless (isDoesNotExistError e)
                 (throw e)))))]
    (mapM_ go0 name)))

(defn (:: get-build-tool (IO BuildTool))
  "Get the running `BuildTool'."
  (do (<- me getExecutablePath)
      (pure (cond
              [(isSubsequenceOf ".stack" me) Stack]
              [(isSubsequenceOf "dist-newstyle" me) Cabal]
              [otherwise Raw]))))

(defn (:: get-stack-resolver (IO String))
  "Return @RESOLVER@ environment variable."
  (fmap (fromMaybe "lts-16") (lookupEnv "RESOLVER")))

(defn (:: get-ghc-lib (IO (Maybe FilePath)))
  (do (<- build-tool get-build-tool)
      (<- p0
        (case build-tool
          Cabal (return (proc "cabal" ["v2-exec" "--" "ghc" "--print-libdir"]))
          Stack (do (<- resolver get-stack-resolver)
                    (return (proc "stack" ["--resolver" resolver "exec" "--"
                                           "ghc" "--print-libdir"])))
          Raw (return (proc "ghc" ["--print-libdir"]))))
      (lept [p1 (p0 {(= std-out CreatePipe)})])
      (<- (, _mb-in mb-out _mb-err ph) (createProcess p1))
      (<- _ec (waitForProcess ph))
      (case mb-out
        (Just out) (fmap pure (hGetLine out))
        Nothing (return Nothing))))

(:doc "List of pair of name and condition for skipping console test.

Pair of cosole filename (without the directory, with extension) and a function
taking GHC version. If the function evaluates to `True', the console test will
be skipped.")
(type ConsoleSkip [(, String (-> Version BuildTool Bool))])

(defn (:: get-console-files (-> FilePath (IO [FilePath])))
  (lept [is-console-file (. (== ".console") takeExtension)]
    (. (fmap (. sort (filter is-console-file))) listDirectory)))

(defn (:: run-console-tests (-> FilePath ConsoleSkip Spec))
  "Run test for @*.console@ files in given directory."
  [dir skips]
  (do (lefn [(test [build-tool file]
               (it (++ "runs " file " successfully")
                 (case (do (<- f (lookup file skips))
                           (<- v mb-ghc-version)
                           (return (f v build-tool)))
                   (Just True) (pendingWith "skipped")
                   _ (run-console-test dir file))))
             (mb-ghc-version
               (case (filter (. null snd)
                             (readP-to-S parseVersion cProjectVersion))
                 (: (, v _) _) (Just v)
                 _ Nothing))])
      (<- console-files (runIO (get-console-files dir)))
      (<- build-tool (runIO get-build-tool))
      (mapM_ (test build-tool) console-files)))

(data BuildTool
  ;; | This package is build with `cabal-install'.
  Cabal

  ;; | This package is build with `stack'.
  Stack

  ;; | This package is build with raw invokation of available commands.
  Raw
  (deriving Eq))

(defn (:: run-console-test (-> FilePath ; ^ Directory to run the command.
                               FilePath ; ^ Console file.
                               Expectation))
  [dir file]
  (do (<- contents (readFile (</> dir file)))
      (<- build-tool get-build-tool)
      (<- finkel
        (case build-tool
          Cabal (return (, "cabal" ["v2-exec" "-v0" "--" "finkel"]))
          Stack (do (<- resolver get-stack-resolver)
                    (return (, "stack" ["--resolver" resolver "--silent"
                                        "exec" "--" "finkel"])))
          Raw (return (, "finkel" []))))
      (lept [tests (parse-console contents)
             aliases [(, "finkel" finkel)]])
      (mapM_ (run-console dir aliases) tests)))

(data ConsoleTest
  (ConsoleTest String           ; ^ The command.
               [String]         ; ^ Arguments passed to the command.
               [String])        ; ^ Expected output lines.
  (deriving Eq Show))

(defn (:: run-console
        (-> String                           ; ^ Directory to run the test
            [(, String (, String [String]))] ; ^ Alias for command.
            ConsoleTest                      ; ^ The test.
            (IO ())))
  [dir aliases (ConsoleTest cmd args expected)]
  (do (lept [(, cmd' args') (case (lookup cmd aliases)
                              (Just (, rc ra)) (, rc (++ ra args))
                              Nothing (, cmd args))])
      (<- (, _mbin mbout mberr ph)
        (createProcess ((proc cmd' args') {(= cwd (Just dir))
                                           (= std-out CreatePipe)})))
      (<- ec (waitForProcess ph))
      (<- errs (case mberr
                 (Just hdl) (hGetContents hdl)
                 Nothing (return "")))
      (when (not (null errs))
        (putStrLn (++ "stderr: " errs)))
      (<- outs0 (case mbout
                 (Just out) (fmap lines (hGetContents out))
                 Nothing (return [])))
      (lept [outs1 (remove-loaded-package-env outs0)])
      (case ec
        ExitSuccess (shouldBe (unlines outs1) (unlines expected))
        _ (expectationFailure (++ "Got exit code " (show ec))))))

(defn (:: remove-loaded-package-env (-> [String] [String]))
  "In ghc-8.10.1, the `Loaded package environment from ...' message has changd
  its output from stderr to stdout. Removing the message line from command
  outputs."
  (filter (. not (isPrefixOf "Loaded package environment from"))))

(defn (:: parse-console (-> String [ConsoleTest]))
  "Parse the contents of console file."
  (lefn [(go [ls]
           (case (span is-cmd-line ls)
             (, (: cl _) r0) (case (words (drop 1 cl))
                               (: cmd args) (case (break is-cmd-line r0)
                                              (, os r1) (: (ct cmd args os)
                                                           (go r1)))
                               _ (go r0))
             _ []))
         (ct ConsoleTest)]
    (. go lines)))

(defn (:: is-cmd-line (-> String Bool))
  "True if the line starts with @$@."
  [(: #'$ _)] True
  [_] False)


================================================
FILE: doc/test/Doc.hs
================================================
;;; -*- mode: finkel -*-
(defmodule Doc
  (export main)
  (import
   ;; hspec
   (Test.Hspec (hspec))

   ;; Internal
   (qualified Doc.FinkelExecutable)
   (qualified Doc.BuildingPackage)
   (qualified Doc.Macros)
   (qualified Doc.LanguageSyntax)))

(defn (:: main (IO ()))
  (hspec (do Doc.FinkelExecutable.spec
             Doc.BuildingPackage.spec
             Doc.Macros.spec
             Doc.LanguageSyntax.spec)))


================================================
FILE: doc/test/Spec.hs
================================================
;;; -*- mode: finkel -*-

(defmodule Main
  (import
   (qualified Doc)))

(defn (:: main (IO ()))
  Doc.main)


================================================
FILE: finkel/CHANGELOG.md
================================================
# Revision history for finkel

## 0.1.0.0 -- YYYY-mm-dd

* First version. Released on an unsuspecting world.


================================================
FILE: finkel/LICENSE
================================================
Copyright (c) 2020-2022, 8c6794b6

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.

    * Redistributions in binary form must reproduce the above
      copyright notice, this list of conditions and the following
      disclaimer in the documentation and/or other materials provided
      with the distribution.

    * Neither the name of the copyright holder nor the names of other
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

================================================
FILE: finkel/Main.hs
================================================
import Finkel.Tool.Main (defaultMain)

main :: IO ()
main = defaultMain


================================================
FILE: finkel/README.md
================================================
# finkel

Package for the @finkel@ executable.

See the [documentation](https://finkel.readthedocs.org) for more info


================================================
FILE: finkel/Setup.hs
================================================
import Distribution.Simple
main = defaultMain


================================================
FILE: finkel/finkel.cabal
================================================
cabal-version:       2.0
name:                finkel
version:             0.0.0
synopsis:            Haskell in S-expression
license:             BSD3
license-file:        LICENSE
author:              8c6794b6
maintainer:          8c6794b6@gmail.com
copyright:           2020-2022 8c6794b6
category:            Language
build-type:          Simple
extra-source-files:  CHANGELOG.md
                     README.md

description:
  Package for the @finkel@ executable.
  .
  See the <https://finkel.readthedocs.org documentation> for more info.

executable finkel
  main-is:             Main.hs
  build-depends:       base        >= 4.14 && < 5
                     , finkel-tool == 0.0.0
  default-language:    Haskell2010
  ghc-options:         -Wall -threaded
                       -rtsopts=all
                       "-with-rtsopts=-K512M -H -I5 -T"

source-repository head
  type:     git
  location: https://github.com/finkel-lang/finkel.git
  subdir:   finkel


================================================
FILE: finkel-core/LICENSE
================================================
Copyright (c) 2017-2022, 8c6794b6

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.

    * Redistributions in binary form must reproduce the above
      copyright notice, this list of conditions and the following
      disclaimer in the documentation and/or other materials provided
      with the distribution.

    * Neither the name of the copyright holder nor the names of other
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

================================================
FILE: finkel-core/README.md
================================================
# finkel-core

Core language macro for Finkel.

See the [documentation][doc] for more details.

[doc]: https://finkel.readthedocs.io/en/latest/


================================================
FILE: finkel-core/Setup.hs
================================================
import Distribution.Simple (defaultMain)
main = defaultMain


================================================
FILE: finkel-core/finkel-core.cabal
================================================
cabal-version:       2.0
name:                finkel-core
version:             0.0.0
synopsis:            Finkel language core
description:
  Finkel language core macros and functions
  .
  See the <https://finkel.readthedocs.org documentation> for more info.

homepage:            https://github.com/finkel-core/finkel#readme
license:             BSD3
license-file:        LICENSE
author:              8c6794b6
maintainer:          8c6794b6@gmail.com
copyright:           2017-2022 8c6794b6
category:            Language
build-type:          Simple
extra-source-files:  README.md
                     --
                     test/data/plugin/*.hs

tested-with:           GHC == 8.10.7
                     , GHC == 9.0.1
                     , GHC == 9.2.8
                     , GHC == 9.4.7
                     , GHC == 9.6.5
                     , GHC == 9.8.2
                     , GHC == 9.10.1

library
  hs-source-dirs:      src
  exposed-modules:     Finkel.Core
                       Finkel.Core.Functions
                       Finkel.Core.Internal
                       Finkel.Core.Plugin
                       Finkel.Prelude
                       Paths_finkel_core
  other-modules:       Finkel.Core.Internal.Stage0
                       Finkel.Core.Internal.Stage1
                       Finkel.Core.Internal.Stage2
                       Finkel.Core.Internal.Ghc
                       Finkel.Core.Internal.Ghc.Compat
                       Finkel.Core.Internal.Ghc.Version
  autogen-modules:     Paths_finkel_core

  build-depends:       base          >= 4.14   && < 5
                     , ghc           >= 8.10.0 && < 9.11
                     , finkel-kernel == 0.0.0
  -- To import "GHC.PackageDb.packageVersion"
  if impl (ghc <= 9.0.0)
    build-depends:     ghc-boot      >= 8.2.0 && < 9

  default-language:    Haskell2010

  build-tool-depends:  fnkpp:fnkpp == 0.0.0
  ghc-options:         -Wall
                       -F -pgmF fnkpp -optF --no-warn-interp
                       -fplugin Language.Finkel.Plugin
  if impl (ghc >= 9.6.0)
    ghc-options:       -keep-hscpp-files

test-suite finkel-core-test
  type:                exitcode-stdio-1.0
  hs-source-dirs:      test
  main-is:             Spec.hs
  other-modules:       Orphan
                       CoreTest
                       FunctionTest
                       PluginTest
                       TestAux
  build-depends:       base
                     , ghc
                     , finkel-core
                     , finkel-kernel
                     --
                     , QuickCheck >= 2.10.1 && < 2.16
                     , directory  >= 1.3    && < 1.4
                     , filepath   >= 1.4    && < 1.6
                     , hspec      >= 2.4.8  && < 2.12

  default-language:    Haskell2010

  -- Known not to work ..., disabling the test under Windows with ghc >= 9.4.
  -- The test requires object files of this package built with "-dynamic"
  -- option, which does not work well under Windows.
  if impl (ghc >= 9.4.0) && os(windows)
    buildable: False

  build-tool-depends:  fnkpp:fnkpp == 0.0.0
  ghc-options:         -Wall -threaded -rtsopts -with-rtsopts=-N
                       -F -pgmF fnkpp -optF --warn-interp=False
                       -fplugin Language.Finkel.Plugin
  if impl (ghc >= 9.6.0)
    ghc-options:       -keep-hscpp-files

source-repository head
  type:     git
  location: https://github.com/finkel-lang/finkel.git
  subdir:   finkel-core


================================================
FILE: finkel-core/src/Finkel/Core/Functions.hs
================================================
;;; -*- mode: finkel -*-
;;;; Exported functions defined in this package

(:doc "Module for exporting functions defined in the @finkel-core@ package.

This module does not export macros, but exports some of the functions to work
with code values when writing macros.")

(module Finkel.Core.Functions
  (:dh1 "Predicates")
  is-atom is-pair is-list is-hslist
  is-symbol is-string is-char is-integer is-fractional is-unit
  caris

  (:dh1 "Atom constructors")
  make-symbol

  (:dh1 "Atom extractors")
  mb-symbol-name mb-symbol-name-fs

  (:dh1 "Code constructors")
  cons list (Listable ..)

  (:dh1 "CXrs")
  (:dh2 "Basic cXrs")
  car cdr

  (:dh2 "Composed cXrs")
  (:doc$ cxr)

  caar cadr
  caaar caadr cadar caddr
  caaaar caaadr caadar caaddr cadaar cadadr caddar cadddr

  cdar cddr
  cdaar cdadr cddar cdddr
  cdaaar cdaadr cdadar cdaddr cddaar cddadr cdddar cddddr

  (:dh1 "Converting")
  curve rev unsnoc

  (:dh1 "Higher order functions")
  reduce reduce1 map1 keep trav1 omni omniM

  (:dh1 "Exceptions")
  (FinkelListException ..) unsafeFinkelSrcError)

;; Internal
(import Finkel.Core.Internal.Stage0)
(import Finkel.Core.Internal.Stage2)

(:doc$ cxr "The `car' and `cdr' are the basic of /cxr/ functions.
Rest of the /cxr/ functions are composed from `car' and `cdr'.

E.g., definition of `cadr' is:

> (cadr x) == (car (cdr x))

and the definition of `cdadr' is:

> (cdadr x) == (cdr (car (cdr x)))")


================================================
FILE: finkel-core/src/Finkel/Core/Internal/Ghc/Compat.hs
================================================
{-# LANGUAGE CPP #-}
-- Module to re-export functions from ghc

module Finkel.Core.Internal.Ghc.Compat
  (
    -- GHC
    getModuleInfo, lookupModule, lookupName, modInfoExports,

    -- GHC.Data.FastString
    FastString, fsLit, unpackFS, nullFS,

    -- GHC.Driver.Env
    HscEnv(..),

    -- GHC.Driver.Monad
    GhcMonad(..),

    -- GHC.Driver.Ppr
    showSDoc,

    -- GHC.Plugin
    Plugin(..),

    -- GHC.Types.SourceText
    SourceText(..),

    -- GHC.Types.TyThing
    TyThing(..),

    -- GHC.Types.Var
    varName,

    -- GHC.Unit.Module
    mkModuleName,

    -- GHC.Utils.Lexeme
    isLexCon,

    -- GHC.Utils.Outputable
    ppr
  ) where

import GHC                  (getModuleInfo, lookupModule, lookupName,
                             modInfoExports)

#if MIN_VERSION_ghc(9,2,0)
import GHC.Driver.Env
import GHC.Driver.Ppr
import GHC.Types.SourceText
import GHC.Types.TyThing
#elif MIN_VERSION_ghc(9,0,0)
import GHC.Driver.Types
import GHC.Types.Basic
import GHC.Types.Var
import GHC.Unit.Module
import GHC.Utils.Outputable
#endif

#if MIN_VERSION_ghc(9,0,0)
import GHC.Data.FastString
import GHC.Driver.Monad
import GHC.Plugins
import GHC.Utils.Lexeme
#else
import BasicTypes
import FastString
import GhcMonad
import HscTypes
import Lexeme
import Module
import Outputable
import Plugins
import Var
#endif



================================================
FILE: finkel-core/src/Finkel/Core/Internal/Ghc/Version.hs
================================================
{-# LANGUAGE CPP #-}
-- | Wrapper module to export version related functions.
module Finkel.Core.Internal.Ghc.Version
  ( __glasgow_haskell__
  , getPackageVersion
  ) where

-- base
import Data.Version                    (Version)

-- finkel-kernel
import Language.Finkel                 (Code, Fnk, finkelSrcError, fromCode)

-- ghc
#if MIN_VERSION_ghc(9,2,0)
import GHC.Driver.Env                  (hsc_units)
#elif MIN_VERSION_ghc(9,0,0)
import GHC.Driver.Session              (unitState)
#endif

#if MIN_VERSION_ghc(9,0,0) && !MIN_VERSION_ghc(9,4,0)
import GHC.Unit.Types                  (indefUnit)
#endif

#if MIN_VERSION_ghc(9,0,0)
import GHC.Unit.State                  (PackageName (..), lookupPackageName,
                                        lookupUnitId, unitPackageVersion)
#else
import Module                          (componentIdToInstalledUnitId)
import Packages                        (PackageName (..),
                                        lookupInstalledPackage,
                                        lookupPackageName)

-- ghc-boot
import GHC.PackageDb                   (packageVersion)
#endif

-- Internal
import Finkel.Core.Internal.Ghc.Compat

-- | Function version of @__GLASGOW_HASKELL__@ C preprocessor macro.
__glasgow_haskell__ :: Int
__glasgow_haskell__ = __GLASGOW_HASKELL__

getPackageVersion :: HscEnv -> Code -> Fnk Version
getPackageVersion hsc_env form =
  let err = finkelSrcError form
  in  case fromCode form of
    Nothing -> err ("want package name `String' value but got: " ++ show form)
    Just name -> case lookupPackageVersion hsc_env name of
      Nothing -> err ("cannot find package: " ++ name)
      Just v  -> pure v

lookupPackageVersion :: HscEnv -> String -> Maybe Version
#if MIN_VERSION_ghc(9,4,0)
lookupPackageVersion hsc_env name =
  -- XXX: Is GHC.Driver.Env.hscActiveUnitId related?
  do let pname = PackageName (fsLit name)
         us = hsc_units hsc_env
     uid <- lookupPackageName us pname
     uinfo <- lookupUnitId us uid
     pure $ unitPackageVersion uinfo
#elif MIN_VERSION_ghc(9,2,0)
lookupPackageVersion hsc_env name =
  do let pname = PackageName (fsLit name)
         us = hsc_units hsc_env
     indef_uid <- lookupPackageName us pname
     uid <- lookupUnitId us (indefUnit indef_uid)
     pure $ unitPackageVersion uid
#elif MIN_VERSION_ghc(9,0,0)
lookupPackageVersion hsc_env name =
  do let pname = PackageName (fsLit name)
         ust = unitState (hsc_dflags hsc_env)
     indef_uid <- lookupPackageName ust pname
     uid <- lookupUnitId ust (indefUnit indef_uid)
     pure $ unitPackageVersion uid
#else
lookupPackageVersion hsc_env name =
  do let pname = PackageName (fsLit name)
     component_id <- lookupPackageName (hsc_dflags hsc_env) pname
     let iuid = componentIdToInstalledUnitId component_id
     conf <- lookupInstalledPackage (hsc_dflags hsc_env) iuid
     pure $ packageVersion conf
#endif


================================================
FILE: finkel-core/src/Finkel/Core/Internal/Ghc.hs
================================================
;;; -*- mode: finkel -*-
;;;; Module for ghc related functions

(:doc "Internal module for @ghc@ related functions.")

(module Finkel.Core.Internal.Ghc
  __glasgow_haskell__
  (module Finkel.Core.Internal.Ghc.Compat))

(import Finkel.Core.Internal.Ghc.Compat)
(import Finkel.Core.Internal.Ghc.Version)


================================================
FILE: finkel-core/src/Finkel/Core/Internal/Stage0.hs
================================================
;;; -*- mode: finkel -*-
;;;; Stage0 - functions used in stage 1.

;;; This module contains few funct
Download .txt
gitextract_w18apfhd/

├── .appveyor.yml
├── .circleci/
│   └── config.yml
├── .codecov.yml
├── .dir-locals.el
├── .gitattributes
├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   └── bug_report.md
│   ├── dependabot.yml
│   └── workflows/
│       ├── cabal-install.yml
│       ├── ci.yml
│       ├── nix-build.yml
│       ├── pre-job.yml
│       ├── sdist.yml
│       └── stack.yml
├── .gitignore
├── .hlint.yaml
├── .readthedocs.yaml
├── .stylish-haskell.yaml
├── .travis.yml
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── cabal.project
├── default.nix
├── doc/
│   ├── LICENSE
│   ├── Makefile
│   ├── Setup.hs
│   ├── conf.py
│   ├── contents/
│   │   ├── building-package.rst
│   │   ├── finkel-executable.rst
│   │   ├── install.rst
│   │   ├── language-syntax.rst
│   │   └── macros.rst
│   ├── doc.cabal
│   ├── include/
│   │   ├── building-package/
│   │   │   ├── my-first-package/
│   │   │   │   ├── Setup.hs
│   │   │   │   ├── my-first-package.cabal
│   │   │   │   ├── package.yaml
│   │   │   │   ├── src/
│   │   │   │   │   └── MyFirstPackage.hs
│   │   │   │   ├── stack.git.yaml
│   │   │   │   └── stack.template.yaml
│   │   │   ├── my-new-package/
│   │   │   │   ├── LICENSE
│   │   │   │   ├── README.md
│   │   │   │   ├── Setup.hs
│   │   │   │   ├── app/
│   │   │   │   │   └── Main.hs
│   │   │   │   ├── my-new-package.cabal
│   │   │   │   ├── src/
│   │   │   │   │   └── Lib.hs
│   │   │   │   ├── stack.yaml
│   │   │   │   └── test/
│   │   │   │       └── Spec.hs
│   │   │   └── my-second-package/
│   │   │       ├── LICENSE
│   │   │       ├── README.md
│   │   │       ├── Setup.hs
│   │   │       ├── app/
│   │   │       │   └── Main.hs
│   │   │       ├── my-second-package.cabal
│   │   │       ├── src/
│   │   │       │   ├── FnkCodes.hs
│   │   │       │   ├── HsCodes.hs
│   │   │       │   └── Lib.hs
│   │   │       └── test/
│   │   │           ├── FactorialTest.hs
│   │   │           └── Spec.hs
│   │   ├── finkel-executable/
│   │   │   ├── finkel-help-make.console
│   │   │   ├── hello-prof.console
│   │   │   ├── hello.console
│   │   │   ├── hello.hs
│   │   │   └── hello904.console
│   │   ├── language-syntax/
│   │   │   ├── decl/
│   │   │   │   ├── bind-pat.fnk
│   │   │   │   ├── bind-pat.hs
│   │   │   │   ├── bind-simpl.fnk
│   │   │   │   ├── bind-simpl.hs
│   │   │   │   ├── bind-where.fnk
│   │   │   │   ├── bind-where.hs
│   │   │   │   ├── class.fnk
│   │   │   │   ├── class.hs
│   │   │   │   ├── data-d1.fnk
│   │   │   │   ├── data-d1.hs
│   │   │   │   ├── data-d2.fnk
│   │   │   │   ├── data-d2.hs
│   │   │   │   ├── default.fnk
│   │   │   │   ├── default.hs
│   │   │   │   ├── fixity.fnk
│   │   │   │   ├── fixity.hs
│   │   │   │   ├── instance.fnk
│   │   │   │   ├── instance.hs
│   │   │   │   ├── newtype.fnk
│   │   │   │   ├── newtype.hs
│   │   │   │   ├── tysig-constraints.fnk
│   │   │   │   ├── tysig-constraints.hs
│   │   │   │   ├── tysig-many.fnk
│   │   │   │   ├── tysig-many.hs
│   │   │   │   ├── tysig-one.fnk
│   │   │   │   ├── tysig-one.hs
│   │   │   │   ├── tysym.fnk
│   │   │   │   └── tysym.hs
│   │   │   ├── expr/
│   │   │   │   ├── block-comment.fnk
│   │   │   │   ├── block-comment.hs
│   │   │   │   ├── case.fnk
│   │   │   │   ├── case.hs
│   │   │   │   ├── char-a.fnk
│   │   │   │   ├── char-a.hs
│   │   │   │   ├── char-escape.fnk
│   │   │   │   ├── char-escape.hs
│   │   │   │   ├── char-ncode.fnk
│   │   │   │   ├── char-ncode.hs
│   │   │   │   ├── char-special.fnk
│   │   │   │   ├── char-special.hs
│   │   │   │   ├── discard-prefix.fnk
│   │   │   │   ├── discard-prefix.hs
│   │   │   │   ├── do.fnk
│   │   │   │   ├── do.hs
│   │   │   │   ├── fieldlabels.fnk
│   │   │   │   ├── fieldlabels.hs
│   │   │   │   ├── funapp-pars.fnk
│   │   │   │   ├── funapp-pars.hs
│   │   │   │   ├── funapp.fnk
│   │   │   │   ├── funapp.hs
│   │   │   │   ├── guard.fnk
│   │   │   │   ├── guard.hs
│   │   │   │   ├── if.fnk
│   │   │   │   ├── if.hs
│   │   │   │   ├── lambda.fnk
│   │   │   │   ├── lambda.hs
│   │   │   │   ├── let.fnk
│   │   │   │   ├── let.hs
│   │   │   │   ├── line-comment.fnk
│   │   │   │   ├── line-comment.hs
│   │   │   │   ├── list-comp.fnk
│   │   │   │   ├── list-comp.hs
│   │   │   │   ├── list-const.fnk
│   │   │   │   ├── list-const.hs
│   │   │   │   ├── list-range.fnk
│   │   │   │   ├── list-range.hs
│   │   │   │   ├── map-mul2.fnk
│   │   │   │   ├── map-mul2.hs
│   │   │   │   ├── map-unary.fnk
│   │   │   │   ├── map-unary.hs
│   │   │   │   ├── muladd.fnk
│   │   │   │   ├── muladd.hs
│   │   │   │   ├── numeric.fnk
│   │   │   │   ├── numeric.hs
│   │   │   │   ├── opexp-add.fnk
│   │   │   │   ├── opexp-add.hs
│   │   │   │   ├── opexp-app.fnk
│   │   │   │   ├── opexp-app.hs
│   │   │   │   ├── pat-as.fnk
│   │   │   │   ├── pat-as.hs
│   │   │   │   ├── pat-irf.fnk
│   │   │   │   ├── pat-irf.hs
│   │   │   │   ├── pat-maybe.fnk
│   │   │   │   ├── pat-maybe.hs
│   │   │   │   ├── pat-opexp.fnk
│   │   │   │   ├── pat-opexp.hs
│   │   │   │   ├── sige.fnk
│   │   │   │   ├── sige.hs
│   │   │   │   ├── string.fnk
│   │   │   │   ├── string.hs
│   │   │   │   ├── tup2.fnk
│   │   │   │   ├── tup2.hs
│   │   │   │   ├── tup5.fnk
│   │   │   │   ├── tup5.hs
│   │   │   │   ├── tupfn.fnk
│   │   │   │   ├── tupfn.hs
│   │   │   │   ├── unit.fnk
│   │   │   │   ├── unit.hs
│   │   │   │   ├── varid.fnk
│   │   │   │   └── varid.hs
│   │   │   ├── ffi/
│   │   │   │   ├── export.fnk
│   │   │   │   ├── export.hs
│   │   │   │   ├── import.fnk
│   │   │   │   └── import.hs
│   │   │   ├── import/
│   │   │   │   ├── altogether.fnk
│   │   │   │   ├── altogether.hs
│   │   │   │   ├── entity-list.fnk
│   │   │   │   ├── entity-list.hs
│   │   │   │   ├── hiding.fnk
│   │   │   │   ├── hiding.hs
│   │   │   │   ├── qualified-as.fnk
│   │   │   │   ├── qualified-as.hs
│   │   │   │   ├── simpl.fnk
│   │   │   │   └── simpl.hs
│   │   │   └── module/
│   │   │       ├── export-list.fnk
│   │   │       ├── export-list.hs
│   │   │       ├── simpl.fnk
│   │   │       └── simpl.hs
│   │   └── macros/
│   │       ├── RequireMe.fnk
│   │       ├── arglist.console
│   │       ├── arglist.fnk
│   │       ├── begin.console
│   │       ├── begin.fnk
│   │       ├── eval-when-compile.console
│   │       ├── eval-when-compile.fnk
│   │       ├── eval-when.console
│   │       ├── eval-when.fnk
│   │       ├── fib-macro.console
│   │       ├── fib-macro.fnk
│   │       ├── macrolet.console
│   │       ├── macrolet.fnk
│   │       ├── quasiquote.console
│   │       ├── quasiquote.fnk
│   │       ├── quasiquote904.console
│   │       ├── quote.console
│   │       ├── quote.fnk
│   │       ├── raw-require.console
│   │       ├── raw-require.fnk
│   │       ├── require.console
│   │       ├── require.fnk
│   │       ├── unquote-splice.console
│   │       ├── unquote-splice.fnk
│   │       ├── unquote.console
│   │       └── unquote.fnk
│   ├── index.rst
│   ├── make.bat
│   ├── requirements.txt
│   └── test/
│       ├── Doc/
│       │   ├── BuildingPackage.hs
│       │   ├── FinkelExecutable.hs
│       │   ├── LanguageSyntax.hs
│       │   ├── Macros.hs
│       │   └── TestAux.hs
│       ├── Doc.hs
│       └── Spec.hs
├── finkel/
│   ├── CHANGELOG.md
│   ├── LICENSE
│   ├── Main.hs
│   ├── README.md
│   ├── Setup.hs
│   └── finkel.cabal
├── finkel-core/
│   ├── LICENSE
│   ├── README.md
│   ├── Setup.hs
│   ├── finkel-core.cabal
│   ├── src/
│   │   └── Finkel/
│   │       ├── Core/
│   │       │   ├── Functions.hs
│   │       │   ├── Internal/
│   │       │   │   ├── Ghc/
│   │       │   │   │   ├── Compat.hs
│   │       │   │   │   └── Version.hs
│   │       │   │   ├── Ghc.hs
│   │       │   │   ├── Stage0.hs
│   │       │   │   ├── Stage1.hs
│   │       │   │   └── Stage2.hs
│   │       │   ├── Internal.hs
│   │       │   └── Plugin.hs
│   │       ├── Core.hs
│   │       └── Prelude.hs
│   └── test/
│       ├── CoreTest.hs
│       ├── FunctionTest.hs
│       ├── Orphan.hs
│       ├── PluginTest.hs
│       ├── Spec.hs
│       ├── TestAux.hs
│       └── data/
│           └── plugin/
│               ├── ImportMe.hs
│               └── c01.hs
├── finkel-kernel/
│   ├── LICENSE
│   ├── README.md
│   ├── Setup.hs
│   ├── exec/
│   │   ├── fnkc.hs
│   │   └── profile.hs
│   ├── finkel-kernel.cabal
│   ├── include/
│   │   ├── ghc_modules.h
│   │   └── hooks.c
│   ├── src/
│   │   └── Language/
│   │       ├── Finkel/
│   │       │   ├── Builder.hs
│   │       │   ├── Data/
│   │       │   │   ├── FastString.hs
│   │       │   │   ├── Fractional.hs
│   │       │   │   └── SourceText.hs
│   │       │   ├── Emit.hs
│   │       │   ├── Error.hs
│   │       │   ├── Eval.hs
│   │       │   ├── Exception.hs
│   │       │   ├── Expand.hs
│   │       │   ├── Fnk.hs
│   │       │   ├── Form.hs
│   │       │   ├── Homoiconic.hs
│   │       │   ├── Hooks.hs
│   │       │   ├── Lexer.x
│   │       │   ├── Main.hs
│   │       │   ├── Make/
│   │       │   │   ├── Cache.hs
│   │       │   │   ├── Recompile.hs
│   │       │   │   ├── Session.hs
│   │       │   │   ├── Summary.hs
│   │       │   │   ├── TargetSource.hs
│   │       │   │   └── Trace.hs
│   │       │   ├── Make.hs
│   │       │   ├── Options.hs
│   │       │   ├── ParsedResult.hs
│   │       │   ├── Plugin.hs
│   │       │   ├── Preprocess.hs
│   │       │   ├── Reader.y
│   │       │   ├── SpecialForms.hs
│   │       │   ├── Syntax/
│   │       │   │   ├── Extension.hs
│   │       │   │   ├── HBind.hs
│   │       │   │   ├── HDecl.hs
│   │       │   │   ├── HExpr.hs
│   │       │   │   ├── HImpExp.hs
│   │       │   │   ├── HPat.hs
│   │       │   │   ├── HType.hs
│   │       │   │   ├── Location.hs
│   │       │   │   └── Utils.hs
│   │       │   └── Syntax.y
│   │       └── Finkel.hs
│   └── test/
│       ├── EmitTest.hs
│       ├── EvalTest.hs
│       ├── ExceptionTest.hs
│       ├── FnkTest.hs
│       ├── FormTest.hs
│       ├── Main.hs
│       ├── MainTest.hs
│       ├── MakeTest.hs
│       ├── Orphan.hs
│       ├── PluginTest.hs
│       ├── PreprocessTest.hs
│       ├── SyntaxTest.hs
│       ├── TestAux.hs
│       └── data/
│           ├── eval/
│           │   ├── 0001-simple.fnk
│           │   ├── 0002-shadowing-macro.fnk
│           │   ├── 0003-expand1.fnk
│           │   └── 0004-unquote-unquote-splice.fnk
│           ├── exception/
│           │   ├── 0001-invalid-unquote-splice.hs
│           │   ├── 0002-invalid-string-literal.hs
│           │   └── 0003-malformed-qq.hs
│           ├── main/
│           │   ├── MyMain.hs
│           │   ├── m001.hs
│           │   ├── m002.hs
│           │   └── m003.c
│           ├── make/
│           │   ├── E01.hs
│           │   ├── E02.hs
│           │   ├── M1.hs
│           │   ├── M2.hs
│           │   ├── M3.hs
│           │   ├── M4/
│           │   │   ├── A.hs
│           │   │   └── B.hs
│           │   ├── M4.hs
│           │   ├── M5.hs
│           │   ├── M6/
│           │   │   ├── A.hs
│           │   │   └── B.hs
│           │   ├── P1.hs
│           │   ├── P2.hs
│           │   ├── P3.hs
│           │   ├── R01.hs.1
│           │   ├── R01.hs.2
│           │   ├── R02.hs
│           │   ├── R03.hs
│           │   ├── R04.hs
│           │   ├── R05.hs
│           │   ├── R05a.hs
│           │   ├── R06.hs
│           │   ├── R06a.hs
│           │   ├── R07.hs
│           │   ├── R07a.hs
│           │   ├── R07b.hs
│           │   ├── R08.hs
│           │   ├── R08a.hs
│           │   ├── R08b.hs
│           │   ├── R09.hs
│           │   ├── R09a.hs
│           │   ├── R09b.hs
│           │   ├── R10.hs
│           │   ├── R10a.hs
│           │   ├── R10b.hs
│           │   ├── R11.hs
│           │   ├── R11a.hs
│           │   ├── R11b.hs
│           │   ├── cbits1.c
│           │   ├── cbits2.c
│           │   ├── cbits3.c
│           │   ├── main1.hs
│           │   ├── main2.hs
│           │   ├── main3.hs
│           │   ├── main4.hs
│           │   ├── main5.hs
│           │   ├── main6.hs
│           │   ├── main7.hs
│           │   ├── main8.hs
│           │   └── main9.hs
│           ├── plugin/
│           │   ├── M01.hs
│           │   ├── M02.hs
│           │   ├── M03.hs
│           │   ├── M04.hs
│           │   ├── M04b.hs
│           │   ├── p01.hs
│           │   ├── p02.hs
│           │   ├── p03.hs
│           │   ├── p04.hs
│           │   ├── p05.hs
│           │   ├── p06.hs
│           │   ├── p07.hs
│           │   ├── p08.hs
│           │   ├── p09.hs
│           │   ├── p10.hs
│           │   └── p11.hs
│           ├── preprocess/
│           │   ├── fnk01.hs
│           │   ├── fnk02.hs
│           │   ├── fnk03.hs
│           │   ├── fnk04.hs
│           │   ├── fnk05.hs
│           │   ├── fnk06.hs
│           │   ├── fnk11.hs
│           │   ├── fnk12.hs
│           │   ├── fnk13.hs
│           │   ├── fnk14.hs
│           │   ├── fnk15.hs
│           │   ├── hs01.hs
│           │   └── hs02.hs
│           └── syntax/
│               ├── 0001-hello.hs
│               ├── 0002-lexical.hs
│               ├── 0003-expressions-1.hs
│               ├── 0003-expressions-2.hs
│               ├── 0003-expressions-3.hs
│               ├── 0004-decls.hs
│               ├── 0005-modules-01.hs
│               ├── 0005-modules-02.hs
│               ├── 0005-modules-03.hs
│               ├── 0005-modules-04.hs
│               ├── 0005-modules-05.hs
│               ├── 0008-ffi.hs
│               ├── 0012-pragmas.hs
│               ├── 1000-comment.hs
│               ├── 1001-quote.hs
│               ├── 1002-macro.hs
│               ├── 1003-eval-when-compile.hs
│               ├── 1004-doccomment-01.hs
│               ├── 1004-doccomment-02.hs
│               ├── 1004-doccomment-03.hs
│               ├── 1005-begin.hs
│               ├── 2001-unpack.hs
│               ├── 2002-bang.hs
│               ├── 2003-derive.hs
│               ├── 2004-overloaded.hs
│               ├── 2005-gadts-01.hs
│               ├── 2005-gadts-02.hs
│               ├── 2006-existential.hs
│               ├── 2007-rankn.hs
│               ├── 2008-options.hs
│               ├── 2009-flexible.hs
│               ├── 2010-kindsig.hs
│               ├── 2011-scoped.hs
│               ├── 2012-typeop.hs
│               ├── 2013-undecidable.hs
│               ├── 2014-noprelude.hs
│               ├── 2015-typefam.hs
│               ├── 2016-datakinds.hs
│               ├── 2017-polykinds.hs
│               ├── 2018-typeapp.hs
│               ├── 2019-overlabel.hs
│               ├── 2020-emptyderiv.hs
│               ├── 2021-dfltsig.hs
│               ├── 2022-drvstrat.hs
│               ├── 2023-standalone.hs
│               ├── 2024-derivingvia.hs
│               ├── 2025-namedfieldpuns.hs
│               ├── 2026-recordwildcards.hs
│               ├── 2027-emptycase-1.hs
│               ├── 2027-emptycase-2.hs
│               ├── 2028-standalonekind.hs
│               └── 2029-impredicative.hs
├── finkel-setup/
│   ├── LICENSE
│   ├── README.md
│   ├── Setup.hs
│   ├── finkel-setup.cabal
│   ├── src/
│   │   └── Distribution/
│   │       └── Simple/
│   │           └── Finkel.hs
│   └── test/
│       ├── Main.hs
│       └── data/
│           ├── p01/
│           │   ├── LICENSE
│           │   ├── Setup.hs
│           │   ├── exec/
│           │   │   └── p01.hs
│           │   ├── p01.cabal
│           │   ├── src/
│           │   │   └── P01/
│           │   │       ├── A.fnk
│           │   │       ├── B.fnk
│           │   │       ├── C.fnk
│           │   │       ├── D.hs
│           │   │       ├── E.hs
│           │   │       ├── F.fnk
│           │   │       ├── G1.fnk
│           │   │       ├── G2.fnk
│           │   │       ├── H.fnk
│           │   │       ├── I.fnk
│           │   │       └── J.fnk
│           │   └── test/
│           │       ├── Spec.hs
│           │       └── TestAll.fnk
│           └── p02/
│               ├── CHANGELOG.md
│               ├── LICENSE
│               ├── Setup.hs
│               ├── app/
│               │   └── Main.hs
│               ├── p02.cabal
│               ├── src/
│               │   └── MyLib.hs
│               └── test/
│                   └── Main.hs
├── finkel-tool/
│   ├── LICENSE
│   ├── README.md
│   ├── Setup.hs
│   ├── finkel-tool.cabal
│   ├── finkel.hsfiles
│   ├── src/
│   │   └── Finkel/
│   │       └── Tool/
│   │           ├── Command/
│   │           │   ├── Eval.hs
│   │           │   ├── Help.hs
│   │           │   ├── Make.hs
│   │           │   ├── Repl.hs
│   │           │   ├── Run.hs
│   │           │   ├── Sdist.hs
│   │           │   └── Version.hs
│   │           ├── Command.hs
│   │           ├── Internal/
│   │           │   ├── CLI.hs
│   │           │   ├── Commit.hs
│   │           │   ├── Compat.hs
│   │           │   ├── Eval.hs
│   │           │   ├── Exception.hs
│   │           │   ├── IO.hs
│   │           │   ├── Listen.hs
│   │           │   ├── Loop.hs
│   │           │   ├── Macro/
│   │           │   │   ├── Ghc.hs
│   │           │   │   └── Repl.hs
│   │           │   └── Types.hs
│   │           └── Main.hs
│   └── test/
│       ├── CLITest.hs
│       ├── GhcTest.hs
│       ├── MainTest.hs
│       ├── ReplMacroTest.hs
│       ├── ReplTest.hs
│       ├── Spec.hs
│       ├── TestAux.hs
│       └── data/
│           ├── Err001.fnk
│           ├── LoadMe.hs
│           ├── RunMeToo.hs
│           ├── input01.txt
│           ├── m01.hs
│           ├── p02/
│           │   ├── LICENSE
│           │   ├── README.md
│           │   ├── Setup.hs
│           │   ├── app/
│           │   │   └── Main.hs
│           │   ├── p02.cabal
│           │   ├── src/
│           │   │   └── Lib.fnk
│           │   ├── stack.yaml
│           │   └── test/
│           │       └── Spec.hs
│           ├── print-int.hs
│           ├── print-load-me.hs
│           ├── run-me.hs
│           └── sleep-for-while.fnk
├── fkc/
│   ├── LICENSE
│   ├── Main.hs
│   ├── README.md
│   ├── Setup.hs
│   └── fkc.cabal
├── fnkpp/
│   ├── LICENSE
│   ├── Main.hs
│   ├── README.md
│   └── fnkpp.cabal
├── nix/
│   ├── docker.nix
│   └── finkel-packages.nix
├── scripts/
│   └── travis.sh
├── shell.nix
└── stack.yaml
Download .txt
SYMBOL INDEX (7 symbols across 6 files)

FILE: doc/conf.py
  class FinkelLexer (line 255) | class FinkelLexer(RegexLexer):
  function setup (line 421) | def setup(sphinx):

FILE: finkel-kernel/include/hooks.c
  function initGCStatistics (line 8) | void initGCStatistics (void)

FILE: finkel-kernel/test/data/main/m003.c
  function hello (line 3) | void hello() {

FILE: finkel-kernel/test/data/make/cbits1.c
  function f1 (line 5) | int f1(int x)

FILE: finkel-kernel/test/data/make/cbits2.c
  function f2 (line 5) | int f2(int x)

FILE: finkel-kernel/test/data/make/cbits3.c
  function f3 (line 5) | int f3(int x)
Condensed preview — 541 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,397K chars).
[
  {
    "path": ".appveyor.yml",
    "chars": 643,
    "preview": "branches:\n  only:\n    - /appveyor-*/\n\nenvironment:\n  global:\n    CABOPTS: \"--store-dir=C:\\\\SR --http-transport=plain-htt"
  },
  {
    "path": ".circleci/config.yml",
    "chars": 1396,
    "preview": "# Use the latest 2.1 version of CircleCI pipeline process engine. See:\n# https://circleci.com/docs/2.0/configuration-ref"
  },
  {
    "path": ".codecov.yml",
    "chars": 70,
    "preview": "coverage:\n  status:\n    project:\n      default:\n        threshold: 5%\n"
  },
  {
    "path": ".dir-locals.el",
    "chars": 509,
    "preview": ";;; Directory Local Variables\n;;; For more information see (info \"(emacs) Directory Variables\")\n\n((nil\n  (fill-column . "
  },
  {
    "path": ".gitattributes",
    "chars": 20,
    "preview": "*         text=auto\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "chars": 1057,
    "preview": "---\nname: Bug Report\nabout: Report a bug in Finkel\n---\n\nPlease follow the steps below for reporting a bug:\n\nMake sure th"
  },
  {
    "path": ".github/dependabot.yml",
    "chars": 119,
    "preview": "version: 2\n\nupdates:\n  - package-ecosystem: \"github-actions\"\n    directory: \"/\"\n    schedule:\n      interval: \"weekly\"\n"
  },
  {
    "path": ".github/workflows/cabal-install.yml",
    "chars": 2370,
    "preview": "name: cabal-install\n\non:\n  workflow_call:\n    inputs:\n      cache-version:\n        description: cache key version\n      "
  },
  {
    "path": ".github/workflows/ci.yml",
    "chars": 798,
    "preview": "name: ci\n\non:\n  pull_request:\n  push:\n    paths-ignore:\n      - '**.md'\n\ndefaults:\n  run:\n    shell: bash\n\njobs:\n  pre-j"
  },
  {
    "path": ".github/workflows/nix-build.yml",
    "chars": 2068,
    "preview": "name: nix-build\n\non:\n  workflow_call:\n\njobs:\n  nix-build:\n    name: Build with nix\n    strategy:\n      matrix:\n        i"
  },
  {
    "path": ".github/workflows/pre-job.yml",
    "chars": 565,
    "preview": "name: pre-job\n\non:\n  workflow_call:\n    outputs:\n      run:\n        description: \\\"true\\\" if running other jobs\n        "
  },
  {
    "path": ".github/workflows/sdist.yml",
    "chars": 2031,
    "preview": "name: sdist\n\non:\n  workflow_call:\n\njobs:\n  make-sdist-with-stack:\n    name: Build *.tar.gz made via sdist\n\n    runs-on: "
  },
  {
    "path": ".github/workflows/stack.yml",
    "chars": 2198,
    "preview": "name: stack\n\non:\n  workflow_call:\n    inputs:\n      cache-version:\n        description: cache key version\n        requir"
  },
  {
    "path": ".gitignore",
    "chars": 545,
    "preview": "*~\n*.hi\n*.hie\n*.hscpp\n*.o\n*.dyn_o\n*.dyn_hi\n*.p_o\n*.p_hi\n*.info\n*.prof\n*.html\n*.hp\n*.tix\n*.yaml.lock\n.ghc.environment.*\nr"
  },
  {
    "path": ".hlint.yaml",
    "chars": 2141,
    "preview": "# HLint configuration file\n# https://github.com/ndmitchell/hlint\n##########################\n\n# This file contains a temp"
  },
  {
    "path": ".readthedocs.yaml",
    "chars": 125,
    "preview": "version: 2\n\nsphinx:\n  configuration: doc/conf.py\n\npython:\n  version: 3.8\n  install:\n    - requirements: doc/requirements"
  },
  {
    "path": ".stylish-haskell.yaml",
    "chars": 8771,
    "preview": "# stylish-haskell configuration file\n# ==================================\n\n# The stylish-haskell tool is mainly configur"
  },
  {
    "path": ".travis.yml",
    "chars": 1116,
    "preview": "language: c\n\nbranches:\n  only:\n    - /^travis-.*/\n\ngit:\n  depth: 3\n\ncache:\n  directories:\n    - $HOME/.stack\n    - $HOME"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "chars": 5226,
    "preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nWe as members, contributors, and leaders pledge to make participa"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 3478,
    "preview": "# Contributing\n\nFirst of all, thanks for your interest in contributing to Finkel!\n\nWe want to make contributing to this "
  },
  {
    "path": "LICENSE",
    "chars": 1529,
    "preview": "Copyright 8c6794b6 (c) 2017-2020\n\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or witho"
  },
  {
    "path": "README.md",
    "chars": 2432,
    "preview": "# Finkel\n\n[![CI status][ci-badge]][ci]\n[![Documentation][doc-badge]][doc]\n[![Codecov][codecov-badge]][codecov]\n\nFinkel i"
  },
  {
    "path": "cabal.project",
    "chars": 376,
    "preview": "packages:\n  -- Main components\n  finkel-kernel/\n  fkc/\n  fnkpp/\n  finkel-setup/\n  finkel-core/\n  finkel-tool/\n  finkel/\n"
  },
  {
    "path": "default.nix",
    "chars": 158,
    "preview": "{\n  nixpkgs ? <nixpkgs>,\n  compiler ? \"ghc8106\"\n}:\n\nlet\n  pkgs = import ./nix/finkel-packages.nix {\n    inherit compiler"
  },
  {
    "path": "doc/LICENSE",
    "chars": 1529,
    "preview": "Copyright 8c6794b6 (c) 2020-2022\n\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or witho"
  },
  {
    "path": "doc/Makefile",
    "chars": 580,
    "preview": "# Minimal makefile for Sphinx documentation\n#\n\n# You can set these variables from the command line.\nSPHINXOPTS    =\nSPHI"
  },
  {
    "path": "doc/Setup.hs",
    "chars": 60,
    "preview": "import Distribution.Simple (defaultMain)\nmain = defaultMain\n"
  },
  {
    "path": "doc/conf.py",
    "chars": 12397,
    "preview": "# -*- coding: utf-8 -*-\n#\n# Configuration file for the Sphinx documentation builder.\n#\n# This file does only contain a s"
  },
  {
    "path": "doc/contents/building-package.rst",
    "chars": 6901,
    "preview": "Building Cabal Package\n======================\n\nTo build a cabal package with Finkel, make a cabal configuration file as "
  },
  {
    "path": "doc/contents/finkel-executable.rst",
    "chars": 3227,
    "preview": "Using The Finkel Executable\n===========================\n\nThe ``finkel`` executable from the ``finkel`` package contains\n"
  },
  {
    "path": "doc/contents/install.rst",
    "chars": 2239,
    "preview": "Building And Installing\n=======================\n\n.. note::\n\n   At the time of writing, Finkel related packages are not y"
  },
  {
    "path": "doc/contents/language-syntax.rst",
    "chars": 19751,
    "preview": "Language Syntax\n===============\n\nThe Finkel language is made from Finkel kernel keywords and Finkel\ncore keywords.\n\nThe "
  },
  {
    "path": "doc/contents/macros.rst",
    "chars": 9826,
    "preview": "Macros In Finkel\n================\n\nThis section shows how to write and use macros. Macros in Finkel are\nsimilar to macro"
  },
  {
    "path": "doc/doc.cabal",
    "chars": 2101,
    "preview": "cabal-version:       2.0\nname:                doc\nversion:             0.0.0\nsynopsis:            Internal test for Fink"
  },
  {
    "path": "doc/include/building-package/my-first-package/Setup.hs",
    "chars": 95,
    "preview": "-- File: my-first-package/Setup.hs\nimport Distribution.Simple (defaultMain)\nmain = defaultMain\n"
  },
  {
    "path": "doc/include/building-package/my-first-package/my-first-package.cabal",
    "chars": 616,
    "preview": "cabal-version: 1.12\n\n-- This file has been generated from package.yaml by hpack version 0.36.0.\n--\n-- see: https://githu"
  },
  {
    "path": "doc/include/building-package/my-first-package/package.yaml",
    "chars": 313,
    "preview": "# File: my-first-package/package.yaml\n\nname: my-first-package\nversion: 0.1.0.0\n\nlibrary:\n  source-dirs: src\n  exposed-mo"
  },
  {
    "path": "doc/include/building-package/my-first-package/src/MyFirstPackage.hs",
    "chars": 422,
    "preview": ";;;; File: my-first-package/src/MyFirstPackage.hs\n\n(defmodule MyFirstPackage\n  (export factorial))\n\n(defn (:: factorial "
  },
  {
    "path": "doc/include/building-package/my-first-package/stack.git.yaml",
    "chars": 271,
    "preview": "resolver: lts-22.31\npackages:\n  - .\nextra-deps:\n  - git: https://github.com/finkel-lang/finkel\n    commit: f7913be75db03"
  },
  {
    "path": "doc/include/building-package/my-first-package/stack.template.yaml",
    "chars": 36,
    "preview": "resolver: lts-22.31\npackages:\n  - .\n"
  },
  {
    "path": "doc/include/building-package/my-new-package/LICENSE",
    "chars": 1532,
    "preview": "Copyright Author name here (c) 2024\n\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or wi"
  },
  {
    "path": "doc/include/building-package/my-new-package/README.md",
    "chars": 17,
    "preview": "# my-new-package\n"
  },
  {
    "path": "doc/include/building-package/my-new-package/Setup.hs",
    "chars": 60,
    "preview": "import Distribution.Simple (defaultMain)\nmain = defaultMain\n"
  },
  {
    "path": "doc/include/building-package/my-new-package/app/Main.hs",
    "chars": 61,
    "preview": "module Main where\n\nimport Lib\n\nmain :: IO ()\nmain = someFunc\n"
  },
  {
    "path": "doc/include/building-package/my-new-package/my-new-package.cabal",
    "chars": 1474,
    "preview": "cabal-version:       3.0\nname:                my-new-package\nversion:             0.1.0.0\n-- synopsis:\n-- description:\nh"
  },
  {
    "path": "doc/include/building-package/my-new-package/src/Lib.hs",
    "chars": 132,
    "preview": ";;; -*- mode: finkel -*-\n(defmodule Lib\n  (export someFunc))\n\n(defn (:: someFunc (IO ()))\n  (putStrLn \"Hello from my-new"
  },
  {
    "path": "doc/include/building-package/my-new-package/stack.yaml",
    "chars": 2586,
    "preview": "# This file was automatically generated by 'stack init'\n#\n# Some commonly used options have been documented as comments "
  },
  {
    "path": "doc/include/building-package/my-new-package/test/Spec.hs",
    "chars": 63,
    "preview": "main :: IO ()\nmain = putStrLn \"Test suite not yet implemented\"\n"
  },
  {
    "path": "doc/include/building-package/my-second-package/LICENSE",
    "chars": 1528,
    "preview": "Copyright Author name here (c) 2019\n\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or wi"
  },
  {
    "path": "doc/include/building-package/my-second-package/README.md",
    "chars": 20,
    "preview": "# my-second-package\n"
  },
  {
    "path": "doc/include/building-package/my-second-package/Setup.hs",
    "chars": 60,
    "preview": "import Distribution.Simple (defaultMain)\nmain = defaultMain\n"
  },
  {
    "path": "doc/include/building-package/my-second-package/app/Main.hs",
    "chars": 61,
    "preview": "module Main where\n\nimport Lib\n\nmain :: IO ()\nmain = someFunc\n"
  },
  {
    "path": "doc/include/building-package/my-second-package/my-second-package.cabal",
    "chars": 1627,
    "preview": "cabal-version:       3.0\nname:                my-second-package\nversion:             0.1.0.0\n-- synopsis:\n-- description"
  },
  {
    "path": "doc/include/building-package/my-second-package/src/FnkCodes.hs",
    "chars": 195,
    "preview": ";;;; File: my-second-package/src/FnkCodes.hs\n\n(defmodule FnkCodes\n  (export fnkfactorial))\n\n(defn (:: fnkfactorial (-> I"
  },
  {
    "path": "doc/include/building-package/my-second-package/src/HsCodes.hs",
    "chars": 172,
    "preview": "-- File: my-second-package/src/HsCodes.hs\n\nmodule HsCodes\n  ( hsfactorial\n  , fnkfactorial\n  ) where\n\nimport FnkCodes\n\nh"
  },
  {
    "path": "doc/include/building-package/my-second-package/src/Lib.hs",
    "chars": 315,
    "preview": ";;;; File: my-second-package/src/Lib.hs\n\n(defmodule Lib\n  (export someFunc)\n  (import (HsCodes [hsfactorial fnkfactorial"
  },
  {
    "path": "doc/include/building-package/my-second-package/test/FactorialTest.hs",
    "chars": 235,
    "preview": ";;;; File: FactorialTest.hs\n\n(defmodule FactorialTest\n  (export test)\n  (import\n   (HsCodes)\n   (System.Exit (exitFailur"
  },
  {
    "path": "doc/include/building-package/my-second-package/test/Spec.hs",
    "chars": 48,
    "preview": "import FactorialTest\n\nmain :: IO ()\nmain = test\n"
  },
  {
    "path": "doc/include/finkel-executable/finkel-help-make.console",
    "chars": 812,
    "preview": "$ finkel help make\nUSAGE: finkel make [command-line-options-and-files]\n\nHELP OPTIONS:\n\n    --fnk-help       Show this he"
  },
  {
    "path": "doc/include/finkel-executable/hello-prof.console",
    "chars": 142,
    "preview": "$ finkel make -o hello -fforce-recomp -prof -fprof-auto hello.fnk\n[1 of 1] Compiling Main             ( hello.hs, hello."
  },
  {
    "path": "doc/include/finkel-executable/hello.console",
    "chars": 132,
    "preview": "$ finkel make -o hello hello.hs\n[1 of 1] Compiling Main             ( hello.hs, hello.o )\nLinking hello ...\n$ ./hello\nHe"
  },
  {
    "path": "doc/include/finkel-executable/hello.hs",
    "chars": 62,
    "preview": ";;;; File: hello.hs\n\n(defn main\n  (putStrLn \"Hello, World!\"))\n"
  },
  {
    "path": "doc/include/finkel-executable/hello904.console",
    "chars": 137,
    "preview": "$ finkel make -o hello hello.hs\n[1 of 2] Compiling Main             ( hello.hs, hello.o )\n[2 of 2] Linking hello\n$ ./hel"
  },
  {
    "path": "doc/include/language-syntax/decl/bind-pat.fnk",
    "chars": 36,
    "preview": "(= (Just x) (lookup k vs)) ; Finkel\n"
  },
  {
    "path": "doc/include/language-syntax/decl/bind-pat.hs",
    "chars": 32,
    "preview": "Just x = lookup k vs -- Haskell\n"
  },
  {
    "path": "doc/include/language-syntax/decl/bind-simpl.fnk",
    "chars": 36,
    "preview": "(= f1 x y z (+ x (* y z))) ; Finkel\n"
  },
  {
    "path": "doc/include/language-syntax/decl/bind-simpl.hs",
    "chars": 34,
    "preview": "f1 x y z = x + (y * z) -- Haskell\n"
  },
  {
    "path": "doc/include/language-syntax/decl/bind-where.fnk",
    "chars": 54,
    "preview": "(= f2 n ; Finkel\n  (where body\n    (= body (+ n 1))))\n"
  },
  {
    "path": "doc/include/language-syntax/decl/bind-where.hs",
    "chars": 48,
    "preview": "f2 n = body -- Haskell\n  where\n    body = n + 1\n"
  },
  {
    "path": "doc/include/language-syntax/decl/class.fnk",
    "chars": 71,
    "preview": "(class (=> (Ord a) (C1 a)) ; Finkel\n  (:: m1 (-> a Int))\n  (= m1 _ 0))\n"
  },
  {
    "path": "doc/include/language-syntax/decl/class.hs",
    "chars": 65,
    "preview": "class Ord a => C1 a where -- Haskell\n  m1 :: a -> Int\n  m1 _ = 0\n"
  },
  {
    "path": "doc/include/language-syntax/decl/data-d1.fnk",
    "chars": 69,
    "preview": "(data (D1 a b) ; Finkel\n  C1\n  (C2 a)\n  (C3 b)\n  (deriving Eq Show))\n"
  },
  {
    "path": "doc/include/language-syntax/decl/data-d1.hs",
    "chars": 70,
    "preview": "data D1 a b -- Haskell\n  = C1\n  | C2 a\n  | C3 b\n  deriving (Eq, Show)\n"
  },
  {
    "path": "doc/include/language-syntax/decl/data-d2.fnk",
    "chars": 80,
    "preview": "(data (D2 a b) ; Finkel\n  (D2 {(:: f1 a)\n       (:: f2 b)\n       (:: f3 Int)}))\n"
  },
  {
    "path": "doc/include/language-syntax/decl/data-d2.hs",
    "chars": 75,
    "preview": "data D2 a b -- Haskell\n = D2 { f1 :: a\n      , f2 :: b\n      , f3 :: Int }\n"
  },
  {
    "path": "doc/include/language-syntax/decl/default.fnk",
    "chars": 30,
    "preview": "(default Int Double) ; Finkel\n"
  },
  {
    "path": "doc/include/language-syntax/decl/default.hs",
    "chars": 33,
    "preview": "default (Int, Double) -- Haskell\n"
  },
  {
    "path": "doc/include/language-syntax/decl/fixity.fnk",
    "chars": 15,
    "preview": "(infixr 6 $+$)\n"
  },
  {
    "path": "doc/include/language-syntax/decl/fixity.hs",
    "chars": 13,
    "preview": "infixr 6 $+$\n"
  },
  {
    "path": "doc/include/language-syntax/decl/instance.fnk",
    "chars": 48,
    "preview": "(instance (C1 Int) ; Finkel\n  (= m1 n (+ n 1)))\n"
  },
  {
    "path": "doc/include/language-syntax/decl/instance.hs",
    "chars": 48,
    "preview": "instance C1 Int where -- Haskell\n  m1 n = n + 1\n"
  },
  {
    "path": "doc/include/language-syntax/decl/newtype.fnk",
    "chars": 40,
    "preview": "(newtype N (N {(:: unN Int)})) ; Finkel\n"
  },
  {
    "path": "doc/include/language-syntax/decl/newtype.hs",
    "chars": 38,
    "preview": "newtype N = N {unN :: Int} -- Haskell\n"
  },
  {
    "path": "doc/include/language-syntax/decl/tysig-constraints.fnk",
    "chars": 62,
    "preview": "(:: f (=> (Eq a) (Ord a) (Show a) (Num a) (-> a a))) ; Finkel\n"
  },
  {
    "path": "doc/include/language-syntax/decl/tysig-constraints.hs",
    "chars": 55,
    "preview": "f :: (Eq a, Ord a, Show a, Num a) => a -> a -- Haskell\n"
  },
  {
    "path": "doc/include/language-syntax/decl/tysig-many.fnk",
    "chars": 33,
    "preview": "(:: f g h (-> Int Int)) ; Finkel\n"
  },
  {
    "path": "doc/include/language-syntax/decl/tysig-many.hs",
    "chars": 33,
    "preview": "f, g, h :: Int -> Int -- Haskell\n"
  },
  {
    "path": "doc/include/language-syntax/decl/tysig-one.fnk",
    "chars": 33,
    "preview": "(:: f (-> Int Int Int)) ; Finkel\n"
  },
  {
    "path": "doc/include/language-syntax/decl/tysig-one.hs",
    "chars": 34,
    "preview": "f :: Int -> Int -> Int -- Haskell\n"
  },
  {
    "path": "doc/include/language-syntax/decl/tysym.fnk",
    "chars": 49,
    "preview": "(type (T1 a) (Maybe (, a Bool String))) ; Finkel\n"
  },
  {
    "path": "doc/include/language-syntax/decl/tysym.hs",
    "chars": 47,
    "preview": "type T1 a = Maybe (a, Bool, String) -- Haskell\n"
  },
  {
    "path": "doc/include/language-syntax/expr/block-comment.fnk",
    "chars": 44,
    "preview": "(putStrLn {- Finkel block comment -} \"bar\")\n"
  },
  {
    "path": "doc/include/language-syntax/expr/block-comment.hs",
    "chars": 43,
    "preview": "putStrLn {- Haskell block comment -} \"bar\"\n"
  },
  {
    "path": "doc/include/language-syntax/expr/case.fnk",
    "chars": 50,
    "preview": "(case n ; Finkel\n  0 \"zero\"\n  1 \"one\"\n  _ \"many\")\n"
  },
  {
    "path": "doc/include/language-syntax/expr/case.hs",
    "chars": 62,
    "preview": "case n of -- Haskell\n  0 -> \"zero\"\n  1 -> \"one\"\n  _ -> \"many\"\n"
  },
  {
    "path": "doc/include/language-syntax/expr/char-a.fnk",
    "chars": 23,
    "preview": "(putChar #'a) ; Finkel\n"
  },
  {
    "path": "doc/include/language-syntax/expr/char-a.hs",
    "chars": 24,
    "preview": "putChar 'a'  -- Haskell\n"
  },
  {
    "path": "doc/include/language-syntax/expr/char-escape.fnk",
    "chars": 27,
    "preview": "(print [#'\\ #'']) ; Finkel\n"
  },
  {
    "path": "doc/include/language-syntax/expr/char-escape.hs",
    "chars": 30,
    "preview": "print ['\\\\', '\\''] -- Haskell\n"
  },
  {
    "path": "doc/include/language-syntax/expr/char-ncode.fnk",
    "chars": 54,
    "preview": "(print [#'\\97 #'\\o141 #'\\x61]) ; Finkel, prints \"aaa\"\n"
  },
  {
    "path": "doc/include/language-syntax/expr/char-ncode.hs",
    "chars": 56,
    "preview": "print ['\\97', '\\o141', '\\x61'] -- Haskell, prints \"aaa\"\n"
  },
  {
    "path": "doc/include/language-syntax/expr/char-special.fnk",
    "chars": 41,
    "preview": "(print [#'\\n #'  #'\\NUL #'\\^L]) ; Finkel\n"
  },
  {
    "path": "doc/include/language-syntax/expr/char-special.hs",
    "chars": 44,
    "preview": "print ['\\n', ' ', '\\NUL', '\\^L'] -- Haskell\n"
  },
  {
    "path": "doc/include/language-syntax/expr/discard-prefix.fnk",
    "chars": 99,
    "preview": "(do (print True) ; Finkel\n    %_(this list (is ignored))\n    (print %_ignored False %_ \"ignored\"))\n"
  },
  {
    "path": "doc/include/language-syntax/expr/discard-prefix.hs",
    "chars": 63,
    "preview": "do print True -- Haskell, ignored forms removed\n   print False\n"
  },
  {
    "path": "doc/include/language-syntax/expr/do.fnk",
    "chars": 71,
    "preview": "(do (putStr \"x: \") ; Finkel\n    (<- l getLine)\n    (return (words l)))\n"
  },
  {
    "path": "doc/include/language-syntax/expr/do.hs",
    "chars": 63,
    "preview": "do putStr \"x: \" -- Haskell\n   l <- getLine\n   return (words l)\n"
  },
  {
    "path": "doc/include/language-syntax/expr/fieldlabels.fnk",
    "chars": 67,
    "preview": "(Constr1 {(= field1 1) (= field2 True) (= field3 \"abc\")}) ; Finkel\n"
  },
  {
    "path": "doc/include/language-syntax/expr/fieldlabels.hs",
    "chars": 57,
    "preview": "Constr1 {field1=1, field2=True, field3=\"abc\"} -- Haskell\n"
  },
  {
    "path": "doc/include/language-syntax/expr/funapp-pars.fnk",
    "chars": 36,
    "preview": "(((((putStrLn)) \"hello\"))) ; Finkel\n"
  },
  {
    "path": "doc/include/language-syntax/expr/funapp-pars.hs",
    "chars": 59,
    "preview": "putStrLn \"hello\" -- Haskell, redundant parentheses removed\n"
  },
  {
    "path": "doc/include/language-syntax/expr/funapp.fnk",
    "chars": 28,
    "preview": "(putStrLn \"hello\") ; Finkel\n"
  },
  {
    "path": "doc/include/language-syntax/expr/funapp.hs",
    "chars": 28,
    "preview": "putStrLn \"hello\" -- Haskell\n"
  },
  {
    "path": "doc/include/language-syntax/expr/guard.fnk",
    "chars": 221,
    "preview": "(case expr ; Finkel\n  (Just y) (| ((even y) r1)\n              ((odd y) (< y 10) r2)\n              ((<- (Just z) (lookup "
  },
  {
    "path": "doc/include/language-syntax/expr/guard.hs",
    "chars": 184,
    "preview": "case expr of -- Haskell\n  Just y | even y -> r1\n         | odd y, y < 10 -> r2\n         | Just z <- lookup y kvs\n       "
  },
  {
    "path": "doc/include/language-syntax/expr/if.fnk",
    "chars": 40,
    "preview": "(if test true-expr false-expr) ; Finkel\n"
  },
  {
    "path": "doc/include/language-syntax/expr/if.hs",
    "chars": 50,
    "preview": "if test then true_expr else false_expr -- Haskell\n"
  },
  {
    "path": "doc/include/language-syntax/expr/lambda.fnk",
    "chars": 56,
    "preview": "(zipWith (\\x y (* x (+ y 1))) [1 2 3] [4 5 6]) ; Finkel\n"
  },
  {
    "path": "doc/include/language-syntax/expr/lambda.hs",
    "chars": 61,
    "preview": "zipWith (\\x y -> x * (y + 1)) [1, 2, 3] [4, 5, 6] -- Haskell\n"
  },
  {
    "path": "doc/include/language-syntax/expr/let.fnk",
    "chars": 108,
    "preview": "(let ((:: a Int) ; Finkel\n      (:: b c Int)\n      (= a 10)\n      (= b 4)\n      (= c 2))\n  (print [a b c]))\n"
  },
  {
    "path": "doc/include/language-syntax/expr/let.hs",
    "chars": 91,
    "preview": "let a :: Int -- Haskell\n    b, c :: Int\n    a = 10\n    b = 4\n    c = 2\nin  print [a, b, c]\n"
  },
  {
    "path": "doc/include/language-syntax/expr/line-comment.fnk",
    "chars": 49,
    "preview": "(putStrLn \"foo\") ; single-line comment in Finkel\n"
  },
  {
    "path": "doc/include/language-syntax/expr/line-comment.hs",
    "chars": 49,
    "preview": "putStrLn \"foo\" -- single-line comment in Haskell\n"
  },
  {
    "path": "doc/include/language-syntax/expr/list-comp.fnk",
    "chars": 41,
    "preview": "[x | (<- x [1 .. 10]) (even x)] ; Finkel\n"
  },
  {
    "path": "doc/include/language-syntax/expr/list-comp.hs",
    "chars": 40,
    "preview": "[x | x <- [1 .. 10], even x] -- Haskell\n"
  },
  {
    "path": "doc/include/language-syntax/expr/list-const.fnk",
    "chars": 25,
    "preview": "(print [1 2 3]) ; Finkel\n"
  },
  {
    "path": "doc/include/language-syntax/expr/list-const.hs",
    "chars": 27,
    "preview": "print [1, 2, 3] -- Haskell\n"
  },
  {
    "path": "doc/include/language-syntax/expr/list-range.fnk",
    "chars": 28,
    "preview": "(print [1 3 .. 9]) ; Finkel\n"
  },
  {
    "path": "doc/include/language-syntax/expr/list-range.hs",
    "chars": 29,
    "preview": "print [1, 3 .. 9] -- Haskell\n"
  },
  {
    "path": "doc/include/language-syntax/expr/map-mul2.fnk",
    "chars": 29,
    "preview": "(map (* 2) [1 2 3]) ; Finkel\n"
  },
  {
    "path": "doc/include/language-syntax/expr/map-mul2.hs",
    "chars": 33,
    "preview": "map ((*) 2) [1, 2, 3] -- Haskell\n"
  },
  {
    "path": "doc/include/language-syntax/expr/map-unary.fnk",
    "chars": 29,
    "preview": "(map (- 1) [1 2 3]) ; Finkel\n"
  },
  {
    "path": "doc/include/language-syntax/expr/map-unary.hs",
    "chars": 33,
    "preview": "map ((-) 1) [1, 2, 3] -- Haskell\n"
  },
  {
    "path": "doc/include/language-syntax/expr/muladd.fnk",
    "chars": 22,
    "preview": "((*+) 2 3 4) ; Finkel\n"
  },
  {
    "path": "doc/include/language-syntax/expr/muladd.hs",
    "chars": 22,
    "preview": "(*+) 2 3 4 -- Haskell\n"
  },
  {
    "path": "doc/include/language-syntax/expr/numeric.fnk",
    "chars": 186,
    "preview": "(do (print 1)     ; decimal integer in Finkel\n    (print 0o77)  ; octal integer\n    (print 0xff)  ; hexadecimal integer\n"
  },
  {
    "path": "doc/include/language-syntax/expr/numeric.hs",
    "chars": 172,
    "preview": "do print 1    -- decimal integer in Haskell\n   print 0o77 -- octal integer\n   print 0xff -- hexadecimal integer\n   print"
  },
  {
    "path": "doc/include/language-syntax/expr/opexp-add.fnk",
    "chars": 23,
    "preview": "(+ 1 2 3 4 5) ; Finkel\n"
  },
  {
    "path": "doc/include/language-syntax/expr/opexp-add.hs",
    "chars": 29,
    "preview": "1 + 2 + 3 + 4 + 5 -- Haskell\n"
  },
  {
    "path": "doc/include/language-syntax/expr/opexp-app.fnk",
    "chars": 59,
    "preview": "(<*> (pure foldr) (Just +) (pure 1) (pure [2 3])) ; Finkel\n"
  },
  {
    "path": "doc/include/language-syntax/expr/opexp-app.hs",
    "chars": 62,
    "preview": "pure foldr <*> Just (+) <*> pure 1 <*> pure [2, 3] -- Haskell\n"
  },
  {
    "path": "doc/include/language-syntax/expr/pat-as.fnk",
    "chars": 51,
    "preview": "(let ((= (@ x (Just n)) expr)) ; Finkel\n  (+ n 1))\n"
  },
  {
    "path": "doc/include/language-syntax/expr/pat-as.hs",
    "chars": 43,
    "preview": "let x@(Just n) = expr -- Haskell\nin  n + 1\n"
  },
  {
    "path": "doc/include/language-syntax/expr/pat-irf.fnk",
    "chars": 58,
    "preview": "(let ((= ~(, a ~(, b c)) expr)) ; Finkel\n  (+ a (* b c)))\n"
  },
  {
    "path": "doc/include/language-syntax/expr/pat-irf.hs",
    "chars": 52,
    "preview": "let ~(a, ~(b, c)) = expr -- Haskell\nin  a + (b * c)\n"
  },
  {
    "path": "doc/include/language-syntax/expr/pat-maybe.fnk",
    "chars": 53,
    "preview": "(case expr ; Finkel\n  (Just x) (+ x 1)\n  Nothing  0)\n"
  },
  {
    "path": "doc/include/language-syntax/expr/pat-maybe.hs",
    "chars": 57,
    "preview": "case expr of -- Haskell\n  Just x -> x + 1\n  Nothing -> 0\n"
  },
  {
    "path": "doc/include/language-syntax/expr/pat-opexp.fnk",
    "chars": 51,
    "preview": "(case expr ; Finkel\n  (: a1 a2 _) (+ a1 a2)\n  _ 0)\n"
  },
  {
    "path": "doc/include/language-syntax/expr/pat-opexp.hs",
    "chars": 58,
    "preview": "case expr of -- Haskell\n  a1 : a2 : _ -> a1 + a2\n  _ -> 0\n"
  },
  {
    "path": "doc/include/language-syntax/expr/sige.fnk",
    "chars": 21,
    "preview": "(:: 42 Int) ; Finkel\n"
  },
  {
    "path": "doc/include/language-syntax/expr/sige.hs",
    "chars": 23,
    "preview": "(42 :: Int) -- Haskell\n"
  },
  {
    "path": "doc/include/language-syntax/expr/string.fnk",
    "chars": 116,
    "preview": "\"Here is a backslant \\\\ as well as \\137, \\\n    \\a numeric escape character, and \\^X, a control character.\" ; Finkel\n"
  },
  {
    "path": "doc/include/language-syntax/expr/string.hs",
    "chars": 118,
    "preview": "\"Here is a backslant \\\\ as well as \\137, \\\n    \\a numeric escape character, and \\^X, a control character.\" -- Haskell\n"
  },
  {
    "path": "doc/include/language-syntax/expr/tup2.fnk",
    "chars": 30,
    "preview": "(print (, True #'x)) ; Finkel\n"
  },
  {
    "path": "doc/include/language-syntax/expr/tup2.hs",
    "chars": 29,
    "preview": "print (True, 'x') -- Haskell\n"
  },
  {
    "path": "doc/include/language-syntax/expr/tup5.fnk",
    "chars": 44,
    "preview": "(print (, True #'x 42 1.23 \"foo\")) ; Finkel\n"
  },
  {
    "path": "doc/include/language-syntax/expr/tup5.hs",
    "chars": 46,
    "preview": "print (True, 'x', 42, 1.23, \"foo\") -- Haskell\n"
  },
  {
    "path": "doc/include/language-syntax/expr/tupfn.fnk",
    "chars": 64,
    "preview": "(<*> (pure (,,,)) (Just 1) (Just 2) (Just 3) (Just 4)) ; Finkel\n"
  },
  {
    "path": "doc/include/language-syntax/expr/tupfn.hs",
    "chars": 66,
    "preview": "pure (,,,) <*> Just 1 <*> Just 2 <*> Just 3 <*> Just 4 -- Haskell\n"
  },
  {
    "path": "doc/include/language-syntax/expr/unit.fnk",
    "chars": 21,
    "preview": "(return ()) ; Finkel\n"
  },
  {
    "path": "doc/include/language-syntax/expr/unit.hs",
    "chars": 21,
    "preview": "return () -- Haskell\n"
  },
  {
    "path": "doc/include/language-syntax/expr/varid.fnk",
    "chars": 29,
    "preview": "(foo-bar-buzz quux) ; Finkel\n"
  },
  {
    "path": "doc/include/language-syntax/expr/varid.hs",
    "chars": 29,
    "preview": "foo_bar_buzz quux -- Haskell\n"
  },
  {
    "path": "doc/include/language-syntax/ffi/export.fnk",
    "chars": 58,
    "preview": "(foreign export ccall \"addInt\"\n  (:: + (-> Int Int Int)))\n"
  },
  {
    "path": "doc/include/language-syntax/ffi/export.hs",
    "chars": 57,
    "preview": "foreign export ccall \"addInt\"\n  (+) :: Int -> Int -> Int\n"
  },
  {
    "path": "doc/include/language-syntax/ffi/import.fnk",
    "chars": 98,
    "preview": "(foreign import ccall safe \"string.h strlen\" ; Finkel\n  (:: cstrlen (-> (Ptr CChar) (IO CSize))))\n"
  },
  {
    "path": "doc/include/language-syntax/ffi/import.hs",
    "chars": 90,
    "preview": "foreign import ccall safe \"string.h strlen\" -- Haskell\n  cstrlen :: Ptr CChar -> IO CSize\n"
  },
  {
    "path": "doc/include/language-syntax/import/altogether.fnk",
    "chars": 63,
    "preview": "(import qualified Data.Maybe as Mb hiding (fromJust)) ; Finkel\n"
  },
  {
    "path": "doc/include/language-syntax/import/altogether.hs",
    "chars": 63,
    "preview": "import qualified Data.Maybe as Mb hiding (fromJust) -- Haskell\n"
  },
  {
    "path": "doc/include/language-syntax/import/entity-list.fnk",
    "chars": 51,
    "preview": "(import Data.Maybe (catMaybes fromMaybe)) ; Finkel\n"
  },
  {
    "path": "doc/include/language-syntax/import/entity-list.hs",
    "chars": 52,
    "preview": "import Data.Maybe (catMaybes, fromMaybe) -- Haskell\n"
  },
  {
    "path": "doc/include/language-syntax/import/hiding.fnk",
    "chars": 57,
    "preview": "(import Data.Maybe hiding (fromJust fromMaybe)) ; Finkel\n"
  },
  {
    "path": "doc/include/language-syntax/import/hiding.hs",
    "chars": 58,
    "preview": "import Data.Maybe hiding (fromJust, fromMaybe) -- Haskell\n"
  },
  {
    "path": "doc/include/language-syntax/import/qualified-as.fnk",
    "chars": 45,
    "preview": "(import qualified Data.Maybe as Mb) ; Finkel\n"
  },
  {
    "path": "doc/include/language-syntax/import/qualified-as.hs",
    "chars": 45,
    "preview": "import qualified Data.Maybe as Mb -- Haskell\n"
  },
  {
    "path": "doc/include/language-syntax/import/simpl.fnk",
    "chars": 29,
    "preview": "(import Data.Maybe) ; Finkel\n"
  },
  {
    "path": "doc/include/language-syntax/import/simpl.hs",
    "chars": 29,
    "preview": "import Data.Maybe -- Haskell\n"
  },
  {
    "path": "doc/include/language-syntax/module/export-list.fnk",
    "chars": 462,
    "preview": "(module M2 ; Finkel\n  f1           ; Value, field name, or class method\n  T1           ; Type constructor only\n  (T2 ..)"
  },
  {
    "path": "doc/include/language-syntax/module/export-list.hs",
    "chars": 488,
    "preview": "module M2 -- Haskell\n  ( f1           -- Value, field name, or class method\n  , T1           -- Type constructor only\n  "
  },
  {
    "path": "doc/include/language-syntax/module/simpl.fnk",
    "chars": 37,
    "preview": "(module M1) ; Finkel\n(= x 1)\n(= y 2)\n"
  },
  {
    "path": "doc/include/language-syntax/module/simpl.hs",
    "chars": 39,
    "preview": "module M1 where -- Haskell\nx = 1\ny = 2\n"
  },
  {
    "path": "doc/include/macros/RequireMe.fnk",
    "chars": 207,
    "preview": ";;;; File: RequireMe.fnk\n\n(defmodule RequireMe\n  (export say-hello say-bye)\n  (import (Finkel.Prelude)))\n\n(defmacro say-"
  },
  {
    "path": "doc/include/macros/arglist.console",
    "chars": 244,
    "preview": "$ finkel make -fno-code -ddump-parsed arglist.fnk\n\n==================== Parser ====================\nmodule Main where\nma"
  },
  {
    "path": "doc/include/macros/arglist.fnk",
    "chars": 225,
    "preview": ";;;; File: arglist.fnk\n\n(defmodule Main\n  (import-when [:compile]\n    (Finkel.Prelude)))\n\n(eval-when [:compile]\n  (defma"
  },
  {
    "path": "doc/include/macros/begin.console",
    "chars": 537,
    "preview": "$ finkel make -fno-code -ddump-parsed begin.fnk\n\n==================== Parser ====================\nmodule Main where\nimpo"
  },
  {
    "path": "doc/include/macros/begin.fnk",
    "chars": 829,
    "preview": ";;;; File: begin.fnk\n\n%p(LANGUAGE DataKinds)\n\n(defmodule Main\n  (import-when [:compile]\n    (Finkel.Prelude))\n  (import "
  },
  {
    "path": "doc/include/macros/eval-when-compile.console",
    "chars": 414,
    "preview": "$ finkel make -fno-code -ddump-parsed eval-when-compile.fnk\n\n==================== Parser ====================\nmodule Mai"
  },
  {
    "path": "doc/include/macros/eval-when-compile.fnk",
    "chars": 674,
    "preview": ";;;; File: eval-when-compile.fnk\n\n(defmodule Main\n  (import-when [:compile]\n    (Finkel.Prelude)))\n\n(:eval-when-compile\n"
  },
  {
    "path": "doc/include/macros/eval-when.console",
    "chars": 298,
    "preview": "$ finkel make -fno-code -ddump-parsed eval-when.fnk\n\n==================== Parser ====================\nmodule Main where\n"
  },
  {
    "path": "doc/include/macros/eval-when.fnk",
    "chars": 320,
    "preview": ";;; File: eval-when.fnk\n\n(defmodule Main\n  (import-when [:compile]\n    (Finkel.Prelude)))\n\n(eval-when [:compile]\n  (defm"
  },
  {
    "path": "doc/include/macros/fib-macro.console",
    "chars": 215,
    "preview": "$ finkel make -fno-code -ddump-parsed fib-macro.fnk\n\n==================== Parser ====================\nmodule Main where\n"
  },
  {
    "path": "doc/include/macros/fib-macro.fnk",
    "chars": 414,
    "preview": ";;;; File: fib-macro.fnk\n\n(defmodule Main\n  (import-when [:compile]\n    (Finkel.Prelude)))\n\n(eval-when [:compile]\n  (def"
  },
  {
    "path": "doc/include/macros/macrolet.console",
    "chars": 295,
    "preview": "$ finkel make -fno-code -ddump-parsed macrolet.fnk\n\n==================== Parser ====================\nmodule Main where\nm"
  },
  {
    "path": "doc/include/macros/macrolet.fnk",
    "chars": 323,
    "preview": ";;;; File: macrolet.fnk\n\n(defmodule Main\n  (import-when [:compile]\n    (Finkel.Prelude)))\n\n(macrolet ((say-hello []\n    "
  },
  {
    "path": "doc/include/macros/quasiquote.console",
    "chars": 155,
    "preview": "$ finkel make -o quasiquote quasiquote.fnk\n[1 of 1] Compiling Main             ( quasiquote.fnk, quasiquote.o )\nLinking "
  },
  {
    "path": "doc/include/macros/quasiquote.fnk",
    "chars": 375,
    "preview": ";;;; File: quasiquote.fnk\n\n(defmodule Main\n  (import (Finkel.Prelude)))\n\n(defn (:: with-sugar [Code])\n  [`(foo ,(length "
  },
  {
    "path": "doc/include/macros/quasiquote904.console",
    "chars": 160,
    "preview": "$ finkel make -o quasiquote quasiquote.fnk\n[1 of 2] Compiling Main             ( quasiquote.fnk, quasiquote.o )\n[2 of 2]"
  },
  {
    "path": "doc/include/macros/quote.console",
    "chars": 566,
    "preview": "$ finkel make -fno-code -ddump-parsed quote.fnk\n\n==================== Parser ====================\nmodule Main where\nimpo"
  },
  {
    "path": "doc/include/macros/quote.fnk",
    "chars": 273,
    "preview": ";;;; File: quote.fnk\n\n(defmodule Main\n  (import (Finkel.Prelude)))\n\n(defn (:: main (IO ()))\n  (do (putStrLn \";;; quote ;"
  },
  {
    "path": "doc/include/macros/raw-require.console",
    "chars": 308,
    "preview": "$ finkel make -fno-code -ddump-parsed raw-require.fnk\n\n==================== Parser ====================\nmodule Main wher"
  }
]

// ... and 341 more files (download for full content)

About this extraction

This page contains the full source code of the finkel-lang/finkel GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 541 files (1.2 MB), approximately 380.1k tokens, and a symbol index with 7 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!