on master help sign in
Merge branch 'master' into fix/master/1211
commit532ef6ce85f5f0b21bc702a80a0151a7fbbb969d authorEdwin Brady <edwin.brady@gmail.com> dateSat 2 Sep 2017, 14:29 (9 years ago) parenta0de8cb4251ad8
115 files changed+1926−701
.github/ISSUE_TEMPLATE.md+9 .gitignore+1 .travis.yml−13 CHANGELOG.md+15−1 CONTRIBUTING.md+15 CONTRIBUTORS+2 Setup.hs+54−42 appveyor.yml+5−4 benchmarks/fasta/fasta.idr−4 docs/reference/partial-evaluation.rst+10−10 docs/reference/syntax-guide.rst+1−1 docs/st/composing.rst+1−1 idris.cabal+29−49 jsrts/Runtime-node.js+1−1 libs/base/System.idr+1 libs/contrib/CFFI/Types.idr+5−5 libs/contrib/Data/Pairs/Implicit.idr+13 libs/contrib/Data/Stream/Extra.idr+10 libs/contrib/Data/ZZ.idr+2−2 libs/contrib/Interfaces/Correlative.idr+55 libs/contrib/Network/Socket.idr+1−5 libs/contrib/Network/Socket/Raw.idr−3 libs/contrib/Text/Lexer.idr+161−32 libs/contrib/Text/Literate.idr+155 libs/contrib/Text/Parser.idr+67−26 libs/contrib/Text/PrettyPrint/WL.idr+18 libs/contrib/Text/PrettyPrint/WL/Characters.idr+103 libs/contrib/Text/PrettyPrint/WL/Combinators.idr+259 libs/contrib/Text/PrettyPrint/WL/Core.idr+225 libs/contrib/contrib.ipkg+12−2 libs/effects/Effect/Logging/Level.idr+9−9 libs/prelude/Prelude.idr+1−2 libs/prelude/Prelude/Bits.idr+4−4 libs/prelude/Prelude/List.idr+5−1 libs/prelude/Prelude/Nat.idr+10−2 libs/pruviloj/Pruviloj/Core.idr+48−2 libs/pruviloj/Pruviloj/Derive/Eliminators.idr+2−2 rts/Makefile+3−4 rts/idris_net.c+36−7 rts/idris_net.h+13 rts/idris_rts.c+10−4 rts/idris_rts.h+2−7 rts/idris_stdfgn.c−4 rts/idris_stdfgn.h−2 rts/windows/idris_net.c−200 scripts/runidris+25 scripts/runidris-node+25 src/IRTS/CodegenC.hs+3−1 src/IRTS/Compiler.hs+17−15 src/IRTS/Defunctionalise.hs+24−25 src/IRTS/JavaScript/Codegen.hs+43−55 src/IRTS/JavaScript/LangTransforms.hs+2−2 src/IRTS/JavaScript/PrimOp.hs+4 src/IRTS/Lang.hs+17−17 src/IRTS/LangOpts.hs+9−9 src/IRTS/Portable.hs+1−1 src/IRTS/Simplified.hs+4−5 src/Idris/AbsSyntax.hs+9−1 src/Idris/AbsSyntaxTree.hs+10−1 src/Idris/Apropos.hs+1 src/Idris/CaseSplit.hs+1−1 src/Idris/Chaser.hs+2 src/Idris/CmdOptions.hs−2 src/Idris/Core/Binary.hs+6−2 src/Idris/Core/CaseTree.hs+3−2 src/Idris/Core/DeepSeq.hs+4−1 src/Idris/Core/ProofState.hs+2−1 src/Idris/Core/TT.hs+4−2 src/Idris/Core/Typecheck.hs+2−2 src/Idris/Core/Unify.hs+1−1 src/Idris/Core/WHNF.hs+1−1 src/Idris/Coverage.hs+1−1 src/Idris/DSL.hs+2 src/Idris/DataOpts.hs+1−1 src/Idris/DeepSeq.hs−14 src/Idris/Docstrings.hs+2−1 src/Idris/Elab/Quasiquote.hs+1 src/Idris/Elab/Term.hs+4−2 src/Idris/Elab/Utils.hs+7−6 src/Idris/Erasure.hs+120−12 src/Idris/Error.hs+1 src/Idris/IBC.hs+24−24 src/Idris/IdrisDoc.hs+1 src/Idris/Imports.hs+13−1 src/Idris/Output.hs+1 src/Idris/Package/Parser.hs+1−8 src/Idris/Parser.hs+9−4 src/Idris/Parser/Expr.hs+7 src/Idris/Parser/Helpers.hs+3−9 src/Idris/Parser/Ops.hs+2−1 src/Idris/PartialEval.hs+1−1 src/Idris/Prover.hs+1 src/Idris/REPL.hs+1−1 src/Idris/Reflection.hs−5 src/Util/Pretty.hs+3 stack-shell.nix+1−1 stack.yaml+4−2 test/TestData.hs+2−1 test/TestRun.hs+2−3 test/base001/exit1.c+4 test/base001/sys.c+4 test/basic009/expected+1−1 test/basic018/expected+4−2 test/interactive017/TestMod.idr+5 test/interactive017/expected+7 test/interactive017/run+9 test/interactive017/shebang-args.idr+6 test/interactive017/shebang-import.idr+6 test/interactive017/shebang-node.idr+4 test/interactive017/shebang.idr+4 test/proof002/Reflect.idr+1−1 test/regression002/expected+2−1 test/regression003/expected+1 test/regression003/regression003.idr+56 test/regression003/run+4
.github/ISSUE_TEMPLATE.mdnew file+9
@@ -0,0 +1,9 @@
1+Please attach complete source files that exhibit the issue in addition
2+to quoting from them here.
3+
4+# Steps to Reproduce
5+
6+# Expected Behavior
7+
8+# Observed Behavior
9+
.gitignore+1
@@ -1,5 +1,6 @@
11# Build artefacts
22dist
3+dist-newstyle
34*.ibc
45*.o
56*.a
.travis.yml−13
@@ -11,15 +11,6 @@ matrix:
1111 include:
1212 - env: CABALVER="1.24" GHCVER="8.0.1" STACKVER="7.14" STYLISH=YES
1313 addons: {apt: {packages: [cabal-install-1.24,ghc-8.0.1,hscolour], sources: [hvr-ghc]}}
14− - os: osx
15− env: CABALVER="1.24" GHCVER="8.0.1" TESTS="test_c"
16− compiler: ": #GHC 8.0.1"
17− - env: CABALVER="1.20" GHCVER="7.6.3" TESTS="test_c"
18− compiler: ": #GHC 7.6.3"
19− addons: {apt: {packages: [cabal-install-1.20,ghc-7.6.3,cppcheck,hscolour], sources: [hvr-ghc]}}
20− - env: CABALVER="1.20" GHCVER="7.8.4" TESTS="test_c"
21− compiler: ": #GHC 7.8.4"
22− addons: {apt: {packages: [cabal-install-1.20,ghc-7.8.4,cppcheck,hscolour], sources: [hvr-ghc]}}
2314 - env: CABALVER="1.22" GHCVER="7.10.3" TESTS="lib_doc doc"
2415 compiler: ": #GHC 7.10.3"
2516 addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.3,cppcheck,hscolour], sources: [hvr-ghc]}}
@@ -38,10 +29,6 @@ matrix:
3829 - env: CABALVER="1.24" GHCVER="8.0.1" TESTS="test_c"
3930 compiler: ": #GHC 8.0.1"
4031 addons: {apt: {packages: [cabal-install-1.24,ghc-8.0.1,cppcheck,hscolour], sources: [hvr-ghc]}}
41− allow_failures:
42− - os: osx
43− env: CABALVER="1.24" GHCVER="8.0.1" TESTS="test_c"
44− compiler: ": #GHC 8.0.1"
4532 fast-finish: true
4633
4734cache:
CHANGELOG.md+15−1
@@ -1,7 +1,21 @@
1−# New in 1.0.1
1+# New in 1.1.*
2+
3++ Addition of `Text.Literate`, a module for working with literate
4+ source files.
5+
6+# New in 1.1.1
7+
8++ Erasure analysis is now faster thanks to a bit smarter constraint solving.
9++ Fixed installation issue
10++ Fixed a potential segfault when concatenating strings
11+
12+# New in 1.1.0
213
314## Library Updates
415
16++ Added `Text.PrettyPrint.WL` an implementation of the Wadler-Leijen
17+ Pretty-Print algorithm. Useful for those wishing to pretty print
18+ things.
519+ Added `Text.Lexer` and `Text.Parser` to `contrib`. These are small libraries
620 for implementing total lexical analysers and parsers.
721+ New instances:
CONTRIBUTING.md+15
@@ -20,6 +20,21 @@ Here are a few guidelines that we would like contributors to follow so that we c
2020Before you report an issue, or wish to add cool functionality please try and check to see if there are existing [issues](https://github.com/idris-lang/Idris-dev/issues) and [pull requests](https://github.com/idris-lang/Idris-dev/pulls).
2121We do not want you wasting your time, duplicating somebody's work!
2222
23+### Template
24+Try as closely as possible to describe the issue, ensuring that it has sections that match the following headings:
25+> \# Steps to Reproduce
26+>
27+> \# Expected Behavior
28+>
29+> \# Observed Behavior
30+>
31+>
32+
33+In addition, please attach complete source files that exhibit the issue to quoting from them in the issue.
34+
35+### Feature Requests
36+We would be delighted to receive feature requests only if they are feasible to implement and the author is willing to implement the suggested features themself. The current Idris developer team consists mostly of volunteers, and so it is unfortunately hard to accommodate implementing nice-to-have ideas that are not essential for core language development.
37+
2338## The Campsite Rule
2439
2540We try to follow the **campsite rule**: leave the code base in better condition than you found it.
CONTRIBUTORS+2
@@ -151,6 +151,7 @@ Michael Gilliland
151151Michael Hensler
152152Michael Maloney
153153Michael McGirr
154+Michael Morgan
154155Michael Thompson
155156Michael Weiss
156157Miikka Koskinen
@@ -200,6 +201,7 @@ Sven Koschnicke
200201tdidriksen
201202Tenor Biel
202203Thomas Cooper
204+Thomas Scholtes
203205Tim Dysinger
204206Tim McGilchrist
205207Timo Petteri Sinnemäki
Setup.hs+54−42
@@ -1,11 +1,15 @@
11{-# LANGUAGE CPP #-}
22
3+#if !defined(MIN_VERSION_Cabal)
4+# define MIN_VERSION_Cabal(x,y,z) 0
5+#endif
6+
37import Control.Monad
48import Data.IORef
59import Control.Exception (SomeException, catch)
610
711import Distribution.Simple
8−import Distribution.Simple.BuildPaths (autogenModulesDir)
12+import Distribution.Simple.BuildPaths
913import Distribution.Simple.InstallDirs as I
1014import Distribution.Simple.LocalBuildInfo as L
1115import qualified Distribution.Simple.Setup as S
@@ -22,6 +26,11 @@ import System.Directory
2226import qualified System.FilePath.Posix as Px
2327import System.Process
2428
29+#if (MIN_VERSION_Cabal(2,0,0))
30+import Distribution.Types.UnqualComponentName
31+#endif
32+
33+
2534-- After Idris is built, we need to check and install the prelude and other libs
2635
2736-- -----------------------------------------------------------------------------
@@ -56,32 +65,37 @@ windres verbosity = P.runProgramInvocation verbosity . P.simpleProgramInvocation
5665
5766usesGMP :: S.ConfigFlags -> Bool
5867usesGMP flags =
59− case lookup (FlagName "gmp") (S.configConfigurationsFlags flags) of
68+ case lookup (mkFlagName "gmp") (S.configConfigurationsFlags flags) of
6069 Just True -> True
6170 Just False -> False
6271 Nothing -> False
6372
6473execOnly :: S.ConfigFlags -> Bool
6574execOnly flags =
66− case lookup (FlagName "execonly") (S.configConfigurationsFlags flags) of
75+ case lookup (mkFlagName "execonly") (S.configConfigurationsFlags flags) of
6776 Just True -> True
6877 Just False -> False
6978 Nothing -> False
7079
7180isRelease :: S.ConfigFlags -> Bool
7281isRelease flags =
73− case lookup (FlagName "release") (S.configConfigurationsFlags flags) of
82+ case lookup (mkFlagName "release") (S.configConfigurationsFlags flags) of
7483 Just True -> True
7584 Just False -> False
7685 Nothing -> False
7786
7887isFreestanding :: S.ConfigFlags -> Bool
7988isFreestanding flags =
80− case lookup (FlagName "freestanding") (S.configConfigurationsFlags flags) of
89+ case lookup (mkFlagName "freestanding") (S.configConfigurationsFlags flags) of
8190 Just True -> True
8291 Just False -> False
8392 Nothing -> False
8493
94+#if !(MIN_VERSION_Cabal(2,0,0))
95+mkFlagName :: String -> FlagName
96+mkFlagName = FlagName
97+#endif
98+
8599-- -----------------------------------------------------------------------------
86100-- Clean
87101
@@ -151,20 +165,22 @@ generateToolchainModule verbosity srcDir toolDir = do
151165 createDirectoryIfMissingVerbose verbosity True srcDir
152166 rewriteFile toolPath (commonContent ++ toolContent)
153167
154−idrisConfigure _ flags _ local = do
168+idrisConfigure _ flags pkgdesc local = do
155169 configureRTS
156− generateVersionModule verbosity (autogenModulesDir local) (isRelease (configFlags local))
157− if isFreestanding $ configFlags local
158− then do
159− toolDir <- lookupEnv "IDRIS_TOOLCHAIN_DIR"
160− generateToolchainModule verbosity (autogenModulesDir local) toolDir
161− targetDir <- lookupEnv "IDRIS_LIB_DIR"
162− case targetDir of
163− Just d -> generateTargetModule verbosity (autogenModulesDir local) d
164− Nothing -> error $ "Trying to build freestanding without a target directory."
165− ++ " Set it by defining IDRIS_LIB_DIR."
166− else
167− generateToolchainModule verbosity (autogenModulesDir local) Nothing
170+ withLibLBI pkgdesc local $ \_ libcfg -> do
171+ let libAutogenDir = autogenComponentModulesDir local libcfg
172+ generateVersionModule verbosity libAutogenDir (isRelease (configFlags local))
173+ if isFreestanding $ configFlags local
174+ then do
175+ toolDir <- lookupEnv "IDRIS_TOOLCHAIN_DIR"
176+ generateToolchainModule verbosity libAutogenDir toolDir
177+ targetDir <- lookupEnv "IDRIS_LIB_DIR"
178+ case targetDir of
179+ Just d -> generateTargetModule verbosity libAutogenDir d
180+ Nothing -> error $ "Trying to build freestanding without a target directory."
181+ ++ " Set it by defining IDRIS_LIB_DIR."
182+ else
183+ generateToolchainModule verbosity libAutogenDir Nothing
168184 where
169185 verbosity = S.fromFlag $ S.configVerbosity flags
170186 version = pkgVersion . package $ localPkgDescr local
@@ -175,6 +191,10 @@ idrisConfigure _ flags _ local = do
175191 -- the file after configure.
176192 configureRTS = make verbosity ["-C", "rts", "clean"]
177193
194+#if !(MIN_VERSION_Cabal(2,0,0))
195+ autogenComponentModulesDir lbi _ = autogenModulesDir lbi
196+#endif
197+
178198idrisPreSDist args flags = do
179199 let dir = S.fromFlag (S.sDistDirectory flags)
180200 let verb = S.fromFlag (S.sDistVerbosity flags)
@@ -213,11 +233,16 @@ getVersion args flags = do
213233 let buildinfo = (emptyBuildInfo { cppOptions = ["-DVERSION="++hash] }) :: BuildInfo
214234 return (Just buildinfo, [])
215235
236+
237+#if !(MIN_VERSION_Cabal(2,0,0))
238+mkUnqualComponentName = id
239+#endif
240+
216241idrisPreBuild args flags = do
217242#ifdef mingw32_HOST_OS
218243 createDirectoryIfMissingVerbose verbosity True dir
219244 windres verbosity ["icons/idris_icon.rc","-o", dir++"/idris_icon.o"]
220− return (Nothing, [("idris", emptyBuildInfo { ldOptions = [dir ++ "/idris_icon.o"] })])
245+ return (Nothing, [(mkUnqualComponentName "idris", emptyBuildInfo { ldOptions = [dir ++ "/idris_icon.o"] })])
221246 where
222247 verbosity = S.fromFlag $ S.buildVerbosity flags
223248 dir = S.fromFlagOrDefault "dist" $ S.buildDistPref flags
@@ -225,9 +250,10 @@ idrisPreBuild args flags = do
225250 return (Nothing, [])
226251#endif
227252
228−idrisBuild _ flags _ local = unless (execOnly (configFlags local)) $ do
229− buildStdLib
230− buildRTS
253+idrisBuild _ flags _ local
254+ = if (execOnly (configFlags local)) then buildRTS
255+ else do buildStdLib
256+ buildRTS
231257 where
232258 verbosity = S.fromFlag $ S.buildVerbosity flags
233259
@@ -246,10 +272,11 @@ idrisBuild _ flags _ local = unless (execOnly (configFlags local)) $ do
246272-- -----------------------------------------------------------------------------
247273-- Copy/Install
248274
249−idrisInstall verbosity copy pkg local = unless (execOnly (configFlags local)) $ do
250− installStdLib
251− installRTS
252− installManPage
275+idrisInstall verbosity copy pkg local
276+ = if (execOnly (configFlags local)) then installRTS
277+ else do installStdLib
278+ installRTS
279+ installManPage
253280 where
254281 target = datadir $ L.absoluteInstallDirs pkg local copy
255282
@@ -274,26 +301,15 @@ idrisInstall verbosity copy pkg local = unless (execOnly (configFlags local)) $
274301-- -----------------------------------------------------------------------------
275302-- Test
276303
277−-- FIXME: We use the __GLASGOW_HASKELL__ macro because MIN_VERSION_cabal seems
278−-- to be broken !
279−
280304-- There are two "dataDir" in cabal, and they don't relate to each other.
281305-- When fetching modules, idris uses the second path (in the pkg record),
282306-- which by default is the root folder of the project.
283307-- We want it to be the install directory where we put the idris libraries.
284308fixPkg pkg target = pkg { dataDir = target }
285309
286−-- The "Args" argument of the testHooks has been added in cabal 1.22.0,
287−-- and should therefore be ignored for prior versions.
288−#if __GLASGOW_HASKELL__ < 710
289−originalTestHook _ = testHook simpleUserHooks
290−#else
291−originalTestHook = testHook simpleUserHooks
292−#endif
293−
294310idrisTestHook args pkg local hooks flags = do
295311 let target = datadir $ L.absoluteInstallDirs pkg local NoCopyDest
296− originalTestHook args (fixPkg pkg target) local hooks flags
312+ testHook simpleUserHooks args (fixPkg pkg target) local hooks flags
297313
298314-- -----------------------------------------------------------------------------
299315-- Main
@@ -314,9 +330,5 @@ main = defaultMainWithHooks $ simpleUserHooks
314330 , preSDist = idrisPreSDist
315331 , sDistHook = idrisSDist (sDistHook simpleUserHooks)
316332 , postSDist = idrisPostSDist
317−#if __GLASGOW_HASKELL__ < 710
318− , testHook = idrisTestHook ()
319−#else
320333 , testHook = idrisTestHook
321−#endif
322334 }
appveyor.yml+5−4
@@ -6,9 +6,9 @@ init:
66 mkdir C:\ghc
77
88 Invoke-WebRequest "http://downloads.haskell.org/~ghc/7.10.3/ghc-7.10.3-x86_64-unknown-mingw32.tar.xz" -OutFile C:\ghc\ghc.tar.xz -UserAgent "Curl"
9−
9+
1010 7z x C:\ghc\ghc.tar.xz -oC:\ghc
11−
11+
1212 7z x C:\ghc\ghc.tar -oC:\ghc
1313
1414 $env:PATH="$env:PATH;c:\ghc\ghc-7.10.3\bin;$HOME\AppData\Roaming\cabal\bin"
@@ -21,6 +21,7 @@ environment:
2121 MSYSTEM: MINGW64
2222 MSYS2_PATH_TYPE: inherit
2323build_script:
24−- ps: c:\msys64\usr\bin\bash -l -c "cd $env:current_posix && cabal install -fffi -j4 --enable-tests"
24+- ps: >-
25+ c:\msys64\usr\bin\bash -l -c "cd $env:current_posix && cabal install -fffi --enable-tests 2>&1"
2526test_script:
26−- ps: c:\msys64\usr\bin\bash -l -c "cd $env:current_posix && make test_c"
27+- ps: c:\msys64\usr\bin\bash -l -c "cd $env:current_posix && make test_c 2>&1"
benchmarks/fasta/fasta.idr−4
@@ -38,10 +38,6 @@ replicate : Int -> Char -> String
3838replicate 0 c = ""
3939replicate n c = singleton c <+> replicate (n-1) c
4040
41−scanl : (f : acc -> a -> acc) -> acc -> List a -> List acc
42−scanl f q ls = q :: (case ls of
43− [] => []
44− x::xs => scanl f (f q x) xs)
4541
4642accum : (Char,Double) -> (Char,Double) -> (Char,Double)
4743accum (_,p) (c,q) = (c,p+q)
docs/reference/partial-evaluation.rst+10−10
@@ -4,15 +4,15 @@ Static Arguments and Partial Evaluation
44
55As of version 0.9.15, Idris has support for *partial evaluation* of
66statically known arguments. This involves creating specialised versions
7−of functions with arguments annotated as ``[static]``.
7+of functions with arguments annotated as ``%static``.
88
99(This is an implementation of the partial evaluator described in `this
1010ICFP 2010
1111paper <http://eb.host.cs.st-andrews.ac.uk/writings/icfp10.pdf>`__.
1212Please refer to this for more precise definitions of what follows.)
1313
14−Partial evaluation is switched on by default. It can be disabled with
15−the ``--no-partial-eval`` flag.
14+Partial evaluation is switched off by default since Idris 1.0. It can
15+be enabled with the ``--partial-eval`` flag.
1616
1717Introductory Example
1818--------------------
@@ -66,18 +66,18 @@ Automatic specialisation of ``pow``
6666~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
6767
6868The trick is to mark the statically known arguments with the
69−``[static]`` flag:
69+``%static`` flag:
7070
7171::
7272
73− my_pow : Nat -> [static] Nat -> Nat
73+ my_pow : Nat -> %static Nat -> Nat
7474 my_pow k Z = 1
7575 my_pow k (S j) = mult k (my_pow k j)
7676
7777When an argument is annotated in this way, Idris will try to create a
7878specialised version whenever it accounts a call with a concrete value
7979(i.e. a constant, constructor form, or globally defined function) in a
80−``[static]`` position. If ``my_pow`` is defined this way, and ``powFn``
80+``%static`` position. If ``my_pow`` is defined this way, and ``powFn``
8181defined as above, we can see the effect by typing ``:printdef powFn`` at
8282the REPL:
8383
@@ -108,7 +108,7 @@ Specialising Type Classes
108108-------------------------
109109
110110Type class dictionaries are very often statically known, so Idris
111−automatically marks any type class constraint as ``[static]`` and builds
111+automatically marks any type class constraint as ``%static`` and builds
112112specialised versions of top level functions where the class is
113113instantiated. For example, given:
114114
@@ -177,7 +177,7 @@ writing ``map`` as follows:
177177
178178::
179179
180− my_map : [static] (a -> b) -> List a -> List b
180+ my_map : %static (a -> b) -> List a -> List b
181181 my_map f [] = []
182182 my_map f (x :: xs) = f x :: my_map f xs
183183
@@ -246,11 +246,11 @@ Then, a function which calculates the factorial of its input:
246246 (App (App eMult (App eFac (Op (-) x (Val 1)))) x))
247247
248248The interpreter's type is written as follows, marking the expression to
249−be evaluated as ``[static]``:
249+be evaluated as ``%static``:
250250
251251::
252252
253− interp : (env : Env gamma) -> [static] (e : Expr gamma t) -> interpTy t
253+ interp : (env : Env gamma) -> %static (e : Expr gamma t) -> interpTy t
254254
255255This means that if we write an Idris program to calculate a factorial by
256256calling ``interp`` on ``eFac``, the resulting definition will be
docs/reference/syntax-guide.rst+1−1
@@ -223,7 +223,7 @@ Every occurence of the the defined type in a constructor argument will be
223223wrapped in the ``Inf`` type constructor. This has the effect of delaying the
224224evaluation of the second argument when the data constructor is applied.
225225An ``Inf`` argument is constructed using ``Delay`` (which Idris will insert
226−implicitly) adn evaluated using ``Force`` (again inserted implicitly).
226+implicitly) and evaluated using ``Force`` (again inserted implicitly).
227227
228228Furthermore, recursive calls under a ``Delay`` must be guarded by a constructor
229229to pass the totality checker.
docs/st/composing.rst+1−1
@@ -437,7 +437,7 @@ using the SDL bindings as follows:
437437
438438.. code-block:: idris
439439
440− interface Draw IO where
440+ implementation Draw IO where
441441 Surface = State SDLSurface
442442
443443 initWindow x y = do Just srf <- lift (startSDL x y)
idris.cabal+29−49
@@ -1,5 +1,5 @@
11Name: idris
2−Version: 1.0
2+Version: 1.1.1
33License: BSD3
44License-file: LICENSE
55Author: Edwin Brady
@@ -40,11 +40,11 @@ Description: Idris is a general purpose language with full dependent types.
4040 .
4141 * Hugs style interactive environment
4242
43−Cabal-Version: >= 1.8.1
43+Cabal-Version: >= 1.18
4444
4545Build-type: Custom
4646
47−Tested-With: GHC == 7.6.3, GHC == 7.8.4, GHC == 7.10.3, GHC == 8.0.1
47+Tested-With: GHC == 7.10.3, GHC == 8.0.1
4848
4949Data-files: idrisdoc/styles.css
5050 jsrts/jsbn/jsbn-browser.js
@@ -97,6 +97,14 @@ source-repository head
9797 type: git
9898 location: git://github.com/idris-lang/Idris-dev.git
9999
100+custom-setup
101+ setup-depends:
102+ Cabal >= 1.10 && <2.1,
103+ base >= 4 && <5,
104+ directory,
105+ filepath,
106+ process
107+
100108Flag FFI
101109 Description: Build support for libffi
102110 Default: False
@@ -259,17 +267,17 @@ Library
259267 , Tools_idris
260268
261269 Build-depends: base >=4 && <5
262− , aeson >= 0.6 && < 1.2
270+ , aeson >= 0.6 && < 1.3
263271 , annotated-wl-pprint >= 0.7 && < 0.8
264272 , ansi-terminal < 0.7
265273 , ansi-wl-pprint < 0.7
266274 , array >= 0.4.0.1 && < 0.6
267275 , base64-bytestring < 1.1
268− , binary >= 0.7 && < 0.9
276+ , binary >= 0.8.4.1 && < 0.9
269277 , blaze-html >= 0.6.1.3 && < 0.10
270278 , blaze-markup >= 0.5.2.1 && < 0.9
271279 , bytestring < 0.11
272− , cheapskate < 0.2
280+ , cheapskate >= 0.1.1 && < 0.2
273281 , code-page >= 0.1 && < 0.2
274282 , containers >= 0.5 && < 0.6
275283 , deepseq < 1.5
@@ -277,20 +285,22 @@ Library
277285 , filepath < 1.5
278286 , fingertree >= 0.1 && < 0.2
279287 , haskeline >= 0.7 && < 0.8
280− , ieee754 >= 0.7 && <= 0.8.0
288+ , ieee754 >= 0.7 && < 0.9
281289 , mtl >= 2.1 && < 2.3
282290 , network < 2.7
283− , optparse-applicative >= 0.11 && < 0.14
291+ , optparse-applicative >= 0.13 && < 0.15
284292 , parsers >= 0.9 && < 0.13
285293 , pretty < 1.2
294+ , process < 1.7
286295 , regex-tdfa >= 1.2
296+ , safe >= 0.3.9
287297 , split < 0.3
288298 , terminal-size < 0.4
289299 , text >=1.2.1.0 && < 1.3
290− , time >= 1.4 && < 1.7
300+ , time >= 1.4 && < 1.9
291301 , transformers < 0.6
292302 , transformers-compat >= 0.3
293− , trifecta >= 1.6 && < 1.7
303+ , trifecta >= 1.6 && < 1.8
294304 , uniplate >=1.6 && < 1.7
295305 , unordered-containers < 0.3
296306 , utf8-string < 1.1
@@ -300,47 +310,14 @@ Library
300310 , fsnotify >= 0.2 && < 2.2
301311 , async < 2.2
302312
303−
304− -- zlib >= 0.6.1 is broken with GHC < 7.10.3
305− -- Travis is broken for 7.6 and 7.8 with a newer process
306− if impl(ghc < 7.10.3)
307− build-depends: zlib < 0.6.1
308− , process < 1.3
309− else
310− build-depends: process < 1.5
311−
312− -- safe 0.3.10 is having issues with cabal 1.20 and ghc 7.6.3, the
313− -- hvr ghc ppa doesn't provide a new enough cabal library. Temporary
314− -- fix until hvr ghc ppa is fixed or we deprecate support for 7.6.3.
315− if impl(ghc < 7.8.4)
316− build-depends: safe == 0.3.9
317− else
318− build-depends: safe >= 0.3.9
319−
320− if impl(ghc < 7.8.4)
321− build-depends: tagsoup < 0.14.1
322−
323− Extensions: MultiParamTypeClasses
324− , DeriveFoldable
325− , DeriveTraversable
326− , FunctionalDependencies
327− , FlexibleContexts
328− , FlexibleInstances
329− , TemplateHaskell
330−
313+ Default-Language: Haskell2010
331314 ghc-prof-options: -auto-all -caf-all
332315
333− if os(linux)
334− build-depends: unix < 2.8
335− if os(freebsd)
336− build-depends: unix < 2.8
337− if os(dragonfly)
338− build-depends: unix < 2.8
339− if os(darwin)
340− build-depends: unix < 2.8
341316 if os(windows)
342317 build-depends: mintty >= 0.1 && < 0.2
343318 , Win32 < 2.4
319+ else
320+ build-depends: unix < 2.8
344321 if flag(FFI)
345322 build-depends: libffi < 0.2
346323 cpp-options: -DIDRIS_FFI
@@ -365,6 +342,7 @@ Executable idris
365342 , haskeline >= 0.7
366343 , transformers
367344
345+ Default-Language: Haskell2010
368346 ghc-prof-options: -auto-all -caf-all
369347 ghc-options: -threaded -rtsopts -funbox-strict-fields -with-rtsopts=-I0
370348
@@ -382,17 +360,16 @@ Test-suite regression-and-feature-tests
382360 , filepath
383361 , directory
384362 , haskeline >= 0.7
385− , optparse-applicative >= 0.11 && < 0.14
363+ , optparse-applicative >= 0.13 && < 0.15
386364 , tagged
387365 , tasty >= 0.8
388366 , tasty-golden >= 2.0
389367 , tasty-rerun >= 1.0.0
390368 , bytestring
391369 , transformers
392− if impl(ghc < 7.10)
393− Extensions: DeriveDataTypeable
394370
395371
372+ Default-Language: Haskell2010
396373 ghc-prof-options: -auto-all -caf-all
397374 ghc-options: -threaded -rtsopts -with-rtsopts=-N -funbox-strict-fields
398375
@@ -406,6 +383,7 @@ Executable idris-codegen-c
406383 , haskeline >= 0.7
407384 , transformers
408385
386+ Default-Language: Haskell2010
409387 ghc-prof-options: -auto-all -caf-all
410388 ghc-options: -threaded -rtsopts -funbox-strict-fields
411389
@@ -419,6 +397,7 @@ Executable idris-codegen-javascript
419397 , haskeline >= 0.7
420398 , transformers
421399
400+ Default-Language: Haskell2010
422401 ghc-prof-options: -auto-all -caf-all
423402 ghc-options: -threaded -rtsopts -funbox-strict-fields
424403
@@ -432,5 +411,6 @@ Executable idris-codegen-node
432411 , haskeline >= 0.7
433412 , transformers
434413
414+ Default-Language: Haskell2010
435415 ghc-prof-options: -auto-all -caf-all
436416 ghc-options: -threaded -rtsopts -funbox-strict-fields
jsrts/Runtime-node.js+1−1
@@ -22,7 +22,7 @@ $JSRTS.prim_readStr = function () {
2222 }
2323 i++;
2424 if (i == b.length) {
25− nb = new Buffer(b.length * 2);
25+ var nb = new Buffer(b.length * 2);
2626 b.copy(nb)
2727 b = nb;
2828 }
libs/base/System.idr+1
@@ -97,5 +97,6 @@ time = do MkRaw t <- foreign FFI_C "idris_time" (IO (Raw Integer))
9797usleep : (i : Int) -> { auto prf : So (i >= 0 && i <= 1000000) } -> IO ()
9898usleep i = foreign FFI_C "usleep" (Int -> IO ()) i
9999
100+||| Execute a program and returns its exit status code.
100101system : String -> IO Int
101102system cmd = foreign FFI_C "system" (String -> IO Int) cmd
libs/contrib/CFFI/Types.idr+5−5
@@ -29,11 +29,11 @@ Show CType where
2929 show PTR = "PTR"
3030
3131Show Composite where
32− show (T ct) = show ct
33− show (ARRAY n t) = "ARRAY " ++ show n ++ " " ++ show t
34− show (STRUCT xs) = "STRUCT " ++ show xs
35− show (UNION xs) = "UNION " ++ show xs
36− show (PACKEDSTRUCT xs) = "PACKEDSTRUCT " ++ show xs
32+ showPrec d (T ct) = showPrec d ct
33+ showPrec d (ARRAY n t) = showCon d "ARRAY" $ showArg n ++ showArg t
34+ showPrec d (STRUCT xs) = showCon d "STRUCT" $ showArg xs
35+ showPrec d (UNION xs) = showCon d "UNION" $ showArg xs
36+ showPrec d (PACKEDSTRUCT xs) = showCon d "PACKEDSTRUCT" $ showArg xs
3737
3838||| What Idris type the C type is marshalled to
3939translate : CType -> Type
libs/contrib/Data/Pairs/Implicit.idrnew file+13
@@ -0,0 +1,13 @@
1+||| Implicit conversions for erased dependent pairs.
2+module Data.Pairs.Implicit
3+
4+%access public export
5+%default total
6+
7+||| Convert an Evidence to its proof.
8+implicit evidence : (x : Exists p) -> p (getWitness x)
9+evidence = getProof
10+
11+||| Convert an Element to its value (a.k.a. witness).
12+implicit element : Subset a p -> a
13+element = getWitness
libs/contrib/Data/Stream/Extra.idrnew file+10
@@ -0,0 +1,10 @@
1+module Data.Stream.Extra
2+
3+%access public export
4+%default total
5+
6+||| Insert elements from a Foldable at the start of an existing Stream
7+||| @ pfx the Foldable containing elements to prepend
8+||| @ stream the Stream to prepend the elements to
9+startWith : Foldable t => (pfx : t a) -> (stream : Stream a) -> Stream a
10+startWith pfx stream = foldr (\x, xs => x :: xs) stream pfx
libs/contrib/Data/ZZ.idr+2−2
@@ -24,8 +24,8 @@ absZ (Pos n) = n
2424absZ (NegS n) = S n
2525
2626implementation Show ZZ where
27− show (Pos n) = show n
28− show (NegS n) = "-" ++ show (S n)
27+ showPrec d (Pos n) = showPrec d n
28+ showPrec d (NegS n) = showParens (d >= PrefixMinus) $ "-" ++ showPrec PrefixMinus (S n)
2929
3030negNat : Nat -> ZZ
3131negNat Z = Pos Z
libs/contrib/Interfaces/Correlative.idrnew file+55
@@ -0,0 +1,55 @@
1+module Interfaces.Correlative
2+
3+import Data.Vect
4+
5+%access public export
6+%default total
7+
8+infixl 2 </>
9+
10+||| A Correlative functor is a functor where, given `(xs, ys : Correlative f)`,
11+||| certain elements from xs and ys can be paired with one another due to some
12+||| intrinsic property of `f`. Elements that cannot be paired are discarded.
13+interface Functor f => Correlative (f : Type -> Type) where
14+ (</>) : f (a -> b) -> f a -> f b
15+
16+||| Combine two containers elementwise using some function.
17+zipWith : Correlative f => (a -> b -> c) -> f a -> f b -> f c
18+zipWith f xs ys = (map f xs) </> ys
19+
20+||| Combine three containers elementwise using some function.
21+zipWith3 : Correlative f => (a -> b -> c -> d) -> f a -> f b -> f c -> f d
22+zipWith3 f xs ys zs = (map f xs) </> ys </> zs
23+
24+||| Combine two containers elementwise into a container of pairs.
25+zip : Correlative f => f a -> f b -> f (a, b)
26+zip = zipWith (\x, y => (x, y))
27+
28+||| Combine three containers elementwise into a container of tuples.
29+zip3 : Correlative f => f a -> f b -> f c -> f (a, b, c)
30+zip3 = zipWith3 (\x, y, z => (x, y, z))
31+
32+||| Convert a container of pairs into a pair of containers.
33+unzip : Functor t => t (a, b) -> (t a, t b)
34+unzip xs = (map fst xs, map snd xs)
35+
36+||| Convert a container of tuples into a tuple of containers.
37+unzip3 : Functor t => t (a, b, c) -> (t a, t b, t c)
38+unzip3 xs = (map fst xs, unzip (map snd xs))
39+
40+Correlative Maybe where
41+ (</>) = (<*>)
42+
43+Correlative (Either a) where
44+ (</>) = (<*>)
45+
46+Correlative List where
47+ (</>) [] _ = []
48+ (</>) _ [] = []
49+ (</>) (f :: fs) (x :: xs) = f x :: (fs </> xs)
50+
51+Correlative Stream where
52+ (</>) = (<*>)
53+
54+Correlative (Vect n) where
55+ (</>) = (<*>)
libs/contrib/Network/Socket.idr+1−5
@@ -8,10 +8,6 @@ import public Network.Socket.Data
88import Network.Socket.Raw
99
1010%include C "idris_net.h"
11−%include C "sys/types.h"
12−%include C "sys/socket.h"
13−%include C "unistd.h"
14−%include C "netdb.h"
1511
1612%access export
1713
@@ -24,7 +20,7 @@ socket : (fam : SocketFamily)
2420 -> (pnum : ProtocolNumber)
2521 -> IO (Either SocketError Socket)
2622socket sf st pn = do
27− socket_res <- foreign FFI_C "socket"
23+ socket_res <- foreign FFI_C "idrnet_socket"
2824 (Int -> Int -> Int -> IO Int)
2925 (toCode sf) (toCode st) pn
3026
libs/contrib/Network/Socket/Raw.idr−3
@@ -8,9 +8,6 @@ module Network.Socket.Raw
88import public Network.Socket.Data
99
1010%include C "idris_net.h"
11−%include C "sys/types.h"
12−%include C "sys/socket.h"
13−%include C "netdb.h"
1411
1512%access public export
1613
libs/contrib/Text/Lexer.idr+161−32
@@ -3,12 +3,13 @@ module Text.Lexer
33%default total
44
55||| A language of token recognisers.
6−||| The `consumes` flag is True is the recogniser is guaranteed to consume
7−||| at least one character
6+||| @ consumes If `True`, this recogniser is guaranteed to consume at
7+||| least one character of input when it succeeds.
88export
99data Recognise : (consumes : Bool) -> Type where
1010 Empty : Recognise False
1111 Fail : Recognise c
12+ Expect : Recognise c -> Recognise False
1213 Pred : (Char -> Bool) -> Recognise True
1314 SeqEat : Recognise True -> Inf (Recognise e) -> Recognise True
1415 SeqEmpty : Recognise e1 -> Recognise e2 -> Recognise (e1 || e2)
@@ -23,11 +24,11 @@ public export
2324inf : Bool -> Type -> Type
2425inf True t = Inf t
2526inf False t = t
26−
27+
2728||| Sequence two recognisers. If either consumes a character, the sequence
2829||| is guaranteed to consume a character.
2930export %inline
30−(<+>) : {c1 : Bool} ->
31+(<+>) : {c1 : Bool} ->
3132 Recognise c1 -> inf c1 (Recognise c2) -> Recognise (c1 || c2)
3233(<+>) {c1 = False} = SeqEmpty
3334(<+>) {c1 = True} = SeqEat
@@ -38,6 +39,22 @@ export
3839(<|>) : Recognise c1 -> Recognise c2 -> Recognise (c1 && c2)
3940(<|>) = Alt
4041
42+||| Positive lookahead. Never consumes input.
43+export
44+expect : Recognise c -> Recognise False
45+expect = Expect
46+
47+||| Negative lookahead. Never consumes input.
48+export
49+reject : Recognise c -> Recognise False
50+reject Empty = Fail
51+reject Fail = Empty
52+reject (Expect x) = reject x
53+reject (Pred f) = Expect (Pred (not . f))
54+reject (SeqEat r1 r2) = reject r1 <|> Expect (SeqEat r1 (reject r2))
55+reject (SeqEmpty r1 r2) = reject r1 <|> Expect (SeqEmpty r1 (reject r2))
56+reject (Alt r1 r2) = reject r1 <+> reject r2
57+
4158||| Recognise a specific character
4259export
4360is : Char -> Lexer
@@ -48,22 +65,46 @@ export
4865isNot : Char -> Lexer
4966isNot x = Pred (/=x)
5067
68+||| Recognise a lexer or recognise no input. This is not guaranteed
69+||| to consume input
70+export
71+opt : Lexer -> Recognise False
72+opt l = l <|> Empty
73+
5174||| Recognise a sequence of at least one sub-lexers
5275export
5376some : Lexer -> Lexer
54−some l = l <+> (some l <|> Empty)
77+some l = l <+> opt (some l)
5578
5679||| Recognise a sequence of at zero or more sub-lexers. This is not
5780||| guaranteed to consume input
5881export
5982many : Lexer -> Recognise False
60−many l = some l <|> Empty
83+many l = opt (some l)
84+
85+||| Recognise the first matching lexer from a non-empty list.
86+export
87+choice : (xs : List Lexer) -> {auto ok : NonEmpty xs} -> Lexer
88+choice (x :: []) = x
89+choice (x :: xs@(_ :: _)) = x <|> choice xs
90+
91+||| Recognise many instances of `l` until an instance of `end` is
92+||| encountered.
93+|||
94+||| Useful for defining comments.
95+export
96+manyTill : (l : Lexer) -> (end : Lexer) -> Recognise False
97+manyTill l end = end <|> opt (l <+> manyTill l end)
6198
6299||| Recognise any character
63100export
64101any : Lexer
65102any = Pred (const True)
66103
104+||| Recognise any character if the sub-lexer `l` fails.
105+non : (l : Lexer) -> Lexer
106+non l = reject l <+> any
107+
67108||| Recognise no input (doesn't consume any input)
68109export
69110empty : Recognise False
@@ -86,7 +127,7 @@ getString : StrLen -> String
86127getString (MkStrLen str n) = str
87128
88129strIndex : StrLen -> Nat -> Maybe Char
89−strIndex (MkStrLen str len) i
130+strIndex (MkStrLen str len) i
90131 = if i >= len then Nothing
91132 else Just (assert_total (prim__strIndex str (cast i)))
92133
@@ -102,70 +143,159 @@ strTail start (MkStrLen str len)
102143scan : Recognise c -> Nat -> StrLen -> Maybe Nat
103144scan Empty idx str = pure idx
104145scan Fail idx str = Nothing
105−scan (Pred f) idx str
146+scan (Expect r) idx str
147+ = case scan r idx str of
148+ Just _ => pure idx
149+ Nothing => Nothing
150+scan (Pred f) idx str
106151 = do c <- strIndex str idx
107152 if f c
108153 then Just (idx + 1)
109154 else Nothing
110−scan (SeqEat r1 r2) idx str
155+scan (SeqEat r1 r2) idx str
111156 = do idx' <- scan r1 idx str
112157 -- TODO: Can we prove totality instead by showing idx has increased?
113158 assert_total (scan r2 idx' str)
114−scan (SeqEmpty r1 r2) idx str
159+scan (SeqEmpty r1 r2) idx str
115160 = do idx' <- scan r1 idx str
116161 scan r2 idx' str
117−scan (Alt r1 r2) idx str
162+scan (Alt r1 r2) idx str
118163 = case scan r1 idx str of
119164 Nothing => scan r2 idx str
120165 Just idx => Just idx
121166
122167takeToken : Lexer -> StrLen -> Maybe (String, StrLen)
123−takeToken lex str
168+takeToken lex str
124169 = do i <- scan lex 0 str -- i must be > 0 if successful
125170 pure (substr 0 i (getString str), strTail i str)
126171
127−||| Recognise a digit 0-9
172+||| Recognise a single digit 0-9
173+export
174+digit : Lexer
175+digit = pred isDigit
176+
177+||| Recognise one or more digits
128178export
129179digits : Lexer
130−digits = some (Pred isDigit)
180+digits = some digit
131181
132182||| Recognise a specific string
133183export
134184exact : String -> Lexer
135185exact str with (unpack str)
136186 exact str | [] = Fail -- Not allowed, Lexer has to consume
137− exact str | (x :: xs)
187+ exact str | (x :: xs)
138188 = foldl SeqEmpty (is x) (map is xs)
139189
140−||| Recognise a whitespace character
190+||| Recognise a single hexidecimal digit
191+export
192+hexDigit : Lexer
193+hexDigit = digit <|> oneOf "abcdefABCDEF"
194+
195+||| Recognise one or more hexidecimal digits
196+export
197+hexDigits : Lexer
198+hexDigits = some hexDigit
199+
200+||| Recognise a single alpha character
201+export
202+alpha : Lexer
203+alpha = pred isAlpha
204+
205+||| Recognise one or more alpha characters
206+export
207+alphas : Lexer
208+alphas = some alpha
209+
210+||| Recognise a lowercase alpha character
211+export
212+lower : Lexer
213+lower = pred isLower
214+
215+||| Recognise one or more lowercase alpha characters
216+export
217+lowers : Lexer
218+lowers = some lower
219+
220+||| Recognise an uppercase alpha character
221+export
222+upper : Lexer
223+upper = pred isUpper
224+
225+||| Recognise one or more uppercase alpha characters
226+export
227+uppers : Lexer
228+uppers = some upper
229+
230+||| Recognise an alphanumeric character
231+export
232+alphaNum : Lexer
233+alphaNum = pred isAlphaNum
234+
235+||| Recognise one or more alphanumeric characters
236+export
237+alphaNums : Lexer
238+alphaNums = some alphaNum
239+
240+||| Recognise a single whitespace character
141241export
142242space : Lexer
143−space = some (pred isSpace)
243+space = pred isSpace
244+
245+||| Recognise one or more whitespace characters
246+export
247+spaces : Lexer
248+spaces = some space
144249
145−||| Recognise a non-alphanumeric, non-whitespace character
250+||| Recognise a single non-whitespace, non-alphanumeric character
146251export
147252symbol : Lexer
148−symbol = some (pred (\x => not (isAlphaNum x) && not (isSpace x)))
253+symbol = pred (\x => not (isSpace x || isAlphaNum x))
254+
255+||| Recognise one or more non-whitespace, non-alphanumeric characters
256+export
257+symbols : Lexer
258+symbols = some symbol
149259
150−strChar : Lexer
151−strChar = (is '\\' <+> any) <|> isNot '"'
260+||| Recognise zero or more occurrences of a sub-lexer between
261+||| delimiting lexers
262+export
263+surround : (start : Lexer) -> (end : Lexer) -> (l : Lexer) -> Lexer
264+surround start end l = start <+> manyTill l end
265+
266+||| Recognise zero or more occurrences of a sub-lexer surrounded
267+||| by the same quote lexer on both sides (useful for strings)
268+export
269+quote : (q : Lexer) -> (l : Lexer) -> Lexer
270+quote q l = surround q q l
271+
272+||| Recognise an escape character (often '\\') followed by a sub-lexer
273+export
274+escape : (esc : Char) -> Lexer -> Lexer
275+escape esc l = is esc <+> l
152276
153277||| Recognise a string literal, including escaped characters.
154278||| (Note: doesn't yet handle escape sequences such as \123)
155279export
156280stringLit : Lexer
157−stringLit = is '"' <+> many strChar <+> is '"'
281+stringLit = quote (is '"') (escape '\\' any <|> any)
158282
159283||| Recognise a character literal, including escaped characters.
160284||| (Note: doesn't yet handle escape sequences such as \123)
161285export
162286charLit : Lexer
163−charLit = is '\'' <+> strChar <+> is '\''
287+charLit = let q = '\'' in
288+ is q <+> (escape '\\' any <|> isNot q) <+> is q
164289
165290||| Recognise an integer literal (possibly with a '-' prefix)
166291export
167292intLit : Lexer
168−intLit = (is '-' <|> Empty) <+> digits
293+intLit = opt (is '-') <+> digits
294+
295+||| Recognise a hexidecimal literal, prefixed by "0x" or "0X"
296+export
297+hexLit : Lexer
298+hexLit = is '0' <+> oneOf "xX" <+> hexDigits
169299
170300||| A mapping from lexers to the tokens they produce.
171301||| This is a list of pairs `(Lexer, String -> tokenType)`
@@ -185,8 +315,8 @@ record TokenData a where
185315
186316fspanEnd : Nat -> (Char -> Bool) -> String -> (Nat, String)
187317fspanEnd k p "" = (k, "")
188−fspanEnd k p xxs
189− = assert_total $
318+fspanEnd k p xxs
319+ = assert_total $
190320 let x = prim__strHead xxs
191321 xs = prim__strTail xxs in
192322 if p x then fspanEnd (S k) p xs
@@ -195,14 +325,14 @@ fspanEnd k p xxs
195325-- Faster version of 'span' from the prelude (avoids unpacking)
196326export
197327fspan : (Char -> Bool) -> String -> (String, String)
198−fspan p xs
328+fspan p xs
199329 = let (end, rest) = fspanEnd 0 p xs in
200330 (substr 0 end xs, rest)
201331
202332tokenise : (line : Int) -> (col : Int) ->
203− List (TokenData a) -> TokenMap a ->
333+ List (TokenData a) -> TokenMap a ->
204334 StrLen -> (List (TokenData a), (Int, Int, StrLen))
205−tokenise line col acc tmap str
335+tokenise line col acc tmap str
206336 = case getFirstToken tmap str of
207337 Just (tok, line', col', rest) =>
208338 -- assert total because getFirstToken must consume something
@@ -213,7 +343,7 @@ tokenise line col acc tmap str
213343 countNLs str = List.length (filter (== '\n') str)
214344
215345 getCols : String -> Int -> Int
216− getCols x c
346+ getCols x c
217347 = case fspan (/= '\n') (reverse x) of
218348 (incol, "") => c + cast (length incol)
219349 (incol, _) => cast (length incol)
@@ -223,7 +353,7 @@ tokenise line col acc tmap str
223353 getFirstToken ((lex, fn) :: ts) str
224354 = case takeToken lex str of
225355 Just (tok, rest) => Just (MkToken line col (fn tok),
226− line + cast (countNLs (unpack tok)),
356+ line + cast (countNLs (unpack tok)),
227357 getCols tok col, rest)
228358 Nothing => getFirstToken ts str
229359
@@ -235,4 +365,3 @@ export
235365lex : TokenMap a -> String -> (List (TokenData a), (Int, Int, String))
236366lex tmap str = let (ts, (l, c, str')) = tokenise 0 0 [] tmap (mkStr str) in
237367 (ts, (l, c, getString str'))
238−
libs/contrib/Text/Literate.idrnew file+155
@@ -0,0 +1,155 @@
1+||| A simple module to process 'literate' documents.
2+|||
3+||| The module uses a lexer to split the document into code blocks,
4+||| delineated by user-defined markers, and code lines that are
5+||| indicated be a line marker. The lexer returns a document stripped
6+||| of non-code elements but preserving the original document's line
7+||| count. Column numbering of code lines are not preserved.
8+|||
9+||| The underlying tokeniser is greedy.
10+|||
11+||| Once it identifies a line marker it reads a prettifying space then
12+||| consumes until the end of line. Once identifies a starting code
13+||| block marker, the lexer will consume input until the next
14+||| identifiable end block is encountered. Any other content is
15+||| treated as part of the original document.
16+|||
17+||| Thus, the input literate files *must* be well-formed w.r.t
18+||| to code line markers and code blocks.
19+|||
20+||| A further restriction is that literate documents cannot contain
21+||| the markers within the document's main text: This will confuse the
22+||| lexer.
23+|||
24+module Text.Literate
25+
26+import Text.Lexer
27+
28+import Data.List.Views
29+
30+%default total
31+
32+untilEOL : Recognise False
33+untilEOL = manyTill any (is '\n')
34+
35+line : String -> Lexer
36+line s = exact s <+> space <+> untilEOL
37+
38+block : String -> String -> Lexer
39+block s e = exact s <+> manyTill any (exact e)
40+
41+data Token = CodeBlock String String String
42+ | Any String
43+ | CodeLine String String
44+
45+Show Token where
46+ showPrec d (CodeBlock l r x) = showCon d "CodeBlock" $ showArg l ++ showArg r ++ showArg x
47+ showPrec d (Any x) = showCon d "Any" $ showArg x
48+ showPrec d (CodeLine m x) = showCon d "CodeLine" $ showArg m ++ showArg x
49+
50+rawTokens : (delims : List (String, String))
51+ -> (markers : List String)
52+ -> TokenMap (Token)
53+rawTokens delims ls =
54+ map (\(l,r) => (block l r, CodeBlock l r)) delims
55+ ++ map (\m => (line m, CodeLine m)) ls
56+ ++ [(any, Any)]
57+
58+||| Merge the tokens into a single source file.
59+reduce : List (TokenData Token) -> String -> String
60+reduce [] acc = acc
61+reduce (MkToken _ _ (Any x) :: rest) acc = reduce rest (acc ++ blank_content)
62+ where
63+ -- Preserve the original document's line count.
64+ blank_content : String
65+ blank_content = if elem '\n' (unpack x)
66+ then concat $ replicate (length (lines x)) "\n"
67+ else ""
68+reduce (MkToken _ _ (CodeLine m src) :: rest) acc =
69+ reduce rest (acc ++ (substr
70+ (length m + 1) -- remove space to right of marker.
71+ (length src)
72+ src))
73+
74+reduce (MkToken _ _ (CodeBlock l r src) :: rest) acc with (lines src) -- Strip the deliminators surrounding the block.
75+ reduce (MkToken _ _ (CodeBlock l r src) :: rest) acc | [] = reduce rest acc -- 1
76+ reduce (MkToken _ _ (CodeBlock l r src) :: rest) acc | (s :: ys) with (snocList ys)
77+ reduce (MkToken _ _ (CodeBlock l r src) :: rest) acc | (s :: []) | Empty = reduce rest acc -- 2
78+ reduce (MkToken _ _ (CodeBlock l r src) :: rest) acc | (s :: (srcs ++ [f])) | (Snoc rec) =
79+ reduce rest (acc ++ "\n" ++ unlines srcs ++ "\n")
80+
81+-- [ NOTE ] 1 & 2 shouldn't happen as code blocks are well formed i.e. have two deliminators.
82+
83+
84+public export
85+record LiterateError where
86+ constructor MkLitErr
87+ line : Int
88+ column : Int
89+ input : String
90+
91+||| Description of literate styles.
92+|||
93+||| A 'literate' style comprises of
94+|||
95+||| + a list of code block deliminators (`deliminators`);
96+||| + a list of code line markers (`line_markers`); and
97+||| + a list of known file extensions `file_extensions`.
98+|||
99+||| Some example specifications:
100+|||
101+||| + Bird Style
102+|||
103+|||```
104+|||MkLitStyle Nil [">", "<"] Nil
105+|||```
106+|||
107+||| + Literate Haskell (for LaTeX)
108+|||
109+|||```
110+|||MkLitStyle [("\\begin{code}", "\\end{code}"),("\\begin{spec}","\\end{spec}")]
111+||| Nil
112+||| ["lhs", "tex"]
113+|||```
114+|||
115+||| + OrgMode
116+|||
117+|||```
118+|||MkLitStyle [("#+BEGIN_SRC idris","#+END_SRC"), ("#+COMMENT idris","#+END_COMMENT")]
119+||| ["#+IDRIS:"]
120+||| ["org"]
121+|||```
122+|||
123+public export
124+record LiterateStyle where
125+ constructor MkLitStyle
126+ ||| The pairs of start and end tags for code blocks.
127+ deliminators : List (String, String)
128+
129+ ||| Line markers that indicate a line contains code.
130+ line_markers : List String
131+
132+ ||| Recognised file extensions. Not used by the module, but will be
133+ ||| of use when connecting to code that reads in the original source
134+ ||| files.
135+ file_extensions : List String
136+
137+||| Given a 'literate specification' extract the code from the
138+||| literate source file (`litStr`) that follows the presented style.
139+|||
140+||| @specification The literate specification to use.
141+||| @litStr The literate source file.
142+|||
143+||| Returns a `LiterateError` if the literate file contains malformed
144+||| code blocks or code lines.
145+|||
146+export
147+extractCode : (specification : LiterateStyle)
148+ -> (litStr : String)
149+ -> Either LiterateError String
150+extractCode (MkLitStyle delims markers exts) str =
151+ case lex (rawTokens delims markers) str of
152+ (toks, (_,_,"")) => Right $ reduce toks ""
153+ (_, (l,c,i)) => Left (MkLitErr l c i)
154+
155+-- --------------------------------------------------------------------- [ EOF ]
libs/contrib/Text/Parser.idr+67−26
@@ -3,7 +3,7 @@ module Text.Parser
33%default total
44
55-- TODO: Add some primitives for helping with error messages.
6−-- e.g. perhaps set a string to state what we're currently trying to
6+-- e.g. perhaps set a string to state what we're currently trying to
77-- parse, or to say what the next expected token is in words
88
99||| Description of a language's grammar. The `tok` parameter is the type
@@ -26,14 +26,14 @@ data Grammar : (tok : Type) -> (consumes : Bool) -> Type -> Type where
2626 Grammar tok c1 a -> (a -> Grammar tok c2 b) ->
2727 Grammar tok (c1 || c2) b
2828 Alt : {c1, c2 : Bool} ->
29− Grammar tok c1 ty -> Grammar tok c2 ty ->
29+ Grammar tok c1 ty -> Grammar tok c2 ty ->
3030 Grammar tok (c1 && c2) ty
3131
3232public export
3333inf : Bool -> Type -> Type
3434inf True t = Inf t
3535inf False t = t
36−
36+
3737||| Sequence two grammars. If either consumes some input, the sequence is
3838||| guaranteed to consume some input. If the first one consumes input, the
3939||| second is allowed to be recursive (because it means some input has been
@@ -44,11 +44,11 @@ export %inline
4444 Grammar tok (c1 || c2) b
4545(>>=) {c1 = False} = SeqEmpty
4646(>>=) {c1 = True} = SeqEat
47−
47+
4848||| Give two alternative grammars. If both consume, the combination is
4949||| guaranteed to consume.
5050export
51−(<|>) : Grammar tok c1 ty -> Grammar tok c2 ty ->
51+(<|>) : Grammar tok c1 ty -> Grammar tok c2 ty ->
5252 Grammar tok (c1 && c2) ty
5353(<|>) = Alt
5454
@@ -82,21 +82,21 @@ export
8282eof : Grammar tok False ()
8383eof = EOF
8484
85−||| Commit to an alternative; if the current branch of an alternative
85+||| Commit to an alternative; if the current branch of an alternative
8686||| fails to parse, no more branches will be tried
8787export
8888commit : Grammar tok False ()
8989commit = Commit
9090
9191data ParseResult : List tok -> (consumes : Bool) -> Type -> Type where
92− Failure : {xs : List tok} ->
92+ Failure : {xs : List tok} ->
9393 (committed : Bool) ->
9494 (err : String) -> (rest : List tok) -> ParseResult xs c ty
9595 EmptyRes : (committed : Bool) ->
9696 (val : ty) -> (more : List tok) -> ParseResult more False ty
9797 NonEmptyRes : (committed : Bool) ->
9898 (val : ty) -> (more : List tok) ->
99− ParseResult (x :: xs ++ more) c ty
99+ ParseResult (x :: xs ++ more) c ty
100100
101101weakenRes : {whatever, c : Bool} -> {xs : List tok} ->
102102 ParseResult xs c ty -> ParseResult xs (whatever && c) ty
@@ -105,13 +105,13 @@ weakenRes {whatever=True} (EmptyRes com val xs) = EmptyRes com val xs
105105weakenRes {whatever=False} (EmptyRes com val xs) = EmptyRes com val xs
106106weakenRes (NonEmptyRes com val more) = NonEmptyRes com val more
107107
108−shorter : (more : List tok) -> .(ys : List tok) ->
108+shorter : (more : List tok) -> .(ys : List tok) ->
109109 LTE (S (length more)) (S (length (ys ++ more)))
110110shorter more [] = lteRefl
111111shorter more (x :: xs) = LTESucc (lteSuccLeft (shorter more xs))
112112
113113doParse : {c : Bool} ->
114− (commit : Bool) -> (xs : List tok) -> (act : Grammar tok c ty) ->
114+ (commit : Bool) -> (xs : List tok) -> (act : Grammar tok c ty) ->
115115 ParseResult xs c ty
116116doParse com xs act with (sizeAccessible xs)
117117 doParse com xs (Empty val) | sml = EmptyRes com val xs
@@ -120,17 +120,17 @@ doParse com xs act with (sizeAccessible xs)
120120 doParse com xs Commit | sml = EmptyRes True () xs
121121
122122 doParse com [] (Terminal f) | sml = Failure com "End of input" []
123− doParse com (x :: xs) (Terminal f) | sml
123+ doParse com (x :: xs) (Terminal f) | sml
124124 = maybe
125125 (Failure com "Unrecognised token" (x :: xs))
126126 (\a => NonEmptyRes com {xs=[]} a xs)
127127 (f x)
128128 doParse com [] EOF | sml = EmptyRes com () []
129− doParse com (x :: xs) EOF | sml
129+ doParse com (x :: xs) EOF | sml
130130 = Failure com "Expected end of input" (x :: xs)
131131 doParse com [] (NextIs f) | sml = Failure com "End of input" []
132− doParse com (x :: xs) (NextIs f) | sml
133− = if f x
132+ doParse com (x :: xs) (NextIs f) | sml
133+ = if f x
134134 then EmptyRes com x (x :: xs)
135135 else Failure com "Unrecognised token" (x :: xs)
136136 doParse com xs (Alt x y) | sml with (doParse False xs x | sml)
@@ -140,19 +140,19 @@ doParse com xs act with (sizeAccessible xs)
140140 then Failure com msg ts
141141 else weakenRes (doParse False xs y | sml)
142142 -- Successfully parsed the first option, so use the outer commit flag
143− doParse com xs (Alt x y) | sml | (EmptyRes _ val xs)
143+ doParse com xs (Alt x y) | sml | (EmptyRes _ val xs)
144144 = EmptyRes com val xs
145− doParse com (z :: (ys ++ more)) (Alt x y) | sml | (NonEmptyRes _ val more)
145+ doParse com (z :: (ys ++ more)) (Alt x y) | sml | (NonEmptyRes _ val more)
146146 = NonEmptyRes com val more
147147 doParse com xs (SeqEmpty act next) | (Access morerec)
148148 = case doParse com xs act | Access morerec of
149149 Failure com msg ts => Failure com msg ts
150− EmptyRes com val xs =>
150+ EmptyRes com val xs =>
151151 case doParse com xs (next val) | (Access morerec) of
152152 Failure com' msg ts => Failure com' msg ts
153153 EmptyRes com' val xs => EmptyRes com' val xs
154154 NonEmptyRes com' val more => NonEmptyRes com' val more
155− NonEmptyRes {x} {xs=ys} com val more =>
155+ NonEmptyRes {x} {xs=ys} com val more =>
156156 case (doParse com more (next val) | morerec _ (shorter more ys)) of
157157 Failure com' msg ts => Failure com' msg ts
158158 EmptyRes com' val _ => NonEmptyRes com' val more
@@ -160,13 +160,13 @@ doParse com xs act with (sizeAccessible xs)
160160 rewrite appendAssociative (x :: ys) (x1 :: xs1) more' in
161161 NonEmptyRes com' val more'
162162 doParse com xs (SeqEat act next) | sml with (doParse com xs act | sml)
163− doParse com xs (SeqEat act next) | sml | Failure com' msg ts
163+ doParse com xs (SeqEat act next) | sml | Failure com' msg ts
164164 = Failure com' msg ts
165− doParse com (x :: (ys ++ more)) (SeqEat act next) | (Access morerec) | (NonEmptyRes com' val more)
165+ doParse com (x :: (ys ++ more)) (SeqEat act next) | (Access morerec) | (NonEmptyRes com' val more)
166166 = case doParse com' more (next val) | morerec _ (shorter more ys) of
167167 Failure com' msg ts => Failure com' msg ts
168168 EmptyRes com' val _ => NonEmptyRes com' val more
169− NonEmptyRes {x=x1} {xs=xs1} com' val more' =>
169+ NonEmptyRes {x=x1} {xs=xs1} com' val more' =>
170170 rewrite appendAssociative (x :: ys) (x1 :: xs1) more' in
171171 NonEmptyRes com' val more'
172172 -- This next line is not strictly necessary, but it stops the coverage
@@ -180,7 +180,7 @@ data ParseError tok = Error String (List tok)
180180||| returns a pair of the parse result and the unparsed tokens (the remaining
181181||| input).
182182export
183−parse : (xs : List tok) -> (act : Grammar tok c ty) ->
183+parse : (xs : List tok) -> (act : Grammar tok c ty) ->
184184 Either (ParseError tok) (ty, List tok)
185185parse xs act
186186 = case doParse False xs act of
@@ -190,7 +190,7 @@ parse xs act
190190
191191||| Parse one or more things
192192export
193−some : Grammar tok True a ->
193+some : Grammar tok True a ->
194194 Grammar tok True (List a)
195195some p = do x <- p
196196 (do xs <- some p
@@ -198,14 +198,14 @@ some p = do x <- p
198198
199199||| Parse zero or more things (may match the empty input)
200200export
201−many : Grammar tok True a ->
201+many : Grammar tok True a ->
202202 Grammar tok False (List a)
203203many p = some p
204204 <|> pure []
205205
206206||| Parse one or more things, separated by another thing
207207export
208−sepBy1 : Grammar tok True () -> Grammar tok True a ->
208+sepBy1 : Grammar tok True () -> Grammar tok True a ->
209209 Grammar tok True (List a)
210210sepBy1 sep p = do x <- p
211211 (do sep
@@ -215,7 +215,7 @@ sepBy1 sep p = do x <- p
215215||| Parse zero or more things, separated by another thing. May
216216||| match the empty input.
217217export
218−sepBy : Grammar tok True () -> Grammar tok True a ->
218+sepBy : Grammar tok True () -> Grammar tok True a ->
219219 Grammar tok False (List a)
220220sepBy sep p = sepBy1 sep p <|> pure []
221221
@@ -227,3 +227,44 @@ optional : Grammar tok True a -> (ifNothing : a) ->
227227optional p def = p <|> pure def
228228
229229
230+||| Parse an instance of `p` that is between `left` and `right`.
231+export
232+between : (left : Grammar tok True ())
233+ -> (right : Grammar tok True ())
234+ -> (p : Grammar tok True a)
235+ -> Grammar tok True a
236+between left right contents = do
237+ left
238+ res <- contents
239+ right
240+ pure res
241+
242+||| Parse one or more instances of `p` separated by `s`, returning the
243+||| parsed items and proof the resulting list is non-empty.
244+export
245+sepBy1' : (sep : Grammar tok True ())
246+ -> (p : Grammar tok True a)
247+ -> Grammar tok True (xs : List a ** NonEmpty xs)
248+sepBy1' sep p
249+ = do x <- p
250+ (do sep
251+ xs <- sepBy1 sep p
252+ pure (x :: xs ** IsNonEmpty)) <|> pure ([x] ** IsNonEmpty)
253+
254+||| Parse one or more instances of `p`, returning the parsed items and proof the resulting list is non-empty.
255+export
256+some' : (p : Grammar tok True a)
257+ -> Grammar tok True (xs : List a ** NonEmpty xs)
258+some' p = do
259+ x <- p
260+ (do xs <- some p
261+ pure (x::xs ** IsNonEmpty)) <|> pure ([x] ** IsNonEmpty)
262+
263+
264+||| Optionally parse a thing. If the grammar provides a default use `optional` instead.
265+export
266+maybe : Grammar tok True a
267+ -> Grammar tok False (Maybe a)
268+maybe p =
269+ (do res <- p; pure $ Just res)
270+ <|> pure Nothing
libs/contrib/Text/PrettyPrint/WL.idrnew file+18
@@ -0,0 +1,18 @@
1+||| A revised Idris port of the Wadler-Leijen pretty-printer.
2+|||
3+||| This port of the Wadler-Leijen Pretty-Printer is based upon the
4+||| port originally created by Shayan Najd [1]. We have changed the
5+||| render function to be total using a technique based on
6+||| continuations proposed by gallais [2], and fix minor errors in the
7+||| original Idris port.
8+|||
9+||| [1] https://github.com/shayan-najd/wl-pprint
10+||| [2] https://gallais.github.io/blog/termination-tricks.html
11+module Text.PrettyPrint.WL
12+
13+import public Text.PrettyPrint.WL.Core
14+import public Text.PrettyPrint.WL.Characters
15+import public Text.PrettyPrint.WL.Combinators
16+
17+%default total
18+%access export
libs/contrib/Text/PrettyPrint/WL/Characters.idrnew file+103
@@ -0,0 +1,103 @@
1+||| Commonly used characters
2+module Text.PrettyPrint.WL.Characters
3+
4+import Text.PrettyPrint.WL.Core
5+
6+%default total
7+%access export
8+
9+lparen : Doc
10+lparen = char '('
11+
12+rparen : Doc
13+rparen = char ')'
14+
15+langle : Doc
16+langle = char '<'
17+
18+rangle : Doc
19+rangle = char '>'
20+
21+lbrace : Doc
22+lbrace = char '{'
23+
24+rbrace : Doc
25+rbrace = char '}'
26+
27+lbracket : Doc
28+lbracket = char '['
29+
30+rbracket : Doc
31+rbracket = char ']'
32+
33+squote : Doc
34+squote = char '\''
35+
36+dquote : Doc
37+dquote = char '"'
38+
39+semi : Doc
40+semi = char ';'
41+
42+colon : Doc
43+colon = char ':'
44+
45+comma : Doc
46+comma = char ','
47+
48+space : Doc
49+space = char ' '
50+
51+dot : Doc
52+dot = char '.'
53+
54+backslash : Doc
55+backslash = char '\\'
56+
57+forwardslash : Doc
58+forwardslash = char '/'
59+
60+equals : Doc
61+equals = char '='
62+
63+pipe : Doc
64+pipe = char '|'
65+
66+bang : Doc
67+bang = char '!'
68+
69+tick : Doc
70+tick = char '`'
71+
72+tilde : Doc
73+tilde = char '~'
74+
75+hash : Doc
76+hash = char '#'
77+
78+asterix : Doc
79+asterix = char '*'
80+
81+ampersand : Doc
82+ampersand = char '&'
83+
84+dash : Doc
85+dash = char '-'
86+
87+question : Doc
88+question = char '?'
89+
90+dollar : Doc
91+dollar = char '$'
92+
93+pound : Doc
94+pound = char '£'
95+
96+euro : Doc
97+euro = char '€'
98+
99+caret : Doc
100+caret = char '^'
101+
102+percent : Doc
103+percent = char '%'
libs/contrib/Text/PrettyPrint/WL/Combinators.idrnew file+259
@@ -0,0 +1,259 @@
1+||| Common combinators.
2+module Text.PrettyPrint.WL.Combinators
3+
4+import Text.PrettyPrint.WL.Core
5+import Text.PrettyPrint.WL.Characters
6+
7+%default total
8+%access export
9+
10+-- --------------------------------------------------- [ Alignment Combinators ]
11+
12+||| The document `(align x)` renders document `x` with the nesting
13+||| level set to the current column. It is used for example to
14+||| implement 'hang'.
15+align : Doc -> Doc
16+align d = column (\k => nesting (\i => nest (k - i) d))
17+
18+||| The hang combinator implements hanging indentation. The document
19+||| `(hang i x)` renders document `x` with a nesting level set to the
20+||| current column plus `i`.
21+hang : Int -> Doc -> Doc
22+hang i d = align (nest i d)
23+
24+||| The document `(indent i x)` indents document `x` with `i` spaces.
25+indent : Int -> Doc -> Doc
26+indent i d = hang i (text (spaces i) <+> d)
27+
28+-- -------------------------------------------------- [ High-Level Combinators ]
29+
30+||| The document `softLine` behaves like `space` if the resulting
31+||| output fits the page, otherwise it behaves like `line`.
32+softLine : Doc
33+softLine = group line
34+
35+||| The document `softbreak` behaves like `empty` if the resulting
36+||| output fits the page, otherwise it behaves like 'line'.
37+softBreak : Doc
38+softBreak = group breakLine
39+
40+infixr 5 |/|, |//|, |$|, |$$|
41+infixr 6 |+|, |++|
42+
43+private
44+concatDoc : Doc -> Doc -> Doc -> Doc
45+concatDoc sep x y = x `beside` (sep `beside` y)
46+
47+||| The document `(x |+| y)` concatenates document `x` and document
48+||| `y`. It is an associative operation having 'empty' as a left and
49+||| right unit.
50+(|+|) : Doc -> Doc -> Doc
51+(|+|) = (<+>)
52+
53+||| The document `(x |++| y)` concatenates document `x` and `y` with a
54+||| `space` in between.
55+(|++|) : Doc -> Doc -> Doc
56+(|++|) = concatDoc space
57+
58+||| The document `(x |/| y)` concatenates document `x` and `y` with a
59+||| 'softline' in between. This effectively puts `x` and `y` either
60+||| next to each other (with a `space` in between) or underneath each
61+||| other.
62+(|/|) : Doc -> Doc -> Doc
63+(|/|) = concatDoc softLine
64+
65+||| The document `(x |//| y)` concatenates document `x` and `y` with
66+||| a 'softbreak' in between. This effectively puts `x` and `y` either
67+||| right next to each other or underneath each other.
68+(|//|) : Doc -> Doc -> Doc
69+(|//|) = concatDoc softBreak
70+
71+||| The document `(x |$| y)` concatenates document `x` and `y` with a
72+||| `line` in between.
73+(|$|) : Doc -> Doc -> Doc
74+(|$|) = concatDoc line
75+
76+||| The document `(x |$$| y)` concatenates document `x` and `y` with
77+||| a `linebreak` in between.
78+(|$$|) : Doc -> Doc -> Doc
79+(|$$|) = concatDoc breakLine
80+
81+||| The document `(vsep xs)` concatenates all documents `xs`
82+||| vertically with `(|$|)`. If a 'group' undoes the line breaks
83+||| inserted by `vsep`, all documents are separated with a space.
84+vsep : List Doc -> Doc
85+vsep = fold (|$|)
86+
87+||| The document `(sep xs)` concatenates all documents `xs` either
88+||| horizontally with `(|++|)`, if it fits the page, or vertically with
89+||| `(|$|)`.
90+sep : List Doc -> Doc
91+sep = group . vsep
92+
93+
94+||| The document `(fillSep xs)` concatenates documents `xs`
95+||| horizontally with `(|++|)` as long as its fits the page, than
96+||| inserts a `line` and continues doing that for all documents in
97+||| `xs`.
98+fillSep : List Doc -> Doc
99+fillSep = fold (|/|)
100+
101+||| The document `(hsep xs)` concatenates all documents `xs`
102+||| horizontally with `(|++|)`.
103+hsep : List Doc -> Doc
104+hsep = fold (|++|)
105+
106+||| The document `(hcat xs)` concatenates all documents `xs`
107+||| horizontally with `(|+|)`.
108+hcat : List Doc -> Doc
109+hcat = fold (<+>)
110+
111+||| The document `(vcat xs)` concatenates all documents `xs`
112+||| vertically with `(|$$|)`. If a `group` undoes the line breaks
113+||| inserted by `vcat`, all documents are directly concatenated.
114+vcat : List Doc -> Doc
115+vcat = fold (|$$|)
116+
117+||| The document `(cat xs)` concatenates all documents `xs` either
118+||| horizontally with `(|+|)`, if it fits the page, or vertically with
119+||| `(|$$|)`.
120+cat : List Doc -> Doc
121+cat = group . vcat
122+
123+||| The document `(fillCat xs)` concatenates documents `xs`
124+||| horizontally with `(|+|)` as long as its fits the page, than inserts
125+||| a `linebreak` and continues doing that for all documents in `xs`.
126+fillCat : List Doc -> Doc
127+fillCat = fold (|//|)
128+
129+||| The document `(enclose l r x)` encloses document `x` between
130+||| documents `l` and `r` using `(|+|)`.
131+enclose : Doc -> Doc -> Doc -> Doc
132+enclose l r x = concatDoc x l r
133+
134+squotes : Doc -> Doc
135+squotes = enclose squote squote
136+
137+dquotes : Doc -> Doc
138+dquotes = enclose dquote dquote
139+
140+braces : Doc -> Doc
141+braces = enclose lbrace rbrace
142+
143+parens : Doc -> Doc
144+parens = enclose lparen rparen
145+
146+angles : Doc -> Doc
147+angles = enclose langle rangle
148+
149+brackets : Doc -> Doc
150+brackets = enclose lbracket rbracket
151+
152+-- ----------------------------------------------------- [ Lists, Sets, Tuples ]
153+
154+||| The document `(encloseSep l r sep xs)` concatenates the documents
155+||| `xs` separated by `sep` and encloses the resulting document by `l`
156+||| and `r`. The documents are rendered horizontally if that fits the
157+||| page. Otherwise they are aligned vertically. All separators are put
158+||| in front of the elements.
159+encloseSep : (l : Doc)
160+ -> (r : Doc)
161+ -> (sep : Doc)
162+ -> (xs : List Doc)
163+ -> Doc
164+encloseSep l r s [] = l <+> r
165+encloseSep l r s [x] = l <+> x <+> r
166+encloseSep l r s xs = align (cat (zipWith (<+>) (l :: replicate (length xs) s) xs) <+> r)
167+
168+||| The document `(list xs)` comma separates the documents `xs` and
169+||| encloses them in square brackets. The documents are rendered
170+||| horizontally if that fits the page. Otherwise they are aligned
171+||| vertically. All comma separators are put in front of the
172+||| elements.
173+list : List Doc -> Doc
174+list = encloseSep lbracket rbracket comma
175+
176+||| The document `(tupled xs)` comma separates the documents `xs`
177+||| and encloses them in parenthesis. The documents are rendered
178+||| horizontally if that fits the page. Otherwise they are aligned
179+||| vertically. All comma separators are put in front of the
180+||| elements.
181+tupled : List Doc -> Doc
182+tupled = encloseSep lparen rparen comma
183+
184+||| The document `(set xs)` separates the documents `xs` with
185+||| commas and encloses them in braces. The documents are
186+||| rendered horizontally if that fits the page. Otherwise they are
187+||| aligned vertically. All comma's are put in front of the
188+||| elements.
189+set : List Doc -> Doc
190+set = encloseSep lbrace rbrace comma
191+
192+||| The document `(semiBraces xs)` separates the documents `xs` with
193+||| semi-colon and encloses them in braces. The documents are
194+||| rendered horizontally if that fits the page. Otherwise they are
195+||| aligned vertically. All semi-colons's are put in front of the
196+||| elements.
197+semiBrace : List Doc -> Doc
198+semiBrace = encloseSep lbrace rbrace semi
199+
200+||| `(punctuate p xs)` concatenates all documents in `xs` with
201+||| document `p` except for the last document.
202+punctuate : Doc -> List Doc -> List Doc
203+punctuate p [] = []
204+punctuate p [x] = [x]
205+punctuate p (x :: xs) = (x <+> p) :: punctuate p xs
206+
207+-- ------------------------------------------------------------------- [ Fills ]
208+
209+width : Doc -> (Int -> Doc) -> Doc
210+width doc f = column (\k => doc <+> column (\k' => f (k' - k)))
211+
212+||| The document `(fillBreak i x)` first renders document `x`. It
213+||| than appends `space`s until the width is equal to `i`. If the
214+||| width of `x` is already larger than `i`, the nesting level is
215+||| increased by `i` and a `line` is appended.
216+fillBreak : (i : Int) -> (x : Doc) -> Doc
217+fillBreak f x =
218+ width x (\w => if (w > f)
219+ then nest f breakLine
220+ else text (spaces (f - w)))
221+
222+||| The document `(fill i x)` renders document `x`. It than appends
223+||| `space`s until the width is equal to `i`. If the width of `x` is
224+||| already larger, nothing is appended. This combinator is quite
225+||| useful in practice to output a list of bindings.
226+fill : (i : Int) -> (x : Doc) -> Doc
227+fill f d =
228+ width d (\w => if (w >= f)
229+ then empty
230+ else text (spaces (f - w)))
231+
232+-- -------------------------------------------------------------- [ Primatives ]
233+
234+||| The document `(literal s)` concatenates all characters in `s`
235+||| using `line` for newline characters and `char` for all other
236+||| characters. It is used instead of 'text' whenever the text contains
237+||| newline characters.
238+literal : (str : String) -> Doc
239+literal str = mkLiteral (unpack str)
240+ where
241+ mkLiteral : List Char -> Doc
242+ mkLiteral Nil = empty
243+ mkLiteral ('\n':: ss) = line <+> mkLiteral ss
244+ mkLiteral (c :: ss) = char c <+> mkLiteral ss
245+
246+bool : Bool -> Doc
247+bool b = text (show b)
248+
249+nat : Nat -> Doc
250+nat n = text (show n)
251+
252+int : Int -> Doc
253+int i = text (show i)
254+
255+integer : Integer -> Doc
256+integer i = text (show i)
257+
258+double : Double -> Doc
259+double d = text (show d)
libs/contrib/Text/PrettyPrint/WL/Core.idrnew file+225
@@ -0,0 +1,225 @@
1+||| Core definitions and primitives.
2+module Text.PrettyPrint.WL.Core
3+
4+%default total
5+%access export
6+
7+-- -------------------------------------------------------------------- [ Core ]
8+
9+||| The abstract data type `Doc` represents pretty documents.
10+|||
11+data Doc : Type where
12+ Empty : Doc
13+ Chara : (c : Char) -> Doc
14+ Text : (len : Int) -> (str : String) -> Doc
15+ Line : (undone : Bool) -> Doc
16+
17+ Cat : (x : Doc) -> (y : Doc) -> Doc
18+ Nest : (lvl : Int) -> (x : Doc) -> Doc
19+ Union : (x : Doc) -> (y : Doc) -> Doc
20+
21+ Column : (f : Int -> Doc) -> Doc
22+ Nesting : (f : Int -> Doc) -> Doc
23+
24+-- -------------------------------------------------------------- [ Primitives ]
25+
26+||| The empty document is, indeed, empty.
27+empty : Doc
28+empty = Empty
29+
30+||| The `line` document advances to the next line and indents to the
31+||| current nesting level. Document `line` behaves like `(text " ")`
32+||| if the line break is undone by 'group'.
33+line : Doc
34+line = Line False
35+
36+||| The document `(char c)` contains the literal character `c`. If the
37+||| character is a newline (`'\n'`) the function returns a line
38+||| document. Ideally, the function 'line' should be used for line
39+||| breaks.
40+char : (c : Char) -> Doc
41+char '\n' = line
42+char c = Chara c
43+
44+||| The document `(text s)` contains the literal string `s`. The
45+||| string shouldn't contain any newline (`'\n'`) characters. If the
46+||| string contains newline characters, the function 'literal' should be
47+||| used.
48+text : (str : String) -> Doc
49+text "" = empty
50+text str = Text (cast $ length str) str
51+
52+||| The `breakLine` document advances to the next line and indents to
53+||| the current nesting level. Document `breakLine` behaves like
54+||| 'empty' if the line break is undone by 'group'.
55+breakLine : Doc
56+breakLine = Line True
57+
58+||| Horizontal concatenation of documents
59+beside : Doc -> Doc -> Doc
60+beside = Cat
61+
62+||| The document `(nest lvl x)` renders document `x` with the current
63+||| indentation level increased by lvl.
64+nest : (lvl : Int)
65+ -> (x : Doc)
66+ -> Doc
67+nest = Nest
68+
69+column : (f : Int -> Doc) -> Doc
70+column = Column
71+
72+nesting : (f : Int -> Doc) -> Doc
73+nesting = Nesting
74+
75+private %inline
76+flatten : Doc -> Doc
77+flatten (Line break) = if break then Empty else Text 1 " "
78+
79+flatten (Cat x y) = Cat (flatten x) (flatten y)
80+flatten (Nest lvl x) = Nest lvl (flatten x)
81+flatten (Union x _) = flatten x
82+flatten (Column f) = Column (\i => flatten $ f i)
83+flatten (Nesting f) = Nesting (\i => flatten $ f i)
84+
85+flatten other = other
86+
87+||| The `group` combinator is used to specify alternative
88+||| layouts. The document `(group x)` undoes all line breaks in
89+||| document `x`. The resulting line is added to the current line if
90+||| that fits the page. Otherwise, the document `x` is rendered without
91+||| any changes.
92+group : Doc -> Doc
93+group x = Union (flatten x) x
94+
95+Semigroup Doc where
96+ (<+>) x y = beside x y
97+
98+Monoid Doc where
99+ neutral = empty
100+
101+fold : (f : Doc -> Doc -> Doc) -> (ds : List Doc) -> Doc
102+fold _ Nil = empty
103+fold f (x::xs) = foldl f x xs
104+
105+-- --------------------------------------------------------------- [ Renderers ]
106+
107+namespace PrettyDoc
108+
109+ ||| The data type `PrettyDoc` represents rendered documents and is
110+ ||| used by the display functions.
111+ data PrettyDoc : Type where
112+ Empty : PrettyDoc
113+ Chara : (c : Char) -> (rest : PrettyDoc) -> PrettyDoc
114+ Text : (len : Int) -> (str : String) -> (rest : PrettyDoc) -> PrettyDoc
115+ Line : (lvl : Int) -> (rest : PrettyDoc) -> PrettyDoc
116+
117+||| Helper function to construct spaces.
118+spaces : (n : Int) -> String
119+spaces n = if n <= 0 then "" else pack $ replicate (cast n) ' '
120+
121+private
122+indentation : Int -> String
123+indentation n = spaces n
124+
125+||| `(showPrettyDoc doc)` takes the output `PrettyDoc` from a
126+||| rendering function and transforms it to a String for printing.
127+showPrettyDoc : (doc : PrettyDoc) -> String
128+showPrettyDoc doc = showPrettyDocS doc ""
129+ where
130+ showPrettyDocS : (doc : PrettyDoc) -> (acc : String) -> String
131+ showPrettyDocS Empty acc = acc
132+ showPrettyDocS (Chara c rest) acc = strCons c (showPrettyDocS rest acc)
133+ showPrettyDocS (Text len str rest) acc = str ++ (showPrettyDocS rest acc)
134+ showPrettyDocS (Line lvl rest) acc = (strCons '\n' (indentation lvl)) ++ showPrettyDocS rest acc
135+
136+private
137+fits : (w : Int) -> (x : PrettyDoc) -> Bool
138+fits w Empty = if w < 0 then False else True
139+fits w (Chara c rest) = if w < 0 then False else fits (w - 1) rest
140+
141+fits w (Text len str rest) = if w < 0 then False else fits (w - len) rest
142+
143+fits w (Line _ _) = if w < 0 then False else True
144+
145+
146+||| Use the Wadler-Leijen algorithm to pretty print the `doc`.
147+||| The algorithm uses a page width of `width` and a ribbon
148+||| width of `(ribbonfrac * width)` characters. The ribbon width is
149+||| the maximal amount of non-indentation characters on a line. The
150+||| parameter `ribbonfrac` should be between `0.0` and `1.0`. If it is
151+||| lower or higher, the ribbon width will be 0 or `width`
152+||| respectively.
153+render : (rfrac : Double)
154+ -> (width : Int)
155+ -> (doc : Doc)
156+ -> PrettyDoc
157+render rfrac w doc = best w 0 0 doc (const Empty)
158+ where
159+ rwidth : Int
160+ rwidth = max 0 $ min w (cast (cast w * rfrac))
161+
162+ nicest : (lvl : Int)
163+ -> (col : Int)
164+ -> (x : PrettyDoc)
165+ -> (y : PrettyDoc)
166+ -> PrettyDoc
167+ nicest n k x y =
168+ let width = min (w - k) (rwidth - k + n)
169+ in if fits width x then x else y
170+
171+ best : (lvl : Int)
172+ -> (col : Int)
173+ -> (curr : Int)
174+ -> (doc : Doc)
175+ -> (k : Int -> PrettyDoc)
176+ -> PrettyDoc
177+ best lvl col curr Empty k = k col
178+ best lvl col curr (Chara c) k = Chara c $ k (col + 1)
179+ best lvl col curr (Text len str) k = Text len str $ k (col + len)
180+ best lvl col curr (Line undone) k = Line curr $ k curr
181+
182+ best lvl col curr (Cat x y) k =
183+ best lvl col curr x (\curr' => best lvl curr' curr y k)
184+
185+ best lvl col curr (Nest x y) k = best lvl col (curr+x) y k
186+
187+ best lvl col curr (Union x y) k =
188+ nicest lvl col (best lvl col curr x k)
189+ (best lvl col curr y k)
190+
191+ best lvl col curr (Column f) k = best lvl col curr (f col) k
192+ best lvl col curr (Nesting f) k = best lvl col curr (f curr) k
193+
194+||| Print the document to a string using the given ribbon fraction
195+||| and page width.
196+toString : (rfrac : Double)
197+ -> (width : Int)
198+ -> (doc : Doc)
199+ -> String
200+toString rfrac width doc = showPrettyDoc (render rfrac width doc)
201+
202+writeDoc : (fname : String)
203+ -> (rfrac : Double)
204+ -> (width : Int)
205+ -> (doc : Doc)
206+ -> IO (Either FileError ())
207+writeDoc fname rfrac width doc = writeFile fname $ toString rfrac width doc
208+
209+namespace Default
210+
211+ ||| Render the document with a default ribbon fraction of 0.4 and page width of 120 characters.
212+ render : (doc : Doc) -> PrettyDoc
213+ render = render 0.4 120
214+
215+ ||| Print the document to a string using a default ribbon fraction
216+ ||| of 0.4 and page width of 120 characters.
217+ toString : (doc : Doc) -> String
218+ toString = toString 0.4 120
219+
220+ ||| Write the doc to `fname` using a default ribbon fraction of 0.4
221+ ||| and page width of 120 characters.
222+ writeDoc : (fname : String)
223+ -> (doc : Doc)
224+ -> IO (Either FileError ())
225+ writeDoc fname doc = writeFile fname $ Default.toString doc
libs/contrib/contrib.ipkg+12−2
@@ -11,6 +11,7 @@ modules = CFFI, CFFI.Types, CFFI.Memory,
1111 Control.Pipeline,
1212 Control.ST, Control.ST.ImplicitCall, Control.ST.Exception,
1313
14+ Interfaces.Correlative,
1415 Interfaces.Verified,
1516
1617 Data.Fun, Data.Rel,
@@ -22,7 +23,8 @@ modules = CFFI, CFFI.Types, CFFI.Memory,
2223 Data.Heap,
2324 Data.SortedMap, Data.SortedSet,
2425 Data.CoList, Data.Storable,
25− Data.List.Zipper,
26+ Data.List.Zipper,
27+ Data.Pairs.Implicit,
2628
2729 Decidable.Decidable, Decidable.Order,
2830
@@ -32,4 +34,12 @@ modules = CFFI, CFFI.Types, CFFI.Memory,
3234
3335 Text.Lexer, Text.Parser,
3436
35− Data.Fin.Extra
37+ Text.PrettyPrint.WL,
38+ Text.PrettyPrint.WL.Core,
39+ Text.PrettyPrint.WL.Characters,
40+ Text.PrettyPrint.WL.Combinators,
41+
42+ Text.Literate,
43+
44+ Data.Fin.Extra,
45+ Data.Stream.Extra
libs/effects/Effect/Logging/Level.idr+9−9
@@ -58,15 +58,15 @@ implementation Cast (LogLevel n) Nat where
5858 cast {n} _ = n
5959
6060implementation Show (LogLevel n) where
61− show OFF = "OFF"
62− show TRACE = "TRACE"
63− show DEBUG = "DEBUG"
64− show INFO = "INFO"
65− show WARN = "WARN"
66− show FATAL = "FATAL"
67− show ERROR = "ERROR"
68− show ALL = "ALL"
69− show (CUSTOM n) = unwords ["CUSTOM", show n]
61+ showPrec d OFF = "OFF"
62+ showPrec d TRACE = "TRACE"
63+ showPrec d DEBUG = "DEBUG"
64+ showPrec d INFO = "INFO"
65+ showPrec d WARN = "WARN"
66+ showPrec d FATAL = "FATAL"
67+ showPrec d ERROR = "ERROR"
68+ showPrec d ALL = "ALL"
69+ showPrec d (CUSTOM n) = showCon d "CUSTOM" $ showArg n
7070
7171implementation Eq (LogLevel n) where
7272 (==) x y = lvlEq x y
libs/prelude/Prelude.idr+1−2
@@ -280,8 +280,7 @@ namespace JSNull
280280
281281||| Pointer equality
282282eqPtr : Ptr -> Ptr -> IO Bool
283−eqPtr x y = do eq <- foreign FFI_C "idris_eqPtr" (Ptr -> Ptr -> IO Int) x y
284− pure (eq /= 0)
283+eqPtr x y = pure $ prim__eqPtr x y /= 0
285284
286285||| Loop while some test is true
287286|||
libs/prelude/Prelude/Bits.idr+4−4
@@ -21,12 +21,12 @@ import Prelude.Strings
2121-- Convert to `List Bits8`
2222--------------------------------------------------------------------------------
2323
24−||| Convert to list of `Bits8` with the most signficant byte at the
24+||| Convert to list of `Bits8` with the most significant byte at the
2525||| head.
2626b8ToBytes : Bits8 -> List Bits8
2727b8ToBytes b = [b]
2828
29−||| Convert to list of `Bits8` with the most signficant byte at the
29+||| Convert to list of `Bits8` with the most significant byte at the
3030||| head.
3131b16ToBytes : Bits16 -> List Bits8
3232b16ToBytes b =
@@ -34,7 +34,7 @@ b16ToBytes b =
3434 , prim__truncB16_B8 b
3535 ]
3636
37−||| Convert to list of `Bits8` with the most signficant byte at the
37+||| Convert to list of `Bits8` with the most significant byte at the
3838||| head.
3939b32ToBytes : Bits32 -> List Bits8
4040b32ToBytes b =
@@ -44,7 +44,7 @@ b32ToBytes b =
4444 , prim__truncB32_B8 b
4545 ]
4646
47−||| Convert to list of `Bits8` with the most signficant byte at the
47+||| Convert to list of `Bits8` with the most significant byte at the
4848||| head.
4949b64ToBytes : Bits64 -> List Bits8
5050b64ToBytes b =
libs/prelude/Prelude/List.idr+5−1
@@ -378,7 +378,7 @@ scanl : (b -> a -> b) -> b -> List a -> List b
378378scanl f q [] = [q]
379379scanl f q (x::xs) = q :: scanl f (f q x) xs
380380
381−||| The scanl1 function is a variant of scanl that doesn't require an explicit
381+||| The scanl1 function is a variant of scanl that doesn't require an explicit
382382||| starting value.
383383||| It assumes the first element of the list to be the starting value and then
384384||| starts the fold with the element following it.
@@ -855,6 +855,10 @@ catMaybes (x::xs) =
855855-- Properties
856856--------------------------------------------------------------------------------
857857
858+||| (::) is injective
859+consInjective : (x :: xs) = (y :: ys) -> (x = y, xs = ys)
860+consInjective Refl = (Refl, Refl)
861+
858862||| The empty list is a right identity for append.
859863appendNilRightNeutral : (l : List a) ->
860864 l ++ [] = l
libs/prelude/Prelude/Nat.idr+10−2
@@ -147,7 +147,7 @@ lteSuccRight : LTE n m -> LTE n (S m)
147147lteSuccRight LTEZero = LTEZero
148148lteSuccRight (LTESucc x) = LTESucc (lteSuccRight x)
149149
150−||| n + 1 < m implies n < m
150+||| n + 1 < m implies n < m
151151lteSuccLeft : LTE (S n) m -> LTE n m
152152lteSuccLeft (LTESucc x) = lteSuccRight x
153153
@@ -160,6 +160,11 @@ lteAddRight : (n : Nat) -> LTE n (plus n m)
160160lteAddRight Z = LTEZero
161161lteAddRight (S k) = LTESucc (lteAddRight k)
162162
163+||| If a number is not less than another, it is greater than or equal to it
164+notLTImpliesGTE : Not (LT a b) -> GTE a b
165+notLTImpliesGTE {b = Z} _ = LTEZero
166+notLTImpliesGTE {a = Z} {b = S k} notLt = absurd (notLt (LTESucc LTEZero))
167+notLTImpliesGTE {a = S k} {b = S j} notLt = LTESucc (notLTImpliesGTE (notLt . LTESucc))
163168
164169||| Boolean test than one Nat is less than or equal to another
165170total lte : Nat -> Nat -> Bool
@@ -231,7 +236,10 @@ Cast Integer Nat where
231236 cast = fromInteger
232237
233238Cast String Nat where
234− cast str = cast (the Integer (cast str))
239+ cast str = cast (the Integer (cast str))
240+
241+Cast Nat String where
242+ cast n = cast (the Integer (cast n))
235243
236244||| A wrapper for Nat that specifies the semigroup and monoid implementations that use (*)
237245record Multiplicative where
libs/pruviloj/Pruviloj/Core.idr+48−2
@@ -225,13 +225,16 @@ refine tm =
225225 countPi (RBind _ (Pi _ _) body) = S (countPi body)
226226 countPi _ = Z
227227
228+||| A helper to extract the type representation for term.
229+getTTType : Raw -> Elab TT
230+getTTType r = snd <$> check !getEnv r
228231
229232||| Split a pair into its projections, binding them in the context
230233||| with the supplied names. A special case of Coq's `inversion`.
231234both : Raw -> TTName -> TTName -> Elab ()
232235both tm n1 n2 =
233236 do -- We don't know that the term is canonical, so let-bind projections applied to it
234− (A, B) <- isPairTy (snd !(check !getEnv tm))
237+ (A, B) <- isPairTy !(getTTType tm)
235238 remember n1 A; apply `(fst {a=~A} {b=~B} ~tm) []; solve
236239 remember n2 B; apply `(snd {a=~A} {b=~B} ~tm) []; solve
237240 where
@@ -253,7 +256,6 @@ unproduct tm =
253256 try (unproduct (Var n1))
254257 try (unproduct (Var n2))
255258
256−
257259||| A special-purpose tactic that attempts to solve a goal using
258260||| `Refl`. This is useful for ensuring that goals in fact are trivial
259261||| when developing or testing other tactics; otherwise, consider
@@ -268,3 +270,47 @@ reflexivity =
268270 , NamePart `{reflexivity}
269271 , TextPart "is not applicable."
270272 ]
273+
274+||| Attempt to swap the sides of equality in a goal. If the goal is `x = y`,
275+||| after the invocation the focus will be on a hole of type `y = x`.
276+symmetry : Elab ()
277+symmetry =
278+ do [_,_,_,_,res] <- apply (Var `{{sym}}) [True, True, True, True, False]
279+ | _ => fail [TextPart "Failed while applying", NamePart `{symmetry}]
280+ solve
281+ focus res
282+
283+||| Swap the sides of an equality, saving the result in a `let`-binding.
284+||| Returns the generated name.
285+|||
286+||| @ t the equality proof to swap
287+||| @ hint a hint to use for generating the variable name for the result
288+symmetryAs : (t : Raw) -> (hint : String) -> Elab TTName
289+symmetryAs t hint =
290+ case !(getTTType t) of
291+ `((=) {A=~A} {B=~B} ~l ~r) =>
292+ do af <- forget A
293+ bf <- forget B
294+ lf <- forget l
295+ rf <- forget r
296+ let ts = the Raw $ `(sym {a=~af} {b=~bf} {left=~lf} {right=~rf} ~t)
297+ n <- gensym hint
298+ letbind n !(forget !(getTTType ts)) ts
299+ pure n
300+ tt => fail [TermPart tt, TextPart "is not an equality"]
301+
302+||| Apply a function term to an argument term, saving the result in a
303+||| `let`-binding. Returns the generated name.
304+|||
305+||| @ f the function to apply
306+||| @ x the term to apply to
307+||| @ hint a hint to use for generating the variable name for the result
308+applyAs : (f : Raw) -> (x : Raw) -> (hint : String) -> Elab TTName
309+applyAs f x hint =
310+ case !(getTTType f) of
311+ `(~xty -> ~yty) =>
312+ do let fx = RApp f x
313+ n <- gensym hint
314+ letbind n !(forget !(getTTType fx)) fx
315+ pure n
316+ ftt => fail [TermPart ftt, TextPart "is not a function"]
libs/pruviloj/Pruviloj/Derive/Eliminators.idr+2−2
@@ -130,8 +130,8 @@ getElimTy info ctors =
130130data ElimArg = IHArgument TTName | NormalArgument TTName
131131
132132implementation Show ElimArg where
133− show (IHArgument x) = "IHArgument " ++ show x
134− show (NormalArgument x) = "NormalArgument " ++ show x
133+ showPrec d (IHArgument x) = showCon d "IHArgument" $ showArg x
134+ showPrec d (NormalArgument x) = showCon d "NormalArgument" $ showArg x
135135
136136getElimClause : TyConInfo -> (elimn : TTName) -> (methCount : Nat) ->
137137 (TTName, List CtorArg, Raw) -> Nat -> Elab (FunClause Raw)
rts/Makefile+3−4
@@ -2,7 +2,7 @@ include ../config.mk
22
33OBJS = idris_rts.o idris_heap.o idris_gc.o idris_gmp.o idris_bitstring.o \
44 idris_opts.o idris_stats.o idris_utf8.o idris_stdfgn.o mini-gmp.o \
5− idris_buffer.o getline.o
5+ idris_buffer.o getline.o idris_net.o
66HDRS = idris_rts.h idris_heap.h idris_gc.h idris_gmp.h idris_bitstring.h \
77 idris_opts.h idris_stats.h mini-gmp.h idris_stdfgn.h idris_net.h \
88 idris_buffer.h idris_utf8.h getline.h
@@ -20,10 +20,9 @@ endif
2020endif
2121
2222ifeq ($(OS), windows)
23− OBJS += windows/idris_net.o windows/win_utils.o
23+ OBJS += windows/win_utils.o
2424else
2525 CFLAGS += -fPIC
26− OBJS += idris_net.o
2726endif
2827
2928LIBTARGET = libidris_rts.a
@@ -31,7 +30,7 @@ LIBTARGET = libidris_rts.a
3130build: $(LIBTARGET) $(DYLIBTARGET)
3231
3332$(LIBTARGET) : $(OBJS)
34− $(AR) r $(LIBTARGET) $(OBJS)
33+ $(AR) rc $(LIBTARGET) $(OBJS)
3534 $(RANLIB) $(LIBTARGET)
3635
3736install :
rts/idris_net.c+36−7
@@ -3,15 +3,34 @@
33// MIT Licensed. Have fun!
44#include "idris_net.h"
55#include <errno.h>
6−#include <netdb.h>
76#include <stdbool.h>
87#include <stdlib.h>
98#include <stdio.h>
109#include <string.h>
11−#include <sys/types.h>
12−#include <sys/socket.h>
10+
11+#ifndef WIN32
1312#include <netinet/in.h>
1413#include <arpa/inet.h>
14+#else
15+static int socket_inited = 0;
16+static WSADATA wsa_data;
17+
18+static void clean_sockets(void) {
19+ WSACleanup();
20+}
21+
22+static int check_init(void) {
23+ if (!socket_inited) {
24+ int result = WSAStartup(MAKEWORD(2, 2), &wsa_data);
25+ if (result == NO_ERROR) {
26+ socket_inited = 1;
27+ atexit(clean_sockets);
28+ }
29+ }
30+ return socket_inited;
31+}
32+#endif
33+
1534
1635void buf_htonl(void* buf, int len) {
1736 int* buf_i = (int*) buf;
@@ -37,6 +56,16 @@ void idrnet_free(void* ptr) {
3756 free(ptr);
3857}
3958
59+
60+int idrnet_socket(int domain, int type, int protocol) {
61+#ifdef WIN32
62+ if (!check_init()) {
63+ return -1;
64+ }
65+#endif
66+ return socket(domain, type, protocol);
67+}
68+
4069// We call this from quite a few functions. Given a textual host and an int port,
4170// populates a struct addrinfo.
4271int idrnet_getaddrinfo(struct addrinfo** address_res, char* host, int port,
@@ -65,7 +94,7 @@ int idrnet_getaddrinfo(struct addrinfo** address_res, char* host, int port,
6594int idrnet_bind(int sockfd, int family, int socket_type, char* host, int port) {
6695 struct addrinfo* address_res;
6796 int addr_res = idrnet_getaddrinfo(&address_res, host, port, family, socket_type);
68− if (addr_res == -1) {
97+ if (addr_res != 0) {
6998 //printf("Lib err: bind getaddrinfo\n");
7099 return -1;
71100 }
@@ -82,7 +111,7 @@ int idrnet_bind(int sockfd, int family, int socket_type, char* host, int port) {
82111int idrnet_connect(int sockfd, int family, int socket_type, char* host, int port) {
83112 struct addrinfo* remote_host;
84113 int addr_res = idrnet_getaddrinfo(&remote_host, host, port, family, socket_type);
85− if (addr_res == -1) {
114+ if (addr_res != 0) {
86115 return -1;
87116 }
88117
@@ -189,7 +218,7 @@ int idrnet_sendto(int sockfd, char* data, char* host, int port, int family) {
189218
190219 struct addrinfo* remote_host;
191220 int addr_res = idrnet_getaddrinfo(&remote_host, host, port, family, SOCK_DGRAM);
192− if (addr_res == -1) {
221+ if (addr_res != 0) {
193222 return -1;
194223 }
195224
@@ -203,7 +232,7 @@ int idrnet_sendto_buf(int sockfd, void* buf, int buf_len, char* host, int port,
203232
204233 struct addrinfo* remote_host;
205234 int addr_res = idrnet_getaddrinfo(&remote_host, host, port, family, SOCK_DGRAM);
206− if (addr_res == -1) {
235+ if (addr_res != 0) {
207236 //printf("lib err: sendto getaddrinfo \n");
208237 return -1;
209238 }
rts/idris_net.h+13
@@ -1,6 +1,17 @@
11#ifndef IDRISNET_H
22#define IDRISNET_H
33
4+// Includes used by the idris-file.
5+#ifdef WIN32
6+#include <winsock2.h>
7+#include <Ws2tcpip.h>
8+#else
9+#include <netdb.h>
10+#include <unistd.h>
11+#include <sys/types.h>
12+#include <sys/socket.h>
13+#endif
14+
415struct sockaddr_storage;
516struct addrinfo;
617
@@ -24,6 +35,8 @@ void idrnet_free(void* ptr);
2435// Gets value of errno
2536int idrnet_errno();
2637
38+int idrnet_socket(int domain, int type, int protocol);
39+
2740// Bind
2841int idrnet_bind(int sockfd, int family, int socket_type, char* host, int port);
2942
rts/idris_rts.c+10−4
@@ -460,6 +460,11 @@ void dumpVal(VAL v) {
460460 case CT_STRING:
461461 printf("STR[%s]", v->info.str.str);
462462 break;
463+ case CT_STROFFSET:
464+ printf("OFFSET[");
465+ dumpVal((VAL)(v->info.str_offset->str));
466+ printf("]");
467+ break;
463468 case CT_FWD:
464469 printf("CT_FWD ");
465470 dumpVal((VAL)(v->info.ptr));
@@ -591,15 +596,16 @@ VAL idris_castStrFloat(VM* vm, VAL i) {
591596VAL idris_concat(VM* vm, VAL l, VAL r) {
592597 char *rs = GETSTR(r);
593598 char *ls = GETSTR(l);
594− // dumpVal(l);
595− // printf("\n");
596− Closure* cl = allocate(sizeof(Closure) + GETSTRLEN(l) + GETSTRLEN(r) + 1, 0);
599+ int llen = GETSTRLEN(l);
600+ int rlen = GETSTRLEN(r);
601+
602+ Closure* cl = allocate(sizeof(Closure) + llen + rlen + 1, 0);
597603 SETTY(cl, CT_STRING);
598604 cl->info.str.str = (char*)cl + sizeof(Closure);
599605 strcpy(cl->info.str.str, ls);
600606 strcat(cl->info.str.str, rs);
601607
602− cl->info.str.len = GETSTRLEN(l) + GETSTRLEN(r);
608+ cl->info.str.len = llen + rlen;
603609 return cl;
604610}
605611
rts/idris_rts.h+2−7
@@ -206,14 +206,9 @@ typedef void(*func)(VM*, VAL*);
206206#define CTAG(x) (((x)->info.c.tag_arity) >> 8)
207207#define CARITY(x) ((x)->info.c.tag_arity & 0x000000ff)
208208
209−// Use top 16 bits for saying which heap value is in
210−// Bottom 16 bits for closure type
211−
212−#define GETTY(x) ((x)->ty & 0x0000ffff)
213−#define SETTY(x,t) (x)->ty = (((x)->ty & 0xffff0000) | (t))
214209
215−#define GETHEAP(x) ((x)->ty >> 16)
216−#define SETHEAP(x,y) (x)->ty = (((x)->ty & 0x0000ffff) | ((y) << 16))
210+#define GETTY(x) ((x)->ty)
211+#define SETTY(x,t) ((x)->ty = t)
217212
218213// Integers, floats and operators
219214
rts/idris_stdfgn.c−4
@@ -103,10 +103,6 @@ int isNull(void* ptr) {
103103 return ptr==NULL;
104104}
105105
106−int idris_eqPtr(void* x, void* y) {
107− return x==y;
108−}
109−
110106void* idris_stdin() {
111107 return (void*)stdin;
112108}
rts/idris_stdfgn.h−2
@@ -29,8 +29,6 @@ VAL idris_getString(VM* vm, void* buffer);
2929void* do_popen(const char* cmd, const char* mode);
3030int fpoll(void* h);
3131
32−
33−int idris_eqPtr(void* x, void* y);
3432int isNull(void* ptr);
3533void* idris_stdin();
3634
rts/windows/idris_net.cdeleted−200
@@ -1,200 +0,0 @@
1−// C-Side of the Idris network library
2−// (C) Simon Fowler, 2014
3−// MIT Licensed. Have fun!
4−#include "../idris_net.h"
5−
6−#include <errno.h>
7−#include <stdbool.h>
8−#include <stdlib.h>
9−#include <stdio.h>
10−#include <string.h>
11−#include <Winsock2.h>
12−#include <Ws2tcpip.h>
13−
14−
15−// inet_ntop isn't defined in the old mingw delivered with GHC,
16−// so put the prototype here, cribbed from a newer version of it
17−WINSOCK_API_LINKAGE LPCSTR WSAAPI InetNtopA(INT Family, PVOID pAddr,
18− LPSTR pStringBuf, size_t StringBufSize);
19−
20−static int socket_inited = 0;
21−static WSADATA wsa_data;
22−
23−void* idrnet_malloc(int size) {
24− return malloc(size);
25−}
26−
27−void idrnet_free(void* ptr) {
28− free(ptr);
29−}
30−
31−static void clean_sockets(void) {
32− WSACleanup();
33−}
34−
35−static int check_init(void)
36−{
37− if (!socket_inited) {
38− int result = WSAStartup(MAKEWORD(2, 2), &wsa_data);
39− if (result == NO_ERROR) {
40− socket_inited = 1;
41− atexit(clean_sockets);
42− }
43− }
44− return socket_inited;
45−}
46−
47−int idrnet_bind(int sockfd, int family, int socket_type, char* host, int port) {
48− struct addrinfo hints;
49− struct addrinfo* address_res;
50− // Convert port into string
51− char str_port[8];
52− sprintf(str_port, "%d", port);
53−
54− if (!check_init()) {
55− return -1;
56− }
57− // Set up hints structure
58− memset(&hints, 0, sizeof(hints)); // zero out hints
59− hints.ai_family = family;
60− hints.ai_socktype = socket_type;
61−
62− // If the length of the hostname is 0 (i.e, it was set to Nothing in Idris)
63− // then we want to instruct the C library to fill in the IP automatically
64− if (strlen(host) == 0) {
65− hints.ai_flags = AI_PASSIVE; // fill in IP automatically
66− }
67−
68− int addr_res = getaddrinfo(host, str_port, &hints, &address_res);
69− if (addr_res == -1) {
70− return -1;
71− }
72−
73− int bind_res = bind(sockfd, address_res->ai_addr, address_res->ai_addrlen);
74− if (bind_res == -1) {
75− return -1;
76− }
77−
78− return 0;
79−}
80−
81−int idrnet_connect(int sockfd, int family, int socket_type, char* host, int port) {
82− char str_port[8];
83− sprintf(str_port, "%d", port);
84− struct addrinfo hints;
85− struct addrinfo* remote_host;
86−
87− if (!check_init()) {
88− return -1;
89− }
90− // Set up hints structure for getaddrinfo
91− memset(&hints, 0, sizeof(hints));
92− hints.ai_family = family;
93− hints.ai_socktype = socket_type;
94−
95− // Get info about the remote host (DNS lookup etc)
96− int addr_res = getaddrinfo(host, str_port, &hints, &remote_host);
97− if (addr_res == -1) {
98− return -1;
99− }
100−
101− int connect_res = connect(sockfd, remote_host->ai_addr, remote_host->ai_addrlen);
102− if (connect_res == -1) {
103− return -1;
104− }
105−
106− return 0;
107−}
108−
109−
110−int idrnet_sockaddr_family(void* sockaddr) {
111− struct sockaddr* addr = (struct sockaddr*) sockaddr;
112− return (int) addr->sa_family;
113−}
114−
115−char* idrnet_sockaddr_ipv4(void* sockaddr) {
116− struct sockaddr_in* addr = (struct sockaddr_in*) sockaddr;
117− char* ip_addr = (char*) malloc(sizeof(char) * INET_ADDRSTRLEN);
118− InetNtopA(AF_INET, &(addr->sin_addr), ip_addr, INET_ADDRSTRLEN);
119− return ip_addr;
120−}
121−
122−void* idrnet_create_sockaddr() {
123− return malloc(sizeof(struct sockaddr_storage));
124−}
125−
126−
127−int idrnet_accept(int sockfd, void* sockaddr) {
128− struct sockaddr* addr = (struct sockaddr*) sockaddr;
129− socklen_t addr_size = 0;
130− if (!check_init()) {
131− return -1;
132− }
133− return accept(sockfd, addr, &addr_size);
134−}
135−
136−int idrnet_send(int sockfd, char* data) {
137− int len = strlen(data); // For now.
138− if (!check_init()) {
139− return -1;
140− }
141− return send(sockfd, (void*) data, len, 0);
142−}
143−
144−int idrnet_send_buf(int sockfd, void* data, int len) {
145− if (!check_init()) {
146− return -1;
147− }
148− return send(sockfd, data, len, 0);
149−}
150−
151−void* idrnet_recv(int sockfd, int len) {
152− if (!check_init()) {
153− return NULL;
154− }
155− idrnet_recv_result* res_struct =
156− (idrnet_recv_result*) malloc(sizeof(idrnet_recv_result));
157−
158− char* buf = malloc(len + 1);
159− int recv_res = recv(sockfd, buf, len, 0);
160− res_struct->result = recv_res;
161−
162− if (recv_res > 0) { // Data was received
163− buf[recv_res + 1] = 0x00; // Null-term, so Idris can interpret it
164− }
165− res_struct->payload = (void*) buf;
166− return (void*) res_struct;
167−}
168−
169−int idrnet_recv_buf(int sockfd, void* buf, int len) {
170− if (!check_init()) {
171− return -1;
172− }
173− return recv(sockfd, buf, len, 0);
174−}
175−
176−int idrnet_get_recv_res(void* res_struct) {
177− return (((idrnet_recv_result*) res_struct)->result);
178−}
179−
180−char* idrnet_get_recv_payload(void* res_struct) {
181− return (((idrnet_recv_result*) res_struct)->payload);
182−}
183−
184−void idrnet_free_recv_struct(void* res_struct) {
185− idrnet_recv_result* i_res_struct =
186− (idrnet_recv_result*) res_struct;
187− if (i_res_struct->payload != NULL) {
188− free(i_res_struct->payload);
189− }
190− free(res_struct);
191−}
192−
193−int idrnet_errno() {
194− return errno;
195−}
196−
197−int idrnet_geteagain() {
198− return EAGAIN;
199−}
200−
scripts/runidrisnew file+25
@@ -0,0 +1,25 @@
1+#!/bin/sh
2+
3+# This is a script that runs an idris program, suitable for use
4+# in a shebang line. We cache the executables by naming them after
5+# the SHA hash of the idris source and looking for it before
6+# compiling
7+RUNIDRIS_DIR="${TEMP:-/tmp}/runidris"
8+if [ ! -d $RUNIDRIS_DIR ]; then
9+ mkdir $RUNIDRIS_DIR
10+ chmod 700 $RUNIDRIS_DIR
11+fi
12+
13+OS=`uname -s`
14+case $OS in
15+ OpenBSD ) TEMP_NAME="runidris-`sha1 -q $1`" ;;
16+ * ) TEMP_NAME="runidris-`sha1sum $1 | cut -c1-40`" ;;
17+esac
18+
19+FP="$RUNIDRIS_DIR/$TEMP_NAME"
20+cp "$1" "$FP.idr" # idris won't compile the script unless it ends in .idr
21+if [ ! -e $FP ]; then
22+ "${IDRIS:-idris}" "$FP.idr" --ibcsubdir "$RUNIDRIS_DIR" -i "." -o $FP
23+fi
24+shift
25+"$FP" "$@"
scripts/runidris-nodenew file+25
@@ -0,0 +1,25 @@
1+#!/bin/sh
2+
3+# This is a script that runs an idris program, suitable for use
4+# in a shebang line. We cache the executables by naming them after
5+# the SHA hash of the idris source and looking for it before
6+# compiling. This is the node version.
7+RUNIDRIS_DIR="${TEMP:-/tmp}/runidris-node"
8+if [ ! -d $RUNIDRIS_DIR ]; then
9+ mkdir $RUNIDRIS_DIR
10+ chmod 700 $RUNIDRIS_DIR
11+fi
12+
13+OS=`uname -s`
14+case $OS in
15+ OpenBSD ) TEMP_NAME="runidris-`sha1 -q $1`" ;;
16+ * ) TEMP_NAME="runidris-`sha1sum $1 | cut -c1-40`" ;;
17+esac
18+
19+FP="$RUNIDRIS_DIR/$TEMP_NAME"
20+cp "$1" "$FP.idr" # idris won't compile the script unless it ends in .idr
21+if [ ! -e "$FP.js" ]; then
22+ "${IDRIS:-idris}" --codegen node --ibcsubdir "$RUNIDRIS_DIR" -i "." "$FP.idr" -o "$FP.js"
23+fi
24+shift
25+node "$FP.js" "$@"
src/IRTS/CodegenC.hs+3−1
@@ -5,6 +5,8 @@ Copyright :
55License : BSD3
66Maintainer : The Idris Community.
77-}
8+{-# LANGUAGE FlexibleContexts #-}
9+
810module IRTS.CodegenC (codegenC) where
911
1012import Idris.AbsSyntax
@@ -183,7 +185,7 @@ bcc i (ASSIGNCONST l c)
183185 mkConst (I i) = "MKINT(" ++ show i ++ ")"
184186 mkConst (BI i) | i < (2^30) = "MKINT(" ++ show i ++ ")"
185187 | otherwise = "MKBIGC(vm,\"" ++ show i ++ "\")"
186− mkConst (Fl f) = "MKFLOAT(vm, " ++ show f ++ ")"
188+ mkConst (Fl f) = "MKFLOAT(vm, " ++ (map toUpper $ show f) ++ ")"
187189 mkConst (Ch c) = "MKINT(" ++ show (fromEnum c) ++ ")"
188190 mkConst (Str s) = "MKSTR(vm, " ++ showCStr s ++ ")"
189191 mkConst (B8 x) = "idris_b8const(vm, " ++ show x ++ "U)"
src/IRTS/Compiler.hs+17−15
@@ -5,7 +5,7 @@ Copyright :
55License : BSD3
66Maintainer : The Idris Community.
77-}
8−{-# LANGUAGE CPP, PatternGuards, TypeSynonymInstances #-}
8+{-# LANGUAGE CPP, FlexibleContexts, PatternGuards, TypeSynonymInstances #-}
99
1010module IRTS.Compiler(compile, generate) where
1111
@@ -63,6 +63,8 @@ compile codegen f mtm = do
6363 Nothing -> []
6464 Just t -> freeNames t
6565
66+ logCodeGen 1 "Running Erasure Analysis"
67+ iReport 3 "Running Erasure Analysis"
6668 reachableNames <- performUsageAnalysis
6769 (rootNames ++ getExpNames exports)
6870 maindef <- case mtm of
@@ -74,7 +76,7 @@ compile codegen f mtm = do
7476 libs <- getLibs codegen
7577 flags <- getFlags codegen
7678 hdrs <- getHdrs codegen
77− impdirs <- allImportDirs
79+ impdirs <- rankedImportDirs f
7880 ttDeclarations <- getDeclarations reachableNames
7981 defsIn <- mkDecls reachableNames
8082 -- if no 'main term' given, generate interface files
@@ -212,7 +214,7 @@ build (n, d)
212214 Just (ar, op) ->
213215 let args = map (\x -> sMN x "op") [0..] in
214216 return (n, (LFun [] n (take ar args)
215− (LOp op (map (LV . Glob) (take ar args)))))
217+ (LOp op (map LV (take ar args)))))
216218 _ -> do def <- mkLDecl n d
217219 logCodeGen 3 $ "Compiled " ++ show n ++ " =\n\t" ++ show def
218220 return (n, def)
@@ -396,7 +398,7 @@ irTerm top vs env tm@(App _ f a) = do
396398 -> irTerm top vs env (head argsPruned)
397399
398400 | otherwise -- not newtype, plain data ctor
399− -> buildApp (LV $ Glob n) argsPruned
401+ -> buildApp (LV n) argsPruned
400402
401403 -- not saturated, underapplied
402404 LT | isNewtype -- newtype
@@ -405,11 +407,11 @@ irTerm top vs env tm@(App _ f a) = do
405407 <$> irTerm top vs env (head argsPruned)
406408
407409 | isNewtype -- newtype but the value is not among args yet
408− -> return . padLams $ \[vn] -> LApp False (LV $ Glob n) [LV $ Glob vn]
410+ -> return . padLams $ \[vn] -> LApp False (LV n) [LV vn]
409411
410412 -- not a newtype, just apply to a constructor
411413 | otherwise
412− -> padLams . applyToNames <$> buildApp (LV $ Glob n) argsPruned
414+ -> padLams . applyToNames <$> buildApp (LV n) argsPruned
413415
414416 -- type constructor
415417 (P (TCon t a) n _, args) -> return LNothing
@@ -444,7 +446,7 @@ irTerm top vs env tm@(App _ f a) = do
444446
445447 applyToNames :: LExp -> [Name] -> LExp
446448 applyToNames tm [] = tm
447− applyToNames tm ns = LApp False tm $ map (LV . Glob) ns
449+ applyToNames tm ns = LApp False tm $ map LV ns
448450
449451 padLambdas :: [Int] -> Int -> Int -> ([Name] -> LExp) -> LExp
450452 padLambdas used startIdx endSIdx mkTerm
@@ -455,7 +457,7 @@ irTerm top vs env tm@(App _ f a) = do
455457
456458 applyName :: Name -> IState -> [Term] -> Idris LExp
457459 applyName n ist args =
458− LApp False (LV $ Glob n) <$> mapM (irTerm top vs env . erase) (zip [0..] args)
460+ LApp False (LV n) <$> mapM (irTerm top vs env . erase) (zip [0..] args)
459461 where
460462 erase (i, x)
461463 | i >= arity || i `elem` used = x
@@ -477,9 +479,9 @@ irTerm top vs env tm@(App _ f a) = do
477479 used = maybe [] (map fst . usedpos) $ lookupCtxtExact uName (idris_callgraph ist)
478480 fst4 (x,_,_,_,_,_) = x
479481
480−irTerm top vs env (P _ n _) = return $ LV (Glob n)
482+irTerm top vs env (P _ n _) = return $ LV n
481483irTerm top vs env (V i)
482− | i >= 0 && i < length env = return $ LV (Glob (env!!i))
484+ | i >= 0 && i < length env = return $ LV (env!!i)
483485 | otherwise = ifail $ "bad de bruijn index: " ++ show i
484486
485487irTerm top vs env (Bind n (Lam _ _) sc) = LLam [n'] <$> irTerm top vs (n':env) sc
@@ -544,7 +546,7 @@ irSC top vs (ProjCase tm alts) = do
544546irSC top vs (Case up n [ConCase (UN delay) i [_, _, n'] sc])
545547 | delay == txt "Delay"
546548 = do sc' <- irSC top vs sc -- mkForce n' n sc
547− return $ lsubst n' (LForce (LV (Glob n))) sc'
549+ return $ lsubst n' (LForce (LV n)) sc'
548550
549551-- There are two transformations in this case:
550552--
@@ -581,10 +583,10 @@ irSC top vs (Case up n [alt]) = do
581583 case replacement of
582584 Just sc -> irSC top vs sc
583585 _ -> do
584− alt' <- irAlt top vs (LV (Glob n)) alt
586+ alt' <- irAlt top vs (LV n) alt
585587 return $ case namesBoundIn alt' `usedIn` subexpr alt' of
586588 [] -> subexpr alt' -- strip the unused top-most case
587− _ -> LCase up (LV (Glob n)) [alt']
589+ _ -> LCase up (LV n) [alt']
588590 where
589591 namesBoundIn :: LAlt -> [Name]
590592 namesBoundIn (LConCase cn i ns sc) = ns
@@ -616,7 +618,7 @@ irSC top vs (Case up n alts@[ConCase cn a ns sc, DefaultCase sc']) = do
616618 detag <- fgetState (opt_detaggable . ist_optimisation cn)
617619 if detag
618620 then irSC top vs (Case up n [ConCase cn a ns sc])
619− else LCase up (LV (Glob n)) <$> mapM (irAlt top vs (LV (Glob n))) alts
621+ else LCase up (LV n) <$> mapM (irAlt top vs (LV n)) alts
620622
621623irSC top vs sc@(Case up n alts) = do
622624 -- check that neither alternative needs the newtype optimisation,
@@ -626,7 +628,7 @@ irSC top vs sc@(Case up n alts) = do
626628 $ ifail ("irSC: non-trivial case-match on detaggable data: " ++ show sc)
627629
628630 -- everything okay
629− LCase up (LV (Glob n)) <$> mapM (irAlt top vs (LV (Glob n))) alts
631+ LCase up (LV n) <$> mapM (irAlt top vs (LV n)) alts
630632 where
631633 isDetaggable (ConCase cn _ _ _) = fgetState $ opt_detaggable . ist_optimisation cn
632634 isDetaggable _ = return False
src/IRTS/Defunctionalise.hs+24−25
@@ -19,7 +19,7 @@ To defunctionalise:
19198. Add explicit EVAL to case, primitives, and foreign calls
2020
2121-}
22−{-# LANGUAGE PatternGuards #-}
22+{-# LANGUAGE FlexibleContexts, PatternGuards #-}
2323module IRTS.Defunctionalise(module IRTS.Defunctionalise
2424 , module IRTS.Lang
2525 ) where
@@ -34,12 +34,12 @@ import Data.List
3434import Data.Maybe
3535import Debug.Trace
3636
37−data DExp = DV LVar
37+data DExp = DV Name
3838 | DApp Bool Name [DExp] -- True = tail call
3939 | DLet Name DExp DExp -- name just for pretty printing
4040 | DUpdate Name DExp -- eval expression, then update var with it
4141 | DProj DExp Int
42− | DC (Maybe LVar) Int Name [DExp]
42+ | DC (Maybe Name) Int Name [DExp]
4343 | DCase CaseType DExp [DAlt]
4444 | DChkCase DExp [DAlt] -- a case where the type is unknown (for EVAL/APPLY)
4545 | DConst Const
@@ -90,27 +90,27 @@ addApps defs (n, LFun _ _ args e)
9090 return (n, DFun n args e')
9191 where
9292 aa :: [Name] -> LExp -> State ([Name], [(Name, Int)]) DExp
93− aa env (LV (Glob n)) | n `elem` env = return $ DV (Glob n)
94− | otherwise = aa env (LApp False (LV (Glob n)) [])
95− aa env (LApp tc (LV (Glob n)) args)
93+ aa env (LV n) | n `elem` env = return $ DV n
94+ | otherwise = aa env (LApp False (LV n) [])
95+ aa env (LApp tc (LV n) args)
9696 = do args' <- mapM (aa env) args
9797 case lookupCtxtExact n defs of
9898 Just (LConstructor _ i ar) -> return $ DApp tc n args'
9999 Just (LFun _ _ as _) -> let arity = length as in
100100 fixApply tc n args' arity
101− Nothing -> return $ chainAPPLY (DV (Glob n)) args'
101+ Nothing -> return $ chainAPPLY (DV n) args'
102102 aa env (LLazyApp n args)
103103 = do args' <- mapM (aa env) args
104104 case lookupCtxtExact n defs of
105105 Just (LConstructor _ i ar) -> return $ DApp False n args'
106106 Just (LFun _ _ as _) -> let arity = length as in
107107 fixLazyApply n args' arity
108− Nothing -> return $ chainAPPLY (DV (Glob n)) args'
109− aa env (LForce (LLazyApp n args)) = aa env (LApp False (LV (Glob n)) args)
108+ Nothing -> return $ chainAPPLY (DV n) args'
109+ aa env (LForce (LLazyApp n args)) = aa env (LApp False (LV n) args)
110110 aa env (LForce e) = liftM eEVAL (aa env e)
111111 aa env (LLet n v sc) = liftM2 (DLet n) (aa env v) (aa (n : env) sc)
112112 aa env (LCon loc i n args) = liftM (DC loc i n) (mapM (aa env) args)
113− aa env (LProj t@(LV (Glob n)) i)
113+ aa env (LProj t@(LV n) i)
114114 | n `elem` env = do t' <- aa env t
115115 return $ DProj (DUpdate n t') i
116116 aa env (LProj t i) = do t' <- aa env t
@@ -170,7 +170,7 @@ addApps defs (n, LFun _ _ args e)
170170
171171 preEval [] t = t
172172 preEval (x : xs) t
173− | needsEval x t = DLet x (DV (Glob x)) (preEval xs t)
173+ | needsEval x t = DLet x (DV x) (preEval xs t)
174174 | otherwise = preEval xs t
175175
176176 needsEval x (DApp _ _ args) = any (needsEval x) args
@@ -188,7 +188,7 @@ addApps defs (n, LFun _ _ args e)
188188 | otherwise = needsEval x v || needsEval x e
189189 needsEval x (DForeign _ _ args) = any (needsEval x) (map snd args)
190190 needsEval x (DOp op args) = any (needsEval x) args
191− needsEval x (DProj (DV (Glob x')) _) = x == x'
191+ needsEval x (DProj (DV x') _) = x == x'
192192 needsEval x _ = False
193193
194194eEVAL x = DApp False (sMN 0 "EVAL") [x]
@@ -207,7 +207,7 @@ toCons ns (n, i)
207207 EvalCase (\tlarg ->
208208 (DConCase (-1) (mkFnCon n) (take i (genArgs 0))
209209 (dupdate tlarg
210− (DApp False n (map (DV . Glob) (take i (genArgs 0))))))))
210+ (DApp False n (map DV (take i (genArgs 0))))))))
211211 : [] -- mkApplyCase n 0 i
212212 | otherwise = []
213213 where dupdate tlarg x = DUpdate tlarg x
@@ -219,7 +219,7 @@ toConsA ns (n, i)
219219-- EvalCase (\tlarg ->
220220-- (DConCase (-1) (mkFnCon n) (take i (genArgs 0))
221221-- (dupdate tlarg
222−-- (DApp False n (map (DV . Glob) (take i (genArgs 0))))))))
222+-- (DApp False n (map DV (take i (genArgs 0))))))))
223223 = mkApplyCase n ar i
224224 | otherwise = []
225225 where dupdate tlarg x = x
@@ -229,13 +229,13 @@ mkApplyCase fname n ar
229229 = let nm = mkUnderCon fname (ar - n) in
230230 (nm, n, ApplyCase (DConCase (-1) nm (take n (genArgs 0))
231231 (DApp False (mkUnderCon fname (ar - (n + 1)))
232− (map (DV . Glob) (take n (genArgs 0) ++
232+ (map DV (take n (genArgs 0) ++
233233 [sMN 0 "arg"])))))
234234 :
235235 if (ar - (n + 2) >=0 )
236236 then (nm, n, Apply2Case (DConCase (-1) nm (take n (genArgs 0))
237237 (DApp False (mkUnderCon fname (ar - (n + 2)))
238− (map (DV . Glob) (take n (genArgs 0) ++
238+ (map DV (take n (genArgs 0) ++
239239 [sMN 0 "arg0", sMN 0 "arg1"])))))
240240 :
241241 mkApplyCase fname (n + 1) ar
@@ -243,9 +243,9 @@ mkApplyCase fname n ar
243243
244244mkEval :: [(Name, Int, EvalApply DAlt)] -> (Name, DDecl)
245245mkEval xs = (sMN 0 "EVAL", DFun (sMN 0 "EVAL") [sMN 0 "arg"]
246− (mkBigCase (sMN 0 "EVAL") 256 (DV (Glob (sMN 0 "arg")))
246+ (mkBigCase (sMN 0 "EVAL") 256 (DV (sMN 0 "arg"))
247247 (mapMaybe evalCase xs ++
248− [DDefaultCase (DV (Glob (sMN 0 "arg")))])))
248+ [DDefaultCase (DV (sMN 0 "arg"))])))
249249 where
250250 evalCase (n, t, EvalCase x) = Just (x (sMN 0 "arg"))
251251 evalCase _ = Nothing
@@ -256,7 +256,7 @@ mkApply xs = (sMN 0 "APPLY", DFun (sMN 0 "APPLY") [sMN 0 "fn", sMN 0 "arg"]
256256 [] -> DNothing
257257 cases ->
258258 mkBigCase (sMN 0 "APPLY") 256
259− (DV (Glob (sMN 0 "fn")))
259+ (DV (sMN 0 "fn"))
260260 (cases ++
261261 [DDefaultCase DNothing])))
262262 where
@@ -269,14 +269,14 @@ mkApply2 xs = (sMN 0 "APPLY2", DFun (sMN 0 "APPLY2") [sMN 0 "fn", sMN 0 "arg0",
269269 [] -> DNothing
270270 cases ->
271271 mkBigCase (sMN 0 "APPLY") 256
272− (DV (Glob (sMN 0 "fn")))
272+ (DV (sMN 0 "fn"))
273273 (cases ++
274274 [DDefaultCase
275275 (DApp False (sMN 0 "APPLY")
276276 [DApp False (sMN 0 "APPLY")
277− [DV (Glob (sMN 0 "fn")),
278− DV (Glob (sMN 0 "arg0"))],
279− DV (Glob (sMN 0 "arg1"))])
277+ [DV (sMN 0 "fn"),
278+ DV (sMN 0 "arg0")],
279+ DV (sMN 0 "arg1")])
280280 ])))
281281 where
282282 applyCase (n, t, Apply2Case x) = Just x
@@ -297,8 +297,7 @@ mkUnderCon n missing = sMN missing ("U_" ++ show n)
297297
298298instance Show DExp where
299299 show e = show' [] e where
300− show' env (DV (Loc i)) = "var " ++ env!!i
301− show' env (DV (Glob n)) = "GLOB " ++ show n
300+ show' env (DV n) = show n
302301 show' env (DApp _ e args) = show e ++ "(" ++
303302 showSep ", " (map (show' env) args) ++")"
304303 show' env (DLet n v e) = "let " ++ show n ++ " = " ++ show' env v ++ " in " ++
src/IRTS/JavaScript/Codegen.hs+43−55
@@ -20,15 +20,16 @@ import IRTS.JavaScript.Name
2020import IRTS.JavaScript.PrimOp
2121import IRTS.JavaScript.Specialize
2222import IRTS.Lang
23−import IRTS.LangOpts
2423import IRTS.System
2524
25+import Control.Applicative (pure, (<$>))
2626import Control.Monad
2727import Control.Monad.Trans.State
28−import Data.List (nub)
28+import Data.Foldable (foldMap)
29+import Data.Generics.Uniplate.Data
30+import Data.List
2931import Data.Map.Strict (Map)
3032import qualified Data.Map.Strict as Map
31−import Data.Maybe (fromJust)
3233import Data.Set (Set)
3334import qualified Data.Set as Set
3435import Data.Text (Text)
@@ -38,23 +39,27 @@ import System.Directory (doesFileExist)
3839import System.Environment
3940import System.FilePath
4041
41−import Control.Applicative (pure, (<$>))
42−import Data.Char
43−import Data.Data
44−import Data.Generics.Uniplate.Data
45−import Data.List
46−import GHC.Generics (Generic)
4742
43+-- | Code generation stats hold information about the generated user
44+-- code. Based on that information we add additional code to make
45+-- things work.
4846data CGStats = CGStats { usedBigInt :: Bool
4947 , partialApplications :: Set Partial
5048 , hiddenClasses :: Set HiddenClass
5149 }
5250
53−emptyStats :: CGStats
54−emptyStats = CGStats { partialApplications = Set.empty
55− , hiddenClasses = Set.empty
56− , usedBigInt = False
57− }
51+-- If we generate code for two declarations we want to merge their code
52+-- generation stats.
53+instance Monoid CGStats where
54+ mempty = CGStats { partialApplications = Set.empty
55+ , hiddenClasses = Set.empty
56+ , usedBigInt = False
57+ }
58+ mappend x y = CGStats { partialApplications = partialApplications x `Set.union` partialApplications y
59+ , hiddenClasses = hiddenClasses x `Set.union` hiddenClasses y
60+ , usedBigInt = usedBigInt x || usedBigInt y
61+ }
62+
5863
5964data CGConf = CGConf { header :: Text
6065 , footer :: Text
@@ -101,13 +106,11 @@ codegenJs conf ci =
101106 let defs' = Map.fromList $ liftDecls ci
102107 let defs = globlToCon defs'
103108 let used = Map.elems $ removeDeadCode defs [sMN 0 "runMain"]
104− if debug then
105− do
109+ when debug $ do
106110 writeFile (outputFile ci ++ ".LDeclsDebug") $ (unlines $ intersperse "" $ map show used) ++ "\n\n\n"
107111 putStrLn $ "Finished calculating used"
108− else pure ()
109112
110− let (out, stats) = doCodegen conf defs used
113+ let (out, stats) = doCodegen defs used
111114
112115 path <- getIdrisJSRTSDir
113116 jsbn <- if usedBigInt stats
@@ -160,20 +163,21 @@ doHiddenClasses x =
160163 JsFun (jsNameHiddenClass p) vars $ JsSeq (JsSet (JsProp JsThis "type") (JsInt id)) $ seqJs
161164 $ map (\tv -> JsSet (JsProp JsThis tv) (JsVar tv)) vars
162165
163−doCodegen :: CGConf -> Map Name LDecl -> [LDecl] -> (Text, CGStats)
164−doCodegen conf defs decls =
165− let xs = map (doCodegenDecl conf defs) decls
166− groupCGStats x y = CGStats { partialApplications = partialApplications x `Set.union` partialApplications y
167− , hiddenClasses = hiddenClasses x `Set.union` hiddenClasses y
168− , usedBigInt = usedBigInt x || usedBigInt y
169− }
170− in (T.intercalate "\n" $ map fst xs, foldl' groupCGStats emptyStats (map snd xs) )
171−
172−doCodegenDecl :: CGConf -> Map Name LDecl -> LDecl -> (Text, CGStats)
173−doCodegenDecl conf defs (LFun _ n args def) =
174− let (ast, stats) = cgFun conf defs n args def
175− in (T.concat [jsStmt2Text (JsComment $ T.pack $ show n), "\n", jsStmt2Text ast], stats)
176−doCodegenDecl conf defs (LConstructor n i sz) = ("", emptyStats)
166+
167+-- | Generate code for each declaration and collect stats.
168+-- LFunctions are turned into JS function declarations. They are
169+-- preceded by a comment that gives their name. Constructor
170+-- declarations are ignored.
171+doCodegen :: Map Name LDecl -> [LDecl] -> (Text, CGStats)
172+doCodegen defs = foldMap (doCodegenDecl defs)
173+ where
174+ doCodegenDecl :: Map Name LDecl -> LDecl -> (Text, CGStats)
175+ doCodegenDecl defs (LFun _ name args def) =
176+ let (ast, stats) = cgFun defs name args def
177+ fnComment = jsStmt2Text (JsComment $ T.pack $ show name)
178+ in (T.concat [fnComment, "\n", jsStmt2Text ast, "\n"], stats)
179+ doCodegenDecl defs (LConstructor n i sz) = ("", mempty)
180+
177181
178182seqJs :: [JsStmt] -> JsStmt
179183seqJs [] = JsEmpty
@@ -186,7 +190,6 @@ data CGBodyState = CGBodyState { defs :: Map Name LDecl
186190 , currentFnNameAndArgs :: (Text, [Text])
187191 , usedArgsTailCallOptim :: Set (Text, Text)
188192 , isTailRec :: Bool
189− , conf :: CGConf
190193 , usedITBig :: Bool
191194 , partialApps :: Set Partial
192195 , hiddenCls :: Set HiddenClass
@@ -212,10 +215,6 @@ addUsedArgsTailCallOptim :: Set (Text, Text) -> State CGBodyState ()
212215addUsedArgsTailCallOptim p =
213216 modify (\s -> s {usedArgsTailCallOptim = Set.union p (usedArgsTailCallOptim s) })
214217
215−getNewCGNames :: Int -> State CGBodyState [Text]
216−getNewCGNames n =
217− mapM (\_ -> getNewCGName) [1..n]
218−
219218getConsId :: Name -> State CGBodyState (Int, Int)
220219getConsId n =
221220 do
@@ -238,8 +237,8 @@ data BodyResTarget = ReturnBT
238237 | DecConstBT Text
239238 | GetExpBT
240239
241−cgFun :: CGConf -> Map Name LDecl -> Name -> [Name] -> LExp -> (JsStmt, CGStats)
242−cgFun cnf dfs n args def = do
240+cgFun :: Map Name LDecl -> Name -> [Name] -> LExp -> (JsStmt, CGStats)
241+cgFun dfs n args def = do
243242 let fnName = jsName n
244243 let argNames = map jsName args
245244 let ((decs, res),st) = runState
@@ -250,7 +249,6 @@ cgFun cnf dfs n args def = do
250249 , currentFnNameAndArgs = (fnName, argNames)
251250 , usedArgsTailCallOptim = Set.empty
252251 , isTailRec = False
253− , conf = cnf
254252 , usedITBig = False
255253 , partialApps = Set.empty
256254 , hiddenCls = Set.empty
@@ -264,16 +262,6 @@ cgFun cnf dfs n args def = do
264262 }
265263 (fn, state')
266264
267−getSwitchJs :: JsExpr -> [LAlt] -> JsExpr
268−getSwitchJs x alts =
269− if any conCase alts then JsArrayProj (JsInt 0) x
270− else if any constBigIntCase alts then JsForeign "%0.toString()" [x]
271− else x
272− where conCase (LConCase _ _ _ _) = True
273− conCase _ = False
274− constBigIntCase (LConstCase (BI _) _) = True
275− constBigIntCase _ = False
276−
277265addRT :: BodyResTarget -> JsExpr -> JsStmt
278266addRT ReturnBT x = JsReturn x
279267addRT (DecBT n) x = JsDecLet n x
@@ -345,15 +333,15 @@ cgBody rt expr =
345333 expr -> cgBody' rt expr
346334
347335cgBody' :: BodyResTarget -> LExp -> State CGBodyState ([JsStmt], JsStmt)
348−cgBody' rt (LV (Glob n)) =
336+cgBody' rt (LV n) =
349337 do
350338 argsFn <- getArgList n
351339 case argsFn of
352− Just a -> cgBody' rt (LApp False (LV (Glob n)) [])
340+ Just a -> cgBody' rt (LApp False (LV n) [])
353341 Nothing -> do
354342 n' <- cgName n
355343 pure $ ([], addRT rt n')
356−cgBody' rt (LApp tailcall (LV (Glob fn)) args) =
344+cgBody' rt (LApp tailcall (LV fn) args) =
357345 do
358346 let fname = jsName fn
359347 st <- get
@@ -372,10 +360,10 @@ cgBody' rt (LApp tailcall (LV (Glob fn)) args) =
372360 app <- formApp fn argVals
373361 pure (preDecs, addRT rt app)
374362
375−cgBody' rt (LForce (LLazyApp n args)) = cgBody rt (LApp False (LV (Glob n)) args)
363+cgBody' rt (LForce (LLazyApp n args)) = cgBody rt (LApp False (LV n) args)
376364cgBody' rt (LLazyApp n args) =
377365 do
378− (d,v) <- cgBody ReturnBT (LApp False (LV (Glob n)) args)
366+ (d,v) <- cgBody ReturnBT (LApp False (LV n) args)
379367 pure ([], addRT rt $ jsLazy $ jsStmt2Expr $ JsSeq (seqJs d) v)
380368cgBody' rt (LForce e) =
381369 do
src/IRTS/JavaScript/LangTransforms.hs+2−2
@@ -57,7 +57,7 @@ mapMapListKeys f (t:r) x = mapMapListKeys f r $ Map.adjust f t x
5757extractGlobs :: Map Name LDecl -> LDecl -> [Name]
5858extractGlobs defs (LConstructor _ _ _) = []
5959extractGlobs defs (LFun _ _ _ e) =
60− let f (LV (Glob x)) = Just x
60+ let f (LV x) = Just x
6161 f (LLazyApp x _) = Just x
6262 f _ = Nothing
6363 in [x | Just x <- map f $ universe e, Map.member x defs]
@@ -102,7 +102,7 @@ globlToCon x =
102102 transformBi (f x) x
103103 where
104104 f :: Map Name LDecl -> LExp -> LExp
105− f y x@(LV (Glob n)) =
105+ f y x@(LV n) =
106106 case Map.lookup n y of
107107 Just (LConstructor _ conId arity) -> LCon Nothing conId n []
108108 _ -> x
src/IRTS/JavaScript/PrimOp.hs+4
@@ -119,6 +119,10 @@ primDB =
119119 , item (LASHR (ITFixed IT16)) False PTAny $ JsForeign "%0 >> %1"
120120 , item (LASHR (ITFixed IT32)) False PTAny $ JsForeign "%0 >> %1|0"
121121 , item (LASHR (ITFixed IT64)) True PTAny $ JsForeign "%0.shiftRight(%1)"
122+ , item (LCompl (ITFixed IT8)) False PTAny $ JsForeign "~%0"
123+ , item (LCompl (ITFixed IT16)) False PTAny $ JsForeign "~%0"
124+ , item (LCompl (ITFixed IT32)) False PTAny $ JsForeign "~%0|0"
125+ , item (LCompl (ITFixed IT64)) True PTAny $ method "not"
122126 , item (LEq ATFloat) False PTBool $ binop "==="
123127 , item (LEq (ATInt ITNative)) False PTBool $ binop "==="
124128 , item (LEq (ATInt ITChar)) False PTBool $ binop "==="
src/IRTS/Lang.hs+17−17
@@ -5,7 +5,8 @@ Copyright :
55License : BSD3
66Maintainer : The Idris Community.
77-}
8−{-# LANGUAGE DeriveDataTypeable, DeriveFunctor, DeriveGeneric, PatternGuards #-}
8+{-# LANGUAGE DeriveDataTypeable, DeriveFunctor, DeriveGeneric, FlexibleContexts,
9+ PatternGuards #-}
910
1011module IRTS.Lang where
1112
@@ -27,7 +28,7 @@ data LVar = Loc Int | Glob Name
2728
2829-- ASSUMPTION: All variable bindings have unique names here
2930-- Constructors commented as lifted are not present in the LIR provided to the different backends.
30−data LExp = LV LVar
31+data LExp = LV Name
3132 | LApp Bool LExp [LExp] -- True = tail call
3233 | LLazyApp Name [LExp] -- True = tail call
3334 | LLazyExp LExp -- lifted out before compiling
@@ -35,7 +36,7 @@ data LExp = LV LVar
3536 | LLet Name LExp LExp -- name just for pretty printing
3637 | LLam [Name] LExp -- lambda, lifted out before compiling
3738 | LProj LExp Int -- projection
38− | LCon (Maybe LVar) -- Location to reallocate, if available
39+ | LCon (Maybe Name) -- Location to reallocate, if available
3940 Int Name [LExp]
4041 | LCase CaseType LExp [LAlt]
4142 | LConst Const
@@ -167,13 +168,13 @@ addFn fn d = do LS n i ds <- get
167168
168169lift :: [Name] -> LExp -> State LiftState LExp
169170lift env (LV v) = return (LV v) -- Lifting happens before these can exist...
170−lift env (LApp tc (LV (Glob n)) args) = do args' <- mapM (lift env) args
171− return (LApp tc (LV (Glob n)) args')
171+lift env (LApp tc (LV n) args) = do args' <- mapM (lift env) args
172+ return (LApp tc (LV n) args')
172173lift env (LApp tc f args) = do f' <- lift env f
173174 fn <- getNextName
174175 addFn fn (LFun [Inline] fn env f')
175176 args' <- mapM (lift env) args
176− return (LApp tc (LV (Glob fn)) (map (LV . Glob) env ++ args'))
177+ return (LApp tc (LV fn) (map LV env ++ args'))
177178lift env (LLazyApp n args) = do args' <- mapM (lift env) args
178179 return (LLazyApp n args')
179180lift env (LLazyExp (LConst c)) = return (LConst c)
@@ -183,7 +184,7 @@ lift env (LLazyExp e) = do e' <- lift env e
183184 let usedArgs = nub $ usedIn env e'
184185 fn <- getNextName
185186 addFn fn (LFun [NoInline] fn usedArgs e')
186− return (LLazyApp fn (map (LV . Glob) usedArgs))
187+ return (LLazyApp fn (map LV usedArgs))
187188lift env (LForce e) = do e' <- lift env e
188189 return (LForce e')
189190lift env (LLet n v e) = do v' <- lift env v
@@ -193,7 +194,7 @@ lift env (LLam args e) = do e' <- lift (env ++ args) e
193194 let usedArgs = nub $ usedIn env e'
194195 fn <- getNextName
195196 addFn fn (LFun [Inline] fn (usedArgs ++ args) e')
196− return (LApp False (LV (Glob fn)) (map (LV . Glob) usedArgs))
197+ return (LApp False (LV fn) (map LV usedArgs))
197198lift env (LProj t i) = do t' <- lift env t
198199 return (LProj t' i)
199200lift env (LCon loc i n args) = do args' <- mapM (lift env) args
@@ -228,11 +229,11 @@ allocUnique defs (n, LFun opts fn args e)
228229 -- Keep track of 'updatable' names in the state, i.e. names whose heap
229230 -- entry may be reused, along with the arity which was there
230231 findUp :: LExp -> State [(Name, Int)] LExp
231− findUp (LApp t (LV (Glob n)) as)
232+ findUp (LApp t (LV n) as)
232233 | Just (LConstructor _ i ar) <- lookupCtxtExact n defs,
233234 ar == length as
234235 = findUp (LCon Nothing i n as)
235− findUp (LV (Glob n))
236+ findUp (LV n)
236237 | Just (LConstructor _ i 0) <- lookupCtxtExact n defs
237238 = return $ LCon Nothing i n [] -- nullary cons are global, no need to update
238239 findUp (LApp t f as) = LApp t <$> findUp f <*> mapM findUp as
@@ -252,7 +253,7 @@ allocUnique defs (n, LFun opts fn args e)
252253 = LForeign t s <$> mapM (\ (t, e) -> do e' <- findUp e
253254 return (t, e')) es
254255 findUp (LOp o es) = LOp o <$> mapM findUp es
255− findUp (LCase Updatable e@(LV (Glob n)) as)
256+ findUp (LCase Updatable e@(LV n) as)
256257 = LCase Updatable e <$> mapM (doUpAlt n) as
257258 findUp (LCase t e as)
258259 = LCase t <$> findUp e <*> mapM findUpAlt as
@@ -276,7 +277,7 @@ allocUnique defs (n, LFun opts fn args e)
276277
277278 findVar _ [] i = return Nothing
278279 findVar acc ((n, l) : ns) i | l == i = do put (reverse acc ++ ns)
279− return (Just (Glob n))
280+ return (Just n)
280281 findVar acc (n : ns) i = findVar (n : acc) ns i
281282
282283
@@ -286,7 +287,7 @@ usedArg env n | n `elem` env = [n]
286287 | otherwise = []
287288
288289usedIn :: [Name] -> LExp -> [Name]
289−usedIn env (LV (Glob n)) = usedArg env n
290+usedIn env (LV n) = usedArg env n
290291usedIn env (LApp _ e args) = usedIn env e ++ concatMap (usedIn env) args
291292usedIn env (LLazyApp n args) = concatMap (usedIn env) args ++ usedArg env n
292293usedIn env (LLazyExp e) = usedIn env e
@@ -296,7 +297,7 @@ usedIn env (LLam ns e) = usedIn (env \\ ns) e
296297usedIn env (LCon v i n args) = let rest = concatMap (usedIn env) args in
297298 case v of
298299 Nothing -> rest
299− Just (Glob n) -> usedArg env n ++ rest
300+ Just n -> usedArg env n ++ rest
300301usedIn env (LProj t i) = usedIn env t
301302usedIn env (LCase up e alts) = usedIn env e ++ concatMap (usedInA env) alts
302303 where usedInA env (LConCase i n ns e) = usedIn env e
@@ -307,7 +308,7 @@ usedIn env (LOp f args) = concatMap (usedIn env) args
307308usedIn env _ = []
308309
309310lsubst :: Name -> LExp -> LExp -> LExp
310−lsubst n new (LV (Glob x)) | n == x = new
311+lsubst n new (LV x) | n == x = new
311312lsubst n new (LApp t e args) = let e' = lsubst n new e
312313 args' = map (lsubst n new) args in
313314 LApp t e' args'
@@ -332,8 +333,7 @@ lsubst n new tm = tm
332333
333334instance Show LExp where
334335 show e = show' [] "" e where
335− show' env ind (LV (Loc i)) = env!!i
336− show' env ind (LV (Glob n)) = show n
336+ show' env ind (LV n) = show n
337337
338338 show' env ind (LLazyApp e args)
339339 = show e ++ "|(" ++ showSep ", " (map (show' env ind) args) ++")"
src/IRTS/LangOpts.hs+9−9
@@ -35,14 +35,14 @@ nextN = do i <- get
3535doInline :: LDefs -> LDecl -> LDecl
3636doInline defs d@(LConstructor _ _ _) = d
3737doInline defs (LFun opts topn args exp)
38− = let res = evalState (inlineWith [topn] (map (\n -> (n, LV (Glob n))) args) exp) 0 in
38+ = let res = evalState (inlineWith [topn] (map (\n -> (n, LV n)) args) exp) 0 in
3939 LFun opts topn args res
4040 where
4141 inlineWith :: [Name] -> [(Name, LExp)] -> LExp -> State Int LExp
42− inlineWith done env var@(LV (Glob n))
43− = case lookup n env of
44− Just t -> return t
45− Nothing -> return var
42+ inlineWith done env var@(LV n)
43+ = case lookup n env of
44+ Just t -> return t
45+ Nothing -> return var
4646 inlineWith done env (LLazyApp n es) = LLazyApp n <$> (mapM (inlineWith done env) es)
4747 inlineWith done env (LForce e) = LForce <$> inlineWith done env e
4848 inlineWith done env (LLazyExp e) = LLazyExp <$> inlineWith done env e
@@ -51,12 +51,12 @@ doInline defs (LFun opts topn args exp)
5151 inlineWith done env (LLet n val sc)
5252 = do n' <- nextN
5353 LLet n' <$> inlineWith done env val <*>
54− inlineWith done ((n, LV (Glob n')) : env) sc
54+ inlineWith done ((n, LV n') : env) sc
5555 inlineWith done env (LLam args sc)
5656 = do ns' <- mapM (\n -> do n' <- nextN
5757 return (n, n')) args
5858 LLam (map snd ns') <$>
59− inlineWith done (map (\ (n,n') -> (n, LV (Glob n'))) ns' ++ env) sc
59+ inlineWith done (map (\ (n,n') -> (n, LV n')) ns' ++ env) sc
6060 inlineWith done env (LProj exp i) = LProj <$> inlineWith done env exp <*> return i
6161 inlineWith done env (LCon loc i n es)
6262 = LCon loc i n <$> mapM (inlineWith done env) es
@@ -64,7 +64,7 @@ doInline defs (LFun opts topn args exp)
6464 = LCase ty <$> inlineWith done env e <*> mapM (inlineWithAlt done env) alts
6565 inlineWith done env (LOp f es) = LOp f <$> mapM (inlineWith done env) es
6666 -- the interesting case!
67− inlineWith done env (LApp t (LV (Glob n)) es)
67+ inlineWith done env (LApp t (LV n) es)
6868 | n `notElem` done,
6969 [LFun opts _ args body] <- lookupCtxt n defs,
7070 Inline `elem` opts,
@@ -82,6 +82,6 @@ doInline defs (LFun opts topn args exp)
8282 = do ns' <- mapM (\n -> do n' <- nextN
8383 return (n, n')) es
8484 LConCase i n (map snd ns') <$>
85− inlineWith done (map (\ (n,n') -> (n, LV (Glob n'))) ns' ++ env) rhs
85+ inlineWith done (map (\ (n,n') -> (n, LV n')) ns' ++ env) rhs
8686 inlineWithAlt done env (LConstCase c e) = LConstCase c <$> inlineWith done env e
8787 inlineWithAlt done env (LDefaultCase e) = LDefaultCase <$> inlineWith done env e
src/IRTS/Portable.hs+1−1
@@ -5,7 +5,7 @@ Copyright :
55License : BSD3
66Maintainer : The Idris Community.
77-}
8−{-# LANGUAGE OverloadedStrings #-}
8+{-# LANGUAGE FlexibleInstances, OverloadedStrings, TypeSynonymInstances #-}
99module IRTS.Portable (writePortable) where
1010
1111import Idris.Core.CaseTree
src/IRTS/Simplified.hs+4−5
@@ -5,6 +5,7 @@ Copyright :
55License : BSD3
66Maintainer : The Idris Community.
77-}
8+{-# LANGUAGE FlexibleContexts #-}
89module IRTS.Simplified(simplifyDefs, SDecl(..), SExp(..), SAlt(..)) where
910
1011import Idris.Core.CaseTree
@@ -52,8 +53,7 @@ ldefs = do (l, h) <- get
5253-- The boolean parameter indicates whether the expression is at tail
5354-- call position.
5455simplify :: Bool -> DExp -> State (DDefs, Int) SExp
55−simplify tl (DV (Loc i)) = return (SV (Loc i))
56−simplify tl (DV (Glob x))
56+simplify tl (DV x)
5757 = do ctxt <- ldefs
5858 case lookupCtxtExact x ctxt of
5959 Just (DConstructor _ t 0) -> return $ SCon Nothing t x []
@@ -67,7 +67,7 @@ simplify tl (DLet n v e) = do v' <- simplify False v
6767 return (SLet (Glob n) v' e')
6868simplify tl (DUpdate n e) = do e' <- simplify False e
6969 return (SUpdate (Glob n) e')
70−simplify tl (DC loc i n args) = bindExprs args (SCon loc i n)
70+simplify tl (DC loc i n args) = bindExprs args (SCon (Glob <$> loc) i n)
7171simplify tl (DProj t i) = bindExpr t (\var -> SProj var i)
7272simplify tl (DCase up e alts)
7373 = do alts' <- mapM (sAlt tl) alts
@@ -96,12 +96,11 @@ bindExpr :: DExp -> (LVar -> SExp) -> State (DDefs, Int) SExp
9696bindExpr e f = bindExprM e (return . f)
9797
9898bindExprM :: DExp -> (LVar -> State (DDefs, Int) SExp) -> State (DDefs, Int) SExp
99−bindExprM (DV (Glob x)) f
99+bindExprM (DV x) f
100100 = do ctxt <- ldefs
101101 case lookupCtxtExact x ctxt of
102102 Just (DConstructor _ t 0) -> bindExprM (DC Nothing t x []) f
103103 _ -> f (Glob x)
104−bindExprM (DV var) f = f var
105104bindExprM e f =
106105 do e' <- simplify False e
107106 var <- freshVar
src/Idris/AbsSyntax.hs+9−1
@@ -6,7 +6,7 @@ License : BSD3
66Maintainer : The Idris Community.
77-}
88
9−{-# LANGUAGE DeriveFunctor, PatternGuards #-}
9+{-# LANGUAGE DeriveFunctor, FlexibleContexts, PatternGuards #-}
1010
1111module Idris.AbsSyntax(
1212 module Idris.AbsSyntax
@@ -1108,6 +1108,14 @@ allImportDirs = do i <- getIState
11081108 let optdirs = opt_importdirs (idris_options i)
11091109 return ("." : reverse optdirs)
11101110
1111+-- Like allImportDirs but the dirs that are a prefix of
1112+-- the files path first. This makes it look in the current
1113+-- package first.
1114+rankedImportDirs :: FilePath -> Idris [FilePath]
1115+rankedImportDirs fp = do ids <- allImportDirs
1116+ let (prefixes, rest) = partition (`isPrefixOf`fp) ids
1117+ return $ prefixes ++ rest
1118+
11111119addSourceDir :: FilePath -> Idris ()
11121120addSourceDir fp = do i <- getIState
11131121 let opts = idris_options i
src/Idris/AbsSyntaxTree.hs+10−1
@@ -6,7 +6,9 @@ License : BSD3
66Maintainer : The Idris Community.
77-}
88
9−{-# LANGUAGE DeriveDataTypeable, DeriveFunctor, DeriveGeneric, PatternGuards #-}
9+{-# LANGUAGE DeriveDataTypeable, DeriveFoldable, DeriveFunctor, DeriveGeneric,
10+ DeriveTraversable, FlexibleContexts, FlexibleInstances,
11+ MultiParamTypeClasses, PatternGuards, TypeSynonymInstances #-}
1012
1113module Idris.AbsSyntaxTree where
1214
@@ -1047,6 +1049,7 @@ mapPTermFC f g (PDoBlock dos) = PDoBlock (map mapPDoFC dos)
10471049 DoBindP (f fc) (mapPTermFC f g t1) (mapPTermFC f g t2) (map (\(l,r)-> (mapPTermFC f g l, mapPTermFC f g r)) alts)
10481050 mapPDoFC (DoLet fc n nfc t1 t2) = DoLet (f fc) n (g nfc) (mapPTermFC f g t1) (mapPTermFC f g t2)
10491051 mapPDoFC (DoLetP fc t1 t2) = DoLetP (f fc) (mapPTermFC f g t1) (mapPTermFC f g t2)
1052+ mapPDoFC (DoRewrite fc h) = DoRewrite (f fc) (mapPTermFC f g h)
10501053mapPTermFC f g (PIdiom fc t) = PIdiom (f fc) (mapPTermFC f g t)
10511054mapPTermFC f g (PMetavar fc n) = PMetavar (g fc) n
10521055mapPTermFC f g (PProof tacs) = PProof (map (fmap (mapPTermFC f g)) tacs)
@@ -1171,6 +1174,7 @@ data PDo' t = DoExp FC t
11711174 | DoBindP FC t t [(t,t)]
11721175 | DoLet FC Name FC t t -- ^ second FC is precise name location
11731176 | DoLetP FC t t
1177+ | DoRewrite FC t -- rewrite in do block
11741178 deriving (Eq, Ord, Functor, Data, Generic, Typeable)
11751179{-!
11761180deriving instance Binary PDo'
@@ -1182,6 +1186,7 @@ instance Sized a => Sized (PDo' a) where
11821186 size (DoBindP fc l r alts) = 1 + size fc + size l + size r + size alts
11831187 size (DoLet fc nm nfc l r) = 1 + size fc + size nm + size l + size r
11841188 size (DoLetP fc l r) = 1 + size fc + size l + size r
1189+ size (DoRewrite fc h) = 1 + size fc + size h
11851190
11861191type PDo = PDo' PTerm
11871192
@@ -1277,6 +1282,7 @@ highestFC (PDoBlock lines) =
12771282 getDoFC (DoBindP fc l r alts) = fc
12781283 getDoFC (DoLet fc nm nfc l r) = fc
12791284 getDoFC (DoLetP fc l r) = fc
1285+ getDoFC (DoRewrite fc h) = fc
12801286
12811287highestFC (PIdiom fc _) = Just fc
12821288highestFC (PMetavar fc _) = Just fc
@@ -1951,6 +1957,9 @@ pprintPTerm ppo bnd docArgs infixes = prettySe (ppopt_depth ppo) startPrec bnd
19511957 ppdo bnd (DoLetP _ _ _ : dos) = -- ok because never made by delab
19521958 text "no pretty printer for pattern-matching do binding" :
19531959 ppdo bnd dos
1960+ ppdo bnd (DoRewrite _ _ : dos) = -- ok because never made by delab
1961+ text "no pretty printer for pattern-matching do binding" :
1962+ ppdo bnd dos
19541963 ppdo _ [] = []
19551964 prettySe d p bnd (PCoerced t) = prettySe d p bnd t
19561965 prettySe d p bnd (PElabError s) = pretty s
src/Idris/Apropos.hs+1
@@ -5,6 +5,7 @@ Copyright :
55License : BSD3
66Maintainer : The Idris Community.
77-}
8+{-# LANGUAGE FlexibleInstances #-}
89module Idris.Apropos (apropos, aproposModules) where
910
1011import Idris.AbsSyntax
src/Idris/CaseSplit.hs+1−1
@@ -17,7 +17,7 @@ Always take the "more specific" argument when there is a discrepancy, i.e.
1717names over '_', patterns over names, etc.
1818-}
1919
20−{-# LANGUAGE PatternGuards #-}
20+{-# LANGUAGE FlexibleContexts, PatternGuards #-}
2121
2222module Idris.CaseSplit(
2323 splitOnLine, replaceSplits
src/Idris/Chaser.hs+2
@@ -5,6 +5,8 @@ Copyright :
55License : BSD3
66Maintainer : The Idris Community.
77-}
8+{-# LANGUAGE FlexibleContexts #-}
9+
810module Idris.Chaser(
911 buildTree, getImports
1012 , getModuleFiles
src/Idris/CmdOptions.hs−2
@@ -25,9 +25,7 @@ import Control.Monad.Trans.Except (throwE)
2525import Control.Monad.Trans.Reader (ask)
2626import Data.Char
2727import Data.Maybe
28−#if MIN_VERSION_optparse_applicative(0,13,0)
2928import Data.Monoid ((<>))
30−#endif
3129import Options.Applicative
3230import Options.Applicative.Arrows
3331import Options.Applicative.Types (ReadM(..))
src/Idris/Core/Binary.hs+6−2
@@ -5,6 +5,8 @@ Copyright :
55License : BSD3
66Maintainer : The Idris Community.
77-}
8+{-# LANGUAGE FlexibleInstances #-}
9+
810{-# OPTIONS_GHC -fwarn-incomplete-patterns #-}
911module Idris.Core.Binary where
1012
@@ -14,6 +16,8 @@ import Control.Applicative ((<$>), (<*>))
1416import Control.DeepSeq (($!!))
1517import Control.Monad (liftM2)
1618import Data.Binary
19+import Data.Binary.Get
20+import Data.Binary.Put
1721import qualified Data.Text as T
1822import qualified Data.Text.Encoding as E
1923import Data.Vector.Binary
@@ -398,7 +402,7 @@ instance Binary Const where
398402 BI x1 -> do putWord8 1
399403 put x1
400404 Fl x1 -> do putWord8 2
401− put x1
405+ putDoublele x1
402406 Ch x1 -> do putWord8 3
403407 put x1
404408 Str x1 -> do putWord8 4
@@ -425,7 +429,7 @@ instance Binary Const where
425429 return (I x1)
426430 1 -> do x1 <- get
427431 return (BI x1)
428− 2 -> do x1 <- get
432+ 2 -> do x1 <- getDoublele
429433 return (Fl x1)
430434 3 -> do x1 <- get
431435 return (Ch x1)
src/Idris/Core/CaseTree.hs+3−2
@@ -18,8 +18,9 @@ allows casing on arbitrary terms, here we choose to maintain the distinction
1818in order to allow for better optimisation opportunities.
1919
2020-}
21−{-# LANGUAGE DeriveFunctor, DeriveGeneric, PatternGuards,
22− TypeSynonymInstances #-}
21+
22+{-# LANGUAGE DeriveFunctor, DeriveGeneric, FlexibleContexts, FlexibleInstances,
23+ PatternGuards, TypeSynonymInstances #-}
2324
2425module Idris.Core.CaseTree (
2526 CaseDef(..), SC, SC'(..), CaseAlt, CaseAlt'(..), ErasureInfo
src/Idris/Core/DeepSeq.hs+4−1
@@ -5,7 +5,8 @@ Copyright :
55License : BSD3
66Maintainer : The Idris Community.
77-}
8−{-# LANGUAGE BangPatterns, ViewPatterns #-}
8+{-# LANGUAGE BangPatterns, CPP, FlexibleInstances, TypeSynonymInstances,
9+ ViewPatterns #-}
910{-# OPTIONS_GHC -fwarn-incomplete-patterns #-}
1011
1112module Idris.Core.DeepSeq where
@@ -27,7 +28,9 @@ forceDefCtxt (force -> !ctxt) = ctxt
2728
2829instance NFData NameOutput
2930instance NFData TextFormatting
31+#if !(MIN_VERSION_base(4,10,0))
3032instance NFData Ordering
33+#endif
3134instance NFData OutputAnnotation
3235instance NFData SpecialName
3336instance NFData Universe
src/Idris/Core/ProofState.hs+2−1
@@ -10,7 +10,8 @@ proofs, and some high level commands for introducing new theorems,
1010evaluation/checking inside the proof system, etc.
1111-}
1212
13−{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, PatternGuards #-}
13+{-# LANGUAGE FlexibleContexts, FlexibleInstances, MultiParamTypeClasses,
14+ PatternGuards #-}
1415module Idris.Core.ProofState(
1516 ProofState(..), newProof, envAtFocus, goalAtFocus
1617 , Tactic(..), Goal(..), processTactic, nowElaboratingPS
src/Idris/Core/TT.hs+4−2
@@ -22,8 +22,10 @@ TT is the core language of Idris. The language has:
2222 * We have a simple collection of tactics which we use to elaborate source
2323 programs with implicit syntax into fully explicit terms.
2424-}
25−{-# LANGUAGE DeriveDataTypeable, DeriveFunctor, DeriveGeneric, FlexibleContexts,
26− FunctionalDependencies, MultiParamTypeClasses, PatternGuards #-}
25+{-# LANGUAGE DeriveDataTypeable, DeriveFoldable, DeriveFunctor, DeriveGeneric,
26+ DeriveTraversable, FlexibleContexts, FlexibleInstances,
27+ FunctionalDependencies, MultiParamTypeClasses, PatternGuards,
28+ TypeSynonymInstances #-}
2729{-# OPTIONS_GHC -fwarn-incomplete-patterns #-}
2830module Idris.Core.TT(
2931 AppStatus(..), ArithTy(..), Binder(..), Const(..), Ctxt(..)
src/Idris/Core/Typecheck.hs+2−2
@@ -6,8 +6,8 @@ License : BSD3
66Maintainer : The Idris Community.
77-}
88
9−{-# LANGUAGE DeriveFunctor, FlexibleInstances, MultiParamTypeClasses,
10− PatternGuards #-}
9+{-# LANGUAGE DeriveFunctor, FlexibleContexts, FlexibleInstances,
10+ MultiParamTypeClasses, PatternGuards #-}
1111
1212module Idris.Core.Typecheck where
1313
src/Idris/Core/Unify.hs+1−1
@@ -11,7 +11,7 @@ Returns a list of hole names paired with the term which solves them, and
1111a list of things which need to be injective.
1212
1313-}
14−{-# LANGUAGE PatternGuards #-}
14+{-# LANGUAGE FlexibleContexts, PatternGuards #-}
1515
1616module Idris.Core.Unify(
1717 match_unify, unify
src/Idris/Core/WHNF.hs+1−1
@@ -6,7 +6,7 @@ License : BSD3
66Maintainer : The Idris Community.
77-}
88
9−{-# LANGUAGE PatternGuards #-}
9+{-# LANGUAGE FlexibleContexts, PatternGuards #-}
1010{-# OPTIONS_GHC -fwarn-incomplete-patterns #-}
1111module Idris.Core.WHNF(whnf, whnfArgs, WEnv) where
1212
src/Idris/Coverage.hs+1−1
@@ -5,7 +5,7 @@ Copyright :
55License : BSD3
66Maintainer : The Idris Community.
77-}
8−{-# LANGUAGE PatternGuards #-}
8+{-# LANGUAGE FlexibleContexts, PatternGuards #-}
99module Idris.Coverage(genClauses, validCoverageCase, recoverableCoverage,
1010 mkPatTm) where
1111
src/Idris/DSL.hs+2
@@ -109,6 +109,8 @@ expandSugar dsl (PDoBlock ds)
109109 = PLet fc n nfc ty tm (block b rest)
110110 block b (DoLetP fc p tm : rest)
111111 = PCase fc tm [(p, block b rest)]
112+ block b (DoRewrite fc h : rest)
113+ = PRewrite fc Nothing h (block b rest) Nothing
112114 block b (DoExp fc tm : rest)
113115 = PApp fc b
114116 [pexp tm,
src/Idris/DataOpts.hs+1−1
@@ -5,7 +5,7 @@ Copyright :
55License : BSD3
66Maintainer : The Idris Community.
77-}
8−{-# LANGUAGE PatternGuards #-}
8+{-# LANGUAGE FlexibleInstances, PatternGuards #-}
99
1010module Idris.DataOpts(applyOpts) where
1111
src/Idris/DeepSeq.hs−14
@@ -29,20 +29,6 @@ import Control.DeepSeq
2929import Network.Socket (PortNumber)
3030
3131-- These types don't have Generic instances
32−instance NFData CT.Options where
33− rnf (CT.Options x1 x2 x3 x4) = rnf x1 `seq` rnf x2 `seq` rnf x3 `seq` rnf x4 `seq` ()
34−
35−instance NFData CT.ListType where
36− rnf (CT.Bullet c) = rnf c `seq` ()
37− rnf (CT.Numbered nw i) = rnf nw `seq` rnf i `seq` ()
38−
39−instance NFData CT.CodeAttr where
40− rnf (CT.CodeAttr a b) = rnf a `seq` rnf b `seq` ()
41−
42−instance NFData CT.NumWrapper where
43− rnf CT.PeriodFollowing = ()
44− rnf CT.ParenFollowing = ()
45−
4632instance NFData DynamicLib where
4733 rnf (Lib x _) = rnf x `seq` ()
4834
src/Idris/Docstrings.hs+2−1
@@ -6,7 +6,8 @@ License : BSD3
66Maintainer : The Idris Community.
77-}
88
9−{-# LANGUAGE DeriveFunctor, DeriveGeneric, ScopedTypeVariables #-}
9+{-# LANGUAGE DeriveFoldable, DeriveFunctor, DeriveGeneric, DeriveTraversable,
10+ ScopedTypeVariables #-}
1011{-# OPTIONS_GHC -fwarn-incomplete-patterns #-}
1112module Idris.Docstrings (
1213 Docstring(..), Block(..), Inline(..), parseDocstring, renderDocstring
src/Idris/Elab/Quasiquote.hs+1
@@ -75,6 +75,7 @@ extractDoUnquotes d (DoLet fc n nfc v b)
7575 (b', ex2) <- extractUnquotes d b
7676 return (DoLet fc n nfc v' b', ex1 ++ ex2)
7777extractDoUnquotes d (DoLetP fc t t') = fail "Pattern-matching lets cannot be quasiquoted"
78+extractDoUnquotes d (DoRewrite fc h) = fail "Rewrites in Do block cannot be quasiquoted"
7879
7980
8081extractUnquotes :: Int -> PTerm -> Elab' aux (PTerm, [(Name, PTerm)])
src/Idris/Elab/Term.hs+4−2
@@ -2659,9 +2659,11 @@ withErrorReflection x = idrisCatch x (\ e -> handle e >>= ierror)
26592659 concat (intersperse ", " (map show handlers))
26602660 let reports = map (\n -> RApp (Var n) (reflectErr err)) handlers
26612661
2662− -- Typecheck error handlers - if this fails, then something else was wrong earlier!
2662+ -- Typecheck error handlers - if this fails, most
2663+ -- likely something which is needed by it has not
2664+ -- been imported, so keep the original error.
26632665 handlers <- case mapM (check (tt_ctxt ist) []) reports of
2664− Error e -> ierror $ ReflectionFailed "Type error while constructing reflected error" e
2666+ Error _ -> return [] -- ierror $ ReflectionFailed "Type error while constructing reflected error" e
26652667 OK hs -> return hs
26662668
26672669 -- Normalize error handler terms to produce the new messages
src/Idris/Elab/Utils.hs+7−6
@@ -5,7 +5,7 @@ Copyright :
55License : BSD3
66Maintainer : The Idris Community.
77-}
8−{-# LANGUAGE PatternGuards #-}
8+{-# LANGUAGE FlexibleContexts, PatternGuards #-}
99module Idris.Elab.Utils where
1010
1111import Idris.AbsSyntax
@@ -449,9 +449,12 @@ displayWarnings est
449449 = mapM_ displayImpWarning (implicit_warnings est)
450450 where
451451 displayImpWarning :: (FC, Name) -> Idris ()
452− displayImpWarning (fc, n) =
453− iputStrLn $ show fc ++ ":WARNING: " ++ show (nsroot n) ++ " is bound as an implicit\n"
454− ++ "\tDid you mean to refer to " ++ show n ++ "?"
452+ displayImpWarning (fc, n) = do
453+ ist <- getIState
454+ let msg = show (nsroot n)
455+ ++ " is bound as an implicit\n"
456+ ++ "\tDid you mean to refer to " ++ show n ++ "?"
457+ iWarn fc (pprintErr ist (Msg msg))
455458
456459propagateParams :: IState -> [Name] -> Type -> [Name] -> PTerm -> PTerm
457460propagateParams i ps t bound tm@(PApp _ (PRef fc hls n) args)
@@ -767,5 +770,3 @@ isPlausible ist var env n ty
767770 collectConstraints env tcs t
768771 | (V i, _) <- unApply t = (Just (env !! i), tcs)
769772 | otherwise = (Nothing, tcs)
770−
771−
src/Idris/Erasure.hs+120−12
@@ -1,6 +1,6 @@
11{-|
22Module : Idris.Erasure
3−Description : Utilities to erase irrelevant stuff.
3+Description : Utilities to erase stuff not necessary for runtime.
44Copyright :
55License : BSD3
66Maintainer : The Idris Community.
@@ -145,10 +145,54 @@ performUsageAnalysis startNames = do
145145 fmt n rs = show n ++ " from " ++ intercalate ", " [show rn ++ " arg# " ++ show ri | (rn,ri) <- rs]
146146 warn = logErasure 0
147147
148+type Constraint = (Cond, DepSet)
149+
148150-- | Find the minimal consistent usage by forward chaining.
151+--
152+-- We use a cleverer implementation that:
153+-- 1. First transforms Deps into a collection of numbered constraints
154+-- 2. For each node, we remember the numbers of constraints
155+-- that contain that node among their preconditions.
156+-- 3. When performing forward chaining, we perform unit propagation
157+-- only on the relevant constraints, not all constraints.
158+--
159+-- Typical numbers from the current version of Blodwen:
160+-- * 56 iterations until fixpoint
161+-- * out of 20k constraints total, 5-1000 are relevant per iteration
149162minimalUsage :: Deps -> (Deps, (Set Name, UseMap))
150−minimalUsage = second gather . forwardChain
163+minimalUsage deps
164+ = fromNumbered *** gather
165+ $ forwardChain (index numbered) seedDeps seedDeps numbered
151166 where
167+ numbered = toNumbered deps
168+
169+ -- The initial solution. Consists of nodes that are
170+ -- reachable immediately, without any preconditions.
171+ seedDeps :: DepSet
172+ seedDeps = M.unionsWith S.union [ds | (cond, ds) <- IM.elems numbered, S.null cond]
173+
174+ toNumbered :: Deps -> IntMap Constraint
175+ toNumbered = IM.fromList . zip [0..] . M.toList
176+
177+ fromNumbered :: IntMap Constraint -> Deps
178+ fromNumbered = IM.foldr addConstraint M.empty
179+ where
180+ addConstraint (ns, vs) = M.insertWith (M.unionWith S.union) ns vs
181+
182+ -- Build an index that maps every node to the set of constraints
183+ -- where the node appears among the preconditions.
184+ index :: IntMap Constraint -> Map Node IntSet
185+ index = IM.foldrWithKey (
186+ -- for each clause (i. ns --> _ds)
187+ \i (ns, _ds) ix -> foldr (
188+ -- for each node `n` in `ns`
189+ \n ix' -> M.insertWith IS.union n (IS.singleton i) ix'
190+ ) ix (S.toList ns)
191+ ) M.empty
192+
193+ -- Convert a solution of constraints into:
194+ -- 1. the list of names used in the program
195+ -- 2. the list of arguments used, together with their reasons
152196 gather :: DepSet -> (Set Name, UseMap)
153197 gather = foldr ins (S.empty, M.empty) . M.toList
154198 where
@@ -156,17 +200,81 @@ minimalUsage = second gather . forwardChain
156200 ins ((n, Result), rs) (ns, umap) = (S.insert n ns, umap)
157201 ins ((n, Arg i ), rs) (ns, umap) = (ns, M.insertWith (IM.unionWith S.union) n (IM.singleton i rs) umap)
158202
159−forwardChain :: Deps -> (Deps, DepSet)
160−forwardChain deps
161− | Just trivials <- M.lookup S.empty deps
162− = (M.unionWith S.union trivials)
163− `second` forwardChain (remove trivials . M.delete S.empty $ deps)
164− | otherwise = (deps, M.empty)
203+-- | In each iteration, we find the set of nodes immediately reachable
204+-- from the current set of constraints, and then reduce the set of constraints
205+-- based on that knowledge.
206+--
207+-- In the implementation, this is phase-shifted. We first reduce the set
208+-- of constraints, given the newly reachable nodes from the previous iteration,
209+-- and then compute the set of currently reachable nodes.
210+-- Then we decide whether to iterate further.
211+forwardChain
212+ :: Map Node IntSet -- ^ node index
213+ -> DepSet -- ^ all reachable nodes found so far
214+ -> DepSet -- ^ nodes reached in the previous iteration
215+ -> IntMap Constraint -- ^ numbered constraints
216+ -> (IntMap Constraint, DepSet)
217+forwardChain index solution previouslyNew constrs
218+ -- no newly reachable nodes, fixed point has been reached
219+ | M.null currentlyNew
220+ = (constrs, solution)
221+
222+ -- some newly reachable nodes, iterate more
223+ | otherwise
224+ = forwardChain index
225+ (M.unionWith S.union solution currentlyNew)
226+ currentlyNew
227+ constrs'
165228 where
166− -- Remove the given nodes from the Deps entirely,
167− -- possibly creating new empty Conds.
168− remove :: DepSet -> Deps -> Deps
169− remove ds = M.mapKeysWith (M.unionWith S.union) (S.\\ M.keysSet ds)
229+ -- which constraints could give new results,
230+ -- given that `previouslyNew` has been derived in the last iteration
231+ affectedIxs = IS.unions [
232+ M.findWithDefault IS.empty n index
233+ | n <- M.keys previouslyNew
234+ ]
235+
236+ -- traverse all (potentially) affected constraints, building:
237+ -- 1. a set of newly reached nodes
238+ -- 2. updated set of constraints where the previously
239+ -- reached nodes have been removed
240+ (currentlyNew, constrs')
241+ = IS.foldr
242+ (reduceConstraint $ M.keysSet previouslyNew)
243+ (M.empty, constrs)
244+ affectedIxs
245+
246+ -- Update the pair (newly reached nodes, numbered constraint set)
247+ -- by reducing the constraint with the given number.
248+ reduceConstraint
249+ :: Set Node -- ^ nodes reached in the previous iteration
250+ -> Int -- ^ constraint number
251+ -> (DepSet, IntMap (Cond, DepSet))
252+ -> (DepSet, IntMap (Cond, DepSet))
253+ reduceConstraint previouslyNew i (news, constrs)
254+ | Just (cond, deps) <- IM.lookup i constrs
255+ = case cond S.\\ previouslyNew of
256+ cond'
257+ -- This constraint's set of preconditions has shrunk
258+ -- to the empty set. We can add its RHS to the set of newly
259+ -- reached nodes, and remove the constraint altogether.
260+ | S.null cond'
261+ -> (M.unionWith S.union news deps, IM.delete i constrs)
262+
263+ -- This constraint's set of preconditions has shrunk
264+ -- so we need to overwrite the numbered slot
265+ -- with the updated constraint.
266+ | S.size cond' < S.size cond
267+ -> (news, IM.insert i (cond', deps) constrs)
268+
269+ -- This constraint's set of preconditions hasn't changed
270+ -- so we do not do anything about it.
271+ | otherwise
272+ -> (news, constrs)
273+
274+ -- Constraint number present in index but not found
275+ -- among the constraints. This happens more and more frequently
276+ -- as we delete constraints from the set.
277+ | otherwise = (news, constrs)
170278
171279-- | Build the dependency graph, starting the depth-first search from
172280-- a list of Names.
src/Idris/Error.hs+1
@@ -138,6 +138,7 @@ warnDisamb ist (PDoBlock steps) = mapM_ wStep steps
138138 mapM_ (\(x,y) -> warnDisamb ist x >> warnDisamb ist y) cs
139139 wStep (DoLet _ _ _ x y) = warnDisamb ist x >> warnDisamb ist y
140140 wStep (DoLetP _ x y) = warnDisamb ist x >> warnDisamb ist y
141+ wStep (DoRewrite _ h) = warnDisamb ist h
141142warnDisamb ist (PIdiom _ x) = warnDisamb ist x
142143warnDisamb ist (PMetavar _ _) = return ()
143144warnDisamb ist (PProof tacs) = mapM_ (Foldable.mapM_ (warnDisamb ist)) tacs
src/Idris/IBC.hs+24−24
@@ -5,7 +5,7 @@ Copyright :
55License : BSD3
66Maintainer : The Idris Community.
77-}
8−{-# LANGUAGE TypeSynonymInstances #-}
8+{-# LANGUAGE FlexibleInstances, TypeSynonymInstances #-}
99{-# OPTIONS_GHC -fwarn-incomplete-patterns #-}
1010
1111module Idris.IBC (loadIBC, loadPkgIndex,
@@ -48,7 +48,7 @@ import System.Directory
4848import System.FilePath
4949
5050ibcVersion :: Word16
51−ibcVersion = 160
51+ibcVersion = 162
5252
5353-- | When IBC is being loaded - we'll load different things (and omit
5454-- different structures/definitions) depending on which phase we're in.
@@ -146,7 +146,7 @@ loadIBC reexport phase fp
146146 Right archive -> do
147147 if fullLoad
148148 then process reexport phase archive fp
149− else unhide phase archive
149+ else unhide phase fp archive
150150 addImported reexport fp
151151
152152-- | Load an entire package from its index file
@@ -359,9 +359,9 @@ getEntry alt f a = case findEntryByPath f a of
359359 Nothing -> return alt
360360 Just e -> return $! (force . decode . fromEntry) e
361361
362−unhide :: IBCPhase -> Archive -> Idris ()
363−unhide phase ar = do
364− processImports True phase ar
362+unhide :: IBCPhase -> FilePath -> Archive -> Idris ()
363+unhide phase fp ar = do
364+ processImports True phase fp ar
365365 processAccess True phase ar
366366
367367process :: Bool -- ^ Reexporting
@@ -393,7 +393,7 @@ process reexp phase archive fn = do
393393 when srcok $ timestampOlder source fn
394394 processImportDirs archive
395395 processSourceDirs archive
396− processImports reexp phase archive
396+ processImports reexp phase fn archive
397397 processImplicits archive
398398 processInfix archive
399399 processStatics archive
@@ -405,7 +405,7 @@ process reexp phase archive fn = do
405405 processOptimise archive
406406 processSyntax archive
407407 processKeywords archive
408− processObjectFiles archive
408+ processObjectFiles fn archive
409409 processLibs archive
410410 processCodegenFlags archive
411411 processDynamicLibs archive
@@ -509,28 +509,21 @@ processSourceDirs ar = do
509509 fs <- getEntry [] "ibc_sourcedirs" ar
510510 mapM_ addSourceDir fs
511511
512−processImports :: Bool -> IBCPhase -> Archive -> Idris ()
513−processImports reexp phase ar = do
512+processImports :: Bool -> IBCPhase -> FilePath -> Archive -> Idris ()
513+processImports reexp phase fname ar = do
514514 fs <- getEntry [] "ibc_imports" ar
515515 mapM_ (\(re, f) -> do
516516 i <- getIState
517517 ibcsd <- valIBCSubDir i
518− ids <- allImportDirs
519− fp <- findImport ids ibcsd f
520−-- if (f `elem` imported i)
521−-- then logLvl 1 $ "Already read " ++ f
518+ ids <- rankedImportDirs fname
522519 putIState (i { imported = f : imported i })
523520 let phase' = case phase of
524521 IBC_REPL _ -> IBC_REPL False
525522 p -> p
523+ fp <- findIBC ids ibcsd f
526524 case fp of
527− LIDR fn -> do
528− logIBC 2 $ "Failed at " ++ fn
529− ifail "Must be an ibc"
530− IDR fn -> do
531− logIBC 2 $ "Failed at " ++ fn
532− ifail "Must be an ibc"
533− IBC fn src -> loadIBC (reexp && re) phase' fn) fs
525+ Nothing -> do logIBC 2 $ "Failed to load ibc " ++ f
526+ Just fn -> do loadIBC (reexp && re) phase' fn) fs
534527
535528processImplicits :: Archive -> Idris ()
536529processImplicits ar = do
@@ -605,11 +598,11 @@ processKeywords ar = do
605598 k <- getEntry [] "ibc_keywords" ar
606599 updateIState (\i -> i { syntax_keywords = k ++ syntax_keywords i })
607600
608−processObjectFiles :: Archive -> Idris ()
609−processObjectFiles ar = do
601+processObjectFiles :: FilePath -> Archive -> Idris ()
602+processObjectFiles fn ar = do
610603 os <- getEntry [] "ibc_objs" ar
611604 mapM_ (\ (cg, obj) -> do
612− dirs <- allImportDirs
605+ dirs <- rankedImportDirs fn
613606 o <- runIO $ findInPath dirs obj
614607 addObjectFile cg o) os
615608
@@ -2293,6 +2286,9 @@ instance (Binary t) => Binary (PDo' t) where
22932286 put x1
22942287 put x2
22952288 put x3
2289+ DoRewrite x1 x2 -> do putWord8 5
2290+ put x1
2291+ put x2
22962292 get
22972293 = do i <- getWord8
22982294 case i of
@@ -2319,6 +2315,10 @@ instance (Binary t) => Binary (PDo' t) where
23192315 x2 <- get
23202316 x3 <- get
23212317 return (DoLetP x1 x2 x3)
2318+ 5 -> do
2319+ x1 <- get
2320+ x2 <- get
2321+ return (DoRewrite x1 x2)
23222322 _ -> error "Corrupted binary data for PDo'"
23232323
23242324
src/Idris/IdrisDoc.hs+1
@@ -344,6 +344,7 @@ extractPDo (DoBindP _ p1 p2 ps) = let (ps1, ps2) = unzip ps
344344 in concatMap extract (p1 : p2 : ps')
345345extractPDo (DoLet _ n _ p1 p2) = n : concatMap extract [p1, p2]
346346extractPDo (DoLetP _ p1 p2) = concatMap extract [p1, p2]
347+extractPDo (DoRewrite _ p) = extract p
347348
348349-- | Helper function for extractPTermNames
349350extractPTactic :: PTactic -> [Name]
src/Idris/Imports.hs+13−1
@@ -6,13 +6,14 @@ License : BSD3
66Maintainer : The Idris Community.
77-}
88module Idris.Imports(
9− IFileType(..), findImport, findInPath, findPkgIndex
9+ IFileType(..), findIBC, findImport, findInPath, findPkgIndex
1010 , ibcPathNoFallback, installedPackages, pkgIndex
1111 ) where
1212
1313import Idris.AbsSyntax
1414import Idris.Core.TT
1515import Idris.Error
16+import Idris.Output
1617import IRTS.System (getIdrisLibDir)
1718
1819import Control.Applicative ((<$>))
@@ -77,6 +78,17 @@ findImport (d:ds) ibcsd fp = do let fp_full = d </> fp
7778 then return isrc
7879 else findImport ds ibcsd fp
7980
81+-- Only look for IBCs and not source
82+findIBC :: [FilePath] -> FilePath -> FilePath -> Idris (Maybe FilePath)
83+findIBC [] _ fp = return Nothing
84+findIBC (d:ds) ibcsd fp = do let fp_full = d </> fp
85+ ibcp <- runIO $ ibcPathWithFallback ibcsd fp_full
86+ ibc <- runIO $ doesFileExist' ibcp
87+ if ibc
88+ then return $ Just ibcp
89+ else findIBC ds ibcsd fp
90+
91+
8092-- find a specific filename somewhere in a path
8193
8294findInPath :: [FilePath] -> FilePath -> IO FilePath
src/Idris/Output.hs+1
@@ -6,6 +6,7 @@ License : BSD3
66Maintainer : The Idris Community.
77-}
88
9+{-# LANGUAGE FlexibleInstances #-}
910{-# OPTIONS_GHC -fwarn-incomplete-patterns #-}
1011
1112module Idris.Output where
src/Idris/Package/Parser.hs+1−8
@@ -5,10 +5,7 @@ Copyright :
55License : BSD3
66Maintainer : The Idris Community.
77-}
8−{-# LANGUAGE CPP, ConstraintKinds #-}
9−#if !(MIN_VERSION_base(4,8,0))
10−{-# LANGUAGE OverlappingInstances #-}
11−#endif
8+{-# LANGUAGE CPP, ConstraintKinds, FlexibleInstances, TypeSynonymInstances #-}
129module Idris.Package.Parser where
1310
1411import Idris.AbsSyntaxTree
@@ -50,11 +47,7 @@ instance {-# OVERLAPPING #-} DeltaParsing PParser where
5047 {-# INLINE restOfLine #-}
5148#endif
5249
53−#if MIN_VERSION_base(4,8,0)
5450instance {-# OVERLAPPING #-} TokenParsing PParser where
55−#else
56−instance TokenParsing PParser where
57−#endif
5851 someSpace = many (simpleWhiteSpace <|> singleLineComment <|> multiLineComment) *> pure ()
5952
6053
src/Idris/Parser.hs+9−4
@@ -5,7 +5,8 @@ Copyright :
55License : BSD3
66Maintainer : The Idris Community.
77-}
8−{-# LANGUAGE ConstraintKinds, GeneralizedNewtypeDeriving, PatternGuards #-}
8+{-# LANGUAGE ConstraintKinds, FlexibleContexts, GeneralizedNewtypeDeriving,
9+ PatternGuards #-}
910{-# OPTIONS_GHC -O0 #-}
1011module Idris.Parser(module Idris.Parser,
1112 module Idris.Parser.Expr,
@@ -1569,7 +1570,8 @@ parseImports fname input
15691570 [ImportInfo],
15701571 Maybe Delta),
15711572 [(FC, OutputAnnotation)], IState)
1572− imports = do whiteSpace
1573+ imports = do optional shebang
1574+ whiteSpace
15731575 (mdoc, mname, annots) <- moduleHeader
15741576 ps_exp <- many import_
15751577 mrk <- mark
@@ -1594,6 +1596,9 @@ parseImports fname input
15941596 (fc, AnnNamespace ns (Just path)) : addPath annots path
15951597 addPath (annot:annots) path = annot : addPath annots path
15961598
1599+ shebang :: IdrisParser ()
1600+ shebang = string "#!" *> many (satisfy $ not . isEol) *> eol *> pure ()
1601+
15971602-- | There should be a better way of doing this...
15981603findFC :: Doc -> (FC, String)
15991604findFC x = let s = show (plain x) in findFC' s
@@ -1659,7 +1664,7 @@ loadModule' f phase
16591664 = do i <- getIState
16601665 let file = takeWhile (/= ' ') f
16611666 ibcsd <- valIBCSubDir i
1662− ids <- allImportDirs
1667+ ids <- rankedImportDirs file
16631668 fp <- findImport ids ibcsd file
16641669 if file `elem` imported i
16651670 then do logParser 1 $ "Already read " ++ file
@@ -1712,7 +1717,7 @@ loadSource lidr f toline
17121717 (mdocs, mname, imports_in, pos) <- parseImports f file
17131718 ai <- getAutoImports
17141719 let imports = map (\n -> ImportInfo True n Nothing [] NoFC NoFC) ai ++ imports_in
1715− ids <- allImportDirs
1720+ ids <- rankedImportDirs f
17161721 ibcsd <- valIBCSubDir i
17171722 mapM_ (\(re, f, ns, nfc) ->
17181723 do fp <- findImport ids ibcsd f
src/Idris/Parser/Expr.hs+7
@@ -234,6 +234,7 @@ updateSynMatch = update
234234 = DoBindP fc (update ns i) (update ns t)
235235 (map (\(l,r) -> (update ns l, update ns r)) ts)
236236 upd ns (DoLetP fc i t) = DoLetP fc (update ns i) (update ns t)
237+ upd ns (DoRewrite fc h) = DoRewrite fc (update ns h)
237238 update ns (PIdiom fc t) = PIdiom fc $ update ns t
238239 update ns (PMetavar fc n) = uncurry (flip PMetavar) $ updateB ns (n, fc)
239240 update ns (PProof tacs) = PProof $ map (updTactic ns) tacs
@@ -1343,6 +1344,7 @@ doBlock syn
13431344Do ::=
13441345 'let' Name TypeSig'? '=' Expr
13451346 | 'let' Expr' '=' Expr
1347+ | 'rewrite Expr
13461348 | Name '<-' Expr
13471349 | Expr' '<-' Expr
13481350 | Expr
@@ -1367,6 +1369,11 @@ do_ syn
13671369 sc <- expr syn
13681370 highlightP kw AnnKeyword
13691371 return (DoLetP fc i sc))
1372+ <|> try (do kw <- reservedFC "rewrite"
1373+ fc <- getFC
1374+ sc <- expr syn
1375+ highlightP kw AnnKeyword
1376+ return (DoRewrite fc sc))
13701377 <|> try (do (i, ifc) <- name
13711378 symbol "<-"
13721379 fc <- getFC
src/Idris/Parser/Helpers.hs+3−9
@@ -5,11 +5,9 @@ Copyright :
55License : BSD3
66Maintainer : The Idris Community.
77-}
8−{-# LANGUAGE CPP, ConstraintKinds, GeneralizedNewtypeDeriving, PatternGuards,
9− StandaloneDeriving #-}
10−#if !(MIN_VERSION_base(4,8,0))
11−{-# LANGUAGE OverlappingInstances #-}
12−#endif
8+{-# LANGUAGE CPP, ConstraintKinds, FlexibleInstances,
9+ GeneralizedNewtypeDeriving, PatternGuards, StandaloneDeriving,
10+ TypeSynonymInstances #-}
1311module Idris.Parser.Helpers where
1412
1513import Idris.AbsSyntax
@@ -70,11 +68,7 @@ instance {-# OVERLAPPING #-} DeltaParsing IdrisParser where
7068
7169#endif
7270
73−#if MIN_VERSION_base(4,8,0)
7471instance {-# OVERLAPPING #-} TokenParsing IdrisParser where
75−#else
76−instance TokenParsing IdrisParser where
77−#endif
7872 someSpace = many (simpleWhiteSpace <|> singleLineComment <|> multiLineComment) *> pure ()
7973 token p = do s <- get
8074 (FC fn (sl, sc) _) <- getFC --TODO: Update after fixing getFC
src/Idris/Parser/Ops.hs+2−1
@@ -5,7 +5,8 @@ Copyright :
55License : BSD3
66Maintainer : The Idris Community.
77-}
8−{-# LANGUAGE ConstraintKinds, GeneralizedNewtypeDeriving, PatternGuards #-}
8+{-# LANGUAGE ConstraintKinds, FlexibleContexts, GeneralizedNewtypeDeriving,
9+ PatternGuards #-}
910module Idris.Parser.Ops where
1011
1112import Idris.AbsSyntax
src/Idris/PartialEval.hs+1−1
@@ -5,7 +5,7 @@ Copyright :
55License : BSD3
66Maintainer : The Idris Community.
77-}
8−{-# LANGUAGE PatternGuards #-}
8+{-# LANGUAGE FlexibleContexts, PatternGuards #-}
99
1010module Idris.PartialEval(
1111 partial_eval, getSpecApps, specType
src/Idris/Prover.hs+1
@@ -350,6 +350,7 @@ elabloop info fn d prompt prf e prev h env
350350 Success (Right cmd') ->
351351 case cmd' of
352352 DoLetP {} -> ifail "Pattern-matching let not supported here"
353+ DoRewrite {} -> ifail "Pattern-matching do-rewrite not supported here"
353354 DoBindP {} -> ifail "Pattern-matching <- not supported here"
354355 DoLet fc i ifc Placeholder expr ->
355356 do (tm, ty) <- elabVal (recinfo proverfc) ERHS (inLets ist env expr)
src/Idris/REPL.hs+1−1
@@ -5,7 +5,7 @@ License : BSD3
55Maintainer : The Idris Community.
66-}
77
8−{-# LANGUAGE PatternGuards #-}
8+{-# LANGUAGE FlexibleContexts, PatternGuards #-}
99
1010module Idris.REPL
1111 ( idemodeStart
src/Idris/Reflection.hs−5
@@ -21,11 +21,6 @@ import Idris.AbsSyntaxTree (ArgOpt(..), ElabD, Fixity(..), IState(idris_datatype
2121 initEState, pairCon, pairTy)
2222import Idris.Delaborate (delab)
2323
24−#if __GLASGOW_HASKELL__ < 710
25−import Control.Applicative (pure, (<$>), (<*>))
26−import Data.Traversable (mapM)
27−import Prelude hiding (mapM)
28−#endif
2924import Control.Monad (liftM, liftM2, liftM4)
3025import Control.Monad.State.Strict (lift)
3126import Data.List (findIndex, (\\))
src/Util/Pretty.hs+3
@@ -5,6 +5,9 @@ Copyright :
55License : BSD3
66Maintainer : The Idris Community.
77-}
8+
9+{-# LANGUAGE MultiParamTypeClasses #-}
10+
811module Util.Pretty (
912 module Text.PrettyPrint.Annotated.Leijen
1013 , Sized(..)
stack-shell.nix+1−1
@@ -2,7 +2,7 @@ with (import <nixpkgs> {});
22
33let
44 # MUST match resolver in stack.yaml
5− resolver = haskell.packages.lts-8_18.ghc;
5+ resolver = haskell.packages.lts-9_0.ghc;
66
77 native_libs = [
88 libffi
stack.yaml+4−2
@@ -1,4 +1,5 @@
1−resolver: lts-8.18
1+#recheck extra-deps next on resolver or cabal file change
2+resolver: lts-9.0
23
34packages:
45 - location: .
@@ -9,7 +10,8 @@ flags:
910 GMP: true
1011
1112extra-deps:
12− - libffi-0.1
13+ - binary-0.8.5.1
14+ - cheapskate-0.1.1
1315
1416nix:
1517 enable: false
test/TestData.hs+2−1
@@ -259,7 +259,8 @@ testFamiliesData = [
259259 ( 77, ANY )]),
260260 ("regression", "Regression",
261261 [ ( 1 , ANY ),
262− ( 2 , ANY )]),
262+ ( 2 , ANY ),
263+ ( 3 , ANY )]),
263264 ("sourceLocation", "Source location",
264265 [ ( 1 , ANY )]),
265266 ("sugar", "Syntactic sugar",
test/TestRun.hs+2−3
@@ -7,9 +7,7 @@ import Control.Monad
77import Data.Char (isLetter)
88import qualified Data.IntMap as IMap
99import Data.List
10−#if MIN_VERSION_optparse_applicative(0,13,0)
1110import Data.Monoid ((<>))
12−#endif
1311import Data.Proxy
1412import Data.Typeable
1513import Options.Applicative
@@ -67,7 +65,8 @@ test testName path = goldenVsFileDiff testName diff ref output
6765 where
6866 ref = path </> "expected"
6967 output = path </> "output"
70− diff ref new = ["diff", "--strip-trailing-cr", "-u", new, ref]
68+ diff ref new | os == "openbsd" = ["diff", "-u", new, ref]
69+ | otherwise = ["diff", "--strip-trailing-cr", "-u", new, ref]
7170
7271-- Should always output a 3-charater string from a postive Int
7372indexToString :: Int -> String
test/base001/exit1.c+4
@@ -1,6 +1,10 @@
11#include <stdio.h>
22#include <stdlib.h>
33
4+#ifdef __OpenBSD__
5+#include <sys/wait.h>
6+#endif
7+
48void doSystem(const char cmd[]) {
59 printf("exit1: Executing cmd '%s'\n", cmd);
610 int exitStatus = system(cmd);
test/base001/sys.c+4
@@ -2,6 +2,10 @@
22
33#include <stdlib.h>
44
5+#ifdef __OpenBSD__
6+#include <sys/wait.h>
7+#endif
8+
59int WIFEXITED_(int status) {
610 return WIFEXITED(status);
711}
test/basic009/expected+1−1
@@ -1,5 +1,5 @@
11MAIN-PASS
2−Faulty.idr:6:9-12:WARNING: num is bound as an implicit
2+Faulty.idr:6:9-12:num is bound as an implicit
33 Did you mean to refer to A.num?
44Faulty.idr:7:7:When checking right hand side of fault with expected type
55 num = 0
test/basic018/expected+4−2
@@ -1,6 +1,8 @@
1−basic018.idr:7:12-17:WARNING: thing is bound as an implicit
1+basic018.idr:7:12-17:
2+thing is bound as an implicit
23 Did you mean to refer to Main.thing?
3−basic018.idr:12:8-13:WARNING: thing is bound as an implicit
4+basic018.idr:12:8-13:
5+thing is bound as an implicit
46 Did you mean to refer to Main.thing?
57basic018.idr:13:6:When checking right hand side of test with expected type
68 thing = S 41
test/interactive017/TestMod.idrnew file+5
@@ -0,0 +1,5 @@
1+module TestMod
2+
3+export
4+test : IO ()
5+test = putStrLn "Hello from a module"
test/interactive017/expectednew file+7
@@ -0,0 +1,7 @@
1+hello from C
2+hello from C
3+hello from node
4+hello from node
5+Hello ["aaa"]
6+Hello ["bbb", "aaa"]
7+Hello from a module
test/interactive017/runnew file+9
@@ -0,0 +1,9 @@
1+#!/bin/sh
2+PATH="../../scripts:$PATH"
3+./shebang.idr
4+./shebang.idr
5+./shebang-node.idr
6+./shebang-node.idr
7+./shebang-args.idr aaa
8+./shebang-args.idr bbb aaa
9+./shebang-import.idr
test/interactive017/shebang-args.idrnew file+6
@@ -0,0 +1,6 @@
1+#!/usr/bin/env runidris
2+
3+main : IO ()
4+main = do
5+ args <- getArgs
6+ putStrLn $ "Hello " ++ (show $ drop 1 args)
test/interactive017/shebang-import.idrnew file+6
@@ -0,0 +1,6 @@
1+#!/usr/bin/env runidris
2+
3+import TestMod
4+
5+main : IO ()
6+main = TestMod.test
test/interactive017/shebang-node.idrnew file+4
@@ -0,0 +1,4 @@
1+#!/usr/bin/env runidris-node
2+
3+main : IO ()
4+main = putStrLn "hello from node"
test/interactive017/shebang.idrnew file+4
@@ -0,0 +1,4 @@
1+#!/usr/bin/env runidris
2+
3+main : IO ()
4+main = putStrLn "hello from C"
test/proof002/Reflect.idr+1−1
@@ -10,7 +10,7 @@ using (xs : List a, ys : List a, G : List (List a))
1010
1111 data Elem : a -> List a -> Type where
1212 Stop : Elem x (x :: xs)
13− Pop : Elem x ys -> Elem x (y :: xs)
13+ Pop : Elem x ys -> Elem x (y :: ys)
1414
1515-- Expr is a reflection of a list, indexed over the concrete list,
1616-- and over a set of list variables.
test/regression002/expected+2−1
@@ -110,7 +110,8 @@ reg068.idr:1:6:Main.nat has a name which may be implicitly bound.
110110This is likely to lead to problems!
111111reg068.idr:2:6:Main.ze has a name which may be implicitly bound.
112112This is likely to lead to problems!
113−reg068.idr:2:8-11:WARNING: nat is bound as an implicit
113+reg068.idr:2:8-11:
114+nat is bound as an implicit
114115 Did you mean to refer to Main.nat?
115116reg068.idr:2:6:When checking constructor Main.ze:
116117Type level variable nat is not Main.nat
test/regression003/expectednew file+1
@@ -0,0 +1 @@
1+ola
test/regression003/regression003.idrnew file+56
@@ -0,0 +1,56 @@
1+module Main
2+
3+data Free : (f : Type -> Type) -> (a : Type) -> Type where
4+ Pure : a -> Free f a
5+ Bind : f (Free f a) -> Free f a
6+
7+Functor f => Functor (Free f) where
8+ map f m = assert_total $ case m of
9+ Pure x => Pure (f x)
10+ Bind x => Bind (map (map f) x)
11+
12+Functor f => Applicative (Free f) where
13+ pure = Pure
14+
15+ m <*> x = assert_total $ case m of
16+ Pure f => map f x
17+ Bind f => Bind (map (<*> x) f)
18+
19+Functor f => Monad (Free f) where
20+ m >>= f = assert_total $ case m of
21+ Pure x => f x
22+ Bind x => Bind (map (>>= f) x)
23+
24+liftFree : Functor f => f a -> Free f a
25+liftFree = assert_total $ Bind . map Pure
26+
27+foldFree : (Monad m, Functor f) => ({ a : Type } -> f a -> m a) -> Free f b -> m b
28+foldFree f m = assert_total $ case m of
29+ Pure x => pure x
30+ Bind x => f x >>= foldFree f
31+
32+data FileSystemF next
33+ = ReadFile (String -> next)
34+
35+FileSystem : Type -> Type
36+FileSystem = Free FileSystemF
37+
38+Functor FileSystemF where
39+ map f (ReadFile nextFn) = ReadFile (f . nextFn)
40+
41+readFileF : FileSystem String
42+readFileF = liftFree $ ReadFile id
43+
44+
45+
46+interpret2 : FileSystemF a -> IO a
47+interpret2 (ReadFile nextFn) = do
48+ contents <- pure "ola"
49+ pure (nextFn contents)
50+
51+main : IO ()
52+main =
53+ do
54+ c <- foldFree interpret2 readFileF
55+ putStrLn' c
56+
test/regression003/runnew file+4
@@ -0,0 +1,4 @@
1+#!/usr/bin/env bash
2+${IDRIS:-idris} $@ regression003.idr -o regression003
3+./regression003
4+rm -f regression003 *.ibc