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': '',
# # 'logo_icon': '',
# 'logo_icon': '',
# '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
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
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.