on master help sign in
Merge branch 'master' into feature/vect-isos
commit7b38ac27c2244c8c28a1e548e342bb83e9477795 authorhowtonotwin <rasheeqhere@gmail.com> dateTue 3 Jul 2018, 21:41 (8 years ago) parentf35d483ebd3119
112 files changed+1909−1772
.hlint.yaml+61 .travis.yml+24−16 CHANGELOG.md+3−1 CONTRIBUTORS+1 HLint.hs−34 INSTALL.md+4−1 Setup.hs+19−9 benchmarks/build.pl+3−2 config.mk+1−1 docs/conf.py+2−2 docs/faq/faq.rst+42−9 docs/guides/type-providers-ffi.rst+1−1 docs/listing/idris-prompt-helloworld.txt+1−1 docs/listing/idris-prompt-interp.txt+1−1 docs/listing/idris-prompt-start.txt+1−1 docs/reference/codegen.rst+5 docs/reference/elaborator-reflection.rst+2−1 docs/reference/erasure.rst+1−1 docs/reference/ffi.rst+6 docs/reference/misc.rst+1−1 docs/reference/packages.rst+1−1 docs/st/composing.rst+16−16 docs/st/introduction.rst+1−1 docs/st/state.rst+1−1 docs/tutorial/interactive.rst+5−6 docs/tutorial/interfaces.rst+6−7 docs/tutorial/interp.rst+2−2 docs/tutorial/miscellany.rst+19−19 docs/tutorial/modules.rst+8−11 docs/tutorial/packages.rst+41−29 docs/tutorial/syntax.rst+4−4 docs/tutorial/theorems.rst+3−3 docs/tutorial/typesfuns.rst+22−30 docs/tutorial/views.rst+3−3 idris-tutorial.pdf idris.cabal+5−5 libs/base/Data/Nat/Views.idr+1−1 libs/base/Makefile+1−1 libs/base/System/Concurrency/Raw.idr+9−10 libs/contrib/CFFI/Types.idr+2−2 libs/contrib/Data/BoundedList.idr+15 libs/contrib/Data/Nat.idr+8 libs/contrib/Data/Sign.idr+29 libs/contrib/Makefile+1−1 libs/contrib/Network/Socket.idr+20−1 libs/contrib/Text/Parser.idr+1−1 libs/contrib/contrib.ipkg+1 libs/effects/Makefile+1−1 libs/prelude/Decidable/Equality.idr+10−7 libs/prelude/Language/Reflection/Elab.idr+9 libs/prelude/Makefile+1−1 libs/prelude/Prelude/File.idr+53−6 libs/prelude/Prelude/Interactive.idr+1−1 libs/prelude/Prelude/Maybe.idr+6 libs/pruviloj/Makefile+1−1 man/idris.1+1−1 rts/Makefile+8−12 rts/idris_bitstring.c+247−513 rts/idris_bitstring.h−5 rts/idris_buffer.c+5−19 rts/idris_gc.c+49−68 rts/idris_gmp.c+87−218 rts/idris_gmp.h+5−1 rts/idris_heap.c+7−6 rts/idris_main.c+2−3 rts/idris_rts.c+256−344 rts/idris_rts.h+191−112 rts/idris_stdfgn.c+42−3 rts/idris_stdfgn.h+6 src/IRTS/CodegenC.hs+75−69 src/IRTS/JavaScript/Codegen.hs+6−1 src/IRTS/Lang.hs+25 src/IRTS/LangOpts.hs+56−27 src/IRTS/System.hs+8−2 src/Idris/AbsSyntaxTree.hs+31−12 src/Idris/Chaser.hs+59−24 src/Idris/Core/ProofState.hs+5−1 src/Idris/Core/TT.hs+16−7 src/Idris/Delaborate.hs+5−1 src/Idris/Directives.hs+7−5 src/Idris/Docs.hs+5−1 src/Idris/Docstrings.hs+6−3 src/Idris/Elab/Clause.hs+2−1 src/Idris/Elab/Data.hs+9−4 src/Idris/Elab/Interface.hs+6−5 src/Idris/Elab/Record.hs+5−4 src/Idris/Elab/Term.hs+9−1 src/Idris/Elab/Type.hs+2−2 src/Idris/Elab/Utils.hs+5−1 src/Idris/Elab/Value.hs+1 src/Idris/ElabDecls.hs+3−1 src/Idris/IdrisDoc.hs+2−2 src/Idris/Imports.hs+7−1 src/Idris/Main.hs+1−2 src/Idris/Output.hs+19−13 src/Idris/Parser.hs+6−5 src/Idris/Parser/Helpers.hs+2−1 src/Idris/Primitives.hs+5−1 src/Idris/REPL.hs+5−1 src/Idris/TypeSearch.hs+17−2 src/Util/System.hs+4 stack-shell.nix+1−1 stack.yaml+1−1 test/base001/Makefile+2−2 test/buffer002/buffer002.idr+2−2 test/buffer002/expected+4−4 test/meta003/Catch.idr+17 test/meta003/expected+2 test/meta003/run+3−1 test/pkg008/expected+1−1 test/regression001/reg007.idr+69 test/regression001/run+1−1
.hlint.yamlnew file+61
@@ -0,0 +1,61 @@
1+# HLint configuration file
2+# https://github.com/ndmitchell/hlint
3+##########################
4+
5+# This file contains a template configuration file, which is typically
6+# placed as .hlint.yaml in the root of your project
7+
8+
9+# Specify additional command line arguments
10+#
11+# - arguments: [--color, --cpp-simple, -XQuasiQuotes]
12+
13+
14+# Control which extensions/flags/modules/functions can be used
15+#
16+# - extensions:
17+# - default: false # all extension are banned by default
18+# - name: [PatternGuards, ViewPatterns] # only these listed extensions can be used
19+# - {name: CPP, within: CrossPlatform} # CPP can only be used in a given module
20+#
21+# - flags:
22+# - {name: -w, within: []} # -w is allowed nowhere
23+#
24+# - modules:
25+# - {name: [Data.Set, Data.HashSet], as: Set} # if you import Data.Set qualified, it must be as 'Set'
26+# - {name: Control.Arrow, within: []} # Certain modules are banned entirely
27+#
28+# - functions:
29+# - {name: unsafePerformIO, within: []} # unsafePerformIO can only appear in no modules
30+
31+
32+# Add custom hints for this project
33+#
34+# Will suggest replacing "wibbleMany [myvar]" with "wibbleOne myvar"
35+# - error: {lhs: "wibbleMany [x]", rhs: wibbleOne x}
36+
37+
38+# Turn on hints that are off by default
39+#
40+# Ban "module X(module X) where", to require a real export list
41+# - warn: {name: Use explicit module export list}
42+#
43+# Replace a $ b $ c with a . b $ c
44+# - group: {name: dollar, enabled: true}
45+#
46+# Generalise map to fmap, ++ to <>
47+# - group: {name: generalise, enabled: true}
48+
49+
50+# Ignore some builtin hints
51+# - ignore: {name: Use let}
52+# - ignore: {name: Use const, within: SpecialModule} # Only within certain modules
53+- ignore: {name: Use camelCase}
54+- ignore: {name: Reduce duplication}
55+
56+# Define some custom infix operators
57+# - fixity: infixr 3 ~^#^~
58+
59+
60+# To generate a suitable file for HLint do:
61+# $ hlint --default > .hlint.yaml
.travis.yml+24−16
@@ -9,26 +9,34 @@ env:
99
1010matrix:
1111 include:
12− - env: CABALVER="1.24" GHCVER="8.0.1" STACKVER="7.14" STYLISH=YES
13− addons: {apt: {packages: [cabal-install-1.24,ghc-8.0.1,hscolour], sources: [hvr-ghc]}}
14− - env: CABALVER="1.22" GHCVER="7.10.3" TESTS="lib_doc doc"
12+ - env: CABALVER="2.2" GHCVER="8.4.1" STACKVER="7.14" STYLISH=YES
13+ addons: {apt: {packages: [cabal-install-2.2,ghc-8.4.1,hscolour], sources: [hvr-ghc]}}
14+ - env: CABALVER="2.2" GHCVER="7.10.3" TESTS="test_c"
1515 compiler: ": #GHC 7.10.3"
16− addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.3,cppcheck,hscolour], sources: [hvr-ghc]}}
17− - env: CABALVER="1.22" GHCVER="7.10.3" TESTS="test_js"
18− compiler: ": #GHC 7.10.3"
19− addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.3,cppcheck,hscolour], sources: [hvr-ghc]}}
20− - env: CABALVER="1.22" GHCVER="7.10.3" TESTS="test_c"
21− compiler: ": #GHC 7.10.3"
22− addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.3,cppcheck,hscolour], sources: [hvr-ghc]}}
23− - env: CABALVER="1.24" GHCVER="8.0.1" TESTS="lib_doc doc"
24− compiler: ": #GHC 8.0.1"
25− addons: {apt: {packages: [cabal-install-1.24,ghc-8.0.1,cppcheck,hscolour], sources: [hvr-ghc]}}
26− - env: CABALVER="1.24" GHCVER="8.0.1" TESTS="test_js"
27− compiler: ": #GHC 8.0.1"
28− addons: {apt: {packages: [cabal-install-1.24,ghc-8.0.1,cppcheck,hscolour], sources: [hvr-ghc]}}
16+ addons: {apt: {packages: [cabal-install-2.2,ghc-7.10.3,cppcheck,hscolour], sources: [hvr-ghc]}}
2917 - env: CABALVER="1.24" GHCVER="8.0.1" TESTS="test_c"
3018 compiler: ": #GHC 8.0.1"
3119 addons: {apt: {packages: [cabal-install-1.24,ghc-8.0.1,cppcheck,hscolour], sources: [hvr-ghc]}}
20+ - env: CABALVER="2.0" GHCVER="8.2.2" TESTS="lib_doc doc"
21+ compiler: ": #GHC 8.2.2"
22+ addons: {apt: {packages: [cabal-install-2.0,ghc-8.2.2,cppcheck,hscolour], sources: [hvr-ghc]}}
23+ - env: CABALVER="2.0" GHCVER="8.2.2" TESTS="test_js"
24+ compiler: ": #GHC 8.2.2"
25+ addons: {apt: {packages: [cabal-install-2.0,ghc-8.2.2,cppcheck,hscolour], sources: [hvr-ghc]}}
26+ - env: CABALVER="2.0" GHCVER="8.2.2" TESTS="test_c"
27+ compiler: ": #GHC 8.2.2"
28+ addons: {apt: {packages: [cabal-install-2.0,ghc-8.2.2,cppcheck,hscolour], sources: [hvr-ghc]}}
29+#TODO: The idris built with those fails due to libffi dynamic linking version mismatch.
30+# Caused by the GHC backport to Trusty?
31+# - env: CABALVER="2.2" GHCVER="8.4.1" TESTS="lib_doc doc"
32+# compiler: ": #GHC 8.4.1"
33+# addons: {apt: {packages: [cabal-install-2.2,ghc-8.4.1,cppcheck,hscolour], sources: [hvr-ghc]}}
34+# - env: CABALVER="2.2" GHCVER="8.4.1" TESTS="test_js"
35+# compiler: ": #GHC 8.4.1"
36+# addons: {apt: {packages: [cabal-install-2.2,ghc-8.4.1,cppcheck,hscolour], sources: [hvr-ghc]}}
37+# - env: CABALVER="2.2" GHCVER="8.4.1" TESTS="test_c"
38+# compiler: ": #GHC 8.4.1"
39+# addons: {apt: {packages: [cabal-install-2.2,ghc-8.4.1,cppcheck,hscolour], sources: [hvr-ghc]}}
3240 fast-finish: true
3341
3442cache:
CHANGELOG.md+3−1
@@ -1,4 +1,4 @@
1−# New in 1.3.*
1+# New in 1.3.0
22
33## Language updates
44+ Old 'induction' tactics and eliminator generation functionality ('%elim', '%case', 'elim_for') is no longer supported.
@@ -18,6 +18,8 @@
1818+ Added a switch `--allow-capitalized-pattern-variables` to optionally allow capitalized pattern variables after they were prohibited in 1.2.0.
1919+ REPL now prints an error message if program compiled by `:exec` terminates
2020 abnormally.
21++ Idris now builds with GHC 8.4.
22++ In the C backend, the representation of Idris values at runtime has been reworked.
2123
2224# New in 1.2.0
2325
CONTRIBUTORS+1
@@ -126,6 +126,7 @@ Jonas De Vuyst
126126Jonas Westerlund
127127Jonathan Sterling
128128Joomy Korkut
129+Jorge Acereda
129130Joseph Huang
130131Josh Vera
131132JP Smith
HLint.hsdeleted−34
@@ -1,34 +0,0 @@
1−{-# LANGUAGE TemplateHaskell #-}
2−-- --------------------------------------------------------------- [ HLint.hs ]
3−-- HLint suggestions we like.
4−--
5−-- This is a work in progress and the list of
6−-- suggestions/warnings/errors will vary.
7−--
8−-- -------------------------------------------------------------------- [ EOH ]
9−
10−-- import "hint" HLint.HLint -- In case we want to use all of them.
11−
12−-- ------------------------------------------------------------ [ Suggestions ]
13−-- Styling that are good Suggestions but are okay if found.
14−
15−suggest "Use exitSuccess"
16−suggest "Use concatMap"
17−suggest "Use unwords"
18−suggest "Use null"
19−suggest "Redundant $"
20−suggest "Use list literal pattern"
21−suggest "Use list literal"
22−
23−-- ------------------------------------------------------------------- [ Warn ]
24−-- Styling that we think a programmer should be warned about using.
25−
26−
27−-- ------------------------------------------------------------------ [ Error ]
28−-- Styling that we think a programmer should not use at all.
29−
30−
31−-- ----------------------------------------------------------------- [ Ignore ]
32−-- Suggestions we want to ignore.
33−
34−-- -------------------------------------------------------------------- [ EOF ]
INSTALL.md+4−1
@@ -81,7 +81,10 @@ To install Idris:
8181* `stack install`
8282
8383Stack will install Idris (and related executables) into `$HOME/.local/bin/`
84−on Unix based systems and an appropriate place on Windows.
84+on Unix based systems and an appropriate place on Windows. The libraries that
85+are included with Idris (e.g. Builtins, Prelude) will 'install' into `<source
86+dir>/.stack_work/install/...` so you'll need to keep your source directory
87+around after you've installed Idris using Stack.
8588
8689Of note: If you haven't used stack before commands will also setup the
8790related infrastructure. For more information about Stack please visit
Setup.hs+19−9
@@ -14,7 +14,7 @@ import Distribution.Simple.InstallDirs as I
1414import Distribution.Simple.LocalBuildInfo as L
1515import qualified Distribution.Simple.Setup as S
1616import qualified Distribution.Simple.Program as P
17−import Distribution.Simple.Utils (createDirectoryIfMissingVerbose, rewriteFile, notice, installOrdinaryFiles)
17+import Distribution.Simple.Utils
1818import Distribution.Compiler
1919import Distribution.PackageDescription
2020import Distribution.Text
@@ -66,28 +66,28 @@ windres verbosity = P.runProgramInvocation verbosity . P.simpleProgramInvocation
6666
6767usesGMP :: S.ConfigFlags -> Bool
6868usesGMP flags =
69− case lookup (mkFlagName "gmp") (S.configConfigurationsFlags flags) of
69+ case lookupFlagAssignment (mkFlagName "gmp") (S.configConfigurationsFlags flags) of
7070 Just True -> True
7171 Just False -> False
7272 Nothing -> False
7373
7474execOnly :: S.ConfigFlags -> Bool
7575execOnly flags =
76− case lookup (mkFlagName "execonly") (S.configConfigurationsFlags flags) of
76+ case lookupFlagAssignment (mkFlagName "execonly") (S.configConfigurationsFlags flags) of
7777 Just True -> True
7878 Just False -> False
7979 Nothing -> False
8080
8181isRelease :: S.ConfigFlags -> Bool
8282isRelease flags =
83− case lookup (mkFlagName "release") (S.configConfigurationsFlags flags) of
83+ case lookupFlagAssignment (mkFlagName "release") (S.configConfigurationsFlags flags) of
8484 Just True -> True
8585 Just False -> False
8686 Nothing -> False
8787
8888isFreestanding :: S.ConfigFlags -> Bool
8989isFreestanding flags =
90− case lookup (mkFlagName "freestanding") (S.configConfigurationsFlags flags) of
90+ case lookupFlagAssignment (mkFlagName "freestanding") (S.configConfigurationsFlags flags) of
9191 Just True -> True
9292 Just False -> False
9393 Nothing -> False
@@ -97,6 +97,11 @@ mkFlagName :: String -> FlagName
9797mkFlagName = FlagName
9898#endif
9999
100+#if !(MIN_VERSION_Cabal(2,2,0))
101+lookupFlagAssignment :: FlagName -> FlagAssignment -> Maybe Bool
102+lookupFlagAssignment = lookup
103+#endif
104+
100105-- -----------------------------------------------------------------------------
101106-- Clean
102107
@@ -123,7 +128,7 @@ generateBuildFlagsModule verbosity dir libdirs = do
123128 let buildFlagsModulePath = dir </> "BuildFlags_idris" Px.<.> "hs"
124129 putStrLn $ "Generating " ++ buildFlagsModulePath
125130 createDirectoryIfMissingVerbose verbosity True dir
126− rewriteFile buildFlagsModulePath contents
131+ rewriteFileEx verbosity buildFlagsModulePath contents
127132 where contents = "module BuildFlags_idris where \n\n" ++
128133 "extraLibDirs :: [String]\n" ++
129134 "extraLibDirs = " ++ show libdirs
@@ -136,7 +141,7 @@ generateVersionModule verbosity dir release = do
136141 putStrLn $ "Generating " ++ versionModulePath ++
137142 if release then " for release" else " for prerelease " ++ hash
138143 createDirectoryIfMissingVerbose verbosity True dir
139− rewriteFile versionModulePath (versionModuleContents hash)
144+ rewriteFileEx verbosity versionModulePath (versionModuleContents hash)
140145
141146 where versionModuleContents h = "module Version_idris where\n\n" ++
142147 "gitHash :: String\n" ++
@@ -150,7 +155,7 @@ generateTargetModule verbosity dir targetDir = do
150155 let targetModulePath = dir </> "Target_idris" Px.<.> "hs"
151156 putStrLn $ "Generating " ++ targetModulePath
152157 createDirectoryIfMissingVerbose verbosity True dir
153− rewriteFile targetModulePath (versionModuleContents absPath targetDir)
158+ rewriteFileEx verbosity targetModulePath (versionModuleContents absPath targetDir)
154159 where versionModuleContents absolute td = "module Target_idris where\n\n" ++
155160 "import System.FilePath\n" ++
156161 "import System.Environment\n" ++
@@ -176,7 +181,7 @@ generateToolchainModule verbosity srcDir toolDir = do
176181 "getToolchainDir = \"\""
177182 let toolPath = srcDir </> "Tools_idris" Px.<.> "hs"
178183 createDirectoryIfMissingVerbose verbosity True srcDir
179− rewriteFile toolPath (commonContent ++ toolContent)
184+ rewriteFileEx verbosity toolPath (commonContent ++ toolContent)
180185
181186idrisConfigure _ flags pkgdesc local = do
182187 configureRTS
@@ -240,6 +245,11 @@ idrisPostSDist args flags desc lbi = do
240245 (\e -> let e' = (e :: SomeException) in return ())
241246 postSDist simpleUserHooks args flags desc lbi
242247
248+#if !(MIN_VERSION_Cabal(2,0,0))
249+rewriteFileEx :: Verbosity -> FilePath -> String -> IO ()
250+rewriteFileEx _ = rewriteFile
251+#endif
252+
243253-- -----------------------------------------------------------------------------
244254-- Build
245255
benchmarks/build.pl+3−2
@@ -2,13 +2,14 @@
22
33$bmarks = `cat ALL`;
44@bm = split(/\n/, $bmarks);
5+$idris = $ENV{'IDRIS'} || "idris";
56
67foreach $b (@bm) {
78 if ($b =~ /([a-zA-Z0-9]+)\/([a-zA-Z0-9]+)\s+(.*)/) {
89 print "Building $1 / $2\n";
910 chdir $1;
10− system("idris --clean $2.ipkg");
11− system("idris --build $2.ipkg") == 0 or die "Unable to build $2: $?";
11+ system("$idris --clean $2.ipkg");
12+ system("$idris --build $2.ipkg") == 0 or die "Unable to build $2: $?";
1213 chdir "..";
1314 }
1415}
config.mk+1−1
@@ -14,7 +14,7 @@ RANLIB ?=ranlib
1414CABAL :=cabal
1515# IDRIS_ENABLE_STATS should not be set in final release
1616# Any flags defined here which alter the RTS API must also be added to src/IRTS/CodegenC.hs
17−CFLAGS :=-O2 -Wall -std=c99 -D_POSIX_C_SOURCE=200809L -DHAS_PTHREAD -DIDRIS_ENABLE_STATS $(CFLAGS)
17+CFLAGS :=-O2 -Wall -std=c99 -pipe -fdata-sections -ffunction-sections -D_POSIX_C_SOURCE=200809L -DHAS_PTHREAD -DIDRIS_ENABLE_STATS $(CFLAGS)
1818
1919# CABALFLAGS :=
2020CABALFLAGS += --enable-tests
docs/conf.py+2−2
@@ -59,9 +59,9 @@ author = u'The Idris Community'
5959# built documents.
6060#
6161# The short X.Y version.
62−version = '1.2'
62+version = '1.3'
6363# The full version, including alpha/beta/rc tags.
64−release = '1.2.0'
64+release = '1.3.0'
6565
6666# The language for content autogenerated by Sphinx. Refer to documentation
6767# for a list of supported languages.
docs/faq/faq.rst+42−9
@@ -33,6 +33,30 @@ for use in production would be very welcome - this includes (but is not
3333limited to) extra library support, polishing the run-time system (and ensuring
3434it is robust), providing and maintaining a JVM back end, etc.
3535
36+Is there some documentation for the standard lib? List of functions?
37+=====================================================================
38+
39+API documentation for the shipped packages is listed on `the
40+documentation page <http://www.idris-lang.org/documentation/>`_.
41+
42+Unfortunately, the default prelude and shipped packages for `Idris`
43+are not necessarily complete with regards to documentation. Other
44+ways to find functions include:
45+
46++ REPL commands:
47+
48+ + Use `:apropos` to search for text in documentation and function names.
49+ + Use `:search` to search for functions of a given type.
50+ + Use `:browse` to list the contents of a given namespace.
51+
52++ Use the REPL's auto-complete functionality.
53++ Grep through the source code in `libs/`
54+
55+If you find that the shipped packages are lacking in documentation,
56+please feel free to write some. Or bug someone to do so. `Idris` has
57+syntax for providing rich documentation, which is then viewable using
58+the `:doc` command and listed in generated HTML API documentation.
59+
3660
3761Why does Idris use eager evaluation rather than lazy?
3862=====================================================
@@ -173,8 +197,10 @@ function back to itself. On such a path, there must be at least one
173197argument which converges to a base case.
174198
175199- Mutually recursive functions are supported
200+
176201- However, all functions on the path must be fully applied. In particular,
177202 higher order applications are not supported
203+
178204- Idris identifies arguments which converge to a base case by looking for
179205 recursive calls to syntactically smaller arguments of inputs. e.g.
180206 ``k`` is syntactically smaller than ``S (S k)`` because ``k`` is a
@@ -189,10 +215,10 @@ function.
189215When will Idris be self-hosting?
190216================================
191217
192−It’s not a priority, though not a bad idea in the long run. It would be a
193−worthwhile effort in the short term to implement libraries to support
194−self-hosting, such as a good parsing library.
195−
218+It’s not a priority, though not a bad idea in the long run. It would
219+be a worthwhile effort in the short term to implement libraries in
220+Idris to support self-hosting, such as argument parsing and a
221+POSIX-compliant library for system interaction.
196222
197223Does Idris have universe polymorphism? What is the type of ``Type``?
198224====================================================================
@@ -233,14 +259,17 @@ where the install directory is unknown at build time. When passing this
233259flag, the IDRIS_LIB_DIR environment variable needs to be set to the path
234260where the Idris libs reside relative to the idris executable. The
235261IDRIS_TOOLCHAIN_DIR environment variable is optional, if that is set,
236−Idris will use that path to find the C compiler.
262+Idris will use that path to find the C compiler. For example:
237263
238−Example::
264+::
239265
240− IDRIS_LIB_DIR="./libs" IDRIS_TOOLCHAIN_DIR="./mingw/bin" CABALFLAGS="-fffi -ffreestanding -frelease" make
266+ IDRIS_LIB_DIR="./libs" \
267+ IDRIS_TOOLCHAIN_DIR="./mingw/bin" \
268+ CABALFLAGS="-fffi -ffreestanding -frelease" \
269+ make
241270
242271
243−What does the name ‘Idris’ mean?
272+What does the name “Idris” mean?
244273================================
245274
246275British people of a certain age may be familiar with this
@@ -256,16 +285,20 @@ There are several reasons why we should not support Unicode operators:
256285- It's hard to type (this is important if you're using someone else's code, for
257286 example). Various editors have their own input methods, but you have to know
258287 what they are.
288+
259289- Not every piece of software easily supports it. Rendering issues have been
260290 noted on some mobile email clients, terminal-based IRC clients, web browsers,
261291 etc. There are ways to resolve these rendering issues but they provide a
262292 barrier to entry to using Idris.
293+
263294- Even if we leave it out of the standard library (which we will in any case!)
264295 as soon as people start using it in their library code, others have to deal
265296 with it.
297+
266298- Too many characters look too similar. We had enough trouble with confusion
267299 between 0 and O without worrying about all the different kinds of colons and
268300 brackets.
301+
269302- There seems to be a tendency to go over the top with use of Unicode. For
270303 example, using sharp and flat for delay and force (or is it the other way
271304 around?) in Agda seems gratuitous. We don't want to encourage this sort of
@@ -280,7 +313,7 @@ This seems like an instance of `Wadler's
280313Law <http://www.haskell.org/haskellwiki/Wadler%27s_Law>`__ in action.
281314
282315This answer is based on Edwin Brady's response in the following
283−`pull request <https://github.com/idris-lang/Idris-dev/pull/694#issuecomment-29559291>`__.
316+`pull request <https://github.com/idris-lang/Idris-dev/pull/694#issuecomment-29559291>`_.
284317
285318Where can I find the community standards for the Idris community?
286319==================================================================
docs/guides/type-providers-ffi.rst+1−1
@@ -3,7 +3,7 @@ Type Providers in Idris
33***********************
44
55`Type providers in Idris
6−<http://www.itu.dk/people/drc/pubs/dependent-type-providers.pdf>`__
6+<http://www.davidchristiansen.dk/pubs/dependent-type-providers.pdf>`__
77are simple enough, but there are a few caveats to using them that it
88would be worthwhile to go through the basic steps. We also go over
99foreign functions, because these will often be used with type
docs/listing/idris-prompt-helloworld.txt+1−1
@@ -1,7 +1,7 @@
11$ idris hello.idr
22 ____ __ _
33 / _/___/ /____(_)____
4− / // __ / ___/ / ___/ Version 1.2.0
4+ / // __ / ___/ / ___/ Version 1.3.0
55 _/ // /_/ / / / (__ ) http://www.idris-lang.org/
66 /___/\__,_/_/ /_/____/ Type :? for help
77
docs/listing/idris-prompt-interp.txt+1−1
@@ -1,7 +1,7 @@
11$ idris interp.idr
22 ____ __ _
33 / _/___/ /____(_)____
4− / // __ / ___/ / ___/ Version 1.2.0
4+ / // __ / ___/ / ___/ Version 1.3.0
55 _/ // /_/ / / / (__ ) http://www.idris-lang.org/
66 /___/\__,_/_/ /_/____/ Type :? for help
77
docs/listing/idris-prompt-start.txt+1−1
@@ -1,7 +1,7 @@
11$ idris
22 ____ __ _
33 / _/___/ /____(_)____
4− / // __ / ___/ / ___/ Version 1.2.0
4+ / // __ / ___/ / ___/ Version 1.3.0
55 _/ // /_/ / / / (__ ) http://www.idris-lang.org/
66/___/\__,_/_/ /_/____/ Type :? for help
77
docs/reference/codegen.rst+5
@@ -131,3 +131,8 @@ WS
131131---
132132
133133`Available online <https://github.com/edwinb/WS-idr>`__
134+
135+WebAssembly
136+-----------
137+
138+`Available online <https://github.com/SPY/idris-codegen-wasm>`__
docs/reference/elaborator-reflection.rst+2−1
@@ -6,7 +6,8 @@ Elaborator Reflection
66
77The Idris elaborator is responsible for converting high-level Idris code into the core language.
88It is implemented as a kind of embedded tactic language in Haskell, where tactic scripts are written in an *elaboration monad* that provides error handling and a proof state.
9−For details, see Edwin Brady's 2013 paper in the Journal of Functional Programming.
9+For details, see `Edwin Brady's 2013 paper in the Journal of Functional
10+Programming <https://eb.host.cs.st-andrews.ac.uk/drafts/impldtp.pdf>`_.
1011
1112Elaborator reflection makes the elaboration type as well as a selection of its tactics available to Idris code.
1213This means that metaprograms written in Idris can have complete control over the elaboration process, generating arbitrary code, and they have access to all of the facilities available in the elaborator, such as higher-order unification, type checking, and emitting auxiliary definitions.
docs/reference/erasure.rst+1−1
@@ -127,7 +127,7 @@ For better intuition, the shape of the U-view of
127127
128128 x0 y0 (two)
129129 x1 y1 (two)
130− x2 y1 (two)
130+ x2 y2 (two)
131131 z (one)
132132
133133When recursing over this structure, the values of ``xs`` range over
docs/reference/ffi.rst+6
@@ -178,6 +178,12 @@ compilation error:
178178 example : (Int -> ()) -> IO ()
179179 example f = foreign FFI_C "callbacker" (CFnPtr (Int -> ()) -> IO ()) f
180180
181+Note that the function that is used as a callback can't be a closure, that is
182+it can't be a partially applied function. This is because the mechanism used is
183+unable to pass the closed-over values through C. If we want to pass Idris values
184+to the callback we have to pass them through C explicitly. Non-primitive Idris
185+values can be passed to C via the ``Raw`` type.
186+
181187The other big limitation is that it doesn't support IO functions. Use
182188``unsafePerformIO`` to wrap them (i.e. to make an IO function usable as a callback, change the return type
183189from IOr to r, and change the = do to = unsafePerformIO $ do).
docs/reference/misc.rst+1−1
@@ -220,7 +220,7 @@ following command::
220220 source <(idris --bash-completion-script `which idris`)
221221
222222
223−To enable completion permenatly you must either:
223+To enable completion permanently you must either:
224224
225225* Modify your bash init script with the above command.
226226
docs/reference/packages.rst+1−1
@@ -123,7 +123,7 @@ Package files support comments using the standard Idris singleline ``--`` and mu
123123Using Package files
124124===================
125125
126−Given an Idris package file ``text.ipkg`` it can be used with the Idris compiler as follows:
126+Given an Idris package file ``test.ipkg`` it can be used with the Idris compiler as follows:
127127
128128+ ``idris --build test.ipkg`` will build all modules in the package
129129
docs/st/composing.rst+16−16
@@ -1,7 +1,7 @@
11.. _composing:
22
33************************
4−Composing State Machines
4+Composing State Machines
55************************
66
77In the previous section, we defined a ``DataStore`` interface and used it
@@ -28,7 +28,7 @@ there was a login failure in a state.
2828
2929Furthermore, we may have *hierarchies* of state machines, in that one
3030state machine could be implemented by composing several others. For
31−example, we can have a state machine representing the state of a
31+example, we can have a state machine representing the state of a
3232graphics system, and use this to implement a *higher level* graphics API
3333such as turtle graphics, which uses the graphics system plus some additional
3434state for the turtle.
@@ -50,7 +50,7 @@ count to zero, a session might run as follows:
5050 *LoginCount> :exec main
5151 Enter password: Mornington Crescent
5252 Secret is: "Secret Data"
53− Enter password: Dollis Hill
53+ Enter password: Dollis Hill
5454 Failure
5555 Number of failures: 1
5656 Enter password: Mornington Crescent
@@ -63,7 +63,7 @@ count to zero, a session might run as follows:
6363We'll start by adding a state resource to ``getData`` to keep track of the
6464number of failures:
6565
66−.. code-block:: idrs
66+.. code-block:: idris
6767
6868 getData : (ConsoleIO m, DataStore m) =>
6969 (failcount : Var) -> ST m () [failcount ::: State Integer]
@@ -116,7 +116,7 @@ match:
116116 Required result states here are: st2_fn
117117
118118In other words, ``connect`` requires that there are *no* resources on
119−entry, but we have *one*, the failure count!
119+entry, but we have *one*, the failure count!
120120This shouldn't be a problem, though: the required resources are a *subset* of
121121the resources we have, after all, and the additional resources (here, the
122122failure count) are not relevant to ``connect``. What we need, therefore,
@@ -214,7 +214,7 @@ ordering of resources is allowed to change, although resources which
214214appear in ``old`` can't appear in the ``sub`` list more than once (you will
215215get a type error if you try this).
216216
217−The function ``updateWith`` takes the *output* resources of the
217+The function ``updateWith`` takes the *output* resources of the
218218called function, and updates them in the current resource list. It makes
219219an effort to preserve ordering as far as possible, although this isn't
220220always possible if the called function does some complicated resource
@@ -338,7 +338,7 @@ representing a surface on which we'll draw lines and rectangles:
338338
339339.. code-block:: idris
340340
341− interface Draw (m : Type -> Type) where
341+ interface Draw (m : Type -> Type) where
342342 Surface : Type
343343
344344We'll need to be able to create a new ``Surface`` by opening a window:
@@ -369,7 +369,7 @@ succeeds (that is, returns a result of the form ``Just val``.
369369 an operation returns ``Just ty``, there's also ``addIfRight``:
370370
371371 .. code-block:: idris
372−
372+
373373 addIfJust : Type -> Action (Maybe Var)
374374 addIfRight : Type -> Action (Either a Var)
375375
@@ -378,10 +378,10 @@ succeeds (that is, returns a result of the form ``Just val``.
378378 of an operation:
379379
380380 .. code-block:: idris
381−
381+
382382 Add : (ty -> Resources) -> Action ty
383−
384− Using this, you can create your own actions to add resources
383+
384+ Using this, you can create your own actions to add resources
385385 based on the result of an operation, if required. For example,
386386 ``addIfJust`` is implemented as follows:
387387
@@ -479,7 +479,7 @@ For example, assuming we have a surface ``win`` to draw onto, we can write a
479479
480480The ``flip win`` at the end is necessary because the drawing primitives
481481are double buffered, to prevent flicker. We draw onto one buffer, off-screen,
482−and display the other. When we call ``flip``, it displays the off-screen
482+and display the other. When we call ``flip``, it displays the off-screen
483483buffer, and creates a new off-screen buffer for drawing the next frame.
484484
485485To include this in a program, we'll write a main loop which renders our
@@ -496,7 +496,7 @@ application:
496496
497497Finally, we can create a main program which initialises a window, if
498498possible, then runs the main loop:
499−
499+
500500.. code-block:: idris
501501
502502 drawMain : (ConsoleIO m, Draw m) => ST m () []
@@ -593,7 +593,7 @@ is implemented using the following type, defined by ``Control.ST``:
593593
594594.. code-block:: idris
595595
596− data Composite : List Type -> Type
596+ data Composite : List Type -> Type
597597
598598If we have a composite resource, we can split it into its constituent
599599resources, and create new variables for each of those resources, using
@@ -604,7 +604,7 @@ the *split* function. For example:
604604 splitComp : (comp : Var) -> ST m () [comp ::: Composite [State Int, State String]]
605605 splitComp comp = do [int, str] <- split comp
606606 ?whatNow
607−
607+
608608The call ``split comp`` extracts the ``State Int`` and ``State String`` from
609609the composite resource ``comp``, and stores them in the variables ``int``
610610and ``str`` respectively. If we check the type of ``whatNow``, we'll see
@@ -713,7 +713,7 @@ A ``Line`` is defined as a start location, and end location, and a colour:
713713 Line : Type
714714 Line = ((Int, Int), (Int, Int), Col)
715715
716−To implement ``start``, which creates a new ``Turtle`` (or returns ``Nothing``
716+To implement ``start``, which creates a new ``Turtle`` (or returns ``Nothing``
717717if this is impossible), we begin by initialising the drawing surface then
718718all of the components of the state. Finally, we combine all of these
719719into a composite resource for the turtle:
docs/st/introduction.rst+1−1
@@ -70,7 +70,7 @@ Outline
7070=======
7171
7272This tutorial starts (:ref:`introst`) by describing how to manipulate
73−individual states, introduce a data type ``STrans`` for describing stateful
73+individual states, introduces a data type ``STrans`` for describing stateful
7474functions, and ``ST`` which describes top level state transitions.
7575Next (:ref:`smstypes`) it describes how to represent state machines in
7676types, and how to define *interfaces* for describing stateful systems.
docs/st/state.rst+1−1
@@ -456,7 +456,7 @@ implicit ``prf`` argument, which has the following type:
456456
457457.. code-block:: idris
458458
459− prf : InState lbl (State ty) res}
459+ prf : InState lbl (State ty) res
460460
461461This relies on a predicate ``InState``. A value of type ``InState x ty res``
462462means that the reference ``x`` must have type ``ty`` in the list of
docs/tutorial/interactive.rst+5−6
@@ -23,13 +23,12 @@ editor, and specifically how to do so in `Vim
2323for `Emacs <https://github.com/idris-hackers/idris-mode>`_ is also
2424available.
2525
26−
2726Editing at the REPL
2827===================
2928
3029The REPL provides a number of commands, which we will describe
3130shortly, which generate new program fragments based on the currently
32−loaded module. These take the general form
31+loaded module. These take the general form:
3332
3433::
3534
@@ -64,9 +63,9 @@ Editing Commands
6463:addclause
6564----------
6665
67−The ``:addclause n f`` command (abbreviated ``:ac n f``) creates a
66+The ``:addclause n f`` command, abbreviated ``:ac n f``, creates a
6867template definition for the function named ``f`` declared on line
69−``n``. For example, if the code beginning on line 94 contains:
68+``n``. For example, if the code beginning on line 94 contains:
7069
7170.. code-block:: idris
7271
@@ -129,7 +128,7 @@ ys`` would lead to a unification error.
129128
130129The ``:addmissing n f`` command, abbreviated ``:am n f``, adds the
131130clauses which are required to make the function ``f`` on line ``n``
132−cover all inputs. For example, if the code beginning on line 94 is
131+cover all inputs. For example, if the code beginning on line 94 is:
133132
134133.. code-block:: idris
135134
@@ -143,7 +142,7 @@ then ``:am 96 vzipWith`` gives:
143142
144143 vzipWith f (x :: xs) (y :: ys) = ?vzipWith_rhs_2
145144
146−That is, it notices that there are no cases for non-empty vectors,
145+That is, it notices that there are no cases for empty vectors,
147146generates the required clauses, and eliminates the clauses which would
148147lead to unification errors.
149148
docs/tutorial/interfaces.rst+6−7
@@ -11,8 +11,8 @@ data types. For example, we would like arithmetic operators to work on
1111to display different types in a uniform way.
1212
1313To achieve this, we use *interfaces*, which are similar to type classes in
14−Haskell or traits in Rust. To define an interface, we provide a collection of
15−overloadable functions. A simple example is the ``Show``
14+Haskell or traits in Rust. To define an interface, we provide a collection of
15+overloadable functions. A simple example is the ``Show``
1616interface, which is defined in the prelude and provides an interface for
1717converting values to ``String``:
1818
@@ -31,8 +31,7 @@ This generates a function of the following type (which we call a
3131We can read this as: “under the constraint that ``a`` has an implementation
3232of ``Show``, take an input ``a`` and return a ``String``.” An implementation
3333of an interface is defined by giving definitions of the methods of the interface.
34−For example, the
35−``Show`` implementation for ``Nat`` could be defined as:
34+For example, the ``Show`` implementation for ``Nat`` could be defined as:
3635
3736.. code-block:: idris
3837
@@ -49,7 +48,7 @@ Only one implementation of an interface can be given for a type — implementati
4948not overlap. Implementation declarations can themselves have constraints.
5049To help with resolution, the arguments of an implementation must be
5150constructors (either data or type constructors) or variables
52−(i.e. you cannot give an implementation for a function). For
51+(i.e. you cannot give an implementation for a function). For
5352example, to define a ``Show`` implementation for vectors, we need to know
5453that there is a ``Show`` implementation for the element type, because we are
5554going to use it to convert each element to a ``String``:
@@ -534,7 +533,7 @@ Named Implementations
534533
535534It can be desirable to have multiple implementations of an interface for the
536535same type, for example to provide alternative methods for sorting or printing
537−values. To achieve this, implementations can be *named* as follows:
536+values. To achieve this, implementations can be *named* as follows:
538537
539538.. code-block:: idris
540539
@@ -574,7 +573,7 @@ the prelude defines the following ``Semigroup`` interface:
574573 interface Semigroup ty where
575574 (<+>) : ty -> ty -> ty
576575
577−Then it defines ``Monoid``, which extends ``Semigroup`` with a "neutral"
576+Then it defines ``Monoid``, which extends ``Semigroup`` with a “neutral”
578577value:
579578
580579.. code-block:: idris
docs/tutorial/interp.rst+2−2
@@ -106,7 +106,7 @@ the ``Var`` constructor:
106106
107107 Var : HasType i G t -> Expr G t
108108
109−So, in an expression ``\x,\y. x y``, the variable ``x`` would have a
109+So, in an expression ``\x. \y. x y``, the variable ``x`` would have a
110110de Bruijn index of 1, represented as ``Pop Stop``, and ``y 0``,
111111represented as ``Stop``. We find these by counting the number of
112112lambdas between the definition and the use.
@@ -194,7 +194,7 @@ each constructor, we translate it into the corresponding Idris value:
194194 interp env (If x t e) = if interp env x then interp env t
195195 else interp env e
196196
197−Let us look at each case in turn. To translate a variable, we simply look it
197+Let us look at each case in turn. To translate a variable, we simply look it
198198up in the environment:
199199
200200.. code-block:: idris
docs/tutorial/miscellany.rst+19−19
@@ -8,7 +8,7 @@ In this section we discuss a variety of additional features:
88
99+ auto, implicit, and default arguments;
1010+ literate programming;
11−+ interfacing with external libraries through the foreign function
11++ interfacing with external libraries through the foreign function;
1212+ interface;
1313+ type providers;
1414+ code generation; and
@@ -23,7 +23,7 @@ omitted when they can be inferred by the type checker, e.g.
2323.. code-block:: idris
2424
2525 index : {a:Type} -> {n:Nat} -> Fin n -> Vect n a -> a
26−
26+
2727Auto implicit arguments
2828------------------------
2929
@@ -69,17 +69,17 @@ In the case that a proof is not found, it can be provided explicitly as normal:
6969.. code-block:: idris
7070
7171 head xs {p = ?headProof}
72−
72+
7373Default implicit arguments
7474---------------------------
7575
76−Besides having Idris automatically find a value of a given type, sometimes we
76+Besides having Idris automatically find a value of a given type, sometimes we
7777want to have an implicit argument with a specific default value. In Idris, we can
7878do this using the ``default`` annotation. While this is primarily intended to assist
79−in automatically constructing a proof where auto fails, or finds an unhelpful value,
80−it might be easier to first consider a simpler case, not involving proofs.
79+in automatically constructing a proof where auto fails, or finds an unhelpful value,
80+it might be easier to first consider a simpler case, not involving proofs.
8181
82−If we want to compute the n'th fibonacci number (and defining the 0th fibonacci
82+If we want to compute the n'th fibonacci number (and defining the 0th fibonacci
8383number as 0), we could write:
8484
8585.. code-block:: idris
@@ -89,8 +89,8 @@ number as 0), we could write:
8989 fibonacci {lag} {lead} (S n) = fibonacci {lag=lead} {lead=lag+lead} n
9090
9191After this definition, ``fibonacci 5`` is equivalent to ``fibonacci {lag=0} {lead=1} 5``,
92−and will return the 5th fibonacci number. Note that while this works, this is not the
93−intended use of the ``default`` annotation. It is included here for illustrative purposes
92+and will return the 5th fibonacci number. Note that while this works, this is not the
93+intended use of the ``default`` annotation. It is included here for illustrative purposes
9494only. Usually, ``default`` is used to provide things like a custom proof search script.
9595
9696
@@ -329,13 +329,13 @@ are available in an external collection [1]_.
329329C Target
330330========
331331
332−The default target of Idris is C. Compiling via :
332+The default target of Idris is C. Compiling via:
333333
334334::
335335
336336 $ idris hello.idr -o hello
337337
338−is equivalent to :
338+is equivalent to:
339339
340340::
341341
@@ -344,14 +344,14 @@ is equivalent to :
344344When the command above is used, a temporary C source is generated, which
345345is then compiled into an executable named ``hello``.
346346
347−In order to view the generated C code, compile via :
347+In order to view the generated C code, compile via:
348348
349349::
350350
351351 $ idris hello.idr -S -o hello.c
352352
353353To turn optimisations on, use the ``%flag C`` pragma within the code, as
354−is shown below :
354+is shown below:
355355
356356.. code-block:: idris
357357
@@ -368,7 +368,7 @@ is shown below :
368368
369369To compile the generated C with debugging information e.g. to use
370370``gdb`` to debug segmentation faults in Idris programs, use the
371−``%flag C`` pragma to include debugging symbols, as is shown below :
371+``%flag C`` pragma to include debugging symbols, as is shown below:
372372
373373.. code-block:: idris
374374
@@ -503,13 +503,13 @@ And for use in the browser:
503503
504504The given files will be added to the top of the generated code.
505505For library packages you can also use the ipkg objs option to include the
506−js file in the installation, and use
506+js file in the installation, and use:
507507
508508.. code-block:: idris
509509
510510 %include Node "package/external.js"
511511
512−This javascript and node backends idris will also lookup for the file on
512+The *JavaScript* and *NodeJS* backends of Idris will also lookup for the file
513513on that location.
514514
515515Including *NodeJS* modules
@@ -552,7 +552,7 @@ types themselves have types. For example:
552552 *universe> :t Vect
553553 Vect : Nat -> Type -> Type
554554
555−But what about the type of ``Type``? If we ask Idris it reports
555+But what about the type of ``Type``? If we ask Idris it reports:
556556
557557::
558558
@@ -560,8 +560,8 @@ But what about the type of ``Type``? If we ask Idris it reports
560560 Type : Type 1
561561
562562If ``Type`` were its own type, it would lead to an inconsistency due to
563−`Girard’s paradox <http://www.cs.cmu.edu/afs/cs.cmu.edu/user/kw/www/scans/girard72thesis.pdf>`_ , so internally there is a
564−*hierarchy* of types (or *universes*):
563+`Girard’s paradox <http://www.cs.cmu.edu/afs/cs.cmu.edu/user/kw/www/scans/girard72thesis.pdf>`_,
564+so internally there is a *hierarchy* of types (or *universes*):
565565
566566.. code-block:: idris
567567
docs/tutorial/modules.rst+8−11
@@ -53,8 +53,7 @@ Then, this gives a main program (in a file
5353 print (Btree.toList t)
5454
5555The same names can be defined in multiple modules: names are *qualified* with
56−the name of the module. The names defined in the ``Btree`` module are, in
57−full:
56+the name of the module. The names defined in the ``Btree`` module are, in full:
5857
5958+ ``Btree.BTree``
6059+ ``Btree.Leaf``
@@ -74,7 +73,7 @@ directories. For example, ``import foo.bar`` would import the file
7473``foo/bar.idr``, which would conventionally have the module declaration
7574``module foo.bar``. The only requirement for module names is that the
7675main module, with the ``main`` function, must be called
77−``Main``—although its filename need not be ``Main.idr``.
76+``Main`` — although its filename need not be ``Main.idr``.
7877
7978Export Modifiers
8079================
@@ -82,18 +81,16 @@ Export Modifiers
8281Idris allows for fine-grained control over the visibility of a
8382module's contents. By default, all names defined in a module are kept
8483private. This aides in specification of a minimal interface and for
85−internal details to be left hidden. Idris allows for functions,
84+internal details to be left hidden. Idris allows for functions,
8685types, and interfaces to be marked as: ``private``, ``export``, or
87−``public export``. Their general meaning is as follows:
86+``public export``. Their general meaning is as follows:
8887
89−- ``private`` meaning that it's not exported at all. This is the
90− default.
88+- ``private`` meaning that it's not exported at all. This is the default.
9189
9290- ``export`` meaning that its top level type is exported.
9391
9492- ``public export`` meaning that the entire definition is exported.
9593
96−
9794A further restriction in modifying the visibility is that definitions
9895must not refer to anything within a lower level of visibility. For
9996example, ``public export`` definitions cannot use private names, and
@@ -129,10 +126,9 @@ Meaning for Data Types
129126
130127For data types, the meanings are:
131128
132−- ``export`` the type constructor is exported
129+- ``export`` the type constructor is exported
133130
134−- ``public export`` the type constructor and data constructors are
135− exported
131+- ``public export`` the type constructor and data constructors are exported
136132
137133
138134Meaning for Interfaces
@@ -141,6 +137,7 @@ Meaning for Interfaces
141137For interfaces, the meanings are:
142138
143139- ``export`` the interface name is exported
140+
144141- ``public export`` the interface name, method names and default
145142 definitions are exported
146143
docs/tutorial/packages.rst+41−29
@@ -1,26 +1,31 @@
1+.. _sect-packages:
2+
13********
24Packages
35********
46
5−
6−Idris includes a simple build system for building packages and executables from a named package description file.
7−These files can be used with the Idris compiler to manage the development process .
7+Idris includes a simple build system for building packages and executables
8+from a named package description file. These files can be used with the
9+Idris compiler to manage the development process .
810
911Package Descriptions
1012====================
1113
1214A package description includes the following:
1315
14−+ A header, consisting of the keyword package followed by the package
16++ A header, consisting of the keyword ``package`` followed by a package
1517 name. Package names can be any valid Idris identifier. The iPKG
1618 format also takes a quoted version that accepts any valid filename.
17−+ Fields describing package contents, ``<field> = <value>``
19+
20++ Fields describing package contents, ``<field> = <value>``.
1821
1922At least one field must be the modules field, where the value is a
20−comma separated list of modules. For example, given an idris package
23+comma separated list of modules. For example, given an idris package
2124``maths`` that has modules ``Maths.idr``, ``Maths.NumOps.idr``,
2225``Maths.BinOps.idr``, and ``Maths.HexOps.idr``, the corresponding
23−package file would be::
26+package file would be:
27+
28+::
2429
2530 package maths
2631
@@ -38,7 +43,6 @@ of the main Idris repository, and in `third-party libraries
3843Using Package files
3944===================
4045
41−
4246Idris itself is aware about packages, and special commands are
4347available to help with, for example, building packages, installing
4448packages, and cleaning packages. For instance, given the ``maths``
@@ -54,7 +58,9 @@ package from earlier we can use Idris as follows:
5458
5559Once the maths package has been installed, the command line option
5660``--package maths`` makes it accessible (abbreviated to ``-p maths``).
57−For example::
61+For example:
62+
63+::
5864
5965 idris -p maths Main.idr
6066
@@ -66,20 +72,18 @@ The integrated build system includes a simple testing framework.
6672This framework collects functions listed in the ``ipkg`` file under ``tests``.
6773All test functions must return ``IO ()``.
6874
69−
7075When you enter ``idris --testpkg yourmodule.ipkg``,
7176the build system creates a temporary file in a fresh environment on your machine
7277by listing the ``tests`` functions under a single ``main`` function.
7378It compiles this temporary file to an executable and then executes it.
7479
75−
7680The tests themselves are responsible for reporting their success or failure.
7781Test functions commonly use ``putStrLn`` to report test results.
7882The test framework does not impose any standards for reporting and consequently
7983does not aggregate test results.
8084
81−
82−For example, lets take the following list of functions that are defined in a module called ``NumOps`` for a sample package ``maths``.
85+For example, lets take the following list of functions that are defined in a
86+module called ``NumOps`` for a sample package ``maths``:
8387
8488.. name: Math/NumOps.idr
8589.. code-block:: idris
@@ -94,7 +98,8 @@ For example, lets take the following list of functions that are defined in a mod
9498 triple : Num a => a -> a
9599 triple a = a + double a
96100
97−A simple test module, with a qualified name of ``Test.NumOps`` can be declared as
101+
102+A simple test module, with a qualified name of ``Test.NumOps`` can be declared as:
98103
99104.. name: Math/TestOps.idr
100105.. code-block:: idris
@@ -122,8 +127,11 @@ A simple test module, with a qualified name of ``Test.NumOps`` can be declared a
122127 testTriple = assertNotEq (triple 2) 5
123128
124129
125−The functions ``assertEq`` and ``assertNotEq`` are used to run expected passing, and failing, equality tests.
126−The actual tests are ``testDouble`` and ``testTriple``, and are declared in the ``maths.ipkg`` file as follows::
130+The functions ``assertEq`` and ``assertNotEq`` are used to run expected passing,
131+and failing, equality tests. The actual tests are ``testDouble`` and ``testTriple``,
132+and are declared in the ``maths.ipkg`` file as follows:
133+
134+::
127135
128136 package maths
129137
@@ -134,7 +142,9 @@ The actual tests are ``testDouble`` and ``testTriple``, and are declared in the
134142 , Test.NumOps.testTriple
135143
136144
137−The testing framework can then be invoked using ``idris --testpkg maths.ipkg``::
145+The testing framework can then be invoked using ``idris --testpkg maths.ipkg``:
146+
147+::
138148
139149 > idris --testpkg maths.ipkg
140150 Type checking ./Maths/NumOps.idr
@@ -146,25 +156,27 @@ The testing framework can then be invoked using ``idris --testpkg maths.ipkg``::
146156Note how both tests have reported success by printing ``Test Passed``
147157as we arranged for with the ``assertEq`` and ``assertNoEq`` functions.
148158
149−Package Dependencies Using Atom
159+Package Dependencies Using Atom
150160===============================
151161
152−If you are using the Atom editor and have a dependency on another package,
153−corresponding to for instance ``import Lightyear`` or ``import Pruviloj``,
154−you need to let Atom know that it should be loaded. The easiest way to
155−accomplish that is with a .ipkg file. The general contents of an ipkg file
156−will be described in the next section of the tutorial, but for now here is
157−a simple recipe for this trivial case.
162+If you are using the Atom editor and have a dependency on another package,
163+corresponding to for instance ``import Lightyear`` or ``import Pruviloj``,
164+you need to let Atom know that it should be loaded. The easiest way to
165+accomplish that is with a .ipkg file. The general contents of an ipkg file
166+will be described in the next section of the tutorial, but for now here is
167+a simple recipe for this trivial case:
168+
169+- Create a folder myProject.
158170
159−- Create a folder myProject.
171+- Add a file myProject.ipkg containing just a couple of lines:
160172
161−- Add a file myProject.ipkg containing just a couple of lines:
173+.. code-block:: idris
162174
163−``package myProject``
175+ package myProject
164176
165−``pkgs = pruviloj, lightyear``
177+ pkgs = pruviloj, lightyear
166178
167−- In Atom, use the File menu to Open Folder myProject.
179+- In Atom, use the File menu to Open Folder myProject.
168180
169181More information
170182================
docs/tutorial/syntax.rst+4−4
@@ -34,7 +34,7 @@ rule, and the right hand side describes its expansion. The syntax rule
3434itself consists of:
3535
3636- **Keywords** — here, ``if``, ``then`` and ``else``, which must be
37− valid identifiers
37+ valid identifiers.
3838
3939- **Non-terminals** — included in square brackets, ``[test]``, ``[t]``
4040 and ``[e]`` here, which stand for arbitrary expressions. To avoid
@@ -44,9 +44,9 @@ itself consists of:
4444- **Names** — included in braces, which stand for names which may be
4545 bound on the right hand side.
4646
47−- **Symbols** — included in quotations marks, e.g. ``:=``. This can
47+- **Symbols** — included in quotations marks, e.g. ``":="``. This can
4848 also be used to include reserved words in syntax rules, such as
49− ``let`` or ``in``.
49+ ``"let"`` or ``"in"``.
5050
5151The limitations on the form of a syntax rule are that it must include
5252at least one symbol or keyword, and there must be no repeated
@@ -63,7 +63,7 @@ recursive. The following syntax extensions would therefore be valid:
6363 syntax select [x] from [t] "where" [w] = SelectWhere x t w;
6464 syntax select [x] from [t] = Select x t;
6565
66−Syntax macros can be further restricted to apply only in patterns (i.e.,
66+Syntax macros can be further restricted to apply only in patterns (i.e.
6767only on the left hand side of a pattern match clause) or only in terms
6868(i.e. everywhere but the left hand side of a pattern match clause) by
6969being marked as ``pattern`` or ``term`` syntax rules. For example, we
docs/tutorial/theorems.rst+3−3
@@ -115,8 +115,8 @@ We can do the same for the reduction behaviour of plus on successors:
115115
116116Even for trivial theorems like these, the proofs are a little tricky to
117117construct in one go. When things get even slightly more complicated, it
118−becomes too much to think about to construct proofs in this ‘batch
119−mode’.
118+becomes too much to think about to construct proofs in this “batch
119+mode”.
120120
121121Idris provides interactive editing capabilities, which can help with
122122building proofs. For more details on building proofs interactively in
@@ -383,7 +383,7 @@ will always be smaller than ``(x :: xs)``:
383383 = qsort (filter (< x) xs) ++
384384 (x :: qsort (filter (>= x) xs))
385385
386−The function ``assert_smaller``, defined in the Prelude, is intended to
386+The function ``assert_smaller``, defined in the prelude, is intended to
387387address this problem:
388388
389389.. code-block:: idris
docs/tutorial/typesfuns.rst+22−30
@@ -13,8 +13,7 @@ manipulation, and ``Ptr`` which represents foreign pointers. There are
1313also several data types declared in the library, including ``Bool``,
1414with values ``True`` and ``False``. We can declare some constants with
1515these types. Enter the following into a file ``Prims.idr`` and load it
16−into the Idris interactive environment by typing ``idris
17−Prims.idr``:
16+into the Idris interactive environment by typing ``idris Prims.idr``:
1817
1918.. code-block:: idris
2019
@@ -38,7 +37,7 @@ collection of declarations and definitions. In this example no imports
3837have been specified. However Idris programs can consist of several
3938modules and the definitions in each module each have their own
4039namespace. This is discussed further in Section
41−:ref:`sect-namespaces`). When writing Idris programs both the order in which
40+:ref:`sect-namespaces`. When writing Idris programs both the order in which
4241definitions are given and indentation are significant. Functions and
4342data types must be defined before use, incidentally each definition must
4443have a type declaration, for example see ``x : Int``, ``foo :
@@ -343,7 +342,7 @@ Vectors
343342
344343A standard example of a dependent data type is the type of “lists with
345344length”, conventionally called vectors in the dependent type
346−literature. They are available as part of the Idris library, by
345+literature. They are available as part of the Idris library, by
347346importing ``Data.Vect``, or we can declare them as follows:
348347
349348.. code-block:: idris
@@ -521,8 +520,8 @@ help document a function by making the purpose of an argument more
521520clear.
522521
523522Furthermore, ``{}`` can be used to pattern match on the left hand side, i.e.
524−``{var = pat}`` gets an implicit variable and attempts to pattern match on "pat";
525−For example :
523+``{var = pat}`` gets an implicit variable and attempts to pattern match on “pat”;
524+For example:
526525
527526.. code-block:: idris
528527
@@ -559,7 +558,6 @@ vector. For example:
559558 inVect : IsElem 5 Main.testVec
560559 inVect = There (There Here)
561560
562−
563561.. important:: Implicit Arguments and Scope
564562
565563 Within the type signature the typechecker will treat all variables
@@ -569,7 +567,6 @@ vector. For example:
569567 ``testVec``. In the example above, we have assumed that the code
570568 lives within the ``Main`` module.
571569
572−
573570If the same implicit arguments are being used a lot, it can make a
574571definition difficult to read. To avoid this problem, a ``using`` block
575572gives the types and ordering of any implicit arguments which can
@@ -582,15 +579,13 @@ appear within the block:
582579 Here : IsElem x (x :: xs)
583580 There : IsElem x xs -> IsElem x (y :: xs)
584581
585−
586−
587582Note: Declaration Order and ``mutual`` blocks
588583~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
589584
590585In general, functions and data types must be defined before use, since
591586dependent types allow functions to appear as part of types, and type
592587checking can rely on how particular functions are defined (though this
593−is only true of total functions; see Section :ref:`sect-totality`)).
588+is only true of total functions; see Section :ref:`sect-totality`).
594589However, this restriction can be relaxed by using a ``mutual`` block,
595590which allows data types and functions to be defined simultaneously:
596591
@@ -673,7 +668,7 @@ Note that several of these return ``Either``, since they may fail.
673668I/O programs will typically need to sequence actions, feeding the
674669output of one computation into the input of the next. ``IO`` is an
675670abstract type, however, so we can’t access the result of a computation
676−directly. Instead, we sequence operations with ``do`` notation:
671+directly. Instead, we sequence operations with ``do`` notation:
677672
678673.. code-block:: idris
679674
@@ -713,7 +708,7 @@ not always the best approach. Consider the following function:
713708
714709This function uses one of the ``t`` or ``e`` arguments, but not both
715710(in fact, this is used to implement the ``if...then...else`` construct
716−as we will see later. We would prefer if *only* the argument which was
711+as we will see later). We would prefer if *only* the argument which was
717712used was evaluated. To achieve this, Idris provides a ``Lazy``
718713data type, which allows evaluation to be suspended:
719714
@@ -797,7 +792,7 @@ infinite loop and cause a stack overflow.
797792To fix this we must add explicit ``Inf`` declarations to the constructor
798793parameter types, since codata will not add it to constructor parameters of a
799794**different** type from the one being defined. For example, the following
800−outputs "1".
795+outputs ``1``.
801796
802797.. code-block:: idris
803798
@@ -902,7 +897,7 @@ For more details of the functions available on ``List`` and
902897
903898- ``libs/base/Data/VectType.idr``
904899
905−Functions include filtering, appending, reversing, and so on.
900+Functions include filtering, appending, reversing, and so on.
906901
907902Aside: Anonymous functions and operator sections
908903~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -999,7 +994,7 @@ Dependent Pairs
999994---------------
1000995
1001996Dependent pairs allow the type of the second element of a pair to depend
1002−on the value of the first element.
997+on the value of the first element:
1003998
1004999.. code-block:: idris
10051000
@@ -1009,7 +1004,7 @@ on the value of the first element.
10091004Again, there is syntactic sugar for this. ``(a : A ** P)`` is the type
10101005of a pair of A and P, where the name ``a`` can occur inside ``P``.
10111006``( a ** p )`` constructs a value of this type. For example, we can
1012−pair a number with a ``Vect`` of a particular length.
1007+pair a number with a ``Vect`` of a particular length:
10131008
10141009.. code-block:: idris
10151010
@@ -1017,7 +1012,7 @@ pair a number with a ``Vect`` of a particular length.
10171012 vec = (2 ** [3, 4])
10181013
10191014If you like, you can write it out the long way, the two are precisely
1020−equivalent.
1015+equivalent:
10211016
10221017.. code-block:: idris
10231018
@@ -1070,7 +1065,7 @@ intermediate values:
10701065
10711066We will see more on ``with`` notation later.
10721067
1073−Dependent pairs are sometimes referred to as “sigma types”.
1068+Dependent pairs are sometimes referred to as “Sigma types”.
10741069
10751070Records
10761071-------
@@ -1080,7 +1075,7 @@ Records
10801075automatically generating field access and update functions. Unlike
10811076the syntax used for data structures, records in Idris follow a
10821077different syntax to that seen with Haskell. For example, we can
1083−represent a person's name and age in a record:
1078+represent a person’s name and age in a record:
10841079
10851080.. code-block:: idris
10861081
@@ -1092,12 +1087,11 @@ represent a person's name and age in a record:
10921087 fred : Person
10931088 fred = MkPerson "Fred" "Joe" "Bloggs" 30
10941089
1095−
10961090The constructor name is provided using the ``constructor`` keyword,
10971091and the *fields* are then given which are in an indented block
10981092following the `where` keyword (here, ``firstName``, ``middleName``,
10991093``lastName``, and ``age``). You can declare multiple fields on a
1100−single line, provided that they have the same type. The field names
1094+single line, provided that they have the same type. The field names
11011095can be used to access the field values:
11021096
11031097::
@@ -1171,7 +1165,7 @@ syntax:
11711165 record { a->b->c = val } x
11721166
11731167This returns a new record, with the field accessed by the path
1174−``a->b->c`` set to ``val``. The syntax is first class, i.e. ``record {
1168+``a->b->c`` set to ``val``. The syntax is first class, i.e. ``record {
11751169a->b->c = val }`` itself has a function type. Symmetrically, the field
11761170can also be accessed with the following syntax:
11771171
@@ -1196,12 +1190,10 @@ name. For example, a pair type could be defined as follows:
11961190 fst : a
11971191 snd : b
11981192
1199−
12001193Using the ``class`` record from earlier, the size of the class can be
12011194restricted using a ``Vect`` and the size included in the type by parameterising
12021195the record with the size. For example:
12031196
1204−
12051197.. code-block:: idris
12061198
12071199 record SizedClass (size : Nat) where
@@ -1214,7 +1206,7 @@ function from earlier, since that would change the size of the class. A
12141206function to add a student must now specify in the type that the
12151207size of the class has been increased by one. As the size is specified
12161208using natural numbers, the new value can be incremented using the
1217−``S`` constructor.
1209+``S`` constructor:
12181210
12191211.. code-block:: idris
12201212
@@ -1327,7 +1319,7 @@ matching ``let`` and lambda bindings. It will *only* work if:
13271319- Each branch *matches* a value of the same type, and *returns* a
13281320 value of the same type.
13291321
1330−- The type of the result is "known". i.e. the type of the expression
1322+- The type of the result is “known”. i.e. the type of the expression
13311323 can be determined *without* type checking the ``case``-expression
13321324 itself.
13331325
@@ -1337,7 +1329,7 @@ Totality
13371329Idris distinguishes between *total* and *partial* functions.
13381330A total function is a function that either:
13391331
1340−+ Terminates for all possible inputs, or
1332++ Terminates for all possible inputs, or
13411333+ Produces a non-empty, finite, prefix of a possibly infinite result
13421334
13431335If a function is total, we can consider its type a precise description of what
@@ -1345,12 +1337,12 @@ that function will do. For example, if we have a function with a return
13451337type of ``String`` we know something different, depending on whether or not
13461338it's total:
13471339
1348−+ If it's total, it will return a value of type ``String`` in finite time
1340++ If it's total, it will return a value of type ``String`` in finite time;
13491341+ If it's partial, then as long as it doesn't crash or enter an infinite loop,
13501342 it will return a ``String``.
13511343
13521344Idris makes this distinction so that it knows which functions are safe to
1353−evaluate while type checking (as we've seen with :ref:`sect-fctypes`). After all,
1345+evaluate while type checking (as we've seen with :ref:`sect-fctypes`). After all,
13541346if it tries to evaluate a function during type checking which doesn't
13551347terminate, then type checking won't terminate!
13561348Therefore, only total functions will be evaluated during type checking.
docs/tutorial/views.rst+3−3
@@ -103,14 +103,14 @@ patterns left of the ``|``. That is:
103103 ``Parity (n + n)`` from the ``Even`` constructor definition. So
104104 ``(j + j)`` replaces ``k`` on the left side of ``|``, and the
105105 ``Even`` constructor appears on the right side. The natural number
106− ``j`` in the refined pattern can be used on the ride side of the
106+ ``j`` in the refined pattern can be used on the right side of the
107107 ``=`` sign.
108108
109109- Otherwise, when ``parity k`` evaluates to ``Odd``, the original
110110 argument ``k`` is refined to ``S (j + j)`` according to ``Parity (S
111111 (n + n))`` from the ``Odd`` constructor definition, and ``Odd`` now
112− appears on the ride side of ``|``, again with the natural number
113− ``j`` used on the ride side of the ``=`` sign.
112+ appears on the right side of ``|``, again with the natural number
113+ ``j`` used on the right side of the ``=`` sign.
114114
115115Note that there is a function in the patterns (``+``) and repeated
116116occurrences of ``j`` - this is allowed because another argument has
idris-tutorial.pdf

Binary file not shown.

idris.cabal+5−5
@@ -1,5 +1,5 @@
11Name: idris
2−Version: 1.2.0
2+Version: 1.3.0
33License: BSD3
44License-file: LICENSE
55Author: Edwin Brady
@@ -100,7 +100,7 @@ source-repository head
100100
101101custom-setup
102102 setup-depends:
103− Cabal >= 1.10 && <2.1,
103+ Cabal >= 1.10 && <2.3,
104104 base >= 4 && <5,
105105 directory,
106106 filepath,
@@ -270,7 +270,7 @@ Library
270270 , BuildFlags_idris
271271
272272 Build-depends: base >=4 && <5
273− , aeson >= 0.6 && < 1.3
273+ , aeson >= 0.6 && < 1.4
274274 , annotated-wl-pprint >= 0.7 && < 0.8
275275 , ansi-terminal < 0.9
276276 , ansi-wl-pprint < 0.7
@@ -286,7 +286,7 @@ Library
286286 , deepseq < 1.5
287287 , directory >= 1.2.2.0 && < 1.2.3.0 || > 1.2.3.0
288288 , filepath < 1.5
289− , fingertree >= 0.1 && < 0.2
289+ , fingertree >= 0.1.4.1 && < 0.2
290290 , haskeline >= 0.7 && < 0.8
291291 , ieee754 >= 0.7 && < 0.9
292292 , megaparsec >= 6.2
@@ -309,7 +309,7 @@ Library
309309 , vector-binary-instances < 0.3
310310 , zip-archive > 0.2.3.5 && < 0.4
311311 , fsnotify >= 0.2 && < 2.2
312− , async < 2.2
312+ , async < 2.3
313313
314314 if !impl(ghc >= 8.0)
315315 Build-Depends: semigroups == 0.18.*
libs/base/Data/Nat/Views.idr+1−1
@@ -14,7 +14,7 @@ data HalfRec : Nat -> Type where
1414 HalfRecOdd : {n : Nat} -> (rec : Lazy (HalfRec n)) -> HalfRec (S (n + n))
1515
1616||| Covering function for the `Half` view
17−export
17+public export
1818half : (n : Nat) -> Half n
1919half Z = HalfEven {n=0}
2020half (S k) with (half k)
libs/base/Makefile+1−1
@@ -1,4 +1,4 @@
1−IDRIS := idris
1+IDRIS ?= idris
22PKG := base
33
44build:
libs/base/System/Concurrency/Raw.idr+9−10
@@ -8,7 +8,7 @@ import System
88
99||| Send a message of any type to the thread with the given thread id
1010||| Returns channel ID if the message was sent successfully, 0 otherwise
11−|||
11+|||
1212||| @channel an ID of a specific channel to send the message on. If 0,
1313||| the receiver will create a new channel ID
1414sendToThread : (thread_id : Ptr) -> (channel : Int) -> a -> IO Int
@@ -29,7 +29,7 @@ checkMsgs = do me <- getMyVM
2929checkMsgsTimeout : Int -> IO Bool
3030checkMsgsTimeout timeout
3131 = do me <- getMyVM
32− msgs <- foreign FFI_C "idris_checkMessagesTimeout"
32+ msgs <- foreign FFI_C "idris_checkMessagesTimeout"
3333 (Ptr -> Int -> IO Ptr) me timeout
3434 null <- nullPtr msgs
3535 pure (not null)
@@ -43,7 +43,7 @@ channel_id : Ptr -> IO Int
4343channel_id msg = foreign FFI_C "idris_getChannel" (Ptr -> IO Int) msg
4444
4545||| Check for messages initiating a conversation in the process inbox.
46−||| Returns either 'Nothing', if none, or 'Just (pid, channel)' as pid
46+||| Returns either 'Nothing', if none, or 'Just (pid, channel)' as pid
4747||| of sender and new channel id.
4848listenMsgs : IO (Maybe (Ptr, Int))
4949listenMsgs = do me <- getMyVM
@@ -58,7 +58,7 @@ listenMsgs = do me <- getMyVM
5858||| Check for messages from a specific sender/channel in the process inbox
5959||| If channel is '0', accept on any channel.
6060checkMsgsFrom : Ptr -> (channel : Int) -> IO Bool
61−checkMsgsFrom sender channel
61+checkMsgsFrom sender channel
6262 = do me <- getMyVM
6363 msgs <- foreign FFI_C "idris_checkMessagesFrom" (Ptr -> Int -> Ptr -> IO Ptr)
6464 me channel sender
@@ -73,6 +73,7 @@ getMsg : IO a
7373getMsg {a} = do me <- getMyVM
7474 m <- foreign FFI_C "idris_recvMessage" (Ptr -> IO Ptr) me
7575 MkRaw x <- foreign FFI_C "idris_getMsg" (Ptr -> IO (Raw a)) m
76+ foreign FFI_C "idris_freeMsg" (Ptr -> IO ()) m
7677 pure x
7778
7879||| Check inbox for messages. If there are none, blocks until a message
@@ -80,9 +81,9 @@ getMsg {a} = do me <- getMyVM
8081||| Note that this is not at all type safe! It is intended to be used in
8182||| a type safe wrapper.
8283getMsgWithSender : IO (Ptr, Int, a)
83−getMsgWithSender {a}
84+getMsgWithSender {a}
8485 = do me <- getMyVM
85− m <- foreign FFI_C "idris_recvMessage"
86+ m <- foreign FFI_C "idris_recvMessage"
8687 (Ptr -> IO Ptr) me
8788 MkRaw x <- foreign FFI_C "idris_getMsg" (Ptr -> IO (Raw a)) m
8889 vm <- sender m
@@ -94,12 +95,12 @@ getMsgWithSender {a}
9495||| blocks until a message arrives. Returns `Nothing` if the sender isn't
9596||| alive
9697getMsgFrom : Ptr -> (channel : Int) -> IO (Maybe a)
97−getMsgFrom {a} sender channel
98+getMsgFrom {a} sender channel
9899 = do me <- getMyVM
99100 m <- foreign FFI_C "idris_recvMessageFrom"
100101 (Ptr -> Int -> Ptr -> IO Ptr) me channel sender
101102 null <- nullPtr m
102− if null
103+ if null
103104 then pure Nothing
104105 else do
105106 MkRaw x <- foreign FFI_C "idris_getMsg" (Ptr -> IO (Raw a)) m
@@ -110,5 +111,3 @@ stopThread : IO a
110111stopThread = do vm <- getMyVM
111112 MkRaw res <- foreign FFI_C "idris_stopThread" (Ptr -> IO (Raw a)) vm
112113 pure res
113−
114−
libs/contrib/CFFI/Types.idr+2−2
@@ -70,9 +70,9 @@ mutual
7070 alignOfCT I8 = 1
7171 alignOfCT I16 = 2
7272 alignOfCT I32 = 4
73− alignOfCT I64 = 8
73+ alignOfCT I64 = min prim__sizeofPtr 8
7474 alignOfCT FLOAT = 4
75− alignOfCT DOUBLE = 8
75+ alignOfCT DOUBLE = min prim__sizeofPtr 8
7676 alignOfCT PTR = prim__sizeofPtr
7777
7878 ||| Alignment requirement of the type
libs/contrib/Data/BoundedList.idr+15
@@ -1,6 +1,7 @@
11module Data.BoundedList
22
33import Data.Fin
4+import Data.Vect
45
56%access public export
67%default total
@@ -50,6 +51,20 @@ fromList : (xs : List a) -> BoundedList (length xs) a
5051fromList [] = []
5152fromList (x :: xs) = x :: fromList xs
5253
54+--------------------------------------------------------------------------------
55+-- Conversions to and from vector
56+--------------------------------------------------------------------------------
57+
58+||| Convert bounded list to vector.
59+toVect : (xs : BoundedList n a) -> Vect (finToNat (length xs)) a
60+toVect [] = []
61+toVect (x :: xs) = x :: toVect xs
62+
63+||| Convert vector to bounded list.
64+fromVect : (xs : Vect n a) -> BoundedList n a
65+fromVect [] = []
66+fromVect (x :: xs) = x :: fromVect xs
67+
5368--------------------------------------------------------------------------------
5469-- Building (bigger) bounded lists
5570--------------------------------------------------------------------------------
libs/contrib/Data/Nat.idrnew file+8
@@ -0,0 +1,8 @@
1+module Data.Nat
2+
3+%default total
4+
5+diff : Nat -> Nat -> Nat
6+diff k Z = k
7+diff Z j = j
8+diff (S k) (S j) = diff k j
libs/contrib/Data/Sign.idr+29
@@ -5,6 +5,35 @@ module Data.Sign
55||| A representation of signs for signed datatypes such as `ZZ`
66data Sign = Plus | Zero | Minus
77
8+opposite : Sign -> Sign
9+opposite Plus = Minus
10+opposite Zero = Zero
11+opposite Minus = Plus
12+
13+multiply : Sign -> Sign -> Sign
14+multiply Zero _ = Zero
15+multiply _ Zero = Zero
16+multiply Plus x = x
17+multiply Minus x = opposite x
18+
819||| Discover the sign of some type
920interface Signed t where
1021 total sign : t -> Sign
22+
23+Signed Int where
24+ sign x with (compare x 0)
25+ | LT = Minus
26+ | EQ = Zero
27+ | GT = Plus
28+
29+Signed Integer where
30+ sign x with (compare x 0)
31+ | LT = Minus
32+ | EQ = Zero
33+ | GT = Plus
34+
35+Signed Double where
36+ sign x with (compare x 0.0)
37+ | LT = Minus
38+ | EQ = Zero
39+ | GT = Plus
libs/contrib/Makefile+1−1
@@ -1,4 +1,4 @@
1−IDRIS := idris
1+IDRIS ?= idris
22PKG := contrib
33
44build:
libs/contrib/Network/Socket.idr+20−1
@@ -133,7 +133,7 @@ send sock dat = do
133133||| + `ResultCode` :: The result of the underlying function.
134134|||
135135||| @sock The socket on which to receive the message.
136−||| @len How much of the data to send.
136+||| @len How much of the data to receive.
137137recv : (sock : Socket)
138138 -> (len : ByteLength)
139139 -> IO (Either SocketError (String, ResultCode))
@@ -164,6 +164,25 @@ recv sock len = do
164164 freeRecvStruct (RSPtr recv_struct_ptr)
165165 pure $ Right (payload, recv_res)
166166
167+||| Receive all the remaining data on the specified socket.
168+|||
169+||| Returns on failure a `SocketError`
170+||| Returns on success the payload `String`
171+|||
172+||| @sock The socket on which to receive the message.
173+partial
174+recvAll : (sock : Socket) -> IO (Either SocketError String)
175+recvAll sock = recvRec sock [] 64
176+ where
177+ partial
178+ recvRec : Socket -> List String -> ByteLength -> IO (Either SocketError String)
179+ recvRec sock acc n = do res <- recv sock n
180+ case res of
181+ Left 0 => pure (Right $ concat $ reverse acc)
182+ Left c => pure (Left c)
183+ Right (str, _) => let n' = min (n * 2) 65536 in
184+ recvRec sock (str :: acc) n'
185+
167186||| Send a message.
168187|||
169188||| Returns on failure a `SocketError`
libs/contrib/Text/Parser.idr+1−1
@@ -118,7 +118,7 @@ mutual
118118||| list of values from `p`, along with a proof that the resulting list is
119119||| non-empty.
120120someTill' : {c : Bool} ->
121− (end : Grammar tok c a) ->
121+ (end : Grammar tok c e) ->
122122 (p : Grammar tok True a) ->
123123 Grammar tok True (xs : List a ** NonEmpty xs)
124124someTill' end p
libs/contrib/contrib.ipkg+1
@@ -43,6 +43,7 @@ modules = CFFI
4343 , Data.Matrix.Algebraic
4444 , Data.Matrix.Numeric
4545
46+ , Data.Nat
4647 , Data.Nat.Parity
4748 , Data.Nat.DivMod
4849 , Data.Nat.DivMod.IteratedSubtraction
libs/effects/Makefile+1−1
@@ -1,4 +1,4 @@
1−IDRIS := idris
1+IDRIS ?= idris
22PKG := effects
33
44build:
libs/prelude/Decidable/Equality.idr+10−7
@@ -157,7 +157,10 @@ implementation DecEq a => DecEq (List a) where
157157
158158
159159-- For the primitives, we have to cheat because we don't have access to their
160−-- internal implementations.
160+-- internal implementations. We use believe_me for the inequality proofs
161+-- because we don't them to reduce (and they should never be needed anyway...)
162+-- A postulate would be better, but erasure analysis may think they're needed
163+-- for computation in a higher order setting.
161164
162165--------------------------------------------------------------------------------
163166-- Int
@@ -170,7 +173,7 @@ implementation DecEq Int where
170173 where primitiveEq : x = y
171174 primitiveEq = really_believe_me (Refl {x})
172175 primitiveNotEq : x = y -> Void
173− primitiveNotEq = really_believe_me (id {a = x = y})
176+ primitiveNotEq prf = believe_me {b = Void} ()
174177
175178--------------------------------------------------------------------------------
176179-- Char
@@ -183,7 +186,7 @@ implementation DecEq Char where
183186 where primitiveEq : x = y
184187 primitiveEq = really_believe_me (Refl {x})
185188 primitiveNotEq : x = y -> Void
186− primitiveNotEq = really_believe_me (id {a = x = y})
189+ primitiveNotEq prf = believe_me {b = Void} ()
187190
188191--------------------------------------------------------------------------------
189192-- Integer
@@ -196,7 +199,7 @@ implementation DecEq Integer where
196199 where primitiveEq : x = y
197200 primitiveEq = really_believe_me (Refl {x})
198201 primitiveNotEq : x = y -> Void
199− primitiveNotEq = really_believe_me (id {a = x = y})
202+ primitiveNotEq prf = believe_me {b = Void} ()
200203
201204--------------------------------------------------------------------------------
202205-- String
@@ -209,7 +212,7 @@ implementation DecEq String where
209212 where primitiveEq : x = y
210213 primitiveEq = really_believe_me (Refl {x})
211214 primitiveNotEq : x = y -> Void
212− primitiveNotEq = really_believe_me (id {a = x = y})
215+ primitiveNotEq prf = believe_me {b = Void} ()
213216
214217--------------------------------------------------------------------------------
215218-- Ptr
@@ -222,7 +225,7 @@ implementation DecEq Ptr where
222225 where primitiveEq : x = y
223226 primitiveEq = really_believe_me (Refl {x})
224227 primitiveNotEq : x = y -> Void
225− primitiveNotEq = really_believe_me (id {a = x = y})
228+ primitiveNotEq prf = believe_me {b = Void} ()
226229
227230--------------------------------------------------------------------------------
228231-- ManagedPtr
@@ -235,4 +238,4 @@ implementation DecEq ManagedPtr where
235238 where primitiveEq : x = y
236239 primitiveEq = really_believe_me (Refl {x})
237240 primitiveNotEq : x = y -> Void
238− primitiveNotEq = really_believe_me (id {a = x = y})
241+ primitiveNotEq prf = believe_me {b = Void} ()
libs/prelude/Language/Reflection/Elab.idr+9
@@ -16,6 +16,7 @@ import Prelude.Maybe
1616import Prelude.Monad
1717import Prelude.Nat
1818import Language.Reflection
19+import Language.Reflection.Errors
1920
2021%access public export
2122
@@ -138,6 +139,7 @@ data Elab : Type -> Type where
138139 Prim__BindElab : {a, b : Type} -> Elab a -> (a -> Elab b) -> Elab b
139140
140141 Prim__Try : {a : Type} -> Elab a -> Elab a -> Elab a
142+ Prim__TryCatch : {a : Type} -> Elab a -> (Err -> Elab a) -> Elab a
141143 Prim__Fail : {a : Type} -> List ErrorReportPart -> Elab a
142144
143145 Prim__Env : Elab (List (TTName, Binder TT))
@@ -218,6 +220,13 @@ namespace Tactics
218220 implementation Monad Elab where
219221 x >>= f = Prim__BindElab x f
220222
223+ ||| `tryCatch t (\err => t')` will run `t`, and if it
224+ ||| fails, roll back the elaboration state and run `t'`,
225+ ||| but with access to the knowledge of why `t` failed.
226+ export
227+ tryCatch : Elab a -> (Err -> Elab a) -> Elab a
228+ tryCatch x f = Prim__TryCatch x f
229+
221230 ||| Halt elaboration with an error
222231 export
223232 fail : List ErrorReportPart -> Elab a
libs/prelude/Makefile+1−1
@@ -1,4 +1,4 @@
1−IDRIS := idris
1+IDRIS ?= idris
22PKG := prelude
33
44build:
libs/prelude/Prelude/File.idr+53−6
@@ -141,17 +141,64 @@ private
141141do_getFileSize : Ptr -> IO Int
142142do_getFileSize h = foreign FFI_C "fileSize" (Ptr -> IO Int) h
143143
144+private
145+do_getFileAccessTime : Ptr -> IO Integer
146+do_getFileAccessTime h =
147+ do MkRaw i <- foreign FFI_C "fileAccessTime" (Ptr -> IO (Raw Integer)) h
148+ pure i
149+
150+private
151+do_getFileModifiedTime : Ptr -> IO Integer
152+do_getFileModifiedTime h =
153+ do MkRaw i <- foreign FFI_C "fileModifiedTime" (Ptr -> IO (Raw Integer)) h
154+ pure i
155+
156+private
157+do_getFileStatusTime : Ptr -> IO Integer
158+do_getFileStatusTime h =
159+ do MkRaw i <- foreign FFI_C "fileStatusTime" (Ptr -> IO (Raw Integer)) h
160+ pure i
161+
144162||| Return the size of a File
145163||| Returns an error if the File is not an ordinary file (e.g. a directory)
146164||| Also note that this currently returns an Int, which may overflow if the
147165||| file is very big
148166export
149167fileSize : File -> IO (Either FileError Int)
150−fileSize (FHandle h) = do s <- do_getFileSize h
151− if (s < 0)
152− then do err <- getFileError
153− pure (Left err)
154− else pure (Right s)
168+fileSize (FHandle h)
169+ = do s <- do_getFileSize h
170+ if (s < 0)
171+ then do err <- getFileError
172+ pure (Left err)
173+ else pure (Right s)
174+
175+export
176+fileModifiedTime : File -> IO (Either FileError Integer)
177+fileModifiedTime (FHandle h)
178+ = do s <- do_getFileModifiedTime h
179+ if (s < 0)
180+ then do err <- getFileError
181+ pure (Left err)
182+ else pure (Right s)
183+
184+export
185+fileAccessTime : File -> IO (Either FileError Integer)
186+fileAccessTime (FHandle h)
187+ = do s <- do_getFileAccessTime h
188+ if (s < 0)
189+ then do err <- getFileError
190+ pure (Left err)
191+ else pure (Right s)
192+
193+export
194+fileStatusTime : File -> IO (Either FileError Integer)
195+fileStatusTime (FHandle h)
196+ = do s <- do_getFileStatusTime h
197+ if (s < 0)
198+ then do err <- getFileError
199+ pure (Left err)
200+ else pure (Right s)
201+
155202
156203private
157204do_fread : Ptr -> IO' l String
@@ -326,5 +373,5 @@ createDir d
326373export
327374changeDir : String -> IO Bool
328375changeDir dir
329− = do ok <- foreign FFI_C "chdir" (String -> IO Int) dir
376+ = do ok <- foreign FFI_C "idris_chdir" (String -> IO Int) dir
330377 pure (ok == 0)
libs/prelude/Prelude/Interactive.idr+1−1
@@ -81,7 +81,7 @@ getLine = getLine'
8181putChar : Char -> IO ()
8282putChar c = foreign FFI_C "putchar" (Int -> IO ()) (cast c)
8383
84−||| Write a singel character to stdout, with a trailing newline
84+||| Write a single character to stdout, with a trailing newline
8585putCharLn : Char -> IO ()
8686putCharLn c = putStrLn (singleton c)
8787
libs/prelude/Prelude/Maybe.idr+6
@@ -100,6 +100,12 @@ maybe_bind (Just x) k = k x
100100 (Just _) == Nothing = False
101101 (Just a) == (Just b) = a == b
102102
103+(Ord a) => Ord (Maybe a) where
104+ compare Nothing Nothing = EQ
105+ compare Nothing (Just _) = LT
106+ compare (Just _) Nothing = GT
107+ compare (Just a) (Just b) = compare a b
108+
103109||| Prioritised choice. Just like the `Alternative` implementation, the
104110||| `Semigroup` for `Maybe a` keeps the first succeeding computation.
105111|||
libs/pruviloj/Makefile+1−1
@@ -1,4 +1,4 @@
1−IDRIS := idris
1+IDRIS ?= idris
22PKG := pruviloj
33
44build:
man/idris.1+1−1
@@ -1,6 +1,6 @@
11.\" Manpage for Idris.
22.\" Contact <> to correct errors or typos.
3−.TH man 1 "7 January 2018" "1.2.0" "Idris man page"
3+.TH man 1 "26 May 2018" "1.3.0" "Idris man page"
44.SH NAME
55idris -\ a general purpose pure functional programming language with dependent types.
66.SH SYNOPSIS
rts/Makefile+8−12
@@ -1,30 +1,26 @@
11include ../config.mk
22
33OBJS = idris_rts.o idris_heap.o idris_gc.o idris_gmp.o idris_bitstring.o \
4− idris_opts.o idris_stats.o idris_utf8.o idris_stdfgn.o mini-gmp.o \
4+ idris_opts.o idris_stats.o idris_utf8.o idris_stdfgn.o \
55 idris_buffer.o getline.o idris_net.o
66HDRS = idris_rts.h idris_heap.h idris_gc.h idris_gmp.h idris_bitstring.h \
7− idris_opts.h idris_stats.h mini-gmp.h idris_stdfgn.h idris_net.h \
7+ idris_opts.h idris_stats.h idris_stdfgn.h idris_net.h \
88 idris_buffer.h idris_utf8.h getline.h
99CFLAGS := $(CFLAGS)
1010CFLAGS += $(GMP_INCLUDE_DIR) $(GMP) -DIDRIS_TARGET_OS="\"$(OS)\""
1111CFLAGS += -DIDRIS_TARGET_TRIPLE="\"$(MACHINE)\""
1212
13−# NOTE: This works around glibc 2.11 not declaring pthread_mutexattr_settype
14−# and PTHREAD_MUTEX_RECURSIVE by default, causing compilation failures on
15−# Debian 6 and Ubuntu 10.04 LTS.
16−ifeq ($(OS), unix)
17−ifneq ($(shell ldd --version | head -n 1 | grep 2.11),)
18− CFLAGS += -D_GNU_SOURCE
19−endif
20−endif
21−
2213ifeq ($(OS), windows)
2314 OBJS += windows/win_utils.o
2415else
2516 CFLAGS += -fPIC
2617endif
2718
19+ifndef IDRIS_GMP
20+ OBJS += mini-gmp.o
21+ HDRS += mini-gmp.h
22+endif
23+
2824LIBTARGET = libidris_rts.a
2925
3026build: $(LIBTARGET) $(DYLIBTARGET)
@@ -40,6 +36,6 @@ install :
4036clean :
4137 rm -f $(OBJS) $(LIBTARGET) $(DYLIBTARGET)
4238
43−idris_rts.o: idris_rts.h
39+$(OBJS): $(HDRS)
4440
4541.PHONY: build install clean
rts/idris_bitstring.c+247−513
@@ -2,824 +2,558 @@
22
33#include "idris_rts.h"
44
5−VAL idris_b8CopyForGC(VM *vm, VAL a) {
6− uint8_t A = a->info.bits8;
7− VAL cl = allocate(sizeof(Closure), 1);
8− SETTY(cl, CT_BITS8);
9− cl->info.bits8 = A;
10− return cl;
5+VAL idris_b8const(VM *vm, uint8_t a) {
6+ return MKINT(a);
117}
128
13−VAL idris_b16CopyForGC(VM *vm, VAL a) {
14− uint16_t A = a->info.bits16;
15− VAL cl = allocate(sizeof(Closure), 1);
16− SETTY(cl, CT_BITS16);
17− cl->info.bits16 = A;
18− return cl;
9+VAL idris_b16const(VM *vm, uint16_t a) {
10+ return MKINT(a);
1911}
2012
21−VAL idris_b32CopyForGC(VM *vm, VAL a) {
22− uint32_t A = a->info.bits32;
23− VAL cl = allocate(sizeof(Closure), 1);
13+VAL idris_b32const(VM *vm, uint32_t a) {
14+ Bits32 * cl = iallocate(vm, sizeof(*cl), 0);
2415 SETTY(cl, CT_BITS32);
25− cl->info.bits32 = A;
26− return cl;
16+ cl->bits32 = a;
17+ return (VAL)cl;
2718}
2819
29−VAL idris_b64CopyForGC(VM *vm, VAL a) {
30− uint64_t A = a->info.bits64;
31− VAL cl = allocate(sizeof(Closure), 1);
20+VAL idris_b64const(VM *vm, uint64_t a) {
21+ Bits64 * cl = iallocate(vm, sizeof(*cl), 0);
3222 SETTY(cl, CT_BITS64);
33− cl->info.bits64 = A;
34− return cl;
23+ cl->bits64 = a;
24+ return (VAL)cl;
3525}
3626
3727VAL idris_b8(VM *vm, VAL a) {
38− uint8_t A = GETINT(a);
39− VAL cl = allocate(sizeof(Closure), 0);
40− SETTY(cl, CT_BITS8);
41− cl->info.bits8 = (uint8_t) A;
42− return cl;
28+ return idris_b8const(vm, GETINT(a));
4329}
4430
4531VAL idris_b16(VM *vm, VAL a) {
46− uint16_t A = GETINT(a);
47− VAL cl = allocate(sizeof(Closure), 0);
48− SETTY(cl, CT_BITS16);
49− cl->info.bits16 = (uint16_t) A;
50− return cl;
32+ return idris_b16const(vm, GETINT(a));
5133}
5234
5335VAL idris_b32(VM *vm, VAL a) {
54− uint32_t A = GETINT(a);
55− VAL cl = allocate(sizeof(Closure), 0);
56− SETTY(cl, CT_BITS32);
57− cl->info.bits32 = (uint32_t) A;
58− return cl;
36+ return idris_b32const(vm, GETINT(a));
5937}
6038
6139VAL idris_b64(VM *vm, VAL a) {
62− uint64_t A = GETINT(a);
63− VAL cl = allocate(sizeof(Closure), 0);
64− SETTY(cl, CT_BITS64);
65− cl->info.bits64 = (uint64_t) A;
66− return cl;
40+ return idris_b64const(vm, GETINT(a));
6741}
6842
6943VAL idris_castB32Int(VM *vm, VAL a) {
70− return MKINT((i_int)a->info.bits32);
71−}
72−
73−VAL idris_b8const(VM *vm, uint8_t a) {
74− VAL cl = allocate(sizeof(Closure), 0);
75− SETTY(cl, CT_BITS8);
76− cl->info.bits8 = a;
77− return cl;
78−}
79−
80−VAL idris_b16const(VM *vm, uint16_t a) {
81− VAL cl = allocate(sizeof(Closure), 0);
82− SETTY(cl, CT_BITS16);
83− cl->info.bits16 = a;
84− return cl;
85−}
86−
87−VAL idris_b32const(VM *vm, uint32_t a) {
88− VAL cl = allocate(sizeof(Closure), 0);
89− SETTY(cl, CT_BITS32);
90− cl->info.bits32 = a;
91− return cl;
92−}
93−
94−VAL idris_b64const(VM *vm, uint64_t a) {
95− VAL cl = allocate(sizeof(Closure), 0);
96− SETTY(cl, CT_BITS64);
97− cl->info.bits64 = a;
98− return cl;
44+ return MKINT(GETBITS32(a));
9945}
10046
10147VAL idris_b8Plus(VM *vm, VAL a, VAL b) {
102− uint8_t A = a->info.bits8;
103− uint8_t B = b->info.bits8;
104− VAL cl = allocate(sizeof(Closure), 0);
105− SETTY(cl, CT_BITS8);
106− cl->info.bits8 = A + B;
107− return cl;
48+ uint8_t A = GETBITS8(a);
49+ uint8_t B = GETBITS8(b);
50+ return idris_b8const(vm, A + B);
10851}
10952
11053VAL idris_b8Minus(VM *vm, VAL a, VAL b) {
111− uint8_t A = a->info.bits8;
112− uint8_t B = b->info.bits8;
113− VAL cl = allocate(sizeof(Closure), 0);
114− SETTY(cl, CT_BITS8);
115− cl->info.bits8 = A - B;
116− return cl;
54+ uint8_t A = GETBITS8(a);
55+ uint8_t B = GETBITS8(b);
56+ return idris_b8const(vm, A - B);
11757}
11858
11959VAL idris_b8Times(VM *vm, VAL a, VAL b) {
120− uint8_t A = a->info.bits8;
121− uint8_t B = b->info.bits8;
122− VAL cl = allocate(sizeof(Closure), 0);
123− SETTY(cl, CT_BITS8);
124− cl->info.bits8 = A * B;
125− return cl;
60+ uint8_t A = GETBITS8(a);
61+ uint8_t B = GETBITS8(b);
62+ return idris_b8const(vm, A * B);
12663}
12764
12865VAL idris_b8UDiv(VM *vm, VAL a, VAL b) {
129− uint8_t A = a->info.bits8;
130− uint8_t B = b->info.bits8;
131− VAL cl = allocate(sizeof(Closure), 0);
132− SETTY(cl, CT_BITS8);
133− cl->info.bits8 = A / B;
134− return cl;
66+ uint8_t A = GETBITS8(a);
67+ uint8_t B = GETBITS8(b);
68+ return idris_b8const(vm, A / B);
13569}
13670
13771VAL idris_b8SDiv(VM *vm, VAL a, VAL b) {
138− uint8_t A = a->info.bits8;
139− uint8_t B = b->info.bits8;
140− VAL cl = allocate(sizeof(Closure), 0);
141− SETTY(cl, CT_BITS8);
142− cl->info.bits8 = (uint8_t) (((int8_t) A) / ((int8_t) B));
143− return cl;
72+ int8_t A = GETBITS8(a);
73+ int8_t B = GETBITS8(b);
74+ return idris_b8const(vm, A / B);
14475}
14576
14677VAL idris_b8URem(VM *vm, VAL a, VAL b) {
147− uint8_t A = a->info.bits8;
148− uint8_t B = b->info.bits8;
149− VAL cl = allocate(sizeof(Closure), 0);
150− SETTY(cl, CT_BITS8);
151− cl->info.bits8 = A % B;
152− return cl;
78+ uint8_t A = GETBITS8(a);
79+ uint8_t B = GETBITS8(b);
80+ return idris_b8const(vm, A % B);
15381}
15482
15583VAL idris_b8SRem(VM *vm, VAL a, VAL b) {
156− uint8_t A = a->info.bits8;
157− uint8_t B = b->info.bits8;
158− VAL cl = allocate(sizeof(Closure), 0);
159− SETTY(cl, CT_BITS8);
160− cl->info.bits8 = (uint8_t) (((int8_t) A) % ((int8_t) B));
161− return cl;
84+ int8_t A = GETBITS8(a);
85+ int8_t B = GETBITS8(b);
86+ return idris_b8const(vm, A % B);
16287}
16388
16489VAL idris_b8Lt(VM *vm, VAL a, VAL b) {
165− return MKINT((i_int) (a->info.bits8 < b->info.bits8));
90+ return MKINT((i_int) (GETBITS8(a) < GETBITS8(b)));
16691}
16792
16893VAL idris_b8Gt(VM *vm, VAL a, VAL b) {
169− return MKINT((i_int) (a->info.bits8 > b->info.bits8));
94+ return MKINT((i_int) (GETBITS8(a) > GETBITS8(b)));
17095}
17196
17297VAL idris_b8Eq(VM *vm, VAL a, VAL b) {
173− return MKINT((i_int) (a->info.bits8 == b->info.bits8));
98+ return MKINT((i_int) (GETBITS8(a) == GETBITS8(b)));
17499}
175100
176101VAL idris_b8Lte(VM *vm, VAL a, VAL b) {
177− return MKINT((i_int) (a->info.bits8 <= b->info.bits8));
102+ return MKINT((i_int) (GETBITS8(a) <= GETBITS8(b)));
178103}
179104
180105VAL idris_b8Gte(VM *vm, VAL a, VAL b) {
181− return MKINT((i_int) (a->info.bits8 >= b->info.bits8));
106+ return MKINT((i_int) (GETBITS8(a) >= GETBITS8(b)));
182107}
183108
184109VAL idris_b8Compl(VM *vm, VAL a) {
185− uint8_t A = a->info.bits8;
186− VAL cl = allocate(sizeof(Closure), 0);
187− SETTY(cl, CT_BITS8);
188− cl->info.bits8 = ~ A;
189− return cl;
110+ uint8_t A = GETBITS8(a);
111+ return idris_b8const(vm, ~ A);
190112}
191113
192114VAL idris_b8And(VM *vm, VAL a, VAL b) {
193− uint8_t A = a->info.bits8;
194− uint8_t B = b->info.bits8;
195− VAL cl = allocate(sizeof(Closure), 0);
196− SETTY(cl, CT_BITS8);
197− cl->info.bits8 = A & B;
198− return cl;
115+ uint8_t A = GETBITS8(a);
116+ uint8_t B = GETBITS8(b);
117+ return idris_b8const(vm, A & B);
199118}
200119
201120VAL idris_b8Or(VM *vm, VAL a, VAL b) {
202− uint8_t A = a->info.bits8;
203− uint8_t B = b->info.bits8;
204− VAL cl = allocate(sizeof(Closure), 0);
205− SETTY(cl, CT_BITS8);
206− cl->info.bits8 = A | B;
207− return cl;
121+ uint8_t A = GETBITS8(a);
122+ uint8_t B = GETBITS8(b);
123+ return idris_b8const(vm, A | B);
208124}
209125
210126VAL idris_b8Xor(VM *vm, VAL a, VAL b) {
211− uint8_t A = a->info.bits8;
212− uint8_t B = b->info.bits8;
213− VAL cl = allocate(sizeof(Closure), 0);
214− SETTY(cl, CT_BITS8);
215− cl->info.bits8 = A ^ B;
216− return cl;
127+ uint8_t A = GETBITS8(a);
128+ uint8_t B = GETBITS8(b);
129+ return idris_b8const(vm, A ^ B);
217130}
218131
219132VAL idris_b8Shl(VM *vm, VAL a, VAL b) {
220− uint8_t A = a->info.bits8;
221− uint8_t B = b->info.bits8;
222− VAL cl = allocate(sizeof(Closure), 0);
223− SETTY(cl, CT_BITS8);
224− cl->info.bits8 = A << B;
225− return cl;
133+ uint8_t A = GETBITS8(a);
134+ uint8_t B = GETBITS8(b);
135+ return idris_b8const(vm, A << B);
226136}
227137
228138VAL idris_b8LShr(VM *vm, VAL a, VAL b) {
229− uint8_t A = a->info.bits8;
230− uint8_t B = b->info.bits8;
231− VAL cl = allocate(sizeof(Closure), 0);
232− SETTY(cl, CT_BITS8);
233− cl->info.bits8 = A >> B;
234− return cl;
139+ uint8_t A = GETBITS8(a);
140+ uint8_t B = GETBITS8(b);
141+ return idris_b8const(vm, A >> B);
235142}
236143
237144VAL idris_b8AShr(VM *vm, VAL a, VAL b) {
238− uint8_t A = a->info.bits8;
239− uint8_t B = b->info.bits8;
240− VAL cl = allocate(sizeof(Closure), 0);
241− SETTY(cl, CT_BITS8);
242− cl->info.bits8 = (uint8_t) (((int8_t) A) >> ((int8_t) B));
243− return cl;
145+ int8_t A = GETBITS8(a);
146+ int8_t B = GETBITS8(b);
147+ return idris_b8const(vm, A >> B);
244148}
245149
246150VAL idris_b16Plus(VM *vm, VAL a, VAL b) {
247− uint16_t A = a->info.bits16;
248− uint16_t B = b->info.bits16;
249− VAL cl = allocate(sizeof(Closure), 0);
250− SETTY(cl, CT_BITS16);
251− cl->info.bits16 = A + B;
252− return cl;
151+ uint16_t A = GETBITS16(a);
152+ uint16_t B = GETBITS16(b);
153+ return idris_b16const(vm, A + B);
253154}
254155
255156VAL idris_b16Minus(VM *vm, VAL a, VAL b) {
256− uint16_t A = a->info.bits16;
257− uint16_t B = b->info.bits16;
258− VAL cl = allocate(sizeof(Closure), 0);
259− SETTY(cl, CT_BITS16);
260− cl->info.bits16 = A - B;
261− return cl;
157+ uint16_t A = GETBITS16(a);
158+ uint16_t B = GETBITS16(b);
159+ return idris_b16const(vm, A - B);
262160}
263161
264162VAL idris_b16Times(VM *vm, VAL a, VAL b) {
265− uint16_t A = a->info.bits16;
266− uint16_t B = b->info.bits16;
267− VAL cl = allocate(sizeof(Closure), 0);
268− SETTY(cl, CT_BITS16);
269− cl->info.bits16 = A * B;
270− return cl;
163+ uint16_t A = GETBITS16(a);
164+ uint16_t B = GETBITS16(b);
165+ return idris_b16const(vm, A * B);
271166}
272167
273168VAL idris_b16UDiv(VM *vm, VAL a, VAL b) {
274− uint16_t A = a->info.bits16;
275− uint16_t B = b->info.bits16;
276− VAL cl = allocate(sizeof(Closure), 0);
277− SETTY(cl, CT_BITS16);
278− cl->info.bits16 = A / B;
279− return cl;
169+ uint16_t A = GETBITS16(a);
170+ uint16_t B = GETBITS16(b);
171+ return idris_b16const(vm, A / B);
280172}
281173
282174VAL idris_b16SDiv(VM *vm, VAL a, VAL b) {
283− uint16_t A = a->info.bits16;
284− uint16_t B = b->info.bits16;
285− VAL cl = allocate(sizeof(Closure), 0);
286− SETTY(cl, CT_BITS16);
287− cl->info.bits16 = (uint16_t) (((int16_t) A) / ((int16_t) B));
288− return cl;
175+ int16_t A = GETBITS16(a);
176+ int16_t B = GETBITS16(b);
177+ return idris_b16const(vm, A / B);
289178}
290179
291180VAL idris_b16URem(VM *vm, VAL a, VAL b) {
292− uint16_t A = a->info.bits16;
293− uint16_t B = b->info.bits16;
294− VAL cl = allocate(sizeof(Closure), 0);
295− SETTY(cl, CT_BITS16);
296− cl->info.bits16 = A % B;
297− return cl;
181+ uint16_t A = GETBITS16(a);
182+ uint16_t B = GETBITS16(b);
183+ return idris_b16const(vm, A % B);
298184}
299185
300186VAL idris_b16SRem(VM *vm, VAL a, VAL b) {
301− uint16_t A = a->info.bits16;
302− uint16_t B = b->info.bits16;
303− VAL cl = allocate(sizeof(Closure), 0);
304− SETTY(cl, CT_BITS16);
305− cl->info.bits16 = (uint16_t) (((int16_t) A) % ((int16_t) B));
306− return cl;
187+ int16_t A = GETBITS16(a);
188+ int16_t B = GETBITS16(b);
189+ return idris_b16const(vm, A % B);
307190}
308191
309192VAL idris_b16Lt(VM *vm, VAL a, VAL b) {
310− return MKINT((i_int) (a->info.bits16 < b->info.bits16));
193+ return MKINT((i_int) (GETBITS16(a) < GETBITS16(b)));
311194}
312195
313196VAL idris_b16Gt(VM *vm, VAL a, VAL b) {
314− return MKINT((i_int) (a->info.bits16 > b->info.bits16));
197+ return MKINT((i_int) (GETBITS16(a) > GETBITS16(b)));
315198}
316199
317200VAL idris_b16Eq(VM *vm, VAL a, VAL b) {
318− return MKINT((i_int) (a->info.bits16 == b->info.bits16));
201+ return MKINT((i_int) (GETBITS16(a) == GETBITS16(b)));
319202}
320203
321204VAL idris_b16Lte(VM *vm, VAL a, VAL b) {
322− return MKINT((i_int) (a->info.bits16 <= b->info.bits16));
205+ return MKINT((i_int) (GETBITS16(a) <= GETBITS16(b)));
323206}
324207
325208VAL idris_b16Gte(VM *vm, VAL a, VAL b) {
326− return MKINT((i_int) (a->info.bits16 >= b->info.bits16));
209+ return MKINT((i_int) (GETBITS16(a) >= GETBITS16(b)));
327210}
328211
329212VAL idris_b16Compl(VM *vm, VAL a) {
330− uint16_t A = a->info.bits16;
331− VAL cl = allocate(sizeof(Closure), 0);
332− SETTY(cl, CT_BITS16);
333− cl->info.bits16 = ~ A;
334− return cl;
213+ uint16_t A = GETBITS16(a);
214+ return idris_b16const(vm, ~ A);
335215}
336216
337217VAL idris_b16And(VM *vm, VAL a, VAL b) {
338− uint16_t A = a->info.bits16;
339− uint16_t B = b->info.bits16;
340− VAL cl = allocate(sizeof(Closure), 0);
341− SETTY(cl, CT_BITS16);
342− cl->info.bits16 = A & B;
343− return cl;
218+ uint16_t A = GETBITS16(a);
219+ uint16_t B = GETBITS16(b);
220+ return idris_b16const(vm, A & B);
344221}
345222
346223VAL idris_b16Or(VM *vm, VAL a, VAL b) {
347− uint16_t A = a->info.bits16;
348− uint16_t B = b->info.bits16;
349− VAL cl = allocate(sizeof(Closure), 0);
350− SETTY(cl, CT_BITS16);
351− cl->info.bits16 = A | B;
352− return cl;
224+ uint16_t A = GETBITS16(a);
225+ uint16_t B = GETBITS16(b);
226+ return idris_b16const(vm, A | B);
353227}
354228
355229VAL idris_b16Xor(VM *vm, VAL a, VAL b) {
356− uint16_t A = a->info.bits16;
357− uint16_t B = b->info.bits16;
358− VAL cl = allocate(sizeof(Closure), 0);
359− SETTY(cl, CT_BITS16);
360− cl->info.bits16 = A ^ B;
361− return cl;
230+ uint16_t A = GETBITS16(a);
231+ uint16_t B = GETBITS16(b);
232+ return idris_b16const(vm, A ^ B);
362233}
363234
364235VAL idris_b16Shl(VM *vm, VAL a, VAL b) {
365− uint16_t A = a->info.bits16;
366− uint16_t B = b->info.bits16;
367− VAL cl = allocate(sizeof(Closure), 0);
368− SETTY(cl, CT_BITS16);
369− cl->info.bits16 = A << B;
370− return cl;
236+ uint16_t A = GETBITS16(a);
237+ uint16_t B = GETBITS16(b);
238+ return idris_b16const(vm, A << B);
371239}
372240
373241VAL idris_b16LShr(VM *vm, VAL a, VAL b) {
374− uint16_t A = a->info.bits16;
375− uint16_t B = b->info.bits16;
376− VAL cl = allocate(sizeof(Closure), 0);
377− SETTY(cl, CT_BITS16);
378− cl->info.bits16 = A >> B;
379− return cl;
242+ uint16_t A = GETBITS16(a);
243+ uint16_t B = GETBITS16(b);
244+ return idris_b16const(vm, A >> B);
380245}
381246
382247VAL idris_b16AShr(VM *vm, VAL a, VAL b) {
383− uint16_t A = a->info.bits16;
384− uint16_t B = b->info.bits16;
385− VAL cl = allocate(sizeof(Closure), 0);
386− SETTY(cl, CT_BITS16);
387− cl->info.bits16 = (uint16_t) (((int16_t) A) >> ((int16_t) B));
388− return cl;
248+ int16_t A = GETBITS16(a);
249+ int16_t B = GETBITS16(b);
250+ return idris_b16const(vm, A >> B);
389251}
390252
391253VAL idris_b32Plus(VM *vm, VAL a, VAL b) {
392− uint32_t A = a->info.bits32;
393− uint32_t B = b->info.bits32;
394− VAL cl = allocate(sizeof(Closure), 0);
395− SETTY(cl, CT_BITS32);
396− cl->info.bits32 = A + B;
397− return cl;
254+ uint32_t A = GETBITS32(a);
255+ uint32_t B = GETBITS32(b);
256+ return idris_b32const(vm, A + B);
398257}
399258
400259VAL idris_b32Minus(VM *vm, VAL a, VAL b) {
401− uint32_t A = a->info.bits32;
402− uint32_t B = b->info.bits32;
403− VAL cl = allocate(sizeof(Closure), 0);
404− SETTY(cl, CT_BITS32);
405− cl->info.bits32 = A - B;
406− return cl;
260+ uint32_t A = GETBITS32(a);
261+ uint32_t B = GETBITS32(b);
262+ return idris_b32const(vm, A - B);
407263}
408264
409265VAL idris_b32Times(VM *vm, VAL a, VAL b) {
410− uint32_t A = a->info.bits32;
411− uint32_t B = b->info.bits32;
412− VAL cl = allocate(sizeof(Closure), 0);
413− SETTY(cl, CT_BITS32);
414− cl->info.bits32 = A * B;
415− return cl;
266+ uint32_t A = GETBITS32(a);
267+ uint32_t B = GETBITS32(b);
268+ return idris_b32const(vm, A * B);
416269}
417270
418271VAL idris_b32UDiv(VM *vm, VAL a, VAL b) {
419− uint32_t A = a->info.bits32;
420− uint32_t B = b->info.bits32;
421− VAL cl = allocate(sizeof(Closure), 0);
422− SETTY(cl, CT_BITS32);
423− cl->info.bits32 = A / B;
424− return cl;
272+ uint32_t A = GETBITS32(a);
273+ uint32_t B = GETBITS32(b);
274+ return idris_b32const(vm, A / B);
425275}
426276
427277VAL idris_b32SDiv(VM *vm, VAL a, VAL b) {
428− uint32_t A = a->info.bits32;
429− uint32_t B = b->info.bits32;
430− VAL cl = allocate(sizeof(Closure), 0);
431− SETTY(cl, CT_BITS32);
432− cl->info.bits32 = (uint32_t) (((int32_t) A) / ((int32_t) B));
433− return cl;
278+ int32_t A = GETBITS32(a);
279+ int32_t B = GETBITS32(b);
280+ return idris_b32const(vm, A / B);
434281}
435282
436283VAL idris_b32URem(VM *vm, VAL a, VAL b) {
437− uint32_t A = a->info.bits32;
438− uint32_t B = b->info.bits32;
439− VAL cl = allocate(sizeof(Closure), 0);
440− SETTY(cl, CT_BITS32);
441− cl->info.bits32 = A % B;
442− return cl;
284+ uint32_t A = GETBITS32(a);
285+ uint32_t B = GETBITS32(b);
286+ return idris_b32const(vm, A % B);
443287}
444288
445289VAL idris_b32SRem(VM *vm, VAL a, VAL b) {
446− uint32_t A = a->info.bits32;
447− uint32_t B = b->info.bits32;
448− VAL cl = allocate(sizeof(Closure), 0);
449− SETTY(cl, CT_BITS32);
450− cl->info.bits32 = (uint32_t) (((int32_t) A) % ((int32_t) B));
451− return cl;
290+ int32_t A = GETBITS32(a);
291+ int32_t B = GETBITS32(b);
292+ return idris_b32const(vm, A % B);
452293}
453294
454295VAL idris_b32Lt(VM *vm, VAL a, VAL b) {
455− return MKINT((i_int) (a->info.bits32 < b->info.bits32));
296+ return MKINT((i_int) (GETBITS32(a) < GETBITS32(b)));
456297}
457298
458299VAL idris_b32Gt(VM *vm, VAL a, VAL b) {
459− return MKINT((i_int) (a->info.bits32 > b->info.bits32));
300+ return MKINT((i_int) (GETBITS32(a) > GETBITS32(b)));
460301}
461302
462303VAL idris_b32Eq(VM *vm, VAL a, VAL b) {
463− return MKINT((i_int) (a->info.bits32 == b->info.bits32));
304+ return MKINT((i_int) (GETBITS32(a) == GETBITS32(b)));
464305}
465306
466307VAL idris_b32Lte(VM *vm, VAL a, VAL b) {
467− return MKINT((i_int) (a->info.bits32 <= b->info.bits32));
308+ return MKINT((i_int) (GETBITS32(a) <= GETBITS32(b)));
468309}
469310
470311VAL idris_b32Gte(VM *vm, VAL a, VAL b) {
471− return MKINT((i_int) (a->info.bits32 >= b->info.bits32));
312+ return MKINT((i_int) (GETBITS32(a) >= GETBITS32(b)));
472313}
473314
474315VAL idris_b32Compl(VM *vm, VAL a) {
475− uint32_t A = a->info.bits32;
476− VAL cl = allocate(sizeof(Closure), 0);
477− SETTY(cl, CT_BITS32);
478− cl->info.bits32 = ~ A;
479− return cl;
316+ uint32_t A = GETBITS32(a);
317+ return idris_b32const(vm, ~ A);
480318}
481319
482320VAL idris_b32And(VM *vm, VAL a, VAL b) {
483− uint32_t A = a->info.bits32;
484− uint32_t B = b->info.bits32;
485− VAL cl = allocate(sizeof(Closure), 0);
486− SETTY(cl, CT_BITS32);
487− cl->info.bits32 = A & B;
488− return cl;
321+ uint32_t A = GETBITS32(a);
322+ uint32_t B = GETBITS32(b);
323+ return idris_b32const(vm, A & B);
489324}
490325
491326VAL idris_b32Or(VM *vm, VAL a, VAL b) {
492− uint32_t A = a->info.bits32;
493− uint32_t B = b->info.bits32;
494− VAL cl = allocate(sizeof(Closure), 0);
495− SETTY(cl, CT_BITS32);
496− cl->info.bits32 = A | B;
497− return cl;
327+ uint32_t A = GETBITS32(a);
328+ uint32_t B = GETBITS32(b);
329+ return idris_b32const(vm, A | B);
498330}
499331
500332VAL idris_b32Xor(VM *vm, VAL a, VAL b) {
501− uint32_t A = a->info.bits32;
502− uint32_t B = b->info.bits32;
503− VAL cl = allocate(sizeof(Closure), 0);
504− SETTY(cl, CT_BITS32);
505− cl->info.bits32 = A ^ B;
506− return cl;
333+ uint32_t A = GETBITS32(a);
334+ uint32_t B = GETBITS32(b);
335+ return idris_b32const(vm, A ^ B);
507336}
508337
509338VAL idris_b32Shl(VM *vm, VAL a, VAL b) {
510− uint32_t A = a->info.bits32;
511− uint32_t B = b->info.bits32;
512− VAL cl = allocate(sizeof(Closure), 0);
513− SETTY(cl, CT_BITS32);
514− cl->info.bits32 = A << B;
515− return cl;
339+ uint32_t A = GETBITS32(a);
340+ uint32_t B = GETBITS32(b);
341+ return idris_b32const(vm, A << B);
516342}
517343
518344VAL idris_b32LShr(VM *vm, VAL a, VAL b) {
519− uint32_t A = a->info.bits32;
520− uint32_t B = b->info.bits32;
521− VAL cl = allocate(sizeof(Closure), 0);
522− SETTY(cl, CT_BITS32);
523− cl->info.bits32 = A >> B;
524− return cl;
345+ uint32_t A = GETBITS32(a);
346+ uint32_t B = GETBITS32(b);
347+ return idris_b32const(vm, A >> B);
525348}
526349
527350VAL idris_b32AShr(VM *vm, VAL a, VAL b) {
528− uint32_t A = a->info.bits32;
529− uint32_t B = b->info.bits32;
530− VAL cl = allocate(sizeof(Closure), 0);
531− SETTY(cl, CT_BITS32);
532− cl->info.bits32 = (uint32_t) (((int32_t)A) >> ((int32_t)B));
533− return cl;
351+ int32_t A = GETBITS32(a);
352+ int32_t B = GETBITS32(b);
353+ return idris_b32const(vm, A >> B);
534354}
535355
536356VAL idris_b64Plus(VM *vm, VAL a, VAL b) {
537− uint64_t A = a->info.bits64;
538− uint64_t B = b->info.bits64;
539− VAL cl = allocate(sizeof(Closure), 0);
540− SETTY(cl, CT_BITS64);
541− cl->info.bits64 = A + B;
542− return cl;
357+ uint64_t A = GETBITS64(a);
358+ uint64_t B = GETBITS64(b);
359+ return idris_b64const(vm, A + B);
543360}
544361
545362VAL idris_b64Minus(VM *vm, VAL a, VAL b) {
546− uint64_t A = a->info.bits64;
547− uint64_t B = b->info.bits64;
548− VAL cl = allocate(sizeof(Closure), 0);
549− SETTY(cl, CT_BITS64);
550− cl->info.bits64 = A - B;
551− return cl;
363+ uint64_t A = GETBITS64(a);
364+ uint64_t B = GETBITS64(b);
365+ return idris_b64const(vm, A - B);
552366}
553367
554368VAL idris_b64Times(VM *vm, VAL a, VAL b) {
555− uint64_t A = a->info.bits64;
556− uint64_t B = b->info.bits64;
557− VAL cl = allocate(sizeof(Closure), 0);
558− SETTY(cl, CT_BITS64);
559− cl->info.bits64 = A * B;
560− return cl;
369+ uint64_t A = GETBITS64(a);
370+ uint64_t B = GETBITS64(b);
371+ return idris_b64const(vm, A * B);
561372}
562373
563374VAL idris_b64UDiv(VM *vm, VAL a, VAL b) {
564− uint64_t A = a->info.bits64;
565− uint64_t B = b->info.bits64;
566− VAL cl = allocate(sizeof(Closure), 0);
567− SETTY(cl, CT_BITS64);
568− cl->info.bits64 = A / B;
569− return cl;
375+ uint64_t A = GETBITS64(a);
376+ uint64_t B = GETBITS64(b);
377+ return idris_b64const(vm, A / B);
570378}
571379
572380VAL idris_b64SDiv(VM *vm, VAL a, VAL b) {
573− uint64_t A = a->info.bits64;
574− uint64_t B = b->info.bits64;
575− VAL cl = allocate(sizeof(Closure), 0);
576− SETTY(cl, CT_BITS64);
577− cl->info.bits64 = (uint64_t) (((int64_t) A) / ((int64_t) B));
578− return cl;
381+ int64_t A = GETBITS64(a);
382+ int64_t B = GETBITS64(b);
383+ return idris_b64const(vm, A / B);
579384}
580385
581386VAL idris_b64URem(VM *vm, VAL a, VAL b) {
582− uint64_t A = a->info.bits64;
583− uint64_t B = b->info.bits64;
584− VAL cl = allocate(sizeof(Closure), 0);
585− SETTY(cl, CT_BITS64);
586− cl->info.bits64 = A % B;
587− return cl;
387+ uint64_t A = GETBITS64(a);
388+ uint64_t B = GETBITS64(b);
389+ return idris_b64const(vm, A % B);
588390}
589391
590392VAL idris_b64SRem(VM *vm, VAL a, VAL b) {
591− uint64_t A = a->info.bits64;
592− uint64_t B = b->info.bits64;
593− VAL cl = allocate(sizeof(Closure), 0);
594− SETTY(cl, CT_BITS64);
595− cl->info.bits64 = (uint64_t) (((int64_t) A) % ((int64_t) B));
596− return cl;
393+ int64_t A = GETBITS64(a);
394+ int64_t B = GETBITS64(b);
395+ return idris_b64const(vm, A % B);
597396}
598397
599398VAL idris_b64Lt(VM *vm, VAL a, VAL b) {
600− return MKINT((i_int) (a->info.bits64 < b->info.bits64));
399+ uint64_t A = GETBITS64(a);
400+ uint64_t B = GETBITS64(b);
401+ return MKINT((i_int) (A < B));
601402}
602403
603404VAL idris_b64Gt(VM *vm, VAL a, VAL b) {
604− return MKINT((i_int) (a->info.bits64 > b->info.bits64));
405+ uint64_t A = GETBITS64(a);
406+ uint64_t B = GETBITS64(b);
407+ return MKINT((i_int) (A > B));
605408}
606409
607410VAL idris_b64Eq(VM *vm, VAL a, VAL b) {
608− return MKINT((i_int) (a->info.bits64 == b->info.bits64));
411+ uint64_t A = GETBITS64(a);
412+ uint64_t B = GETBITS64(b);
413+ return MKINT((i_int) (A == B));
609414}
610415
611416VAL idris_b64Lte(VM *vm, VAL a, VAL b) {
612− return MKINT((i_int) (a->info.bits64 <= b->info.bits64));
417+ uint64_t A = GETBITS64(a);
418+ uint64_t B = GETBITS64(b);
419+ return MKINT((i_int) (A <= B));
613420}
614421
615422VAL idris_b64Gte(VM *vm, VAL a, VAL b) {
616− return MKINT((i_int) (a->info.bits64 >= b->info.bits64));
423+ uint64_t A = GETBITS64(a);
424+ uint64_t B = GETBITS64(b);
425+ return MKINT((i_int) (A >= B));
617426}
618427
619428VAL idris_b64Compl(VM *vm, VAL a) {
620− uint64_t A = a->info.bits64;
621− VAL cl = allocate(sizeof(Closure), 0);
622− SETTY(cl, CT_BITS64);
623− cl->info.bits64 = ~ A;
624− return cl;
429+ uint64_t A = GETBITS64(a);
430+ return idris_b64const(vm, ~ A);
625431}
626432
627433VAL idris_b64And(VM *vm, VAL a, VAL b) {
628− uint64_t A = a->info.bits64;
629− uint64_t B = b->info.bits64;
630− VAL cl = allocate(sizeof(Closure), 0);
631− SETTY(cl, CT_BITS64);
632− cl->info.bits64 = A & B;
633− return cl;
434+ uint64_t A = GETBITS64(a);
435+ uint64_t B = GETBITS64(b);
436+ return idris_b64const(vm, A & B);
634437}
635438
636439VAL idris_b64Or(VM *vm, VAL a, VAL b) {
637− uint64_t A = a->info.bits64;
638− uint64_t B = b->info.bits64;
639− VAL cl = allocate(sizeof(Closure), 0);
640− SETTY(cl, CT_BITS64);
641− cl->info.bits64 = A | B;
642− return cl;
440+ uint64_t A = GETBITS64(a);
441+ uint64_t B = GETBITS64(b);
442+ return idris_b64const(vm, A | B);
643443}
644444
645445VAL idris_b64Xor(VM *vm, VAL a, VAL b) {
646− uint64_t A = a->info.bits64;
647− uint64_t B = b->info.bits64;
648− VAL cl = allocate(sizeof(Closure), 0);
649− SETTY(cl, CT_BITS64);
650− cl->info.bits64 = A ^ B;
651− return cl;
446+ uint64_t A = GETBITS64(a);
447+ uint64_t B = GETBITS64(b);
448+ return idris_b64const(vm, A ^ B);
652449}
653450
654451VAL idris_b64Shl(VM *vm, VAL a, VAL b) {
655− uint64_t A = a->info.bits64;
656− uint64_t B = b->info.bits64;
657− VAL cl = allocate(sizeof(Closure), 0);
658− SETTY(cl, CT_BITS64);
659− cl->info.bits64 = A << B;
660− return cl;
452+ uint64_t A = GETBITS64(a);
453+ uint64_t B = GETBITS64(b);
454+ return idris_b64const(vm, A << B);
661455}
662456
663457VAL idris_b64LShr(VM *vm, VAL a, VAL b) {
664− uint64_t A = a->info.bits64;
665− uint64_t B = b->info.bits64;
666− VAL cl = allocate(sizeof(Closure), 0);
667− SETTY(cl, CT_BITS64);
668− cl->info.bits64 = A >> B;
669− return cl;
458+ uint64_t A = GETBITS64(a);
459+ uint64_t B = GETBITS64(b);
460+ return idris_b64const(vm, A >> B);
670461}
671462
672463VAL idris_b64AShr(VM *vm, VAL a, VAL b) {
673− uint64_t A = a->info.bits64;
674− uint64_t B = b->info.bits64;
675− VAL cl = allocate(sizeof(Closure), 0);
676− SETTY(cl, CT_BITS64);
677− cl->info.bits64 = (uint64_t) (((int64_t) A) >> ((int64_t) B));
678− return cl;
464+ int64_t A = GETBITS64(a);
465+ int64_t B = GETBITS64(b);
466+ return idris_b64const(vm, A >> B);
679467}
680468
681469VAL idris_b8Z16(VM *vm, VAL a) {
682− uint8_t A = a->info.bits8;
683− VAL cl = allocate(sizeof(Closure), 0);
684− SETTY(cl, CT_BITS16);
685− cl->info.bits16 = (uint16_t) A;
686− return cl;
470+ uint8_t A = GETBITS8(a);
471+ return idris_b16const(vm, A);
687472}
688473
689474VAL idris_b8Z32(VM *vm, VAL a) {
690− uint8_t A = a->info.bits8;
691− VAL cl = allocate(sizeof(Closure), 0);
692− SETTY(cl, CT_BITS32);
693− cl->info.bits32 = (uint32_t) A;
694− return cl;
475+ uint8_t A = GETBITS8(a);
476+ return idris_b32const(vm, A);
695477}
696478
697479VAL idris_b8Z64(VM *vm, VAL a) {
698− uint8_t A = a->info.bits8;
699− VAL cl = allocate(sizeof(Closure), 0);
700− SETTY(cl, CT_BITS64);
701− cl->info.bits64 = (uint64_t) A;
702− return cl;
480+ uint8_t A = GETBITS8(a);
481+ return idris_b64const(vm, A);
703482}
704483
705484VAL idris_b8S16(VM *vm, VAL a) {
706− uint8_t A = a->info.bits8;
707− VAL cl = allocate(sizeof(Closure), 0);
708− SETTY(cl, CT_BITS16);
709− cl->info.bits16 = (uint16_t) (int16_t) (int8_t) A;
710− return cl;
485+ int8_t A = GETBITS8(a);
486+ return idris_b16const(vm, (int16_t) A);
711487}
712488
713489VAL idris_b8S32(VM *vm, VAL a) {
714− uint8_t A = a->info.bits8;
715− VAL cl = allocate(sizeof(Closure), 0);
716− SETTY(cl, CT_BITS32);
717− cl->info.bits32 = (uint32_t) (int32_t) (int8_t) A;
718− return cl;
490+ int8_t A = GETBITS8(a);
491+ return idris_b32const(vm, (int32_t) A);
719492}
720493
721494VAL idris_b8S64(VM *vm, VAL a) {
722− uint8_t A = a->info.bits8;
723− VAL cl = allocate(sizeof(Closure), 0);
724− SETTY(cl, CT_BITS64);
725− cl->info.bits64 = (uint64_t) (int64_t) (int8_t) A;
726− return cl;
495+ int8_t A = GETBITS8(a);
496+ return idris_b64const(vm, (int64_t) A);
727497}
728498
729499VAL idris_b16Z32(VM *vm, VAL a) {
730− uint16_t A = a->info.bits16;
731− VAL cl = allocate(sizeof(Closure), 0);
732− SETTY(cl, CT_BITS32);
733− cl->info.bits32 = (uint32_t) A;
734− return cl;
500+ uint16_t A = GETBITS16(a);
501+ return idris_b32const(vm, (uint32_t) A);
735502}
736503
737504VAL idris_b16Z64(VM *vm, VAL a) {
738− uint16_t A = a->info.bits16;
739− VAL cl = allocate(sizeof(Closure), 0);
740− SETTY(cl, CT_BITS64);
741− cl->info.bits64 = (uint64_t) A;
742− return cl;
505+ uint16_t A = GETBITS16(a);
506+ return idris_b64const(vm, (uint64_t) A);
743507}
744508
745509VAL idris_b16S32(VM *vm, VAL a) {
746− uint16_t A = a->info.bits16;
747− VAL cl = allocate(sizeof(Closure), 0);
748− SETTY(cl, CT_BITS32);
749− cl->info.bits32 = (uint32_t) (int32_t) (int16_t) A;
750− return cl;
510+ int16_t A = GETBITS16(a);
511+ return idris_b32const(vm, (int32_t) A);
751512}
752513
753514VAL idris_b16S64(VM *vm, VAL a) {
754− uint16_t A = a->info.bits16;
755− VAL cl = allocate(sizeof(Closure), 0);
756− SETTY(cl, CT_BITS64);
757− cl->info.bits64 = (uint64_t) (int64_t) (int16_t) A;
758− return cl;
515+ int16_t A = GETBITS16(a);
516+ return idris_b64const(vm, (int64_t) A);
759517}
760518
761519VAL idris_b16T8(VM *vm, VAL a) {
762− uint16_t A = a->info.bits16;
763− VAL cl = allocate(sizeof(Closure), 0);
764− SETTY(cl, CT_BITS8);
765− cl->info.bits8 = (uint8_t) A;
766− return cl;
520+ uint16_t A = GETBITS16(a);
521+ return idris_b8const(vm, (uint8_t) A);
767522}
768523
769524VAL idris_b32Z64(VM *vm, VAL a) {
770− uint32_t A = a->info.bits32;
771− VAL cl = allocate(sizeof(Closure), 0);
772− SETTY(cl, CT_BITS64);
773− cl->info.bits64 = (uint64_t) A;
774− return cl;
525+ uint32_t A = GETBITS32(a);
526+ return idris_b64const(vm, (uint64_t) A);
775527}
776528
777529VAL idris_b32S64(VM *vm, VAL a) {
778− uint32_t A = a->info.bits32;
779− VAL cl = allocate(sizeof(Closure), 0);
780− SETTY(cl, CT_BITS64);
781− cl->info.bits64 = (uint64_t) (int64_t) (int32_t) A;
782− return cl;
530+ int32_t A = GETBITS32(a);
531+ return idris_b64const(vm, (int64_t) A);
783532}
784533
785534VAL idris_b32T8(VM *vm, VAL a) {
786− uint32_t A = a->info.bits32;
787− VAL cl = allocate(sizeof(Closure), 0);
788− SETTY(cl, CT_BITS8);
789− cl->info.bits8 = (uint8_t) A;
790− return cl;
535+ uint32_t A = GETBITS32(a);
536+ return idris_b8const(vm, (uint8_t) A);
791537}
792538
793539VAL idris_b32T16(VM *vm, VAL a) {
794− uint32_t A = a->info.bits32;
795− VAL cl = allocate(sizeof(Closure), 0);
796− SETTY(cl, CT_BITS16);
797− cl->info.bits16 = (uint16_t) A;
798− return cl;
540+ uint32_t A = GETBITS32(a);
541+ return idris_b16const(vm, (uint16_t) A);
799542}
800543
801544VAL idris_b64T8(VM *vm, VAL a) {
802− uint64_t A = a->info.bits64;
803− VAL cl = allocate(sizeof(Closure), 0);
804− SETTY(cl, CT_BITS8);
805− cl->info.bits8 = (uint8_t) A;
806− return cl;
545+ uint64_t A = GETBITS64(a);
546+ return idris_b8const(vm, (uint8_t) A);
807547}
808548
809549VAL idris_b64T16(VM *vm, VAL a) {
810− uint64_t A = a->info.bits64;
811− VAL cl = allocate(sizeof(Closure), 0);
812− SETTY(cl, CT_BITS16);
813− cl->info.bits16 = (uint16_t) A;
814− return cl;
550+ uint64_t A = GETBITS64(a);
551+ return idris_b16const(vm, (uint16_t) A);
815552}
816553
817554VAL idris_b64T32(VM *vm, VAL a) {
818− uint64_t A = a->info.bits64;
819− VAL cl = allocate(sizeof(Closure), 0);
820− SETTY(cl, CT_BITS32);
821− cl->info.bits32 = (uint32_t) A;
822− return cl;
555+ uint64_t A = GETBITS64(a);
556+ return idris_b32const(vm, (uint32_t) A);
823557}
824558
825559VAL idris_peekB8(VM* vm, VAL ptr, VAL offset) {
rts/idris_bitstring.h−5
@@ -1,11 +1,6 @@
11#ifndef _IDRISBITSTRING_H
22#define _IDRISBITSTRING_H
33
4−VAL idris_b8CopyForGC(VM *vm, VAL a);
5−VAL idris_b16CopyForGC(VM *vm, VAL a);
6−VAL idris_b32CopyForGC(VM *vm, VAL a);
7−VAL idris_b64CopyForGC(VM *vm, VAL a);
8−
94VAL idris_b8(VM *vm, VAL a);
105VAL idris_b16(VM *vm, VAL a);
116VAL idris_b32(VM *vm, VAL a);
rts/idris_buffer.c+5−19
@@ -82,9 +82,9 @@ uint8_t idris_getBufferByte(void* buffer, int loc) {
8282int idris_getBufferInt(void* buffer, int loc) {
8383 Buffer* b = buffer;
8484 if (loc >= 0 && loc+3 < b->size) {
85− return b->data[loc] +
85+ return b->data[loc] +
8686 (b->data[loc+1] << 8) +
87− (b->data[loc+2] << 16) +
87+ (b->data[loc+2] << 16) +
8888 (b->data[loc+3] << 24);
8989 } else {
9090 return 0;
@@ -110,22 +110,9 @@ double idris_getBufferDouble(void* buffer, int loc) {
110110
111111VAL idris_getBufferString(void* buffer, int loc, int len) {
112112 Buffer* b = buffer;
113−
114− Closure* cl = allocate(sizeof(Closure) + // Type) + sizeof(char*) +
115− sizeof(char)*(len+1), 0);
116− SETTY(cl, CT_STRING);
117− cl->info.str.str = (char*)cl + sizeof(Closure);
118−
119− if (loc >= 0 && loc+len <= b->size) {
120− memcpy(cl->info.str.str, (b->data)+loc, len);
121− cl->info.str.str[len]='\0';
122− cl->info.str.len = len;
123− } else {
124− cl->info.str.str[0] = '\0';
125− cl->info.str.len = 0;
126− }
127−
128− return cl;
113+ char * s = (char*)(b->data + loc);
114+ size_t sz = loc >= 0 && loc+len <= b->size? len : 0;
115+ return MKSTRlen(get_vm(), s, sz);
129116}
130117
131118int idris_readBuffer(FILE* h, void* buffer, int loc, int max) {
@@ -153,4 +140,3 @@ void idris_writeBuffer(FILE* h, void* buffer, int loc, int len) {
153140 fwrite((b->data)+loc, sizeof(uint8_t), len, h);
154141 }
155142}
156−
rts/idris_gc.c+49−68
@@ -4,116 +4,97 @@
44#include "idris_bitstring.h"
55#include <assert.h>
66
7+static inline VAL copy_plain(VM* vm, VAL x, size_t sz) {
8+ VAL cl = iallocate(vm, sz, 1);
9+ memcpy(cl, x, sz);
10+ return cl;
11+}
12+
713VAL copy(VM* vm, VAL x) {
8− int ar, len;
9− Closure* cl = NULL;
10− if (x==NULL || ISINT(x)) {
14+ int ar;
15+ VAL cl;
16+ if (x==NULL) {
1117 return x;
1218 }
1319 switch(GETTY(x)) {
20+ case CT_INT: return x;
21+ case CT_BITS32: return copy_plain(vm, x, sizeof(Bits32));
22+ case CT_BITS64: return copy_plain(vm, x, sizeof(Bits64));
23+ case CT_FLOAT: return copy_plain(vm, x, sizeof(Float));
24+ case CT_FWD:
25+ return GETPTR(x);
26+ case CT_CDATA:
27+ cl = copy_plain(vm, x, sizeof(CDataC));
28+ c_heap_mark_item(GETCDATA(x));
29+ break;
30+ case CT_BIGINT:
31+ cl = MKBIGMc(vm, GETMPZ(x));
32+ break;
1433 case CT_CON:
1534 ar = CARITY(x);
1635 if (ar == 0 && CTAG(x) < 256) {
1736 return x;
18− } else {
19− allocCon(cl, vm, CTAG(x), ar, 1);
20− memcpy(&(cl->info.c.args), &(x->info.c.args), sizeof(VAL)*ar);
2137 }
22− break;
38+ // FALLTHROUGH
2339 case CT_ARRAY:
24− len = x->info.arr.length;
25− allocArray(cl, vm, len, 1);
26− memcpy(&(cl->info.arr.content), &(x->info.arr.content), sizeof(VAL)*len);
27− break;
28− case CT_FLOAT:
29− cl = MKFLOATc(vm, x->info.f);
30− break;
3140 case CT_STRING:
32− cl = MKSTRclen(vm, x->info.str.str, x->info.str.len);
33− break;
41+ case CT_REF:
3442 case CT_STROFFSET:
35− cl = MKSTROFFc(vm, x->info.str_offset);
36− break;
37− case CT_BIGINT:
38− cl = MKBIGMc(vm, x->info.ptr);
39− break;
4043 case CT_PTR:
41− cl = MKPTRc(vm, x->info.ptr);
42− break;
4344 case CT_MANAGEDPTR:
44− cl = MKMPTRc(vm, x->info.mptr->data, x->info.mptr->size);
45− break;
46− case CT_BITS8:
47− cl = idris_b8CopyForGC(vm, x);
48− break;
49− case CT_BITS16:
50− cl = idris_b16CopyForGC(vm, x);
51− break;
52− case CT_BITS32:
53− cl = idris_b32CopyForGC(vm, x);
54− break;
55− case CT_BITS64:
56− cl = idris_b64CopyForGC(vm, x);
57− break;
58− case CT_REF:
59− cl = idris_newRefLock((VAL)(x->info.ptr), 1);
60− break;
61− case CT_FWD:
62− return x->info.ptr;
6345 case CT_RAWDATA:
64− {
65− size_t size = x->info.size + sizeof(Closure);
66− cl = allocate(size, 1);
67− memcpy(cl, x, size);
68− }
69− break;
70− case CT_CDATA:
71− cl = MKCDATAc(vm, x->info.c_heap_item);
72− c_heap_mark_item(x->info.c_heap_item);
46+ cl = copy_plain(vm, x, x->hdr.sz);
7347 break;
7448 default:
49+ cl = NULL;
50+ assert(0);
7551 break;
7652 }
53+ assert(x->hdr.sz >= sizeof(Fwd));
7754 SETTY(x, CT_FWD);
78− x->info.ptr = cl;
55+ ((Fwd*)x)->fwd = cl;
7956 return cl;
8057}
8158
8259void cheney(VM *vm) {
83− int i;
84− int ar, len;
8560 char* scan = aligned_heap_pointer(vm->heap.heap);
8661
8762 while(scan < vm->heap.next) {
88− size_t inc = *((size_t*)scan);
89− VAL heap_item = (VAL)(scan+sizeof(size_t));
63+ VAL heap_item = (VAL)scan;
9064 // If it's a CT_CON, CT_REF or CT_STROFFSET, copy its arguments
9165 switch(GETTY(heap_item)) {
9266 case CT_CON:
93− ar = ARITY(heap_item);
94− for(i = 0; i < ar; ++i) {
95− VAL newptr = copy(vm, heap_item->info.c.args[i]);
96− heap_item->info.c.args[i] = newptr;
67+ {
68+ Con * c = (Con*)heap_item;
69+ size_t len = CARITY(c);
70+ for(size_t i = 0; i < len; ++i)
71+ c->args[i] = copy(vm, c->args[i]);
9772 }
9873 break;
9974 case CT_ARRAY:
100− len = heap_item->info.arr.length;
101− for(i = 0; i < len; ++i) {
102− VAL newptr = copy(vm, heap_item->info.arr.content[i]);
103− heap_item->info.arr.content[i] = newptr;
75+ {
76+ Array * a = (Array*)heap_item;
77+ size_t len = CELEM(a);
78+ for(size_t i = 0; i < len; ++i)
79+ a->array[i] = copy(vm, a->array[i]);
10480 }
10581 break;
10682 case CT_REF:
107− heap_item->info.ptr = copy(vm, (VAL)(heap_item->info.ptr));
83+ {
84+ Ref * r = (Ref*)heap_item;
85+ r->ref = copy(vm, r->ref);
86+ }
10887 break;
10988 case CT_STROFFSET:
110− heap_item->info.str_offset->str
111− = copy(vm, heap_item->info.str_offset->str);
89+ {
90+ StrOffset * s = (StrOffset*)heap_item;
91+ s->base = (String*)copy(vm, (VAL)s->base);
92+ }
11293 break;
11394 default: // Nothing to copy
11495 break;
11596 }
116− scan += inc;
97+ scan += aligned(valSize(heap_item));
11798 }
11899 assert(scan == vm->heap.next);
119100}
rts/idris_gmp.c+87−218
@@ -22,249 +22,126 @@ VAL MKBIGI(int val) {
2222 return MKINT((i_int)val);
2323}
2424
25+static BigInt * allocBig(VM * vm) {
26+ idris_requireAlloc(vm, IDRIS_MAXGMP);
27+ BigInt * cl = iallocate(vm, sizeof(*cl) + sizeof(mpz_t), 0);
28+ idris_doneAlloc(vm);
29+ SETTY(cl, CT_BIGINT);
30+ mpz_init(*getmpz(cl));
31+ return cl;
32+}
33+
2534VAL MKBIGC(VM* vm, char* val) {
2635 if (*val == '\0') {
2736 return MKBIGI(0);
2837 }
2938 else {
30− idris_requireAlloc(IDRIS_MAXGMP);
31− mpz_t* bigint;
32−
33− VAL cl = allocate(sizeof(Closure) + sizeof(mpz_t), 0);
34− idris_doneAlloc();
35− bigint = (mpz_t*)(((char*)cl) + sizeof(Closure));
36−
37− mpz_init(*bigint);
38− mpz_set_str(*bigint, val, 10);
39−
40− SETTY(cl, CT_BIGINT);
41− cl -> info.ptr = (void*)bigint;
42−
43− return cl;
39+ BigInt * cl = allocBig(vm);
40+ mpz_set_str(*getmpz(cl), val, 10);
41+ return (VAL)cl;
4442 }
4543}
4644
47−VAL MKBIGM(VM* vm, void* big) {
48− idris_requireAlloc(IDRIS_MAXGMP);
49−
50− mpz_t* bigint;
51− VAL cl = allocate(sizeof(Closure) + sizeof(mpz_t), 0);
52− idris_doneAlloc();
53− bigint = (mpz_t*)(((char*)cl) + sizeof(Closure));
54−
55− mpz_init(*bigint);
56− mpz_set(*bigint, *((mpz_t*)big));
57−
58− SETTY(cl, CT_BIGINT);
59− cl -> info.ptr = (void*)bigint;
60−
61− return cl;
45+VAL MKBIGM(VM* vm, void* ibig) {
46+ BigInt * cl = allocBig(vm);
47+ mpz_set(*getmpz(cl), *((mpz_t*)ibig));
48+ return (VAL)cl;
6249}
6350
64−VAL MKBIGMc(VM* vm, void* big) {
65− idris_requireAlloc(IDRIS_MAXGMP);
66−
67− mpz_t* bigint;
68− VAL cl = allocate(sizeof(Closure) + sizeof(mpz_t), 0);
69− idris_doneAlloc();
70− bigint = (mpz_t*)(((char*)cl) + sizeof(Closure));
71−
72− mpz_init_set(*bigint, *((mpz_t*)big));
73−
74− SETTY(cl, CT_BIGINT);
75− cl -> info.ptr = (void*)bigint;
76−
77− return cl;
51+VAL MKBIGMc(VM* vm, void* ibig) {
52+ BigInt * cl = allocBig(vm);
53+ mpz_init_set(*getmpz(cl), *((mpz_t*)ibig));
54+ return (VAL)cl;
7855}
7956
8057VAL MKBIGUI(VM* vm, unsigned long val) {
81− idris_requireAlloc(IDRIS_MAXGMP);
82−
83− mpz_t* bigint;
84− VAL cl = allocate(sizeof(Closure) + sizeof(mpz_t), 0);
85− idris_doneAlloc();
86− bigint = (mpz_t*)(((char*)cl) + sizeof(Closure));
87−
88− mpz_init_set_ui(*bigint, val);
89−
90− SETTY(cl, CT_BIGINT);
91− cl -> info.ptr = (void*)bigint;
92−
93− return cl;
58+ BigInt * cl = allocBig(vm);
59+ mpz_init_set_ui(*getmpz(cl), val);
60+ return (VAL)cl;
9461}
9562
9663VAL MKBIGSI(VM* vm, signed long val) {
97− idris_requireAlloc(IDRIS_MAXGMP);
98−
99− mpz_t* bigint;
100− VAL cl = allocate(sizeof(Closure) + sizeof(mpz_t), 0);
101− idris_doneAlloc();
102− bigint = (mpz_t*)(((char*)cl) + sizeof(Closure));
103−
104− mpz_init_set_si(*bigint, val);
105−
106− SETTY(cl, CT_BIGINT);
107− cl -> info.ptr = (void*)bigint;
108−
109− return cl;
110−}
111−
112−VAL GETBIG(VM * vm, VAL x) {
113− idris_requireAlloc(IDRIS_MAXGMP);
114−
115− if (ISINT(x)) {
116− mpz_t* bigint;
117− VAL cl = allocate(sizeof(Closure) + sizeof(mpz_t), 0);
118− idris_doneAlloc();
119− bigint = (mpz_t*)(((char*)cl) + sizeof(Closure));
120−
121− mpz_init(*bigint);
122− mpz_set_si(*bigint, GETINT(x));
123−
124− SETTY(cl, CT_BIGINT);
125− cl -> info.ptr = (void*)bigint;
126−
127− return cl;
128− } else {
129− idris_doneAlloc();
130− switch(GETTY(x)) {
131− case CT_FWD:
132− return GETBIG(vm, x->info.ptr);
133− default:
134− return x;
64+ BigInt * cl = allocBig(vm);
65+ mpz_init_set_si(*getmpz(cl), val);
66+ return (VAL)cl;
67+}
68+
69+static BigInt * getbig(VM * vm, VAL x) {
70+ switch(GETTY(x)) {
71+ case CT_INT:
72+ {
73+ BigInt * cl = allocBig(vm);
74+ mpz_set_si(*getmpz(cl), GETINT(x));
75+ return cl;
13576 }
77+ case CT_FWD:
78+ return getbig(vm, ((Fwd*)x)->fwd);
79+ default:
80+ return (BigInt*)x;
13681 }
13782}
13883
139−VAL bigAdd(VM* vm, VAL x, VAL y) {
140− idris_requireAlloc(IDRIS_MAXGMP);
84+#define GETBIG (VAL)getbig
14185
142− mpz_t* bigint;
143− VAL cl = allocate(sizeof(Closure) + sizeof(mpz_t), 0);
144− idris_doneAlloc();
145− bigint = (mpz_t*)(((char*)cl) + sizeof(Closure));
146− mpz_add(*bigint, GETMPZ(GETBIG(vm,x)), GETMPZ(GETBIG(vm,y)));
147− SETTY(cl, CT_BIGINT);
148− cl -> info.ptr = (void*)bigint;
149− return cl;
86+VAL bigAdd(VM* vm, VAL x, VAL y) {
87+ BigInt * cl = allocBig(vm);
88+ mpz_add(*getmpz(cl), *getmpz(getbig(vm,x)), *getmpz(getbig(vm,y)));
89+ return (VAL)cl;
15090}
15191
15292VAL bigSub(VM* vm, VAL x, VAL y) {
153− idris_requireAlloc(IDRIS_MAXGMP);
154−
155− mpz_t* bigint;
156− VAL cl = allocate(sizeof(Closure) + sizeof(mpz_t), 0);
157− idris_doneAlloc();
158− bigint = (mpz_t*)(((char*)cl) + sizeof(Closure));
159− mpz_sub(*bigint, GETMPZ(GETBIG(vm,x)), GETMPZ(GETBIG(vm,y)));
160− SETTY(cl, CT_BIGINT);
161− cl -> info.ptr = (void*)bigint;
162− return cl;
93+ BigInt * cl = allocBig(vm);
94+ mpz_sub(*getmpz(cl), *getmpz(getbig(vm,x)), *getmpz(getbig(vm,y)));
95+ return (VAL)cl;
16396}
16497
16598VAL bigMul(VM* vm, VAL x, VAL y) {
166− idris_requireAlloc(IDRIS_MAXGMP);
167−
168− mpz_t* bigint;
169− VAL cl = allocate(sizeof(Closure) + sizeof(mpz_t), 0);
170− idris_doneAlloc();
171− bigint = (mpz_t*)(((char*)cl) + sizeof(Closure));
172− mpz_mul(*bigint, GETMPZ(GETBIG(vm,x)), GETMPZ(GETBIG(vm,y)));
173− SETTY(cl, CT_BIGINT);
174− cl -> info.ptr = (void*)bigint;
175− return cl;
99+ BigInt * cl = allocBig(vm);
100+ mpz_mul(*getmpz(cl), *getmpz(getbig(vm,x)), *getmpz(getbig(vm,y)));
101+ return (VAL)cl;
176102}
177103
178104VAL bigDiv(VM* vm, VAL x, VAL y) {
179− idris_requireAlloc(IDRIS_MAXGMP);
180−
181− mpz_t* bigint;
182− VAL cl = allocate(sizeof(Closure) + sizeof(mpz_t), 0);
183− idris_doneAlloc();
184− bigint = (mpz_t*)(((char*)cl) + sizeof(Closure));
185− mpz_tdiv_q(*bigint, GETMPZ(GETBIG(vm,x)), GETMPZ(GETBIG(vm,y)));
186− SETTY(cl, CT_BIGINT);
187− cl -> info.ptr = (void*)bigint;
188− return cl;
105+ BigInt * cl = allocBig(vm);
106+ mpz_tdiv_q(*getmpz(cl), *getmpz(getbig(vm,x)), *getmpz(getbig(vm,y)));
107+ return (VAL)cl;
189108}
190109
191110VAL bigMod(VM* vm, VAL x, VAL y) {
192− idris_requireAlloc(IDRIS_MAXGMP);
193−
194− mpz_t* bigint;
195− VAL cl = allocate(sizeof(Closure) + sizeof(mpz_t), 0);
196− idris_doneAlloc();
197− bigint = (mpz_t*)(((char*)cl) + sizeof(Closure));
198− mpz_tdiv_r(*bigint, GETMPZ(GETBIG(vm,x)), GETMPZ(GETBIG(vm,y)));
199− SETTY(cl, CT_BIGINT);
200− cl -> info.ptr = (void*)bigint;
201− return cl;
111+ BigInt * cl = allocBig(vm);
112+ mpz_tdiv_r(*getmpz(cl), *getmpz(getbig(vm,x)), *getmpz(getbig(vm,y)));
113+ return (VAL)cl;
202114}
203115
204116VAL bigAnd(VM* vm, VAL x, VAL y) {
205− idris_requireAlloc(IDRIS_MAXGMP);
206−
207− mpz_t* bigint;
208− VAL cl = allocate(sizeof(Closure) + sizeof(mpz_t), 0);
209− idris_doneAlloc();
210− bigint = (mpz_t*)(((char*)cl) + sizeof(Closure));
211− mpz_and(*bigint, GETMPZ(GETBIG(vm,x)), GETMPZ(GETBIG(vm,y)));
212− SETTY(cl, CT_BIGINT);
213− cl -> info.ptr = (void*)bigint;
214− return cl;
117+ BigInt * cl = allocBig(vm);
118+ mpz_and(*getmpz(cl), *getmpz(getbig(vm,x)), *getmpz(getbig(vm,y)));
119+ return (VAL)cl;
215120}
216121
217122VAL bigOr(VM* vm, VAL x, VAL y) {
218− idris_requireAlloc(IDRIS_MAXGMP);
219−
220− mpz_t* bigint;
221− VAL cl = allocate(sizeof(Closure) + sizeof(mpz_t), 0);
222− idris_doneAlloc();
223− bigint = (mpz_t*)(((char*)cl) + sizeof(Closure));
224− mpz_ior(*bigint, GETMPZ(GETBIG(vm,x)), GETMPZ(GETBIG(vm,y)));
225− SETTY(cl, CT_BIGINT);
226− cl -> info.ptr = (void*)bigint;
227− return cl;
123+ BigInt * cl = allocBig(vm);
124+ mpz_ior(*getmpz(cl), *getmpz(getbig(vm,x)), *getmpz(getbig(vm,y)));
125+ return (VAL)cl;
228126}
229127
230128VAL bigShiftLeft(VM* vm, VAL x, VAL y) {
231− idris_requireAlloc(IDRIS_MAXGMP);
232−
233− mpz_t* bigint;
234− VAL cl = allocate(sizeof(Closure) + sizeof(mpz_t), 0);
235− idris_doneAlloc();
236− bigint = (mpz_t*)(((char*)cl) + sizeof(Closure));
237− mpz_mul_2exp(*bigint, GETMPZ(GETBIG(vm,x)), GETINT(y));
238− SETTY(cl, CT_BIGINT);
239− cl -> info.ptr = (void*)bigint;
240− return cl;
129+ BigInt * cl = allocBig(vm);
130+ mpz_mul_2exp(*getmpz(cl), *getmpz(getbig(vm,x)), GETINT(y));
131+ return (VAL)cl;
241132}
242133
243134
244135VAL bigLShiftRight(VM* vm, VAL x, VAL y) {
245− idris_requireAlloc(IDRIS_MAXGMP);
246−
247− mpz_t* bigint;
248− VAL cl = allocate(sizeof(Closure) + sizeof(mpz_t), 0);
249− idris_doneAlloc();
250− bigint = (mpz_t*)(((char*)cl) + sizeof(Closure));
251− mpz_fdiv_q_2exp(*bigint, GETMPZ(GETBIG(vm,x)), GETINT(y));
252− SETTY(cl, CT_BIGINT);
253− cl -> info.ptr = (void*)bigint;
254− return cl;
136+ BigInt * cl = allocBig(vm);
137+ mpz_fdiv_q_2exp(*getmpz(cl), *getmpz(getbig(vm,x)), GETINT(y));
138+ return (VAL)cl;
255139}
256140
257141VAL bigAShiftRight(VM* vm, VAL x, VAL y) {
258− idris_requireAlloc(IDRIS_MAXGMP);
259−
260− mpz_t* bigint;
261− VAL cl = allocate(sizeof(Closure) + sizeof(mpz_t), 0);
262− idris_doneAlloc();
263− bigint = (mpz_t*)(((char*)cl) + sizeof(Closure));
264− mpz_fdiv_q_2exp(*bigint, GETMPZ(GETBIG(vm,x)), GETINT(y));
265− SETTY(cl, CT_BIGINT);
266− cl -> info.ptr = (void*)bigint;
267− return cl;
142+ BigInt * cl = allocBig(vm);
143+ mpz_fdiv_q_2exp(*getmpz(cl), *getmpz(getbig(vm,x)), GETINT(y));
144+ return (VAL)cl;
268145}
269146
270147VAL idris_bigAnd(VM* vm, VAL x, VAL y) {
@@ -323,15 +200,15 @@ VAL idris_bigTimes(VM* vm, VAL x, VAL y) {
323200 if (ISINT(x) && ISINT(y)) {
324201 i_int vx = GETINT(x);
325202 i_int vy = GETINT(y);
326− // we could work out likelihood of overflow by checking the number
327− // of necessary bits. Here's a quick conservative hack instead.
328− if ((vx < (1<<15) && vy < (1<16)) ||
329− (vx < (1<<16) && vy < (1<15)) ||
330− (vx < (1<<20) && vy < (1<11)) ||
331− (vx < (1<<11) && vy < (1<20)) ||
332− (vx < (1<<23) && vy < (1<<8)) ||
333− (vx < (1<<8) && vy < (1<<23))) { // ultra-conservative!
334− return INTOP(*,x,y);
203+ // we could work out likelihood of overflow by checking the number
204+ // of necessary bits. Here's a quick conservative hack instead.
205+ if ((vx < (1<<15) && vy < (1<16)) ||
206+ (vx < (1<<16) && vy < (1<15)) ||
207+ (vx < (1<<20) && vy < (1<11)) ||
208+ (vx < (1<<11) && vy < (1<20)) ||
209+ (vx < (1<<23) && vy < (1<<8)) ||
210+ (vx < (1<<8) && vy < (1<<23))) { // ultra-conservative!
211+ return INTOP(*,x,y);
335212 } else {
336213 return bigMul(vm, GETBIG(vm, x), GETBIG(vm, y));
337214 }
@@ -382,8 +259,8 @@ VAL idris_bigMod(VM* vm, VAL x, VAL y) {
382259
383260int bigEqConst(VAL x, int c) {
384261 if (ISINT(x)) { return (GETINT(x) == c); }
385− else {
386− int rv = mpz_cmp_si(GETMPZ(x), c);
262+ else {
263+ int rv = mpz_cmp_si(GETMPZ(x), c);
387264 return (rv == 0);
388265 }
389266}
@@ -471,17 +348,9 @@ VAL idris_castBigFloat(VM* vm, VAL i) {
471348
472349VAL idris_castFloatBig(VM* vm, VAL f) {
473350 double val = GETFLOAT(f);
474−
475− mpz_t* bigint;
476− VAL cl = allocate(sizeof(Closure) + sizeof(mpz_t), 0);
477− bigint = (mpz_t*)(((char*)cl) + sizeof(Closure));
478−
479− mpz_init_set_d(*bigint, val);
480−
481− SETTY(cl, CT_BIGINT);
482− cl -> info.ptr = (void*)bigint;
483−
484− return cl;
351+ BigInt * cl = allocBig(vm);
352+ mpz_init_set_d(*getmpz(cl), val);
353+ return (VAL)cl;
485354}
486355
487356VAL idris_castStrBig(VM* vm, VAL i) {
@@ -489,7 +358,7 @@ VAL idris_castStrBig(VM* vm, VAL i) {
489358}
490359
491360VAL idris_castBigStr(VM* vm, VAL i) {
492− char* str = mpz_get_str(NULL, 10, GETMPZ(GETBIG(vm, i)));
361+ char* str = mpz_get_str(NULL, 10, *getmpz(getbig(vm, i)));
493362 return MKSTR(vm, str);
494363}
495364
@@ -502,7 +371,7 @@ uint64_t idris_truncBigB64(const mpz_t bi) {
502371 }
503372 int64_t out = mpz_get_ui(bi);
504373 if (mpz_size(bi) > 1) {
505− out |= mpz_getlimbn(bi, 1) << 32;
374+ out |= ((int64_t)mpz_getlimbn(bi, 1)) << 32;
506375 }
507376 return out;
508377}
rts/idris_gmp.h+5−1
@@ -48,6 +48,10 @@ VAL idris_bigLShiftRight(VM* vm, VAL x, VAL y);
4848
4949uint64_t idris_truncBigB64(const mpz_t bi);
5050
51−#define GETMPZ(x) *((mpz_t*)((x)->info.ptr))
51+static inline mpz_t * getmpz(BigInt * v) {
52+ return (mpz_t*)(v->big);
53+}
54+
55+#define GETMPZ(x) *getmpz((BigInt*)x)
5256
5357#endif
rts/idris_heap.c+7−6
@@ -55,7 +55,7 @@ void c_heap_insert_if_needed(VM * vm, CHeap * heap, CHeapItem * item)
5555 heap->first = item;
5656
5757 // at this point, links are done; let's calculate sizes
58−
58+
5959 heap->size += item->size;
6060 if (heap->size >= heap->gc_trigger_size)
6161 {
@@ -186,16 +186,17 @@ void heap_check_pointers(Heap * heap) {
186186
187187 size_t item_size = 0;
188188 for(scan = heap->heap; scan < heap->next; scan += item_size) {
189− item_size = *((size_t*)scan);
190− VAL heap_item = (VAL)(scan + sizeof(size_t));
189+ VAL heap_item = (VAL)scan;
190+ item_size = aligned(valSize(heap_item));
191191
192192 switch(GETTY(heap_item)) {
193193 case CT_CON:
194194 {
195− int ar = ARITY(heap_item);
196− int i = 0;
195+ Con * c = (Con*)heap_item;
196+ size_t ar = CARITY(c);
197+ size_t i;
197198 for(i = 0; i < ar; ++i) {
198− VAL ptr = heap_item->info.c.args[i];
199+ VAL ptr = c->args[i];
199200
200201 if (is_valid_ref(ptr)) {
201202 // Check for closure.
rts/idris_main.c+2−3
@@ -3,7 +3,7 @@
33#include "idris_rts.h"
44#include "idris_stats.h"
55
6−void _idris__123_runMain_95_0_125_(VM* vm, VAL* oldbase);
6+void* _idris__123_runMain_95_0_125_(VM* vm, VAL* oldbase);
77
88#ifdef _WIN32
99
@@ -33,7 +33,7 @@ int win32_get_argv_utf8(int *argc_ptr, char ***argv_ptr)
3333#endif
3434
3535// The default options should give satisfactory results under many circumstances.
36−RTSOpts opts = {
36+RTSOpts opts = {
3737 .init_heap_size = 16384000,
3838 .max_stack_size = 4096000,
3939 .show_summary = 0
@@ -74,6 +74,5 @@ int main(int argc, char **argv) {
7474 print_stats(&stats);
7575 }
7676
77− free_nullaries();
7877 return EXIT_SUCCESS;
7978}
rts/idris_rts.c+256−344
@@ -7,13 +7,22 @@
77#include "idris_bitstring.h"
88#include "getline.h"
99
10+#define STATIC_ASSERT(COND,MSG) typedef char static_assertion_##MSG[(COND)?1:-1]
11+
12+STATIC_ASSERT(sizeof(Hdr) == 8, condSizeOfHdr);
13+
14+#if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__DragonFly__)
15+#include <signal.h>
16+#endif
17+
18+
1019#ifdef HAS_PTHREAD
1120static pthread_key_t vm_key;
1221#else
1322static VM* global_vm;
1423#endif
1524
16−void free_key(VM *vm) {
25+void free_key(void *vvm) {
1726 // nothing to free, we just used the VM pointer which is freed elsewhere
1827}
1928
@@ -40,8 +49,9 @@ VM* init_vm(int stack_size, size_t heap_size,
4049 vm->ret = NULL;
4150 vm->reg1 = NULL;
4251#ifdef HAS_PTHREAD
43− vm->inbox = malloc(1024*sizeof(VAL));
44− memset(vm->inbox, 0, 1024*sizeof(VAL));
52+ vm->inbox = malloc(1024*sizeof(vm->inbox[0]));
53+ assert(vm->inbox);
54+ memset(vm->inbox, 0, 1024*sizeof(vm->inbox[0]));
4555 vm->inbox_end = vm->inbox + 1024;
4656 vm->inbox_write = vm->inbox;
4757 vm->inbox_nextid = 1;
@@ -83,7 +93,6 @@ VM* idris_vm(void) {
8393
8494VM* get_vm(void) {
8595#ifdef HAS_PTHREAD
86− init_threadkeys();
8796 return pthread_getspecific(vm_key);
8897#else
8998 return global_vm;
@@ -96,7 +105,7 @@ void close_vm(VM* vm) {
96105
97106#ifdef HAS_PTHREAD
98107void create_key(void) {
99− pthread_key_create(&vm_key, (void*)free_key);
108+ pthread_key_create(&vm_key, free_key);
100109}
101110#endif
102111
@@ -155,13 +164,7 @@ CData cdata_manage(void * data, size_t size, CDataFinalizer finalizer)
155164 return c_heap_create_item(data, size, finalizer);
156165}
157166
158−void idris_requireAlloc(size_t size) {
159−#ifdef HAS_PTHREAD
160− VM* vm = pthread_getspecific(vm_key);
161−#else
162− VM* vm = global_vm;
163−#endif
164−
167+void idris_requireAlloc(VM * vm, size_t size) {
165168 if (!(vm->heap.next + size < vm->heap.end)) {
166169 idris_gc(vm);
167170 }
@@ -173,9 +176,8 @@ void idris_requireAlloc(size_t size) {
173176#endif
174177}
175178
176−void idris_doneAlloc(void) {
179+void idris_doneAlloc(VM * vm) {
177180#ifdef HAS_PTHREAD
178− VM* vm = pthread_getspecific(vm_key);
179181 int lock = vm->processes > 0;
180182 if (lock) { // We only need to lock if we're in concurrent mode
181183 pthread_mutex_unlock(&vm->alloc_lock);
@@ -184,14 +186,13 @@ void idris_doneAlloc(void) {
184186}
185187
186188int space(VM* vm, size_t size) {
187− return (vm->heap.next + size + sizeof(size_t) < vm->heap.end);
189+ return (vm->heap.next + size) < vm->heap.end;
188190}
189191
190192void* idris_alloc(size_t size) {
191− Closure* cl = (Closure*) allocate(sizeof(Closure)+size, 0);
193+ RawData * cl = (RawData*) allocate(sizeof(*cl)+size, 0);
192194 SETTY(cl, CT_RAWDATA);
193− cl->info.size = size;
194− return (void*)((char *)cl+sizeof(Closure));
195+ return (void*)cl->raw;
195196}
196197
197198void* idris_realloc(void* old, size_t old_size, size_t size) {
@@ -203,41 +204,36 @@ void* idris_realloc(void* old, size_t old_size, size_t size) {
203204void idris_free(void* ptr, size_t size) {
204205}
205206
206−void* allocate(size_t size, int outerlock) {
207−// return malloc(size);
207+void * allocate(size_t sz, int lock) {
208+ return iallocate(get_vm(), sz, lock);
209+}
210+
211+void* iallocate(VM * vm, size_t isize, int outerlock) {
212+// return malloc(isize);
213+ size_t size = aligned(isize);
208214
209215#ifdef HAS_PTHREAD
210− VM* vm = pthread_getspecific(vm_key);
211216 int lock = vm->processes > 0 && !outerlock;
212217
213218 if (lock) { // not message passing
214219 pthread_mutex_lock(&vm->alloc_lock);
215220 }
216−#else
217− VM* vm = global_vm;
218221#endif
219222
220− if ((size & 7)!=0) {
221− size = 8 + ((size >> 3) << 3);
222− }
223−
224− size_t chunk_size = size + sizeof(size_t);
225−
226− if (vm->heap.next + chunk_size < vm->heap.end) {
227− STATS_ALLOC(vm->stats, chunk_size)
228− void* ptr = (void*)(vm->heap.next + sizeof(size_t));
229− *((size_t*)(vm->heap.next)) = chunk_size;
230− vm->heap.next += chunk_size;
231−
223+ if (vm->heap.next + size < vm->heap.end) {
224+ STATS_ALLOC(vm->stats, size)
225+ char* ptr = vm->heap.next;
226+ vm->heap.next += size;
232227 assert(vm->heap.next <= vm->heap.end);
233−
234228 memset(ptr, 0, size);
229+ ((Hdr*)ptr)->sz = isize;
230+
235231#ifdef HAS_PTHREAD
236232 if (lock) { // not message passing
237233 pthread_mutex_unlock(&vm->alloc_lock);
238234 }
239235#endif
240− return ptr;
236+ return (void*)ptr;
241237 } else {
242238 // If we're trying to allocate something bigger than the heap,
243239 // grow the heap here so that the new heap is big enough.
@@ -250,173 +246,143 @@ void* allocate(size_t size, int outerlock) {
250246 pthread_mutex_unlock(&vm->alloc_lock);
251247 }
252248#endif
253− return allocate(size, 0);
249+ return iallocate(vm, size, outerlock);
254250 }
255251
256252}
257253
258−/* Now a macro
259−void* allocCon(VM* vm, int arity, int outer) {
260− Closure* cl = allocate(vm, sizeof(Closure) + sizeof(VAL)*arity,
261− outer);
262− SETTY(cl, CT_CON);
254+static String * allocStr(VM * vm, size_t len, int outer) {
255+ String * cl = iallocate(vm, sizeof(*cl) + len + 1, outer);
256+ SETTY(cl, CT_STRING);
257+ cl->slen = len;
258+ return cl;
259+}
263260
264− cl -> info.c.arity = arity;
265−// cl -> info.c.tag = 42424242;
266−// printf("%p\n", cl);
267− return (void*)cl;
261+static VAL mkfloat(VM* vm, double val, int outer) {
262+ Float * cl = iallocate(vm, sizeof(*cl), outer);
263+ SETTY(cl, CT_FLOAT);
264+ cl->f = val;
265+ return (VAL)cl;
268266}
269−*/
270267
271268VAL MKFLOAT(VM* vm, double val) {
272− Closure* cl = allocate(sizeof(Closure), 0);
273− SETTY(cl, CT_FLOAT);
274− cl -> info.f = val;
275− return cl;
269+ return mkfloat(vm, val, 0);
270+}
271+
272+VAL MKFLOATc(VM* vm, double val) {
273+ return mkfloat(vm, val, 1);
274+}
275+
276+static VAL mkstrlen(VM* vm, const char * str, size_t len, int outer) {
277+ String * cl = allocStr(vm, len, outer);
278+ // hdr.u8 used to mark a null string
279+ cl->hdr.u8 = str == NULL;
280+ if (!cl->hdr.u8)
281+ memcpy(cl->str, str, len);
282+ return (VAL)cl;
283+}
284+
285+VAL MKSTRlen(VM* vm, const char * str, size_t len) {
286+ return mkstrlen(vm, str, len, 0);
287+}
288+
289+VAL MKSTRclen(VM* vm, char* str, size_t len) {
290+ return mkstrlen(vm, str, len, 1);
276291}
277292
278293VAL MKSTR(VM* vm, const char* str) {
279− int len;
280− if (str == NULL) {
281− len = 0;
282− } else {
283− len = strlen(str)+1;
284− }
285− Closure* cl = allocate(sizeof(Closure) + // Type) + sizeof(char*) +
286− sizeof(char)*len, 0);
287− SETTY(cl, CT_STRING);
288− cl->info.str.str = (char*)cl + sizeof(Closure);
289− if (str == NULL) {
290− cl->info.str.str = NULL;
291− } else {
292− strcpy(cl->info.str.str, str);
293− }
294− cl->info.str.len = len > 0 ? len : 0;
295− return cl;
294+ return mkstrlen(vm, str, str? strlen(str) : 0, 0);
295+}
296+
297+VAL MKSTRc(VM* vm, char* str) {
298+ return mkstrlen(vm, str, strlen(str), 1);
299+}
300+
301+static char * getstroff(StrOffset * stroff) {
302+ return stroff->base->str + stroff->offset;
296303}
297304
298305char* GETSTROFF(VAL stroff) {
299306 // Assume STROFF
300− StrOffset* root = stroff->info.str_offset;
301− return (root->str->info.str.str + root->offset);
307+ return getstroff((StrOffset*)stroff);
308+}
309+
310+static size_t getstrofflen(StrOffset * stroff) {
311+ return stroff->base->slen - stroff->offset;
302312}
303313
304314size_t GETSTROFFLEN(VAL stroff) {
305315 // Assume STROFF
306316 // we're working in char* here so no worries about utf8 char length
307− StrOffset* root = stroff->info.str_offset;
308− return (root->str->info.str.len - root->offset);
317+ return getstrofflen((StrOffset*)stroff);
309318}
310319
311−VAL MKCDATA(VM* vm, CHeapItem * item) {
320+static VAL mkcdata(VM * vm, CHeapItem * item, int outer) {
312321 c_heap_insert_if_needed(vm, &vm->c_heap, item);
313− Closure* cl = allocate(sizeof(Closure), 0);
322+ CDataC * cl = iallocate(vm, sizeof(*cl), outer);
314323 SETTY(cl, CT_CDATA);
315− cl->info.c_heap_item = item;
316− return cl;
324+ cl->item = item;
325+ return (VAL)cl;
317326}
318327
319−VAL MKCDATAc(VM* vm, CHeapItem * item) {
320− c_heap_insert_if_needed(vm, &vm->c_heap, item);
321− Closure* cl = allocate(sizeof(Closure), 1);
322− SETTY(cl, CT_CDATA);
323− cl->info.c_heap_item = item;
324− return cl;
328+VAL MKCDATA(VM* vm, CHeapItem * item) {
329+ return mkcdata(vm, item, 0);
325330}
326331
327−VAL MKPTR(VM* vm, void* ptr) {
328− Closure* cl = allocate(sizeof(Closure), 0);
329− SETTY(cl, CT_PTR);
330− cl -> info.ptr = ptr;
331− return cl;
332+VAL MKCDATAc(VM* vm, CHeapItem * item) {
333+ return mkcdata(vm, item, 1);
332334}
333335
334−VAL MKMPTR(VM* vm, void* ptr, size_t size) {
335− Closure* cl = allocate(sizeof(Closure) +
336− sizeof(ManagedPtr) + size, 0);
337− SETTY(cl, CT_MANAGEDPTR);
338− cl->info.mptr = (ManagedPtr*)((char*)cl + sizeof(Closure));
339− cl->info.mptr->data = (char*)cl + sizeof(Closure) + sizeof(ManagedPtr);
340− memcpy(cl->info.mptr->data, ptr, size);
341− cl->info.mptr->size = size;
342− return cl;
336+static VAL mkptr(VM* vm, void* ptr, int outer) {
337+ Ptr * cl = iallocate(vm, sizeof(*cl), outer);
338+ SETTY(cl, CT_PTR);
339+ cl->ptr = ptr;
340+ return (VAL)cl;
343341}
344342
345−VAL MKFLOATc(VM* vm, double val) {
346− Closure* cl = allocate(sizeof(Closure), 1);
347− SETTY(cl, CT_FLOAT);
348− cl -> info.f = val;
349− return cl;
343+VAL MKPTR(VM* vm, void* ptr) {
344+ return mkptr(vm, ptr, 0);
350345}
351346
352−VAL MKSTRc(VM* vm, char* str) {
353− int len = strlen(str);
354−
355− Closure* cl = allocate(sizeof(Closure) + // Type) + sizeof(char*) +
356− sizeof(char)*len+1, 1);
357− SETTY(cl, CT_STRING);
358− cl -> info.str.str = (char*)cl + sizeof(Closure);
359−
360− strcpy(cl->info.str.str, str);
361− cl->info.str.len = len;
362− return cl;
347+VAL MKPTRc(VM* vm, void* ptr) {
348+ return mkptr(vm, ptr, 1);
363349}
364350
365−VAL MKSTRclen(VM* vm, char* str, int len) {
366− Closure* cl = allocate(sizeof(Closure) + // Type) + sizeof(char*) +
367− sizeof(char)*len+1, 1);
368− SETTY(cl, CT_STRING);
369− cl -> info.str.str = (char*)cl + sizeof(Closure);
370−
371− strcpy(cl->info.str.str, str);
372− cl->info.str.len = len;
373− return cl;
351+VAL mkmptr(VM* vm, void* ptr, size_t size, int outer) {
352+ ManagedPtr * cl = iallocate(vm, sizeof(*cl) + size, outer);
353+ SETTY(cl, CT_MANAGEDPTR);
354+ memcpy(cl->mptr, ptr, size);
355+ return (VAL)cl;
374356}
375357
376−VAL MKPTRc(VM* vm, void* ptr) {
377− Closure* cl = allocate(sizeof(Closure), 1);
378− SETTY(cl, CT_PTR);
379− cl -> info.ptr = ptr;
380− return cl;
358+VAL MKMPTR(VM* vm, void* ptr, size_t size) {
359+ return mkmptr(vm, ptr, size, 0);
381360}
382361
383362VAL MKMPTRc(VM* vm, void* ptr, size_t size) {
384− Closure* cl = allocate(sizeof(Closure) +
385− sizeof(ManagedPtr) + size, 1);
386− SETTY(cl, CT_MANAGEDPTR);
387− cl->info.mptr = (ManagedPtr*)((char*)cl + sizeof(Closure));
388− cl->info.mptr->data = (char*)cl + sizeof(Closure) + sizeof(ManagedPtr);
389− memcpy(cl->info.mptr->data, ptr, size);
390− cl->info.mptr->size = size;
391− return cl;
363+ return mkmptr(vm, ptr, size, 1);
392364}
393365
394366VAL MKB8(VM* vm, uint8_t bits8) {
395− Closure* cl = allocate(sizeof(Closure), 1);
396− SETTY(cl, CT_BITS8);
397− cl -> info.bits8 = bits8;
398− return cl;
367+ return MKINT(bits8);
399368}
400369
401370VAL MKB16(VM* vm, uint16_t bits16) {
402− Closure* cl = allocate(sizeof(Closure), 1);
403− SETTY(cl, CT_BITS16);
404− cl -> info.bits16 = bits16;
405− return cl;
371+ return MKINT(bits16);
406372}
407373
408374VAL MKB32(VM* vm, uint32_t bits32) {
409− Closure* cl = allocate(sizeof(Closure), 1);
375+ Bits32 * cl = iallocate(vm, sizeof(*cl), 1);
410376 SETTY(cl, CT_BITS32);
411− cl -> info.bits32 = bits32;
412− return cl;
377+ cl->bits32 = bits32;
378+ return (VAL)cl;
413379}
414380
415381VAL MKB64(VM* vm, uint64_t bits64) {
416− Closure* cl = allocate(sizeof(Closure), 1);
382+ Bits64 * cl = iallocate(vm, sizeof(*cl), 1);
417383 SETTY(cl, CT_BITS64);
418− cl -> info.bits64 = bits64;
419− return cl;
384+ cl->bits64 = bits64;
385+ return (VAL)cl;
420386}
421387
422388void idris_trace(VM* vm, const char* func, int line) {
@@ -445,29 +411,40 @@ void dumpStack(VM* vm) {
445411void dumpVal(VAL v) {
446412 if (v==NULL) return;
447413 int i;
448− if (ISINT(v)) {
449− printf("%d ", (int)(GETINT(v)));
450− return;
451− }
452414 switch(GETTY(v)) {
415+ case CT_INT:
416+ printf("%" PRIdPTR " ", GETINT(v));
417+ break;
453418 case CT_CON:
454− printf("%d[", TAG(v));
455− for(i = 0; i < ARITY(v); ++i) {
456− dumpVal(v->info.c.args[i]);
419+ {
420+ Con * cl = (Con*)v;
421+ printf("%d[", (int)TAG(cl));
422+ for(i = 0; i < CARITY(cl); ++i) {
423+ dumpVal(cl->args[i]);
424+ }
425+ printf("] ");
457426 }
458− printf("] ");
459427 break;
460428 case CT_STRING:
461− printf("STR[%s]", v->info.str.str);
429+ {
430+ String * cl = (String*)v;
431+ printf("STR[%s]", cl->str);
432+ }
462433 break;
463434 case CT_STROFFSET:
464− printf("OFFSET[");
465− dumpVal((VAL)(v->info.str_offset->str));
466− printf("]");
435+ {
436+ StrOffset * cl = (StrOffset*)v;
437+ printf("OFFSET[");
438+ dumpVal((VAL)cl->base);
439+ printf("]");
440+ }
467441 break;
468442 case CT_FWD:
469− printf("CT_FWD ");
470− dumpVal((VAL)(v->info.ptr));
443+ {
444+ Fwd * cl = (Fwd*)v;
445+ printf("CT_FWD ");
446+ dumpVal((VAL)cl->fwd);
447+ }
471448 break;
472449 default:
473450 printf("val");
@@ -489,7 +466,7 @@ void idris_poke(void* ptr, i_int offset, uint8_t data) {
489466
490467
491468VAL idris_peekPtr(VM* vm, VAL ptr, VAL offset) {
492− void** addr = (void **)((char *)GETPTR(ptr) + GETINT(offset));
469+ void** addr = (void **)(((char *)GETPTR(ptr)) + GETINT(offset));
493470 return MKPTR(vm, *addr);
494471}
495472
@@ -523,51 +500,36 @@ void idris_memmove(void* dest, void* src, i_int dest_offset, i_int src_offset, i
523500
524501VAL idris_castIntStr(VM* vm, VAL i) {
525502 int x = (int) GETINT(i);
526− Closure* cl = allocate(sizeof(Closure) + sizeof(char)*16, 0);
527− SETTY(cl, CT_STRING);
528− cl->info.str.str = (char*)cl + sizeof(Closure);
529− sprintf(cl->info.str.str, "%d", x);
530− cl->info.str.len = strlen(cl->info.str.str);
531− return cl;
503+ String * cl = allocStr(vm, 16, 0);
504+ cl->slen = sprintf(cl->str, "%d", x);
505+ return (VAL)cl;
532506}
533507
534508VAL idris_castBitsStr(VM* vm, VAL i) {
535− Closure* cl;
536− ClosureType ty = i->ty;
509+ String * cl;
510+ ClosureType ty = GETTY(i);
537511
538512 switch (ty) {
539− case CT_BITS8:
540− // max length 8 bit unsigned int str 3 chars (256)
541− cl = allocate(sizeof(Closure) + sizeof(char)*4, 0);
542− cl->info.str.str = (char*)cl + sizeof(Closure);
543− sprintf(cl->info.str.str, "%" PRIu8, (uint8_t)i->info.bits8);
544− break;
545− case CT_BITS16:
513+ case CT_INT: // 8/16 bits
546514 // max length 16 bit unsigned int str 5 chars (65,535)
547− cl = allocate(sizeof(Closure) + sizeof(char)*6, 0);
548− cl->info.str.str = (char*)cl + sizeof(Closure);
549− sprintf(cl->info.str.str, "%" PRIu16, (uint16_t)i->info.bits16);
515+ cl = allocStr(vm, 6, 0);
516+ cl->slen = sprintf(cl->str, "%" PRIu16, (uint16_t)GETBITS16(i));
550517 break;
551518 case CT_BITS32:
552519 // max length 32 bit unsigned int str 10 chars (4,294,967,295)
553− cl = allocate(sizeof(Closure) + sizeof(char)*11, 0);
554− cl->info.str.str = (char*)cl + sizeof(Closure);
555− sprintf(cl->info.str.str, "%" PRIu32, (uint32_t)i->info.bits32);
520+ cl = allocStr(vm, 11, 0);
521+ cl->slen = sprintf(cl->str, "%" PRIu32, GETBITS32(i));
556522 break;
557523 case CT_BITS64:
558524 // max length 64 bit unsigned int str 20 chars (18,446,744,073,709,551,615)
559− cl = allocate(sizeof(Closure) + sizeof(char)*21, 0);
560− cl->info.str.str = (char*)cl + sizeof(Closure);
561− sprintf(cl->info.str.str, "%" PRIu64, (uint64_t)i->info.bits64);
525+ cl = allocStr(vm, 21, 0);
526+ cl->slen = sprintf(cl->str, "%" PRIu64, GETBITS64(i));
562527 break;
563528 default:
564529 fprintf(stderr, "Fatal Error: ClosureType %d, not an integer type", ty);
565530 exit(EXIT_FAILURE);
566531 }
567−
568− cl->info.str.len = strlen(cl->info.str.str);
569− SETTY(cl, CT_STRING);
570− return cl;
532+ return (VAL)cl;
571533}
572534
573535VAL idris_castStrInt(VM* vm, VAL i) {
@@ -580,13 +542,9 @@ VAL idris_castStrInt(VM* vm, VAL i) {
580542}
581543
582544VAL idris_castFloatStr(VM* vm, VAL i) {
583− Closure* cl = allocate(sizeof(Closure) + sizeof(char)*32, 0);
584− SETTY(cl, CT_STRING);
585− cl->info.str.str = (char*)cl + sizeof(Closure);
586− snprintf(cl->info.str.str, 32, "%.16g", GETFLOAT(i));
587−
588− cl->info.str.len = strlen(cl->info.str.str);
589− return cl;
545+ String * cl = allocStr(vm, 32, 0);
546+ cl->slen = snprintf(cl->str, 32, "%.16g", GETFLOAT(i));
547+ return (VAL)cl;
590548}
591549
592550VAL idris_castStrFloat(VM* vm, VAL i) {
@@ -596,17 +554,13 @@ VAL idris_castStrFloat(VM* vm, VAL i) {
596554VAL idris_concat(VM* vm, VAL l, VAL r) {
597555 char *rs = GETSTR(r);
598556 char *ls = GETSTR(l);
599− int llen = GETSTRLEN(l);
600− int rlen = GETSTRLEN(r);
601−
602− Closure* cl = allocate(sizeof(Closure) + llen + rlen + 1, 0);
603− SETTY(cl, CT_STRING);
604− cl->info.str.str = (char*)cl + sizeof(Closure);
605− strcpy(cl->info.str.str, ls);
606− strcat(cl->info.str.str, rs);
557+ size_t llen = GETSTRLEN(l);
558+ size_t rlen = GETSTRLEN(r);
607559
608− cl->info.str.len = llen + rlen;
609− return cl;
560+ String * cl = allocStr(vm, llen + rlen, 0);
561+ memcpy(cl->str, ls, llen);
562+ memcpy(cl->str + llen, rs, rlen);
563+ return (VAL)cl;
610564}
611565
612566VAL idris_strlt(VM* vm, VAL l, VAL r) {
@@ -667,38 +621,32 @@ VAL idris_strHead(VM* vm, VAL str) {
667621 return idris_strIndex(vm, str, 0);
668622}
669623
670−VAL MKSTROFFc(VM* vm, StrOffset* off) {
671− Closure* cl = allocate(sizeof(Closure) + sizeof(StrOffset), 1);
624+VAL MKSTROFFc(VM* vm, VAL basestr) {
625+ StrOffset * cl = iallocate(vm, sizeof(*cl), 1);
672626 SETTY(cl, CT_STROFFSET);
673− cl->info.str_offset = (StrOffset*)((char*)cl + sizeof(Closure));
674−
675− cl->info.str_offset->str = off->str;
676− cl->info.str_offset->offset = off->offset;
677−
678− return cl;
627+ cl->base = (String*)basestr;
628+ return (VAL)cl;
679629}
680630
681631VAL idris_strShift(VM* vm, VAL str, int num) {
632+ size_t sz = sizeof(StrOffset);
682633 // If there's no room, just copy the string, or we'll have a problem after
683634 // gc moves str
684− if (space(vm, sizeof(Closure) + sizeof(StrOffset))) {
685− Closure* cl = allocate(sizeof(Closure) + sizeof(StrOffset), 0);
686− SETTY(cl, CT_STROFFSET);
687− cl->info.str_offset = (StrOffset*)((char*)cl + sizeof(Closure));
688−
635+ if (space(vm, sz)) {
689636 int offset = 0;
690− VAL root = str;
637+ StrOffset * root = (StrOffset*)str;
638+ StrOffset * cl = iallocate(vm, sz, 0);
639+ SETTY(cl, CT_STROFFSET);
691640
692641 while(root!=NULL && !ISSTR(root)) { // find the root, carry on.
693642 // In theory, at most one step here!
694− offset += root->info.str_offset->offset;
695− root = root->info.str_offset->str;
643+ offset += root->offset;
644+ root = (StrOffset*)root->base;
696645 }
697646
698− cl->info.str_offset->str = root;
699− cl->info.str_offset->offset = offset+idris_utf8_findOffset(GETSTR(str), num);
700−
701− return cl;
647+ cl->base = (String*)root;
648+ cl->offset = offset+idris_utf8_findOffset(GETSTR(str), num);
649+ return (VAL)cl;
702650 } else {
703651 char* nstr = GETSTR(str);
704652 return MKSTR(vm, nstr+idris_utf8_charlen(nstr));
@@ -712,29 +660,23 @@ VAL idris_strTail(VM* vm, VAL str) {
712660VAL idris_strCons(VM* vm, VAL x, VAL xs) {
713661 char *xstr = GETSTR(xs);
714662 int xval = GETINT(x);
715− int xlen = GETSTRLEN(xs);
663+ size_t xlen = GETSTRLEN(xs);
664+ String * cl;
716665
717666 if (xval < 0x80) { // ASCII char
718− Closure* cl = allocate(sizeof(Closure) +
719− xlen + 2, 0);
720− SETTY(cl, CT_STRING);
721− cl->info.str.str = (char*)cl + sizeof(Closure);
722− cl->info.str.str[0] = (char)(GETINT(x));
723− strcpy(cl->info.str.str+1, xstr);
724− cl->info.str.len = xlen + 1;
725− return cl;
667+ cl = allocStr(vm, xlen + 1, 0);
668+ cl->str[0] = (char)(GETINT(x));
669+ memcpy(cl->str+1, xstr, xlen);
726670 } else {
727671 char *init = idris_utf8_fromChar(xval);
728− int newlen = strlen(init) + xlen;
729− Closure* cl = allocate(sizeof(Closure) + newlen + 1, 0);
730− SETTY(cl, CT_STRING);
731− cl->info.str.str = (char*)cl + sizeof(Closure);
732− strcpy(cl->info.str.str, init);
733− strcat(cl->info.str.str, xstr);
734− cl->info.str.len = newlen;
672+ size_t ilen = strlen(init);
673+ int newlen = ilen + xlen;
674+ cl = allocStr(vm, newlen, 0);
675+ memcpy(cl->str, init, ilen);
676+ memcpy(cl->str + ilen, xstr, xlen);
735677 free(init);
736− return cl;
737678 }
679+ return (VAL)cl;
738680}
739681
740682VAL idris_strIndex(VM* vm, VAL str, VAL i) {
@@ -743,8 +685,8 @@ VAL idris_strIndex(VM* vm, VAL str, VAL i) {
743685}
744686
745687VAL idris_substr(VM* vm, VAL offset, VAL length, VAL str) {
746− int offset_val = GETINT(offset);
747− int length_val = GETINT(length);
688+ size_t offset_val = GETINT(offset);
689+ size_t length_val = GETINT(length);
748690 char* str_val = GETSTR(str);
749691
750692 // If the substring is a suffix, use idris_strShift to avoid reallocating
@@ -754,33 +696,28 @@ VAL idris_substr(VM* vm, VAL offset, VAL length, VAL str) {
754696 else {
755697 char *start = idris_utf8_advance(str_val, offset_val);
756698 char *end = idris_utf8_advance(start, length_val);
757− Closure* newstr = allocate(sizeof(Closure) + (end - start) +1, 0);
758− SETTY(newstr, CT_STRING);
759− newstr->info.str.str = (char*)newstr + sizeof(Closure);
760− memcpy(newstr->info.str.str, start, end - start);
761− *(newstr->info.str.str + (end - start) + 1) = '\0';
762− newstr->info.str.len = strlen(newstr->info.str.str);
763− return newstr;
699+ size_t sz = end - start;
700+ String * newstr = allocStr(vm, sz, 0);
701+ memcpy(newstr->str, start, sz);
702+ newstr->str[sz] = '\0';
703+ return (VAL)newstr;
764704 }
765705}
766706
767707VAL idris_strRev(VM* vm, VAL str) {
768708 char *xstr = GETSTR(str);
769− int xlen = GETSTRLEN(str);
709+ size_t xlen = GETSTRLEN(str);
770710
771− Closure* cl = allocate(sizeof(Closure) + xlen + 1, 0);
772− SETTY(cl, CT_STRING);
773− cl->info.str.str = (char*)cl + sizeof(Closure);
774− cl->info.str.len = xlen;
775− idris_utf8_rev(xstr, cl->info.str.str);
776− return cl;
711+ String * cl = allocStr(vm, xlen, 0);
712+ idris_utf8_rev(xstr, cl->str);
713+ return (VAL)cl;
777714}
778715
779716VAL idris_newRefLock(VAL x, int outerlock) {
780− Closure* cl = allocate(sizeof(Closure), outerlock);
717+ Ref * cl = allocate(sizeof(*cl), outerlock);
781718 SETTY(cl, CT_REF);
782− cl->info.ptr = (void*)x;
783− return cl;
719+ cl->ref = x;
720+ return (VAL)cl;
784721}
785722
786723VAL idris_newRef(VAL x) {
@@ -788,30 +725,34 @@ VAL idris_newRef(VAL x) {
788725}
789726
790727void idris_writeRef(VAL ref, VAL x) {
791− ref->info.ptr = (void*)x;
728+ Ref * r = (Ref*)ref;
729+ r->ref = x;
792730 SETTY(ref, CT_REF);
793731}
794732
795733VAL idris_readRef(VAL ref) {
796− return (VAL)(ref->info.ptr);
734+ Ref * r = (Ref*)ref;
735+ return r->ref;
797736}
798737
799738VAL idris_newArray(VM* vm, int size, VAL def) {
800− Closure* cl;
739+ Array * cl;
801740 int i;
802− allocArray(cl, vm, size, 0);
741+ cl = allocArrayF(vm, size, 0);
803742 for(i=0; i<size; ++i) {
804− cl->info.arr.content[i] = def;
743+ cl->array[i] = def;
805744 }
806− return cl;
745+ return (VAL)cl;
807746}
808747
809748void idris_arraySet(VAL arr, int index, VAL newval) {
810− arr->info.arr.content[index] = newval;
749+ Array * cl = (Array*)arr;
750+ cl->array[index] = newval;
811751}
812752
813753VAL idris_arrayGet(VAL arr, int index) {
814− return arr->info.arr.content[index];
754+ Array * cl = (Array*)arr;
755+ return cl->array[index];
815756}
816757
817758VAL idris_systemInfo(VM* vm, VAL index) {
@@ -892,88 +833,69 @@ void* idris_stopThread(VM* vm) {
892833 return NULL;
893834}
894835
836+static VAL doCopyTo(VM* vm, VAL x);
837+
838+static void copyArray(VM* vm, VAL * dst, VAL * src, size_t len) {
839+ size_t i;
840+ for(i = 0; i < len; ++i)
841+ dst[i] = doCopyTo(vm, src[i]);
842+}
843+
844+
895845// VM is assumed to be a different vm from the one x lives on
896846
897−VAL doCopyTo(VM* vm, VAL x) {
898− int i, ar, len;
899− VAL* argptr;
900− Closure* cl;
901− if (x==NULL || ISINT(x)) {
847+static VAL doCopyTo(VM* vm, VAL x) {
848+ int ar;
849+ VAL cl;
850+ if (x==NULL) {
902851 return x;
903852 }
904853 switch(GETTY(x)) {
854+ case CT_INT:
855+ return x;
856+ case CT_CDATA:
857+ cl = MKCDATAc(vm, GETCDATA(x));
858+ break;
859+ case CT_BIGINT:
860+ cl = MKBIGMc(vm, GETMPZ(x));
861+ break;
905862 case CT_CON:
906863 ar = CARITY(x);
907864 if (ar == 0 && CTAG(x) < 256) { // globally allocated
908865 cl = x;
909866 } else {
910− allocCon(cl, vm, CTAG(x), ar, 1);
911−
912− argptr = (VAL*)(cl->info.c.args);
913− for(i = 0; i < ar; ++i) {
914− *argptr = doCopyTo(vm, *((VAL*)(x->info.c.args)+i)); // recursive version
915− argptr++;
916− }
867+ Con * c = allocConF(vm, CTAG(x), ar, 1);
868+ copyArray(vm, c->args, ((Con*)x)->args, ar);
869+ cl = (VAL)c;
917870 }
918871 break;
919− case CT_ARRAY:
920− len = x->info.arr.length;
921− allocArray(cl, vm, len, 1);
922−
923− argptr = (VAL*)(cl->info.arr.content);
924− for(i = 0; i < len; ++i) {
925− *argptr = doCopyTo(vm, *((VAL*)(x->info.arr.content)+i)); // recursive version
926− argptr++;
927− }
928− break;
929− case CT_FLOAT:
930− cl = MKFLOATc(vm, x->info.f);
931− break;
872+ case CT_ARRAY: {
873+ size_t len = CELEM(x);
874+ Array * a = allocArrayF(vm, len, 1);
875+ copyArray(vm, a->array, ((Array*)x)->array, len);
876+ cl = (VAL)a;
877+ } break;
932878 case CT_STRING:
933− cl = MKSTRc(vm, x->info.str.str);
934− break;
935− case CT_BIGINT:
936− cl = MKBIGMc(vm, x->info.ptr);
937− break;
879+ case CT_FLOAT:
938880 case CT_PTR:
939− cl = MKPTRc(vm, x->info.ptr);
940− break;
941881 case CT_MANAGEDPTR:
942− cl = MKMPTRc(vm, x->info.mptr->data, x->info.mptr->size);
943− break;
944− case CT_CDATA:
945− cl = MKCDATAc(vm, x->info.c_heap_item);
946− break;
947− case CT_BITS8:
948− cl = idris_b8CopyForGC(vm, x);
949− break;
950− case CT_BITS16:
951− cl = idris_b16CopyForGC(vm, x);
952− break;
953882 case CT_BITS32:
954− cl = idris_b32CopyForGC(vm, x);
955− break;
956883 case CT_BITS64:
957− cl = idris_b64CopyForGC(vm, x);
958− break;
959884 case CT_RAWDATA:
960885 {
961− size_t size = x->info.size + sizeof(Closure);
962− cl = allocate(size, 0);
963− memcpy(cl, x, size);
886+ cl = iallocate(vm, x->hdr.sz, 0);
887+ memcpy(cl, x, x->hdr.sz);
964888 }
965889 break;
966890 default:
967891 assert(0); // We're in trouble if this happens...
892+ cl = NULL;
968893 }
969894 return cl;
970895}
971896
972897VAL copyTo(VM* vm, VAL x) {
973− VM* current = pthread_getspecific(vm_key);
974− pthread_setspecific(vm_key, vm);
975898 VAL ret = doCopyTo(vm, x);
976− pthread_setspecific(vm_key, current);
977899 return ret;
978900}
979901
@@ -1045,7 +967,7 @@ Msg* idris_checkInitMessages(VM* vm) {
1045967 Msg* msg;
1046968
1047969 for (msg = vm->inbox; msg < vm->inbox_end && msg->msg != NULL; ++msg) {
1048− if (msg->channel_id && 1 == 1) { // init bit set
970+ if ((msg->channel_id & 1) == 1) { // init bit set
1049971 return msg;
1050972 }
1051973 }
@@ -1108,11 +1030,11 @@ Msg* idris_recvMessage(VM* vm) {
11081030
11091031Msg* idris_recvMessageFrom(VM* vm, int channel_id, VM* sender) {
11101032 Msg* msg;
1111− Msg* ret = malloc(sizeof(Msg));
1033+ Msg* ret;
11121034
11131035 struct timespec timeout;
11141036 int status;
1115−
1037+
11161038 if (sender && sender->active == 0) { return NULL; } // No VM to receive from
11171039
11181040 pthread_mutex_lock(&vm->inbox_block);
@@ -1132,6 +1054,7 @@ Msg* idris_recvMessageFrom(VM* vm, int channel_id, VM* sender) {
11321054 pthread_mutex_unlock(&vm->inbox_block);
11331055
11341056 if (msg != NULL) {
1057+ ret = malloc(sizeof(*ret));
11351058 ret->msg = msg->msg;
11361059 ret->sender = msg->sender;
11371060
@@ -1158,7 +1081,6 @@ Msg* idris_recvMessageFrom(VM* vm, int channel_id, VM* sender) {
11581081 fprintf(stderr, "No messages waiting");
11591082 exit(-1);
11601083 }
1161−
11621084 return ret;
11631085}
11641086#endif
@@ -1187,26 +1109,16 @@ char* idris_showerror(int err) {
11871109 return strerror(err);
11881110}
11891111
1190−VAL* nullary_cons;
1112+Con nullary_cons[256];
11911113
11921114void init_nullaries(void) {
11931115 int i;
1194− VAL cl;
1195− nullary_cons = malloc(256 * sizeof(VAL));
11961116 for(i = 0; i < 256; ++i) {
1197− cl = malloc(sizeof(Closure));
1117+ Con * cl = nullary_cons + i;
1118+ cl->hdr.sz = sizeof(*cl);
11981119 SETTY(cl, CT_CON);
1199− cl->info.c.tag_arity = i << 8;
1200− nullary_cons[i] = cl;
1201− }
1202−}
1203−
1204−void free_nullaries(void) {
1205− int i;
1206− for(i = 0; i < 256; ++i) {
1207− free(nullary_cons[i]);
1120+ cl->tag = i;
12081121 }
1209− free(nullary_cons);
12101122}
12111123
12121124int __idris_argc;
rts/idris_rts.h+191−112
@@ -1,21 +1,19 @@
11#ifndef _IDRISRTS_H
22#define _IDRISRTS_H
33
4+#include <assert.h>
45#include <stdlib.h>
56#include <stdio.h>
7+#ifdef HAS_PTHREAD
68#include <string.h>
79#include <stdarg.h>
8−#ifdef HAS_PTHREAD
910#include <pthread.h>
1011#endif
11−#include <stdint.h>
12−#if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__DragonFly__)
13−#include <signal.h>
14−#endif
1512
1613#include "idris_heap.h"
1714#include "idris_stats.h"
1815
16+
1917#ifndef EXIT_SUCCESS
2018#define EXIT_SUCCESS 0
2119#endif
@@ -25,68 +23,97 @@
2523
2624// Closures
2725typedef enum {
28− CT_CON, CT_ARRAY, CT_INT, CT_BIGINT, CT_FLOAT, CT_STRING, CT_STROFFSET,
29− CT_BITS8, CT_BITS16, CT_BITS32, CT_BITS64, CT_UNIT, CT_PTR, CT_REF,
30− CT_FWD, CT_MANAGEDPTR, CT_RAWDATA, CT_CDATA
26+ CT_CON, CT_ARRAY, CT_INT, CT_BIGINT,
27+ CT_FLOAT, CT_STRING, CT_STROFFSET, CT_BITS32,
28+ CT_BITS64, CT_PTR, CT_REF, CT_FWD,
29+ CT_MANAGEDPTR, CT_RAWDATA, CT_CDATA
3130} ClosureType;
3231
33−typedef struct Closure *VAL;
34−
35−// A constructor, consisting of a tag, an arity (16 bits each of the
36−// tag_arity field) and arguments
37−typedef struct {
38− uint32_t tag_arity;
39− VAL args[];
40−} con;
41−
42−// An array; similar to a constructor but with a length, and contents
43−// initialised to NULL (high level Idris programs are responsible for
44−// initialising them properly)
45−typedef struct {
46− uint32_t length;
47− VAL content[];
48−} array;
49−
50−typedef struct {
51− VAL str;
32+typedef struct Hdr {
33+ uint8_t ty;
34+ uint8_t u8;
35+ uint16_t u16;
36+ uint32_t sz;
37+} Hdr;
38+
39+typedef struct Val {
40+ Hdr hdr;
41+} Val;
42+
43+typedef struct Val * VAL;
44+
45+typedef struct Con {
46+ Hdr hdr;
47+ uint32_t tag;
48+ VAL args[0];
49+} Con;
50+
51+typedef struct Array {
52+ Hdr hdr;
53+ VAL array[0];
54+} Array;
55+
56+typedef struct BigInt {
57+ Hdr hdr;
58+ char big[0];
59+} BigInt;
60+
61+typedef struct Float {
62+ Hdr hdr;
63+ double f;
64+} Float;
65+
66+typedef struct String {
67+ Hdr hdr;
68+ size_t slen;
69+ char str[0];
70+} String;
71+
72+typedef struct StrOffset {
73+ Hdr hdr;
74+ String * base;
5275 size_t offset;
5376} StrOffset;
5477
55−typedef struct {
56− char* str;
57− size_t len; // Cached strlen (we do 'strlen' a lot)
58−} String;
59−
60−// A foreign pointer, managed by the idris GC
61−typedef struct {
62− size_t size;
63− void* data;
78+typedef struct Bits32 {
79+ Hdr hdr;
80+ uint32_t bits32;
81+} Bits32;
82+
83+typedef struct Bits64 {
84+ Hdr hdr;
85+ uint64_t bits64;
86+} Bits64;
87+
88+typedef struct Ptr {
89+ Hdr hdr;
90+ void * ptr;
91+} Ptr;
92+
93+typedef struct Ref {
94+ Hdr hdr;
95+ VAL ref;
96+} Ref;
97+
98+typedef struct Fwd {
99+ Hdr hdr;
100+ VAL fwd;
101+} Fwd;
102+
103+typedef struct ManagedPtr {
104+ Hdr hdr;
105+ char mptr[0];
64106} ManagedPtr;
65107
66−typedef struct Closure {
67−// Use top 16 bits of ty for saying which heap value is in
68−// Bottom 16 bits for closure type
69−//
70−// NOTE: ty can not have type ClosureType because ty must be a
71−// uint32_t but enum is platform dependent
72− uint32_t ty;
73− union {
74− con c;
75− array arr;
76− int i;
77− double f;
78− String str;
79− StrOffset* str_offset;
80− void* ptr;
81− uint8_t bits8;
82− uint16_t bits16;
83− uint32_t bits32;
84− uint64_t bits64;
85− ManagedPtr* mptr;
86− CHeapItem* c_heap_item;
87− size_t size;
88− } info;
89−} Closure;
108+typedef struct RawData {
109+ Hdr hdr;
110+ char raw[0];
111+} RawData;
112+
113+typedef struct CDataC {
114+ Hdr hdr;
115+ CHeapItem * item;
116+} CDataC;
90117
91118struct VM;
92119
@@ -185,38 +212,48 @@ void init_threadkeys(void);
185212
186213// Functions all take a pointer to their VM, and previous stack base,
187214// and return nothing.
188−typedef void(*func)(VM*, VAL*);
215+typedef void*(*func)(VM*, VAL*);
189216
190217// Register access
191218
192219#define RVAL (vm->ret)
193−#define LOC(x) (*(vm->valstack_base + (x)))
194−#define TOP(x) (*(vm->valstack_top + (x)))
220+#define LOC(x) (vm->valstack_base[x])
221+#define TOP(x) (vm->valstack_top[x])
195222#define REG1 (vm->reg1)
196223
197224// Retrieving values
198−#define GETSTR(x) (ISSTR(x) ? (((VAL)(x))->info.str.str) : GETSTROFF(x))
199−#define GETSTRLEN(x) (ISSTR(x) ? (((VAL)(x))->info.str.len) : GETSTROFFLEN(x))
200−#define GETPTR(x) (((VAL)(x))->info.ptr)
201−#define GETMPTR(x) (((VAL)(x))->info.mptr->data)
202−#define GETFLOAT(x) (((VAL)(x))->info.f)
203−#define GETCDATA(x) (((VAL)(x))->info.c_heap_item)
204−
205−#define GETBITS8(x) (((VAL)(x))->info.bits8)
206−#define GETBITS16(x) (((VAL)(x))->info.bits16)
207−#define GETBITS32(x) (((VAL)(x))->info.bits32)
208−#define GETBITS64(x) (((VAL)(x))->info.bits64)
209−
210−#define TAG(x) (ISINT(x) || x == NULL ? (-1) : ( GETTY(x) == CT_CON ? (x)->info.c.tag_arity >> 8 : (-1)) )
211−#define ARITY(x) (ISINT(x) || x == NULL ? (-1) : ( GETTY(x) == CT_CON ? (x)->info.c.tag_arity & 0x000000ff : (-1)) )
225+static inline char * getstr(String * x) {
226+ // hdr.u8 used to mark a null string
227+ return x->hdr.u8? NULL : x->str;
228+}
229+
230+static inline size_t getstrlen(String * x) {
231+ return x->slen;
232+}
233+
234+#define GETSTR(x) (ISSTR(x) ? getstr((String*)(x)) : GETSTROFF(x))
235+#define GETSTRLEN(x) (ISSTR(x) ? getstrlen((String*)(x)) : GETSTROFFLEN(x))
236+#define GETPTR(x) (((Ptr*)(x))->ptr)
237+#define GETMPTR(x) (((ManagedPtr*)(x))->mptr)
238+#define GETFLOAT(x) (((Float*)(x))->f)
239+#define GETCDATA(x) (((CDataC*)(x))->item)
240+
241+#define GETBITS8(x) (GETINT(x))
242+#define GETBITS16(x) (GETINT(x))
243+#define GETBITS32(x) (((Bits32*)(x))->bits32)
244+#define GETBITS64(x) (((Bits64*)(x))->bits64)
212245
213246// Already checked it's a CT_CON
214−#define CTAG(x) (((x)->info.c.tag_arity) >> 8)
215−#define CARITY(x) ((x)->info.c.tag_arity & 0x000000ff)
247+#define CTAG(x) (((Con*)(x))->tag)
248+#define CARITY(x) (((Con*)(x))->hdr.u16) // hdr.u16 used to store arity
249+
250+#define TAG(x) (ISINT(x) || x == NULL ? (-1) : ( GETTY(x) == CT_CON ? CTAG((Con*)x) : (-1)) )
251+#define ARITY(x) (ISINT(x) || x == NULL ? (-1) : ( GETTY(x) == CT_CON ? CARITY((Con*)x) : (-1)) )
216252
253+#define CELEM(x) (((x)->hdr.sz - sizeof(Array)) / sizeof(VAL))
217254
218−#define GETTY(x) ((x)->ty)
219−#define SETTY(x,t) ((x)->ty = t)
255+#define GETTY(x) (ISINT(x)? CT_INT : (ClosureType)((x)->hdr.ty))
256+#define SETTY(x,t) ((x)->hdr.ty = t)
220257
221258// Integers, floats and operators
222259
@@ -241,25 +278,33 @@ typedef intptr_t i_int;
241278#ifdef IDRIS_TRACE
242279#define TRACE idris_trace(vm, __FUNCTION__, __LINE__);
243280#else
244−#define TRACE
281+#define TRACE
245282#endif
246283
247284#define INITFRAME TRACE\
248− __attribute__((unused)) VAL* myoldbase
249−
250−#define REBASE vm->valstack_base = oldbase
251−#define RESERVE(x) if (vm->valstack_top+(x) > vm->stack_max) { stackOverflow(); } \
252− else { memset(vm->valstack_top, 0, (x)*sizeof(VAL)); }
285+ __attribute__((unused)) VAL* myoldbase;\
286+ void* callres
287+
288+#define REBASE vm->valstack_base = oldbase; return NULL
289+#define RESERVE(x) do { \
290+ if (vm->valstack_top+(x) > vm->stack_max) { stackOverflow(); } \
291+ else { memset(vm->valstack_top, 0, (x)*sizeof(VAL)); } \
292+ } while(0)
253293#define ADDTOP(x) vm->valstack_top += (x)
254294#define TOPBASE(x) vm->valstack_top = vm->valstack_base + (x)
255295#define BASETOP(x) vm->valstack_base = vm->valstack_top + (x)
256296#define STOREOLD myoldbase = vm->valstack_base
257−#define CALL(f) f(vm, myoldbase);
258−#define TAILCALL(f) f(vm, oldbase);
297+
298+#define CALL(f) callres = f(vm, myoldbase); \
299+ while(callres!=NULL) { \
300+ callres = ((func)(callres))(vm, myoldbase); \
301+ }
302+#define TAILCALL(f) return (void*)(f);
259303
260304// Creating new values (each value placed at the top of the stack)
261305VAL MKFLOAT(VM* vm, double val);
262306VAL MKSTR(VM* vm, const char* str);
307+VAL MKSTRlen(VM* vm, const char* str, size_t size);
263308VAL MKPTR(VM* vm, void* ptr);
264309VAL MKMPTR(VM* vm, void* ptr, size_t size);
265310VAL MKB8(VM* vm, uint8_t b);
@@ -270,9 +315,9 @@ VAL MKCDATA(VM* vm, CHeapItem * item);
270315
271316// following versions don't take a lock when allocating
272317VAL MKFLOATc(VM* vm, double val);
273−VAL MKSTROFFc(VM* vm, StrOffset* off);
318+VAL MKSTROFFc(VM* vm, VAL basestr);
274319VAL MKSTRc(VM* vm, char* str);
275−VAL MKSTRclen(VM* vm, char* str, int len);
320+VAL MKSTRclen(VM* vm, char* str, size_t len);
276321VAL MKPTRc(VM* vm, void* ptr);
277322VAL MKMPTRc(VM* vm, void* ptr, size_t size);
278323VAL MKCDATAc(VM* vm, CHeapItem * item);
@@ -280,15 +325,16 @@ VAL MKCDATAc(VM* vm, CHeapItem * item);
280325char* GETSTROFF(VAL stroff);
281326size_t GETSTROFFLEN(VAL stroff);
282327
283−// #define SETTAG(x, a) (x)->info.c.tag = (a)
284−#define SETARG(x, i, a) ((x)->info.c.args)[i] = ((VAL)(a))
285−#define GETARG(x, i) ((x)->info.c.args)[i]
328+#define SETARG(x, i, a) (((Con*)(x))->args)[i] = ((VAL)(a))
329+#define GETARG(x, i) (((Con*)(x))->args[i])
286330
287331#define PROJECT(vm,r,loc,num) \
288− memcpy(&(LOC(loc)), &((r)->info.c.args), sizeof(VAL)*num)
332+ memcpy(&(LOC(loc)), ((Con*)(r))->args, sizeof(VAL)*num)
289333#define SLIDE(vm, args) \
290334 memcpy(&(LOC(0)), &(TOP(0)), sizeof(VAL)*args)
291335
336+void* iallocate(VM *, size_t, int);
337+
292338void* allocate(size_t size, int outerlock);
293339// void* allocCon(VM* vm, int arity, int outerlock);
294340
@@ -298,8 +344,8 @@ void* allocate(size_t size, int outerlock);
298344// idris_doneAlloc *must* be called when allocation from C is done (as it
299345// may take a lock if other threads are running).
300346
301−void idris_requireAlloc(size_t size);
302−void idris_doneAlloc(void);
347+void idris_requireAlloc(VM *, size_t size);
348+void idris_doneAlloc(VM *);
303349
304350// public interface to allocation (note that this may move other pointers
305351// if allocating beyond the limits given by idris_requireAlloc!)
@@ -308,29 +354,44 @@ void* idris_alloc(size_t size);
308354void* idris_realloc(void* old, size_t old_size, size_t size);
309355void idris_free(void* ptr, size_t size);
310356
311−#define allocCon(cl, vm, t, a, o) \
312− cl = allocate(sizeof(Closure) + sizeof(VAL)*a, o); \
313− SETTY(cl, CT_CON); \
314− cl->info.c.tag_arity = ((t) << 8) | (a);
357+static inline void updateConF(Con * cl, unsigned tag, unsigned arity) {
358+ SETTY(cl, CT_CON);
359+ cl->tag = tag;
360+ // hdr.u16 used to store arity
361+ cl->hdr.u16 = arity;
362+ assert(cl->hdr.sz == sizeof(*cl) + sizeof(VAL) * arity);
363+ // cl->hdr.sz = sizeof(*cl) + sizeof(VAL) * arity;
364+}
365+
366+static inline Con * allocConF(VM * vm, unsigned tag, unsigned arity, int outer) {
367+ Con * cl = iallocate(vm, sizeof(*cl) + sizeof(VAL) * arity, outer);
368+ SETTY(cl, CT_CON);
369+ cl->tag = tag;
370+ // hdr.u16 used to store arity
371+ cl->hdr.u16 = arity;
372+ return cl;
373+}
374+
375+static inline Array * allocArrayF(VM * vm, size_t len, int outer) {
376+ Array * cl = iallocate(vm, sizeof(*cl) + sizeof(VAL) * len, outer);
377+ SETTY(cl, CT_ARRAY);
378+ return cl;
379+}
380+
315381
316−#define updateCon(cl, old, t, a) \
317− cl = old; \
318− SETTY(cl, CT_CON); \
319− cl->info.c.tag_arity = ((t) << 8) | (a);
382+#define allocCon(cl, vm, t, a, o) (cl) = (VAL)allocConF(vm, t, a, o)
320383
321−#define NULL_CON(x) nullary_cons[x]
384+#define updateCon(cl, old, tag, arity) (cl) = (old); updateConF(cl, tag, arity)
322385
323−#define allocArray(cl, vm, len, o) \
324− cl = allocate(sizeof(Closure) + sizeof(VAL)*len, o); \
325− SETTY(cl, CT_ARRAY); \
326− cl->info.arr.length = len;
386+#define NULL_CON(x) ((VAL)(nullary_cons + x))
387+
388+#define allocArray(cl, vm, len, o) (cl) = (VAL)allocArrayF(vm, len, o)
327389
328390int idris_errno(void);
329391char* idris_showerror(int err);
330392
331−extern VAL* nullary_cons;
393+extern Con nullary_cons[];
332394void init_nullaries(void);
333−void free_nullaries(void);
334395
335396void init_signals(void);
336397
@@ -460,4 +521,22 @@ void stackOverflow(void);
460521
461522#include "idris_gmp.h"
462523
524+static inline size_t valSize(VAL v) {
525+ return v->hdr.sz;
526+}
527+
528+static inline size_t aligned(size_t sz) {
529+ return (sz + sizeof(void*) - 1) & ~(sizeof(void*)-1);
530+}
531+
532+VM* get_vm(void);
533+
463534#endif
535+
536+/*
537+ Local variables: **
538+ c-file-style: "bsd" **
539+ c-basic-offset: 4 **
540+ indent-tabs-mode: nil **
541+ End: **
542+*/
rts/idris_stdfgn.c+42−3
@@ -6,9 +6,9 @@
66#include <fcntl.h>
77#include <errno.h>
88#include <sys/stat.h>
9−#include <stdio.h>
109#include <time.h>
1110#include <dirent.h>
11+#include <unistd.h>
1212
1313#ifdef _WIN32
1414int win_fpoll(void* h);
@@ -60,6 +60,42 @@ int fileSize(void* h) {
6060 }
6161}
6262
63+VAL fileAccessTime(void* h) {
64+ FILE* f = (FILE*)h;
65+ int fd = fileno(f);
66+
67+ struct stat buf;
68+ if (fstat(fd, &buf) == 0) {
69+ return MKBIGI(buf.st_atime);
70+ } else {
71+ return MKBIGI(-1);
72+ }
73+}
74+
75+VAL fileModifiedTime(void* h) {
76+ FILE* f = (FILE*)h;
77+ int fd = fileno(f);
78+
79+ struct stat buf;
80+ if (fstat(fd, &buf) == 0) {
81+ return MKBIGI(buf.st_mtime);
82+ } else {
83+ return MKBIGI(-1);
84+ }
85+}
86+
87+VAL fileStatusTime(void* h) {
88+ FILE* f = (FILE*)h;
89+ int fd = fileno(f);
90+
91+ struct stat buf;
92+ if (fstat(fd, &buf) == 0) {
93+ return MKBIGI(buf.st_ctime);
94+ } else {
95+ return MKBIGI(-1);
96+ }
97+}
98+
6399typedef struct {
64100 DIR* dirptr;
65101 int error;
@@ -79,7 +115,7 @@ void* idris_dirOpen(char* dname) {
79115
80116void idris_dirClose(void* h) {
81117 DirInfo* di = (DirInfo*)h;
82−
118+
83119 closedir(di->dirptr);
84120 free(di);
85121}
@@ -104,6 +140,10 @@ int idris_mkdir(char* dname) {
104140#endif
105141}
106142
143+int idris_chdir(char* dname) {
144+ return chdir(dname);
145+}
146+
107147int idris_dirError(void *dptr) {
108148 return ((DirInfo*)dptr)->error;
109149}
@@ -219,4 +259,3 @@ VAL idris_getString(VM* vm, void* buffer) {
219259 free(sb);
220260 return str;
221261}
222−
rts/idris_stdfgn.h+6
@@ -15,12 +15,18 @@ int fileError(void* h);
1515// Returns a negative number if not a file (e.g. directory or device)
1616int fileSize(void* h);
1717
18+// Return a negative number if not a file (e.g. directory or device)
19+VAL fileAccessTime(void* h);
20+VAL fileModifiedTime(void* h);
21+VAL fileStatusTime(void* h);
22+
1823void* idris_dirOpen(char* dname);
1924void idris_dirClose(void* h);
2025char* idris_nextDirEntry(void* h);
2126
2227// Create a directory; return 0 on success or -1 on failure
2328int idris_mkdir(char* dname);
29+int idris_chdir(char* dname);
2430
2531// Return 0 if ok, or -1 if there was an error with the given directory
2632// (like ferror)
src/IRTS/CodegenC.hs+75−69
@@ -79,18 +79,22 @@ codegenC' defs out exec incs objs libs flags exports iface dbg
7979 libFlags <- getLibFlags
8080 incFlags <- getIncFlags
8181 envFlags <- getEnvFlags
82− let stackFlag = if isWindows then ["-Wl,--stack,16777216"] else []
82+ let stripFlag = if isDarwin then "-dead_strip" else "-Wl,-gc-sections"
83+ let stackFlags = if isWindows then ["-Wl,--stack,16777216"] else []
84+ let linkFlags = stripFlag : stackFlags
8385 let args = gccDbg dbg ++
8486 gccFlags iface ++
8587 -- # Any flags defined here which alter the RTS API must also be added to config.mk
86− ["-std=c99", "-D_POSIX_C_SOURCE=200809L", "-DHAS_PTHREAD", "-DIDRIS_ENABLE_STATS",
87− "-I."] ++ objs ++ envFlags ++
88− (if (exec == Executable) then [] else ["-c"]) ++
88+ [ "-std=c99", "-pipe"
89+ , "-fdata-sections", "-ffunction-sections"
90+ , "-D_POSIX_C_SOURCE=200809L", "-DHAS_PTHREAD", "-DIDRIS_ENABLE_STATS"
91+ , "-I."] ++ objs ++ envFlags ++
92+ (if (exec == Executable) then linkFlags else ["-c"]) ++
8993 [tmpn] ++
9094 (if not iface then libFlags else []) ++
9195 incFlags ++
9296 (if not iface then libs else []) ++
93− flags ++ stackFlag ++
97+ flags ++
9498 ["-o", out]
9599-- putStrLn (show args)
96100 exit <- rawSystem comp args
@@ -113,11 +117,7 @@ gccFlags i = if i then ["-fwrapv"]
113117 else ["-fwrapv", "-fno-strict-overflow"]
114118
115119gccDbg DEBUG = ["-g"]
116−-- clang optimises sibling calls in O1, but gcc doesn't
117−-- on the other hand, O1 compiles significantly faster in clang without
118−-- any noticeable performance hit.
119−gccDbg TRACE = ["-O1", "-foptimize-sibling-calls"]
120−gccDbg _ = ["-O1", "-foptimize-sibling-calls"]
120+gccDbg _ = []
121121
122122cname :: Name -> String
123123cname n = "_idris_" ++ concatMap cchar (showCG n)
@@ -133,14 +133,14 @@ creg (T i) = "TOP(" ++ show i ++ ")"
133133creg Tmp = "REG1"
134134
135135toDecl :: Name -> String
136−toDecl f = "void " ++ cname f ++ "(VM*, VAL*);\n"
136+toDecl f = "void* " ++ cname f ++ "(VM*, VAL*);\n"
137137
138138toC :: Name -> [BC] -> String
139139toC f code
140140 = -- "/* " ++ show code ++ "*/\n\n" ++
141− "void " ++ cname f ++ "(VM* vm, VAL* oldbase) {\n" ++
142− indent 1 ++ "INITFRAME;\n" ++
143− concatMap (bcc 1) code ++ "}\n\n"
141+ "void* " ++ cname f ++ "(VM* vm, VAL* oldbase) {\n" ++
142+ indent 1 ++ "INITFRAME;\nloop:\n" ++
143+ concatMap (bcc f 1) code ++ "}\n\n"
144144
145145showCStr :: String -> String
146146showCStr s = '"' : foldr ((++) . showChar) "\"" s
@@ -176,9 +176,9 @@ showCStr s = '"' : foldr ((++) . showChar) "\"" s
176176 2 -> s
177177 _ -> error $ "Can't happen: String of invalid length " ++ show s
178178
179−bcc :: Int -> BC -> String
180−bcc i (ASSIGN l r) = indent i ++ creg l ++ " = " ++ creg r ++ ";\n"
181−bcc i (ASSIGNCONST l c)
179+bcc :: Name -> Int -> BC -> String
180+bcc f i (ASSIGN l r) = indent i ++ creg l ++ " = " ++ creg r ++ ";\n"
181+bcc f i (ASSIGNCONST l c)
182182 = indent i ++ creg l ++ " = " ++ mkConst c ++ ";\n"
183183 where
184184 mkConst (I i) = "MKINT(" ++ show i ++ ")"
@@ -199,10 +199,10 @@ bcc i (ASSIGNCONST l c)
199199 mkConst c | isTypeConst c = "MKINT(42424242)"
200200 mkConst c = error $ "mkConst of (" ++ show c ++ ") not implemented"
201201
202−bcc i (UPDATE l r) = indent i ++ creg l ++ " = " ++ creg r ++ ";\n"
203−bcc i (MKCON l loc tag []) | tag < 256
202+bcc f i (UPDATE l r) = indent i ++ creg l ++ " = " ++ creg r ++ ";\n"
203+bcc f i (MKCON l loc tag []) | tag < 256
204204 = indent i ++ creg l ++ " = NULL_CON(" ++ show tag ++ ");\n"
205−bcc i (MKCON l loc tag args)
205+bcc f i (MKCON l loc tag args)
206206 = indent i ++ alloc loc tag ++
207207 indent i ++ setArgs 0 args ++ "\n" ++
208208 indent i ++ creg l ++ " = " ++ creg Tmp ++ ";\n"
@@ -216,21 +216,21 @@ bcc i (MKCON l loc tag args)
216216 = "updateCon(" ++ creg Tmp ++ ", " ++ creg old ++ ", " ++ show tag ++ ", " ++
217217 show (length args) ++ ");\n"
218218
219−bcc i (PROJECT l loc a) = indent i ++ "PROJECT(vm, " ++ creg l ++ ", " ++ show loc ++
219+bcc f i (PROJECT l loc a) = indent i ++ "PROJECT(vm, " ++ creg l ++ ", " ++ show loc ++
220220 ", " ++ show a ++ ");\n"
221−bcc i (PROJECTINTO r t idx)
221+bcc f i (PROJECTINTO r t idx)
222222 = indent i ++ creg r ++ " = GETARG(" ++ creg t ++ ", " ++ show idx ++ ");\n"
223−bcc i (CASE True r [(_, alt)] Nothing)
223+bcc f i (CASE True r [(_, alt)] Nothing)
224224 = indent i ++ showCode i alt
225225 where
226226 showCode :: Int -> [BC] -> String
227− showCode i bc = "{\n" ++ concatMap (bcc (i + 1)) bc ++
227+ showCode i bc = "{\n" ++ concatMap (bcc f (i + 1)) bc ++
228228 indent i ++ "}\n"
229−bcc i (CASE True r code def)
229+bcc f i (CASE True r code def)
230230 | length code < 6 && length code > 1 = showCase i def code
231231 where
232232 showCode :: Int -> [BC] -> String
233− showCode i bc = "{\n" ++ concatMap (bcc (i + 1)) bc ++
233+ showCode i bc = "{\n" ++ concatMap (bcc f (i + 1)) bc ++
234234 indent i ++ "}\n"
235235
236236 showCase :: Int -> Maybe [BC] -> [(Int, [BC])] -> String
@@ -240,7 +240,7 @@ bcc i (CASE True r code def)
240240 = indent i ++ "if (CTAG(" ++ creg r ++ ") == " ++ show t ++ ") " ++ showCode i c
241241 ++ indent i ++ "else\n" ++ showCase i def cs
242242
243−bcc i (CASE safe r code def)
243+bcc f i (CASE safe r code def)
244244 = indent i ++ "switch(" ++ ctag safe ++ "(" ++ creg r ++ ")) {\n" ++
245245 concatMap (showCase i) code ++
246246 showDef i def ++
@@ -250,11 +250,12 @@ bcc i (CASE safe r code def)
250250 ctag False = "TAG"
251251
252252 showCase i (t, bc) = indent i ++ "case " ++ show t ++ ":\n"
253− ++ concatMap (bcc (i+1)) bc ++ indent (i + 1) ++ "break;\n"
254− showDef i Nothing = ""
253+ ++ concatMap (bcc f (i+1)) bc ++ indent (i + 1) ++ "break;\n"
254+ showDef i Nothing = indent i ++ "default:\n" ++
255+ indent (i + 1) ++ "return NULL;\n"
255256 showDef i (Just c) = indent i ++ "default:\n"
256− ++ concatMap (bcc (i+1)) c ++ indent (i + 1) ++ "break;\n"
257−bcc i (CONSTCASE r code def)
257+ ++ concatMap (bcc f (i+1)) c ++ indent (i + 1) ++ "break;\n"
258+bcc f i (CONSTCASE r code def)
258259 | intConsts code
259260-- = indent i ++ "switch(GETINT(" ++ creg r ++ ")) {\n" ++
260261-- concatMap (showCase i) code ++
@@ -286,65 +287,67 @@ bcc i (CONSTCASE r code def)
286287
287288 strCase sv (s, bc) =
288289 indent i ++ "if (strcmp(" ++ sv ++ ", " ++ show s ++ ") == 0) {\n" ++
289− concatMap (bcc (i+1)) bc ++ indent i ++ "} else\n"
290+ concatMap (bcc f (i+1)) bc ++ indent i ++ "} else\n"
290291 biCase bv (BI b, bc) =
291292 indent i ++ "if (bigEqConst(" ++ bv ++ ", " ++ show b ++ ")) {\n"
292− ++ concatMap (bcc (i+1)) bc ++ indent i ++ "} else\n"
293+ ++ concatMap (bcc f (i+1)) bc ++ indent i ++ "} else\n"
293294 iCase v (I b, bc) =
294295 indent i ++ "if (GETINT(" ++ v ++ ") == " ++ show b ++ ") {\n"
295− ++ concatMap (bcc (i+1)) bc ++ indent i ++ "} else\n"
296+ ++ concatMap (bcc f (i+1)) bc ++ indent i ++ "} else\n"
296297 iCase v (Ch b, bc) =
297298 indent i ++ "if (GETINT(" ++ v ++ ") == " ++ show (fromEnum b) ++ ") {\n"
298− ++ concatMap (bcc (i+1)) bc ++ indent i ++ "} else\n"
299+ ++ concatMap (bcc f (i+1)) bc ++ indent i ++ "} else\n"
299300 iCase v (B8 w, bc) =
300301 indent i ++ "if (GETBITS8(" ++ v ++ ") == " ++ show (fromEnum w) ++ ") {\n"
301− ++ concatMap (bcc (i+1)) bc ++ indent i ++ "} else\n"
302+ ++ concatMap (bcc f (i+1)) bc ++ indent i ++ "} else\n"
302303 iCase v (B16 w, bc) =
303304 indent i ++ "if (GETBITS16(" ++ v ++ ") == " ++ show (fromEnum w) ++ ") {\n"
304− ++ concatMap (bcc (i+1)) bc ++ indent i ++ "} else\n"
305+ ++ concatMap (bcc f (i+1)) bc ++ indent i ++ "} else\n"
305306 iCase v (B32 w, bc) =
306307 indent i ++ "if (GETBITS32(" ++ v ++ ") == " ++ show (fromEnum w) ++ ") {\n"
307− ++ concatMap (bcc (i+1)) bc ++ indent i ++ "} else\n"
308+ ++ concatMap (bcc f (i+1)) bc ++ indent i ++ "} else\n"
308309 iCase v (B64 w, bc) =
309310 indent i ++ "if (GETBITS64(" ++ v ++ ") == " ++ show (fromEnum w) ++ ") {\n"
310− ++ concatMap (bcc (i+1)) bc ++ indent i ++ "} else\n"
311+ ++ concatMap (bcc f (i+1)) bc ++ indent i ++ "} else\n"
311312 showDefS i Nothing = ""
312− showDefS i (Just c) = concatMap (bcc (i+1)) c
313−
314−bcc i (CALL n) = indent i ++ "CALL(" ++ cname n ++ ");\n"
315−bcc i (TAILCALL n) = indent i ++ "TAILCALL(" ++ cname n ++ ");\n"
316−bcc i (SLIDE n) = indent i ++ "SLIDE(vm, " ++ show n ++ ");\n"
317−bcc i REBASE = indent i ++ "REBASE;\n"
318−bcc i (RESERVE 0) = ""
319−bcc i (RESERVE n) = indent i ++ "RESERVE(" ++ show n ++ ");\n"
320−bcc i (ADDTOP 0) = ""
321−bcc i (ADDTOP n) = indent i ++ "ADDTOP(" ++ show n ++ ");\n"
322−bcc i (TOPBASE n) = indent i ++ "TOPBASE(" ++ show n ++ ");\n"
323−bcc i (BASETOP n) = indent i ++ "BASETOP(" ++ show n ++ ");\n"
324−bcc i STOREOLD = indent i ++ "STOREOLD;\n"
325−bcc i (OP l fn args) = indent i ++ doOp (creg l ++ " = ") fn args ++ ";\n"
326−bcc i (FOREIGNCALL l rty (FStr ('#':name)) [])
313+ showDefS i (Just c) = concatMap (bcc f (i+1)) c
314+
315+bcc f i (CALL n) = indent i ++ "CALL(" ++ cname n ++ ");\n"
316+bcc f i (TAILCALL n)
317+ | f == n = indent i ++ "goto loop;\n"
318+ | otherwise = indent i ++ "TAILCALL(" ++ cname n ++ ");\n"
319+bcc f i (SLIDE n) = indent i ++ "SLIDE(vm, " ++ show n ++ ");\n"
320+bcc f i REBASE = indent i ++ "REBASE;\n"
321+bcc f i (RESERVE 0) = ""
322+bcc f i (RESERVE n) = indent i ++ "RESERVE(" ++ show n ++ ");\n"
323+bcc f i (ADDTOP 0) = ""
324+bcc f i (ADDTOP n) = indent i ++ "ADDTOP(" ++ show n ++ ");\n"
325+bcc f i (TOPBASE n) = indent i ++ "TOPBASE(" ++ show n ++ ");\n"
326+bcc f i (BASETOP n) = indent i ++ "BASETOP(" ++ show n ++ ");\n"
327+bcc f i STOREOLD = indent i ++ "STOREOLD;\n"
328+bcc f i (OP l fn args) = indent i ++ doOp (creg l ++ " = ") fn args ++ ";\n"
329+bcc f i (FOREIGNCALL l rty (FStr ('#':name)) [])
327330 = indent i ++
328331 c_irts (toFType rty) (creg l ++ " = ") name ++ ";\n"
329−bcc i (FOREIGNCALL l rty (FStr fn@('&':name)) [])
332+bcc f i (FOREIGNCALL l rty (FStr fn@('&':name)) [])
330333 = indent i ++
331334 c_irts (toFType rty) (creg l ++ " = ") fn ++ ";\n"
332−bcc i (FOREIGNCALL l rty (FStr fn) (x:xs)) | fn == "%wrapper"
335+bcc f i (FOREIGNCALL l rty (FStr fn) (x:xs)) | fn == "%wrapper"
333336 = indent i ++
334337 c_irts (toFType rty) (creg l ++ " = ")
335338 ("_idris_get_wrapper(" ++ creg (snd x) ++ ")") ++ ";\n"
336−bcc i (FOREIGNCALL l rty (FStr fn) (x:xs)) | fn == "%dynamic"
339+bcc f i (FOREIGNCALL l rty (FStr fn) (x:xs)) | fn == "%dynamic"
337340 = indent i ++ c_irts (toFType rty) (creg l ++ " = ")
338341 ("(*(" ++ cFnSig "" rty xs ++ ") GETPTR(" ++ creg (snd x) ++ "))" ++
339342 "(" ++ showSep "," (map fcall xs) ++ ")") ++ ";\n"
340−bcc i (FOREIGNCALL l rty (FStr fn) args)
343+bcc f i (FOREIGNCALL l rty (FStr fn) args)
341344 = indent i ++
342345 c_irts (toFType rty) (creg l ++ " = ")
343346 (fn ++ "(" ++ showSep "," (map fcall args) ++ ")") ++ ";\n"
344−bcc i (FOREIGNCALL l rty _ args) = error "Foreign Function calls cannot be partially applied, without being inlined."
345−bcc i (NULL r) = indent i ++ creg r ++ " = NULL;\n" -- clear, so it'll be GCed
346−bcc i (ERROR str) = indent i ++ "fprintf(stderr, " ++ show str ++ "); fprintf(stderr, \"\\n\"); exit(-1);\n"
347−-- bcc i c = error (show c) -- indent i ++ "// not done yet\n"
347+bcc f i (FOREIGNCALL l rty _ args) = error "Foreign Function calls cannot be partially applied, without being inlined."
348+bcc f i (NULL r) = indent i ++ creg r ++ " = NULL;\n" -- clear, so it'll be GCed
349+bcc f i (ERROR str) = indent i ++ "fprintf(stderr, " ++ show str ++ "); fprintf(stderr, \"\\n\"); exit(-1);\n"
350+-- bcc f i c = error (show c) -- indent i ++ "// not done yet\n"
348351
349352fcall (t, arg) = irts_c (toFType t) (creg arg)
350353-- Deconstruct the Foreign type in the defunctionalised expression and build
@@ -396,7 +399,7 @@ c_irts FFunctionIO l x = error "Return of function from foreign call is not supp
396399irts_c (FArith (ATInt ITNative)) x = "GETINT(" ++ x ++ ")"
397400irts_c (FArith (ATInt ITChar)) x = irts_c (FArith (ATInt ITNative)) x
398401irts_c (FArith (ATInt (ITFixed ity))) x
399− = "(" ++ x ++ "->info.bits" ++ show (nativeTyWidth ity) ++ ")"
402+ = "GETBITS" ++ show (nativeTyWidth ity) ++ "(" ++ x ++ ")"
400403irts_c FString x = "GETSTR(" ++ x ++ ")"
401404irts_c FUnit x = x
402405irts_c FPtr x = "GETPTR(" ++ x ++ ")"
@@ -536,13 +539,13 @@ doOp v (LURem (ITFixed ty)) [x, y] = bitOp v "URem" ty [x, y]
536539doOp v (LSRem (ATInt (ITFixed ty))) [x, y] = bitOp v "SRem" ty [x, y]
537540
538541doOp v (LSExt (ITFixed from) ITBig) [x]
539− = v ++ "MKBIGSI(vm, (" ++ signedTy from ++ ")" ++ creg x ++ "->info.bits" ++ show (nativeTyWidth from) ++ ")"
542+ = v ++ "MKBIGSI(vm, (" ++ signedTy from ++ ") GETBITS" ++ show (nativeTyWidth from) ++ "(" ++ creg x ++ "))"
540543doOp v (LSExt ITNative (ITFixed to)) [x]
541544 = v ++ "idris_b" ++ show (nativeTyWidth to) ++ "const(vm, GETINT(" ++ creg x ++ "))"
542545doOp v (LSExt ITChar (ITFixed to)) [x]
543546 = doOp v (LSExt ITNative (ITFixed to)) [x]
544547doOp v (LSExt (ITFixed from) ITNative) [x]
545− = v ++ "MKINT((i_int)((" ++ signedTy from ++ ")" ++ creg x ++ "->info.bits" ++ show (nativeTyWidth from) ++ "))"
548+ = v ++ "MKINT((i_int)((" ++ signedTy from ++ ") GETBITS" ++ show (nativeTyWidth from) ++ "(" ++ creg x ++ ")))"
546549doOp v (LSExt (ITFixed from) ITChar) [x]
547550 = doOp v (LSExt (ITFixed from) ITNative) [x]
548551doOp v (LSExt (ITFixed from) (ITFixed to)) [x]
@@ -552,11 +555,11 @@ doOp v (LZExt ITNative (ITFixed to)) [x]
552555doOp v (LZExt ITChar (ITFixed to)) [x]
553556 = doOp v (LZExt ITNative (ITFixed to)) [x]
554557doOp v (LZExt (ITFixed from) ITNative) [x]
555− = v ++ "MKINT((i_int)" ++ creg x ++ "->info.bits" ++ show (nativeTyWidth from) ++ ")"
558+ = v ++ "MKINT((i_int)GETBITS" ++ show (nativeTyWidth from) ++ "(" ++ creg x ++ "))"
556559doOp v (LZExt (ITFixed from) ITChar) [x]
557560 = doOp v (LZExt (ITFixed from) ITNative) [x]
558561doOp v (LZExt (ITFixed from) ITBig) [x]
559− = v ++ "MKBIGUI(vm, " ++ creg x ++ "->info.bits" ++ show (nativeTyWidth from) ++ ")"
562+ = v ++ "MKBIGUI(vm, GETBITS" ++ show (nativeTyWidth from) ++ "(" ++ creg x ++ "))"
560563doOp v (LZExt ITNative ITBig) [x]
561564 = v ++ "MKBIGUI(vm, (uintptr_t)GETINT(" ++ creg x ++ "))"
562565doOp v (LZExt (ITFixed from) (ITFixed to)) [x]
@@ -566,7 +569,7 @@ doOp v (LTrunc ITNative (ITFixed to)) [x]
566569doOp v (LTrunc ITChar (ITFixed to)) [x]
567570 = doOp v (LTrunc ITNative (ITFixed to)) [x]
568571doOp v (LTrunc (ITFixed from) ITNative) [x]
569− = v ++ "MKINT((i_int)" ++ creg x ++ "->info.bits" ++ show (nativeTyWidth from) ++ ")"
572+ = v ++ "MKINT((i_int)GETBITS" ++ show (nativeTyWidth from) ++ "(" ++ creg x ++ "))"
570573doOp v (LTrunc (ITFixed from) ITChar) [x]
571574 = doOp v (LTrunc (ITFixed from) ITNative) [x]
572575doOp v (LTrunc ITBig (ITFixed IT64)) [x]
@@ -886,7 +889,10 @@ getCallback bc = getCallback' (reverse bc)
886889 getCallback' [] = []
887890 findCons (c:cs) xs = findCon c xs ++ findCons cs xs
888891 findCons [] _ = []
889− findCon c ((MKCON l loc tag args):xs) | snd c == l = [(fst c, tag)]
892+ findCon c ((MKCON l loc tag args):xs) | snd c == l =
893+ if null args
894+ then [(fst c, tag)]
895+ else error "Can't wrap a closure as callback."
890896 findCon c (_:xs) = findCon c xs
891897 findCon c [] = []
892898
src/IRTS/JavaScript/Codegen.hs+6−1
@@ -5,7 +5,7 @@ Description : The JavaScript common code generator.
55License : BSD3
66Maintainer : The Idris Community.
77-}
8−{-# LANGUAGE OverloadedStrings #-}
8+{-# LANGUAGE CPP, OverloadedStrings #-}
99
1010module IRTS.JavaScript.Codegen( codegenJs
1111 , CGConf(..)
@@ -48,6 +48,11 @@ data CGStats = CGStats { usedBigInt :: Bool
4848 , hiddenClasses :: Set HiddenClass
4949 }
5050
51+#if (MIN_VERSION_base(4,11,0))
52+instance Semigroup CGStats where
53+ (<>) = mappend
54+#endif
55+
5156-- If we generate code for two declarations we want to merge their code
5257-- generation stats.
5358instance Monoid CGStats where
src/IRTS/Lang.hs+25
@@ -455,3 +455,28 @@ instance Show LExp where
455455
456456 showAlt env ind (LConstCase c e) = show c ++ " => " ++ show' env ind e
457457 showAlt env ind (LDefaultCase e) = "_ => " ++ show' env ind e
458+
459+occName :: Name -> LExp -> Int
460+occName n (LV x) = if n == x then 1 else 0
461+occName n (LApp t e es) = occName n e + sum (map (occName n) es)
462+occName n (LLazyApp x es)
463+ = if n == x then 1 + sum (map (occName n) es)
464+ else sum (map (occName n) es)
465+occName n (LForce e) = occName n e
466+occName n (LLet x v sc)
467+ = if n == x then occName n v
468+ else occName n v + occName n sc
469+occName n (LLam ns sc)
470+ = if n `elem` ns then 0 else occName n sc
471+occName n (LProj e i) = occName n e
472+occName n (LCon _ _ _ es) = sum (map (occName n) es)
473+occName n (LCase t e alts) = occName n e + maximum (map occAlt alts)
474+ where
475+ occAlt (LConCase _ _ ns e)
476+ = if n `elem` ns then 0 else occName n e
477+ occAlt (LConstCase _ e) = occName n e
478+ occAlt (LDefaultCase e) = occName n e
479+occName n (LForeign _ _ es) = sum (map (occName n . snd) es)
480+occName n (LOp _ es) = sum (map (occName n) es)
481+occName n _ = 0
482+
src/IRTS/LangOpts.hs+56−27
@@ -33,16 +33,23 @@ nextN = do i <- get
3333-- uniqueness of variable names in the resulting definition, so invent
3434-- a new name for every variable we encounter
3535doInline :: LDefs -> LDecl -> LDecl
36−doInline defs d@(LConstructor _ _ _) = d
37−doInline defs (LFun opts topn args exp)
36+doInline = doInline' 1
37+
38+doInline' :: Int -> LDefs -> LDecl -> LDecl
39+doInline' 0 defs d = d
40+doInline' i defs d@(LConstructor _ _ _) = d
41+doInline' i defs (LFun opts topn args exp)
3842 = let inl = evalState (eval [] initEnv [topn] defs exp)
3943 (length args)
4044 -- do some case floating, which might arise as a result
4145 -- then, eta contract
4246 res = eta $ caseFloats 10 inl in
4347 case res of
44− LLam args' body -> LFun opts topn (map snd initNames ++ args') body
45− _ -> LFun opts topn (map snd initNames) res
48+ LLam args' body ->
49+ doInline' (i - 1) defs $
50+ LFun opts topn (map snd initNames ++ args') body
51+ _ -> doInline' (i - 1) defs $
52+ LFun opts topn (map snd initNames) res
4653 where
4754 caseFloats 0 tm = tm
4855 caseFloats n tm
@@ -72,8 +79,8 @@ eval stk env rec defs (LLazyApp n es)
7279eval stk env rec defs (LForce e)
7380 = do e' <- eval [] env rec defs e
7481 case e' of
75− LLazyExp forced -> return $ unload stk forced
76− LLazyApp n es -> return $ unload stk (LApp False (LV n) es)
82+ LLazyExp forced -> eval stk env rec defs forced
83+ LLazyApp n es -> eval stk env rec defs (LApp False (LV n) es)
7784 _ -> return (unload stk (LForce e'))
7885eval stk env rec defs (LLazyExp e)
7986 = unload stk <$> LLazyExp <$> eval [] env rec defs e
@@ -92,6 +99,7 @@ eval (world : stk) env rec defs (LApp t (LV n) [_, _, _, act, (LLam [arg] k)])
9299 = do act' <- eval [] env rec defs (LApp False act [world])
93100 argn <- nextN
94101 k' <- eval stk ((arg, LV argn) : env) rec defs (LApp False k [world])
102+ -- Needs to be a LLet to make sure the action gets evaluated
95103 return $ LLet argn act' k'
96104
97105eval stk env rec defs (LApp t f es)
@@ -105,16 +113,30 @@ eval stk env rec defs (LProj exp i)
105113 = unload stk <$> (LProj <$> eval [] env rec defs exp <*> return i)
106114eval stk env rec defs (LCon loc i n es)
107115 = unload stk <$> (LCon loc i n <$> mapM (eval [] env rec defs) es)
116+eval stk env rec defs (LCase ty e [])
117+ = pure LNothing
108118eval stk env rec defs (LCase ty e alts)
109− = do alts' <- mapM (evalAlt stk env rec defs) alts
110− e' <- eval [] env rec defs e
111− -- If they're all lambdas, bind the lambda at the top
112− let prefix = getLams (map getRHS alts')
113− case prefix of
114− [] -> return $ conOpt $ LCase ty e' (replaceInAlts e' alts')
115− args -> do alts_red <- mapM (dropArgs args) alts'
116− return $ LLam args
117− (conOpt (LCase ty e' (replaceInAlts e' alts_red)))
119+ = do e' <- eval [] env rec defs e
120+ case evalAlts e' alts of
121+ Just (env', tm) -> eval stk env' rec defs tm
122+ Nothing ->
123+ do alts' <- mapM (evalAlt stk env rec defs) alts
124+ -- If they're all lambdas, bind the lambda at the top
125+ let prefix = getLams (map getRHS alts')
126+ case prefix of
127+ [] -> return $ LCase ty e' (replaceInAlts e' alts')
128+ args -> do alts_red <- mapM (dropArgs args) alts'
129+ return $ LLam args
130+ (LCase ty e' (replaceInAlts e' alts_red))
131+ where
132+ evalAlts e' [] = Nothing
133+ evalAlts (LCon _ t n args) (LConCase i n' es rhs : as)
134+ | n == n' = Just (zip es args ++ env, rhs)
135+ evalAlts (LConst c) (LConstCase c' rhs : as)
136+ | c == c' = Just (env, rhs)
137+ evalAlts (LCon _ _ _ _) (LDefaultCase rhs : as) = Just (env, rhs)
138+ evalAlts (LConst _) (LDefaultCase rhs : as) = Just (env, rhs)
139+ evalAlts tm (_ : as) = evalAlts tm as
118140eval stk env rec defs (LOp f es)
119141 = unload stk <$> LOp f <$> mapM (eval [] env rec defs) es
120142eval stk env rec defs (LForeign t s args)
@@ -129,9 +151,9 @@ eval stk env rec defs (LLam args sc)
129151 [] -> eval stk' env' rec defs sc
130152 as -> do ns' <- mapM (\n -> do n' <- nextN
131153 return (n, n')) args'
132− unload stk' <$> LLam (map snd ns') <$>
133− eval [] (map (\ (n, n') -> (n, LV n')) ns' ++ env')
134− rec defs sc
154+ LLam (map snd ns') <$>
155+ eval stk' (map (\ (n, n') -> (n, LV n')) ns' ++ env')
156+ rec defs sc
135157eval stk env rec defs var@(LV n)
136158 = case lookup n env of
137159 Just t
@@ -164,19 +186,24 @@ apply stk env rec defs var args body
164186 = eval stk env rec defs (LLam args body)
165187
166188dropArgs :: [Name] -> LAlt -> State Int LAlt
167−dropArgs as (LConCase i n es (LLam args rhs))
168− = do let old = take (length as) args
169− rhs' <- eval [] (zipWith (\ o n -> (o, LV n)) old as) [] emptyContext rhs
189+dropArgs as (LConCase i n es t)
190+ = do rhs' <- dropArgsTm as t
170191 return (LConCase i n es rhs')
171−dropArgs as (LConstCase c (LLam args rhs))
172− = do let old = take (length as) args
173− rhs' <- eval [] (zipWith (\ o n -> (o, LV n)) old as) [] emptyContext rhs
192+dropArgs as (LConstCase c t)
193+ = do rhs' <- dropArgsTm as t
174194 return (LConstCase c rhs')
175−dropArgs as (LDefaultCase (LLam args rhs))
176− = do let old = take (length as) args
177− rhs' <- eval [] (zipWith (\ o n -> (o, LV n)) old as) [] emptyContext rhs
195+dropArgs as (LDefaultCase t)
196+ = do rhs' <- dropArgsTm as t
178197 return (LDefaultCase rhs')
179198
199+dropArgsTm as (LLam args rhs)
200+ = do let old = take (length as) args
201+ eval [] (zipWith (\ o n -> (o, LV n)) old as) [] emptyContext rhs
202+dropArgsTm as (LLet n val rhs)
203+ = do rhs' <- dropArgsTm as rhs
204+ pure (LLet n val rhs')
205+dropArgsTm as tm = return tm
206+
180207caseFloat :: LExp -> LExp
181208caseFloat (LApp tc e es) = LApp tc (caseFloat e) (map caseFloat es)
182209caseFloat (LLazyExp e) = LLazyExp (caseFloat e)
@@ -272,12 +299,14 @@ getRHS (LDefaultCase rhs) = rhs
272299
273300getLams [] = []
274301getLams (LLam args tm : cs) = getLamPrefix args cs
302+getLams (LLet n val exp : cs) = getLams (exp : cs)
275303getLams _ = []
276304
277305getLamPrefix as [] = as
278306getLamPrefix as (LLam args tm : cs)
279307 | length args < length as = getLamPrefix args cs
280308 | otherwise = getLamPrefix as cs
309+getLamPrefix as (LLet n val exp : cs) = getLamPrefix as (exp : cs)
281310getLamPrefix as (_ : cs) = []
282311
283312-- eta contract ('\x -> f x' can just be compiled as 'f' when f is local)
src/IRTS/System.hs+8−2
@@ -61,7 +61,13 @@ overrideIdrisSubDirWith fp envVar = do
6161 Just ddir -> return ddir
6262
6363getCC :: IO String
64−getCC = fromMaybe "gcc" <$> lookupEnv "IDRIS_CC"
64+getCC = fromMaybe cc <$> lookupEnv "IDRIS_CC"
65+ where
66+#ifdef mingw32_HOST_OS
67+ cc = "gcc"
68+#else
69+ cc = "cc"
70+#endif
6571
6672getEnvFlags :: IO [String]
6773getEnvFlags = maybe [] (splitOn " ") <$> lookupEnv "IDRIS_CFLAGS"
@@ -77,7 +83,7 @@ extraInclude = []
7783#endif
7884
7985#ifdef IDRIS_GMP
80−gmpLib = ["-lgmp"]
86+gmpLib = ["-lgmp", "-DIDRIS_GMP"]
8187#else
8288gmpLib = []
8389#endif
src/Idris/AbsSyntaxTree.hs+31−12
@@ -6,9 +6,10 @@ License : BSD3
66Maintainer : The Idris Community.
77-}
88
9−{-# LANGUAGE DeriveDataTypeable, DeriveFoldable, DeriveFunctor, DeriveGeneric,
10− DeriveTraversable, FlexibleContexts, FlexibleInstances,
11− MultiParamTypeClasses, PatternGuards, TypeSynonymInstances #-}
9+{-# LANGUAGE CPP, DeriveDataTypeable, DeriveFoldable, DeriveFunctor,
10+ DeriveGeneric, DeriveTraversable, FlexibleContexts,
11+ FlexibleInstances, MultiParamTypeClasses, PatternGuards,
12+ TypeSynonymInstances #-}
1213
1314module Idris.AbsSyntaxTree where
1415
@@ -25,8 +26,11 @@ import Util.Pretty
2526import Idris.Colours
2627
2728import System.IO
28−
29+#if (MIN_VERSION_base(4,11,0))
30+import Prelude hiding (Foldable, Traversable, (<$>), (<>))
31+#else
2932import Prelude hiding (Foldable, Traversable, (<$>))
33+#endif
3034
3135import Control.Applicative ((<|>))
3236import qualified Control.Monad.Trans.Class as Trans (lift)
@@ -47,7 +51,6 @@ import Data.Traversable (Traversable)
4751import Data.Typeable
4852import GHC.Generics (Generic)
4953
50−
5154data ElabWhat = ETypes | EDefns | EAll
5255 deriving (Show, Eq)
5356
@@ -299,8 +302,8 @@ data IState = IState {
299302
300303 , idris_symbols :: M.Map Name Name -- ^ Symbol table (preserves sharing of names)
301304 , idris_exports :: [Name] -- ^ Functions with ExportList
302− , idris_highlightedRegions :: [(FC, OutputAnnotation)] -- ^ Highlighting information to output
303− , idris_parserHighlights :: [(FC, OutputAnnotation)] -- ^ Highlighting information from the parser
305+ , idris_highlightedRegions :: S.Set (FC', OutputAnnotation) -- ^ Highlighting information to output
306+ , idris_parserHighlights :: S.Set (FC', OutputAnnotation) -- ^ Highlighting information from the parser
304307 , idris_deprecated :: Ctxt String -- ^ Deprecated names and explanation
305308 , idris_inmodule :: S.Set Name -- ^ Names defined in current module
306309 , idris_ttstats :: M.Map Term (Int, Term)
@@ -408,7 +411,7 @@ idrisInit = IState initContext S.empty []
408411 [] [] [] defaultOpts 6 [] [] [] [] [] emptySyntaxRules [] [] [] [] [] [] []
409412 [] [] Nothing [] Nothing [] [] Nothing emptyContext Private DefaultCheckingPartial [] Nothing [] []
410413 (RawOutput stdout) True defaultTheme [] (0, emptyContext) emptyContext M.empty
411− AutomaticWidth S.empty S.empty [] [] [] M.empty [] [] []
414+ AutomaticWidth S.empty S.empty [] [] [] M.empty [] S.empty S.empty
412415 emptyContext S.empty M.empty emptyContext initialInteractiveOpts
413416
414417
@@ -707,19 +710,19 @@ data EState = EState {
707710 case_decls :: [(Name, PDecl)]
708711 , delayed_elab :: [(Int, Elab' EState ())]
709712 , new_tyDecls :: [RDeclInstructions]
710− , highlighting :: [(FC, OutputAnnotation)]
713+ , highlighting :: S.Set (FC', OutputAnnotation)
711714 , auto_binds :: [Name] -- ^ names bound as auto implicits
712715 , implicit_warnings :: [(FC, Name)] -- ^ Implicit warnings to report (location and global name)
713716 }
714717
715718initEState :: EState
716−initEState = EState [] [] [] [] [] []
719+initEState = EState [] [] [] S.empty [] []
717720
718721type ElabD a = Elab' EState a
719722
720723highlightSource :: FC -> OutputAnnotation -> ElabD ()
721724highlightSource fc annot =
722− updateAux (\aux -> aux { highlighting = (fc, annot) : highlighting aux })
725+ updateAux (\aux -> aux { highlighting = S.insert (FC' fc, annot) (highlighting aux) })
723726
724727-- | One clause of a top-level definition. Term arguments to constructors are:
725728--
@@ -1988,7 +1991,7 @@ pprintPTerm ppo bnd docArgs infixes = prettySe (ppopt_depth ppo) startPrec bnd
19881991 prettyArgS d bnd (PConstraint _ _ _ tm) = prettyArgSc d bnd tm
19891992 prettyArgS d bnd (PTacImplicit _ _ n _ tm) = prettyArgSti d bnd (n, tm)
19901993
1991− prettyArgSe d bnd arg = prettySe d (funcAppPrec + 1) bnd arg
1994+ prettyArgSe d bnd arg = prettySe (decD d) (funcAppPrec + 1) bnd arg
19921995 prettyArgSi d bnd (n, val) = lbrace <> pretty n <+> text "=" <+> prettySe (decD d) startPrec bnd val <> rbrace
19931996 prettyArgSc d bnd val = lbrace <> lbrace <> prettySe (decD d) startPrec bnd val <> rbrace <> rbrace
19941997 prettyArgSti d bnd (n, val) = lbrace <> kwd "auto" <+> pretty n <+> text "=" <+> prettySe (decD d) startPrec bnd val <> rbrace
@@ -2275,25 +2278,41 @@ allNamesIn tm = nub $ ni 0 [] tm
22752278 ni 0 env (PPatvar _ n) = [n]
22762279 ni 0 env (PApp _ f as) = ni 0 env f ++ concatMap (ni 0 env . getTm) as
22772280 ni 0 env (PAppBind _ f as) = ni 0 env f ++ concatMap (ni 0 env . getTm) as
2281+ ni 0 env (PWithApp _ f a) = ni 0 env f ++ ni 0 env a
2282+ ni 0 env (PAppImpl t _) = ni 0 env t
22782283 ni 0 env (PCase _ c os) = ni 0 env c ++ concatMap (ni 0 env . snd) os
22792284 ni 0 env (PIfThenElse _ c t f) = ni 0 env c ++ ni 0 env t ++ ni 0 env f
22802285 ni 0 env (PLam fc n _ ty sc) = ni 0 env ty ++ ni 0 (n:env) sc
22812286 ni 0 env (PPi p n _ ty sc) = niTacImp 0 env p ++ ni 0 env ty ++ ni 0 (n:env) sc
22822287 ni 0 env (PLet _ _ n _ ty val sc) = ni 0 env ty ++ ni 0 env val ++ ni 0 (n:env) sc
22832288 ni 0 env (PHidden tm) = ni 0 env tm
2289+ ni 0 env (PGoal _ t _ sc) = ni 0 env t ++ ni 0 env sc
2290+ ni 0 env (PIdiom _ tm) = ni 0 env tm
22842291 ni 0 env (PRewrite _ _ l r _) = ni 0 env l ++ ni 0 env r
22852292 ni 0 env (PTyped l r) = ni 0 env l ++ ni 0 env r
22862293 ni 0 env (PPair _ _ _ l r) = ni 0 env l ++ ni 0 env r
22872294 ni 0 env (PDPair _ _ _ (PRef _ _ n) Placeholder r) = n : ni 0 env r
22882295 ni 0 env (PDPair _ _ _ (PRef _ _ n) t r) = ni 0 env t ++ ni 0 (n:env) r
22892296 ni 0 env (PDPair _ _ _ l t r) = ni 0 env l ++ ni 0 env t ++ ni 0 env r
2297+ ni 0 env (PAs _ _ tm) = ni 0 env tm
2298+ -- Just take the first, when disambiguating, since the shape will be
2299+ -- the same and we'll get the name root
2300+ ni 0 env (PAlternative ns (ExactlyOne _) (a : as))
2301+ = map snd ns ++ ni 0 env a
22902302 ni 0 env (PAlternative ns a ls) = map snd ns ++ concatMap (ni 0 env) ls
22912303 ni 0 env (PUnifyLog tm) = ni 0 env tm
22922304 ni 0 env (PDisamb _ tm) = ni 0 env tm
22932305 ni 0 env (PNoImplicits tm) = ni 0 env tm
2306+ ni 0 env (PCoerced tm) = ni 0 env tm
2307+ ni 0 env (PRunElab _ tm _) = ni 0 env tm
2308+ ni 0 env (PConstSugar _ tm) = ni 0 env tm
2309+ ni 0 env tm@(PDoBlock _) = concatMap (ni 0 env) (children tm)
2310+ ni 0 env tm@(PProof _) = concatMap (ni 0 env) (children tm)
2311+ ni 0 env tm@(PTactics _) = concatMap (ni 0 env) (children tm)
22942312
22952313 ni i env (PQuasiquote tm ty) = ni (i+1) env tm ++ maybe [] (ni i env) ty
22962314 ni i env (PUnquote tm) = ni (i - 1) env tm
2315+ ni 0 env tm = []
22972316 ni i env tm = concatMap (ni i env) (children tm)
22982317
22992318 niTacImp i env (TacImp _ _ scr _) = ni i env scr
src/Idris/Chaser.hs+59−24
@@ -22,6 +22,8 @@ import Idris.Unlit
2222
2323import Control.Monad.State
2424import Data.List
25+import qualified Data.Map as M
26+import qualified Data.Set as S
2527import Data.Time.Clock
2628import System.Directory
2729import Util.System (readSource)
@@ -36,8 +38,7 @@ latest :: UTCTime -> [IFileType] -> [ModuleTree] -> UTCTime
3638latest tm done [] = tm
3739latest tm done (m : ms)
3840 | mod_path m `elem` done = latest tm done ms
39− | otherwise = latest (max tm (mod_time m)) (mod_path m : done)
40− (ms ++ mod_deps m)
41+ | otherwise = latest (max tm (mod_time m)) (mod_path m : done) ms
4142
4243modName :: IFileType -> String
4344modName (IDR fp) = fp
@@ -48,23 +49,52 @@ modName (IBC fp src) = modName src
4849-- any module has a descendent which needs reloading, return its
4950-- source, otherwise return the IBC
5051getModuleFiles :: [ModuleTree] -> [IFileType]
51−getModuleFiles ts = nub $ execState (modList ts) [] where
52− modList :: [ModuleTree] -> State [IFileType] ()
53− modList [] = return ()
54− modList (m : ms) = do modTree [] m; modList ms
55−
56− modTree path (MTree p rechk tm deps)
52+getModuleFiles ts
53+ = let (files, (rebuild, _)) = runState (modList ts) (S.empty, M.empty) in
54+ updateToSrc rebuild (reverse files)
55+ where
56+ -- Get the order of building modules. As we go we'll find things that
57+ -- need rebuilding, which we keep track of in the Set.
58+ -- The order of the list matters - things which get built first appear
59+ -- in the list first. We'll remove any repetition later.
60+ modList :: [ModuleTree] ->
61+ State (S.Set IFileType,
62+ M.Map IFileType (Bool, [IFileType])) [IFileType]
63+ modList [] = return []
64+ modList (m : ms) = do (_, fs) <- modTree S.empty m
65+ fs' <- modList ms
66+ pure (fs ++ fs')
67+
68+ modTree path m@(MTree p rechk tm deps)
5769 = do let file = chkReload rechk p
58− -- Needs rechecking if 'rechk' is true, or if any of the
59− -- modification times in 'deps' are later than tm
60− let depMod = latest tm [] deps
61− let needsRechk = rechk || depMod > tm
62−
63− st <- get
64− if needsRechk then put $ nub (getSrc file : updateToSrc path st)
65− else put $ nub (file : st)
66− st <- get
67− mapM_ (modTree (getSrc p : path)) deps
70+ (rebuild, res) <- get
71+ case M.lookup file res of
72+ Just ms -> pure ms
73+ Nothing -> do
74+ toBuildsAll <- mapM (modTree (S.insert (getSrc p) path)) deps
75+ let (rechkDep_in, toBuilds) = unzip toBuildsAll
76+ let rechkDep = or rechkDep_in
77+
78+ (rebuild, res) <- get
79+
80+ -- Needs rechecking if 'rechk' is true, or if any of the
81+ -- modification times in 'deps' are later than tm, or
82+ -- if any dependency needed rechecking
83+ let depMod = latest tm [] deps
84+ let needsRechk = rechkDep || rechk || depMod > tm
85+
86+ -- Remove duplicates, but keep the last...
87+ let rnub = reverse . nub . reverse
88+
89+ let ret = if needsRechk
90+ then (needsRechk, rnub (getSrc file : concat toBuilds))
91+ else (needsRechk, rnub (file : concat toBuilds))
92+
93+ -- Cache the result
94+ put (if needsRechk
95+ then S.union path rebuild
96+ else rebuild, M.insert file ret res)
97+ pure ret
6898
6999 chkReload False p = p
70100 chkReload True (IBC fn src) = chkReload True src
@@ -73,10 +103,11 @@ getModuleFiles ts = nub $ execState (modList ts) [] where
73103 getSrc (IBC fn src) = getSrc src
74104 getSrc f = f
75105
76− updateToSrc path [] = []
77− updateToSrc path (x : xs) = if getSrc x `elem` path
78− then getSrc x : updateToSrc path xs
79− else x : updateToSrc path xs
106+ updateToSrc rebuilds [] = []
107+ updateToSrc rebuilds (x : xs)
108+ = if getSrc x `S.member` rebuilds
109+ then getSrc x : updateToSrc rebuilds xs
110+ else x : updateToSrc rebuilds xs
80111
81112-- | Strip quotes and the backslash escapes that Haskeline adds
82113extractFileName :: String -> String
@@ -173,8 +204,12 @@ buildTree built importlists fp = evalStateT (btree [] fp) []
173204 do [MTree _ _ _ ms'] <- mkChildren file src
174205 return ms'
175206 else return []
176− mt <- lift $ idrisCatch (runIO $ getModificationTime fn)
177− (\c -> runIO $ getIModTime src)
207+ -- Modification time is the later of the source/ibc modification time
208+ smt <- lift $ idrisCatch (runIO $ getIModTime src)
209+ (\c -> runIO $ getModificationTime fn)
210+ mt <- lift $ idrisCatch (do t <- runIO $ getModificationTime fn
211+ return (max smt t))
212+ (\c -> return smt)
178213 -- FIXME: It's also not up to date if anything it imports has
179214 -- been modified since its own ibc has.
180215 --
src/Idris/Core/ProofState.hs+5−1
@@ -10,7 +10,7 @@ proofs, and some high level commands for introducing new theorems,
1010evaluation/checking inside the proof system, etc.
1111-}
1212
13−{-# LANGUAGE FlexibleContexts, FlexibleInstances, MultiParamTypeClasses,
13+{-# LANGUAGE CPP, FlexibleContexts, FlexibleInstances, MultiParamTypeClasses,
1414 PatternGuards #-}
1515module Idris.Core.ProofState(
1616 ProofState(..), newProof, envAtFocus, goalAtFocus
@@ -32,6 +32,10 @@ import Control.Arrow ((***))
3232import Control.Monad.State.Strict
3333import Data.List
3434
35+#if (MIN_VERSION_base(4,11,0))
36+import Prelude hiding ((<>))
37+#endif
38+
3539data ProofState = PS { thname :: Name,
3640 holes :: [Name], -- ^ holes still to be solved
3741 usedns :: [Name], -- ^ used names, don't use again
src/Idris/Core/TT.hs+16−7
@@ -22,10 +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, DeriveFoldable, DeriveFunctor, DeriveGeneric,
26− DeriveTraversable, FlexibleContexts, FlexibleInstances,
27− FunctionalDependencies, MultiParamTypeClasses, PatternGuards,
28− TypeSynonymInstances #-}
25+{-# LANGUAGE CPP, DeriveDataTypeable, DeriveFoldable, DeriveFunctor,
26+ DeriveGeneric, DeriveTraversable, FlexibleContexts,
27+ FlexibleInstances, FunctionalDependencies, MultiParamTypeClasses,
28+ PatternGuards, TypeSynonymInstances #-}
2929{-# OPTIONS_GHC -fwarn-incomplete-patterns #-}
3030module Idris.Core.TT(
3131 AppStatus(..), ArithTy(..), Binder(..), Const(..), Ctxt(..)
@@ -63,6 +63,10 @@ import Prelude (Bool(..), Double, Enum(..), Eq(..), FilePath, Functor(..), Int,
6363 Ordering(..), Show(..), String, div, error, fst, max, min, mod,
6464 not, otherwise, read, snd, ($), (&&), (.), (||))
6565
66+#if (MIN_VERSION_base(4,11,0))
67+import qualified Prelude as S (Semigroup(..))
68+#endif
69+
6670import Control.Applicative (Alternative, Applicative(..))
6771import qualified Control.Applicative as A (Alternative(..))
6872import Control.DeepSeq (($!!))
@@ -117,6 +121,11 @@ fc_end (FC _ _ end) = end
117121fc_end NoFC = (0, 0)
118122fc_end (FileFC f) = (0, 0)
119123
124+#if (MIN_VERSION_base(4,11,0))
125+instance S.Semigroup FC where
126+ (<>) = mappend
127+#endif
128+
120129instance Monoid FC where
121130 mempty = NoFC
122131
@@ -188,10 +197,10 @@ instance Show FC where
188197 show (FileFC f) = f
189198
190199-- | Output annotation for pretty-printed name - decides colour
191−data NameOutput = TypeOutput | FunOutput | DataOutput | MetavarOutput | PostulateOutput deriving (Show, Eq, Generic)
200+data NameOutput = TypeOutput | FunOutput | DataOutput | MetavarOutput | PostulateOutput deriving (Show, Eq, Ord, Generic)
192201
193202-- | Text formatting output
194−data TextFormatting = BoldText | ItalicText | UnderlineText deriving (Show, Eq, Generic)
203+data TextFormatting = BoldText | ItalicText | UnderlineText deriving (Show, Eq, Ord, Generic)
195204
196205-- | Output annotations for pretty-printing
197206data OutputAnnotation = AnnName Name (Maybe NameOutput) (Maybe String) (Maybe String)
@@ -218,7 +227,7 @@ data OutputAnnotation = AnnName Name (Maybe NameOutput) (Maybe String) (Maybe St
218227 | AnnQuasiquote
219228 | AnnAntiquote
220229 | AnnSyntax String -- ^ type of syntax element: backslash or braces etc.
221− deriving (Show, Eq, Generic)
230+ deriving (Show, Eq, Generic, Ord)
222231
223232-- | Used for error reflection
224233data ErrorReportPart = TextPart String
src/Idris/Delaborate.hs+5−1
@@ -5,7 +5,7 @@ Description : Convert core TT back into high level syntax, primarily for display
55License : BSD3
66Maintainer : The Idris Community.
77-}
8−{-# LANGUAGE PatternGuards #-}
8+{-# LANGUAGE CPP, PatternGuards #-}
99{-# OPTIONS_GHC -fwarn-incomplete-patterns #-}
1010module Idris.Delaborate (
1111 annName, bugaddr, delab, delabWithEnv, delabDirect, delab', delabMV, delabSugared
@@ -21,7 +21,11 @@ import Idris.ErrReverse
2121
2222import Util.Pretty
2323
24+#if (MIN_VERSION_base(4,11,0))
25+import Prelude hiding ((<$>), (<>))
26+#else
2427import Prelude hiding ((<$>))
28+#endif
2529
2630import Control.Applicative (Alternative((<|>)))
2731import Control.Monad.State
src/Idris/Directives.hs+7−5
@@ -13,6 +13,8 @@ import Idris.Core.TT
1313import Idris.Imports
1414import Idris.Output (sendHighlighting)
1515
16+import qualified Data.Set as S
17+
1618import Util.DynamicLinker
1719
1820-- | Run the action corresponding to a directive
@@ -81,7 +83,7 @@ directiveAction (DNameHint ty tyFC ns) = do
8183 ty' <- disambiguate ty
8284 mapM_ (addNameHint ty' . fst) ns
8385 mapM_ (\n -> addIBC (IBCNameHint (ty', fst n))) ns
84− sendHighlighting $ [(tyFC, AnnName ty' Nothing Nothing Nothing)] ++ map (\(n, fc) -> (fc, AnnBoundName n False)) ns
86+ sendHighlighting $ S.fromList $ [(FC' tyFC, AnnName ty' Nothing Nothing Nothing)] ++ map (\(n, fc) -> (FC' fc, AnnBoundName n False)) ns
8587
8688directiveAction (DErrorHandlers fn nfc arg afc ns) = do
8789 fn' <- disambiguate fn
@@ -90,10 +92,10 @@ directiveAction (DErrorHandlers fn nfc arg afc ns) = do
9092 return (n', fc)) ns
9193 addFunctionErrorHandlers fn' arg (map fst ns')
9294 mapM_ (addIBC . IBCFunctionErrorHandler fn' arg . fst) ns'
93− sendHighlighting $
94− [ (nfc, AnnName fn' Nothing Nothing Nothing)
95− , (afc, AnnBoundName arg False)
96− ] ++ map (\(n, fc) -> (fc, AnnName n Nothing Nothing Nothing)) ns'
95+ sendHighlighting $ S.fromList $
96+ [ (FC' nfc, AnnName fn' Nothing Nothing Nothing)
97+ , (FC' afc, AnnBoundName arg False)
98+ ] ++ map (\(n, fc) -> (FC' fc, AnnName n Nothing Nothing Nothing)) ns'
9799
98100directiveAction (DLanguage ext) = addLangExt ext
99101
src/Idris/Docs.hs+5−1
@@ -6,7 +6,7 @@ License : BSD3
66Maintainer : The Idris Community.
77-}
88
9−{-# LANGUAGE DeriveFunctor, MultiWayIf, PatternGuards #-}
9+{-# LANGUAGE CPP, DeriveFunctor, MultiWayIf, PatternGuards #-}
1010{-# OPTIONS_GHC -fwarn-incomplete-patterns #-}
1111
1212module Idris.Docs (
@@ -30,7 +30,11 @@ import Idris.Options (HowMuchDocs(..))
3030
3131import Util.Pretty
3232
33+#if (MIN_VERSION_base(4,11,0))
34+import Prelude hiding ((<$>), (<>))
35+#else
3336import Prelude hiding ((<$>))
37+#endif
3438
3539import Data.List
3640import Data.Maybe
src/Idris/Docstrings.hs+6−3
@@ -6,8 +6,8 @@ License : BSD3
66Maintainer : The Idris Community.
77-}
88
9−{-# LANGUAGE DeriveFoldable, DeriveFunctor, DeriveGeneric, DeriveTraversable,
10− ScopedTypeVariables #-}
9+{-# LANGUAGE CPP, DeriveFoldable, DeriveFunctor, DeriveGeneric,
10+ DeriveTraversable, ScopedTypeVariables #-}
1111{-# OPTIONS_GHC -fwarn-incomplete-patterns #-}
1212module Idris.Docstrings (
1313 Docstring(..), Block(..), Inline(..), parseDocstring, renderDocstring
@@ -19,8 +19,11 @@ import Idris.Core.TT (Err, Name, OutputAnnotation(..), Term, TextFormatting(..))
1919
2020import Util.Pretty
2121
22+#if (MIN_VERSION_base(4,11,0))
23+import Prelude hiding ((<$>), (<>))
24+#else
2225import Prelude hiding ((<$>))
23−
26+#endif
2427import qualified Cheapskate as C
2528import Cheapskate.Html (renderDoc)
2629import qualified Cheapskate.Types as CT
src/Idris/Elab/Clause.hs+2−1
@@ -44,6 +44,7 @@ import qualified Control.Monad.State.Lazy as LState
4444import Control.Monad.State.Strict as State
4545import Data.List
4646import Data.Maybe
47+import qualified Data.Set as S
4748import Data.Word
4849import Debug.Trace
4950import Numeric
@@ -1028,7 +1029,7 @@ elabClause info opts (_, PWith fc fname lhs_in withs wval_in pn_in withblock)
10281029 Just (n, nfc) -> Just (uniqueName n (map fst bargs))
10291030
10301031 -- Highlight explicit proofs
1031− sendHighlighting [(fc, AnnBoundName n False) | (n, fc) <- maybeToList pn_in]
1032+ sendHighlighting $ S.fromList [(FC' fc, AnnBoundName n False) | (n, fc) <- maybeToList pn_in]
10321033
10331034 logElab 10 ("With type " ++ show (getRetTy cwvaltyN) ++
10341035 " depends on " ++ show pdeps ++ " from " ++ show pvars)
src/Idris/Elab/Data.hs+9−4
@@ -5,7 +5,7 @@ Description : Code to elaborate data structures.
55License : BSD3
66Maintainer : The Idris Community.
77-}
8−{-# LANGUAGE PatternGuards #-}
8+{-# LANGUAGE CPP, PatternGuards #-}
99module Idris.Elab.Data(elabData) where
1010
1111import Idris.AbsSyntax
@@ -24,7 +24,11 @@ import Idris.Output (iWarn, sendHighlighting)
2424
2525import Util.Pretty
2626
27+#if (MIN_VERSION_base(4,11,0))
28+import Prelude hiding (id, (.), (<>))
29+#else
2730import Prelude hiding (id, (.))
31+#endif
2832
2933import Control.Category
3034import Control.Monad
@@ -33,6 +37,7 @@ import Data.Char (isLetter, toLower)
3337import Data.List
3438import qualified Data.Map as Map
3539import Data.Maybe
40+import qualified Data.Set as S
3641import qualified Data.Text as T
3742
3843warnLC :: FC -> Name -> Idris ()
@@ -49,7 +54,7 @@ elabData info syn doc argDocs fc opts (PLaterdecl n nfc t_in)
4954
5055 addIBC (IBCDef n)
5156 updateContext (addTyDecl n (TCon 0 0) cty) -- temporary, to check cons
52− sendHighlighting [(nfc, AnnName n Nothing Nothing Nothing)]
57+ sendHighlighting $ S.fromList [(FC' nfc, AnnName n Nothing Nothing Nothing)]
5358
5459elabData info syn doc argDocs fc opts (PDatadecl n nfc t_in dcons)
5560 = do let codata = Codata `elem` opts
@@ -114,9 +119,9 @@ elabData info syn doc argDocs fc opts (PDatadecl n nfc t_in dcons)
114119 when (n /= sUN "=") $
115120 elabRewriteLemma info n cty
116121 -- Emit highlighting info
117− sendHighlighting $ [(nfc, AnnName n Nothing Nothing Nothing)] ++
122+ sendHighlighting $ S.fromList $ [(FC' nfc, AnnName n Nothing Nothing Nothing)] ++
118123 map (\(_, _, n, nfc, _, _, _) ->
119− (nfc, AnnName n Nothing Nothing Nothing))
124+ (FC' nfc, AnnName n Nothing Nothing Nothing))
120125 dcons
121126 where
122127 checkDefinedAs fc n t i
src/Idris/Elab/Interface.hs+6−5
@@ -26,6 +26,7 @@ import Control.Monad
2626import Data.Generics.Uniplate.Data (transform)
2727import Data.List
2828import Data.Maybe
29+import qualified Data.Set as S
2930
3031data MArgTy = IA Name | EA Name | CA deriving Show
3132
@@ -167,11 +168,11 @@ elabInterface info_in syn_in doc what fc constraints tn tnfc ps pDocs fds ds mcn
167168 mapM_ (rec_elabDecl info EAll info) (concatMap (snd.snd) defs)
168169 addIBC (IBCInterface tn)
169170
170− sendHighlighting $
171− [(tnfc, AnnName tn Nothing Nothing Nothing)] ++
172− [(pnfc, AnnBoundName pn False) | (pn, pnfc, _) <- ps] ++
173− [(fdfc, AnnBoundName fc False) | (fc, fdfc) <- fds] ++
174− maybe [] (\(conN, conNFC) -> [(conNFC, AnnName conN Nothing Nothing Nothing)]) mcn
171+ sendHighlighting $ S.fromList $
172+ [(FC' tnfc, AnnName tn Nothing Nothing Nothing)] ++
173+ [(FC' pnfc, AnnBoundName pn False) | (pn, pnfc, _) <- ps] ++
174+ [(FC' fdfc, AnnBoundName fc False) | (fc, fdfc) <- fds] ++
175+ maybe [] (\(conN, conNFC) -> [(FC' conNFC, AnnName conN Nothing Nothing Nothing)]) mcn
175176
176177 where
177178 info = info_in { noCaseLift = tn : noCaseLift info_in }
src/Idris/Elab/Record.hs+5−4
@@ -20,6 +20,7 @@ import Idris.Output (sendHighlighting)
2020import Control.Monad
2121import Data.List
2222import Data.Maybe
23+import qualified Data.Set as S
2324
2425-- | Elaborate a record declaration
2526elabRecord :: ElabInfo
@@ -66,10 +67,10 @@ elabRecord info what doc rsyn fc opts tyn nfc params paramDocs fields cname cdoc
6667 logElab 1 $ "fieldsWIthNameAndDoc " ++ show fieldsWithNameAndDoc
6768 elabRecordFunctions info rsyn fc tyn paramsAndDoc fieldsWithNameAndDoc dconName target
6869
69− sendHighlighting $
70− [(nfc, AnnName tyn Nothing Nothing Nothing)] ++
71− maybe [] (\(_, cnfc) -> [(cnfc, AnnName dconName Nothing Nothing Nothing)]) cname ++
72− [(ffc, AnnBoundName fn False) | (fn, ffc, _, _, _) <- fieldsWithName]
70+ sendHighlighting $ S.fromList $
71+ [(FC' nfc, AnnName tyn Nothing Nothing Nothing)] ++
72+ maybe [] (\(_, cnfc) -> [(FC' cnfc, AnnName dconName Nothing Nothing Nothing)]) cname ++
73+ [(FC' ffc, AnnBoundName fn False) | (fn, ffc, _, _, _) <- fieldsWithName]
7374
7475 where
7576 -- | Generates a type constructor.
src/Idris/Elab/Term.hs+9−1
@@ -56,7 +56,7 @@ data ElabResult = ElabResult {
5656 -- | Meta-info about the new type declarations
5757 , resultTyDecls :: [RDeclInstructions]
5858 -- | Saved highlights from elaboration
59− , resultHighlighting :: [(FC, OutputAnnotation)]
59+ , resultHighlighting :: S.Set (FC', OutputAnnotation)
6060 -- | The new global name counter
6161 , resultName :: Int
6262 }
@@ -2026,6 +2026,14 @@ runElabAction info ist fc env tm ns = do tm' <- eval tm
20262026 first' <- eval first
20272027 alt' <- eval alt
20282028 try' (runTacTm first') (runTacTm alt') True
2029+ | n == tacN "Prim__TryCatch"
2030+ = do ~[_a, first, f] <- tacTmArgs 3 tac args
2031+ first' <- eval first
2032+ f' <- eval f
2033+ tryCatch (runTacTm first') $ \err ->
2034+ do (err', _) <- checkClosed (reflectErr err)
2035+ f' <- eval (App Complete f err')
2036+ runTacTm f'
20292037 | n == tacN "Prim__Fill"
20302038 = do ~[raw] <- tacTmArgs 1 tac args
20312039 raw' <- reifyRaw =<< eval raw
src/Idris/Elab/Type.hs+2−2
@@ -205,7 +205,7 @@ elabType' norm info syn doc argDocs fc opts n nfc ty' = {- let ty' = piBind (par
205205 else ifail $ "The type " ++ show nty' ++ " is invalid for an error handler"
206206 else ifail "Error handlers can only be defined when the ErrorReflection language extension is enabled."
207207 -- Send highlighting information about the name being declared
208− sendHighlighting [(nfc, AnnName n Nothing Nothing Nothing)]
208+ sendHighlighting $ S.fromList [(FC' nfc, AnnName n Nothing Nothing Nothing)]
209209 -- if it's an export list type, make a note of it
210210 case (unApply usety) of
211211 (P _ ut _, _)
@@ -238,7 +238,7 @@ elabPostulate info syn doc fc nfc opts n ty = do
238238 elabType info syn doc [] fc opts n NoFC ty
239239 putIState . (\ist -> ist{ idris_postulates = S.insert n (idris_postulates ist) }) =<< getIState
240240 addIBC (IBCPostulate n)
241− sendHighlighting [(nfc, AnnName n (Just PostulateOutput) Nothing Nothing)]
241+ sendHighlighting $ S.fromList [(FC' nfc, AnnName n (Just PostulateOutput) Nothing Nothing)]
242242
243243 -- remove it from the deferred definitions list
244244 solveDeferred fc n
src/Idris/Elab/Utils.hs+5−1
@@ -5,7 +5,7 @@ Description : Elaborator utilities.
55License : BSD3
66Maintainer : The Idris Community.
77-}
8−{-# LANGUAGE FlexibleContexts, PatternGuards #-}
8+{-# LANGUAGE CPP, FlexibleContexts, PatternGuards #-}
99module Idris.Elab.Utils where
1010
1111import Idris.AbsSyntax
@@ -21,6 +21,10 @@ import Idris.Output
2121
2222import Util.Pretty
2323
24+#if (MIN_VERSION_base(4,11,0))
25+import Prelude hiding ((<>))
26+#endif
27+
2428import Control.Monad
2529import Control.Monad.State
2630import Data.List
src/Idris/Elab/Value.hs+1
@@ -26,6 +26,7 @@ import Prelude hiding (id, (.))
2626
2727import Control.Category
2828import Data.Char (toLower)
29+import qualified Data.Set as S ()
2930import qualified Data.Traversable as Traversable
3031
3132-- | Elaborate a value, returning any new bindings created (this will only
src/Idris/ElabDecls.hs+3−1
@@ -41,8 +41,10 @@ import Control.Category
4141import Control.Monad
4242import Control.Monad.State.Strict as State
4343import Data.Maybe
44+import qualified Data.Set as S
4445import qualified Data.Text as T
4546
47+
4648-- | Top level elaborator info, supporting recursive elaboration
4749recinfo :: FC -> ElabInfo
4850recinfo fc = EInfo [] emptyContext id [] (Just fc) (fc_fname fc) 0 [] id elabDecl'
@@ -260,7 +262,7 @@ elabDecl' what info (POpenInterfaces f ns ds)
260262elabDecl' what info (PNamespace n nfc ps) =
261263 do mapM_ (elabDecl' what ninfo) ps
262264 let ns = reverse (map T.pack newNS)
263− sendHighlighting [(nfc, AnnNamespace ns Nothing)]
265+ sendHighlighting $ S.fromList [(FC' nfc, AnnNamespace ns Nothing)]
264266 where
265267 newNS = n : namespace info
266268 ninfo = info { namespace = newNS }
src/Idris/IdrisDoc.hs+2−2
@@ -403,7 +403,7 @@ createIndex :: S.Set NsName -- ^ Set of namespace names to
403403 -- documentation will be written.
404404 -> IO ()
405405createIndex nss out =
406− do (path, h) <- openTempFile out "index.html"
406+ do (path, h) <- openTempFileWithDefaultPermissions out "index.html"
407407 BS2.hPut h $ renderHtml $ wrapper Nothing $ do
408408 H.h1 "Namespaces"
409409 H.ul ! class_ "names" $ do
@@ -435,7 +435,7 @@ createNsDoc ist ns content out =
435435 -- We cannot do anything without a Doc
436436 content' = concatMap haveDocs (nsContents content)
437437 createDirectoryIfMissing True dir
438− (path, h) <- openTempFile dir file
438+ (path, h) <- openTempFileWithDefaultPermissions dir file
439439 BS2.hPut h $ renderHtml $ wrapper (Just ns) $ do
440440 H.h1 $ toHtml (nsName2Str ns)
441441 case nsDocstring content of
src/Idris/Imports.hs+7−1
@@ -24,7 +24,13 @@ import System.Directory
2424import System.FilePath
2525
2626data IFileType = IDR FilePath | LIDR FilePath | IBC FilePath IFileType
27− deriving (Show, Eq)
27+ deriving (Show, Ord)
28+
29+instance Eq IFileType where
30+ IDR x == IDR y = x == y
31+ LIDR x == LIDR y = x == y
32+ IBC x _ == IBC y _ = x == y
33+ _ == _ = False
2834
2935newtype PkgName = PkgName String
3036
src/Idris/Main.hs+1−2
@@ -112,6 +112,7 @@ idrisMain opts =
112112 putIState (i { default_total = DefaultCheckingTotal })
113113 tty <- runIO isATTY
114114 setColourise $ not quiet && last (tty : opt getColour opts)
115+ runIO $ hSetBuffering stdout LineBuffering
115116
116117
117118
@@ -181,8 +182,6 @@ idrisMain opts =
181182 [] -> ""
182183 (f:_) -> f
183184
184− runIO $ hSetBuffering stdout LineBuffering
185−
186185 ok <- noErrors
187186 when ok $ case output of
188187 [] -> return ()
src/Idris/Output.hs+19−13
@@ -6,7 +6,7 @@ License : BSD3
66Maintainer : The Idris Community.
77-}
88
9−{-# LANGUAGE FlexibleInstances #-}
9+{-# LANGUAGE CPP, FlexibleInstances #-}
1010{-# OPTIONS_GHC -fwarn-incomplete-patterns #-}
1111
1212module Idris.Output (clearHighlights, emitWarning, formatMessage, idemodePutSExp,
@@ -30,12 +30,17 @@ import Util.Pretty
3030import Util.ScreenSize (getScreenWidth)
3131import Util.System (isATTY)
3232
33+#if (MIN_VERSION_base(4,11,0))
34+import Prelude hiding ((<$>), (<>))
35+#else
3336import Prelude hiding ((<$>))
37+#endif
3438
3539import Control.Arrow (first)
3640import Control.Monad.Trans.Except (ExceptT(ExceptT), runExceptT)
3741import Data.List (intersperse, nub)
3842import Data.Maybe (fromJust, fromMaybe, isJust, listToMaybe)
43+import qualified Data.Set as S
3944import System.Console.Haskeline.MonadException (MonadException(controlIO),
4045 RunIO(RunIO))
4146import System.FilePath (replaceExtension)
@@ -73,9 +78,12 @@ formatMessage w = do
7378 maybeSource <- case messageSource w of
7479 Just src -> pure (Just src)
7580 Nothing -> readSource fc
76− let maybeFormattedSource = maybeSource >>= layoutSource fc (idris_highlightedRegions i)
81+ let maybeFormattedSource = maybeSource >>= layoutSource fc (regions (idris_highlightedRegions i))
7782 return $ layoutMessage (layoutFC fc) maybeFormattedSource (messageText w)
7883 where
84+ regions :: S.Set (FC', OutputAnnotation) -> [(FC, OutputAnnotation)]
85+ regions rs = map (\(FC' a,b) -> (a, b)) $ S.toList rs
86+
7987 fc :: FC
8088 fc = messageExtent w
8189
@@ -355,25 +363,23 @@ prettyDocumentedIst ist (name, ty, docs) =
355363sendParserHighlighting :: Idris ()
356364sendParserHighlighting =
357365 do ist <- getIState
358− let hs = map unwrap . nub . map wrap $ idris_parserHighlights ist
366+ let hs = idris_parserHighlights ist
359367 sendHighlighting hs
360368 ist <- getIState
361− putIState ist {idris_parserHighlights = []}
362− where wrap (fc, a) = (FC' fc, a)
363− unwrap (fc', a) = (unwrapFC fc', a)
369+ putIState ist {idris_parserHighlights = S.empty}
364370
365−sendHighlighting :: [(FC, OutputAnnotation)] -> Idris ()
371+sendHighlighting :: S.Set (FC', OutputAnnotation) -> Idris ()
366372sendHighlighting highlights =
367373 do ist <- getIState
368374 case idris_outputmode ist of
369375 RawOutput _ -> updateIState $
370376 \ist -> ist { idris_highlightedRegions =
371− highlights ++ idris_highlightedRegions ist }
377+ S.union highlights (idris_highlightedRegions ist) }
372378 IdeMode n h ->
373379 let fancier = [ toSExp (fc, fancifyAnnots ist False annot)
374− | (fc, annot) <- highlights, fullFC fc
375− ]
376− in case fancier of
380+ | (FC' fc, annot) <- S.toList highlights, fullFC fc
381+ ] in
382+ case fancier of
377383 [] -> return ()
378384 _ -> runIO . hPutStrLn h $
379385 convSExp "output"
@@ -388,7 +394,7 @@ sendHighlighting highlights =
388394writeHighlights :: FilePath -> Idris ()
389395writeHighlights f =
390396 do ist <- getIState
391− let hs = reverse $ idris_highlightedRegions ist
397+ let hs = reverse $ map (\(FC' a, b) -> (a,b)) $ S.toList (idris_highlightedRegions ist)
392398 let hfile = replaceExtension f "idh"
393399 let annots = toSExp [ (fc, fancifyAnnots ist False annot)
394400 | (fc@(FC _ _ _), annot) <- hs
@@ -396,7 +402,7 @@ writeHighlights f =
396402 runIO $ writeFile hfile $ sExpToString annots
397403
398404clearHighlights :: Idris ()
399−clearHighlights = updateIState $ \ist -> ist { idris_highlightedRegions = [] }
405+clearHighlights = updateIState $ \ist -> ist { idris_highlightedRegions = S.empty }
400406
401407renderExternal :: OutputFmt -> Int -> Doc OutputAnnotation -> Idris String
402408renderExternal fmt width doc
src/Idris/Parser.hs+6−5
@@ -53,6 +53,7 @@ import qualified Data.List.Split as Spl
5353import qualified Data.Map as M
5454import Data.Maybe
5555import Data.Ord
56+import qualified Data.Set as S
5657import qualified Data.Text as T
5758import qualified System.Directory as Dir (makeAbsolute)
5859import System.FilePath
@@ -1491,7 +1492,7 @@ parseImports fname input
14911492 Right (x, annots, i) ->
14921493 do putIState i
14931494 fname' <- runIO $ Dir.makeAbsolute fname
1494− sendHighlighting $ addPath annots fname'
1495+ sendHighlighting $ S.fromList $ addPath annots fname'
14951496 return x
14961497 where imports :: IdrisParser ((Maybe (Docstring ()), [String],
14971498 [ImportInfo],
@@ -1512,11 +1513,11 @@ parseImports fname input
15121513 let ps = ps_exp -- imp "Builtins" : imp "Prelude" : ps_exp
15131514 return ((mdoc, mname, ps, mrk'), annots, i)
15141515
1515− addPath :: [(FC, OutputAnnotation)] -> FilePath -> [(FC, OutputAnnotation)]
1516+ addPath :: [(FC, OutputAnnotation)] -> FilePath -> [(FC', OutputAnnotation)]
15161517 addPath [] _ = []
15171518 addPath ((fc, AnnNamespace ns Nothing) : annots) path =
1518− (fc, AnnNamespace ns (Just path)) : addPath annots path
1519− addPath (annot:annots) path = annot : addPath annots path
1519+ (FC' fc, AnnNamespace ns (Just path)) : addPath annots path
1520+ addPath ((fc,annot):annots) path = (FC' fc, annot) : addPath annots path
15201521
15211522 shebang :: IdrisParser ()
15221523 shebang = string "#!" *> many (P.satisfy $ not . isEol) *> eol *> pure ()
@@ -1664,7 +1665,7 @@ loadSource lidr f toline
16641665 srcFnAbs <- case srcFn of
16651666 Just fn -> fmap Just (runIO $ Dir.makeAbsolute fn)
16661667 Nothing -> return Nothing
1667− sendHighlighting [(nfc, AnnNamespace ns srcFnAbs)])
1668+ sendHighlighting $ S.fromList [(FC' nfc, AnnNamespace ns srcFnAbs)])
16681669 [(re, fn, ns, nfc) | ImportInfo re fn _ ns _ nfc <- imports]
16691670 reportParserWarnings
16701671 sendParserHighlighting
src/Idris/Parser/Helpers.hs+2−1
@@ -89,6 +89,7 @@ import Data.List
8989import qualified Data.List.NonEmpty as NonEmpty
9090import qualified Data.Map as M
9191import Data.Maybe
92+import qualified Data.Set as S
9293import qualified Data.Text as T
9394import Text.Megaparsec ((<?>))
9495import qualified Text.Megaparsec as P
@@ -112,7 +113,7 @@ token p = trackExtent p <* whiteSpace
112113highlight :: (MonadState IState m, Parsing m) => OutputAnnotation -> m a -> m a
113114highlight annot p = do
114115 (result, fc) <- withExtent p
115− modify $ \ist -> ist { idris_parserHighlights = (fc, annot) : idris_parserHighlights ist }
116+ modify $ \ist -> ist { idris_parserHighlights = S.insert (FC' fc, annot) (idris_parserHighlights ist) }
116117 return result
117118
118119-- | Parse a reserved identfier, highlighting it as a keyword
src/Idris/Primitives.hs+5−1
@@ -416,9 +416,13 @@ getInt (BI x : xs) = x : getInt xs
416416getInt _ = []
417417
418418strToInt :: IntTy -> [Const] -> Maybe Const
419−strToInt ity [Str x] = case reads x of
419+strToInt ity [Str x] = case reads $ dropFirstPlus x of
420420 [(n,s)] -> Just $ if all isSpace s then toInt ity (n :: Integer) else I 0
421421 _ -> Just $ I 0
422+ where
423+ dropFirstPlus :: String -> String
424+ dropFirstPlus ('+' : str) = str
425+ dropFirstPlus str = str
422426strToInt _ _ = Nothing
423427
424428intToFloat :: [Const] -> Maybe Const
src/Idris/REPL.hs+5−1
@@ -5,7 +5,7 @@ License : BSD3
55Maintainer : The Idris Community.
66-}
77
8−{-# LANGUAGE FlexibleContexts, PatternGuards #-}
8+{-# LANGUAGE CPP, FlexibleContexts, PatternGuards #-}
99-- FIXME: {-# OPTIONS_GHC -fwarn-incomplete-patterns #-}
1010{-# OPTIONS_GHC -fwarn-unused-imports #-}
1111
@@ -82,7 +82,11 @@ import Idris.WhoCalls
8282import IRTS.CodegenCommon
8383import IRTS.Compiler
8484import Network
85+#if (MIN_VERSION_base(4,11,0))
86+import Prelude hiding (id, (.), (<$>), (<>))
87+#else
8588import Prelude hiding (id, (.), (<$>))
89+#endif
8690import System.Console.Haskeline as H
8791import System.Directory
8892import System.Environment
src/Idris/TypeSearch.hs+17−2
@@ -5,7 +5,7 @@ Description : A Hoogle for Idris.
55License : BSD3
66Maintainer : The Idris Community.
77-}
8−{-# LANGUAGE ScopedTypeVariables #-}
8+{-# LANGUAGE CPP, ScopedTypeVariables #-}
99
1010module Idris.TypeSearch (
1111 searchByType
@@ -32,8 +32,12 @@ import Idris.Output (iPrintResult, iRenderError, iRenderOutput, iRenderResult,
3232
3333import Util.Pretty (Doc, annotate, char, text, vsep, (<>))
3434
35+#if (MIN_VERSION_base(4,11,0))
36+import Prelude hiding (Semigroup(..), pred)
37+import qualified Prelude as S (Semigroup(..))
38+#else
3539import Prelude hiding (pred)
36−
40+#endif
3741import Control.Applicative (Applicative(..), (<$>), (<*>), (<|>))
3842import Control.Arrow (first, second, (&&&), (***))
3943import Control.Monad (guard, when)
@@ -238,6 +242,17 @@ instance Ord Score where
238242 compare = comparing defaultScoreFunction
239243
240244
245+#if (MIN_VERSION_base(4,11,0))
246+instance S.Semigroup a => S.Semigroup (Sided a) where
247+ (Sided l1 r1) <> (Sided l2 r2) = Sided (l1 S.<> l2) (r1 S.<> r2)
248+
249+instance S.Semigroup AsymMods where
250+ (<>) = mappend
251+
252+instance S.Semigroup Score where
253+ (<>) = mappend
254+#endif
255+
241256instance Monoid a => Monoid (Sided a) where
242257 mempty = Sided mempty mempty
243258 (Sided l1 r1) `mappend` (Sided l2 r2) = Sided (l1 `mappend` l2) (r1 `mappend` r2)
src/Util/System.hs+4
@@ -10,6 +10,7 @@ module Util.System( tempfile
1010 , withTempdir
1111 , rmFile
1212 , catchIO
13+ , isDarwin
1314 , isWindows
1415 , writeSource
1516 , writeSourceText
@@ -50,6 +51,9 @@ catchIO = CE.catch
5051isWindows :: Bool
5152isWindows = os `elem` ["win32", "mingw32", "cygwin32"]
5253
54+isDarwin :: Bool
55+isDarwin = os == "darwin"
56+
5357-- | Create a temp file with the extensiom ext (in the format ".xxx")
5458tempfile :: String -> IO (FilePath, Handle)
5559tempfile ext = do dir <- getTemporaryDirectory
stack-shell.nix+1−1
@@ -18,5 +18,5 @@ in haskell.lib.buildStackProject {
1818 nativeBuildInputs = native_libs;
1919 buildInputs = libs;
2020 name = "idrisBuildEnv";
21− src = ./.;
21+ src = if lib.inNixShell then null else ./.;
2222}
stack.yaml+1−1
@@ -1,5 +1,5 @@
11#recheck extra-deps next on resolver or cabal file change
2−resolver: lts-10.4
2+resolver: lts-11.14
33
44packages:
55 - location: .
test/base001/Makefile+2−2
@@ -2,10 +2,10 @@
22all: exit1 sys.o
33
44exit1:
5− @gcc -Wall -o exit1 exit1.c
5+ @$(CC) -Wall -o exit1 exit1.c
66
77sys.o:
8− @gcc -Wall -c sys.c
8+ @$(CC) -Wall -c sys.c
99
1010clean:
1111 -@rm exit1 sys.o
test/buffer002/buffer002.idr+2−2
@@ -3,8 +3,8 @@ import Data.Buffer
33main : IO ()
44main = do Just buf <- newBuffer 40
55 printLn (size buf)
6− setInt buf 5 1234567890
7− setInt buf 36 1234567890
6+ setInt buf 5 (-1024567890)
7+ setInt buf 36 1034567890
88 setString buf 20 "Hello world!"
99
1010 printLn !(bufferData buf)
test/buffer002/expected+4−4
@@ -1,9 +1,9 @@
1140
2−[00, 00, 00, 00, 00, D2, 02, 96, 49, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 48, 65, 6C, 6C, 6F, 20, 77, 6F, 72, 6C, 64, 21, 00, 00, 00, 00, D2, 02, 96, 49]
3−1234567890
4−4822530
2+[00, 00, 00, 00, 00, AE, 55, EE, C2, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 48, 65, 6C, 6C, 6F, 20, 77, 6F, 72, 6C, 64, 21, 00, 00, 00, 00, D2, 40, AA, 3D]
3+-1024567890
4+12774997
55123.456
6−1234567890
6+1034567890
770
88Hello worl
99Hello world!
test/meta003/Catch.idrnew file+17
@@ -0,0 +1,17 @@
1+import Language.Reflection.Elab
2+
3+%language ElabReflection
4+
5+f : Err -> Elab ()
6+f (Msg _) = fill `("message error")
7+f (CantUnify _ _ _ _ _ _) = fill `("unification error")
8+f _ = fill `("other")
9+
10+s1 : String
11+s1 = %runElab (do tryCatch (fail []) f ; solve)
12+
13+s2 : String
14+s2 = %runElab (do tryCatch (fill `(True)) f ; solve)
15+
16+main : IO ()
17+main = do putStrLn s1 ; putStrLn s2
test/meta003/expected+2
@@ -8,3 +8,5 @@ Type mismatch between
88and
99 String
1010
11+message error
12+unification error
test/meta003/run+3−1
@@ -1,3 +1,5 @@
11#!/usr/bin/env bash
22${IDRIS:-idris} $@ --nocolour --check --consolewidth 70 BadDef.idr
3−rm -f *.ibc
3+${IDRIS:-idris} $@ --nocolour --consolewidth 70 -o meta003 Catch.idr
4+./meta003
5+rm -f meta003 *.ibc
test/pkg008/expected+1−1
@@ -2,9 +2,9 @@ Entering directory `./src'
22Type checking ./NumOps.idr
33Type checking ./Test.idr
44Leaving directory `./src'
5+Entering directory `./src'
56Test Passed
67Test Passed
7−Entering directory `./src'
88Leaving directory `./src'
99Entering directory `./src'
1010Removed: NumOps.ibc
test/regression001/reg007.idrnew file+69
@@ -0,0 +1,69 @@
1+{-
2+See: http://lpaste.net/104020
3+ and https://github.com/gonzaw/extensible-records
4+-}
5+module Record
6+
7+import Data.List
8+
9+%default total
10+
11+data HList : List Type -> Type where
12+ Nil : HList []
13+ (::) : a -> HList xs -> HList (a :: xs)
14+
15+infix 5 :=
16+
17+data Field : lbl -> Type -> Type where
18+ (:=) : (label : lbl) ->
19+ (value : b) -> Field label b
20+
21+labelsOf : List (lbl, Type) -> List lbl
22+labelsOf [] = []
23+labelsOf ((label, _) :: xs) = label :: labelsOf xs
24+
25+toFields : List (lbl, Type) -> List Type
26+toFields [] = []
27+toFields ((l, t) :: xs) = (Field l t) :: toFields xs
28+
29+data IsSet : List t -> Type where
30+ IsSetNil : IsSet []
31+ IsSetCons : Not (Elem x xs) -> IsSet xs -> IsSet (x :: xs)
32+
33+data Record : List (lty, Type) -> Type where
34+ MkRecord : IsSet (labelsOf ts) -> HList (toFields ts) ->
35+ Record ts
36+
37+infixr 6 +:
38+
39+rnil : Record []
40+rnil = MkRecord IsSetNil []
41+
42+prepend : { label : lbl,
43+ xs : List (lbl, Type),
44+ prf : Not (Elem label (labelsOf xs))
45+ } ->
46+ Field label t ->
47+ Record xs ->
48+ Record ((label, t) :: xs)
49+prepend {prf} f (MkRecord isSet fs) = MkRecord (IsSetCons prf isSet) (f :: fs)
50+
51+data IsNo : Dec prop -> Type where
52+ ItIsNo : IsNo (No yprf)
53+
54+(+:) : DecEq lbl =>
55+ { label : lbl, xs : List (lbl, Type) } ->
56+ Field label t ->
57+ Record xs ->
58+ { auto isno : IsNo (isElem label $ labelsOf xs) } ->
59+ Record ((label, t) :: xs)
60+
61+(+:) {label} {xs} f r with (isElem label $ labelsOf xs)
62+ (+:) { isno = ItIsNo } _ _ | (Yes _) impossible
63+ (+:) f r | (No no) = prepend {prf = no} f r
64+
65+foo : Record [("Year", Integer)]
66+
67+bar : Record [("Title", String), ("Year", Integer)]
68+bar = (+:) ("Title" := "test") foo
69+
test/regression001/run+1−1
@@ -1,7 +1,7 @@
11#!/usr/bin/env bash
22${IDRIS:-idris} $@ --check \
33 reg001.idr reg002.idr reg003.idr reg004.lidr reg005.idr \
4− reg006.idr reg036.idr reg037.idr reg038.idr reg046.idr \
4+ reg006.idr reg007.idr reg036.idr reg037.idr reg038.idr reg046.idr \
55 reg047a.idr reg053.idr reg057.idr reg058.idr reg058a.idr \
66 reg059.idr reg060.idr reg061.idr reg062.idr reg063.idr \
77 reg064.idr reg065.idr reg066.idr reg071.idr reg074.idr \