on master help sign in
Merge branch 'master' into feature/vect-isos
7b38ac2howtonotwin
.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:
9
9
10matrix:
10matrix:
11 include:
11 include:
12− - env: CABALVER="1.24" GHCVER="8.0.1" STACKVER="7.14" STYLISH=YES
12+ - env: CABALVER="2.2" GHCVER="8.4.1" STACKVER="7.14" STYLISH=YES
13− addons: {apt: {packages: [cabal-install-1.24,ghc-8.0.1,hscolour], sources: [hvr-ghc]}}
13+ addons: {apt: {packages: [cabal-install-2.2,ghc-8.4.1,hscolour], sources: [hvr-ghc]}}
14− - env: CABALVER="1.22" GHCVER="7.10.3" TESTS="lib_doc doc"
14+ - env: CABALVER="2.2" GHCVER="7.10.3" TESTS="test_c"
15 compiler: ": #GHC 7.10.3"
15 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]}}
29 - env: CABALVER="1.24" GHCVER="8.0.1" TESTS="test_c"
17 - env: CABALVER="1.24" GHCVER="8.0.1" TESTS="test_c"
30 compiler: ": #GHC 8.0.1"
18 compiler: ": #GHC 8.0.1"
31 addons: {apt: {packages: [cabal-install-1.24,ghc-8.0.1,cppcheck,hscolour], sources: [hvr-ghc]}}
19 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]}}
32 fast-finish: true
40 fast-finish: true
33
41
34cache:
42cache:
CHANGELOG.md+3−1
@@ -1,4 +1,4 @@
1−# New in 1.3.*
1+# New in 1.3.0
2
2
3## Language updates
3## Language updates
4+ Old 'induction' tactics and eliminator generation functionality ('%elim', '%case', 'elim_for') is no longer supported.
4+ Old 'induction' tactics and eliminator generation functionality ('%elim', '%case', 'elim_for') is no longer supported.
@@ -18,6 +18,8 @@
18+ Added a switch `--allow-capitalized-pattern-variables` to optionally allow capitalized pattern variables after they were prohibited in 1.2.0.
18+ Added a switch `--allow-capitalized-pattern-variables` to optionally allow capitalized pattern variables after they were prohibited in 1.2.0.
19+ REPL now prints an error message if program compiled by `:exec` terminates
19+ REPL now prints an error message if program compiled by `:exec` terminates
20 abnormally.
20 abnormally.
21++ Idris now builds with GHC 8.4.
22++ In the C backend, the representation of Idris values at runtime has been reworked.
21
23
22# New in 1.2.0
24# New in 1.2.0
23
25
CONTRIBUTORS+1
@@ -126,6 +126,7 @@ Jonas De Vuyst
126Jonas Westerlund
126Jonas Westerlund
127Jonathan Sterling
127Jonathan Sterling
128Joomy Korkut
128Joomy Korkut
129+Jorge Acereda
129Joseph Huang
130Joseph Huang
130Josh Vera
131Josh Vera
131JP Smith
132JP 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:
81* `stack install`
81* `stack install`
82
82
83Stack will install Idris (and related executables) into `$HOME/.local/bin/`
83Stack 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.
85
88
86Of note: If you haven't used stack before commands will also setup the
89Of note: If you haven't used stack before commands will also setup the
87related infrastructure. For more information about Stack please visit
90related infrastructure. For more information about Stack please visit
Setup.hs+19−9
@@ -14,7 +14,7 @@ import Distribution.Simple.InstallDirs as I
14import Distribution.Simple.LocalBuildInfo as L
14import Distribution.Simple.LocalBuildInfo as L
15import qualified Distribution.Simple.Setup as S
15import qualified Distribution.Simple.Setup as S
16import qualified Distribution.Simple.Program as P
16import qualified Distribution.Simple.Program as P
17−import Distribution.Simple.Utils (createDirectoryIfMissingVerbose, rewriteFile, notice, installOrdinaryFiles)
17+import Distribution.Simple.Utils
18import Distribution.Compiler
18import Distribution.Compiler
19import Distribution.PackageDescription
19import Distribution.PackageDescription
20import Distribution.Text
20import Distribution.Text
@@ -66,28 +66,28 @@ windres verbosity = P.runProgramInvocation verbosity . P.simpleProgramInvocation
66
66
67usesGMP :: S.ConfigFlags -> Bool
67usesGMP :: S.ConfigFlags -> Bool
68usesGMP flags =
68usesGMP flags =
69− case lookup (mkFlagName "gmp") (S.configConfigurationsFlags flags) of
69+ case lookupFlagAssignment (mkFlagName "gmp") (S.configConfigurationsFlags flags) of
70 Just True -> True
70 Just True -> True
71 Just False -> False
71 Just False -> False
72 Nothing -> False
72 Nothing -> False
73
73
74execOnly :: S.ConfigFlags -> Bool
74execOnly :: S.ConfigFlags -> Bool
75execOnly flags =
75execOnly flags =
76− case lookup (mkFlagName "execonly") (S.configConfigurationsFlags flags) of
76+ case lookupFlagAssignment (mkFlagName "execonly") (S.configConfigurationsFlags flags) of
77 Just True -> True
77 Just True -> True
78 Just False -> False
78 Just False -> False
79 Nothing -> False
79 Nothing -> False
80
80
81isRelease :: S.ConfigFlags -> Bool
81isRelease :: S.ConfigFlags -> Bool
82isRelease flags =
82isRelease flags =
83− case lookup (mkFlagName "release") (S.configConfigurationsFlags flags) of
83+ case lookupFlagAssignment (mkFlagName "release") (S.configConfigurationsFlags flags) of
84 Just True -> True
84 Just True -> True
85 Just False -> False
85 Just False -> False
86 Nothing -> False
86 Nothing -> False
87
87
88isFreestanding :: S.ConfigFlags -> Bool
88isFreestanding :: S.ConfigFlags -> Bool
89isFreestanding flags =
89isFreestanding flags =
90− case lookup (mkFlagName "freestanding") (S.configConfigurationsFlags flags) of
90+ case lookupFlagAssignment (mkFlagName "freestanding") (S.configConfigurationsFlags flags) of
91 Just True -> True
91 Just True -> True
92 Just False -> False
92 Just False -> False
93 Nothing -> False
93 Nothing -> False
@@ -97,6 +97,11 @@ mkFlagName :: String -> FlagName
97mkFlagName = FlagName
97mkFlagName = FlagName
98#endif
98#endif
99
99
100+#if !(MIN_VERSION_Cabal(2,2,0))
101+lookupFlagAssignment :: FlagName -> FlagAssignment -> Maybe Bool
102+lookupFlagAssignment = lookup
103+#endif
104+
100-- -----------------------------------------------------------------------------
105-- -----------------------------------------------------------------------------
101-- Clean
106-- Clean
102
107
@@ -123,7 +128,7 @@ generateBuildFlagsModule verbosity dir libdirs = do
123 let buildFlagsModulePath = dir </> "BuildFlags_idris" Px.<.> "hs"
128 let buildFlagsModulePath = dir </> "BuildFlags_idris" Px.<.> "hs"
124 putStrLn $ "Generating " ++ buildFlagsModulePath
129 putStrLn $ "Generating " ++ buildFlagsModulePath
125 createDirectoryIfMissingVerbose verbosity True dir
130 createDirectoryIfMissingVerbose verbosity True dir
126− rewriteFile buildFlagsModulePath contents
131+ rewriteFileEx verbosity buildFlagsModulePath contents
127 where contents = "module BuildFlags_idris where \n\n" ++
132 where contents = "module BuildFlags_idris where \n\n" ++
128 "extraLibDirs :: [String]\n" ++
133 "extraLibDirs :: [String]\n" ++
129 "extraLibDirs = " ++ show libdirs
134 "extraLibDirs = " ++ show libdirs
@@ -136,7 +141,7 @@ generateVersionModule verbosity dir release = do
136 putStrLn $ "Generating " ++ versionModulePath ++
141 putStrLn $ "Generating " ++ versionModulePath ++
137 if release then " for release" else " for prerelease " ++ hash
142 if release then " for release" else " for prerelease " ++ hash
138 createDirectoryIfMissingVerbose verbosity True dir
143 createDirectoryIfMissingVerbose verbosity True dir
139− rewriteFile versionModulePath (versionModuleContents hash)
144+ rewriteFileEx verbosity versionModulePath (versionModuleContents hash)
140
145
141 where versionModuleContents h = "module Version_idris where\n\n" ++
146 where versionModuleContents h = "module Version_idris where\n\n" ++
142 "gitHash :: String\n" ++
147 "gitHash :: String\n" ++
@@ -150,7 +155,7 @@ generateTargetModule verbosity dir targetDir = do
150 let targetModulePath = dir </> "Target_idris" Px.<.> "hs"
155 let targetModulePath = dir </> "Target_idris" Px.<.> "hs"
151 putStrLn $ "Generating " ++ targetModulePath
156 putStrLn $ "Generating " ++ targetModulePath
152 createDirectoryIfMissingVerbose verbosity True dir
157 createDirectoryIfMissingVerbose verbosity True dir
153− rewriteFile targetModulePath (versionModuleContents absPath targetDir)
158+ rewriteFileEx verbosity targetModulePath (versionModuleContents absPath targetDir)
154 where versionModuleContents absolute td = "module Target_idris where\n\n" ++
159 where versionModuleContents absolute td = "module Target_idris where\n\n" ++
155 "import System.FilePath\n" ++
160 "import System.FilePath\n" ++
156 "import System.Environment\n" ++
161 "import System.Environment\n" ++
@@ -176,7 +181,7 @@ generateToolchainModule verbosity srcDir toolDir = do
176 "getToolchainDir = \"\""
181 "getToolchainDir = \"\""
177 let toolPath = srcDir </> "Tools_idris" Px.<.> "hs"
182 let toolPath = srcDir </> "Tools_idris" Px.<.> "hs"
178 createDirectoryIfMissingVerbose verbosity True srcDir
183 createDirectoryIfMissingVerbose verbosity True srcDir
179− rewriteFile toolPath (commonContent ++ toolContent)
184+ rewriteFileEx verbosity toolPath (commonContent ++ toolContent)
180
185
181idrisConfigure _ flags pkgdesc local = do
186idrisConfigure _ flags pkgdesc local = do
182 configureRTS
187 configureRTS
@@ -240,6 +245,11 @@ idrisPostSDist args flags desc lbi = do
240 (\e -> let e' = (e :: SomeException) in return ())
245 (\e -> let e' = (e :: SomeException) in return ())
241 postSDist simpleUserHooks args flags desc lbi
246 postSDist simpleUserHooks args flags desc lbi
242
247
248+#if !(MIN_VERSION_Cabal(2,0,0))
249+rewriteFileEx :: Verbosity -> FilePath -> String -> IO ()
250+rewriteFileEx _ = rewriteFile
251+#endif
252+
243-- -----------------------------------------------------------------------------
253-- -----------------------------------------------------------------------------
244-- Build
254-- Build
245
255
benchmarks/build.pl+3−2
@@ -2,13 +2,14 @@
2
2
3$bmarks = `cat ALL`;
3$bmarks = `cat ALL`;
4@bm = split(/\n/, $bmarks);
4@bm = split(/\n/, $bmarks);
5+$idris = $ENV{'IDRIS'} || "idris";
5
6
6foreach $b (@bm) {
7foreach $b (@bm) {
7 if ($b =~ /([a-zA-Z0-9]+)\/([a-zA-Z0-9]+)\s+(.*)/) {
8 if ($b =~ /([a-zA-Z0-9]+)\/([a-zA-Z0-9]+)\s+(.*)/) {
8 print "Building $1 / $2\n";
9 print "Building $1 / $2\n";
9 chdir $1;
10 chdir $1;
10− system("idris --clean $2.ipkg");
11+ system("$idris --clean $2.ipkg");
11− system("idris --build $2.ipkg") == 0 or die "Unable to build $2: $?";
12+ system("$idris --build $2.ipkg") == 0 or die "Unable to build $2: $?";
12 chdir "..";
13 chdir "..";
13 }
14 }
14}
15}
config.mk+1−1
@@ -14,7 +14,7 @@ RANLIB ?=ranlib
14CABAL :=cabal
14CABAL :=cabal
15# IDRIS_ENABLE_STATS should not be set in final release
15# IDRIS_ENABLE_STATS should not be set in final release
16# Any flags defined here which alter the RTS API must also be added to src/IRTS/CodegenC.hs
16# 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)
18
18
19# CABALFLAGS :=
19# CABALFLAGS :=
20CABALFLAGS += --enable-tests
20CABALFLAGS += --enable-tests
docs/conf.py+2−2
@@ -59,9 +59,9 @@ author = u'The Idris Community'
59# built documents.
59# built documents.
60#
60#
61# The short X.Y version.
61# The short X.Y version.
62−version = '1.2'
62+version = '1.3'
63# The full version, including alpha/beta/rc tags.
63# The full version, including alpha/beta/rc tags.
64−release = '1.2.0'
64+release = '1.3.0'
65
65
66# The language for content autogenerated by Sphinx. Refer to documentation
66# The language for content autogenerated by Sphinx. Refer to documentation
67# for a list of supported languages.
67# 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
33limited to) extra library support, polishing the run-time system (and ensuring
33limited to) extra library support, polishing the run-time system (and ensuring
34it is robust), providing and maintaining a JVM back end, etc.
34it is robust), providing and maintaining a JVM back end, etc.
35
35
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+
36
60
37Why does Idris use eager evaluation rather than lazy?
61Why does Idris use eager evaluation rather than lazy?
38=====================================================
62=====================================================
@@ -173,8 +197,10 @@ function back to itself. On such a path, there must be at least one
173argument which converges to a base case.
197argument which converges to a base case.
174
198
175- Mutually recursive functions are supported
199- Mutually recursive functions are supported
200+
176- However, all functions on the path must be fully applied. In particular,
201- However, all functions on the path must be fully applied. In particular,
177 higher order applications are not supported
202 higher order applications are not supported
203+
178- Idris identifies arguments which converge to a base case by looking for
204- Idris identifies arguments which converge to a base case by looking for
179 recursive calls to syntactically smaller arguments of inputs. e.g.
205 recursive calls to syntactically smaller arguments of inputs. e.g.
180 ``k`` is syntactically smaller than ``S (S k)`` because ``k`` is a
206 ``k`` is syntactically smaller than ``S (S k)`` because ``k`` is a
@@ -189,10 +215,10 @@ function.
189When will Idris be self-hosting?
215When will Idris be self-hosting?
190================================
216================================
191
217
192−It’s not a priority, though not a bad idea in the long run. It would be a
218+It’s not a priority, though not a bad idea in the long run. It would
193−worthwhile effort in the short term to implement libraries to support
219+be a worthwhile effort in the short term to implement libraries in
194−self-hosting, such as a good parsing library.
220+Idris to support self-hosting, such as argument parsing and a
195−
221+POSIX-compliant library for system interaction.
196
222
197Does Idris have universe polymorphism? What is the type of ``Type``?
223Does Idris have universe polymorphism? What is the type of ``Type``?
198====================================================================
224====================================================================
@@ -233,14 +259,17 @@ where the install directory is unknown at build time. When passing this
233flag, the IDRIS_LIB_DIR environment variable needs to be set to the path
259flag, the IDRIS_LIB_DIR environment variable needs to be set to the path
234where the Idris libs reside relative to the idris executable. The
260where the Idris libs reside relative to the idris executable. The
235IDRIS_TOOLCHAIN_DIR environment variable is optional, if that is set,
261IDRIS_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:
237
263
238−Example::
264+::
239
265
266+ IDRIS_LIB_DIR="./libs" \
267+ IDRIS_TOOLCHAIN_DIR="./mingw/bin" \
240− IDRIS_LIB_DIR="./libs" IDRIS_TOOLCHAIN_DIR="./mingw/bin" CABALFLAGS="-fffi -ffreestanding -frelease" make
268+ CABALFLAGS="-fffi -ffreestanding -frelease" \
269+ make
241
270
242
271
243−What does the name ‘Idris’ mean?
272+What does the name “Idris” mean?
244================================
273================================
245
274
246British people of a certain age may be familiar with this
275British 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:
256- It's hard to type (this is important if you're using someone else's code, for
285- It's hard to type (this is important if you're using someone else's code, for
257 example). Various editors have their own input methods, but you have to know
286 example). Various editors have their own input methods, but you have to know
258 what they are.
287 what they are.
288+
259- Not every piece of software easily supports it. Rendering issues have been
289- Not every piece of software easily supports it. Rendering issues have been
260 noted on some mobile email clients, terminal-based IRC clients, web browsers,
290 noted on some mobile email clients, terminal-based IRC clients, web browsers,
261 etc. There are ways to resolve these rendering issues but they provide a
291 etc. There are ways to resolve these rendering issues but they provide a
262 barrier to entry to using Idris.
292 barrier to entry to using Idris.
293+
263- Even if we leave it out of the standard library (which we will in any case!)
294- Even if we leave it out of the standard library (which we will in any case!)
264 as soon as people start using it in their library code, others have to deal
295 as soon as people start using it in their library code, others have to deal
265 with it.
296 with it.
297+
266- Too many characters look too similar. We had enough trouble with confusion
298- Too many characters look too similar. We had enough trouble with confusion
267 between 0 and O without worrying about all the different kinds of colons and
299 between 0 and O without worrying about all the different kinds of colons and
268 brackets.
300 brackets.
301+
269- There seems to be a tendency to go over the top with use of Unicode. For
302- There seems to be a tendency to go over the top with use of Unicode. For
270 example, using sharp and flat for delay and force (or is it the other way
303 example, using sharp and flat for delay and force (or is it the other way
271 around?) in Agda seems gratuitous. We don't want to encourage this sort of
304 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
280Law <http://www.haskell.org/haskellwiki/Wadler%27s_Law>`__ in action.
313Law <http://www.haskell.org/haskellwiki/Wadler%27s_Law>`__ in action.
281
314
282This answer is based on Edwin Brady's response in the following
315This 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>`_.
284
317
285Where can I find the community standards for the Idris community?
318Where can I find the community standards for the Idris community?
286==================================================================
319==================================================================
docs/guides/type-providers-ffi.rst+1−1
@@ -3,7 +3,7 @@ Type Providers in Idris
3***********************
3***********************
4
4
5`Type providers in Idris
5`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>`__
7are simple enough, but there are a few caveats to using them that it
7are simple enough, but there are a few caveats to using them that it
8would be worthwhile to go through the basic steps. We also go over
8would be worthwhile to go through the basic steps. We also go over
9foreign functions, because these will often be used with type
9foreign functions, because these will often be used with type
docs/listing/idris-prompt-helloworld.txt+1−1
@@ -1,7 +1,7 @@
1$ idris hello.idr
1$ idris hello.idr
2 ____ __ _
2 ____ __ _
3 / _/___/ /____(_)____
3 / _/___/ /____(_)____
4− / // __ / ___/ / ___/ Version 1.2.0
4+ / // __ / ___/ / ___/ Version 1.3.0
5 _/ // /_/ / / / (__ ) http://www.idris-lang.org/
5 _/ // /_/ / / / (__ ) http://www.idris-lang.org/
6 /___/\__,_/_/ /_/____/ Type :? for help
6 /___/\__,_/_/ /_/____/ Type :? for help
7
7
docs/listing/idris-prompt-interp.txt+1−1
@@ -1,7 +1,7 @@
1$ idris interp.idr
1$ idris interp.idr
2 ____ __ _
2 ____ __ _
3 / _/___/ /____(_)____
3 / _/___/ /____(_)____
4− / // __ / ___/ / ___/ Version 1.2.0
4+ / // __ / ___/ / ___/ Version 1.3.0
5 _/ // /_/ / / / (__ ) http://www.idris-lang.org/
5 _/ // /_/ / / / (__ ) http://www.idris-lang.org/
6 /___/\__,_/_/ /_/____/ Type :? for help
6 /___/\__,_/_/ /_/____/ Type :? for help
7
7
docs/listing/idris-prompt-start.txt+1−1
@@ -1,7 +1,7 @@
1$ idris
1$ idris
2 ____ __ _
2 ____ __ _
3 / _/___/ /____(_)____
3 / _/___/ /____(_)____
4− / // __ / ___/ / ___/ Version 1.2.0
4+ / // __ / ___/ / ___/ Version 1.3.0
5 _/ // /_/ / / / (__ ) http://www.idris-lang.org/
5 _/ // /_/ / / / (__ ) http://www.idris-lang.org/
6/___/\__,_/_/ /_/____/ Type :? for help
6/___/\__,_/_/ /_/____/ Type :? for help
7
7
docs/reference/codegen.rst+5
@@ -131,3 +131,8 @@ WS
131---
131---
132
132
133`Available online <https://github.com/edwinb/WS-idr>`__
133`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
6
6
7The Idris elaborator is responsible for converting high-level Idris code into the core language.
7The Idris elaborator is responsible for converting high-level Idris code into the core language.
8It 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.
8It 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>`_.
10
11
11Elaborator reflection makes the elaboration type as well as a selection of its tactics available to Idris code.
12Elaborator reflection makes the elaboration type as well as a selection of its tactics available to Idris code.
12This 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.
13This 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
127
127
128 x0 y0 (two)
128 x0 y0 (two)
129 x1 y1 (two)
129 x1 y1 (two)
130− x2 y1 (two)
130+ x2 y2 (two)
131 z (one)
131 z (one)
132
132
133When recursing over this structure, the values of ``xs`` range over
133When recursing over this structure, the values of ``xs`` range over
docs/reference/ffi.rst+6
@@ -178,6 +178,12 @@ compilation error:
178 example : (Int -> ()) -> IO ()
178 example : (Int -> ()) -> IO ()
179 example f = foreign FFI_C "callbacker" (CFnPtr (Int -> ()) -> IO ()) f
179 example f = foreign FFI_C "callbacker" (CFnPtr (Int -> ()) -> IO ()) f
180
180
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+
181The other big limitation is that it doesn't support IO functions. Use
187The other big limitation is that it doesn't support IO functions. Use
182``unsafePerformIO`` to wrap them (i.e. to make an IO function usable as a callback, change the return type
188``unsafePerformIO`` to wrap them (i.e. to make an IO function usable as a callback, change the return type
183from IOr to r, and change the = do to = unsafePerformIO $ do).
189from IOr to r, and change the = do to = unsafePerformIO $ do).
docs/reference/misc.rst+1−1
@@ -220,7 +220,7 @@ following command::
220 source <(idris --bash-completion-script `which idris`)
220 source <(idris --bash-completion-script `which idris`)
221
221
222
222
223−To enable completion permenatly you must either:
223+To enable completion permanently you must either:
224
224
225* Modify your bash init script with the above command.
225* Modify your bash init script with the above command.
226
226
docs/reference/packages.rst+1−1
@@ -123,7 +123,7 @@ Package files support comments using the standard Idris singleline ``--`` and mu
123Using Package files
123Using Package files
124===================
124===================
125
125
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:
127
127
128+ ``idris --build test.ipkg`` will build all modules in the package
128+ ``idris --build test.ipkg`` will build all modules in the package
129
129
docs/st/composing.rst+16−16
@@ -1,7 +1,7 @@
1.. _composing:
1.. _composing:
2
2
3************************
3************************
4−Composing State Machines
4+Composing State Machines
5************************
5************************
6
6
7In the previous section, we defined a ``DataStore`` interface and used it
7In the previous section, we defined a ``DataStore`` interface and used it
@@ -28,7 +28,7 @@ there was a login failure in a state.
28
28
29Furthermore, we may have *hierarchies* of state machines, in that one
29Furthermore, we may have *hierarchies* of state machines, in that one
30state machine could be implemented by composing several others. For
30state 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
32graphics system, and use this to implement a *higher level* graphics API
32graphics system, and use this to implement a *higher level* graphics API
33such as turtle graphics, which uses the graphics system plus some additional
33such as turtle graphics, which uses the graphics system plus some additional
34state for the turtle.
34state for the turtle.
@@ -50,7 +50,7 @@ count to zero, a session might run as follows:
50 *LoginCount> :exec main
50 *LoginCount> :exec main
51 Enter password: Mornington Crescent
51 Enter password: Mornington Crescent
52 Secret is: "Secret Data"
52 Secret is: "Secret Data"
53− Enter password: Dollis Hill
53+ Enter password: Dollis Hill
54 Failure
54 Failure
55 Number of failures: 1
55 Number of failures: 1
56 Enter password: Mornington Crescent
56 Enter password: Mornington Crescent
@@ -63,7 +63,7 @@ count to zero, a session might run as follows:
63We'll start by adding a state resource to ``getData`` to keep track of the
63We'll start by adding a state resource to ``getData`` to keep track of the
64number of failures:
64number of failures:
65
65
66−.. code-block:: idrs
66+.. code-block:: idris
67
67
68 getData : (ConsoleIO m, DataStore m) =>
68 getData : (ConsoleIO m, DataStore m) =>
69 (failcount : Var) -> ST m () [failcount ::: State Integer]
69 (failcount : Var) -> ST m () [failcount ::: State Integer]
@@ -116,7 +116,7 @@ match:
116 Required result states here are: st2_fn
116 Required result states here are: st2_fn
117
117
118In other words, ``connect`` requires that there are *no* resources on
118In 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!
120This shouldn't be a problem, though: the required resources are a *subset* of
120This shouldn't be a problem, though: the required resources are a *subset* of
121the resources we have, after all, and the additional resources (here, the
121the resources we have, after all, and the additional resources (here, the
122failure count) are not relevant to ``connect``. What we need, therefore,
122failure count) are not relevant to ``connect``. What we need, therefore,
@@ -214,7 +214,7 @@ ordering of resources is allowed to change, although resources which
214appear in ``old`` can't appear in the ``sub`` list more than once (you will
214appear in ``old`` can't appear in the ``sub`` list more than once (you will
215get a type error if you try this).
215get a type error if you try this).
216
216
217−The function ``updateWith`` takes the *output* resources of the
217+The function ``updateWith`` takes the *output* resources of the
218called function, and updates them in the current resource list. It makes
218called function, and updates them in the current resource list. It makes
219an effort to preserve ordering as far as possible, although this isn't
219an effort to preserve ordering as far as possible, although this isn't
220always possible if the called function does some complicated resource
220always possible if the called function does some complicated resource
@@ -338,7 +338,7 @@ representing a surface on which we'll draw lines and rectangles:
338
338
339.. code-block:: idris
339.. code-block:: idris
340
340
341− interface Draw (m : Type -> Type) where
341+ interface Draw (m : Type -> Type) where
342 Surface : Type
342 Surface : Type
343
343
344We'll need to be able to create a new ``Surface`` by opening a window:
344We'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``.
369 an operation returns ``Just ty``, there's also ``addIfRight``:
369 an operation returns ``Just ty``, there's also ``addIfRight``:
370
370
371 .. code-block:: idris
371 .. code-block:: idris
372−
372+
373 addIfJust : Type -> Action (Maybe Var)
373 addIfJust : Type -> Action (Maybe Var)
374 addIfRight : Type -> Action (Either a Var)
374 addIfRight : Type -> Action (Either a Var)
375
375
@@ -378,10 +378,10 @@ succeeds (that is, returns a result of the form ``Just val``.
378 of an operation:
378 of an operation:
379
379
380 .. code-block:: idris
380 .. code-block:: idris
381−
381+
382 Add : (ty -> Resources) -> Action ty
382 Add : (ty -> Resources) -> Action ty
383−
383+
384− Using this, you can create your own actions to add resources
384+ Using this, you can create your own actions to add resources
385 based on the result of an operation, if required. For example,
385 based on the result of an operation, if required. For example,
386 ``addIfJust`` is implemented as follows:
386 ``addIfJust`` is implemented as follows:
387
387
@@ -479,7 +479,7 @@ For example, assuming we have a surface ``win`` to draw onto, we can write a
479
479
480The ``flip win`` at the end is necessary because the drawing primitives
480The ``flip win`` at the end is necessary because the drawing primitives
481are double buffered, to prevent flicker. We draw onto one buffer, off-screen,
481are 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
483buffer, and creates a new off-screen buffer for drawing the next frame.
483buffer, and creates a new off-screen buffer for drawing the next frame.
484
484
485To include this in a program, we'll write a main loop which renders our
485To include this in a program, we'll write a main loop which renders our
@@ -496,7 +496,7 @@ application:
496
496
497Finally, we can create a main program which initialises a window, if
497Finally, we can create a main program which initialises a window, if
498possible, then runs the main loop:
498possible, then runs the main loop:
499−
499+
500.. code-block:: idris
500.. code-block:: idris
501
501
502 drawMain : (ConsoleIO m, Draw m) => ST m () []
502 drawMain : (ConsoleIO m, Draw m) => ST m () []
@@ -593,7 +593,7 @@ is implemented using the following type, defined by ``Control.ST``:
593
593
594.. code-block:: idris
594.. code-block:: idris
595
595
596− data Composite : List Type -> Type
596+ data Composite : List Type -> Type
597
597
598If we have a composite resource, we can split it into its constituent
598If we have a composite resource, we can split it into its constituent
599resources, and create new variables for each of those resources, using
599resources, and create new variables for each of those resources, using
@@ -604,7 +604,7 @@ the *split* function. For example:
604 splitComp : (comp : Var) -> ST m () [comp ::: Composite [State Int, State String]]
604 splitComp : (comp : Var) -> ST m () [comp ::: Composite [State Int, State String]]
605 splitComp comp = do [int, str] <- split comp
605 splitComp comp = do [int, str] <- split comp
606 ?whatNow
606 ?whatNow
607−
607+
608The call ``split comp`` extracts the ``State Int`` and ``State String`` from
608The call ``split comp`` extracts the ``State Int`` and ``State String`` from
609the composite resource ``comp``, and stores them in the variables ``int``
609the composite resource ``comp``, and stores them in the variables ``int``
610and ``str`` respectively. If we check the type of ``whatNow``, we'll see
610and ``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:
713 Line : Type
713 Line : Type
714 Line = ((Int, Int), (Int, Int), Col)
714 Line = ((Int, Int), (Int, Int), Col)
715
715
716−To implement ``start``, which creates a new ``Turtle`` (or returns ``Nothing``
716+To implement ``start``, which creates a new ``Turtle`` (or returns ``Nothing``
717if this is impossible), we begin by initialising the drawing surface then
717if this is impossible), we begin by initialising the drawing surface then
718all of the components of the state. Finally, we combine all of these
718all of the components of the state. Finally, we combine all of these
719into a composite resource for the turtle:
719into a composite resource for the turtle:
docs/st/introduction.rst+1−1
@@ -70,7 +70,7 @@ Outline
70=======
70=======
71
71
72This tutorial starts (:ref:`introst`) by describing how to manipulate
72This 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
74functions, and ``ST`` which describes top level state transitions.
74functions, and ``ST`` which describes top level state transitions.
75Next (:ref:`smstypes`) it describes how to represent state machines in
75Next (:ref:`smstypes`) it describes how to represent state machines in
76types, and how to define *interfaces* for describing stateful systems.
76types, 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:
456
456
457.. code-block:: idris
457.. code-block:: idris
458
458
459− prf : InState lbl (State ty) res}
459+ prf : InState lbl (State ty) res
460
460
461This relies on a predicate ``InState``. A value of type ``InState x ty res``
461This relies on a predicate ``InState``. A value of type ``InState x ty res``
462means that the reference ``x`` must have type ``ty`` in the list of
462means 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
23for `Emacs <https://github.com/idris-hackers/idris-mode>`_ is also
23for `Emacs <https://github.com/idris-hackers/idris-mode>`_ is also
24available.
24available.
25
25
26−
27Editing at the REPL
26Editing at the REPL
28===================
27===================
29
28
30The REPL provides a number of commands, which we will describe
29The REPL provides a number of commands, which we will describe
31shortly, which generate new program fragments based on the currently
30shortly, 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:
33
32
34::
33::
35
34
@@ -64,9 +63,9 @@ Editing Commands
64:addclause
63:addclause
65----------
64----------
66
65
67−The ``:addclause n f`` command (abbreviated ``:ac n f``) creates a
66+The ``:addclause n f`` command, abbreviated ``:ac n f``, creates a
68template definition for the function named ``f`` declared on line
67template 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:
70
69
71.. code-block:: idris
70.. code-block:: idris
72
71
@@ -129,7 +128,7 @@ ys`` would lead to a unification error.
129
128
130The ``:addmissing n f`` command, abbreviated ``:am n f``, adds the
129The ``:addmissing n f`` command, abbreviated ``:am n f``, adds the
131clauses which are required to make the function ``f`` on line ``n``
130clauses 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:
133
132
134.. code-block:: idris
133.. code-block:: idris
135
134
@@ -143,7 +142,7 @@ then ``:am 96 vzipWith`` gives:
143
142
144 vzipWith f (x :: xs) (y :: ys) = ?vzipWith_rhs_2
143 vzipWith f (x :: xs) (y :: ys) = ?vzipWith_rhs_2
145
144
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,
147generates the required clauses, and eliminates the clauses which would
146generates the required clauses, and eliminates the clauses which would
148lead to unification errors.
147lead to unification errors.
149
148
docs/tutorial/interfaces.rst+6−7
@@ -11,8 +11,8 @@ data types. For example, we would like arithmetic operators to work on
11to display different types in a uniform way.
11to display different types in a uniform way.
12
12
13To achieve this, we use *interfaces*, which are similar to type classes in
13To 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
14+Haskell or traits in Rust. To define an interface, we provide a collection of
15−overloadable functions. A simple example is the ``Show``
15+overloadable functions. A simple example is the ``Show``
16interface, which is defined in the prelude and provides an interface for
16interface, which is defined in the prelude and provides an interface for
17converting values to ``String``:
17converting values to ``String``:
18
18
@@ -31,8 +31,7 @@ This generates a function of the following type (which we call a
31We can read this as: “under the constraint that ``a`` has an implementation
31We can read this as: “under the constraint that ``a`` has an implementation
32of ``Show``, take an input ``a`` and return a ``String``.” An implementation
32of ``Show``, take an input ``a`` and return a ``String``.” An implementation
33of an interface is defined by giving definitions of the methods of the interface.
33of 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:
36
35
37.. code-block:: idris
36.. code-block:: idris
38
37
@@ -49,7 +48,7 @@ Only one implementation of an interface can be given for a type — implementati
49not overlap. Implementation declarations can themselves have constraints.
48not overlap. Implementation declarations can themselves have constraints.
50To help with resolution, the arguments of an implementation must be
49To help with resolution, the arguments of an implementation must be
51constructors (either data or type constructors) or variables
50constructors (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
53example, to define a ``Show`` implementation for vectors, we need to know
52example, to define a ``Show`` implementation for vectors, we need to know
54that there is a ``Show`` implementation for the element type, because we are
53that there is a ``Show`` implementation for the element type, because we are
55going to use it to convert each element to a ``String``:
54going to use it to convert each element to a ``String``:
@@ -534,7 +533,7 @@ Named Implementations
534
533
535It can be desirable to have multiple implementations of an interface for the
534It can be desirable to have multiple implementations of an interface for the
536same type, for example to provide alternative methods for sorting or printing
535same 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:
538
537
539.. code-block:: idris
538.. code-block:: idris
540
539
@@ -574,7 +573,7 @@ the prelude defines the following ``Semigroup`` interface:
574 interface Semigroup ty where
573 interface Semigroup ty where
575 (<+>) : ty -> ty -> ty
574 (<+>) : ty -> ty -> ty
576
575
577−Then it defines ``Monoid``, which extends ``Semigroup`` with a "neutral"
576+Then it defines ``Monoid``, which extends ``Semigroup`` with a “neutral”
578value:
577value:
579
578
580.. code-block:: idris
579.. code-block:: idris
docs/tutorial/interp.rst+2−2
@@ -106,7 +106,7 @@ the ``Var`` constructor:
106
106
107 Var : HasType i G t -> Expr G t
107 Var : HasType i G t -> Expr G t
108
108
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
110de Bruijn index of 1, represented as ``Pop Stop``, and ``y 0``,
110de Bruijn index of 1, represented as ``Pop Stop``, and ``y 0``,
111represented as ``Stop``. We find these by counting the number of
111represented as ``Stop``. We find these by counting the number of
112lambdas between the definition and the use.
112lambdas between the definition and the use.
@@ -194,7 +194,7 @@ each constructor, we translate it into the corresponding Idris value:
194 interp env (If x t e) = if interp env x then interp env t
194 interp env (If x t e) = if interp env x then interp env t
195 else interp env e
195 else interp env e
196
196
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
198up in the environment:
198up in the environment:
199
199
200.. code-block:: idris
200.. code-block:: idris
docs/tutorial/miscellany.rst+19−19
@@ -8,7 +8,7 @@ In this section we discuss a variety of additional features:
8
8
9+ auto, implicit, and default arguments;
9+ auto, implicit, and default arguments;
10+ literate programming;
10+ literate programming;
11−+ interfacing with external libraries through the foreign function
11++ interfacing with external libraries through the foreign function;
12+ interface;
12+ interface;
13+ type providers;
13+ type providers;
14+ code generation; and
14+ code generation; and
@@ -23,7 +23,7 @@ omitted when they can be inferred by the type checker, e.g.
23.. code-block:: idris
23.. code-block:: idris
24
24
25 index : {a:Type} -> {n:Nat} -> Fin n -> Vect n a -> a
25 index : {a:Type} -> {n:Nat} -> Fin n -> Vect n a -> a
26−
26+
27Auto implicit arguments
27Auto implicit arguments
28------------------------
28------------------------
29
29
@@ -69,17 +69,17 @@ In the case that a proof is not found, it can be provided explicitly as normal:
69.. code-block:: idris
69.. code-block:: idris
70
70
71 head xs {p = ?headProof}
71 head xs {p = ?headProof}
72−
72+
73Default implicit arguments
73Default implicit arguments
74---------------------------
74---------------------------
75
75
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
77want to have an implicit argument with a specific default value. In Idris, we can
77want to have an implicit argument with a specific default value. In Idris, we can
78do this using the ``default`` annotation. While this is primarily intended to assist
78do 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,
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.
80+it might be easier to first consider a simpler case, not involving proofs.
81
81
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
83number as 0), we could write:
83number as 0), we could write:
84
84
85.. code-block:: idris
85.. code-block:: idris
@@ -89,8 +89,8 @@ number as 0), we could write:
89 fibonacci {lag} {lead} (S n) = fibonacci {lag=lead} {lead=lag+lead} n
89 fibonacci {lag} {lead} (S n) = fibonacci {lag=lead} {lead=lag+lead} n
90
90
91After this definition, ``fibonacci 5`` is equivalent to ``fibonacci {lag=0} {lead=1} 5``,
91After 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
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
93+intended use of the ``default`` annotation. It is included here for illustrative purposes
94only. Usually, ``default`` is used to provide things like a custom proof search script.
94only. Usually, ``default`` is used to provide things like a custom proof search script.
95
95
96
96
@@ -329,13 +329,13 @@ are available in an external collection [1]_.
329C Target
329C Target
330========
330========
331
331
332−The default target of Idris is C. Compiling via :
332+The default target of Idris is C. Compiling via:
333
333
334::
334::
335
335
336 $ idris hello.idr -o hello
336 $ idris hello.idr -o hello
337
337
338−is equivalent to :
338+is equivalent to:
339
339
340::
340::
341
341
@@ -344,14 +344,14 @@ is equivalent to :
344When the command above is used, a temporary C source is generated, which
344When the command above is used, a temporary C source is generated, which
345is then compiled into an executable named ``hello``.
345is then compiled into an executable named ``hello``.
346
346
347−In order to view the generated C code, compile via :
347+In order to view the generated C code, compile via:
348
348
349::
349::
350
350
351 $ idris hello.idr -S -o hello.c
351 $ idris hello.idr -S -o hello.c
352
352
353To turn optimisations on, use the ``%flag C`` pragma within the code, as
353To turn optimisations on, use the ``%flag C`` pragma within the code, as
354−is shown below :
354+is shown below:
355
355
356.. code-block:: idris
356.. code-block:: idris
357
357
@@ -368,7 +368,7 @@ is shown below :
368
368
369To compile the generated C with debugging information e.g. to use
369To compile the generated C with debugging information e.g. to use
370``gdb`` to debug segmentation faults in Idris programs, use the
370``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:
372
372
373.. code-block:: idris
373.. code-block:: idris
374
374
@@ -503,13 +503,13 @@ And for use in the browser:
503
503
504The given files will be added to the top of the generated code.
504The given files will be added to the top of the generated code.
505For library packages you can also use the ipkg objs option to include the
505For 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:
507
507
508.. code-block:: idris
508.. code-block:: idris
509
509
510 %include Node "package/external.js"
510 %include Node "package/external.js"
511
511
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
513on that location.
513on that location.
514
514
515Including *NodeJS* modules
515Including *NodeJS* modules
@@ -552,7 +552,7 @@ types themselves have types. For example:
552 *universe> :t Vect
552 *universe> :t Vect
553 Vect : Nat -> Type -> Type
553 Vect : Nat -> Type -> Type
554
554
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:
556
556
557::
557::
558
558
@@ -560,8 +560,8 @@ But what about the type of ``Type``? If we ask Idris it reports
560 Type : Type 1
560 Type : Type 1
561
561
562If ``Type`` were its own type, it would lead to an inconsistency due to
562If ``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
563+`Girard’s paradox <http://www.cs.cmu.edu/afs/cs.cmu.edu/user/kw/www/scans/girard72thesis.pdf>`_,
564−*hierarchy* of types (or *universes*):
564+so internally there is a *hierarchy* of types (or *universes*):
565
565
566.. code-block:: idris
566.. code-block:: idris
567
567
docs/tutorial/modules.rst+8−11
@@ -53,8 +53,7 @@ Then, this gives a main program (in a file
53 print (Btree.toList t)
53 print (Btree.toList t)
54
54
55The same names can be defined in multiple modules: names are *qualified* with
55The 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
56+the name of the module. The names defined in the ``Btree`` module are, in full:
57−full:
58
57
59+ ``Btree.BTree``
58+ ``Btree.BTree``
60+ ``Btree.Leaf``
59+ ``Btree.Leaf``
@@ -74,7 +73,7 @@ directories. For example, ``import foo.bar`` would import the file
74``foo/bar.idr``, which would conventionally have the module declaration
73``foo/bar.idr``, which would conventionally have the module declaration
75``module foo.bar``. The only requirement for module names is that the
74``module foo.bar``. The only requirement for module names is that the
76main module, with the ``main`` function, must be called
75main 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``.
78
77
79Export Modifiers
78Export Modifiers
80================
79================
@@ -82,18 +81,16 @@ Export Modifiers
82Idris allows for fine-grained control over the visibility of a
81Idris allows for fine-grained control over the visibility of a
83module's contents. By default, all names defined in a module are kept
82module's contents. By default, all names defined in a module are kept
84private. This aides in specification of a minimal interface and for
83private. 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,
86types, and interfaces to be marked as: ``private``, ``export``, or
85types, 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:
88
87
89−- ``private`` meaning that it's not exported at all. This is the
88+- ``private`` meaning that it's not exported at all. This is the default.
90− default.
91
89
92- ``export`` meaning that its top level type is exported.
90- ``export`` meaning that its top level type is exported.
93
91
94- ``public export`` meaning that the entire definition is exported.
92- ``public export`` meaning that the entire definition is exported.
95
93
96−
97A further restriction in modifying the visibility is that definitions
94A further restriction in modifying the visibility is that definitions
98must not refer to anything within a lower level of visibility. For
95must not refer to anything within a lower level of visibility. For
99example, ``public export`` definitions cannot use private names, and
96example, ``public export`` definitions cannot use private names, and
@@ -129,10 +126,9 @@ Meaning for Data Types
129
126
130For data types, the meanings are:
127For data types, the meanings are:
131
128
132−- ``export`` the type constructor is exported
129+- ``export`` the type constructor is exported
133
130
134−- ``public export`` the type constructor and data constructors are
131+- ``public export`` the type constructor and data constructors are exported
135− exported
136
132
137
133
138Meaning for Interfaces
134Meaning for Interfaces
@@ -141,6 +137,7 @@ Meaning for Interfaces
141For interfaces, the meanings are:
137For interfaces, the meanings are:
142
138
143- ``export`` the interface name is exported
139- ``export`` the interface name is exported
140+
144- ``public export`` the interface name, method names and default
141- ``public export`` the interface name, method names and default
145 definitions are exported
142 definitions are exported
146
143
docs/tutorial/packages.rst+41−29
@@ -1,26 +1,31 @@
1+.. _sect-packages:
2+
1********
3********
2Packages
4Packages
3********
5********
4
6
5−
6−Idris includes a simple build system for building packages and executables from a named package description file.
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
7−These files can be used with the Idris compiler to manage the development process .
9+Idris compiler to manage the development process .
8
10
9Package Descriptions
11Package Descriptions
10====================
12====================
11
13
12A package description includes the following:
14A package description includes the following:
13
15
14−+ A header, consisting of the keyword package followed by the package
16++ A header, consisting of the keyword ``package`` followed by a package
15 name. Package names can be any valid Idris identifier. The iPKG
17 name. Package names can be any valid Idris identifier. The iPKG
16 format also takes a quoted version that accepts any valid filename.
18 format also takes a quoted version that accepts any valid filename.
19+
17−+ Fields describing package contents, ``<field> = <value>``
20++ Fields describing package contents, ``<field> = <value>``.
18
21
19At least one field must be the modules field, where the value is a
22At 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
21``maths`` that has modules ``Maths.idr``, ``Maths.NumOps.idr``,
24``maths`` that has modules ``Maths.idr``, ``Maths.NumOps.idr``,
22``Maths.BinOps.idr``, and ``Maths.HexOps.idr``, the corresponding
25``Maths.BinOps.idr``, and ``Maths.HexOps.idr``, the corresponding
23−package file would be::
26+package file would be:
27+
28+::
24
29
25 package maths
30 package maths
26
31
@@ -38,7 +43,6 @@ of the main Idris repository, and in `third-party libraries
38Using Package files
43Using Package files
39===================
44===================
40
45
41−
42Idris itself is aware about packages, and special commands are
46Idris itself is aware about packages, and special commands are
43available to help with, for example, building packages, installing
47available to help with, for example, building packages, installing
44packages, and cleaning packages. For instance, given the ``maths``
48packages, and cleaning packages. For instance, given the ``maths``
@@ -54,7 +58,9 @@ package from earlier we can use Idris as follows:
54
58
55Once the maths package has been installed, the command line option
59Once the maths package has been installed, the command line option
56``--package maths`` makes it accessible (abbreviated to ``-p maths``).
60``--package maths`` makes it accessible (abbreviated to ``-p maths``).
57−For example::
61+For example:
62+
63+::
58
64
59 idris -p maths Main.idr
65 idris -p maths Main.idr
60
66
@@ -66,20 +72,18 @@ The integrated build system includes a simple testing framework.
66This framework collects functions listed in the ``ipkg`` file under ``tests``.
72This framework collects functions listed in the ``ipkg`` file under ``tests``.
67All test functions must return ``IO ()``.
73All test functions must return ``IO ()``.
68
74
69−
70When you enter ``idris --testpkg yourmodule.ipkg``,
75When you enter ``idris --testpkg yourmodule.ipkg``,
71the build system creates a temporary file in a fresh environment on your machine
76the build system creates a temporary file in a fresh environment on your machine
72by listing the ``tests`` functions under a single ``main`` function.
77by listing the ``tests`` functions under a single ``main`` function.
73It compiles this temporary file to an executable and then executes it.
78It compiles this temporary file to an executable and then executes it.
74
79
75−
76The tests themselves are responsible for reporting their success or failure.
80The tests themselves are responsible for reporting their success or failure.
77Test functions commonly use ``putStrLn`` to report test results.
81Test functions commonly use ``putStrLn`` to report test results.
78The test framework does not impose any standards for reporting and consequently
82The test framework does not impose any standards for reporting and consequently
79does not aggregate test results.
83does not aggregate test results.
80
84
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``:
83
87
84.. name: Math/NumOps.idr
88.. name: Math/NumOps.idr
85.. code-block:: idris
89.. code-block:: idris
@@ -94,7 +98,8 @@ For example, lets take the following list of functions that are defined in a mod
94 triple : Num a => a -> a
98 triple : Num a => a -> a
95 triple a = a + double a
99 triple a = a + double a
96
100
101+
97−A simple test module, with a qualified name of ``Test.NumOps`` can be declared as
102+A simple test module, with a qualified name of ``Test.NumOps`` can be declared as:
98
103
99.. name: Math/TestOps.idr
104.. name: Math/TestOps.idr
100.. code-block:: idris
105.. code-block:: idris
@@ -122,8 +127,11 @@ A simple test module, with a qualified name of ``Test.NumOps`` can be declared a
122 testTriple = assertNotEq (triple 2) 5
127 testTriple = assertNotEq (triple 2) 5
123
128
124
129
125−The functions ``assertEq`` and ``assertNotEq`` are used to run expected passing, and failing, equality tests.
130+The functions ``assertEq`` and ``assertNotEq`` are used to run expected passing,
131+and failing, equality tests. The actual tests are ``testDouble`` and ``testTriple``,
126−The actual tests are ``testDouble`` and ``testTriple``, and are declared in the ``maths.ipkg`` file as follows::
132+and are declared in the ``maths.ipkg`` file as follows:
133+
134+::
127
135
128 package maths
136 package maths
129
137
@@ -134,7 +142,9 @@ The actual tests are ``testDouble`` and ``testTriple``, and are declared in the
134 , Test.NumOps.testTriple
142 , Test.NumOps.testTriple
135
143
136
144
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+::
138
148
139 > idris --testpkg maths.ipkg
149 > idris --testpkg maths.ipkg
140 Type checking ./Maths/NumOps.idr
150 Type checking ./Maths/NumOps.idr
@@ -146,25 +156,27 @@ The testing framework can then be invoked using ``idris --testpkg maths.ipkg``::
146Note how both tests have reported success by printing ``Test Passed``
156Note how both tests have reported success by printing ``Test Passed``
147as we arranged for with the ``assertEq`` and ``assertNoEq`` functions.
157as we arranged for with the ``assertEq`` and ``assertNoEq`` functions.
148
158
149−Package Dependencies Using Atom
159+Package Dependencies Using Atom
150===============================
160===============================
151
161
152−If you are using the Atom editor and have a dependency on another package,
162+If you are using the Atom editor and have a dependency on another package,
153−corresponding to for instance ``import Lightyear`` or ``import Pruviloj``,
163+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
164+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
165+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
166+will be described in the next section of the tutorial, but for now here is
157−a simple recipe for this trivial case.
167+a simple recipe for this trivial case:
168+
169+- Create a folder myProject.
158
170
159−- Create a folder myProject.
171+- Add a file myProject.ipkg containing just a couple of lines:
160
172
161−- Add a file myProject.ipkg containing just a couple of lines:
173+.. code-block:: idris
162
174
163−``package myProject``
175+ package myProject
164
176
165−``pkgs = pruviloj, lightyear``
177+ pkgs = pruviloj, lightyear
166
178
167−- In Atom, use the File menu to Open Folder myProject.
179+- In Atom, use the File menu to Open Folder myProject.
168
180
169More information
181More information
170================
182================
docs/tutorial/syntax.rst+4−4
@@ -34,7 +34,7 @@ rule, and the right hand side describes its expansion. The syntax rule
34itself consists of:
34itself consists of:
35
35
36- **Keywords** — here, ``if``, ``then`` and ``else``, which must be
36- **Keywords** — here, ``if``, ``then`` and ``else``, which must be
37− valid identifiers
37+ valid identifiers.
38
38
39- **Non-terminals** — included in square brackets, ``[test]``, ``[t]``
39- **Non-terminals** — included in square brackets, ``[test]``, ``[t]``
40 and ``[e]`` here, which stand for arbitrary expressions. To avoid
40 and ``[e]`` here, which stand for arbitrary expressions. To avoid
@@ -44,9 +44,9 @@ itself consists of:
44- **Names** — included in braces, which stand for names which may be
44- **Names** — included in braces, which stand for names which may be
45 bound on the right hand side.
45 bound on the right hand side.
46
46
47−- **Symbols** — included in quotations marks, e.g. ``:=``. This can
47+- **Symbols** — included in quotations marks, e.g. ``":="``. This can
48 also be used to include reserved words in syntax rules, such as
48 also be used to include reserved words in syntax rules, such as
49− ``let`` or ``in``.
49+ ``"let"`` or ``"in"``.
50
50
51The limitations on the form of a syntax rule are that it must include
51The limitations on the form of a syntax rule are that it must include
52at least one symbol or keyword, and there must be no repeated
52at least one symbol or keyword, and there must be no repeated
@@ -63,7 +63,7 @@ recursive. The following syntax extensions would therefore be valid:
63 syntax select [x] from [t] "where" [w] = SelectWhere x t w;
63 syntax select [x] from [t] "where" [w] = SelectWhere x t w;
64 syntax select [x] from [t] = Select x t;
64 syntax select [x] from [t] = Select x t;
65
65
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.
67only on the left hand side of a pattern match clause) or only in terms
67only on the left hand side of a pattern match clause) or only in terms
68(i.e. everywhere but the left hand side of a pattern match clause) by
68(i.e. everywhere but the left hand side of a pattern match clause) by
69being marked as ``pattern`` or ``term`` syntax rules. For example, we
69being 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:
115
115
116Even for trivial theorems like these, the proofs are a little tricky to
116Even for trivial theorems like these, the proofs are a little tricky to
117construct in one go. When things get even slightly more complicated, it
117construct in one go. When things get even slightly more complicated, it
118−becomes too much to think about to construct proofs in this ‘batch
118+becomes too much to think about to construct proofs in this “batch
119−mode’.
119+mode”.
120
120
121Idris provides interactive editing capabilities, which can help with
121Idris provides interactive editing capabilities, which can help with
122building proofs. For more details on building proofs interactively in
122building proofs. For more details on building proofs interactively in
@@ -383,7 +383,7 @@ will always be smaller than ``(x :: xs)``:
383 = qsort (filter (< x) xs) ++
383 = qsort (filter (< x) xs) ++
384 (x :: qsort (filter (>= x) xs))
384 (x :: qsort (filter (>= x) xs))
385
385
386−The function ``assert_smaller``, defined in the Prelude, is intended to
386+The function ``assert_smaller``, defined in the prelude, is intended to
387address this problem:
387address this problem:
388
388
389.. code-block:: idris
389.. code-block:: idris
docs/tutorial/typesfuns.rst+22−30
@@ -13,8 +13,7 @@ manipulation, and ``Ptr`` which represents foreign pointers. There are
13also several data types declared in the library, including ``Bool``,
13also several data types declared in the library, including ``Bool``,
14with values ``True`` and ``False``. We can declare some constants with
14with values ``True`` and ``False``. We can declare some constants with
15these types. Enter the following into a file ``Prims.idr`` and load it
15these types. Enter the following into a file ``Prims.idr`` and load it
16−into the Idris interactive environment by typing ``idris
16+into the Idris interactive environment by typing ``idris Prims.idr``:
17−Prims.idr``:
18
17
19.. code-block:: idris
18.. code-block:: idris
20
19
@@ -38,7 +37,7 @@ collection of declarations and definitions. In this example no imports
38have been specified. However Idris programs can consist of several
37have been specified. However Idris programs can consist of several
39modules and the definitions in each module each have their own
38modules and the definitions in each module each have their own
40namespace. This is discussed further in Section
39namespace. 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
42definitions are given and indentation are significant. Functions and
41definitions are given and indentation are significant. Functions and
43data types must be defined before use, incidentally each definition must
42data types must be defined before use, incidentally each definition must
44have a type declaration, for example see ``x : Int``, ``foo :
43have a type declaration, for example see ``x : Int``, ``foo :
@@ -343,7 +342,7 @@ Vectors
343
342
344A standard example of a dependent data type is the type of “lists with
343A standard example of a dependent data type is the type of “lists with
345length”, conventionally called vectors in the dependent type
344length”, 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
347importing ``Data.Vect``, or we can declare them as follows:
346importing ``Data.Vect``, or we can declare them as follows:
348
347
349.. code-block:: idris
348.. code-block:: idris
@@ -521,8 +520,8 @@ help document a function by making the purpose of an argument more
521clear.
520clear.
522
521
523Furthermore, ``{}`` can be used to pattern match on the left hand side, i.e.
522Furthermore, ``{}`` 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";
523+``{var = pat}`` gets an implicit variable and attempts to pattern match on “pat”;
525−For example :
524+For example:
526
525
527.. code-block:: idris
526.. code-block:: idris
528
527
@@ -559,7 +558,6 @@ vector. For example:
559 inVect : IsElem 5 Main.testVec
558 inVect : IsElem 5 Main.testVec
560 inVect = There (There Here)
559 inVect = There (There Here)
561
560
562−
563.. important:: Implicit Arguments and Scope
561.. important:: Implicit Arguments and Scope
564
562
565 Within the type signature the typechecker will treat all variables
563 Within the type signature the typechecker will treat all variables
@@ -569,7 +567,6 @@ vector. For example:
569 ``testVec``. In the example above, we have assumed that the code
567 ``testVec``. In the example above, we have assumed that the code
570 lives within the ``Main`` module.
568 lives within the ``Main`` module.
571
569
572−
573If the same implicit arguments are being used a lot, it can make a
570If the same implicit arguments are being used a lot, it can make a
574definition difficult to read. To avoid this problem, a ``using`` block
571definition difficult to read. To avoid this problem, a ``using`` block
575gives the types and ordering of any implicit arguments which can
572gives the types and ordering of any implicit arguments which can
@@ -582,15 +579,13 @@ appear within the block:
582 Here : IsElem x (x :: xs)
579 Here : IsElem x (x :: xs)
583 There : IsElem x xs -> IsElem x (y :: xs)
580 There : IsElem x xs -> IsElem x (y :: xs)
584
581
585−
586−
587Note: Declaration Order and ``mutual`` blocks
582Note: Declaration Order and ``mutual`` blocks
588~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
583~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
589
584
590In general, functions and data types must be defined before use, since
585In general, functions and data types must be defined before use, since
591dependent types allow functions to appear as part of types, and type
586dependent types allow functions to appear as part of types, and type
592checking can rely on how particular functions are defined (though this
587checking 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`).
594However, this restriction can be relaxed by using a ``mutual`` block,
589However, this restriction can be relaxed by using a ``mutual`` block,
595which allows data types and functions to be defined simultaneously:
590which allows data types and functions to be defined simultaneously:
596
591
@@ -673,7 +668,7 @@ Note that several of these return ``Either``, since they may fail.
673I/O programs will typically need to sequence actions, feeding the
668I/O programs will typically need to sequence actions, feeding the
674output of one computation into the input of the next. ``IO`` is an
669output of one computation into the input of the next. ``IO`` is an
675abstract type, however, so we can’t access the result of a computation
670abstract 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:
677
672
678.. code-block:: idris
673.. code-block:: idris
679
674
@@ -713,7 +708,7 @@ not always the best approach. Consider the following function:
713
708
714This function uses one of the ``t`` or ``e`` arguments, but not both
709This function uses one of the ``t`` or ``e`` arguments, but not both
715(in fact, this is used to implement the ``if...then...else`` construct
710(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
717used was evaluated. To achieve this, Idris provides a ``Lazy``
712used was evaluated. To achieve this, Idris provides a ``Lazy``
718data type, which allows evaluation to be suspended:
713data type, which allows evaluation to be suspended:
719
714
@@ -797,7 +792,7 @@ infinite loop and cause a stack overflow.
797To fix this we must add explicit ``Inf`` declarations to the constructor
792To fix this we must add explicit ``Inf`` declarations to the constructor
798parameter types, since codata will not add it to constructor parameters of a
793parameter types, since codata will not add it to constructor parameters of a
799**different** type from the one being defined. For example, the following
794**different** type from the one being defined. For example, the following
800−outputs "1".
795+outputs ``1``.
801
796
802.. code-block:: idris
797.. code-block:: idris
803
798
@@ -902,7 +897,7 @@ For more details of the functions available on ``List`` and
902
897
903- ``libs/base/Data/VectType.idr``
898- ``libs/base/Data/VectType.idr``
904
899
905−Functions include filtering, appending, reversing, and so on.
900+Functions include filtering, appending, reversing, and so on.
906
901
907Aside: Anonymous functions and operator sections
902Aside: Anonymous functions and operator sections
908~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
903~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -999,7 +994,7 @@ Dependent Pairs
999---------------
994---------------
1000
995
1001Dependent pairs allow the type of the second element of a pair to depend
996Dependent 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:
1003
998
1004.. code-block:: idris
999.. code-block:: idris
1005
1000
@@ -1009,7 +1004,7 @@ on the value of the first element.
1009Again, there is syntactic sugar for this. ``(a : A ** P)`` is the type
1004Again, there is syntactic sugar for this. ``(a : A ** P)`` is the type
1010of a pair of A and P, where the name ``a`` can occur inside ``P``.
1005of a pair of A and P, where the name ``a`` can occur inside ``P``.
1011``( a ** p )`` constructs a value of this type. For example, we can
1006``( 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:
1013
1008
1014.. code-block:: idris
1009.. code-block:: idris
1015
1010
@@ -1017,7 +1012,7 @@ pair a number with a ``Vect`` of a particular length.
1017 vec = (2 ** [3, 4])
1012 vec = (2 ** [3, 4])
1018
1013
1019If you like, you can write it out the long way, the two are precisely
1014If you like, you can write it out the long way, the two are precisely
1020−equivalent.
1015+equivalent:
1021
1016
1022.. code-block:: idris
1017.. code-block:: idris
1023
1018
@@ -1070,7 +1065,7 @@ intermediate values:
1070
1065
1071We will see more on ``with`` notation later.
1066We will see more on ``with`` notation later.
1072
1067
1073−Dependent pairs are sometimes referred to as “sigma types”.
1068+Dependent pairs are sometimes referred to as “Sigma types”.
1074
1069
1075Records
1070Records
1076-------
1071-------
@@ -1080,7 +1075,7 @@ Records
1080automatically generating field access and update functions. Unlike
1075automatically generating field access and update functions. Unlike
1081the syntax used for data structures, records in Idris follow a
1076the syntax used for data structures, records in Idris follow a
1082different syntax to that seen with Haskell. For example, we can
1077different 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:
1084
1079
1085.. code-block:: idris
1080.. code-block:: idris
1086
1081
@@ -1092,12 +1087,11 @@ represent a person's name and age in a record:
1092 fred : Person
1087 fred : Person
1093 fred = MkPerson "Fred" "Joe" "Bloggs" 30
1088 fred = MkPerson "Fred" "Joe" "Bloggs" 30
1094
1089
1095−
1096The constructor name is provided using the ``constructor`` keyword,
1090The constructor name is provided using the ``constructor`` keyword,
1097and the *fields* are then given which are in an indented block
1091and the *fields* are then given which are in an indented block
1098following the `where` keyword (here, ``firstName``, ``middleName``,
1092following the `where` keyword (here, ``firstName``, ``middleName``,
1099``lastName``, and ``age``). You can declare multiple fields on a
1093``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
1101can be used to access the field values:
1095can be used to access the field values:
1102
1096
1103::
1097::
@@ -1171,7 +1165,7 @@ syntax:
1171 record { a->b->c = val } x
1165 record { a->b->c = val } x
1172
1166
1173This returns a new record, with the field accessed by the path
1167This 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 {
1175a->b->c = val }`` itself has a function type. Symmetrically, the field
1169a->b->c = val }`` itself has a function type. Symmetrically, the field
1176can also be accessed with the following syntax:
1170can also be accessed with the following syntax:
1177
1171
@@ -1196,12 +1190,10 @@ name. For example, a pair type could be defined as follows:
1196 fst : a
1190 fst : a
1197 snd : b
1191 snd : b
1198
1192
1199−
1200Using the ``class`` record from earlier, the size of the class can be
1193Using the ``class`` record from earlier, the size of the class can be
1201restricted using a ``Vect`` and the size included in the type by parameterising
1194restricted using a ``Vect`` and the size included in the type by parameterising
1202the record with the size. For example:
1195the record with the size. For example:
1203
1196
1204−
1205.. code-block:: idris
1197.. code-block:: idris
1206
1198
1207 record SizedClass (size : Nat) where
1199 record SizedClass (size : Nat) where
@@ -1214,7 +1206,7 @@ function from earlier, since that would change the size of the class. A
1214function to add a student must now specify in the type that the
1206function to add a student must now specify in the type that the
1215size of the class has been increased by one. As the size is specified
1207size of the class has been increased by one. As the size is specified
1216using natural numbers, the new value can be incremented using the
1208using natural numbers, the new value can be incremented using the
1217−``S`` constructor.
1209+``S`` constructor:
1218
1210
1219.. code-block:: idris
1211.. code-block:: idris
1220
1212
@@ -1327,7 +1319,7 @@ matching ``let`` and lambda bindings. It will *only* work if:
1327- Each branch *matches* a value of the same type, and *returns* a
1319- Each branch *matches* a value of the same type, and *returns* a
1328 value of the same type.
1320 value of the same type.
1329
1321
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
1331 can be determined *without* type checking the ``case``-expression
1323 can be determined *without* type checking the ``case``-expression
1332 itself.
1324 itself.
1333
1325
@@ -1337,7 +1329,7 @@ Totality
1337Idris distinguishes between *total* and *partial* functions.
1329Idris distinguishes between *total* and *partial* functions.
1338A total function is a function that either:
1330A total function is a function that either:
1339
1331
1340−+ Terminates for all possible inputs, or
1332++ Terminates for all possible inputs, or
1341+ Produces a non-empty, finite, prefix of a possibly infinite result
1333+ Produces a non-empty, finite, prefix of a possibly infinite result
1342
1334
1343If a function is total, we can consider its type a precise description of what
1335If 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
1345type of ``String`` we know something different, depending on whether or not
1337type of ``String`` we know something different, depending on whether or not
1346it's total:
1338it's total:
1347
1339
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;
1349+ If it's partial, then as long as it doesn't crash or enter an infinite loop,
1341+ If it's partial, then as long as it doesn't crash or enter an infinite loop,
1350 it will return a ``String``.
1342 it will return a ``String``.
1351
1343
1352Idris makes this distinction so that it knows which functions are safe to
1344Idris 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,
1354if it tries to evaluate a function during type checking which doesn't
1346if it tries to evaluate a function during type checking which doesn't
1355terminate, then type checking won't terminate!
1347terminate, then type checking won't terminate!
1356Therefore, only total functions will be evaluated during type checking.
1348Therefore, 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:
103 ``Parity (n + n)`` from the ``Even`` constructor definition. So
103 ``Parity (n + n)`` from the ``Even`` constructor definition. So
104 ``(j + j)`` replaces ``k`` on the left side of ``|``, and the
104 ``(j + j)`` replaces ``k`` on the left side of ``|``, and the
105 ``Even`` constructor appears on the right side. The natural number
105 ``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
107 ``=`` sign.
107 ``=`` sign.
108
108
109- Otherwise, when ``parity k`` evaluates to ``Odd``, the original
109- Otherwise, when ``parity k`` evaluates to ``Odd``, the original
110 argument ``k`` is refined to ``S (j + j)`` according to ``Parity (S
110 argument ``k`` is refined to ``S (j + j)`` according to ``Parity (S
111 (n + n))`` from the ``Odd`` constructor definition, and ``Odd`` now
111 (n + n))`` from the ``Odd`` constructor definition, and ``Odd`` now
112− appears on the ride side of ``|``, again with the natural number
112+ appears on the right side of ``|``, again with the natural number
113− ``j`` used on the ride side of the ``=`` sign.
113+ ``j`` used on the right side of the ``=`` sign.
114
114
115Note that there is a function in the patterns (``+``) and repeated
115Note that there is a function in the patterns (``+``) and repeated
116occurrences of ``j`` - this is allowed because another argument has
116occurrences of ``j`` - this is allowed because another argument has
idris-tutorial.pdf

Binary file not shown.

idris.cabal+5−5
@@ -1,5 +1,5 @@
1Name: idris
1Name: idris
2−Version: 1.2.0
2+Version: 1.3.0
3License: BSD3
3License: BSD3
4License-file: LICENSE
4License-file: LICENSE
5Author: Edwin Brady
5Author: Edwin Brady
@@ -100,7 +100,7 @@ source-repository head
100
100
101custom-setup
101custom-setup
102 setup-depends:
102 setup-depends:
103− Cabal >= 1.10 && <2.1,
103+ Cabal >= 1.10 && <2.3,
104 base >= 4 && <5,
104 base >= 4 && <5,
105 directory,
105 directory,
106 filepath,
106 filepath,
@@ -270,7 +270,7 @@ Library
270 , BuildFlags_idris
270 , BuildFlags_idris
271
271
272 Build-depends: base >=4 && <5
272 Build-depends: base >=4 && <5
273− , aeson >= 0.6 && < 1.3
273+ , aeson >= 0.6 && < 1.4
274 , annotated-wl-pprint >= 0.7 && < 0.8
274 , annotated-wl-pprint >= 0.7 && < 0.8
275 , ansi-terminal < 0.9
275 , ansi-terminal < 0.9
276 , ansi-wl-pprint < 0.7
276 , ansi-wl-pprint < 0.7
@@ -286,7 +286,7 @@ Library
286 , deepseq < 1.5
286 , deepseq < 1.5
287 , directory >= 1.2.2.0 && < 1.2.3.0 || > 1.2.3.0
287 , directory >= 1.2.2.0 && < 1.2.3.0 || > 1.2.3.0
288 , filepath < 1.5
288 , filepath < 1.5
289− , fingertree >= 0.1 && < 0.2
289+ , fingertree >= 0.1.4.1 && < 0.2
290 , haskeline >= 0.7 && < 0.8
290 , haskeline >= 0.7 && < 0.8
291 , ieee754 >= 0.7 && < 0.9
291 , ieee754 >= 0.7 && < 0.9
292 , megaparsec >= 6.2
292 , megaparsec >= 6.2
@@ -309,7 +309,7 @@ Library
309 , vector-binary-instances < 0.3
309 , vector-binary-instances < 0.3
310 , zip-archive > 0.2.3.5 && < 0.4
310 , zip-archive > 0.2.3.5 && < 0.4
311 , fsnotify >= 0.2 && < 2.2
311 , fsnotify >= 0.2 && < 2.2
312− , async < 2.2
312+ , async < 2.3
313
313
314 if !impl(ghc >= 8.0)
314 if !impl(ghc >= 8.0)
315 Build-Depends: semigroups == 0.18.*
315 Build-Depends: semigroups == 0.18.*
libs/base/Data/Nat/Views.idr+1−1
@@ -14,7 +14,7 @@ data HalfRec : Nat -> Type where
14 HalfRecOdd : {n : Nat} -> (rec : Lazy (HalfRec n)) -> HalfRec (S (n + n))
14 HalfRecOdd : {n : Nat} -> (rec : Lazy (HalfRec n)) -> HalfRec (S (n + n))
15
15
16||| Covering function for the `Half` view
16||| Covering function for the `Half` view
17−export
17+public export
18half : (n : Nat) -> Half n
18half : (n : Nat) -> Half n
19half Z = HalfEven {n=0}
19half Z = HalfEven {n=0}
20half (S k) with (half k)
20half (S k) with (half k)
libs/base/Makefile+1−1
@@ -1,4 +1,4 @@
1−IDRIS := idris
1+IDRIS ?= idris
2PKG := base
2PKG := base
3
3
4build:
4build:
libs/base/System/Concurrency/Raw.idr+9−10
@@ -8,7 +8,7 @@ import System
8
8
9||| Send a message of any type to the thread with the given thread id
9||| Send a message of any type to the thread with the given thread id
10||| Returns channel ID if the message was sent successfully, 0 otherwise
10||| Returns channel ID if the message was sent successfully, 0 otherwise
11−|||
11+|||
12||| @channel an ID of a specific channel to send the message on. If 0,
12||| @channel an ID of a specific channel to send the message on. If 0,
13||| the receiver will create a new channel ID
13||| the receiver will create a new channel ID
14sendToThread : (thread_id : Ptr) -> (channel : Int) -> a -> IO Int
14sendToThread : (thread_id : Ptr) -> (channel : Int) -> a -> IO Int
@@ -29,7 +29,7 @@ checkMsgs = do me <- getMyVM
29checkMsgsTimeout : Int -> IO Bool
29checkMsgsTimeout : Int -> IO Bool
30checkMsgsTimeout timeout
30checkMsgsTimeout timeout
31 = do me <- getMyVM
31 = do me <- getMyVM
32− msgs <- foreign FFI_C "idris_checkMessagesTimeout"
32+ msgs <- foreign FFI_C "idris_checkMessagesTimeout"
33 (Ptr -> Int -> IO Ptr) me timeout
33 (Ptr -> Int -> IO Ptr) me timeout
34 null <- nullPtr msgs
34 null <- nullPtr msgs
35 pure (not null)
35 pure (not null)
@@ -43,7 +43,7 @@ channel_id : Ptr -> IO Int
43channel_id msg = foreign FFI_C "idris_getChannel" (Ptr -> IO Int) msg
43channel_id msg = foreign FFI_C "idris_getChannel" (Ptr -> IO Int) msg
44
44
45||| Check for messages initiating a conversation in the process inbox.
45||| 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
47||| of sender and new channel id.
47||| of sender and new channel id.
48listenMsgs : IO (Maybe (Ptr, Int))
48listenMsgs : IO (Maybe (Ptr, Int))
49listenMsgs = do me <- getMyVM
49listenMsgs = do me <- getMyVM
@@ -58,7 +58,7 @@ listenMsgs = do me <- getMyVM
58||| Check for messages from a specific sender/channel in the process inbox
58||| Check for messages from a specific sender/channel in the process inbox
59||| If channel is '0', accept on any channel.
59||| If channel is '0', accept on any channel.
60checkMsgsFrom : Ptr -> (channel : Int) -> IO Bool
60checkMsgsFrom : Ptr -> (channel : Int) -> IO Bool
61−checkMsgsFrom sender channel
61+checkMsgsFrom sender channel
62 = do me <- getMyVM
62 = do me <- getMyVM
63 msgs <- foreign FFI_C "idris_checkMessagesFrom" (Ptr -> Int -> Ptr -> IO Ptr)
63 msgs <- foreign FFI_C "idris_checkMessagesFrom" (Ptr -> Int -> Ptr -> IO Ptr)
64 me channel sender
64 me channel sender
@@ -73,6 +73,7 @@ getMsg : IO a
73getMsg {a} = do me <- getMyVM
73getMsg {a} = do me <- getMyVM
74 m <- foreign FFI_C "idris_recvMessage" (Ptr -> IO Ptr) me
74 m <- foreign FFI_C "idris_recvMessage" (Ptr -> IO Ptr) me
75 MkRaw x <- foreign FFI_C "idris_getMsg" (Ptr -> IO (Raw a)) m
75 MkRaw x <- foreign FFI_C "idris_getMsg" (Ptr -> IO (Raw a)) m
76+ foreign FFI_C "idris_freeMsg" (Ptr -> IO ()) m
76 pure x
77 pure x
77
78
78||| Check inbox for messages. If there are none, blocks until a message
79||| Check inbox for messages. If there are none, blocks until a message
@@ -80,9 +81,9 @@ getMsg {a} = do me <- getMyVM
80||| Note that this is not at all type safe! It is intended to be used in
81||| Note that this is not at all type safe! It is intended to be used in
81||| a type safe wrapper.
82||| a type safe wrapper.
82getMsgWithSender : IO (Ptr, Int, a)
83getMsgWithSender : IO (Ptr, Int, a)
83−getMsgWithSender {a}
84+getMsgWithSender {a}
84 = do me <- getMyVM
85 = do me <- getMyVM
85− m <- foreign FFI_C "idris_recvMessage"
86+ m <- foreign FFI_C "idris_recvMessage"
86 (Ptr -> IO Ptr) me
87 (Ptr -> IO Ptr) me
87 MkRaw x <- foreign FFI_C "idris_getMsg" (Ptr -> IO (Raw a)) m
88 MkRaw x <- foreign FFI_C "idris_getMsg" (Ptr -> IO (Raw a)) m
88 vm <- sender m
89 vm <- sender m
@@ -94,12 +95,12 @@ getMsgWithSender {a}
94||| blocks until a message arrives. Returns `Nothing` if the sender isn't
95||| blocks until a message arrives. Returns `Nothing` if the sender isn't
95||| alive
96||| alive
96getMsgFrom : Ptr -> (channel : Int) -> IO (Maybe a)
97getMsgFrom : Ptr -> (channel : Int) -> IO (Maybe a)
97−getMsgFrom {a} sender channel
98+getMsgFrom {a} sender channel
98 = do me <- getMyVM
99 = do me <- getMyVM
99 m <- foreign FFI_C "idris_recvMessageFrom"
100 m <- foreign FFI_C "idris_recvMessageFrom"
100 (Ptr -> Int -> Ptr -> IO Ptr) me channel sender
101 (Ptr -> Int -> Ptr -> IO Ptr) me channel sender
101 null <- nullPtr m
102 null <- nullPtr m
102− if null
103+ if null
103 then pure Nothing
104 then pure Nothing
104 else do
105 else do
105 MkRaw x <- foreign FFI_C "idris_getMsg" (Ptr -> IO (Raw a)) m
106 MkRaw x <- foreign FFI_C "idris_getMsg" (Ptr -> IO (Raw a)) m
@@ -110,5 +111,3 @@ stopThread : IO a
110stopThread = do vm <- getMyVM
111stopThread = do vm <- getMyVM
111 MkRaw res <- foreign FFI_C "idris_stopThread" (Ptr -> IO (Raw a)) vm
112 MkRaw res <- foreign FFI_C "idris_stopThread" (Ptr -> IO (Raw a)) vm
112 pure res
113 pure res
113−
114−
libs/contrib/CFFI/Types.idr+2−2
@@ -70,9 +70,9 @@ mutual
70 alignOfCT I8 = 1
70 alignOfCT I8 = 1
71 alignOfCT I16 = 2
71 alignOfCT I16 = 2
72 alignOfCT I32 = 4
72 alignOfCT I32 = 4
73− alignOfCT I64 = 8
73+ alignOfCT I64 = min prim__sizeofPtr 8
74 alignOfCT FLOAT = 4
74 alignOfCT FLOAT = 4
75− alignOfCT DOUBLE = 8
75+ alignOfCT DOUBLE = min prim__sizeofPtr 8
76 alignOfCT PTR = prim__sizeofPtr
76 alignOfCT PTR = prim__sizeofPtr
77
77
78 ||| Alignment requirement of the type
78 ||| Alignment requirement of the type
libs/contrib/Data/BoundedList.idr+15
@@ -1,6 +1,7 @@
1module Data.BoundedList
1module Data.BoundedList
2
2
3import Data.Fin
3import Data.Fin
4+import Data.Vect
4
5
5%access public export
6%access public export
6%default total
7%default total
@@ -50,6 +51,20 @@ fromList : (xs : List a) -> BoundedList (length xs) a
50fromList [] = []
51fromList [] = []
51fromList (x :: xs) = x :: fromList xs
52fromList (x :: xs) = x :: fromList xs
52
53
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+
53--------------------------------------------------------------------------------
68--------------------------------------------------------------------------------
54-- Building (bigger) bounded lists
69-- Building (bigger) bounded lists
55--------------------------------------------------------------------------------
70--------------------------------------------------------------------------------
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
5||| A representation of signs for signed datatypes such as `ZZ`
5||| A representation of signs for signed datatypes such as `ZZ`
6data Sign = Plus | Zero | Minus
6data Sign = Plus | Zero | Minus
7
7
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+
8||| Discover the sign of some type
19||| Discover the sign of some type
9interface Signed t where
20interface Signed t where
10 total sign : t -> Sign
21 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
2PKG := contrib
2PKG := contrib
3
3
4build:
4build:
libs/contrib/Network/Socket.idr+20−1
@@ -133,7 +133,7 @@ send sock dat = do
133||| + `ResultCode` :: The result of the underlying function.
133||| + `ResultCode` :: The result of the underlying function.
134|||
134|||
135||| @sock The socket on which to receive the message.
135||| @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.
137recv : (sock : Socket)
137recv : (sock : Socket)
138 -> (len : ByteLength)
138 -> (len : ByteLength)
139 -> IO (Either SocketError (String, ResultCode))
139 -> IO (Either SocketError (String, ResultCode))
@@ -164,6 +164,25 @@ recv sock len = do
164 freeRecvStruct (RSPtr recv_struct_ptr)
164 freeRecvStruct (RSPtr recv_struct_ptr)
165 pure $ Right (payload, recv_res)
165 pure $ Right (payload, recv_res)
166
166
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+
167||| Send a message.
186||| Send a message.
168|||
187|||
169||| Returns on failure a `SocketError`
188||| Returns on failure a `SocketError`
libs/contrib/Text/Parser.idr+1−1
@@ -118,7 +118,7 @@ mutual
118||| list of values from `p`, along with a proof that the resulting list is
118||| list of values from `p`, along with a proof that the resulting list is
119||| non-empty.
119||| non-empty.
120someTill' : {c : Bool} ->
120someTill' : {c : Bool} ->
121− (end : Grammar tok c a) ->
121+ (end : Grammar tok c e) ->
122 (p : Grammar tok True a) ->
122 (p : Grammar tok True a) ->
123 Grammar tok True (xs : List a ** NonEmpty xs)
123 Grammar tok True (xs : List a ** NonEmpty xs)
124someTill' end p
124someTill' end p
libs/contrib/contrib.ipkg+1
@@ -43,6 +43,7 @@ modules = CFFI
43 , Data.Matrix.Algebraic
43 , Data.Matrix.Algebraic
44 , Data.Matrix.Numeric
44 , Data.Matrix.Numeric
45
45
46+ , Data.Nat
46 , Data.Nat.Parity
47 , Data.Nat.Parity
47 , Data.Nat.DivMod
48 , Data.Nat.DivMod
48 , Data.Nat.DivMod.IteratedSubtraction
49 , Data.Nat.DivMod.IteratedSubtraction
libs/effects/Makefile+1−1
@@ -1,4 +1,4 @@
1−IDRIS := idris
1+IDRIS ?= idris
2PKG := effects
2PKG := effects
3
3
4build:
4build:
libs/prelude/Decidable/Equality.idr+10−7
@@ -157,7 +157,10 @@ implementation DecEq a => DecEq (List a) where
157
157
158
158
159-- For the primitives, we have to cheat because we don't have access to their
159-- 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.
161
164
162--------------------------------------------------------------------------------
165--------------------------------------------------------------------------------
163-- Int
166-- Int
@@ -170,7 +173,7 @@ implementation DecEq Int where
170 where primitiveEq : x = y
173 where primitiveEq : x = y
171 primitiveEq = really_believe_me (Refl {x})
174 primitiveEq = really_believe_me (Refl {x})
172 primitiveNotEq : x = y -> Void
175 primitiveNotEq : x = y -> Void
173− primitiveNotEq = really_believe_me (id {a = x = y})
176+ primitiveNotEq prf = believe_me {b = Void} ()
174
177
175--------------------------------------------------------------------------------
178--------------------------------------------------------------------------------
176-- Char
179-- Char
@@ -183,7 +186,7 @@ implementation DecEq Char where
183 where primitiveEq : x = y
186 where primitiveEq : x = y
184 primitiveEq = really_believe_me (Refl {x})
187 primitiveEq = really_believe_me (Refl {x})
185 primitiveNotEq : x = y -> Void
188 primitiveNotEq : x = y -> Void
186− primitiveNotEq = really_believe_me (id {a = x = y})
189+ primitiveNotEq prf = believe_me {b = Void} ()
187
190
188--------------------------------------------------------------------------------
191--------------------------------------------------------------------------------
189-- Integer
192-- Integer
@@ -196,7 +199,7 @@ implementation DecEq Integer where
196 where primitiveEq : x = y
199 where primitiveEq : x = y
197 primitiveEq = really_believe_me (Refl {x})
200 primitiveEq = really_believe_me (Refl {x})
198 primitiveNotEq : x = y -> Void
201 primitiveNotEq : x = y -> Void
199− primitiveNotEq = really_believe_me (id {a = x = y})
202+ primitiveNotEq prf = believe_me {b = Void} ()
200
203
201--------------------------------------------------------------------------------
204--------------------------------------------------------------------------------
202-- String
205-- String
@@ -209,7 +212,7 @@ implementation DecEq String where
209 where primitiveEq : x = y
212 where primitiveEq : x = y
210 primitiveEq = really_believe_me (Refl {x})
213 primitiveEq = really_believe_me (Refl {x})
211 primitiveNotEq : x = y -> Void
214 primitiveNotEq : x = y -> Void
212− primitiveNotEq = really_believe_me (id {a = x = y})
215+ primitiveNotEq prf = believe_me {b = Void} ()
213
216
214--------------------------------------------------------------------------------
217--------------------------------------------------------------------------------
215-- Ptr
218-- Ptr
@@ -222,7 +225,7 @@ implementation DecEq Ptr where
222 where primitiveEq : x = y
225 where primitiveEq : x = y
223 primitiveEq = really_believe_me (Refl {x})
226 primitiveEq = really_believe_me (Refl {x})
224 primitiveNotEq : x = y -> Void
227 primitiveNotEq : x = y -> Void
225− primitiveNotEq = really_believe_me (id {a = x = y})
228+ primitiveNotEq prf = believe_me {b = Void} ()
226
229
227--------------------------------------------------------------------------------
230--------------------------------------------------------------------------------
228-- ManagedPtr
231-- ManagedPtr
@@ -235,4 +238,4 @@ implementation DecEq ManagedPtr where
235 where primitiveEq : x = y
238 where primitiveEq : x = y
236 primitiveEq = really_believe_me (Refl {x})
239 primitiveEq = really_believe_me (Refl {x})
237 primitiveNotEq : x = y -> Void
240 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
16import Prelude.Monad
16import Prelude.Monad
17import Prelude.Nat
17import Prelude.Nat
18import Language.Reflection
18import Language.Reflection
19+import Language.Reflection.Errors
19
20
20%access public export
21%access public export
21
22
@@ -138,6 +139,7 @@ data Elab : Type -> Type where
138 Prim__BindElab : {a, b : Type} -> Elab a -> (a -> Elab b) -> Elab b
139 Prim__BindElab : {a, b : Type} -> Elab a -> (a -> Elab b) -> Elab b
139
140
140 Prim__Try : {a : Type} -> Elab a -> Elab a -> Elab a
141 Prim__Try : {a : Type} -> Elab a -> Elab a -> Elab a
142+ Prim__TryCatch : {a : Type} -> Elab a -> (Err -> Elab a) -> Elab a
141 Prim__Fail : {a : Type} -> List ErrorReportPart -> Elab a
143 Prim__Fail : {a : Type} -> List ErrorReportPart -> Elab a
142
144
143 Prim__Env : Elab (List (TTName, Binder TT))
145 Prim__Env : Elab (List (TTName, Binder TT))
@@ -218,6 +220,13 @@ namespace Tactics
218 implementation Monad Elab where
220 implementation Monad Elab where
219 x >>= f = Prim__BindElab x f
221 x >>= f = Prim__BindElab x f
220
222
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+
221 ||| Halt elaboration with an error
230 ||| Halt elaboration with an error
222 export
231 export
223 fail : List ErrorReportPart -> Elab a
232 fail : List ErrorReportPart -> Elab a
libs/prelude/Makefile+1−1
@@ -1,4 +1,4 @@
1−IDRIS := idris
1+IDRIS ?= idris
2PKG := prelude
2PKG := prelude
3
3
4build:
4build:
libs/prelude/Prelude/File.idr+53−6
@@ -141,17 +141,64 @@ private
141do_getFileSize : Ptr -> IO Int
141do_getFileSize : Ptr -> IO Int
142do_getFileSize h = foreign FFI_C "fileSize" (Ptr -> IO Int) h
142do_getFileSize h = foreign FFI_C "fileSize" (Ptr -> IO Int) h
143
143
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+
144||| Return the size of a File
162||| Return the size of a File
145||| Returns an error if the File is not an ordinary file (e.g. a directory)
163||| Returns an error if the File is not an ordinary file (e.g. a directory)
146||| Also note that this currently returns an Int, which may overflow if the
164||| Also note that this currently returns an Int, which may overflow if the
147||| file is very big
165||| file is very big
148export
166export
149fileSize : File -> IO (Either FileError Int)
167fileSize : File -> IO (Either FileError Int)
168+fileSize (FHandle h)
150−fileSize (FHandle h) = do s <- do_getFileSize h
169+ = do s <- do_getFileSize h
151− if (s < 0)
170+ if (s < 0)
152− then do err <- getFileError
171+ then do err <- getFileError
153− pure (Left err)
172+ pure (Left err)
154− else pure (Right s)
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+
155
202
156private
203private
157do_fread : Ptr -> IO' l String
204do_fread : Ptr -> IO' l String
@@ -326,5 +373,5 @@ createDir d
326export
373export
327changeDir : String -> IO Bool
374changeDir : String -> IO Bool
328changeDir dir
375changeDir dir
329− = do ok <- foreign FFI_C "chdir" (String -> IO Int) dir
376+ = do ok <- foreign FFI_C "idris_chdir" (String -> IO Int) dir
330 pure (ok == 0)
377 pure (ok == 0)
libs/prelude/Prelude/Interactive.idr+1−1
@@ -81,7 +81,7 @@ getLine = getLine'
81putChar : Char -> IO ()
81putChar : Char -> IO ()
82putChar c = foreign FFI_C "putchar" (Int -> IO ()) (cast c)
82putChar c = foreign FFI_C "putchar" (Int -> IO ()) (cast c)
83
83
84−||| Write a singel character to stdout, with a trailing newline
84+||| Write a single character to stdout, with a trailing newline
85putCharLn : Char -> IO ()
85putCharLn : Char -> IO ()
86putCharLn c = putStrLn (singleton c)
86putCharLn c = putStrLn (singleton c)
87
87
libs/prelude/Prelude/Maybe.idr+6
@@ -100,6 +100,12 @@ maybe_bind (Just x) k = k x
100 (Just _) == Nothing = False
100 (Just _) == Nothing = False
101 (Just a) == (Just b) = a == b
101 (Just a) == (Just b) = a == b
102
102
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+
103||| Prioritised choice. Just like the `Alternative` implementation, the
109||| Prioritised choice. Just like the `Alternative` implementation, the
104||| `Semigroup` for `Maybe a` keeps the first succeeding computation.
110||| `Semigroup` for `Maybe a` keeps the first succeeding computation.
105|||
111|||
libs/pruviloj/Makefile+1−1
@@ -1,4 +1,4 @@
1−IDRIS := idris
1+IDRIS ?= idris
2PKG := pruviloj
2PKG := pruviloj
3
3
4build:
4build:
man/idris.1+1−1
@@ -1,6 +1,6 @@
1.\" Manpage for Idris.
1.\" Manpage for Idris.
2.\" Contact <> to correct errors or typos.
2.\" 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"
4.SH NAME
4.SH NAME
5idris -\ a general purpose pure functional programming language with dependent types.
5idris -\ a general purpose pure functional programming language with dependent types.
6.SH SYNOPSIS
6.SH SYNOPSIS
rts/Makefile+8−12
@@ -1,30 +1,26 @@
1include ../config.mk
1include ../config.mk
2
2
3OBJS = idris_rts.o idris_heap.o idris_gc.o idris_gmp.o idris_bitstring.o \
3OBJS = 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 \
5 idris_buffer.o getline.o idris_net.o
5 idris_buffer.o getline.o idris_net.o
6HDRS = idris_rts.h idris_heap.h idris_gc.h idris_gmp.h idris_bitstring.h \
6HDRS = 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 \
8 idris_buffer.h idris_utf8.h getline.h
8 idris_buffer.h idris_utf8.h getline.h
9CFLAGS := $(CFLAGS)
9CFLAGS := $(CFLAGS)
10CFLAGS += $(GMP_INCLUDE_DIR) $(GMP) -DIDRIS_TARGET_OS="\"$(OS)\""
10CFLAGS += $(GMP_INCLUDE_DIR) $(GMP) -DIDRIS_TARGET_OS="\"$(OS)\""
11CFLAGS += -DIDRIS_TARGET_TRIPLE="\"$(MACHINE)\""
11CFLAGS += -DIDRIS_TARGET_TRIPLE="\"$(MACHINE)\""
12
12
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−
22ifeq ($(OS), windows)
13ifeq ($(OS), windows)
23 OBJS += windows/win_utils.o
14 OBJS += windows/win_utils.o
24else
15else
25 CFLAGS += -fPIC
16 CFLAGS += -fPIC
26endif
17endif
27
18
19+ifndef IDRIS_GMP
20+ OBJS += mini-gmp.o
21+ HDRS += mini-gmp.h
22+endif
23+
28LIBTARGET = libidris_rts.a
24LIBTARGET = libidris_rts.a
29
25
30build: $(LIBTARGET) $(DYLIBTARGET)
26build: $(LIBTARGET) $(DYLIBTARGET)
@@ -40,6 +36,6 @@ install :
40clean :
36clean :
41 rm -f $(OBJS) $(LIBTARGET) $(DYLIBTARGET)
37 rm -f $(OBJS) $(LIBTARGET) $(DYLIBTARGET)
42
38
43−idris_rts.o: idris_rts.h
39+$(OBJS): $(HDRS)
44
40
45.PHONY: build install clean
41.PHONY: build install clean
rts/idris_bitstring.c+247−513
@@ -2,824 +2,558 @@
2
2
3#include "idris_rts.h"
3#include "idris_rts.h"
4
4
5−VAL idris_b8CopyForGC(VM *vm, VAL a) {
5+VAL idris_b8const(VM *vm, uint8_t 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;
6+ return MKINT(a);
11}
7}
12
8
13−VAL idris_b16CopyForGC(VM *vm, VAL a) {
9+VAL idris_b16const(VM *vm, uint16_t 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;
10+ return MKINT(a);
19}
11}
20
12
21−VAL idris_b32CopyForGC(VM *vm, VAL a) {
13+VAL idris_b32const(VM *vm, uint32_t a) {
22− uint32_t A = a->info.bits32;
14+ Bits32 * cl = iallocate(vm, sizeof(*cl), 0);
23− VAL cl = allocate(sizeof(Closure), 1);
24 SETTY(cl, CT_BITS32);
15 SETTY(cl, CT_BITS32);
25− cl->info.bits32 = A;
16+ cl->bits32 = a;
26− return cl;
17+ return (VAL)cl;
27}
18}
28
19
29−VAL idris_b64CopyForGC(VM *vm, VAL a) {
20+VAL idris_b64const(VM *vm, uint64_t a) {
30− uint64_t A = a->info.bits64;
21+ Bits64 * cl = iallocate(vm, sizeof(*cl), 0);
31− VAL cl = allocate(sizeof(Closure), 1);
32 SETTY(cl, CT_BITS64);
22 SETTY(cl, CT_BITS64);
33− cl->info.bits64 = A;
23+ cl->bits64 = a;
34− return cl;
24+ return (VAL)cl;
35}
25}
36
26
37VAL idris_b8(VM *vm, VAL a) {
27VAL idris_b8(VM *vm, VAL a) {
38− uint8_t A = GETINT(a);
28+ return idris_b8const(vm, GETINT(a));
39− VAL cl = allocate(sizeof(Closure), 0);
40− SETTY(cl, CT_BITS8);
41− cl->info.bits8 = (uint8_t) A;
42− return cl;
43}
29}
44
30
45VAL idris_b16(VM *vm, VAL a) {
31VAL idris_b16(VM *vm, VAL a) {
46− uint16_t A = GETINT(a);
32+ return idris_b16const(vm, GETINT(a));
47− VAL cl = allocate(sizeof(Closure), 0);
48− SETTY(cl, CT_BITS16);
49− cl->info.bits16 = (uint16_t) A;
50− return cl;
51}
33}
52
34
53VAL idris_b32(VM *vm, VAL a) {
35VAL idris_b32(VM *vm, VAL a) {
54− uint32_t A = GETINT(a);
36+ return idris_b32const(vm, GETINT(a));
55− VAL cl = allocate(sizeof(Closure), 0);
56− SETTY(cl, CT_BITS32);
57− cl->info.bits32 = (uint32_t) A;
58− return cl;
59}
37}
60
38
61VAL idris_b64(VM *vm, VAL a) {
39VAL idris_b64(VM *vm, VAL a) {
62− uint64_t A = GETINT(a);
40+ return idris_b64const(vm, GETINT(a));
63− VAL cl = allocate(sizeof(Closure), 0);
64− SETTY(cl, CT_BITS64);
65− cl->info.bits64 = (uint64_t) A;
66− return cl;
67}
41}
68
42
69VAL idris_castB32Int(VM *vm, VAL a) {
43VAL idris_castB32Int(VM *vm, VAL a) {
70− return MKINT((i_int)a->info.bits32);
44+ return MKINT(GETBITS32(a));
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;
99}
45}
100
46
101VAL idris_b8Plus(VM *vm, VAL a, VAL b) {
47VAL idris_b8Plus(VM *vm, VAL a, VAL b) {
102− uint8_t A = a->info.bits8;
48+ uint8_t A = GETBITS8(a);
103− uint8_t B = b->info.bits8;
49+ uint8_t B = GETBITS8(b);
104− VAL cl = allocate(sizeof(Closure), 0);
50+ return idris_b8const(vm, A + B);
105− SETTY(cl, CT_BITS8);
106− cl->info.bits8 = A + B;
107− return cl;
108}
51}
109
52
110VAL idris_b8Minus(VM *vm, VAL a, VAL b) {
53VAL idris_b8Minus(VM *vm, VAL a, VAL b) {
111− uint8_t A = a->info.bits8;
54+ uint8_t A = GETBITS8(a);
112− uint8_t B = b->info.bits8;
55+ uint8_t B = GETBITS8(b);
113− VAL cl = allocate(sizeof(Closure), 0);
56+ return idris_b8const(vm, A - B);
114− SETTY(cl, CT_BITS8);
115− cl->info.bits8 = A - B;
116− return cl;
117}
57}
118
58
119VAL idris_b8Times(VM *vm, VAL a, VAL b) {
59VAL idris_b8Times(VM *vm, VAL a, VAL b) {
120− uint8_t A = a->info.bits8;
60+ uint8_t A = GETBITS8(a);
121− uint8_t B = b->info.bits8;
61+ uint8_t B = GETBITS8(b);
122− VAL cl = allocate(sizeof(Closure), 0);
62+ return idris_b8const(vm, A * B);
123− SETTY(cl, CT_BITS8);
124− cl->info.bits8 = A * B;
125− return cl;
126}
63}
127
64
128VAL idris_b8UDiv(VM *vm, VAL a, VAL b) {
65VAL idris_b8UDiv(VM *vm, VAL a, VAL b) {
129− uint8_t A = a->info.bits8;
66+ uint8_t A = GETBITS8(a);
130− uint8_t B = b->info.bits8;
67+ uint8_t B = GETBITS8(b);
131− VAL cl = allocate(sizeof(Closure), 0);
68+ return idris_b8const(vm, A / B);
132− SETTY(cl, CT_BITS8);
133− cl->info.bits8 = A / B;
134− return cl;
135}
69}
136
70
137VAL idris_b8SDiv(VM *vm, VAL a, VAL b) {
71VAL idris_b8SDiv(VM *vm, VAL a, VAL b) {
138− uint8_t A = a->info.bits8;
72+ int8_t A = GETBITS8(a);
139− uint8_t B = b->info.bits8;
73+ int8_t B = GETBITS8(b);
140− VAL cl = allocate(sizeof(Closure), 0);
74+ return idris_b8const(vm, A / B);
141− SETTY(cl, CT_BITS8);
142− cl->info.bits8 = (uint8_t) (((int8_t) A) / ((int8_t) B));
143− return cl;
144}
75}
145
76
146VAL idris_b8URem(VM *vm, VAL a, VAL b) {
77VAL idris_b8URem(VM *vm, VAL a, VAL b) {
147− uint8_t A = a->info.bits8;
78+ uint8_t A = GETBITS8(a);
148− uint8_t B = b->info.bits8;
79+ uint8_t B = GETBITS8(b);
149− VAL cl = allocate(sizeof(Closure), 0);
80+ return idris_b8const(vm, A % B);
150− SETTY(cl, CT_BITS8);
151− cl->info.bits8 = A % B;
152− return cl;
153}
81}
154
82
155VAL idris_b8SRem(VM *vm, VAL a, VAL b) {
83VAL idris_b8SRem(VM *vm, VAL a, VAL b) {
156− uint8_t A = a->info.bits8;
84+ int8_t A = GETBITS8(a);
157− uint8_t B = b->info.bits8;
85+ int8_t B = GETBITS8(b);
158− VAL cl = allocate(sizeof(Closure), 0);
86+ return idris_b8const(vm, A % B);
159− SETTY(cl, CT_BITS8);
160− cl->info.bits8 = (uint8_t) (((int8_t) A) % ((int8_t) B));
161− return cl;
162}
87}
163
88
164VAL idris_b8Lt(VM *vm, VAL a, VAL b) {
89VAL 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)));
166}
91}
167
92
168VAL idris_b8Gt(VM *vm, VAL a, VAL b) {
93VAL 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)));
170}
95}
171
96
172VAL idris_b8Eq(VM *vm, VAL a, VAL b) {
97VAL 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)));
174}
99}
175
100
176VAL idris_b8Lte(VM *vm, VAL a, VAL b) {
101VAL 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)));
178}
103}
179
104
180VAL idris_b8Gte(VM *vm, VAL a, VAL b) {
105VAL 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)));
182}
107}
183
108
184VAL idris_b8Compl(VM *vm, VAL a) {
109VAL idris_b8Compl(VM *vm, VAL a) {
185− uint8_t A = a->info.bits8;
110+ uint8_t A = GETBITS8(a);
186− VAL cl = allocate(sizeof(Closure), 0);
187− SETTY(cl, CT_BITS8);
188− cl->info.bits8 = ~ A;
189− return cl;
111+ return idris_b8const(vm, ~ A);
190}
112}
191
113
192VAL idris_b8And(VM *vm, VAL a, VAL b) {
114VAL idris_b8And(VM *vm, VAL a, VAL b) {
193− uint8_t A = a->info.bits8;
115+ uint8_t A = GETBITS8(a);
194− uint8_t B = b->info.bits8;
116+ uint8_t B = GETBITS8(b);
195− VAL cl = allocate(sizeof(Closure), 0);
117+ return idris_b8const(vm, A & B);
196− SETTY(cl, CT_BITS8);
197− cl->info.bits8 = A & B;
198− return cl;
199}
118}
200
119
201VAL idris_b8Or(VM *vm, VAL a, VAL b) {
120VAL idris_b8Or(VM *vm, VAL a, VAL b) {
202− uint8_t A = a->info.bits8;
121+ uint8_t A = GETBITS8(a);
203− uint8_t B = b->info.bits8;
122+ uint8_t B = GETBITS8(b);
204− VAL cl = allocate(sizeof(Closure), 0);
123+ return idris_b8const(vm, A | B);
205− SETTY(cl, CT_BITS8);
206− cl->info.bits8 = A | B;
207− return cl;
208}
124}
209
125
210VAL idris_b8Xor(VM *vm, VAL a, VAL b) {
126VAL idris_b8Xor(VM *vm, VAL a, VAL b) {
211− uint8_t A = a->info.bits8;
127+ uint8_t A = GETBITS8(a);
212− uint8_t B = b->info.bits8;
128+ uint8_t B = GETBITS8(b);
213− VAL cl = allocate(sizeof(Closure), 0);
129+ return idris_b8const(vm, A ^ B);
214− SETTY(cl, CT_BITS8);
215− cl->info.bits8 = A ^ B;
216− return cl;
217}
130}
218
131
219VAL idris_b8Shl(VM *vm, VAL a, VAL b) {
132VAL idris_b8Shl(VM *vm, VAL a, VAL b) {
220− uint8_t A = a->info.bits8;
133+ uint8_t A = GETBITS8(a);
221− uint8_t B = b->info.bits8;
134+ uint8_t B = GETBITS8(b);
222− VAL cl = allocate(sizeof(Closure), 0);
135+ return idris_b8const(vm, A << B);
223− SETTY(cl, CT_BITS8);
224− cl->info.bits8 = A << B;
225− return cl;
226}
136}
227
137
228VAL idris_b8LShr(VM *vm, VAL a, VAL b) {
138VAL idris_b8LShr(VM *vm, VAL a, VAL b) {
229− uint8_t A = a->info.bits8;
139+ uint8_t A = GETBITS8(a);
230− uint8_t B = b->info.bits8;
140+ uint8_t B = GETBITS8(b);
231− VAL cl = allocate(sizeof(Closure), 0);
141+ return idris_b8const(vm, A >> B);
232− SETTY(cl, CT_BITS8);
233− cl->info.bits8 = A >> B;
234− return cl;
235}
142}
236
143
237VAL idris_b8AShr(VM *vm, VAL a, VAL b) {
144VAL idris_b8AShr(VM *vm, VAL a, VAL b) {
238− uint8_t A = a->info.bits8;
145+ int8_t A = GETBITS8(a);
239− uint8_t B = b->info.bits8;
146+ int8_t B = GETBITS8(b);
240− VAL cl = allocate(sizeof(Closure), 0);
147+ return idris_b8const(vm, A >> B);
241− SETTY(cl, CT_BITS8);
242− cl->info.bits8 = (uint8_t) (((int8_t) A) >> ((int8_t) B));
243− return cl;
244}
148}
245
149
246VAL idris_b16Plus(VM *vm, VAL a, VAL b) {
150VAL idris_b16Plus(VM *vm, VAL a, VAL b) {
247− uint16_t A = a->info.bits16;
151+ uint16_t A = GETBITS16(a);
248− uint16_t B = b->info.bits16;
152+ uint16_t B = GETBITS16(b);
249− VAL cl = allocate(sizeof(Closure), 0);
153+ return idris_b16const(vm, A + B);
250− SETTY(cl, CT_BITS16);
251− cl->info.bits16 = A + B;
252− return cl;
253}
154}
254
155
255VAL idris_b16Minus(VM *vm, VAL a, VAL b) {
156VAL idris_b16Minus(VM *vm, VAL a, VAL b) {
256− uint16_t A = a->info.bits16;
157+ uint16_t A = GETBITS16(a);
257− uint16_t B = b->info.bits16;
158+ uint16_t B = GETBITS16(b);
258− VAL cl = allocate(sizeof(Closure), 0);
159+ return idris_b16const(vm, A - B);
259− SETTY(cl, CT_BITS16);
260− cl->info.bits16 = A - B;
261− return cl;
262}
160}
263
161
264VAL idris_b16Times(VM *vm, VAL a, VAL b) {
162VAL idris_b16Times(VM *vm, VAL a, VAL b) {
265− uint16_t A = a->info.bits16;
163+ uint16_t A = GETBITS16(a);
266− uint16_t B = b->info.bits16;
164+ uint16_t B = GETBITS16(b);
267− VAL cl = allocate(sizeof(Closure), 0);
165+ return idris_b16const(vm, A * B);
268− SETTY(cl, CT_BITS16);
269− cl->info.bits16 = A * B;
270− return cl;
271}
166}
272
167
273VAL idris_b16UDiv(VM *vm, VAL a, VAL b) {
168VAL idris_b16UDiv(VM *vm, VAL a, VAL b) {
274− uint16_t A = a->info.bits16;
169+ uint16_t A = GETBITS16(a);
275− uint16_t B = b->info.bits16;
170+ uint16_t B = GETBITS16(b);
276− VAL cl = allocate(sizeof(Closure), 0);
171+ return idris_b16const(vm, A / B);
277− SETTY(cl, CT_BITS16);
278− cl->info.bits16 = A / B;
279− return cl;
280}
172}
281
173
282VAL idris_b16SDiv(VM *vm, VAL a, VAL b) {
174VAL idris_b16SDiv(VM *vm, VAL a, VAL b) {
283− uint16_t A = a->info.bits16;
175+ int16_t A = GETBITS16(a);
284− uint16_t B = b->info.bits16;
176+ int16_t B = GETBITS16(b);
285− VAL cl = allocate(sizeof(Closure), 0);
177+ return idris_b16const(vm, A / B);
286− SETTY(cl, CT_BITS16);
287− cl->info.bits16 = (uint16_t) (((int16_t) A) / ((int16_t) B));
288− return cl;
289}
178}
290
179
291VAL idris_b16URem(VM *vm, VAL a, VAL b) {
180VAL idris_b16URem(VM *vm, VAL a, VAL b) {
292− uint16_t A = a->info.bits16;
181+ uint16_t A = GETBITS16(a);
293− uint16_t B = b->info.bits16;
182+ uint16_t B = GETBITS16(b);
294− VAL cl = allocate(sizeof(Closure), 0);
183+ return idris_b16const(vm, A % B);
295− SETTY(cl, CT_BITS16);
296− cl->info.bits16 = A % B;
297− return cl;
298}
184}
299
185
300VAL idris_b16SRem(VM *vm, VAL a, VAL b) {
186VAL idris_b16SRem(VM *vm, VAL a, VAL b) {
301− uint16_t A = a->info.bits16;
187+ int16_t A = GETBITS16(a);
302− uint16_t B = b->info.bits16;
188+ int16_t B = GETBITS16(b);
303− VAL cl = allocate(sizeof(Closure), 0);
189+ return idris_b16const(vm, A % B);
304− SETTY(cl, CT_BITS16);
305− cl->info.bits16 = (uint16_t) (((int16_t) A) % ((int16_t) B));
306− return cl;
307}
190}
308
191
309VAL idris_b16Lt(VM *vm, VAL a, VAL b) {
192VAL 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)));
311}
194}
312
195
313VAL idris_b16Gt(VM *vm, VAL a, VAL b) {
196VAL 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)));
315}
198}
316
199
317VAL idris_b16Eq(VM *vm, VAL a, VAL b) {
200VAL 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)));
319}
202}
320
203
321VAL idris_b16Lte(VM *vm, VAL a, VAL b) {
204VAL 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)));
323}
206}
324
207
325VAL idris_b16Gte(VM *vm, VAL a, VAL b) {
208VAL 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)));
327}
210}
328
211
329VAL idris_b16Compl(VM *vm, VAL a) {
212VAL idris_b16Compl(VM *vm, VAL a) {
330− uint16_t A = a->info.bits16;
213+ uint16_t A = GETBITS16(a);
331− VAL cl = allocate(sizeof(Closure), 0);
214+ return idris_b16const(vm, ~ A);
332− SETTY(cl, CT_BITS16);
333− cl->info.bits16 = ~ A;
334− return cl;
335}
215}
336
216
337VAL idris_b16And(VM *vm, VAL a, VAL b) {
217VAL idris_b16And(VM *vm, VAL a, VAL b) {
338− uint16_t A = a->info.bits16;
218+ uint16_t A = GETBITS16(a);
339− uint16_t B = b->info.bits16;
219+ uint16_t B = GETBITS16(b);
340− VAL cl = allocate(sizeof(Closure), 0);
220+ return idris_b16const(vm, A & B);
341− SETTY(cl, CT_BITS16);
342− cl->info.bits16 = A & B;
343− return cl;
344}
221}
345
222
346VAL idris_b16Or(VM *vm, VAL a, VAL b) {
223VAL idris_b16Or(VM *vm, VAL a, VAL b) {
347− uint16_t A = a->info.bits16;
224+ uint16_t A = GETBITS16(a);
348− uint16_t B = b->info.bits16;
225+ uint16_t B = GETBITS16(b);
349− VAL cl = allocate(sizeof(Closure), 0);
226+ return idris_b16const(vm, A | B);
350− SETTY(cl, CT_BITS16);
351− cl->info.bits16 = A | B;
352− return cl;
353}
227}
354
228
355VAL idris_b16Xor(VM *vm, VAL a, VAL b) {
229VAL idris_b16Xor(VM *vm, VAL a, VAL b) {
356− uint16_t A = a->info.bits16;
230+ uint16_t A = GETBITS16(a);
357− uint16_t B = b->info.bits16;
231+ uint16_t B = GETBITS16(b);
358− VAL cl = allocate(sizeof(Closure), 0);
232+ return idris_b16const(vm, A ^ B);
359− SETTY(cl, CT_BITS16);
360− cl->info.bits16 = A ^ B;
361− return cl;
362}
233}
363
234
364VAL idris_b16Shl(VM *vm, VAL a, VAL b) {
235VAL idris_b16Shl(VM *vm, VAL a, VAL b) {
365− uint16_t A = a->info.bits16;
236+ uint16_t A = GETBITS16(a);
366− uint16_t B = b->info.bits16;
237+ uint16_t B = GETBITS16(b);
367− VAL cl = allocate(sizeof(Closure), 0);
238+ return idris_b16const(vm, A << B);
368− SETTY(cl, CT_BITS16);
369− cl->info.bits16 = A << B;
370− return cl;
371}
239}
372
240
373VAL idris_b16LShr(VM *vm, VAL a, VAL b) {
241VAL idris_b16LShr(VM *vm, VAL a, VAL b) {
374− uint16_t A = a->info.bits16;
242+ uint16_t A = GETBITS16(a);
375− uint16_t B = b->info.bits16;
243+ uint16_t B = GETBITS16(b);
376− VAL cl = allocate(sizeof(Closure), 0);
244+ return idris_b16const(vm, A >> B);
377− SETTY(cl, CT_BITS16);
378− cl->info.bits16 = A >> B;
379− return cl;
380}
245}
381
246
382VAL idris_b16AShr(VM *vm, VAL a, VAL b) {
247VAL idris_b16AShr(VM *vm, VAL a, VAL b) {
383− uint16_t A = a->info.bits16;
248+ int16_t A = GETBITS16(a);
384− uint16_t B = b->info.bits16;
249+ int16_t B = GETBITS16(b);
385− VAL cl = allocate(sizeof(Closure), 0);
250+ return idris_b16const(vm, A >> B);
386− SETTY(cl, CT_BITS16);
387− cl->info.bits16 = (uint16_t) (((int16_t) A) >> ((int16_t) B));
388− return cl;
389}
251}
390
252
391VAL idris_b32Plus(VM *vm, VAL a, VAL b) {
253VAL idris_b32Plus(VM *vm, VAL a, VAL b) {
392− uint32_t A = a->info.bits32;
254+ uint32_t A = GETBITS32(a);
393− uint32_t B = b->info.bits32;
255+ uint32_t B = GETBITS32(b);
394− VAL cl = allocate(sizeof(Closure), 0);
256+ return idris_b32const(vm, A + B);
395− SETTY(cl, CT_BITS32);
396− cl->info.bits32 = A + B;
397− return cl;
398}
257}
399
258
400VAL idris_b32Minus(VM *vm, VAL a, VAL b) {
259VAL idris_b32Minus(VM *vm, VAL a, VAL b) {
401− uint32_t A = a->info.bits32;
260+ uint32_t A = GETBITS32(a);
402− uint32_t B = b->info.bits32;
261+ uint32_t B = GETBITS32(b);
403− VAL cl = allocate(sizeof(Closure), 0);
262+ return idris_b32const(vm, A - B);
404− SETTY(cl, CT_BITS32);
405− cl->info.bits32 = A - B;
406− return cl;
407}
263}
408
264
409VAL idris_b32Times(VM *vm, VAL a, VAL b) {
265VAL idris_b32Times(VM *vm, VAL a, VAL b) {
410− uint32_t A = a->info.bits32;
266+ uint32_t A = GETBITS32(a);
411− uint32_t B = b->info.bits32;
267+ uint32_t B = GETBITS32(b);
412− VAL cl = allocate(sizeof(Closure), 0);
268+ return idris_b32const(vm, A * B);
413− SETTY(cl, CT_BITS32);
414− cl->info.bits32 = A * B;
415− return cl;
416}
269}
417
270
418VAL idris_b32UDiv(VM *vm, VAL a, VAL b) {
271VAL idris_b32UDiv(VM *vm, VAL a, VAL b) {
419− uint32_t A = a->info.bits32;
272+ uint32_t A = GETBITS32(a);
420− uint32_t B = b->info.bits32;
273+ uint32_t B = GETBITS32(b);
421− VAL cl = allocate(sizeof(Closure), 0);
274+ return idris_b32const(vm, A / B);
422− SETTY(cl, CT_BITS32);
423− cl->info.bits32 = A / B;
424− return cl;
425}
275}
426
276
427VAL idris_b32SDiv(VM *vm, VAL a, VAL b) {
277VAL idris_b32SDiv(VM *vm, VAL a, VAL b) {
428− uint32_t A = a->info.bits32;
278+ int32_t A = GETBITS32(a);
429− uint32_t B = b->info.bits32;
279+ int32_t B = GETBITS32(b);
430− VAL cl = allocate(sizeof(Closure), 0);
280+ return idris_b32const(vm, A / B);
431− SETTY(cl, CT_BITS32);
432− cl->info.bits32 = (uint32_t) (((int32_t) A) / ((int32_t) B));
433− return cl;
434}
281}
435
282
436VAL idris_b32URem(VM *vm, VAL a, VAL b) {
283VAL idris_b32URem(VM *vm, VAL a, VAL b) {
437− uint32_t A = a->info.bits32;
284+ uint32_t A = GETBITS32(a);
438− uint32_t B = b->info.bits32;
285+ uint32_t B = GETBITS32(b);
439− VAL cl = allocate(sizeof(Closure), 0);
286+ return idris_b32const(vm, A % B);
440− SETTY(cl, CT_BITS32);
441− cl->info.bits32 = A % B;
442− return cl;
443}
287}
444
288
445VAL idris_b32SRem(VM *vm, VAL a, VAL b) {
289VAL idris_b32SRem(VM *vm, VAL a, VAL b) {
446− uint32_t A = a->info.bits32;
290+ int32_t A = GETBITS32(a);
447− uint32_t B = b->info.bits32;
291+ int32_t B = GETBITS32(b);
448− VAL cl = allocate(sizeof(Closure), 0);
292+ return idris_b32const(vm, A % B);
449− SETTY(cl, CT_BITS32);
450− cl->info.bits32 = (uint32_t) (((int32_t) A) % ((int32_t) B));
451− return cl;
452}
293}
453
294
454VAL idris_b32Lt(VM *vm, VAL a, VAL b) {
295VAL 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)));
456}
297}
457
298
458VAL idris_b32Gt(VM *vm, VAL a, VAL b) {
299VAL 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)));
460}
301}
461
302
462VAL idris_b32Eq(VM *vm, VAL a, VAL b) {
303VAL 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)));
464}
305}
465
306
466VAL idris_b32Lte(VM *vm, VAL a, VAL b) {
307VAL 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)));
468}
309}
469
310
470VAL idris_b32Gte(VM *vm, VAL a, VAL b) {
311VAL 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)));
472}
313}
473
314
474VAL idris_b32Compl(VM *vm, VAL a) {
315VAL idris_b32Compl(VM *vm, VAL a) {
475− uint32_t A = a->info.bits32;
316+ uint32_t A = GETBITS32(a);
476− VAL cl = allocate(sizeof(Closure), 0);
317+ return idris_b32const(vm, ~ A);
477− SETTY(cl, CT_BITS32);
478− cl->info.bits32 = ~ A;
479− return cl;
480}
318}
481
319
482VAL idris_b32And(VM *vm, VAL a, VAL b) {
320VAL idris_b32And(VM *vm, VAL a, VAL b) {
483− uint32_t A = a->info.bits32;
321+ uint32_t A = GETBITS32(a);
484− uint32_t B = b->info.bits32;
322+ uint32_t B = GETBITS32(b);
485− VAL cl = allocate(sizeof(Closure), 0);
323+ return idris_b32const(vm, A & B);
486− SETTY(cl, CT_BITS32);
487− cl->info.bits32 = A & B;
488− return cl;
489}
324}
490
325
491VAL idris_b32Or(VM *vm, VAL a, VAL b) {
326VAL idris_b32Or(VM *vm, VAL a, VAL b) {
492− uint32_t A = a->info.bits32;
327+ uint32_t A = GETBITS32(a);
493− uint32_t B = b->info.bits32;
328+ uint32_t B = GETBITS32(b);
494− VAL cl = allocate(sizeof(Closure), 0);
329+ return idris_b32const(vm, A | B);
495− SETTY(cl, CT_BITS32);
496− cl->info.bits32 = A | B;
497− return cl;
498}
330}
499
331
500VAL idris_b32Xor(VM *vm, VAL a, VAL b) {
332VAL idris_b32Xor(VM *vm, VAL a, VAL b) {
501− uint32_t A = a->info.bits32;
333+ uint32_t A = GETBITS32(a);
502− uint32_t B = b->info.bits32;
334+ uint32_t B = GETBITS32(b);
503− VAL cl = allocate(sizeof(Closure), 0);
335+ return idris_b32const(vm, A ^ B);
504− SETTY(cl, CT_BITS32);
505− cl->info.bits32 = A ^ B;
506− return cl;
507}
336}
508
337
509VAL idris_b32Shl(VM *vm, VAL a, VAL b) {
338VAL idris_b32Shl(VM *vm, VAL a, VAL b) {
510− uint32_t A = a->info.bits32;
339+ uint32_t A = GETBITS32(a);
511− uint32_t B = b->info.bits32;
340+ uint32_t B = GETBITS32(b);
512− VAL cl = allocate(sizeof(Closure), 0);
341+ return idris_b32const(vm, A << B);
513− SETTY(cl, CT_BITS32);
514− cl->info.bits32 = A << B;
515− return cl;
516}
342}
517
343
518VAL idris_b32LShr(VM *vm, VAL a, VAL b) {
344VAL idris_b32LShr(VM *vm, VAL a, VAL b) {
519− uint32_t A = a->info.bits32;
345+ uint32_t A = GETBITS32(a);
520− uint32_t B = b->info.bits32;
346+ uint32_t B = GETBITS32(b);
521− VAL cl = allocate(sizeof(Closure), 0);
347+ return idris_b32const(vm, A >> B);
522− SETTY(cl, CT_BITS32);
523− cl->info.bits32 = A >> B;
524− return cl;
525}
348}
526
349
527VAL idris_b32AShr(VM *vm, VAL a, VAL b) {
350VAL idris_b32AShr(VM *vm, VAL a, VAL b) {
528− uint32_t A = a->info.bits32;
351+ int32_t A = GETBITS32(a);
529− uint32_t B = b->info.bits32;
352+ int32_t B = GETBITS32(b);
530− VAL cl = allocate(sizeof(Closure), 0);
353+ return idris_b32const(vm, A >> B);
531− SETTY(cl, CT_BITS32);
532− cl->info.bits32 = (uint32_t) (((int32_t)A) >> ((int32_t)B));
533− return cl;
534}
354}
535
355
536VAL idris_b64Plus(VM *vm, VAL a, VAL b) {
356VAL idris_b64Plus(VM *vm, VAL a, VAL b) {
537− uint64_t A = a->info.bits64;
357+ uint64_t A = GETBITS64(a);
538− uint64_t B = b->info.bits64;
358+ uint64_t B = GETBITS64(b);
539− VAL cl = allocate(sizeof(Closure), 0);
359+ return idris_b64const(vm, A + B);
540− SETTY(cl, CT_BITS64);
541− cl->info.bits64 = A + B;
542− return cl;
543}
360}
544
361
545VAL idris_b64Minus(VM *vm, VAL a, VAL b) {
362VAL idris_b64Minus(VM *vm, VAL a, VAL b) {
546− uint64_t A = a->info.bits64;
363+ uint64_t A = GETBITS64(a);
547− uint64_t B = b->info.bits64;
364+ uint64_t B = GETBITS64(b);
548− VAL cl = allocate(sizeof(Closure), 0);
365+ return idris_b64const(vm, A - B);
549− SETTY(cl, CT_BITS64);
550− cl->info.bits64 = A - B;
551− return cl;
552}
366}
553
367
554VAL idris_b64Times(VM *vm, VAL a, VAL b) {
368VAL idris_b64Times(VM *vm, VAL a, VAL b) {
555− uint64_t A = a->info.bits64;
369+ uint64_t A = GETBITS64(a);
556− uint64_t B = b->info.bits64;
370+ uint64_t B = GETBITS64(b);
557− VAL cl = allocate(sizeof(Closure), 0);
371+ return idris_b64const(vm, A * B);
558− SETTY(cl, CT_BITS64);
559− cl->info.bits64 = A * B;
560− return cl;
561}
372}
562
373
563VAL idris_b64UDiv(VM *vm, VAL a, VAL b) {
374VAL idris_b64UDiv(VM *vm, VAL a, VAL b) {
564− uint64_t A = a->info.bits64;
375+ uint64_t A = GETBITS64(a);
565− uint64_t B = b->info.bits64;
376+ uint64_t B = GETBITS64(b);
566− VAL cl = allocate(sizeof(Closure), 0);
377+ return idris_b64const(vm, A / B);
567− SETTY(cl, CT_BITS64);
568− cl->info.bits64 = A / B;
569− return cl;
570}
378}
571
379
572VAL idris_b64SDiv(VM *vm, VAL a, VAL b) {
380VAL idris_b64SDiv(VM *vm, VAL a, VAL b) {
573− uint64_t A = a->info.bits64;
381+ int64_t A = GETBITS64(a);
574− uint64_t B = b->info.bits64;
382+ int64_t B = GETBITS64(b);
575− VAL cl = allocate(sizeof(Closure), 0);
383+ return idris_b64const(vm, A / B);
576− SETTY(cl, CT_BITS64);
577− cl->info.bits64 = (uint64_t) (((int64_t) A) / ((int64_t) B));
578− return cl;
579}
384}
580
385
581VAL idris_b64URem(VM *vm, VAL a, VAL b) {
386VAL idris_b64URem(VM *vm, VAL a, VAL b) {
582− uint64_t A = a->info.bits64;
387+ uint64_t A = GETBITS64(a);
583− uint64_t B = b->info.bits64;
388+ uint64_t B = GETBITS64(b);
584− VAL cl = allocate(sizeof(Closure), 0);
389+ return idris_b64const(vm, A % B);
585− SETTY(cl, CT_BITS64);
586− cl->info.bits64 = A % B;
587− return cl;
588}
390}
589
391
590VAL idris_b64SRem(VM *vm, VAL a, VAL b) {
392VAL idris_b64SRem(VM *vm, VAL a, VAL b) {
591− uint64_t A = a->info.bits64;
393+ int64_t A = GETBITS64(a);
592− uint64_t B = b->info.bits64;
394+ int64_t B = GETBITS64(b);
593− VAL cl = allocate(sizeof(Closure), 0);
395+ return idris_b64const(vm, A % B);
594− SETTY(cl, CT_BITS64);
595− cl->info.bits64 = (uint64_t) (((int64_t) A) % ((int64_t) B));
596− return cl;
597}
396}
598
397
599VAL idris_b64Lt(VM *vm, VAL a, VAL b) {
398VAL idris_b64Lt(VM *vm, VAL a, VAL b) {
399+ uint64_t A = GETBITS64(a);
400+ uint64_t B = GETBITS64(b);
600− return MKINT((i_int) (a->info.bits64 < b->info.bits64));
401+ return MKINT((i_int) (A < B));
601}
402}
602
403
603VAL idris_b64Gt(VM *vm, VAL a, VAL b) {
404VAL idris_b64Gt(VM *vm, VAL a, VAL b) {
405+ uint64_t A = GETBITS64(a);
406+ uint64_t B = GETBITS64(b);
604− return MKINT((i_int) (a->info.bits64 > b->info.bits64));
407+ return MKINT((i_int) (A > B));
605}
408}
606
409
607VAL idris_b64Eq(VM *vm, VAL a, VAL b) {
410VAL idris_b64Eq(VM *vm, VAL a, VAL b) {
411+ uint64_t A = GETBITS64(a);
412+ uint64_t B = GETBITS64(b);
608− return MKINT((i_int) (a->info.bits64 == b->info.bits64));
413+ return MKINT((i_int) (A == B));
609}
414}
610
415
611VAL idris_b64Lte(VM *vm, VAL a, VAL b) {
416VAL idris_b64Lte(VM *vm, VAL a, VAL b) {
417+ uint64_t A = GETBITS64(a);
418+ uint64_t B = GETBITS64(b);
612− return MKINT((i_int) (a->info.bits64 <= b->info.bits64));
419+ return MKINT((i_int) (A <= B));
613}
420}
614
421
615VAL idris_b64Gte(VM *vm, VAL a, VAL b) {
422VAL idris_b64Gte(VM *vm, VAL a, VAL b) {
423+ uint64_t A = GETBITS64(a);
424+ uint64_t B = GETBITS64(b);
616− return MKINT((i_int) (a->info.bits64 >= b->info.bits64));
425+ return MKINT((i_int) (A >= B));
617}
426}
618
427
619VAL idris_b64Compl(VM *vm, VAL a) {
428VAL idris_b64Compl(VM *vm, VAL a) {
620− uint64_t A = a->info.bits64;
429+ uint64_t A = GETBITS64(a);
621− VAL cl = allocate(sizeof(Closure), 0);
430+ return idris_b64const(vm, ~ A);
622− SETTY(cl, CT_BITS64);
623− cl->info.bits64 = ~ A;
624− return cl;
625}
431}
626
432
627VAL idris_b64And(VM *vm, VAL a, VAL b) {
433VAL idris_b64And(VM *vm, VAL a, VAL b) {
628− uint64_t A = a->info.bits64;
434+ uint64_t A = GETBITS64(a);
629− uint64_t B = b->info.bits64;
435+ uint64_t B = GETBITS64(b);
630− VAL cl = allocate(sizeof(Closure), 0);
436+ return idris_b64const(vm, A & B);
631− SETTY(cl, CT_BITS64);
632− cl->info.bits64 = A & B;
633− return cl;
634}
437}
635
438
636VAL idris_b64Or(VM *vm, VAL a, VAL b) {
439VAL idris_b64Or(VM *vm, VAL a, VAL b) {
637− uint64_t A = a->info.bits64;
440+ uint64_t A = GETBITS64(a);
638− uint64_t B = b->info.bits64;
441+ uint64_t B = GETBITS64(b);
639− VAL cl = allocate(sizeof(Closure), 0);
442+ return idris_b64const(vm, A | B);
640− SETTY(cl, CT_BITS64);
641− cl->info.bits64 = A | B;
642− return cl;
643}
443}
644
444
645VAL idris_b64Xor(VM *vm, VAL a, VAL b) {
445VAL idris_b64Xor(VM *vm, VAL a, VAL b) {
646− uint64_t A = a->info.bits64;
446+ uint64_t A = GETBITS64(a);
647− uint64_t B = b->info.bits64;
447+ uint64_t B = GETBITS64(b);
648− VAL cl = allocate(sizeof(Closure), 0);
448+ return idris_b64const(vm, A ^ B);
649− SETTY(cl, CT_BITS64);
650− cl->info.bits64 = A ^ B;
651− return cl;
652}
449}
653
450
654VAL idris_b64Shl(VM *vm, VAL a, VAL b) {
451VAL idris_b64Shl(VM *vm, VAL a, VAL b) {
655− uint64_t A = a->info.bits64;
452+ uint64_t A = GETBITS64(a);
656− uint64_t B = b->info.bits64;
453+ uint64_t B = GETBITS64(b);
657− VAL cl = allocate(sizeof(Closure), 0);
454+ return idris_b64const(vm, A << B);
658− SETTY(cl, CT_BITS64);
659− cl->info.bits64 = A << B;
660− return cl;
661}
455}
662
456
663VAL idris_b64LShr(VM *vm, VAL a, VAL b) {
457VAL idris_b64LShr(VM *vm, VAL a, VAL b) {
664− uint64_t A = a->info.bits64;
458+ uint64_t A = GETBITS64(a);
665− uint64_t B = b->info.bits64;
459+ uint64_t B = GETBITS64(b);
666− VAL cl = allocate(sizeof(Closure), 0);
460+ return idris_b64const(vm, A >> B);
667− SETTY(cl, CT_BITS64);
668− cl->info.bits64 = A >> B;
669− return cl;
670}
461}
671
462
672VAL idris_b64AShr(VM *vm, VAL a, VAL b) {
463VAL idris_b64AShr(VM *vm, VAL a, VAL b) {
673− uint64_t A = a->info.bits64;
464+ int64_t A = GETBITS64(a);
674− uint64_t B = b->info.bits64;
465+ int64_t B = GETBITS64(b);
675− VAL cl = allocate(sizeof(Closure), 0);
466+ return idris_b64const(vm, A >> B);
676− SETTY(cl, CT_BITS64);
677− cl->info.bits64 = (uint64_t) (((int64_t) A) >> ((int64_t) B));
678− return cl;
679}
467}
680
468
681VAL idris_b8Z16(VM *vm, VAL a) {
469VAL idris_b8Z16(VM *vm, VAL a) {
682− uint8_t A = a->info.bits8;
470+ uint8_t A = GETBITS8(a);
683− VAL cl = allocate(sizeof(Closure), 0);
471+ return idris_b16const(vm, A);
684− SETTY(cl, CT_BITS16);
685− cl->info.bits16 = (uint16_t) A;
686− return cl;
687}
472}
688
473
689VAL idris_b8Z32(VM *vm, VAL a) {
474VAL idris_b8Z32(VM *vm, VAL a) {
690− uint8_t A = a->info.bits8;
475+ uint8_t A = GETBITS8(a);
691− VAL cl = allocate(sizeof(Closure), 0);
476+ return idris_b32const(vm, A);
692− SETTY(cl, CT_BITS32);
693− cl->info.bits32 = (uint32_t) A;
694− return cl;
695}
477}
696
478
697VAL idris_b8Z64(VM *vm, VAL a) {
479VAL idris_b8Z64(VM *vm, VAL a) {
698− uint8_t A = a->info.bits8;
480+ uint8_t A = GETBITS8(a);
699− VAL cl = allocate(sizeof(Closure), 0);
481+ return idris_b64const(vm, A);
700− SETTY(cl, CT_BITS64);
701− cl->info.bits64 = (uint64_t) A;
702− return cl;
703}
482}
704
483
705VAL idris_b8S16(VM *vm, VAL a) {
484VAL idris_b8S16(VM *vm, VAL a) {
706− uint8_t A = a->info.bits8;
485+ int8_t A = GETBITS8(a);
707− VAL cl = allocate(sizeof(Closure), 0);
486+ return idris_b16const(vm, (int16_t) A);
708− SETTY(cl, CT_BITS16);
709− cl->info.bits16 = (uint16_t) (int16_t) (int8_t) A;
710− return cl;
711}
487}
712
488
713VAL idris_b8S32(VM *vm, VAL a) {
489VAL idris_b8S32(VM *vm, VAL a) {
714− uint8_t A = a->info.bits8;
490+ int8_t A = GETBITS8(a);
715− VAL cl = allocate(sizeof(Closure), 0);
491+ return idris_b32const(vm, (int32_t) A);
716− SETTY(cl, CT_BITS32);
717− cl->info.bits32 = (uint32_t) (int32_t) (int8_t) A;
718− return cl;
719}
492}
720
493
721VAL idris_b8S64(VM *vm, VAL a) {
494VAL idris_b8S64(VM *vm, VAL a) {
722− uint8_t A = a->info.bits8;
495+ int8_t A = GETBITS8(a);
723− VAL cl = allocate(sizeof(Closure), 0);
496+ return idris_b64const(vm, (int64_t) A);
724− SETTY(cl, CT_BITS64);
725− cl->info.bits64 = (uint64_t) (int64_t) (int8_t) A;
726− return cl;
727}
497}
728
498
729VAL idris_b16Z32(VM *vm, VAL a) {
499VAL idris_b16Z32(VM *vm, VAL a) {
730− uint16_t A = a->info.bits16;
500+ uint16_t A = GETBITS16(a);
731− VAL cl = allocate(sizeof(Closure), 0);
501+ return idris_b32const(vm, (uint32_t) A);
732− SETTY(cl, CT_BITS32);
733− cl->info.bits32 = (uint32_t) A;
734− return cl;
735}
502}
736
503
737VAL idris_b16Z64(VM *vm, VAL a) {
504VAL idris_b16Z64(VM *vm, VAL a) {
738− uint16_t A = a->info.bits16;
505+ uint16_t A = GETBITS16(a);
739− VAL cl = allocate(sizeof(Closure), 0);
506+ return idris_b64const(vm, (uint64_t) A);
740− SETTY(cl, CT_BITS64);
741− cl->info.bits64 = (uint64_t) A;
742− return cl;
743}
507}
744
508
745VAL idris_b16S32(VM *vm, VAL a) {
509VAL idris_b16S32(VM *vm, VAL a) {
746− uint16_t A = a->info.bits16;
510+ int16_t A = GETBITS16(a);
747− VAL cl = allocate(sizeof(Closure), 0);
511+ return idris_b32const(vm, (int32_t) A);
748− SETTY(cl, CT_BITS32);
749− cl->info.bits32 = (uint32_t) (int32_t) (int16_t) A;
750− return cl;
751}
512}
752
513
753VAL idris_b16S64(VM *vm, VAL a) {
514VAL idris_b16S64(VM *vm, VAL a) {
754− uint16_t A = a->info.bits16;
515+ int16_t A = GETBITS16(a);
755− VAL cl = allocate(sizeof(Closure), 0);
516+ return idris_b64const(vm, (int64_t) A);
756− SETTY(cl, CT_BITS64);
757− cl->info.bits64 = (uint64_t) (int64_t) (int16_t) A;
758− return cl;
759}
517}
760
518
761VAL idris_b16T8(VM *vm, VAL a) {
519VAL idris_b16T8(VM *vm, VAL a) {
762− uint16_t A = a->info.bits16;
520+ uint16_t A = GETBITS16(a);
763− VAL cl = allocate(sizeof(Closure), 0);
521+ return idris_b8const(vm, (uint8_t) A);
764− SETTY(cl, CT_BITS8);
765− cl->info.bits8 = (uint8_t) A;
766− return cl;
767}
522}
768
523
769VAL idris_b32Z64(VM *vm, VAL a) {
524VAL idris_b32Z64(VM *vm, VAL a) {
770− uint32_t A = a->info.bits32;
525+ uint32_t A = GETBITS32(a);
771− VAL cl = allocate(sizeof(Closure), 0);
526+ return idris_b64const(vm, (uint64_t) A);
772− SETTY(cl, CT_BITS64);
773− cl->info.bits64 = (uint64_t) A;
774− return cl;
775}
527}
776
528
777VAL idris_b32S64(VM *vm, VAL a) {
529VAL idris_b32S64(VM *vm, VAL a) {
778− uint32_t A = a->info.bits32;
530+ int32_t A = GETBITS32(a);
779− VAL cl = allocate(sizeof(Closure), 0);
531+ return idris_b64const(vm, (int64_t) A);
780− SETTY(cl, CT_BITS64);
781− cl->info.bits64 = (uint64_t) (int64_t) (int32_t) A;
782− return cl;
783}
532}
784
533
785VAL idris_b32T8(VM *vm, VAL a) {
534VAL idris_b32T8(VM *vm, VAL a) {
786− uint32_t A = a->info.bits32;
535+ uint32_t A = GETBITS32(a);
787− VAL cl = allocate(sizeof(Closure), 0);
536+ return idris_b8const(vm, (uint8_t) A);
788− SETTY(cl, CT_BITS8);
789− cl->info.bits8 = (uint8_t) A;
790− return cl;
791}
537}
792
538
793VAL idris_b32T16(VM *vm, VAL a) {
539VAL idris_b32T16(VM *vm, VAL a) {
794− uint32_t A = a->info.bits32;
540+ uint32_t A = GETBITS32(a);
795− VAL cl = allocate(sizeof(Closure), 0);
541+ return idris_b16const(vm, (uint16_t) A);
796− SETTY(cl, CT_BITS16);
797− cl->info.bits16 = (uint16_t) A;
798− return cl;
799}
542}
800
543
801VAL idris_b64T8(VM *vm, VAL a) {
544VAL idris_b64T8(VM *vm, VAL a) {
802− uint64_t A = a->info.bits64;
545+ uint64_t A = GETBITS64(a);
803− VAL cl = allocate(sizeof(Closure), 0);
546+ return idris_b8const(vm, (uint8_t) A);
804− SETTY(cl, CT_BITS8);
805− cl->info.bits8 = (uint8_t) A;
806− return cl;
807}
547}
808
548
809VAL idris_b64T16(VM *vm, VAL a) {
549VAL idris_b64T16(VM *vm, VAL a) {
810− uint64_t A = a->info.bits64;
550+ uint64_t A = GETBITS64(a);
811− VAL cl = allocate(sizeof(Closure), 0);
551+ return idris_b16const(vm, (uint16_t) A);
812− SETTY(cl, CT_BITS16);
813− cl->info.bits16 = (uint16_t) A;
814− return cl;
815}
552}
816
553
817VAL idris_b64T32(VM *vm, VAL a) {
554VAL idris_b64T32(VM *vm, VAL a) {
818− uint64_t A = a->info.bits64;
555+ uint64_t A = GETBITS64(a);
819− VAL cl = allocate(sizeof(Closure), 0);
556+ return idris_b32const(vm, (uint32_t) A);
820− SETTY(cl, CT_BITS32);
821− cl->info.bits32 = (uint32_t) A;
822− return cl;
823}
557}
824
558
825VAL idris_peekB8(VM* vm, VAL ptr, VAL offset) {
559VAL idris_peekB8(VM* vm, VAL ptr, VAL offset) {
rts/idris_bitstring.h−5
@@ -1,11 +1,6 @@
1#ifndef _IDRISBITSTRING_H
1#ifndef _IDRISBITSTRING_H
2#define _IDRISBITSTRING_H
2#define _IDRISBITSTRING_H
3
3
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−
9VAL idris_b8(VM *vm, VAL a);
4VAL idris_b8(VM *vm, VAL a);
10VAL idris_b16(VM *vm, VAL a);
5VAL idris_b16(VM *vm, VAL a);
11VAL idris_b32(VM *vm, VAL a);
6VAL idris_b32(VM *vm, VAL a);
rts/idris_buffer.c+5−19
@@ -82,9 +82,9 @@ uint8_t idris_getBufferByte(void* buffer, int loc) {
82int idris_getBufferInt(void* buffer, int loc) {
82int idris_getBufferInt(void* buffer, int loc) {
83 Buffer* b = buffer;
83 Buffer* b = buffer;
84 if (loc >= 0 && loc+3 < b->size) {
84 if (loc >= 0 && loc+3 < b->size) {
85− return b->data[loc] +
85+ return b->data[loc] +
86 (b->data[loc+1] << 8) +
86 (b->data[loc+1] << 8) +
87− (b->data[loc+2] << 16) +
87+ (b->data[loc+2] << 16) +
88 (b->data[loc+3] << 24);
88 (b->data[loc+3] << 24);
89 } else {
89 } else {
90 return 0;
90 return 0;
@@ -110,22 +110,9 @@ double idris_getBufferDouble(void* buffer, int loc) {
110
110
111VAL idris_getBufferString(void* buffer, int loc, int len) {
111VAL idris_getBufferString(void* buffer, int loc, int len) {
112 Buffer* b = buffer;
112 Buffer* b = buffer;
113−
113+ char * s = (char*)(b->data + loc);
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) {
114+ size_t sz = loc >= 0 && loc+len <= b->size? len : 0;
120− memcpy(cl->info.str.str, (b->data)+loc, len);
115+ return MKSTRlen(get_vm(), s, sz);
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;
129}
116}
130
117
131int idris_readBuffer(FILE* h, void* buffer, int loc, int max) {
118int 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) {
153 fwrite((b->data)+loc, sizeof(uint8_t), len, h);
140 fwrite((b->data)+loc, sizeof(uint8_t), len, h);
154 }
141 }
155}
142}
156−
rts/idris_gc.c+49−68
@@ -4,116 +4,97 @@
4#include "idris_bitstring.h"
4#include "idris_bitstring.h"
5#include <assert.h>
5#include <assert.h>
6
6
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+
7VAL copy(VM* vm, VAL x) {
13VAL copy(VM* vm, VAL x) {
8− int ar, len;
14+ int ar;
9− Closure* cl = NULL;
15+ VAL cl;
10− if (x==NULL || ISINT(x)) {
16+ if (x==NULL) {
11 return x;
17 return x;
12 }
18 }
13 switch(GETTY(x)) {
19 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;
14 case CT_CON:
33 case CT_CON:
15 ar = CARITY(x);
34 ar = CARITY(x);
16 if (ar == 0 && CTAG(x) < 256) {
35 if (ar == 0 && CTAG(x) < 256) {
17 return x;
36 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);
21 }
37 }
22− break;
38+ // FALLTHROUGH
23 case CT_ARRAY:
39 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;
31 case CT_STRING:
40 case CT_STRING:
32− cl = MKSTRclen(vm, x->info.str.str, x->info.str.len);
41+ case CT_REF:
33− break;
34 case CT_STROFFSET:
42 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;
40 case CT_PTR:
43 case CT_PTR:
41− cl = MKPTRc(vm, x->info.ptr);
42− break;
43 case CT_MANAGEDPTR:
44 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;
63 case CT_RAWDATA:
45 case CT_RAWDATA:
64− {
46+ cl = copy_plain(vm, x, x->hdr.sz);
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);
73 break;
47 break;
74 default:
48 default:
49+ cl = NULL;
50+ assert(0);
75 break;
51 break;
76 }
52 }
53+ assert(x->hdr.sz >= sizeof(Fwd));
77 SETTY(x, CT_FWD);
54 SETTY(x, CT_FWD);
78− x->info.ptr = cl;
55+ ((Fwd*)x)->fwd = cl;
79 return cl;
56 return cl;
80}
57}
81
58
82void cheney(VM *vm) {
59void cheney(VM *vm) {
83− int i;
84− int ar, len;
85 char* scan = aligned_heap_pointer(vm->heap.heap);
60 char* scan = aligned_heap_pointer(vm->heap.heap);
86
61
87 while(scan < vm->heap.next) {
62 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;
90 // If it's a CT_CON, CT_REF or CT_STROFFSET, copy its arguments
64 // If it's a CT_CON, CT_REF or CT_STROFFSET, copy its arguments
91 switch(GETTY(heap_item)) {
65 switch(GETTY(heap_item)) {
92 case CT_CON:
66 case CT_CON:
67+ {
93− ar = ARITY(heap_item);
68+ Con * c = (Con*)heap_item;
69+ size_t len = CARITY(c);
94− for(i = 0; i < ar; ++i) {
70+ for(size_t i = 0; i < len; ++i)
95− VAL newptr = copy(vm, heap_item->info.c.args[i]);
71+ c->args[i] = copy(vm, c->args[i]);
96− heap_item->info.c.args[i] = newptr;
97 }
72 }
98 break;
73 break;
99 case CT_ARRAY:
74 case CT_ARRAY:
100− len = heap_item->info.arr.length;
75+ {
76+ Array * a = (Array*)heap_item;
77+ size_t len = CELEM(a);
101− for(i = 0; i < len; ++i) {
78+ for(size_t i = 0; i < len; ++i)
102− VAL newptr = copy(vm, heap_item->info.arr.content[i]);
79+ a->array[i] = copy(vm, a->array[i]);
103− heap_item->info.arr.content[i] = newptr;
104 }
80 }
105 break;
81 break;
106 case CT_REF:
82 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+ }
108 break;
87 break;
109 case CT_STROFFSET:
88 case CT_STROFFSET:
110− heap_item->info.str_offset->str
89+ {
111− = copy(vm, heap_item->info.str_offset->str);
90+ StrOffset * s = (StrOffset*)heap_item;
91+ s->base = (String*)copy(vm, (VAL)s->base);
92+ }
112 break;
93 break;
113 default: // Nothing to copy
94 default: // Nothing to copy
114 break;
95 break;
115 }
96 }
116− scan += inc;
97+ scan += aligned(valSize(heap_item));
117 }
98 }
118 assert(scan == vm->heap.next);
99 assert(scan == vm->heap.next);
119}
100}
rts/idris_gmp.c+87−218
@@ -22,249 +22,126 @@ VAL MKBIGI(int val) {
22 return MKINT((i_int)val);
22 return MKINT((i_int)val);
23}
23}
24
24
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+
25VAL MKBIGC(VM* vm, char* val) {
34VAL MKBIGC(VM* vm, char* val) {
26 if (*val == '\0') {
35 if (*val == '\0') {
27 return MKBIGI(0);
36 return MKBIGI(0);
28 }
37 }
29 else {
38 else {
30− idris_requireAlloc(IDRIS_MAXGMP);
39+ BigInt * cl = allocBig(vm);
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);
40+ mpz_set_str(*getmpz(cl), val, 10);
39−
40− SETTY(cl, CT_BIGINT);
41− cl -> info.ptr = (void*)bigint;
42−
43− return cl;
41+ return (VAL)cl;
44 }
42 }
45}
43}
46
44
47−VAL MKBIGM(VM* vm, void* big) {
45+VAL MKBIGM(VM* vm, void* ibig) {
48− idris_requireAlloc(IDRIS_MAXGMP);
46+ BigInt * cl = allocBig(vm);
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));
47+ mpz_set(*getmpz(cl), *((mpz_t*)ibig));
57−
58− SETTY(cl, CT_BIGINT);
59− cl -> info.ptr = (void*)bigint;
60−
61− return cl;
48+ return (VAL)cl;
62}
49}
63
50
64−VAL MKBIGMc(VM* vm, void* big) {
51+VAL MKBIGMc(VM* vm, void* ibig) {
65− idris_requireAlloc(IDRIS_MAXGMP);
52+ BigInt * cl = allocBig(vm);
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));
53+ mpz_init_set(*getmpz(cl), *((mpz_t*)ibig));
73−
74− SETTY(cl, CT_BIGINT);
75− cl -> info.ptr = (void*)bigint;
76−
77− return cl;
54+ return (VAL)cl;
78}
55}
79
56
80VAL MKBIGUI(VM* vm, unsigned long val) {
57VAL MKBIGUI(VM* vm, unsigned long val) {
81− idris_requireAlloc(IDRIS_MAXGMP);
58+ BigInt * cl = allocBig(vm);
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);
59+ mpz_init_set_ui(*getmpz(cl), val);
89−
90− SETTY(cl, CT_BIGINT);
91− cl -> info.ptr = (void*)bigint;
92−
93− return cl;
60+ return (VAL)cl;
94}
61}
95
62
96VAL MKBIGSI(VM* vm, signed long val) {
63VAL MKBIGSI(VM* vm, signed long val) {
97− idris_requireAlloc(IDRIS_MAXGMP);
64+ BigInt * cl = allocBig(vm);
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);
65+ mpz_init_set_si(*getmpz(cl), val);
105−
66+ return (VAL)cl;
106− SETTY(cl, CT_BIGINT);
107− cl -> info.ptr = (void*)bigint;
108−
109− return cl;
110−}
67+}
111−
68+
112−VAL GETBIG(VM * vm, VAL x) {
69+static BigInt * 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)) {
70+ switch(GETTY(x)) {
131− case CT_FWD:
71+ case CT_INT:
132− return GETBIG(vm, x->info.ptr);
72+ {
133− default:
73+ BigInt * cl = allocBig(vm);
74+ mpz_set_si(*getmpz(cl), GETINT(x));
134− return x;
75+ return cl;
135 }
76 }
77+ case CT_FWD:
78+ return getbig(vm, ((Fwd*)x)->fwd);
79+ default:
80+ return (BigInt*)x;
136 }
81 }
137}
82}
138
83
139−VAL bigAdd(VM* vm, VAL x, VAL y) {
84+#define GETBIG (VAL)getbig
140− idris_requireAlloc(IDRIS_MAXGMP);
141
85
142− mpz_t* bigint;
86+VAL bigAdd(VM* vm, VAL x, VAL y) {
143− VAL cl = allocate(sizeof(Closure) + sizeof(mpz_t), 0);
87+ BigInt * cl = allocBig(vm);
144− idris_doneAlloc();
88+ mpz_add(*getmpz(cl), *getmpz(getbig(vm,x)), *getmpz(getbig(vm,y)));
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;
89+ return (VAL)cl;
150}
90}
151
91
152VAL bigSub(VM* vm, VAL x, VAL y) {
92VAL bigSub(VM* vm, VAL x, VAL y) {
153− idris_requireAlloc(IDRIS_MAXGMP);
93+ BigInt * cl = allocBig(vm);
154−
94+ mpz_sub(*getmpz(cl), *getmpz(getbig(vm,x)), *getmpz(getbig(vm,y)));
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;
95+ return (VAL)cl;
163}
96}
164
97
165VAL bigMul(VM* vm, VAL x, VAL y) {
98VAL bigMul(VM* vm, VAL x, VAL y) {
166− idris_requireAlloc(IDRIS_MAXGMP);
99+ BigInt * cl = allocBig(vm);
167−
100+ mpz_mul(*getmpz(cl), *getmpz(getbig(vm,x)), *getmpz(getbig(vm,y)));
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;
101+ return (VAL)cl;
176}
102}
177
103
178VAL bigDiv(VM* vm, VAL x, VAL y) {
104VAL bigDiv(VM* vm, VAL x, VAL y) {
179− idris_requireAlloc(IDRIS_MAXGMP);
105+ BigInt * cl = allocBig(vm);
180−
106+ mpz_tdiv_q(*getmpz(cl), *getmpz(getbig(vm,x)), *getmpz(getbig(vm,y)));
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;
107+ return (VAL)cl;
189}
108}
190
109
191VAL bigMod(VM* vm, VAL x, VAL y) {
110VAL bigMod(VM* vm, VAL x, VAL y) {
192− idris_requireAlloc(IDRIS_MAXGMP);
111+ BigInt * cl = allocBig(vm);
193−
112+ mpz_tdiv_r(*getmpz(cl), *getmpz(getbig(vm,x)), *getmpz(getbig(vm,y)));
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;
113+ return (VAL)cl;
202}
114}
203
115
204VAL bigAnd(VM* vm, VAL x, VAL y) {
116VAL bigAnd(VM* vm, VAL x, VAL y) {
205− idris_requireAlloc(IDRIS_MAXGMP);
117+ BigInt * cl = allocBig(vm);
206−
118+ mpz_and(*getmpz(cl), *getmpz(getbig(vm,x)), *getmpz(getbig(vm,y)));
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;
119+ return (VAL)cl;
215}
120}
216
121
217VAL bigOr(VM* vm, VAL x, VAL y) {
122VAL bigOr(VM* vm, VAL x, VAL y) {
218− idris_requireAlloc(IDRIS_MAXGMP);
123+ BigInt * cl = allocBig(vm);
219−
124+ mpz_ior(*getmpz(cl), *getmpz(getbig(vm,x)), *getmpz(getbig(vm,y)));
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;
125+ return (VAL)cl;
228}
126}
229
127
230VAL bigShiftLeft(VM* vm, VAL x, VAL y) {
128VAL bigShiftLeft(VM* vm, VAL x, VAL y) {
231− idris_requireAlloc(IDRIS_MAXGMP);
129+ BigInt * cl = allocBig(vm);
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));
130+ mpz_mul_2exp(*getmpz(cl), *getmpz(getbig(vm,x)), GETINT(y));
238− SETTY(cl, CT_BIGINT);
239− cl -> info.ptr = (void*)bigint;
240− return cl;
131+ return (VAL)cl;
241}
132}
242
133
243
134
244VAL bigLShiftRight(VM* vm, VAL x, VAL y) {
135VAL bigLShiftRight(VM* vm, VAL x, VAL y) {
245− idris_requireAlloc(IDRIS_MAXGMP);
136+ BigInt * cl = allocBig(vm);
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));
137+ mpz_fdiv_q_2exp(*getmpz(cl), *getmpz(getbig(vm,x)), GETINT(y));
252− SETTY(cl, CT_BIGINT);
253− cl -> info.ptr = (void*)bigint;
254− return cl;
138+ return (VAL)cl;
255}
139}
256
140
257VAL bigAShiftRight(VM* vm, VAL x, VAL y) {
141VAL bigAShiftRight(VM* vm, VAL x, VAL y) {
258− idris_requireAlloc(IDRIS_MAXGMP);
142+ BigInt * cl = allocBig(vm);
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));
143+ mpz_fdiv_q_2exp(*getmpz(cl), *getmpz(getbig(vm,x)), GETINT(y));
265− SETTY(cl, CT_BIGINT);
266− cl -> info.ptr = (void*)bigint;
267− return cl;
144+ return (VAL)cl;
268}
145}
269
146
270VAL idris_bigAnd(VM* vm, VAL x, VAL y) {
147VAL idris_bigAnd(VM* vm, VAL x, VAL y) {
@@ -323,15 +200,15 @@ VAL idris_bigTimes(VM* vm, VAL x, VAL y) {
323 if (ISINT(x) && ISINT(y)) {
200 if (ISINT(x) && ISINT(y)) {
324 i_int vx = GETINT(x);
201 i_int vx = GETINT(x);
325 i_int vy = GETINT(y);
202 i_int vy = GETINT(y);
326− // we could work out likelihood of overflow by checking the number
203+ // we could work out likelihood of overflow by checking the number
327− // of necessary bits. Here's a quick conservative hack instead.
204+ // of necessary bits. Here's a quick conservative hack instead.
328− if ((vx < (1<<15) && vy < (1<16)) ||
205+ if ((vx < (1<<15) && vy < (1<16)) ||
329− (vx < (1<<16) && vy < (1<15)) ||
206+ (vx < (1<<16) && vy < (1<15)) ||
330− (vx < (1<<20) && vy < (1<11)) ||
207+ (vx < (1<<20) && vy < (1<11)) ||
331− (vx < (1<<11) && vy < (1<20)) ||
208+ (vx < (1<<11) && vy < (1<20)) ||
332− (vx < (1<<23) && vy < (1<<8)) ||
209+ (vx < (1<<23) && vy < (1<<8)) ||
333− (vx < (1<<8) && vy < (1<<23))) { // ultra-conservative!
210+ (vx < (1<<8) && vy < (1<<23))) { // ultra-conservative!
334− return INTOP(*,x,y);
211+ return INTOP(*,x,y);
335 } else {
212 } else {
336 return bigMul(vm, GETBIG(vm, x), GETBIG(vm, y));
213 return bigMul(vm, GETBIG(vm, x), GETBIG(vm, y));
337 }
214 }
@@ -382,8 +259,8 @@ VAL idris_bigMod(VM* vm, VAL x, VAL y) {
382
259
383int bigEqConst(VAL x, int c) {
260int bigEqConst(VAL x, int c) {
384 if (ISINT(x)) { return (GETINT(x) == c); }
261 if (ISINT(x)) { return (GETINT(x) == c); }
385− else {
262+ else {
386− int rv = mpz_cmp_si(GETMPZ(x), c);
263+ int rv = mpz_cmp_si(GETMPZ(x), c);
387 return (rv == 0);
264 return (rv == 0);
388 }
265 }
389}
266}
@@ -471,17 +348,9 @@ VAL idris_castBigFloat(VM* vm, VAL i) {
471
348
472VAL idris_castFloatBig(VM* vm, VAL f) {
349VAL idris_castFloatBig(VM* vm, VAL f) {
473 double val = GETFLOAT(f);
350 double val = GETFLOAT(f);
474−
351+ BigInt * cl = allocBig(vm);
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);
352+ mpz_init_set_d(*getmpz(cl), val);
480−
481− SETTY(cl, CT_BIGINT);
482− cl -> info.ptr = (void*)bigint;
483−
484− return cl;
353+ return (VAL)cl;
485}
354}
486
355
487VAL idris_castStrBig(VM* vm, VAL i) {
356VAL idris_castStrBig(VM* vm, VAL i) {
@@ -489,7 +358,7 @@ VAL idris_castStrBig(VM* vm, VAL i) {
489}
358}
490
359
491VAL idris_castBigStr(VM* vm, VAL i) {
360VAL 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)));
493 return MKSTR(vm, str);
362 return MKSTR(vm, str);
494}
363}
495
364
@@ -502,7 +371,7 @@ uint64_t idris_truncBigB64(const mpz_t bi) {
502 }
371 }
503 int64_t out = mpz_get_ui(bi);
372 int64_t out = mpz_get_ui(bi);
504 if (mpz_size(bi) > 1) {
373 if (mpz_size(bi) > 1) {
505− out |= mpz_getlimbn(bi, 1) << 32;
374+ out |= ((int64_t)mpz_getlimbn(bi, 1)) << 32;
506 }
375 }
507 return out;
376 return out;
508}
377}
rts/idris_gmp.h+5−1
@@ -48,6 +48,10 @@ VAL idris_bigLShiftRight(VM* vm, VAL x, VAL y);
48
48
49uint64_t idris_truncBigB64(const mpz_t bi);
49uint64_t idris_truncBigB64(const mpz_t bi);
50
50
51+static inline mpz_t * getmpz(BigInt * v) {
52+ return (mpz_t*)(v->big);
53+}
54+
51−#define GETMPZ(x) *((mpz_t*)((x)->info.ptr))
55+#define GETMPZ(x) *getmpz((BigInt*)x)
52
56
53#endif
57#endif
rts/idris_heap.c+7−6
@@ -55,7 +55,7 @@ void c_heap_insert_if_needed(VM * vm, CHeap * heap, CHeapItem * item)
55 heap->first = item;
55 heap->first = item;
56
56
57 // at this point, links are done; let's calculate sizes
57 // at this point, links are done; let's calculate sizes
58−
58+
59 heap->size += item->size;
59 heap->size += item->size;
60 if (heap->size >= heap->gc_trigger_size)
60 if (heap->size >= heap->gc_trigger_size)
61 {
61 {
@@ -186,16 +186,17 @@ void heap_check_pointers(Heap * heap) {
186
186
187 size_t item_size = 0;
187 size_t item_size = 0;
188 for(scan = heap->heap; scan < heap->next; scan += item_size) {
188 for(scan = heap->heap; scan < heap->next; scan += item_size) {
189− item_size = *((size_t*)scan);
189+ VAL heap_item = (VAL)scan;
190− VAL heap_item = (VAL)(scan + sizeof(size_t));
190+ item_size = aligned(valSize(heap_item));
191
191
192 switch(GETTY(heap_item)) {
192 switch(GETTY(heap_item)) {
193 case CT_CON:
193 case CT_CON:
194 {
194 {
195− int ar = ARITY(heap_item);
195+ Con * c = (Con*)heap_item;
196− int i = 0;
196+ size_t ar = CARITY(c);
197+ size_t i;
197 for(i = 0; i < ar; ++i) {
198 for(i = 0; i < ar; ++i) {
198− VAL ptr = heap_item->info.c.args[i];
199+ VAL ptr = c->args[i];
199
200
200 if (is_valid_ref(ptr)) {
201 if (is_valid_ref(ptr)) {
201 // Check for closure.
202 // Check for closure.
rts/idris_main.c+2−3
@@ -3,7 +3,7 @@
3#include "idris_rts.h"
3#include "idris_rts.h"
4#include "idris_stats.h"
4#include "idris_stats.h"
5
5
6−void _idris__123_runMain_95_0_125_(VM* vm, VAL* oldbase);
6+void* _idris__123_runMain_95_0_125_(VM* vm, VAL* oldbase);
7
7
8#ifdef _WIN32
8#ifdef _WIN32
9
9
@@ -33,7 +33,7 @@ int win32_get_argv_utf8(int *argc_ptr, char ***argv_ptr)
33#endif
33#endif
34
34
35// The default options should give satisfactory results under many circumstances.
35// The default options should give satisfactory results under many circumstances.
36−RTSOpts opts = {
36+RTSOpts opts = {
37 .init_heap_size = 16384000,
37 .init_heap_size = 16384000,
38 .max_stack_size = 4096000,
38 .max_stack_size = 4096000,
39 .show_summary = 0
39 .show_summary = 0
@@ -74,6 +74,5 @@ int main(int argc, char **argv) {
74 print_stats(&stats);
74 print_stats(&stats);
75 }
75 }
76
76
77− free_nullaries();
78 return EXIT_SUCCESS;
77 return EXIT_SUCCESS;
79}
78}
rts/idris_rts.c+256−344
@@ -7,13 +7,22 @@
7#include "idris_bitstring.h"
7#include "idris_bitstring.h"
8#include "getline.h"
8#include "getline.h"
9
9
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+
10#ifdef HAS_PTHREAD
19#ifdef HAS_PTHREAD
11static pthread_key_t vm_key;
20static pthread_key_t vm_key;
12#else
21#else
13static VM* global_vm;
22static VM* global_vm;
14#endif
23#endif
15
24
16−void free_key(VM *vm) {
25+void free_key(void *vvm) {
17 // nothing to free, we just used the VM pointer which is freed elsewhere
26 // nothing to free, we just used the VM pointer which is freed elsewhere
18}
27}
19
28
@@ -40,8 +49,9 @@ VM* init_vm(int stack_size, size_t heap_size,
40 vm->ret = NULL;
49 vm->ret = NULL;
41 vm->reg1 = NULL;
50 vm->reg1 = NULL;
42#ifdef HAS_PTHREAD
51#ifdef HAS_PTHREAD
43− vm->inbox = malloc(1024*sizeof(VAL));
52+ vm->inbox = malloc(1024*sizeof(vm->inbox[0]));
53+ assert(vm->inbox);
44− memset(vm->inbox, 0, 1024*sizeof(VAL));
54+ memset(vm->inbox, 0, 1024*sizeof(vm->inbox[0]));
45 vm->inbox_end = vm->inbox + 1024;
55 vm->inbox_end = vm->inbox + 1024;
46 vm->inbox_write = vm->inbox;
56 vm->inbox_write = vm->inbox;
47 vm->inbox_nextid = 1;
57 vm->inbox_nextid = 1;
@@ -83,7 +93,6 @@ VM* idris_vm(void) {
83
93
84VM* get_vm(void) {
94VM* get_vm(void) {
85#ifdef HAS_PTHREAD
95#ifdef HAS_PTHREAD
86− init_threadkeys();
87 return pthread_getspecific(vm_key);
96 return pthread_getspecific(vm_key);
88#else
97#else
89 return global_vm;
98 return global_vm;
@@ -96,7 +105,7 @@ void close_vm(VM* vm) {
96
105
97#ifdef HAS_PTHREAD
106#ifdef HAS_PTHREAD
98void create_key(void) {
107void create_key(void) {
99− pthread_key_create(&vm_key, (void*)free_key);
108+ pthread_key_create(&vm_key, free_key);
100}
109}
101#endif
110#endif
102
111
@@ -155,13 +164,7 @@ CData cdata_manage(void * data, size_t size, CDataFinalizer finalizer)
155 return c_heap_create_item(data, size, finalizer);
164 return c_heap_create_item(data, size, finalizer);
156}
165}
157
166
158−void idris_requireAlloc(size_t size) {
167+void idris_requireAlloc(VM * vm, size_t size) {
159−#ifdef HAS_PTHREAD
160− VM* vm = pthread_getspecific(vm_key);
161−#else
162− VM* vm = global_vm;
163−#endif
164−
165 if (!(vm->heap.next + size < vm->heap.end)) {
168 if (!(vm->heap.next + size < vm->heap.end)) {
166 idris_gc(vm);
169 idris_gc(vm);
167 }
170 }
@@ -173,9 +176,8 @@ void idris_requireAlloc(size_t size) {
173#endif
176#endif
174}
177}
175
178
176−void idris_doneAlloc(void) {
179+void idris_doneAlloc(VM * vm) {
177#ifdef HAS_PTHREAD
180#ifdef HAS_PTHREAD
178− VM* vm = pthread_getspecific(vm_key);
179 int lock = vm->processes > 0;
181 int lock = vm->processes > 0;
180 if (lock) { // We only need to lock if we're in concurrent mode
182 if (lock) { // We only need to lock if we're in concurrent mode
181 pthread_mutex_unlock(&vm->alloc_lock);
183 pthread_mutex_unlock(&vm->alloc_lock);
@@ -184,14 +186,13 @@ void idris_doneAlloc(void) {
184}
186}
185
187
186int space(VM* vm, size_t size) {
188int 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;
188}
190}
189
191
190void* idris_alloc(size_t size) {
192void* idris_alloc(size_t size) {
191− Closure* cl = (Closure*) allocate(sizeof(Closure)+size, 0);
193+ RawData * cl = (RawData*) allocate(sizeof(*cl)+size, 0);
192 SETTY(cl, CT_RAWDATA);
194 SETTY(cl, CT_RAWDATA);
193− cl->info.size = size;
194− return (void*)((char *)cl+sizeof(Closure));
195+ return (void*)cl->raw;
195}
196}
196
197
197void* idris_realloc(void* old, size_t old_size, size_t size) {
198void* 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) {
203void idris_free(void* ptr, size_t size) {
204void idris_free(void* ptr, size_t size) {
204}
205}
205
206
206−void* allocate(size_t size, int outerlock) {
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) {
207−// return malloc(size);
212+// return malloc(isize);
213+ size_t size = aligned(isize);
208
214
209#ifdef HAS_PTHREAD
215#ifdef HAS_PTHREAD
210− VM* vm = pthread_getspecific(vm_key);
211 int lock = vm->processes > 0 && !outerlock;
216 int lock = vm->processes > 0 && !outerlock;
212
217
213 if (lock) { // not message passing
218 if (lock) { // not message passing
214 pthread_mutex_lock(&vm->alloc_lock);
219 pthread_mutex_lock(&vm->alloc_lock);
215 }
220 }
216−#else
217− VM* vm = global_vm;
218#endif
221#endif
219
222
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) {
223+ if (vm->heap.next + size < vm->heap.end) {
227− STATS_ALLOC(vm->stats, chunk_size)
224+ STATS_ALLOC(vm->stats, size)
228− void* ptr = (void*)(vm->heap.next + sizeof(size_t));
229− *((size_t*)(vm->heap.next)) = chunk_size;
225+ char* ptr = vm->heap.next;
230− vm->heap.next += chunk_size;
226+ vm->heap.next += size;
231−
232 assert(vm->heap.next <= vm->heap.end);
227 assert(vm->heap.next <= vm->heap.end);
233−
234 memset(ptr, 0, size);
228 memset(ptr, 0, size);
229+ ((Hdr*)ptr)->sz = isize;
230+
235#ifdef HAS_PTHREAD
231#ifdef HAS_PTHREAD
236 if (lock) { // not message passing
232 if (lock) { // not message passing
237 pthread_mutex_unlock(&vm->alloc_lock);
233 pthread_mutex_unlock(&vm->alloc_lock);
238 }
234 }
239#endif
235#endif
240− return ptr;
236+ return (void*)ptr;
241 } else {
237 } else {
242 // If we're trying to allocate something bigger than the heap,
238 // If we're trying to allocate something bigger than the heap,
243 // grow the heap here so that the new heap is big enough.
239 // grow the heap here so that the new heap is big enough.
@@ -250,173 +246,143 @@ void* allocate(size_t size, int outerlock) {
250 pthread_mutex_unlock(&vm->alloc_lock);
246 pthread_mutex_unlock(&vm->alloc_lock);
251 }
247 }
252#endif
248#endif
253− return allocate(size, 0);
249+ return iallocate(vm, size, outerlock);
254 }
250 }
255
251
256}
252}
257
253
258−/* Now a macro
254+static String * allocStr(VM * vm, size_t len, int outer) {
259−void* allocCon(VM* vm, int arity, int outer) {
255+ String * cl = iallocate(vm, sizeof(*cl) + len + 1, outer);
260− Closure* cl = allocate(vm, sizeof(Closure) + sizeof(VAL)*arity,
261− outer);
262− SETTY(cl, CT_CON);
256+ SETTY(cl, CT_STRING);
257+ cl->slen = len;
258+ return cl;
259+}
263
260
264− cl -> info.c.arity = arity;
261+static VAL mkfloat(VM* vm, double val, int outer) {
265−// cl -> info.c.tag = 42424242;
262+ Float * cl = iallocate(vm, sizeof(*cl), outer);
266−// printf("%p\n", cl);
263+ SETTY(cl, CT_FLOAT);
264+ cl->f = val;
267− return (void*)cl;
265+ return (VAL)cl;
268}
266}
269−*/
270
267
271VAL MKFLOAT(VM* vm, double val) {
268VAL MKFLOAT(VM* vm, double val) {
272− Closure* cl = allocate(sizeof(Closure), 0);
269+ return mkfloat(vm, val, 0);
273− SETTY(cl, CT_FLOAT);
270+}
274− cl -> info.f = val;
271+
275− return cl;
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);
276}
291}
277
292
278VAL MKSTR(VM* vm, const char* str) {
293VAL MKSTR(VM* vm, const char* str) {
279− int len;
294+ return mkstrlen(vm, str, str? strlen(str) : 0, 0);
280− if (str == NULL) {
295+}
281− len = 0;
296+
282− } else {
297+VAL MKSTRc(VM* vm, char* str) {
283− len = strlen(str)+1;
298+ return mkstrlen(vm, str, strlen(str), 1);
284− }
299+}
285− Closure* cl = allocate(sizeof(Closure) + // Type) + sizeof(char*) +
300+
286− sizeof(char)*len, 0);
301+static char * getstroff(StrOffset * stroff) {
287− SETTY(cl, CT_STRING);
302+ return stroff->base->str + stroff->offset;
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;
296}
303}
297
304
298char* GETSTROFF(VAL stroff) {
305char* GETSTROFF(VAL stroff) {
299 // Assume STROFF
306 // Assume STROFF
300− StrOffset* root = stroff->info.str_offset;
307+ return getstroff((StrOffset*)stroff);
301− return (root->str->info.str.str + root->offset);
308+}
309+
310+static size_t getstrofflen(StrOffset * stroff) {
311+ return stroff->base->slen - stroff->offset;
302}
312}
303
313
304size_t GETSTROFFLEN(VAL stroff) {
314size_t GETSTROFFLEN(VAL stroff) {
305 // Assume STROFF
315 // Assume STROFF
306 // we're working in char* here so no worries about utf8 char length
316 // we're working in char* here so no worries about utf8 char length
307− StrOffset* root = stroff->info.str_offset;
317+ return getstrofflen((StrOffset*)stroff);
308− return (root->str->info.str.len - root->offset);
309}
318}
310
319
311−VAL MKCDATA(VM* vm, CHeapItem * item) {
320+static VAL mkcdata(VM * vm, CHeapItem * item, int outer) {
312 c_heap_insert_if_needed(vm, &vm->c_heap, item);
321 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);
314 SETTY(cl, CT_CDATA);
323 SETTY(cl, CT_CDATA);
315− cl->info.c_heap_item = item;
324+ cl->item = item;
316− return cl;
325+ return (VAL)cl;
317}
326}
318
327
319−VAL MKCDATAc(VM* vm, CHeapItem * item) {
328+VAL MKCDATA(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;
329+ return mkcdata(vm, item, 0);
325}
330}
326
331
327−VAL MKPTR(VM* vm, void* ptr) {
332+VAL MKCDATAc(VM* vm, CHeapItem * item) {
328− Closure* cl = allocate(sizeof(Closure), 0);
329− SETTY(cl, CT_PTR);
330− cl -> info.ptr = ptr;
331− return cl;
333+ return mkcdata(vm, item, 1);
332}
334}
333
335
334−VAL MKMPTR(VM* vm, void* ptr, size_t size) {
336+static VAL mkptr(VM* vm, void* ptr, int outer) {
335− Closure* cl = allocate(sizeof(Closure) +
337+ Ptr * cl = iallocate(vm, sizeof(*cl), outer);
336− sizeof(ManagedPtr) + size, 0);
337− SETTY(cl, CT_MANAGEDPTR);
338+ SETTY(cl, CT_PTR);
338− cl->info.mptr = (ManagedPtr*)((char*)cl + sizeof(Closure));
339+ cl->ptr = ptr;
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;
340+ return (VAL)cl;
343}
341}
344
342
345−VAL MKFLOATc(VM* vm, double val) {
343+VAL MKPTR(VM* vm, void* ptr) {
346− Closure* cl = allocate(sizeof(Closure), 1);
347− SETTY(cl, CT_FLOAT);
348− cl -> info.f = val;
349− return cl;
344+ return mkptr(vm, ptr, 0);
350}
345}
351
346
352−VAL MKSTRc(VM* vm, char* str) {
347+VAL MKPTRc(VM* vm, void* ptr) {
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;
348+ return mkptr(vm, ptr, 1);
363}
349}
364
350
365−VAL MKSTRclen(VM* vm, char* str, int len) {
351+VAL mkmptr(VM* vm, void* ptr, size_t size, int outer) {
366− Closure* cl = allocate(sizeof(Closure) + // Type) + sizeof(char*) +
352+ ManagedPtr * cl = iallocate(vm, sizeof(*cl) + size, outer);
367− sizeof(char)*len+1, 1);
353+ SETTY(cl, CT_MANAGEDPTR);
368− SETTY(cl, CT_STRING);
354+ memcpy(cl->mptr, ptr, size);
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;
355+ return (VAL)cl;
374}
356}
375
357
376−VAL MKPTRc(VM* vm, void* ptr) {
358+VAL MKMPTR(VM* vm, void* ptr, size_t size) {
377− Closure* cl = allocate(sizeof(Closure), 1);
378− SETTY(cl, CT_PTR);
379− cl -> info.ptr = ptr;
380− return cl;
359+ return mkmptr(vm, ptr, size, 0);
381}
360}
382
361
383VAL MKMPTRc(VM* vm, void* ptr, size_t size) {
362VAL MKMPTRc(VM* vm, void* ptr, size_t size) {
384− Closure* cl = allocate(sizeof(Closure) +
363+ return mkmptr(vm, ptr, size, 1);
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;
392}
364}
393
365
394VAL MKB8(VM* vm, uint8_t bits8) {
366VAL 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);
399}
368}
400
369
401VAL MKB16(VM* vm, uint16_t bits16) {
370VAL 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);
406}
372}
407
373
408VAL MKB32(VM* vm, uint32_t bits32) {
374VAL MKB32(VM* vm, uint32_t bits32) {
409− Closure* cl = allocate(sizeof(Closure), 1);
375+ Bits32 * cl = iallocate(vm, sizeof(*cl), 1);
410 SETTY(cl, CT_BITS32);
376 SETTY(cl, CT_BITS32);
411− cl -> info.bits32 = bits32;
377+ cl->bits32 = bits32;
412− return cl;
378+ return (VAL)cl;
413}
379}
414
380
415VAL MKB64(VM* vm, uint64_t bits64) {
381VAL MKB64(VM* vm, uint64_t bits64) {
416− Closure* cl = allocate(sizeof(Closure), 1);
382+ Bits64 * cl = iallocate(vm, sizeof(*cl), 1);
417 SETTY(cl, CT_BITS64);
383 SETTY(cl, CT_BITS64);
418− cl -> info.bits64 = bits64;
384+ cl->bits64 = bits64;
419− return cl;
385+ return (VAL)cl;
420}
386}
421
387
422void idris_trace(VM* vm, const char* func, int line) {
388void idris_trace(VM* vm, const char* func, int line) {
@@ -445,29 +411,40 @@ void dumpStack(VM* vm) {
445void dumpVal(VAL v) {
411void dumpVal(VAL v) {
446 if (v==NULL) return;
412 if (v==NULL) return;
447 int i;
413 int i;
448− if (ISINT(v)) {
449− printf("%d ", (int)(GETINT(v)));
450− return;
451− }
452 switch(GETTY(v)) {
414 switch(GETTY(v)) {
415+ case CT_INT:
416+ printf("%" PRIdPTR " ", GETINT(v));
417+ break;
453 case CT_CON:
418 case CT_CON:
419+ {
420+ Con * cl = (Con*)v;
454− printf("%d[", TAG(v));
421+ printf("%d[", (int)TAG(cl));
455− for(i = 0; i < ARITY(v); ++i) {
422+ for(i = 0; i < CARITY(cl); ++i) {
456− dumpVal(v->info.c.args[i]);
423+ dumpVal(cl->args[i]);
424+ }
425+ printf("] ");
457 }
426 }
458− printf("] ");
459 break;
427 break;
460 case CT_STRING:
428 case CT_STRING:
429+ {
430+ String * cl = (String*)v;
461− printf("STR[%s]", v->info.str.str);
431+ printf("STR[%s]", cl->str);
432+ }
462 break;
433 break;
463 case CT_STROFFSET:
434 case CT_STROFFSET:
435+ {
436+ StrOffset * cl = (StrOffset*)v;
464− printf("OFFSET[");
437+ printf("OFFSET[");
465− dumpVal((VAL)(v->info.str_offset->str));
438+ dumpVal((VAL)cl->base);
466− printf("]");
439+ printf("]");
440+ }
467 break;
441 break;
468 case CT_FWD:
442 case CT_FWD:
443+ {
444+ Fwd * cl = (Fwd*)v;
469− printf("CT_FWD ");
445+ printf("CT_FWD ");
470− dumpVal((VAL)(v->info.ptr));
446+ dumpVal((VAL)cl->fwd);
447+ }
471 break;
448 break;
472 default:
449 default:
473 printf("val");
450 printf("val");
@@ -489,7 +466,7 @@ void idris_poke(void* ptr, i_int offset, uint8_t data) {
489
466
490
467
491VAL idris_peekPtr(VM* vm, VAL ptr, VAL offset) {
468VAL 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));
493 return MKPTR(vm, *addr);
470 return MKPTR(vm, *addr);
494}
471}
495
472
@@ -523,51 +500,36 @@ void idris_memmove(void* dest, void* src, i_int dest_offset, i_int src_offset, i
523
500
524VAL idris_castIntStr(VM* vm, VAL i) {
501VAL idris_castIntStr(VM* vm, VAL i) {
525 int x = (int) GETINT(i);
502 int x = (int) GETINT(i);
526− Closure* cl = allocate(sizeof(Closure) + sizeof(char)*16, 0);
503+ String * cl = allocStr(vm, 16, 0);
527− SETTY(cl, CT_STRING);
528− cl->info.str.str = (char*)cl + sizeof(Closure);
529− sprintf(cl->info.str.str, "%d", x);
504+ cl->slen = sprintf(cl->str, "%d", x);
530− cl->info.str.len = strlen(cl->info.str.str);
531− return cl;
505+ return (VAL)cl;
532}
506}
533
507
534VAL idris_castBitsStr(VM* vm, VAL i) {
508VAL idris_castBitsStr(VM* vm, VAL i) {
535− Closure* cl;
509+ String * cl;
536− ClosureType ty = i->ty;
510+ ClosureType ty = GETTY(i);
537
511
538 switch (ty) {
512 switch (ty) {
539− case CT_BITS8:
513+ case CT_INT: // 8/16 bits
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:
546 // max length 16 bit unsigned int str 5 chars (65,535)
514 // max length 16 bit unsigned int str 5 chars (65,535)
547− cl = allocate(sizeof(Closure) + sizeof(char)*6, 0);
515+ cl = allocStr(vm, 6, 0);
548− cl->info.str.str = (char*)cl + sizeof(Closure);
549− sprintf(cl->info.str.str, "%" PRIu16, (uint16_t)i->info.bits16);
516+ cl->slen = sprintf(cl->str, "%" PRIu16, (uint16_t)GETBITS16(i));
550 break;
517 break;
551 case CT_BITS32:
518 case CT_BITS32:
552 // max length 32 bit unsigned int str 10 chars (4,294,967,295)
519 // max length 32 bit unsigned int str 10 chars (4,294,967,295)
553− cl = allocate(sizeof(Closure) + sizeof(char)*11, 0);
520+ cl = allocStr(vm, 11, 0);
554− cl->info.str.str = (char*)cl + sizeof(Closure);
555− sprintf(cl->info.str.str, "%" PRIu32, (uint32_t)i->info.bits32);
521+ cl->slen = sprintf(cl->str, "%" PRIu32, GETBITS32(i));
556 break;
522 break;
557 case CT_BITS64:
523 case CT_BITS64:
558 // max length 64 bit unsigned int str 20 chars (18,446,744,073,709,551,615)
524 // 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);
525+ cl = allocStr(vm, 21, 0);
560− cl->info.str.str = (char*)cl + sizeof(Closure);
561− sprintf(cl->info.str.str, "%" PRIu64, (uint64_t)i->info.bits64);
526+ cl->slen = sprintf(cl->str, "%" PRIu64, GETBITS64(i));
562 break;
527 break;
563 default:
528 default:
564 fprintf(stderr, "Fatal Error: ClosureType %d, not an integer type", ty);
529 fprintf(stderr, "Fatal Error: ClosureType %d, not an integer type", ty);
565 exit(EXIT_FAILURE);
530 exit(EXIT_FAILURE);
566 }
531 }
567−
568− cl->info.str.len = strlen(cl->info.str.str);
569− SETTY(cl, CT_STRING);
570− return cl;
532+ return (VAL)cl;
571}
533}
572
534
573VAL idris_castStrInt(VM* vm, VAL i) {
535VAL idris_castStrInt(VM* vm, VAL i) {
@@ -580,13 +542,9 @@ VAL idris_castStrInt(VM* vm, VAL i) {
580}
542}
581
543
582VAL idris_castFloatStr(VM* vm, VAL i) {
544VAL idris_castFloatStr(VM* vm, VAL i) {
583− Closure* cl = allocate(sizeof(Closure) + sizeof(char)*32, 0);
545+ String * cl = allocStr(vm, 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));
546+ cl->slen = snprintf(cl->str, 32, "%.16g", GETFLOAT(i));
587−
588− cl->info.str.len = strlen(cl->info.str.str);
589− return cl;
547+ return (VAL)cl;
590}
548}
591
549
592VAL idris_castStrFloat(VM* vm, VAL i) {
550VAL idris_castStrFloat(VM* vm, VAL i) {
@@ -596,17 +554,13 @@ VAL idris_castStrFloat(VM* vm, VAL i) {
596VAL idris_concat(VM* vm, VAL l, VAL r) {
554VAL idris_concat(VM* vm, VAL l, VAL r) {
597 char *rs = GETSTR(r);
555 char *rs = GETSTR(r);
598 char *ls = GETSTR(l);
556 char *ls = GETSTR(l);
599− int llen = GETSTRLEN(l);
557+ size_t llen = GETSTRLEN(l);
600− int rlen = GETSTRLEN(r);
558+ size_t 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);
607
559
608− cl->info.str.len = llen + rlen;
560+ String * cl = allocStr(vm, llen + rlen, 0);
561+ memcpy(cl->str, ls, llen);
562+ memcpy(cl->str + llen, rs, rlen);
609− return cl;
563+ return (VAL)cl;
610}
564}
611
565
612VAL idris_strlt(VM* vm, VAL l, VAL r) {
566VAL idris_strlt(VM* vm, VAL l, VAL r) {
@@ -667,38 +621,32 @@ VAL idris_strHead(VM* vm, VAL str) {
667 return idris_strIndex(vm, str, 0);
621 return idris_strIndex(vm, str, 0);
668}
622}
669
623
670−VAL MKSTROFFc(VM* vm, StrOffset* off) {
624+VAL MKSTROFFc(VM* vm, VAL basestr) {
671− Closure* cl = allocate(sizeof(Closure) + sizeof(StrOffset), 1);
625+ StrOffset * cl = iallocate(vm, sizeof(*cl), 1);
672 SETTY(cl, CT_STROFFSET);
626 SETTY(cl, CT_STROFFSET);
673− cl->info.str_offset = (StrOffset*)((char*)cl + sizeof(Closure));
627+ cl->base = (String*)basestr;
674−
675− cl->info.str_offset->str = off->str;
676− cl->info.str_offset->offset = off->offset;
677−
678− return cl;
628+ return (VAL)cl;
679}
629}
680
630
681VAL idris_strShift(VM* vm, VAL str, int num) {
631VAL idris_strShift(VM* vm, VAL str, int num) {
632+ size_t sz = sizeof(StrOffset);
682 // If there's no room, just copy the string, or we'll have a problem after
633 // If there's no room, just copy the string, or we'll have a problem after
683 // gc moves str
634 // gc moves str
684− if (space(vm, sizeof(Closure) + sizeof(StrOffset))) {
635+ if (space(vm, sz)) {
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−
689 int offset = 0;
636 int offset = 0;
690− VAL root = str;
637+ StrOffset * root = (StrOffset*)str;
638+ StrOffset * cl = iallocate(vm, sz, 0);
639+ SETTY(cl, CT_STROFFSET);
691
640
692 while(root!=NULL && !ISSTR(root)) { // find the root, carry on.
641 while(root!=NULL && !ISSTR(root)) { // find the root, carry on.
693 // In theory, at most one step here!
642 // In theory, at most one step here!
694− offset += root->info.str_offset->offset;
643+ offset += root->offset;
695− root = root->info.str_offset->str;
644+ root = (StrOffset*)root->base;
696 }
645 }
697
646
698− cl->info.str_offset->str = root;
647+ cl->base = (String*)root;
699− cl->info.str_offset->offset = offset+idris_utf8_findOffset(GETSTR(str), num);
648+ cl->offset = offset+idris_utf8_findOffset(GETSTR(str), num);
700−
701− return cl;
649+ return (VAL)cl;
702 } else {
650 } else {
703 char* nstr = GETSTR(str);
651 char* nstr = GETSTR(str);
704 return MKSTR(vm, nstr+idris_utf8_charlen(nstr));
652 return MKSTR(vm, nstr+idris_utf8_charlen(nstr));
@@ -712,29 +660,23 @@ VAL idris_strTail(VM* vm, VAL str) {
712VAL idris_strCons(VM* vm, VAL x, VAL xs) {
660VAL idris_strCons(VM* vm, VAL x, VAL xs) {
713 char *xstr = GETSTR(xs);
661 char *xstr = GETSTR(xs);
714 int xval = GETINT(x);
662 int xval = GETINT(x);
715− int xlen = GETSTRLEN(xs);
663+ size_t xlen = GETSTRLEN(xs);
664+ String * cl;
716
665
717 if (xval < 0x80) { // ASCII char
666 if (xval < 0x80) { // ASCII char
718− Closure* cl = allocate(sizeof(Closure) +
719− xlen + 2, 0);
667+ cl = allocStr(vm, xlen + 1, 0);
720− SETTY(cl, CT_STRING);
721− cl->info.str.str = (char*)cl + sizeof(Closure);
722− cl->info.str.str[0] = (char)(GETINT(x));
668+ cl->str[0] = (char)(GETINT(x));
723− strcpy(cl->info.str.str+1, xstr);
669+ memcpy(cl->str+1, xstr, xlen);
724− cl->info.str.len = xlen + 1;
725− return cl;
726 } else {
670 } else {
727 char *init = idris_utf8_fromChar(xval);
671 char *init = idris_utf8_fromChar(xval);
728− int newlen = strlen(init) + xlen;
672+ size_t ilen = strlen(init);
729− Closure* cl = allocate(sizeof(Closure) + newlen + 1, 0);
673+ int newlen = ilen + xlen;
730− SETTY(cl, CT_STRING);
674+ cl = allocStr(vm, newlen, 0);
731− cl->info.str.str = (char*)cl + sizeof(Closure);
675+ memcpy(cl->str, init, ilen);
732− strcpy(cl->info.str.str, init);
676+ memcpy(cl->str + ilen, xstr, xlen);
733− strcat(cl->info.str.str, xstr);
734− cl->info.str.len = newlen;
735 free(init);
677 free(init);
736− return cl;
737 }
678 }
679+ return (VAL)cl;
738}
680}
739
681
740VAL idris_strIndex(VM* vm, VAL str, VAL i) {
682VAL idris_strIndex(VM* vm, VAL str, VAL i) {
@@ -743,8 +685,8 @@ VAL idris_strIndex(VM* vm, VAL str, VAL i) {
743}
685}
744
686
745VAL idris_substr(VM* vm, VAL offset, VAL length, VAL str) {
687VAL idris_substr(VM* vm, VAL offset, VAL length, VAL str) {
746− int offset_val = GETINT(offset);
688+ size_t offset_val = GETINT(offset);
747− int length_val = GETINT(length);
689+ size_t length_val = GETINT(length);
748 char* str_val = GETSTR(str);
690 char* str_val = GETSTR(str);
749
691
750 // If the substring is a suffix, use idris_strShift to avoid reallocating
692 // 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) {
754 else {
696 else {
755 char *start = idris_utf8_advance(str_val, offset_val);
697 char *start = idris_utf8_advance(str_val, offset_val);
756 char *end = idris_utf8_advance(start, length_val);
698 char *end = idris_utf8_advance(start, length_val);
757− Closure* newstr = allocate(sizeof(Closure) + (end - start) +1, 0);
699+ size_t sz = end - start;
758− SETTY(newstr, CT_STRING);
700+ String * newstr = allocStr(vm, sz, 0);
759− newstr->info.str.str = (char*)newstr + sizeof(Closure);
760− memcpy(newstr->info.str.str, start, end - start);
701+ memcpy(newstr->str, start, sz);
761− *(newstr->info.str.str + (end - start) + 1) = '\0';
702+ newstr->str[sz] = '\0';
762− newstr->info.str.len = strlen(newstr->info.str.str);
763− return newstr;
703+ return (VAL)newstr;
764 }
704 }
765}
705}
766
706
767VAL idris_strRev(VM* vm, VAL str) {
707VAL idris_strRev(VM* vm, VAL str) {
768 char *xstr = GETSTR(str);
708 char *xstr = GETSTR(str);
769− int xlen = GETSTRLEN(str);
709+ size_t xlen = GETSTRLEN(str);
770
710
771− Closure* cl = allocate(sizeof(Closure) + xlen + 1, 0);
711+ String * cl = allocStr(vm, xlen, 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);
712+ idris_utf8_rev(xstr, cl->str);
776− return cl;
713+ return (VAL)cl;
777}
714}
778
715
779VAL idris_newRefLock(VAL x, int outerlock) {
716VAL idris_newRefLock(VAL x, int outerlock) {
780− Closure* cl = allocate(sizeof(Closure), outerlock);
717+ Ref * cl = allocate(sizeof(*cl), outerlock);
781 SETTY(cl, CT_REF);
718 SETTY(cl, CT_REF);
782− cl->info.ptr = (void*)x;
719+ cl->ref = x;
783− return cl;
720+ return (VAL)cl;
784}
721}
785
722
786VAL idris_newRef(VAL x) {
723VAL idris_newRef(VAL x) {
@@ -788,30 +725,34 @@ VAL idris_newRef(VAL x) {
788}
725}
789
726
790void idris_writeRef(VAL ref, VAL x) {
727void idris_writeRef(VAL ref, VAL x) {
791− ref->info.ptr = (void*)x;
728+ Ref * r = (Ref*)ref;
729+ r->ref = x;
792 SETTY(ref, CT_REF);
730 SETTY(ref, CT_REF);
793}
731}
794
732
795VAL idris_readRef(VAL ref) {
733VAL idris_readRef(VAL ref) {
734+ Ref * r = (Ref*)ref;
796− return (VAL)(ref->info.ptr);
735+ return r->ref;
797}
736}
798
737
799VAL idris_newArray(VM* vm, int size, VAL def) {
738VAL idris_newArray(VM* vm, int size, VAL def) {
800− Closure* cl;
739+ Array * cl;
801 int i;
740 int i;
802− allocArray(cl, vm, size, 0);
741+ cl = allocArrayF(vm, size, 0);
803 for(i=0; i<size; ++i) {
742 for(i=0; i<size; ++i) {
804− cl->info.arr.content[i] = def;
743+ cl->array[i] = def;
805 }
744 }
806− return cl;
745+ return (VAL)cl;
807}
746}
808
747
809void idris_arraySet(VAL arr, int index, VAL newval) {
748void idris_arraySet(VAL arr, int index, VAL newval) {
749+ Array * cl = (Array*)arr;
810− arr->info.arr.content[index] = newval;
750+ cl->array[index] = newval;
811}
751}
812
752
813VAL idris_arrayGet(VAL arr, int index) {
753VAL idris_arrayGet(VAL arr, int index) {
754+ Array * cl = (Array*)arr;
814− return arr->info.arr.content[index];
755+ return cl->array[index];
815}
756}
816
757
817VAL idris_systemInfo(VM* vm, VAL index) {
758VAL idris_systemInfo(VM* vm, VAL index) {
@@ -892,88 +833,69 @@ void* idris_stopThread(VM* vm) {
892 return NULL;
833 return NULL;
893}
834}
894
835
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+
895// VM is assumed to be a different vm from the one x lives on
845// VM is assumed to be a different vm from the one x lives on
896
846
897−VAL doCopyTo(VM* vm, VAL x) {
847+static VAL doCopyTo(VM* vm, VAL x) {
898− int i, ar, len;
848+ int ar;
899− VAL* argptr;
849+ VAL cl;
900− Closure* cl;
901− if (x==NULL || ISINT(x)) {
850+ if (x==NULL) {
902 return x;
851 return x;
903 }
852 }
904 switch(GETTY(x)) {
853 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;
905 case CT_CON:
862 case CT_CON:
906 ar = CARITY(x);
863 ar = CARITY(x);
907 if (ar == 0 && CTAG(x) < 256) { // globally allocated
864 if (ar == 0 && CTAG(x) < 256) { // globally allocated
908 cl = x;
865 cl = x;
909 } else {
866 } else {
910− allocCon(cl, vm, CTAG(x), ar, 1);
867+ Con * c = allocConF(vm, CTAG(x), ar, 1);
911−
868+ copyArray(vm, c->args, ((Con*)x)->args, ar);
912− argptr = (VAL*)(cl->info.c.args);
869+ cl = (VAL)c;
913− for(i = 0; i < ar; ++i) {
914− *argptr = doCopyTo(vm, *((VAL*)(x->info.c.args)+i)); // recursive version
915− argptr++;
916− }
917 }
870 }
918 break;
871 break;
919− case CT_ARRAY:
872+ case CT_ARRAY: {
920− len = x->info.arr.length;
873+ size_t len = CELEM(x);
921− allocArray(cl, vm, len, 1);
874+ Array * a = allocArrayF(vm, len, 1);
922−
875+ copyArray(vm, a->array, ((Array*)x)->array, len);
923− argptr = (VAL*)(cl->info.arr.content);
876+ cl = (VAL)a;
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;
877+ } break;
932 case CT_STRING:
878 case CT_STRING:
933− cl = MKSTRc(vm, x->info.str.str);
879+ case CT_FLOAT:
934− break;
935− case CT_BIGINT:
936− cl = MKBIGMc(vm, x->info.ptr);
937− break;
938 case CT_PTR:
880 case CT_PTR:
939− cl = MKPTRc(vm, x->info.ptr);
940− break;
941 case CT_MANAGEDPTR:
881 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;
953 case CT_BITS32:
882 case CT_BITS32:
954− cl = idris_b32CopyForGC(vm, x);
955− break;
956 case CT_BITS64:
883 case CT_BITS64:
957− cl = idris_b64CopyForGC(vm, x);
958− break;
959 case CT_RAWDATA:
884 case CT_RAWDATA:
960 {
885 {
961− size_t size = x->info.size + sizeof(Closure);
886+ cl = iallocate(vm, x->hdr.sz, 0);
962− cl = allocate(size, 0);
963− memcpy(cl, x, size);
887+ memcpy(cl, x, x->hdr.sz);
964 }
888 }
965 break;
889 break;
966 default:
890 default:
967 assert(0); // We're in trouble if this happens...
891 assert(0); // We're in trouble if this happens...
892+ cl = NULL;
968 }
893 }
969 return cl;
894 return cl;
970}
895}
971
896
972VAL copyTo(VM* vm, VAL x) {
897VAL copyTo(VM* vm, VAL x) {
973− VM* current = pthread_getspecific(vm_key);
974− pthread_setspecific(vm_key, vm);
975 VAL ret = doCopyTo(vm, x);
898 VAL ret = doCopyTo(vm, x);
976− pthread_setspecific(vm_key, current);
977 return ret;
899 return ret;
978}
900}
979
901
@@ -1045,7 +967,7 @@ Msg* idris_checkInitMessages(VM* vm) {
1045 Msg* msg;
967 Msg* msg;
1046
968
1047 for (msg = vm->inbox; msg < vm->inbox_end && msg->msg != NULL; ++msg) {
969 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
1049 return msg;
971 return msg;
1050 }
972 }
1051 }
973 }
@@ -1108,11 +1030,11 @@ Msg* idris_recvMessage(VM* vm) {
1108
1030
1109Msg* idris_recvMessageFrom(VM* vm, int channel_id, VM* sender) {
1031Msg* idris_recvMessageFrom(VM* vm, int channel_id, VM* sender) {
1110 Msg* msg;
1032 Msg* msg;
1111− Msg* ret = malloc(sizeof(Msg));
1033+ Msg* ret;
1112
1034
1113 struct timespec timeout;
1035 struct timespec timeout;
1114 int status;
1036 int status;
1115−
1037+
1116 if (sender && sender->active == 0) { return NULL; } // No VM to receive from
1038 if (sender && sender->active == 0) { return NULL; } // No VM to receive from
1117
1039
1118 pthread_mutex_lock(&vm->inbox_block);
1040 pthread_mutex_lock(&vm->inbox_block);
@@ -1132,6 +1054,7 @@ Msg* idris_recvMessageFrom(VM* vm, int channel_id, VM* sender) {
1132 pthread_mutex_unlock(&vm->inbox_block);
1054 pthread_mutex_unlock(&vm->inbox_block);
1133
1055
1134 if (msg != NULL) {
1056 if (msg != NULL) {
1057+ ret = malloc(sizeof(*ret));
1135 ret->msg = msg->msg;
1058 ret->msg = msg->msg;
1136 ret->sender = msg->sender;
1059 ret->sender = msg->sender;
1137
1060
@@ -1158,7 +1081,6 @@ Msg* idris_recvMessageFrom(VM* vm, int channel_id, VM* sender) {
1158 fprintf(stderr, "No messages waiting");
1081 fprintf(stderr, "No messages waiting");
1159 exit(-1);
1082 exit(-1);
1160 }
1083 }
1161−
1162 return ret;
1084 return ret;
1163}
1085}
1164#endif
1086#endif
@@ -1187,26 +1109,16 @@ char* idris_showerror(int err) {
1187 return strerror(err);
1109 return strerror(err);
1188}
1110}
1189
1111
1190−VAL* nullary_cons;
1112+Con nullary_cons[256];
1191
1113
1192void init_nullaries(void) {
1114void init_nullaries(void) {
1193 int i;
1115 int i;
1194− VAL cl;
1195− nullary_cons = malloc(256 * sizeof(VAL));
1196 for(i = 0; i < 256; ++i) {
1116 for(i = 0; i < 256; ++i) {
1117+ Con * cl = nullary_cons + i;
1197− cl = malloc(sizeof(Closure));
1118+ cl->hdr.sz = sizeof(*cl);
1198 SETTY(cl, CT_CON);
1119 SETTY(cl, CT_CON);
1199− cl->info.c.tag_arity = i << 8;
1120+ cl->tag = i;
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]);
1208 }
1121 }
1209− free(nullary_cons);
1210}
1122}
1211
1123
1212int __idris_argc;
1124int __idris_argc;
rts/idris_rts.h+191−112
@@ -1,21 +1,19 @@
1#ifndef _IDRISRTS_H
1#ifndef _IDRISRTS_H
2#define _IDRISRTS_H
2#define _IDRISRTS_H
3
3
4+#include <assert.h>
4#include <stdlib.h>
5#include <stdlib.h>
5#include <stdio.h>
6#include <stdio.h>
7+#ifdef HAS_PTHREAD
6#include <string.h>
8#include <string.h>
7#include <stdarg.h>
9#include <stdarg.h>
8−#ifdef HAS_PTHREAD
9#include <pthread.h>
10#include <pthread.h>
10#endif
11#endif
11−#include <stdint.h>
12−#if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__DragonFly__)
13−#include <signal.h>
14−#endif
15
12
16#include "idris_heap.h"
13#include "idris_heap.h"
17#include "idris_stats.h"
14#include "idris_stats.h"
18
15
16+
19#ifndef EXIT_SUCCESS
17#ifndef EXIT_SUCCESS
20#define EXIT_SUCCESS 0
18#define EXIT_SUCCESS 0
21#endif
19#endif
@@ -25,68 +23,97 @@
25
23
26// Closures
24// Closures
27typedef enum {
25typedef enum {
28− CT_CON, CT_ARRAY, CT_INT, CT_BIGINT, CT_FLOAT, CT_STRING, CT_STROFFSET,
26+ CT_CON, CT_ARRAY, CT_INT, CT_BIGINT,
27+ CT_FLOAT, CT_STRING, CT_STROFFSET, CT_BITS32,
29− CT_BITS8, CT_BITS16, CT_BITS32, CT_BITS64, CT_UNIT, CT_PTR, CT_REF,
28+ CT_BITS64, CT_PTR, CT_REF, CT_FWD,
30− CT_FWD, CT_MANAGEDPTR, CT_RAWDATA, CT_CDATA
29+ CT_MANAGEDPTR, CT_RAWDATA, CT_CDATA
31} ClosureType;
30} ClosureType;
32
31
33−typedef struct Closure *VAL;
32+typedef struct Hdr {
34−
33+ uint8_t ty;
35−// A constructor, consisting of a tag, an arity (16 bits each of the
34+ uint8_t u8;
36−// tag_arity field) and arguments
35+ uint16_t u16;
37−typedef struct {
36+ uint32_t sz;
38− uint32_t tag_arity;
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;
39− VAL args[];
48+ VAL args[0];
40−} con;
49+} Con;
41−
50+
42−// An array; similar to a constructor but with a length, and contents
51+typedef struct Array {
43−// initialised to NULL (high level Idris programs are responsible for
52+ Hdr hdr;
44−// initialising them properly)
53+ VAL array[0];
54+} Array;
55+
56+typedef struct BigInt {
57+ Hdr hdr;
58+ char big[0];
59+} BigInt;
60+
45−typedef struct {
61+typedef struct Float {
46− uint32_t length;
62+ Hdr hdr;
47− VAL content[];
63+ double f;
48−} array;
64+} Float;
49−
65+
50−typedef struct {
66+typedef struct String {
67+ Hdr hdr;
68+ size_t slen;
51− VAL str;
69+ char str[0];
70+} String;
71+
72+typedef struct StrOffset {
73+ Hdr hdr;
74+ String * base;
52 size_t offset;
75 size_t offset;
53} StrOffset;
76} StrOffset;
54
77
55−typedef struct {
78+typedef struct Bits32 {
56− char* str;
79+ Hdr hdr;
57− size_t len; // Cached strlen (we do 'strlen' a lot)
80+ uint32_t bits32;
58−} String;
81+} Bits32;
59−
82+
60−// A foreign pointer, managed by the idris GC
83+typedef struct Bits64 {
84+ Hdr hdr;
85+ uint64_t bits64;
86+} Bits64;
87+
61−typedef struct {
88+typedef struct Ptr {
62− size_t size;
89+ Hdr hdr;
63− void* data;
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];
64} ManagedPtr;
106} ManagedPtr;
65
107
66−typedef struct Closure {
108+typedef struct RawData {
67−// Use top 16 bits of ty for saying which heap value is in
109+ Hdr hdr;
68−// Bottom 16 bits for closure type
110+ char raw[0];
69−//
111+} RawData;
70−// NOTE: ty can not have type ClosureType because ty must be a
112+
71−// uint32_t but enum is platform dependent
113+typedef struct CDataC {
72− uint32_t ty;
114+ Hdr hdr;
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;
115+ CHeapItem * item;
87− size_t size;
116+} CDataC;
88− } info;
89−} Closure;
90
117
91struct VM;
118struct VM;
92
119
@@ -185,38 +212,48 @@ void init_threadkeys(void);
185
212
186// Functions all take a pointer to their VM, and previous stack base,
213// Functions all take a pointer to their VM, and previous stack base,
187// and return nothing.
214// and return nothing.
188−typedef void(*func)(VM*, VAL*);
215+typedef void*(*func)(VM*, VAL*);
189
216
190// Register access
217// Register access
191
218
192#define RVAL (vm->ret)
219#define RVAL (vm->ret)
193−#define LOC(x) (*(vm->valstack_base + (x)))
220+#define LOC(x) (vm->valstack_base[x])
194−#define TOP(x) (*(vm->valstack_top + (x)))
221+#define TOP(x) (vm->valstack_top[x])
195#define REG1 (vm->reg1)
222#define REG1 (vm->reg1)
196
223
197// Retrieving values
224// Retrieving values
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+
198−#define GETSTR(x) (ISSTR(x) ? (((VAL)(x))->info.str.str) : GETSTROFF(x))
234+#define GETSTR(x) (ISSTR(x) ? getstr((String*)(x)) : GETSTROFF(x))
199−#define GETSTRLEN(x) (ISSTR(x) ? (((VAL)(x))->info.str.len) : GETSTROFFLEN(x))
235+#define GETSTRLEN(x) (ISSTR(x) ? getstrlen((String*)(x)) : GETSTROFFLEN(x))
200−#define GETPTR(x) (((VAL)(x))->info.ptr)
236+#define GETPTR(x) (((Ptr*)(x))->ptr)
201−#define GETMPTR(x) (((VAL)(x))->info.mptr->data)
237+#define GETMPTR(x) (((ManagedPtr*)(x))->mptr)
202−#define GETFLOAT(x) (((VAL)(x))->info.f)
238+#define GETFLOAT(x) (((Float*)(x))->f)
203−#define GETCDATA(x) (((VAL)(x))->info.c_heap_item)
239+#define GETCDATA(x) (((CDataC*)(x))->item)
204−
240+
205−#define GETBITS8(x) (((VAL)(x))->info.bits8)
241+#define GETBITS8(x) (GETINT(x))
206−#define GETBITS16(x) (((VAL)(x))->info.bits16)
242+#define GETBITS16(x) (GETINT(x))
207−#define GETBITS32(x) (((VAL)(x))->info.bits32)
243+#define GETBITS32(x) (((Bits32*)(x))->bits32)
208−#define GETBITS64(x) (((VAL)(x))->info.bits64)
244+#define GETBITS64(x) (((Bits64*)(x))->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)) )
212
245
213// Already checked it's a CT_CON
246// Already checked it's a CT_CON
214−#define CTAG(x) (((x)->info.c.tag_arity) >> 8)
247+#define CTAG(x) (((Con*)(x))->tag)
215−#define CARITY(x) ((x)->info.c.tag_arity & 0x000000ff)
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)) )
216
252
253+#define CELEM(x) (((x)->hdr.sz - sizeof(Array)) / sizeof(VAL))
217
254
218−#define GETTY(x) ((x)->ty)
255+#define GETTY(x) (ISINT(x)? CT_INT : (ClosureType)((x)->hdr.ty))
219−#define SETTY(x,t) ((x)->ty = t)
256+#define SETTY(x,t) ((x)->hdr.ty = t)
220
257
221// Integers, floats and operators
258// Integers, floats and operators
222
259
@@ -241,25 +278,33 @@ typedef intptr_t i_int;
241#ifdef IDRIS_TRACE
278#ifdef IDRIS_TRACE
242#define TRACE idris_trace(vm, __FUNCTION__, __LINE__);
279#define TRACE idris_trace(vm, __FUNCTION__, __LINE__);
243#else
280#else
244−#define TRACE
281+#define TRACE
245#endif
282#endif
246
283
247#define INITFRAME TRACE\
284#define INITFRAME TRACE\
248− __attribute__((unused)) VAL* myoldbase
285+ __attribute__((unused)) VAL* myoldbase;\
249−
286+ void* callres
287+
250−#define REBASE vm->valstack_base = oldbase
288+#define REBASE vm->valstack_base = oldbase; return NULL
289+#define RESERVE(x) do { \
251−#define RESERVE(x) if (vm->valstack_top+(x) > vm->stack_max) { stackOverflow(); } \
290+ if (vm->valstack_top+(x) > vm->stack_max) { stackOverflow(); } \
252− else { memset(vm->valstack_top, 0, (x)*sizeof(VAL)); }
291+ else { memset(vm->valstack_top, 0, (x)*sizeof(VAL)); } \
292+ } while(0)
253#define ADDTOP(x) vm->valstack_top += (x)
293#define ADDTOP(x) vm->valstack_top += (x)
254#define TOPBASE(x) vm->valstack_top = vm->valstack_base + (x)
294#define TOPBASE(x) vm->valstack_top = vm->valstack_base + (x)
255#define BASETOP(x) vm->valstack_base = vm->valstack_top + (x)
295#define BASETOP(x) vm->valstack_base = vm->valstack_top + (x)
256#define STOREOLD myoldbase = vm->valstack_base
296#define STOREOLD myoldbase = vm->valstack_base
297+
257−#define CALL(f) f(vm, myoldbase);
298+#define CALL(f) callres = f(vm, myoldbase); \
299+ while(callres!=NULL) { \
300+ callres = ((func)(callres))(vm, myoldbase); \
301+ }
258−#define TAILCALL(f) f(vm, oldbase);
302+#define TAILCALL(f) return (void*)(f);
259
303
260// Creating new values (each value placed at the top of the stack)
304// Creating new values (each value placed at the top of the stack)
261VAL MKFLOAT(VM* vm, double val);
305VAL MKFLOAT(VM* vm, double val);
262VAL MKSTR(VM* vm, const char* str);
306VAL MKSTR(VM* vm, const char* str);
307+VAL MKSTRlen(VM* vm, const char* str, size_t size);
263VAL MKPTR(VM* vm, void* ptr);
308VAL MKPTR(VM* vm, void* ptr);
264VAL MKMPTR(VM* vm, void* ptr, size_t size);
309VAL MKMPTR(VM* vm, void* ptr, size_t size);
265VAL MKB8(VM* vm, uint8_t b);
310VAL MKB8(VM* vm, uint8_t b);
@@ -270,9 +315,9 @@ VAL MKCDATA(VM* vm, CHeapItem * item);
270
315
271// following versions don't take a lock when allocating
316// following versions don't take a lock when allocating
272VAL MKFLOATc(VM* vm, double val);
317VAL MKFLOATc(VM* vm, double val);
273−VAL MKSTROFFc(VM* vm, StrOffset* off);
318+VAL MKSTROFFc(VM* vm, VAL basestr);
274VAL MKSTRc(VM* vm, char* str);
319VAL MKSTRc(VM* vm, char* str);
275−VAL MKSTRclen(VM* vm, char* str, int len);
320+VAL MKSTRclen(VM* vm, char* str, size_t len);
276VAL MKPTRc(VM* vm, void* ptr);
321VAL MKPTRc(VM* vm, void* ptr);
277VAL MKMPTRc(VM* vm, void* ptr, size_t size);
322VAL MKMPTRc(VM* vm, void* ptr, size_t size);
278VAL MKCDATAc(VM* vm, CHeapItem * item);
323VAL MKCDATAc(VM* vm, CHeapItem * item);
@@ -280,15 +325,16 @@ VAL MKCDATAc(VM* vm, CHeapItem * item);
280char* GETSTROFF(VAL stroff);
325char* GETSTROFF(VAL stroff);
281size_t GETSTROFFLEN(VAL stroff);
326size_t GETSTROFFLEN(VAL stroff);
282
327
283−// #define SETTAG(x, a) (x)->info.c.tag = (a)
284−#define SETARG(x, i, a) ((x)->info.c.args)[i] = ((VAL)(a))
328+#define SETARG(x, i, a) (((Con*)(x))->args)[i] = ((VAL)(a))
285−#define GETARG(x, i) ((x)->info.c.args)[i]
329+#define GETARG(x, i) (((Con*)(x))->args[i])
286
330
287#define PROJECT(vm,r,loc,num) \
331#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)
289#define SLIDE(vm, args) \
333#define SLIDE(vm, args) \
290 memcpy(&(LOC(0)), &(TOP(0)), sizeof(VAL)*args)
334 memcpy(&(LOC(0)), &(TOP(0)), sizeof(VAL)*args)
291
335
336+void* iallocate(VM *, size_t, int);
337+
292void* allocate(size_t size, int outerlock);
338void* allocate(size_t size, int outerlock);
293// void* allocCon(VM* vm, int arity, int outerlock);
339// void* allocCon(VM* vm, int arity, int outerlock);
294
340
@@ -298,8 +344,8 @@ void* allocate(size_t size, int outerlock);
298// idris_doneAlloc *must* be called when allocation from C is done (as it
344// idris_doneAlloc *must* be called when allocation from C is done (as it
299// may take a lock if other threads are running).
345// may take a lock if other threads are running).
300
346
301−void idris_requireAlloc(size_t size);
347+void idris_requireAlloc(VM *, size_t size);
302−void idris_doneAlloc(void);
348+void idris_doneAlloc(VM *);
303
349
304// public interface to allocation (note that this may move other pointers
350// public interface to allocation (note that this may move other pointers
305// if allocating beyond the limits given by idris_requireAlloc!)
351// if allocating beyond the limits given by idris_requireAlloc!)
@@ -308,29 +354,44 @@ void* idris_alloc(size_t size);
308void* idris_realloc(void* old, size_t old_size, size_t size);
354void* idris_realloc(void* old, size_t old_size, size_t size);
309void idris_free(void* ptr, size_t size);
355void idris_free(void* ptr, size_t size);
310
356
311−#define allocCon(cl, vm, t, a, o) \
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) {
312− cl = allocate(sizeof(Closure) + sizeof(VAL)*a, o); \
367+ Con * cl = iallocate(vm, sizeof(*cl) + sizeof(VAL) * arity, outer);
313− SETTY(cl, CT_CON); \
368+ SETTY(cl, CT_CON);
314− cl->info.c.tag_arity = ((t) << 8) | (a);
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+
315
381
316−#define updateCon(cl, old, t, a) \
382+#define allocCon(cl, vm, t, a, o) (cl) = (VAL)allocConF(vm, t, a, o)
317− cl = old; \
318− SETTY(cl, CT_CON); \
319− cl->info.c.tag_arity = ((t) << 8) | (a);
320
383
321−#define NULL_CON(x) nullary_cons[x]
384+#define updateCon(cl, old, tag, arity) (cl) = (old); updateConF(cl, tag, arity)
322
385
323−#define allocArray(cl, vm, len, o) \
386+#define NULL_CON(x) ((VAL)(nullary_cons + x))
324− cl = allocate(sizeof(Closure) + sizeof(VAL)*len, o); \
387+
325− SETTY(cl, CT_ARRAY); \
388+#define allocArray(cl, vm, len, o) (cl) = (VAL)allocArrayF(vm, len, o)
326− cl->info.arr.length = len;
327
389
328int idris_errno(void);
390int idris_errno(void);
329char* idris_showerror(int err);
391char* idris_showerror(int err);
330
392
331−extern VAL* nullary_cons;
393+extern Con nullary_cons[];
332void init_nullaries(void);
394void init_nullaries(void);
333−void free_nullaries(void);
334
395
335void init_signals(void);
396void init_signals(void);
336
397
@@ -460,4 +521,22 @@ void stackOverflow(void);
460
521
461#include "idris_gmp.h"
522#include "idris_gmp.h"
462
523
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+
463#endif
534#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 @@
6#include <fcntl.h>
6#include <fcntl.h>
7#include <errno.h>
7#include <errno.h>
8#include <sys/stat.h>
8#include <sys/stat.h>
9−#include <stdio.h>
10#include <time.h>
9#include <time.h>
11#include <dirent.h>
10#include <dirent.h>
11+#include <unistd.h>
12
12
13#ifdef _WIN32
13#ifdef _WIN32
14int win_fpoll(void* h);
14int win_fpoll(void* h);
@@ -60,6 +60,42 @@ int fileSize(void* h) {
60 }
60 }
61}
61}
62
62
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+
63typedef struct {
99typedef struct {
64 DIR* dirptr;
100 DIR* dirptr;
65 int error;
101 int error;
@@ -79,7 +115,7 @@ void* idris_dirOpen(char* dname) {
79
115
80void idris_dirClose(void* h) {
116void idris_dirClose(void* h) {
81 DirInfo* di = (DirInfo*)h;
117 DirInfo* di = (DirInfo*)h;
82−
118+
83 closedir(di->dirptr);
119 closedir(di->dirptr);
84 free(di);
120 free(di);
85}
121}
@@ -104,6 +140,10 @@ int idris_mkdir(char* dname) {
104#endif
140#endif
105}
141}
106
142
143+int idris_chdir(char* dname) {
144+ return chdir(dname);
145+}
146+
107int idris_dirError(void *dptr) {
147int idris_dirError(void *dptr) {
108 return ((DirInfo*)dptr)->error;
148 return ((DirInfo*)dptr)->error;
109}
149}
@@ -219,4 +259,3 @@ VAL idris_getString(VM* vm, void* buffer) {
219 free(sb);
259 free(sb);
220 return str;
260 return str;
221}
261}
222−
rts/idris_stdfgn.h+6
@@ -15,12 +15,18 @@ int fileError(void* h);
15// Returns a negative number if not a file (e.g. directory or device)
15// Returns a negative number if not a file (e.g. directory or device)
16int fileSize(void* h);
16int fileSize(void* h);
17
17
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+
18void* idris_dirOpen(char* dname);
23void* idris_dirOpen(char* dname);
19void idris_dirClose(void* h);
24void idris_dirClose(void* h);
20char* idris_nextDirEntry(void* h);
25char* idris_nextDirEntry(void* h);
21
26
22// Create a directory; return 0 on success or -1 on failure
27// Create a directory; return 0 on success or -1 on failure
23int idris_mkdir(char* dname);
28int idris_mkdir(char* dname);
29+int idris_chdir(char* dname);
24
30
25// Return 0 if ok, or -1 if there was an error with the given directory
31// Return 0 if ok, or -1 if there was an error with the given directory
26// (like ferror)
32// (like ferror)
src/IRTS/CodegenC.hs+75−69
@@ -79,18 +79,22 @@ codegenC' defs out exec incs objs libs flags exports iface dbg
79 libFlags <- getLibFlags
79 libFlags <- getLibFlags
80 incFlags <- getIncFlags
80 incFlags <- getIncFlags
81 envFlags <- getEnvFlags
81 envFlags <- getEnvFlags
82+ let stripFlag = if isDarwin then "-dead_strip" else "-Wl,-gc-sections"
82− let stackFlag = if isWindows then ["-Wl,--stack,16777216"] else []
83+ let stackFlags = if isWindows then ["-Wl,--stack,16777216"] else []
84+ let linkFlags = stripFlag : stackFlags
83 let args = gccDbg dbg ++
85 let args = gccDbg dbg ++
84 gccFlags iface ++
86 gccFlags iface ++
85 -- # Any flags defined here which alter the RTS API must also be added to config.mk
87 -- # Any flags defined here which alter the RTS API must also be added to config.mk
88+ [ "-std=c99", "-pipe"
89+ , "-fdata-sections", "-ffunction-sections"
86− ["-std=c99", "-D_POSIX_C_SOURCE=200809L", "-DHAS_PTHREAD", "-DIDRIS_ENABLE_STATS",
90+ , "-D_POSIX_C_SOURCE=200809L", "-DHAS_PTHREAD", "-DIDRIS_ENABLE_STATS"
87− "-I."] ++ objs ++ envFlags ++
91+ , "-I."] ++ objs ++ envFlags ++
88− (if (exec == Executable) then [] else ["-c"]) ++
92+ (if (exec == Executable) then linkFlags else ["-c"]) ++
89 [tmpn] ++
93 [tmpn] ++
90 (if not iface then libFlags else []) ++
94 (if not iface then libFlags else []) ++
91 incFlags ++
95 incFlags ++
92 (if not iface then libs else []) ++
96 (if not iface then libs else []) ++
93− flags ++ stackFlag ++
97+ flags ++
94 ["-o", out]
98 ["-o", out]
95-- putStrLn (show args)
99-- putStrLn (show args)
96 exit <- rawSystem comp args
100 exit <- rawSystem comp args
@@ -113,11 +117,7 @@ gccFlags i = if i then ["-fwrapv"]
113 else ["-fwrapv", "-fno-strict-overflow"]
117 else ["-fwrapv", "-fno-strict-overflow"]
114
118
115gccDbg DEBUG = ["-g"]
119gccDbg DEBUG = ["-g"]
116−-- clang optimises sibling calls in O1, but gcc doesn't
120+gccDbg _ = []
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"]
121
121
122cname :: Name -> String
122cname :: Name -> String
123cname n = "_idris_" ++ concatMap cchar (showCG n)
123cname n = "_idris_" ++ concatMap cchar (showCG n)
@@ -133,14 +133,14 @@ creg (T i) = "TOP(" ++ show i ++ ")"
133creg Tmp = "REG1"
133creg Tmp = "REG1"
134
134
135toDecl :: Name -> String
135toDecl :: Name -> String
136−toDecl f = "void " ++ cname f ++ "(VM*, VAL*);\n"
136+toDecl f = "void* " ++ cname f ++ "(VM*, VAL*);\n"
137
137
138toC :: Name -> [BC] -> String
138toC :: Name -> [BC] -> String
139toC f code
139toC f code
140 = -- "/* " ++ show code ++ "*/\n\n" ++
140 = -- "/* " ++ show code ++ "*/\n\n" ++
141− "void " ++ cname f ++ "(VM* vm, VAL* oldbase) {\n" ++
141+ "void* " ++ cname f ++ "(VM* vm, VAL* oldbase) {\n" ++
142− indent 1 ++ "INITFRAME;\n" ++
142+ indent 1 ++ "INITFRAME;\nloop:\n" ++
143− concatMap (bcc 1) code ++ "}\n\n"
143+ concatMap (bcc f 1) code ++ "}\n\n"
144
144
145showCStr :: String -> String
145showCStr :: String -> String
146showCStr s = '"' : foldr ((++) . showChar) "\"" s
146showCStr s = '"' : foldr ((++) . showChar) "\"" s
@@ -176,9 +176,9 @@ showCStr s = '"' : foldr ((++) . showChar) "\"" s
176 2 -> s
176 2 -> s
177 _ -> error $ "Can't happen: String of invalid length " ++ show s
177 _ -> error $ "Can't happen: String of invalid length " ++ show s
178
178
179−bcc :: Int -> BC -> String
179+bcc :: Name -> Int -> BC -> String
180−bcc i (ASSIGN l r) = indent i ++ creg l ++ " = " ++ creg r ++ ";\n"
180+bcc f i (ASSIGN l r) = indent i ++ creg l ++ " = " ++ creg r ++ ";\n"
181−bcc i (ASSIGNCONST l c)
181+bcc f i (ASSIGNCONST l c)
182 = indent i ++ creg l ++ " = " ++ mkConst c ++ ";\n"
182 = indent i ++ creg l ++ " = " ++ mkConst c ++ ";\n"
183 where
183 where
184 mkConst (I i) = "MKINT(" ++ show i ++ ")"
184 mkConst (I i) = "MKINT(" ++ show i ++ ")"
@@ -199,10 +199,10 @@ bcc i (ASSIGNCONST l c)
199 mkConst c | isTypeConst c = "MKINT(42424242)"
199 mkConst c | isTypeConst c = "MKINT(42424242)"
200 mkConst c = error $ "mkConst of (" ++ show c ++ ") not implemented"
200 mkConst c = error $ "mkConst of (" ++ show c ++ ") not implemented"
201
201
202−bcc i (UPDATE l r) = indent i ++ creg l ++ " = " ++ creg r ++ ";\n"
202+bcc f i (UPDATE l r) = indent i ++ creg l ++ " = " ++ creg r ++ ";\n"
203−bcc i (MKCON l loc tag []) | tag < 256
203+bcc f i (MKCON l loc tag []) | tag < 256
204 = indent i ++ creg l ++ " = NULL_CON(" ++ show tag ++ ");\n"
204 = 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)
206 = indent i ++ alloc loc tag ++
206 = indent i ++ alloc loc tag ++
207 indent i ++ setArgs 0 args ++ "\n" ++
207 indent i ++ setArgs 0 args ++ "\n" ++
208 indent i ++ creg l ++ " = " ++ creg Tmp ++ ";\n"
208 indent i ++ creg l ++ " = " ++ creg Tmp ++ ";\n"
@@ -216,21 +216,21 @@ bcc i (MKCON l loc tag args)
216 = "updateCon(" ++ creg Tmp ++ ", " ++ creg old ++ ", " ++ show tag ++ ", " ++
216 = "updateCon(" ++ creg Tmp ++ ", " ++ creg old ++ ", " ++ show tag ++ ", " ++
217 show (length args) ++ ");\n"
217 show (length args) ++ ");\n"
218
218
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 ++
220 ", " ++ show a ++ ");\n"
220 ", " ++ show a ++ ");\n"
221−bcc i (PROJECTINTO r t idx)
221+bcc f i (PROJECTINTO r t idx)
222 = indent i ++ creg r ++ " = GETARG(" ++ creg t ++ ", " ++ show idx ++ ");\n"
222 = 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)
224 = indent i ++ showCode i alt
224 = indent i ++ showCode i alt
225 where
225 where
226 showCode :: Int -> [BC] -> String
226 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 ++
228 indent i ++ "}\n"
228 indent i ++ "}\n"
229−bcc i (CASE True r code def)
229+bcc f i (CASE True r code def)
230 | length code < 6 && length code > 1 = showCase i def code
230 | length code < 6 && length code > 1 = showCase i def code
231 where
231 where
232 showCode :: Int -> [BC] -> String
232 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 ++
234 indent i ++ "}\n"
234 indent i ++ "}\n"
235
235
236 showCase :: Int -> Maybe [BC] -> [(Int, [BC])] -> String
236 showCase :: Int -> Maybe [BC] -> [(Int, [BC])] -> String
@@ -240,7 +240,7 @@ bcc i (CASE True r code def)
240 = indent i ++ "if (CTAG(" ++ creg r ++ ") == " ++ show t ++ ") " ++ showCode i c
240 = indent i ++ "if (CTAG(" ++ creg r ++ ") == " ++ show t ++ ") " ++ showCode i c
241 ++ indent i ++ "else\n" ++ showCase i def cs
241 ++ indent i ++ "else\n" ++ showCase i def cs
242
242
243−bcc i (CASE safe r code def)
243+bcc f i (CASE safe r code def)
244 = indent i ++ "switch(" ++ ctag safe ++ "(" ++ creg r ++ ")) {\n" ++
244 = indent i ++ "switch(" ++ ctag safe ++ "(" ++ creg r ++ ")) {\n" ++
245 concatMap (showCase i) code ++
245 concatMap (showCase i) code ++
246 showDef i def ++
246 showDef i def ++
@@ -250,11 +250,12 @@ bcc i (CASE safe r code def)
250 ctag False = "TAG"
250 ctag False = "TAG"
251
251
252 showCase i (t, bc) = indent i ++ "case " ++ show t ++ ":\n"
252 showCase i (t, bc) = indent i ++ "case " ++ show t ++ ":\n"
253− ++ concatMap (bcc (i+1)) bc ++ indent (i + 1) ++ "break;\n"
253+ ++ concatMap (bcc f (i+1)) bc ++ indent (i + 1) ++ "break;\n"
254− showDef i Nothing = ""
254+ showDef i Nothing = indent i ++ "default:\n" ++
255+ indent (i + 1) ++ "return NULL;\n"
255 showDef i (Just c) = indent i ++ "default:\n"
256 showDef i (Just c) = indent i ++ "default:\n"
256− ++ concatMap (bcc (i+1)) c ++ indent (i + 1) ++ "break;\n"
257+ ++ concatMap (bcc f (i+1)) c ++ indent (i + 1) ++ "break;\n"
257−bcc i (CONSTCASE r code def)
258+bcc f i (CONSTCASE r code def)
258 | intConsts code
259 | intConsts code
259-- = indent i ++ "switch(GETINT(" ++ creg r ++ ")) {\n" ++
260-- = indent i ++ "switch(GETINT(" ++ creg r ++ ")) {\n" ++
260-- concatMap (showCase i) code ++
261-- concatMap (showCase i) code ++
@@ -286,65 +287,67 @@ bcc i (CONSTCASE r code def)
286
287
287 strCase sv (s, bc) =
288 strCase sv (s, bc) =
288 indent i ++ "if (strcmp(" ++ sv ++ ", " ++ show s ++ ") == 0) {\n" ++
289 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"
290 biCase bv (BI b, bc) =
291 biCase bv (BI b, bc) =
291 indent i ++ "if (bigEqConst(" ++ bv ++ ", " ++ show b ++ ")) {\n"
292 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"
293 iCase v (I b, bc) =
294 iCase v (I b, bc) =
294 indent i ++ "if (GETINT(" ++ v ++ ") == " ++ show b ++ ") {\n"
295 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"
296 iCase v (Ch b, bc) =
297 iCase v (Ch b, bc) =
297 indent i ++ "if (GETINT(" ++ v ++ ") == " ++ show (fromEnum b) ++ ") {\n"
298 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"
299 iCase v (B8 w, bc) =
300 iCase v (B8 w, bc) =
300 indent i ++ "if (GETBITS8(" ++ v ++ ") == " ++ show (fromEnum w) ++ ") {\n"
301 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"
302 iCase v (B16 w, bc) =
303 iCase v (B16 w, bc) =
303 indent i ++ "if (GETBITS16(" ++ v ++ ") == " ++ show (fromEnum w) ++ ") {\n"
304 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"
305 iCase v (B32 w, bc) =
306 iCase v (B32 w, bc) =
306 indent i ++ "if (GETBITS32(" ++ v ++ ") == " ++ show (fromEnum w) ++ ") {\n"
307 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"
308 iCase v (B64 w, bc) =
309 iCase v (B64 w, bc) =
309 indent i ++ "if (GETBITS64(" ++ v ++ ") == " ++ show (fromEnum w) ++ ") {\n"
310 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"
311 showDefS i Nothing = ""
312 showDefS i Nothing = ""
312− showDefS i (Just c) = concatMap (bcc (i+1)) c
313+ showDefS i (Just c) = concatMap (bcc f (i+1)) c
313−
314+
314−bcc i (CALL n) = indent i ++ "CALL(" ++ cname n ++ ");\n"
315+bcc f i (CALL n) = indent i ++ "CALL(" ++ cname n ++ ");\n"
315−bcc i (TAILCALL n) = indent i ++ "TAILCALL(" ++ 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"
316−bcc i (SLIDE n) = indent i ++ "SLIDE(vm, " ++ show n ++ ");\n"
319+bcc f i (SLIDE n) = indent i ++ "SLIDE(vm, " ++ show n ++ ");\n"
317−bcc i REBASE = indent i ++ "REBASE;\n"
320+bcc f i REBASE = indent i ++ "REBASE;\n"
318−bcc i (RESERVE 0) = ""
321+bcc f i (RESERVE 0) = ""
319−bcc i (RESERVE n) = indent i ++ "RESERVE(" ++ show n ++ ");\n"
322+bcc f i (RESERVE n) = indent i ++ "RESERVE(" ++ show n ++ ");\n"
320−bcc i (ADDTOP 0) = ""
323+bcc f i (ADDTOP 0) = ""
321−bcc i (ADDTOP n) = indent i ++ "ADDTOP(" ++ show n ++ ");\n"
324+bcc f i (ADDTOP n) = indent i ++ "ADDTOP(" ++ show n ++ ");\n"
322−bcc i (TOPBASE n) = indent i ++ "TOPBASE(" ++ show n ++ ");\n"
325+bcc f i (TOPBASE n) = indent i ++ "TOPBASE(" ++ show n ++ ");\n"
323−bcc i (BASETOP n) = indent i ++ "BASETOP(" ++ show n ++ ");\n"
326+bcc f i (BASETOP n) = indent i ++ "BASETOP(" ++ show n ++ ");\n"
324−bcc i STOREOLD = indent i ++ "STOREOLD;\n"
327+bcc f i STOREOLD = indent i ++ "STOREOLD;\n"
325−bcc i (OP l fn args) = indent i ++ doOp (creg l ++ " = ") fn args ++ ";\n"
328+bcc f i (OP l fn args) = indent i ++ doOp (creg l ++ " = ") fn args ++ ";\n"
326−bcc i (FOREIGNCALL l rty (FStr ('#':name)) [])
329+bcc f i (FOREIGNCALL l rty (FStr ('#':name)) [])
327 = indent i ++
330 = indent i ++
328 c_irts (toFType rty) (creg l ++ " = ") name ++ ";\n"
331 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)) [])
330 = indent i ++
333 = indent i ++
331 c_irts (toFType rty) (creg l ++ " = ") fn ++ ";\n"
334 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"
333 = indent i ++
336 = indent i ++
334 c_irts (toFType rty) (creg l ++ " = ")
337 c_irts (toFType rty) (creg l ++ " = ")
335 ("_idris_get_wrapper(" ++ creg (snd x) ++ ")") ++ ";\n"
338 ("_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"
337 = indent i ++ c_irts (toFType rty) (creg l ++ " = ")
340 = indent i ++ c_irts (toFType rty) (creg l ++ " = ")
338 ("(*(" ++ cFnSig "" rty xs ++ ") GETPTR(" ++ creg (snd x) ++ "))" ++
341 ("(*(" ++ cFnSig "" rty xs ++ ") GETPTR(" ++ creg (snd x) ++ "))" ++
339 "(" ++ showSep "," (map fcall xs) ++ ")") ++ ";\n"
342 "(" ++ showSep "," (map fcall xs) ++ ")") ++ ";\n"
340−bcc i (FOREIGNCALL l rty (FStr fn) args)
343+bcc f i (FOREIGNCALL l rty (FStr fn) args)
341 = indent i ++
344 = indent i ++
342 c_irts (toFType rty) (creg l ++ " = ")
345 c_irts (toFType rty) (creg l ++ " = ")
343 (fn ++ "(" ++ showSep "," (map fcall args) ++ ")") ++ ";\n"
346 (fn ++ "(" ++ showSep "," (map fcall args) ++ ")") ++ ";\n"
344−bcc i (FOREIGNCALL l rty _ args) = error "Foreign Function calls cannot be partially applied, without being inlined."
347+bcc f 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
348+bcc f 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"
349+bcc f 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"
350+-- bcc f i c = error (show c) -- indent i ++ "// not done yet\n"
348
351
349fcall (t, arg) = irts_c (toFType t) (creg arg)
352fcall (t, arg) = irts_c (toFType t) (creg arg)
350-- Deconstruct the Foreign type in the defunctionalised expression and build
353-- 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
396irts_c (FArith (ATInt ITNative)) x = "GETINT(" ++ x ++ ")"
399irts_c (FArith (ATInt ITNative)) x = "GETINT(" ++ x ++ ")"
397irts_c (FArith (ATInt ITChar)) x = irts_c (FArith (ATInt ITNative)) x
400irts_c (FArith (ATInt ITChar)) x = irts_c (FArith (ATInt ITNative)) x
398irts_c (FArith (ATInt (ITFixed ity))) x
401irts_c (FArith (ATInt (ITFixed ity))) x
399− = "(" ++ x ++ "->info.bits" ++ show (nativeTyWidth ity) ++ ")"
402+ = "GETBITS" ++ show (nativeTyWidth ity) ++ "(" ++ x ++ ")"
400irts_c FString x = "GETSTR(" ++ x ++ ")"
403irts_c FString x = "GETSTR(" ++ x ++ ")"
401irts_c FUnit x = x
404irts_c FUnit x = x
402irts_c FPtr x = "GETPTR(" ++ x ++ ")"
405irts_c FPtr x = "GETPTR(" ++ x ++ ")"
@@ -536,13 +539,13 @@ doOp v (LURem (ITFixed ty)) [x, y] = bitOp v "URem" ty [x, y]
536doOp v (LSRem (ATInt (ITFixed ty))) [x, y] = bitOp v "SRem" ty [x, y]
539doOp v (LSRem (ATInt (ITFixed ty))) [x, y] = bitOp v "SRem" ty [x, y]
537
540
538doOp v (LSExt (ITFixed from) ITBig) [x]
541doOp 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 ++ "))"
540doOp v (LSExt ITNative (ITFixed to)) [x]
543doOp v (LSExt ITNative (ITFixed to)) [x]
541 = v ++ "idris_b" ++ show (nativeTyWidth to) ++ "const(vm, GETINT(" ++ creg x ++ "))"
544 = v ++ "idris_b" ++ show (nativeTyWidth to) ++ "const(vm, GETINT(" ++ creg x ++ "))"
542doOp v (LSExt ITChar (ITFixed to)) [x]
545doOp v (LSExt ITChar (ITFixed to)) [x]
543 = doOp v (LSExt ITNative (ITFixed to)) [x]
546 = doOp v (LSExt ITNative (ITFixed to)) [x]
544doOp v (LSExt (ITFixed from) ITNative) [x]
547doOp 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 ++ ")))"
546doOp v (LSExt (ITFixed from) ITChar) [x]
549doOp v (LSExt (ITFixed from) ITChar) [x]
547 = doOp v (LSExt (ITFixed from) ITNative) [x]
550 = doOp v (LSExt (ITFixed from) ITNative) [x]
548doOp v (LSExt (ITFixed from) (ITFixed to)) [x]
551doOp v (LSExt (ITFixed from) (ITFixed to)) [x]
@@ -552,11 +555,11 @@ doOp v (LZExt ITNative (ITFixed to)) [x]
552doOp v (LZExt ITChar (ITFixed to)) [x]
555doOp v (LZExt ITChar (ITFixed to)) [x]
553 = doOp v (LZExt ITNative (ITFixed to)) [x]
556 = doOp v (LZExt ITNative (ITFixed to)) [x]
554doOp v (LZExt (ITFixed from) ITNative) [x]
557doOp 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 ++ "))"
556doOp v (LZExt (ITFixed from) ITChar) [x]
559doOp v (LZExt (ITFixed from) ITChar) [x]
557 = doOp v (LZExt (ITFixed from) ITNative) [x]
560 = doOp v (LZExt (ITFixed from) ITNative) [x]
558doOp v (LZExt (ITFixed from) ITBig) [x]
561doOp 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 ++ "))"
560doOp v (LZExt ITNative ITBig) [x]
563doOp v (LZExt ITNative ITBig) [x]
561 = v ++ "MKBIGUI(vm, (uintptr_t)GETINT(" ++ creg x ++ "))"
564 = v ++ "MKBIGUI(vm, (uintptr_t)GETINT(" ++ creg x ++ "))"
562doOp v (LZExt (ITFixed from) (ITFixed to)) [x]
565doOp v (LZExt (ITFixed from) (ITFixed to)) [x]
@@ -566,7 +569,7 @@ doOp v (LTrunc ITNative (ITFixed to)) [x]
566doOp v (LTrunc ITChar (ITFixed to)) [x]
569doOp v (LTrunc ITChar (ITFixed to)) [x]
567 = doOp v (LTrunc ITNative (ITFixed to)) [x]
570 = doOp v (LTrunc ITNative (ITFixed to)) [x]
568doOp v (LTrunc (ITFixed from) ITNative) [x]
571doOp 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 ++ "))"
570doOp v (LTrunc (ITFixed from) ITChar) [x]
573doOp v (LTrunc (ITFixed from) ITChar) [x]
571 = doOp v (LTrunc (ITFixed from) ITNative) [x]
574 = doOp v (LTrunc (ITFixed from) ITNative) [x]
572doOp v (LTrunc ITBig (ITFixed IT64)) [x]
575doOp v (LTrunc ITBig (ITFixed IT64)) [x]
@@ -886,7 +889,10 @@ getCallback bc = getCallback' (reverse bc)
886 getCallback' [] = []
889 getCallback' [] = []
887 findCons (c:cs) xs = findCon c xs ++ findCons cs xs
890 findCons (c:cs) xs = findCon c xs ++ findCons cs xs
888 findCons [] _ = []
891 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."
890 findCon c (_:xs) = findCon c xs
896 findCon c (_:xs) = findCon c xs
891 findCon c [] = []
897 findCon c [] = []
892
898
src/IRTS/JavaScript/Codegen.hs+6−1
@@ -5,7 +5,7 @@ Description : The JavaScript common code generator.
5License : BSD3
5License : BSD3
6Maintainer : The Idris Community.
6Maintainer : The Idris Community.
7-}
7-}
8−{-# LANGUAGE OverloadedStrings #-}
8+{-# LANGUAGE CPP, OverloadedStrings #-}
9
9
10module IRTS.JavaScript.Codegen( codegenJs
10module IRTS.JavaScript.Codegen( codegenJs
11 , CGConf(..)
11 , CGConf(..)
@@ -48,6 +48,11 @@ data CGStats = CGStats { usedBigInt :: Bool
48 , hiddenClasses :: Set HiddenClass
48 , hiddenClasses :: Set HiddenClass
49 }
49 }
50
50
51+#if (MIN_VERSION_base(4,11,0))
52+instance Semigroup CGStats where
53+ (<>) = mappend
54+#endif
55+
51-- If we generate code for two declarations we want to merge their code
56-- If we generate code for two declarations we want to merge their code
52-- generation stats.
57-- generation stats.
53instance Monoid CGStats where
58instance Monoid CGStats where
src/IRTS/Lang.hs+25
@@ -455,3 +455,28 @@ instance Show LExp where
455
455
456 showAlt env ind (LConstCase c e) = show c ++ " => " ++ show' env ind e
456 showAlt env ind (LConstCase c e) = show c ++ " => " ++ show' env ind e
457 showAlt env ind (LDefaultCase e) = "_ => " ++ show' env ind e
457 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
33-- uniqueness of variable names in the resulting definition, so invent
33-- uniqueness of variable names in the resulting definition, so invent
34-- a new name for every variable we encounter
34-- a new name for every variable we encounter
35doInline :: LDefs -> LDecl -> LDecl
35doInline :: LDefs -> LDecl -> LDecl
36+doInline = doInline' 1
37+
38+doInline' :: Int -> LDefs -> LDecl -> LDecl
39+doInline' 0 defs d = d
36−doInline defs d@(LConstructor _ _ _) = d
40+doInline' i defs d@(LConstructor _ _ _) = d
37−doInline defs (LFun opts topn args exp)
41+doInline' i defs (LFun opts topn args exp)
38 = let inl = evalState (eval [] initEnv [topn] defs exp)
42 = let inl = evalState (eval [] initEnv [topn] defs exp)
39 (length args)
43 (length args)
40 -- do some case floating, which might arise as a result
44 -- do some case floating, which might arise as a result
41 -- then, eta contract
45 -- then, eta contract
42 res = eta $ caseFloats 10 inl in
46 res = eta $ caseFloats 10 inl in
43 case res of
47 case res of
48+ LLam args' body ->
49+ doInline' (i - 1) defs $
44− LLam args' body -> LFun opts topn (map snd initNames ++ args') body
50+ LFun opts topn (map snd initNames ++ args') body
51+ _ -> doInline' (i - 1) defs $
45− _ -> LFun opts topn (map snd initNames) res
52+ LFun opts topn (map snd initNames) res
46 where
53 where
47 caseFloats 0 tm = tm
54 caseFloats 0 tm = tm
48 caseFloats n tm
55 caseFloats n tm
@@ -72,8 +79,8 @@ eval stk env rec defs (LLazyApp n es)
72eval stk env rec defs (LForce e)
79eval stk env rec defs (LForce e)
73 = do e' <- eval [] env rec defs e
80 = do e' <- eval [] env rec defs e
74 case e' of
81 case e' of
75− LLazyExp forced -> return $ unload stk forced
82+ LLazyExp forced -> eval stk env rec defs forced
76− LLazyApp n es -> return $ unload stk (LApp False (LV n) es)
83+ LLazyApp n es -> eval stk env rec defs (LApp False (LV n) es)
77 _ -> return (unload stk (LForce e'))
84 _ -> return (unload stk (LForce e'))
78eval stk env rec defs (LLazyExp e)
85eval stk env rec defs (LLazyExp e)
79 = unload stk <$> LLazyExp <$> eval [] env rec defs e
86 = 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)])
92 = do act' <- eval [] env rec defs (LApp False act [world])
99 = do act' <- eval [] env rec defs (LApp False act [world])
93 argn <- nextN
100 argn <- nextN
94 k' <- eval stk ((arg, LV argn) : env) rec defs (LApp False k [world])
101 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
95 return $ LLet argn act' k'
103 return $ LLet argn act' k'
96
104
97eval stk env rec defs (LApp t f es)
105eval stk env rec defs (LApp t f es)
@@ -105,16 +113,30 @@ eval stk env rec defs (LProj exp i)
105 = unload stk <$> (LProj <$> eval [] env rec defs exp <*> return i)
113 = unload stk <$> (LProj <$> eval [] env rec defs exp <*> return i)
106eval stk env rec defs (LCon loc i n es)
114eval stk env rec defs (LCon loc i n es)
107 = unload stk <$> (LCon loc i n <$> mapM (eval [] env rec defs) es)
115 = unload stk <$> (LCon loc i n <$> mapM (eval [] env rec defs) es)
116+eval stk env rec defs (LCase ty e [])
117+ = pure LNothing
108eval stk env rec defs (LCase ty e alts)
118eval stk env rec defs (LCase ty e alts)
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 ->
109− = do alts' <- mapM (evalAlt stk env rec defs) alts
123+ 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
124+ -- If they're all lambdas, bind the lambda at the top
112− let prefix = getLams (map getRHS alts')
125+ let prefix = getLams (map getRHS alts')
113− case prefix of
126+ case prefix of
114− [] -> return $ conOpt $ LCase ty e' (replaceInAlts e' alts')
127+ [] -> return $ LCase ty e' (replaceInAlts e' alts')
115− args -> do alts_red <- mapM (dropArgs args) alts'
128+ args -> do alts_red <- mapM (dropArgs args) alts'
116− return $ LLam args
129+ return $ LLam args
117− (conOpt (LCase ty e' (replaceInAlts e' alts_red)))
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
118eval stk env rec defs (LOp f es)
140eval stk env rec defs (LOp f es)
119 = unload stk <$> LOp f <$> mapM (eval [] env rec defs) es
141 = unload stk <$> LOp f <$> mapM (eval [] env rec defs) es
120eval stk env rec defs (LForeign t s args)
142eval stk env rec defs (LForeign t s args)
@@ -129,9 +151,9 @@ eval stk env rec defs (LLam args sc)
129 [] -> eval stk' env' rec defs sc
151 [] -> eval stk' env' rec defs sc
130 as -> do ns' <- mapM (\n -> do n' <- nextN
152 as -> do ns' <- mapM (\n -> do n' <- nextN
131 return (n, n')) args'
153 return (n, n')) args'
132− unload stk' <$> LLam (map snd ns') <$>
154+ LLam (map snd ns') <$>
133− eval [] (map (\ (n, n') -> (n, LV n')) ns' ++ env')
155+ eval stk' (map (\ (n, n') -> (n, LV n')) ns' ++ env')
134− rec defs sc
156+ rec defs sc
135eval stk env rec defs var@(LV n)
157eval stk env rec defs var@(LV n)
136 = case lookup n env of
158 = case lookup n env of
137 Just t
159 Just t
@@ -164,19 +186,24 @@ apply stk env rec defs var args body
164 = eval stk env rec defs (LLam args body)
186 = eval stk env rec defs (LLam args body)
165
187
166dropArgs :: [Name] -> LAlt -> State Int LAlt
188dropArgs :: [Name] -> LAlt -> State Int LAlt
167−dropArgs as (LConCase i n es (LLam args rhs))
189+dropArgs as (LConCase i n es t)
168− = do let old = take (length as) args
190+ = do rhs' <- dropArgsTm as t
169− rhs' <- eval [] (zipWith (\ o n -> (o, LV n)) old as) [] emptyContext rhs
170 return (LConCase i n es rhs')
191 return (LConCase i n es rhs')
171−dropArgs as (LConstCase c (LLam args rhs))
192+dropArgs as (LConstCase c t)
172− = do let old = take (length as) args
193+ = do rhs' <- dropArgsTm as t
173− rhs' <- eval [] (zipWith (\ o n -> (o, LV n)) old as) [] emptyContext rhs
174 return (LConstCase c rhs')
194 return (LConstCase c rhs')
175−dropArgs as (LDefaultCase (LLam args rhs))
195+dropArgs as (LDefaultCase t)
176− = do let old = take (length as) args
196+ = do rhs' <- dropArgsTm as t
177− rhs' <- eval [] (zipWith (\ o n -> (o, LV n)) old as) [] emptyContext rhs
178 return (LDefaultCase rhs')
197 return (LDefaultCase rhs')
179
198
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+
180caseFloat :: LExp -> LExp
207caseFloat :: LExp -> LExp
181caseFloat (LApp tc e es) = LApp tc (caseFloat e) (map caseFloat es)
208caseFloat (LApp tc e es) = LApp tc (caseFloat e) (map caseFloat es)
182caseFloat (LLazyExp e) = LLazyExp (caseFloat e)
209caseFloat (LLazyExp e) = LLazyExp (caseFloat e)
@@ -272,12 +299,14 @@ getRHS (LDefaultCase rhs) = rhs
272
299
273getLams [] = []
300getLams [] = []
274getLams (LLam args tm : cs) = getLamPrefix args cs
301getLams (LLam args tm : cs) = getLamPrefix args cs
302+getLams (LLet n val exp : cs) = getLams (exp : cs)
275getLams _ = []
303getLams _ = []
276
304
277getLamPrefix as [] = as
305getLamPrefix as [] = as
278getLamPrefix as (LLam args tm : cs)
306getLamPrefix as (LLam args tm : cs)
279 | length args < length as = getLamPrefix args cs
307 | length args < length as = getLamPrefix args cs
280 | otherwise = getLamPrefix as cs
308 | otherwise = getLamPrefix as cs
309+getLamPrefix as (LLet n val exp : cs) = getLamPrefix as (exp : cs)
281getLamPrefix as (_ : cs) = []
310getLamPrefix as (_ : cs) = []
282
311
283-- eta contract ('\x -> f x' can just be compiled as 'f' when f is local)
312-- 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
61 Just ddir -> return ddir
61 Just ddir -> return ddir
62
62
63getCC :: IO String
63getCC :: 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
65
71
66getEnvFlags :: IO [String]
72getEnvFlags :: IO [String]
67getEnvFlags = maybe [] (splitOn " ") <$> lookupEnv "IDRIS_CFLAGS"
73getEnvFlags = maybe [] (splitOn " ") <$> lookupEnv "IDRIS_CFLAGS"
@@ -77,7 +83,7 @@ extraInclude = []
77#endif
83#endif
78
84
79#ifdef IDRIS_GMP
85#ifdef IDRIS_GMP
80−gmpLib = ["-lgmp"]
86+gmpLib = ["-lgmp", "-DIDRIS_GMP"]
81#else
87#else
82gmpLib = []
88gmpLib = []
83#endif
89#endif
src/Idris/AbsSyntaxTree.hs+31−12
@@ -6,9 +6,10 @@ License : BSD3
6Maintainer : The Idris Community.
6Maintainer : The Idris Community.
7-}
7-}
8
8
9−{-# LANGUAGE DeriveDataTypeable, DeriveFoldable, DeriveFunctor, DeriveGeneric,
9+{-# LANGUAGE CPP, DeriveDataTypeable, DeriveFoldable, DeriveFunctor,
10− DeriveTraversable, FlexibleContexts, FlexibleInstances,
10+ DeriveGeneric, DeriveTraversable, FlexibleContexts,
11− MultiParamTypeClasses, PatternGuards, TypeSynonymInstances #-}
11+ FlexibleInstances, MultiParamTypeClasses, PatternGuards,
12+ TypeSynonymInstances #-}
12
13
13module Idris.AbsSyntaxTree where
14module Idris.AbsSyntaxTree where
14
15
@@ -25,8 +26,11 @@ import Util.Pretty
25import Idris.Colours
26import Idris.Colours
26
27
27import System.IO
28import System.IO
28−
29+#if (MIN_VERSION_base(4,11,0))
30+import Prelude hiding (Foldable, Traversable, (<$>), (<>))
31+#else
29import Prelude hiding (Foldable, Traversable, (<$>))
32import Prelude hiding (Foldable, Traversable, (<$>))
33+#endif
30
34
31import Control.Applicative ((<|>))
35import Control.Applicative ((<|>))
32import qualified Control.Monad.Trans.Class as Trans (lift)
36import qualified Control.Monad.Trans.Class as Trans (lift)
@@ -47,7 +51,6 @@ import Data.Traversable (Traversable)
47import Data.Typeable
51import Data.Typeable
48import GHC.Generics (Generic)
52import GHC.Generics (Generic)
49
53
50−
51data ElabWhat = ETypes | EDefns | EAll
54data ElabWhat = ETypes | EDefns | EAll
52 deriving (Show, Eq)
55 deriving (Show, Eq)
53
56
@@ -299,8 +302,8 @@ data IState = IState {
299
302
300 , idris_symbols :: M.Map Name Name -- ^ Symbol table (preserves sharing of names)
303 , idris_symbols :: M.Map Name Name -- ^ Symbol table (preserves sharing of names)
301 , idris_exports :: [Name] -- ^ Functions with ExportList
304 , idris_exports :: [Name] -- ^ Functions with ExportList
302− , idris_highlightedRegions :: [(FC, OutputAnnotation)] -- ^ Highlighting information to output
305+ , idris_highlightedRegions :: S.Set (FC', OutputAnnotation) -- ^ Highlighting information to output
303− , idris_parserHighlights :: [(FC, OutputAnnotation)] -- ^ Highlighting information from the parser
306+ , idris_parserHighlights :: S.Set (FC', OutputAnnotation) -- ^ Highlighting information from the parser
304 , idris_deprecated :: Ctxt String -- ^ Deprecated names and explanation
307 , idris_deprecated :: Ctxt String -- ^ Deprecated names and explanation
305 , idris_inmodule :: S.Set Name -- ^ Names defined in current module
308 , idris_inmodule :: S.Set Name -- ^ Names defined in current module
306 , idris_ttstats :: M.Map Term (Int, Term)
309 , idris_ttstats :: M.Map Term (Int, Term)
@@ -408,7 +411,7 @@ idrisInit = IState initContext S.empty []
408 [] [] [] defaultOpts 6 [] [] [] [] [] emptySyntaxRules [] [] [] [] [] [] []
411 [] [] [] defaultOpts 6 [] [] [] [] [] emptySyntaxRules [] [] [] [] [] [] []
409 [] [] Nothing [] Nothing [] [] Nothing emptyContext Private DefaultCheckingPartial [] Nothing [] []
412 [] [] Nothing [] Nothing [] [] Nothing emptyContext Private DefaultCheckingPartial [] Nothing [] []
410 (RawOutput stdout) True defaultTheme [] (0, emptyContext) emptyContext M.empty
413 (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
412 emptyContext S.empty M.empty emptyContext initialInteractiveOpts
415 emptyContext S.empty M.empty emptyContext initialInteractiveOpts
413
416
414
417
@@ -707,19 +710,19 @@ data EState = EState {
707 case_decls :: [(Name, PDecl)]
710 case_decls :: [(Name, PDecl)]
708 , delayed_elab :: [(Int, Elab' EState ())]
711 , delayed_elab :: [(Int, Elab' EState ())]
709 , new_tyDecls :: [RDeclInstructions]
712 , new_tyDecls :: [RDeclInstructions]
710− , highlighting :: [(FC, OutputAnnotation)]
713+ , highlighting :: S.Set (FC', OutputAnnotation)
711 , auto_binds :: [Name] -- ^ names bound as auto implicits
714 , auto_binds :: [Name] -- ^ names bound as auto implicits
712 , implicit_warnings :: [(FC, Name)] -- ^ Implicit warnings to report (location and global name)
715 , implicit_warnings :: [(FC, Name)] -- ^ Implicit warnings to report (location and global name)
713 }
716 }
714
717
715initEState :: EState
718initEState :: EState
716−initEState = EState [] [] [] [] [] []
719+initEState = EState [] [] [] S.empty [] []
717
720
718type ElabD a = Elab' EState a
721type ElabD a = Elab' EState a
719
722
720highlightSource :: FC -> OutputAnnotation -> ElabD ()
723highlightSource :: FC -> OutputAnnotation -> ElabD ()
721highlightSource fc annot =
724highlightSource fc annot =
722− updateAux (\aux -> aux { highlighting = (fc, annot) : highlighting aux })
725+ updateAux (\aux -> aux { highlighting = S.insert (FC' fc, annot) (highlighting aux) })
723
726
724-- | One clause of a top-level definition. Term arguments to constructors are:
727-- | One clause of a top-level definition. Term arguments to constructors are:
725--
728--
@@ -1988,7 +1991,7 @@ pprintPTerm ppo bnd docArgs infixes = prettySe (ppopt_depth ppo) startPrec bnd
1988 prettyArgS d bnd (PConstraint _ _ _ tm) = prettyArgSc d bnd tm
1991 prettyArgS d bnd (PConstraint _ _ _ tm) = prettyArgSc d bnd tm
1989 prettyArgS d bnd (PTacImplicit _ _ n _ tm) = prettyArgSti d bnd (n, tm)
1992 prettyArgS d bnd (PTacImplicit _ _ n _ tm) = prettyArgSti d bnd (n, tm)
1990
1993
1991− prettyArgSe d bnd arg = prettySe d (funcAppPrec + 1) bnd arg
1994+ prettyArgSe d bnd arg = prettySe (decD d) (funcAppPrec + 1) bnd arg
1992 prettyArgSi d bnd (n, val) = lbrace <> pretty n <+> text "=" <+> prettySe (decD d) startPrec bnd val <> rbrace
1995 prettyArgSi d bnd (n, val) = lbrace <> pretty n <+> text "=" <+> prettySe (decD d) startPrec bnd val <> rbrace
1993 prettyArgSc d bnd val = lbrace <> lbrace <> prettySe (decD d) startPrec bnd val <> rbrace <> rbrace
1996 prettyArgSc d bnd val = lbrace <> lbrace <> prettySe (decD d) startPrec bnd val <> rbrace <> rbrace
1994 prettyArgSti d bnd (n, val) = lbrace <> kwd "auto" <+> pretty n <+> text "=" <+> prettySe (decD d) startPrec bnd val <> rbrace
1997 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
2275 ni 0 env (PPatvar _ n) = [n]
2278 ni 0 env (PPatvar _ n) = [n]
2276 ni 0 env (PApp _ f as) = ni 0 env f ++ concatMap (ni 0 env . getTm) as
2279 ni 0 env (PApp _ f as) = ni 0 env f ++ concatMap (ni 0 env . getTm) as
2277 ni 0 env (PAppBind _ f as) = ni 0 env f ++ concatMap (ni 0 env . getTm) as
2280 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
2278 ni 0 env (PCase _ c os) = ni 0 env c ++ concatMap (ni 0 env . snd) os
2283 ni 0 env (PCase _ c os) = ni 0 env c ++ concatMap (ni 0 env . snd) os
2279 ni 0 env (PIfThenElse _ c t f) = ni 0 env c ++ ni 0 env t ++ ni 0 env f
2284 ni 0 env (PIfThenElse _ c t f) = ni 0 env c ++ ni 0 env t ++ ni 0 env f
2280 ni 0 env (PLam fc n _ ty sc) = ni 0 env ty ++ ni 0 (n:env) sc
2285 ni 0 env (PLam fc n _ ty sc) = ni 0 env ty ++ ni 0 (n:env) sc
2281 ni 0 env (PPi p n _ ty sc) = niTacImp 0 env p ++ ni 0 env ty ++ ni 0 (n:env) sc
2286 ni 0 env (PPi p n _ ty sc) = niTacImp 0 env p ++ ni 0 env ty ++ ni 0 (n:env) sc
2282 ni 0 env (PLet _ _ n _ ty val sc) = ni 0 env ty ++ ni 0 env val ++ ni 0 (n:env) sc
2287 ni 0 env (PLet _ _ n _ ty val sc) = ni 0 env ty ++ ni 0 env val ++ ni 0 (n:env) sc
2283 ni 0 env (PHidden tm) = ni 0 env tm
2288 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
2284 ni 0 env (PRewrite _ _ l r _) = ni 0 env l ++ ni 0 env r
2291 ni 0 env (PRewrite _ _ l r _) = ni 0 env l ++ ni 0 env r
2285 ni 0 env (PTyped l r) = ni 0 env l ++ ni 0 env r
2292 ni 0 env (PTyped l r) = ni 0 env l ++ ni 0 env r
2286 ni 0 env (PPair _ _ _ l r) = ni 0 env l ++ ni 0 env r
2293 ni 0 env (PPair _ _ _ l r) = ni 0 env l ++ ni 0 env r
2287 ni 0 env (PDPair _ _ _ (PRef _ _ n) Placeholder r) = n : ni 0 env r
2294 ni 0 env (PDPair _ _ _ (PRef _ _ n) Placeholder r) = n : ni 0 env r
2288 ni 0 env (PDPair _ _ _ (PRef _ _ n) t r) = ni 0 env t ++ ni 0 (n:env) r
2295 ni 0 env (PDPair _ _ _ (PRef _ _ n) t r) = ni 0 env t ++ ni 0 (n:env) r
2289 ni 0 env (PDPair _ _ _ l t r) = ni 0 env l ++ ni 0 env t ++ ni 0 env r
2296 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
2290 ni 0 env (PAlternative ns a ls) = map snd ns ++ concatMap (ni 0 env) ls
2302 ni 0 env (PAlternative ns a ls) = map snd ns ++ concatMap (ni 0 env) ls
2291 ni 0 env (PUnifyLog tm) = ni 0 env tm
2303 ni 0 env (PUnifyLog tm) = ni 0 env tm
2292 ni 0 env (PDisamb _ tm) = ni 0 env tm
2304 ni 0 env (PDisamb _ tm) = ni 0 env tm
2293 ni 0 env (PNoImplicits tm) = ni 0 env tm
2305 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)
2294
2312
2295 ni i env (PQuasiquote tm ty) = ni (i+1) env tm ++ maybe [] (ni i env) ty
2313 ni i env (PQuasiquote tm ty) = ni (i+1) env tm ++ maybe [] (ni i env) ty
2296 ni i env (PUnquote tm) = ni (i - 1) env tm
2314 ni i env (PUnquote tm) = ni (i - 1) env tm
2315+ ni 0 env tm = []
2297 ni i env tm = concatMap (ni i env) (children tm)
2316 ni i env tm = concatMap (ni i env) (children tm)
2298
2317
2299 niTacImp i env (TacImp _ _ scr _) = ni i env scr
2318 niTacImp i env (TacImp _ _ scr _) = ni i env scr
src/Idris/Chaser.hs+59−24
@@ -22,6 +22,8 @@ import Idris.Unlit
22
22
23import Control.Monad.State
23import Control.Monad.State
24import Data.List
24import Data.List
25+import qualified Data.Map as M
26+import qualified Data.Set as S
25import Data.Time.Clock
27import Data.Time.Clock
26import System.Directory
28import System.Directory
27import Util.System (readSource)
29import Util.System (readSource)
@@ -36,8 +38,7 @@ latest :: UTCTime -> [IFileType] -> [ModuleTree] -> UTCTime
36latest tm done [] = tm
38latest tm done [] = tm
37latest tm done (m : ms)
39latest tm done (m : ms)
38 | mod_path m `elem` done = latest tm done ms
40 | mod_path m `elem` done = latest tm done ms
39− | otherwise = latest (max tm (mod_time m)) (mod_path m : done)
41+ | otherwise = latest (max tm (mod_time m)) (mod_path m : done) ms
40− (ms ++ mod_deps m)
41
42
42modName :: IFileType -> String
43modName :: IFileType -> String
43modName (IDR fp) = fp
44modName (IDR fp) = fp
@@ -48,23 +49,52 @@ modName (IBC fp src) = modName src
48-- any module has a descendent which needs reloading, return its
49-- any module has a descendent which needs reloading, return its
49-- source, otherwise return the IBC
50-- source, otherwise return the IBC
50getModuleFiles :: [ModuleTree] -> [IFileType]
51getModuleFiles :: [ModuleTree] -> [IFileType]
51−getModuleFiles ts = nub $ execState (modList ts) [] where
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.
52− modList :: [ModuleTree] -> State [IFileType] ()
60+ modList :: [ModuleTree] ->
61+ State (S.Set IFileType,
62+ M.Map IFileType (Bool, [IFileType])) [IFileType]
53− modList [] = return ()
63+ modList [] = return []
54− modList (m : ms) = do modTree [] m; modList ms
64+ modList (m : ms) = do (_, fs) <- modTree S.empty m
55−
65+ fs' <- modList ms
66+ pure (fs ++ fs')
67+
56− modTree path (MTree p rechk tm deps)
68+ modTree path m@(MTree p rechk tm deps)
57 = do let file = chkReload rechk p
69 = do let file = chkReload rechk p
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+
58− -- Needs rechecking if 'rechk' is true, or if any of the
80+ -- Needs rechecking if 'rechk' is true, or if any of the
59− -- modification times in 'deps' are later than tm
81+ -- modification times in 'deps' are later than tm, or
82+ -- if any dependency needed rechecking
60− let depMod = latest tm [] deps
83+ let depMod = latest tm [] deps
61− let needsRechk = rechk || depMod > tm
84+ let needsRechk = rechkDep || rechk || depMod > tm
62−
85+
63− st <- get
86+ -- Remove duplicates, but keep the last...
64− if needsRechk then put $ nub (getSrc file : updateToSrc path st)
87+ let rnub = reverse . nub . reverse
65− else put $ nub (file : st)
88+
66− st <- get
89+ let ret = if needsRechk
67− mapM_ (modTree (getSrc p : path)) deps
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
68
98
69 chkReload False p = p
99 chkReload False p = p
70 chkReload True (IBC fn src) = chkReload True src
100 chkReload True (IBC fn src) = chkReload True src
@@ -73,10 +103,11 @@ getModuleFiles ts = nub $ execState (modList ts) [] where
73 getSrc (IBC fn src) = getSrc src
103 getSrc (IBC fn src) = getSrc src
74 getSrc f = f
104 getSrc f = f
75
105
76− updateToSrc path [] = []
106+ updateToSrc rebuilds [] = []
77− updateToSrc path (x : xs) = if getSrc x `elem` path
107+ updateToSrc rebuilds (x : xs)
108+ = if getSrc x `S.member` rebuilds
78− then getSrc x : updateToSrc path xs
109+ then getSrc x : updateToSrc rebuilds xs
79− else x : updateToSrc path xs
110+ else x : updateToSrc rebuilds xs
80
111
81-- | Strip quotes and the backslash escapes that Haskeline adds
112-- | Strip quotes and the backslash escapes that Haskeline adds
82extractFileName :: String -> String
113extractFileName :: String -> String
@@ -173,8 +204,12 @@ buildTree built importlists fp = evalStateT (btree [] fp) []
173 do [MTree _ _ _ ms'] <- mkChildren file src
204 do [MTree _ _ _ ms'] <- mkChildren file src
174 return ms'
205 return ms'
175 else return []
206 else return []
176− mt <- lift $ idrisCatch (runIO $ getModificationTime fn)
207+ -- Modification time is the later of the source/ibc modification time
177− (\c -> runIO $ getIModTime src)
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)
178 -- FIXME: It's also not up to date if anything it imports has
213 -- FIXME: It's also not up to date if anything it imports has
179 -- been modified since its own ibc has.
214 -- been modified since its own ibc has.
180 --
215 --
src/Idris/Core/ProofState.hs+5−1
@@ -10,7 +10,7 @@ proofs, and some high level commands for introducing new theorems,
10evaluation/checking inside the proof system, etc.
10evaluation/checking inside the proof system, etc.
11-}
11-}
12
12
13−{-# LANGUAGE FlexibleContexts, FlexibleInstances, MultiParamTypeClasses,
13+{-# LANGUAGE CPP, FlexibleContexts, FlexibleInstances, MultiParamTypeClasses,
14 PatternGuards #-}
14 PatternGuards #-}
15module Idris.Core.ProofState(
15module Idris.Core.ProofState(
16 ProofState(..), newProof, envAtFocus, goalAtFocus
16 ProofState(..), newProof, envAtFocus, goalAtFocus
@@ -32,6 +32,10 @@ import Control.Arrow ((***))
32import Control.Monad.State.Strict
32import Control.Monad.State.Strict
33import Data.List
33import Data.List
34
34
35+#if (MIN_VERSION_base(4,11,0))
36+import Prelude hiding ((<>))
37+#endif
38+
35data ProofState = PS { thname :: Name,
39data ProofState = PS { thname :: Name,
36 holes :: [Name], -- ^ holes still to be solved
40 holes :: [Name], -- ^ holes still to be solved
37 usedns :: [Name], -- ^ used names, don't use again
41 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:
22 * We have a simple collection of tactics which we use to elaborate source
22 * We have a simple collection of tactics which we use to elaborate source
23 programs with implicit syntax into fully explicit terms.
23 programs with implicit syntax into fully explicit terms.
24-}
24-}
25−{-# LANGUAGE DeriveDataTypeable, DeriveFoldable, DeriveFunctor, DeriveGeneric,
25+{-# LANGUAGE CPP, DeriveDataTypeable, DeriveFoldable, DeriveFunctor,
26− DeriveTraversable, FlexibleContexts, FlexibleInstances,
26+ DeriveGeneric, DeriveTraversable, FlexibleContexts,
27− FunctionalDependencies, MultiParamTypeClasses, PatternGuards,
27+ FlexibleInstances, FunctionalDependencies, MultiParamTypeClasses,
28− TypeSynonymInstances #-}
28+ PatternGuards, TypeSynonymInstances #-}
29{-# OPTIONS_GHC -fwarn-incomplete-patterns #-}
29{-# OPTIONS_GHC -fwarn-incomplete-patterns #-}
30module Idris.Core.TT(
30module Idris.Core.TT(
31 AppStatus(..), ArithTy(..), Binder(..), Const(..), Ctxt(..)
31 AppStatus(..), ArithTy(..), Binder(..), Const(..), Ctxt(..)
@@ -63,6 +63,10 @@ import Prelude (Bool(..), Double, Enum(..), Eq(..), FilePath, Functor(..), Int,
63 Ordering(..), Show(..), String, div, error, fst, max, min, mod,
63 Ordering(..), Show(..), String, div, error, fst, max, min, mod,
64 not, otherwise, read, snd, ($), (&&), (.), (||))
64 not, otherwise, read, snd, ($), (&&), (.), (||))
65
65
66+#if (MIN_VERSION_base(4,11,0))
67+import qualified Prelude as S (Semigroup(..))
68+#endif
69+
66import Control.Applicative (Alternative, Applicative(..))
70import Control.Applicative (Alternative, Applicative(..))
67import qualified Control.Applicative as A (Alternative(..))
71import qualified Control.Applicative as A (Alternative(..))
68import Control.DeepSeq (($!!))
72import Control.DeepSeq (($!!))
@@ -117,6 +121,11 @@ fc_end (FC _ _ end) = end
117fc_end NoFC = (0, 0)
121fc_end NoFC = (0, 0)
118fc_end (FileFC f) = (0, 0)
122fc_end (FileFC f) = (0, 0)
119
123
124+#if (MIN_VERSION_base(4,11,0))
125+instance S.Semigroup FC where
126+ (<>) = mappend
127+#endif
128+
120instance Monoid FC where
129instance Monoid FC where
121 mempty = NoFC
130 mempty = NoFC
122
131
@@ -188,10 +197,10 @@ instance Show FC where
188 show (FileFC f) = f
197 show (FileFC f) = f
189
198
190-- | Output annotation for pretty-printed name - decides colour
199-- | 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)
192
201
193-- | Text formatting output
202-- | Text formatting output
194−data TextFormatting = BoldText | ItalicText | UnderlineText deriving (Show, Eq, Generic)
203+data TextFormatting = BoldText | ItalicText | UnderlineText deriving (Show, Eq, Ord, Generic)
195
204
196-- | Output annotations for pretty-printing
205-- | Output annotations for pretty-printing
197data OutputAnnotation = AnnName Name (Maybe NameOutput) (Maybe String) (Maybe String)
206data OutputAnnotation = AnnName Name (Maybe NameOutput) (Maybe String) (Maybe String)
@@ -218,7 +227,7 @@ data OutputAnnotation = AnnName Name (Maybe NameOutput) (Maybe String) (Maybe St
218 | AnnQuasiquote
227 | AnnQuasiquote
219 | AnnAntiquote
228 | AnnAntiquote
220 | AnnSyntax String -- ^ type of syntax element: backslash or braces etc.
229 | AnnSyntax String -- ^ type of syntax element: backslash or braces etc.
221− deriving (Show, Eq, Generic)
230+ deriving (Show, Eq, Generic, Ord)
222
231
223-- | Used for error reflection
232-- | Used for error reflection
224data ErrorReportPart = TextPart String
233data 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
5License : BSD3
5License : BSD3
6Maintainer : The Idris Community.
6Maintainer : The Idris Community.
7-}
7-}
8−{-# LANGUAGE PatternGuards #-}
8+{-# LANGUAGE CPP, PatternGuards #-}
9{-# OPTIONS_GHC -fwarn-incomplete-patterns #-}
9{-# OPTIONS_GHC -fwarn-incomplete-patterns #-}
10module Idris.Delaborate (
10module Idris.Delaborate (
11 annName, bugaddr, delab, delabWithEnv, delabDirect, delab', delabMV, delabSugared
11 annName, bugaddr, delab, delabWithEnv, delabDirect, delab', delabMV, delabSugared
@@ -21,7 +21,11 @@ import Idris.ErrReverse
21
21
22import Util.Pretty
22import Util.Pretty
23
23
24+#if (MIN_VERSION_base(4,11,0))
25+import Prelude hiding ((<$>), (<>))
26+#else
24import Prelude hiding ((<$>))
27import Prelude hiding ((<$>))
28+#endif
25
29
26import Control.Applicative (Alternative((<|>)))
30import Control.Applicative (Alternative((<|>)))
27import Control.Monad.State
31import Control.Monad.State
src/Idris/Directives.hs+7−5
@@ -13,6 +13,8 @@ import Idris.Core.TT
13import Idris.Imports
13import Idris.Imports
14import Idris.Output (sendHighlighting)
14import Idris.Output (sendHighlighting)
15
15
16+import qualified Data.Set as S
17+
16import Util.DynamicLinker
18import Util.DynamicLinker
17
19
18-- | Run the action corresponding to a directive
20-- | Run the action corresponding to a directive
@@ -81,7 +83,7 @@ directiveAction (DNameHint ty tyFC ns) = do
81 ty' <- disambiguate ty
83 ty' <- disambiguate ty
82 mapM_ (addNameHint ty' . fst) ns
84 mapM_ (addNameHint ty' . fst) ns
83 mapM_ (\n -> addIBC (IBCNameHint (ty', fst n))) ns
85 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
85
87
86directiveAction (DErrorHandlers fn nfc arg afc ns) = do
88directiveAction (DErrorHandlers fn nfc arg afc ns) = do
87 fn' <- disambiguate fn
89 fn' <- disambiguate fn
@@ -90,10 +92,10 @@ directiveAction (DErrorHandlers fn nfc arg afc ns) = do
90 return (n', fc)) ns
92 return (n', fc)) ns
91 addFunctionErrorHandlers fn' arg (map fst ns')
93 addFunctionErrorHandlers fn' arg (map fst ns')
92 mapM_ (addIBC . IBCFunctionErrorHandler fn' arg . fst) ns'
94 mapM_ (addIBC . IBCFunctionErrorHandler fn' arg . fst) ns'
93− sendHighlighting $
95+ sendHighlighting $ S.fromList $
94− [ (nfc, AnnName fn' Nothing Nothing Nothing)
96+ [ (FC' nfc, AnnName fn' Nothing Nothing Nothing)
95− , (afc, AnnBoundName arg False)
97+ , (FC' afc, AnnBoundName arg False)
96− ] ++ map (\(n, fc) -> (fc, AnnName n Nothing Nothing Nothing)) ns'
98+ ] ++ map (\(n, fc) -> (FC' fc, AnnName n Nothing Nothing Nothing)) ns'
97
99
98directiveAction (DLanguage ext) = addLangExt ext
100directiveAction (DLanguage ext) = addLangExt ext
99
101
src/Idris/Docs.hs+5−1
@@ -6,7 +6,7 @@ License : BSD3
6Maintainer : The Idris Community.
6Maintainer : The Idris Community.
7-}
7-}
8
8
9−{-# LANGUAGE DeriveFunctor, MultiWayIf, PatternGuards #-}
9+{-# LANGUAGE CPP, DeriveFunctor, MultiWayIf, PatternGuards #-}
10{-# OPTIONS_GHC -fwarn-incomplete-patterns #-}
10{-# OPTIONS_GHC -fwarn-incomplete-patterns #-}
11
11
12module Idris.Docs (
12module Idris.Docs (
@@ -30,7 +30,11 @@ import Idris.Options (HowMuchDocs(..))
30
30
31import Util.Pretty
31import Util.Pretty
32
32
33+#if (MIN_VERSION_base(4,11,0))
34+import Prelude hiding ((<$>), (<>))
35+#else
33import Prelude hiding ((<$>))
36import Prelude hiding ((<$>))
37+#endif
34
38
35import Data.List
39import Data.List
36import Data.Maybe
40import Data.Maybe
src/Idris/Docstrings.hs+6−3
@@ -6,8 +6,8 @@ License : BSD3
6Maintainer : The Idris Community.
6Maintainer : The Idris Community.
7-}
7-}
8
8
9−{-# LANGUAGE DeriveFoldable, DeriveFunctor, DeriveGeneric, DeriveTraversable,
9+{-# LANGUAGE CPP, DeriveFoldable, DeriveFunctor, DeriveGeneric,
10− ScopedTypeVariables #-}
10+ DeriveTraversable, ScopedTypeVariables #-}
11{-# OPTIONS_GHC -fwarn-incomplete-patterns #-}
11{-# OPTIONS_GHC -fwarn-incomplete-patterns #-}
12module Idris.Docstrings (
12module Idris.Docstrings (
13 Docstring(..), Block(..), Inline(..), parseDocstring, renderDocstring
13 Docstring(..), Block(..), Inline(..), parseDocstring, renderDocstring
@@ -19,8 +19,11 @@ import Idris.Core.TT (Err, Name, OutputAnnotation(..), Term, TextFormatting(..))
19
19
20import Util.Pretty
20import Util.Pretty
21
21
22+#if (MIN_VERSION_base(4,11,0))
23+import Prelude hiding ((<$>), (<>))
24+#else
22import Prelude hiding ((<$>))
25import Prelude hiding ((<$>))
23−
26+#endif
24import qualified Cheapskate as C
27import qualified Cheapskate as C
25import Cheapskate.Html (renderDoc)
28import Cheapskate.Html (renderDoc)
26import qualified Cheapskate.Types as CT
29import qualified Cheapskate.Types as CT
src/Idris/Elab/Clause.hs+2−1
@@ -44,6 +44,7 @@ import qualified Control.Monad.State.Lazy as LState
44import Control.Monad.State.Strict as State
44import Control.Monad.State.Strict as State
45import Data.List
45import Data.List
46import Data.Maybe
46import Data.Maybe
47+import qualified Data.Set as S
47import Data.Word
48import Data.Word
48import Debug.Trace
49import Debug.Trace
49import Numeric
50import Numeric
@@ -1028,7 +1029,7 @@ elabClause info opts (_, PWith fc fname lhs_in withs wval_in pn_in withblock)
1028 Just (n, nfc) -> Just (uniqueName n (map fst bargs))
1029 Just (n, nfc) -> Just (uniqueName n (map fst bargs))
1029
1030
1030 -- Highlight explicit proofs
1031 -- 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]
1032
1033
1033 logElab 10 ("With type " ++ show (getRetTy cwvaltyN) ++
1034 logElab 10 ("With type " ++ show (getRetTy cwvaltyN) ++
1034 " depends on " ++ show pdeps ++ " from " ++ show pvars)
1035 " depends on " ++ show pdeps ++ " from " ++ show pvars)
src/Idris/Elab/Data.hs+9−4
@@ -5,7 +5,7 @@ Description : Code to elaborate data structures.
5License : BSD3
5License : BSD3
6Maintainer : The Idris Community.
6Maintainer : The Idris Community.
7-}
7-}
8−{-# LANGUAGE PatternGuards #-}
8+{-# LANGUAGE CPP, PatternGuards #-}
9module Idris.Elab.Data(elabData) where
9module Idris.Elab.Data(elabData) where
10
10
11import Idris.AbsSyntax
11import Idris.AbsSyntax
@@ -24,7 +24,11 @@ import Idris.Output (iWarn, sendHighlighting)
24
24
25import Util.Pretty
25import Util.Pretty
26
26
27+#if (MIN_VERSION_base(4,11,0))
28+import Prelude hiding (id, (.), (<>))
29+#else
27import Prelude hiding (id, (.))
30import Prelude hiding (id, (.))
31+#endif
28
32
29import Control.Category
33import Control.Category
30import Control.Monad
34import Control.Monad
@@ -33,6 +37,7 @@ import Data.Char (isLetter, toLower)
33import Data.List
37import Data.List
34import qualified Data.Map as Map
38import qualified Data.Map as Map
35import Data.Maybe
39import Data.Maybe
40+import qualified Data.Set as S
36import qualified Data.Text as T
41import qualified Data.Text as T
37
42
38warnLC :: FC -> Name -> Idris ()
43warnLC :: FC -> Name -> Idris ()
@@ -49,7 +54,7 @@ elabData info syn doc argDocs fc opts (PLaterdecl n nfc t_in)
49
54
50 addIBC (IBCDef n)
55 addIBC (IBCDef n)
51 updateContext (addTyDecl n (TCon 0 0) cty) -- temporary, to check cons
56 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)]
53
58
54elabData info syn doc argDocs fc opts (PDatadecl n nfc t_in dcons)
59elabData info syn doc argDocs fc opts (PDatadecl n nfc t_in dcons)
55 = do let codata = Codata `elem` opts
60 = do let codata = Codata `elem` opts
@@ -114,9 +119,9 @@ elabData info syn doc argDocs fc opts (PDatadecl n nfc t_in dcons)
114 when (n /= sUN "=") $
119 when (n /= sUN "=") $
115 elabRewriteLemma info n cty
120 elabRewriteLemma info n cty
116 -- Emit highlighting info
121 -- Emit highlighting info
117− sendHighlighting $ [(nfc, AnnName n Nothing Nothing Nothing)] ++
122+ sendHighlighting $ S.fromList $ [(FC' nfc, AnnName n Nothing Nothing Nothing)] ++
118 map (\(_, _, n, nfc, _, _, _) ->
123 map (\(_, _, n, nfc, _, _, _) ->
119− (nfc, AnnName n Nothing Nothing Nothing))
124+ (FC' nfc, AnnName n Nothing Nothing Nothing))
120 dcons
125 dcons
121 where
126 where
122 checkDefinedAs fc n t i
127 checkDefinedAs fc n t i
src/Idris/Elab/Interface.hs+6−5
@@ -26,6 +26,7 @@ import Control.Monad
26import Data.Generics.Uniplate.Data (transform)
26import Data.Generics.Uniplate.Data (transform)
27import Data.List
27import Data.List
28import Data.Maybe
28import Data.Maybe
29+import qualified Data.Set as S
29
30
30data MArgTy = IA Name | EA Name | CA deriving Show
31data MArgTy = IA Name | EA Name | CA deriving Show
31
32
@@ -167,11 +168,11 @@ elabInterface info_in syn_in doc what fc constraints tn tnfc ps pDocs fds ds mcn
167 mapM_ (rec_elabDecl info EAll info) (concatMap (snd.snd) defs)
168 mapM_ (rec_elabDecl info EAll info) (concatMap (snd.snd) defs)
168 addIBC (IBCInterface tn)
169 addIBC (IBCInterface tn)
169
170
170− sendHighlighting $
171+ sendHighlighting $ S.fromList $
171− [(tnfc, AnnName tn Nothing Nothing Nothing)] ++
172+ [(FC' tnfc, AnnName tn Nothing Nothing Nothing)] ++
172− [(pnfc, AnnBoundName pn False) | (pn, pnfc, _) <- ps] ++
173+ [(FC' pnfc, AnnBoundName pn False) | (pn, pnfc, _) <- ps] ++
173− [(fdfc, AnnBoundName fc False) | (fc, fdfc) <- fds] ++
174+ [(FC' fdfc, AnnBoundName fc False) | (fc, fdfc) <- fds] ++
174− maybe [] (\(conN, conNFC) -> [(conNFC, AnnName conN Nothing Nothing Nothing)]) mcn
175+ maybe [] (\(conN, conNFC) -> [(FC' conNFC, AnnName conN Nothing Nothing Nothing)]) mcn
175
176
176 where
177 where
177 info = info_in { noCaseLift = tn : noCaseLift info_in }
178 info = info_in { noCaseLift = tn : noCaseLift info_in }
src/Idris/Elab/Record.hs+5−4
@@ -20,6 +20,7 @@ import Idris.Output (sendHighlighting)
20import Control.Monad
20import Control.Monad
21import Data.List
21import Data.List
22import Data.Maybe
22import Data.Maybe
23+import qualified Data.Set as S
23
24
24-- | Elaborate a record declaration
25-- | Elaborate a record declaration
25elabRecord :: ElabInfo
26elabRecord :: ElabInfo
@@ -66,10 +67,10 @@ elabRecord info what doc rsyn fc opts tyn nfc params paramDocs fields cname cdoc
66 logElab 1 $ "fieldsWIthNameAndDoc " ++ show fieldsWithNameAndDoc
67 logElab 1 $ "fieldsWIthNameAndDoc " ++ show fieldsWithNameAndDoc
67 elabRecordFunctions info rsyn fc tyn paramsAndDoc fieldsWithNameAndDoc dconName target
68 elabRecordFunctions info rsyn fc tyn paramsAndDoc fieldsWithNameAndDoc dconName target
68
69
69− sendHighlighting $
70+ sendHighlighting $ S.fromList $
70− [(nfc, AnnName tyn Nothing Nothing Nothing)] ++
71+ [(FC' nfc, AnnName tyn Nothing Nothing Nothing)] ++
71− maybe [] (\(_, cnfc) -> [(cnfc, AnnName dconName Nothing Nothing Nothing)]) cname ++
72+ maybe [] (\(_, cnfc) -> [(FC' cnfc, AnnName dconName Nothing Nothing Nothing)]) cname ++
72− [(ffc, AnnBoundName fn False) | (fn, ffc, _, _, _) <- fieldsWithName]
73+ [(FC' ffc, AnnBoundName fn False) | (fn, ffc, _, _, _) <- fieldsWithName]
73
74
74 where
75 where
75 -- | Generates a type constructor.
76 -- | Generates a type constructor.
src/Idris/Elab/Term.hs+9−1
@@ -56,7 +56,7 @@ data ElabResult = ElabResult {
56 -- | Meta-info about the new type declarations
56 -- | Meta-info about the new type declarations
57 , resultTyDecls :: [RDeclInstructions]
57 , resultTyDecls :: [RDeclInstructions]
58 -- | Saved highlights from elaboration
58 -- | Saved highlights from elaboration
59− , resultHighlighting :: [(FC, OutputAnnotation)]
59+ , resultHighlighting :: S.Set (FC', OutputAnnotation)
60 -- | The new global name counter
60 -- | The new global name counter
61 , resultName :: Int
61 , resultName :: Int
62 }
62 }
@@ -2026,6 +2026,14 @@ runElabAction info ist fc env tm ns = do tm' <- eval tm
2026 first' <- eval first
2026 first' <- eval first
2027 alt' <- eval alt
2027 alt' <- eval alt
2028 try' (runTacTm first') (runTacTm alt') True
2028 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'
2029 | n == tacN "Prim__Fill"
2037 | n == tacN "Prim__Fill"
2030 = do ~[raw] <- tacTmArgs 1 tac args
2038 = do ~[raw] <- tacTmArgs 1 tac args
2031 raw' <- reifyRaw =<< eval raw
2039 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
205 else ifail $ "The type " ++ show nty' ++ " is invalid for an error handler"
205 else ifail $ "The type " ++ show nty' ++ " is invalid for an error handler"
206 else ifail "Error handlers can only be defined when the ErrorReflection language extension is enabled."
206 else ifail "Error handlers can only be defined when the ErrorReflection language extension is enabled."
207 -- Send highlighting information about the name being declared
207 -- 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)]
209 -- if it's an export list type, make a note of it
209 -- if it's an export list type, make a note of it
210 case (unApply usety) of
210 case (unApply usety) of
211 (P _ ut _, _)
211 (P _ ut _, _)
@@ -238,7 +238,7 @@ elabPostulate info syn doc fc nfc opts n ty = do
238 elabType info syn doc [] fc opts n NoFC ty
238 elabType info syn doc [] fc opts n NoFC ty
239 putIState . (\ist -> ist{ idris_postulates = S.insert n (idris_postulates ist) }) =<< getIState
239 putIState . (\ist -> ist{ idris_postulates = S.insert n (idris_postulates ist) }) =<< getIState
240 addIBC (IBCPostulate n)
240 addIBC (IBCPostulate n)
241− sendHighlighting [(nfc, AnnName n (Just PostulateOutput) Nothing Nothing)]
241+ sendHighlighting $ S.fromList [(FC' nfc, AnnName n (Just PostulateOutput) Nothing Nothing)]
242
242
243 -- remove it from the deferred definitions list
243 -- remove it from the deferred definitions list
244 solveDeferred fc n
244 solveDeferred fc n
src/Idris/Elab/Utils.hs+5−1
@@ -5,7 +5,7 @@ Description : Elaborator utilities.
5License : BSD3
5License : BSD3
6Maintainer : The Idris Community.
6Maintainer : The Idris Community.
7-}
7-}
8−{-# LANGUAGE FlexibleContexts, PatternGuards #-}
8+{-# LANGUAGE CPP, FlexibleContexts, PatternGuards #-}
9module Idris.Elab.Utils where
9module Idris.Elab.Utils where
10
10
11import Idris.AbsSyntax
11import Idris.AbsSyntax
@@ -21,6 +21,10 @@ import Idris.Output
21
21
22import Util.Pretty
22import Util.Pretty
23
23
24+#if (MIN_VERSION_base(4,11,0))
25+import Prelude hiding ((<>))
26+#endif
27+
24import Control.Monad
28import Control.Monad
25import Control.Monad.State
29import Control.Monad.State
26import Data.List
30import Data.List
src/Idris/Elab/Value.hs+1
@@ -26,6 +26,7 @@ import Prelude hiding (id, (.))
26
26
27import Control.Category
27import Control.Category
28import Data.Char (toLower)
28import Data.Char (toLower)
29+import qualified Data.Set as S ()
29import qualified Data.Traversable as Traversable
30import qualified Data.Traversable as Traversable
30
31
31-- | Elaborate a value, returning any new bindings created (this will only
32-- | Elaborate a value, returning any new bindings created (this will only
src/Idris/ElabDecls.hs+3−1
@@ -41,8 +41,10 @@ import Control.Category
41import Control.Monad
41import Control.Monad
42import Control.Monad.State.Strict as State
42import Control.Monad.State.Strict as State
43import Data.Maybe
43import Data.Maybe
44+import qualified Data.Set as S
44import qualified Data.Text as T
45import qualified Data.Text as T
45
46
47+
46-- | Top level elaborator info, supporting recursive elaboration
48-- | Top level elaborator info, supporting recursive elaboration
47recinfo :: FC -> ElabInfo
49recinfo :: FC -> ElabInfo
48recinfo fc = EInfo [] emptyContext id [] (Just fc) (fc_fname fc) 0 [] id elabDecl'
50recinfo fc = EInfo [] emptyContext id [] (Just fc) (fc_fname fc) 0 [] id elabDecl'
@@ -260,7 +262,7 @@ elabDecl' what info (POpenInterfaces f ns ds)
260elabDecl' what info (PNamespace n nfc ps) =
262elabDecl' what info (PNamespace n nfc ps) =
261 do mapM_ (elabDecl' what ninfo) ps
263 do mapM_ (elabDecl' what ninfo) ps
262 let ns = reverse (map T.pack newNS)
264 let ns = reverse (map T.pack newNS)
263− sendHighlighting [(nfc, AnnNamespace ns Nothing)]
265+ sendHighlighting $ S.fromList [(FC' nfc, AnnNamespace ns Nothing)]
264 where
266 where
265 newNS = n : namespace info
267 newNS = n : namespace info
266 ninfo = info { namespace = newNS }
268 ninfo = info { namespace = newNS }
src/Idris/IdrisDoc.hs+2−2
@@ -403,7 +403,7 @@ createIndex :: S.Set NsName -- ^ Set of namespace names to
403 -- documentation will be written.
403 -- documentation will be written.
404 -> IO ()
404 -> IO ()
405createIndex nss out =
405createIndex nss out =
406− do (path, h) <- openTempFile out "index.html"
406+ do (path, h) <- openTempFileWithDefaultPermissions out "index.html"
407 BS2.hPut h $ renderHtml $ wrapper Nothing $ do
407 BS2.hPut h $ renderHtml $ wrapper Nothing $ do
408 H.h1 "Namespaces"
408 H.h1 "Namespaces"
409 H.ul ! class_ "names" $ do
409 H.ul ! class_ "names" $ do
@@ -435,7 +435,7 @@ createNsDoc ist ns content out =
435 -- We cannot do anything without a Doc
435 -- We cannot do anything without a Doc
436 content' = concatMap haveDocs (nsContents content)
436 content' = concatMap haveDocs (nsContents content)
437 createDirectoryIfMissing True dir
437 createDirectoryIfMissing True dir
438− (path, h) <- openTempFile dir file
438+ (path, h) <- openTempFileWithDefaultPermissions dir file
439 BS2.hPut h $ renderHtml $ wrapper (Just ns) $ do
439 BS2.hPut h $ renderHtml $ wrapper (Just ns) $ do
440 H.h1 $ toHtml (nsName2Str ns)
440 H.h1 $ toHtml (nsName2Str ns)
441 case nsDocstring content of
441 case nsDocstring content of
src/Idris/Imports.hs+7−1
@@ -24,7 +24,13 @@ import System.Directory
24import System.FilePath
24import System.FilePath
25
25
26data IFileType = IDR FilePath | LIDR FilePath | IBC FilePath IFileType
26data 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
28
34
29newtype PkgName = PkgName String
35newtype PkgName = PkgName String
30
36
src/Idris/Main.hs+1−2
@@ -112,6 +112,7 @@ idrisMain opts =
112 putIState (i { default_total = DefaultCheckingTotal })
112 putIState (i { default_total = DefaultCheckingTotal })
113 tty <- runIO isATTY
113 tty <- runIO isATTY
114 setColourise $ not quiet && last (tty : opt getColour opts)
114 setColourise $ not quiet && last (tty : opt getColour opts)
115+ runIO $ hSetBuffering stdout LineBuffering
115
116
116
117
117
118
@@ -181,8 +182,6 @@ idrisMain opts =
181 [] -> ""
182 [] -> ""
182 (f:_) -> f
183 (f:_) -> f
183
184
184− runIO $ hSetBuffering stdout LineBuffering
185−
186 ok <- noErrors
185 ok <- noErrors
187 when ok $ case output of
186 when ok $ case output of
188 [] -> return ()
187 [] -> return ()
src/Idris/Output.hs+19−13
@@ -6,7 +6,7 @@ License : BSD3
6Maintainer : The Idris Community.
6Maintainer : The Idris Community.
7-}
7-}
8
8
9−{-# LANGUAGE FlexibleInstances #-}
9+{-# LANGUAGE CPP, FlexibleInstances #-}
10{-# OPTIONS_GHC -fwarn-incomplete-patterns #-}
10{-# OPTIONS_GHC -fwarn-incomplete-patterns #-}
11
11
12module Idris.Output (clearHighlights, emitWarning, formatMessage, idemodePutSExp,
12module Idris.Output (clearHighlights, emitWarning, formatMessage, idemodePutSExp,
@@ -30,12 +30,17 @@ import Util.Pretty
30import Util.ScreenSize (getScreenWidth)
30import Util.ScreenSize (getScreenWidth)
31import Util.System (isATTY)
31import Util.System (isATTY)
32
32
33+#if (MIN_VERSION_base(4,11,0))
34+import Prelude hiding ((<$>), (<>))
35+#else
33import Prelude hiding ((<$>))
36import Prelude hiding ((<$>))
37+#endif
34
38
35import Control.Arrow (first)
39import Control.Arrow (first)
36import Control.Monad.Trans.Except (ExceptT(ExceptT), runExceptT)
40import Control.Monad.Trans.Except (ExceptT(ExceptT), runExceptT)
37import Data.List (intersperse, nub)
41import Data.List (intersperse, nub)
38import Data.Maybe (fromJust, fromMaybe, isJust, listToMaybe)
42import Data.Maybe (fromJust, fromMaybe, isJust, listToMaybe)
43+import qualified Data.Set as S
39import System.Console.Haskeline.MonadException (MonadException(controlIO),
44import System.Console.Haskeline.MonadException (MonadException(controlIO),
40 RunIO(RunIO))
45 RunIO(RunIO))
41import System.FilePath (replaceExtension)
46import System.FilePath (replaceExtension)
@@ -73,9 +78,12 @@ formatMessage w = do
73 maybeSource <- case messageSource w of
78 maybeSource <- case messageSource w of
74 Just src -> pure (Just src)
79 Just src -> pure (Just src)
75 Nothing -> readSource fc
80 Nothing -> readSource fc
76− let maybeFormattedSource = maybeSource >>= layoutSource fc (idris_highlightedRegions i)
81+ let maybeFormattedSource = maybeSource >>= layoutSource fc (regions (idris_highlightedRegions i))
77 return $ layoutMessage (layoutFC fc) maybeFormattedSource (messageText w)
82 return $ layoutMessage (layoutFC fc) maybeFormattedSource (messageText w)
78 where
83 where
84+ regions :: S.Set (FC', OutputAnnotation) -> [(FC, OutputAnnotation)]
85+ regions rs = map (\(FC' a,b) -> (a, b)) $ S.toList rs
86+
79 fc :: FC
87 fc :: FC
80 fc = messageExtent w
88 fc = messageExtent w
81
89
@@ -355,25 +363,23 @@ prettyDocumentedIst ist (name, ty, docs) =
355sendParserHighlighting :: Idris ()
363sendParserHighlighting :: Idris ()
356sendParserHighlighting =
364sendParserHighlighting =
357 do ist <- getIState
365 do ist <- getIState
358− let hs = map unwrap . nub . map wrap $ idris_parserHighlights ist
366+ let hs = idris_parserHighlights ist
359 sendHighlighting hs
367 sendHighlighting hs
360 ist <- getIState
368 ist <- getIState
361− putIState ist {idris_parserHighlights = []}
369+ putIState ist {idris_parserHighlights = S.empty}
362− where wrap (fc, a) = (FC' fc, a)
363− unwrap (fc', a) = (unwrapFC fc', a)
364
370
365−sendHighlighting :: [(FC, OutputAnnotation)] -> Idris ()
371+sendHighlighting :: S.Set (FC', OutputAnnotation) -> Idris ()
366sendHighlighting highlights =
372sendHighlighting highlights =
367 do ist <- getIState
373 do ist <- getIState
368 case idris_outputmode ist of
374 case idris_outputmode ist of
369 RawOutput _ -> updateIState $
375 RawOutput _ -> updateIState $
370 \ist -> ist { idris_highlightedRegions =
376 \ist -> ist { idris_highlightedRegions =
371− highlights ++ idris_highlightedRegions ist }
377+ S.union highlights (idris_highlightedRegions ist) }
372 IdeMode n h ->
378 IdeMode n h ->
373 let fancier = [ toSExp (fc, fancifyAnnots ist False annot)
379 let fancier = [ toSExp (fc, fancifyAnnots ist False annot)
374− | (fc, annot) <- highlights, fullFC fc
380+ | (FC' fc, annot) <- S.toList highlights, fullFC fc
375− ]
381+ ] in
376− in case fancier of
382+ case fancier of
377 [] -> return ()
383 [] -> return ()
378 _ -> runIO . hPutStrLn h $
384 _ -> runIO . hPutStrLn h $
379 convSExp "output"
385 convSExp "output"
@@ -388,7 +394,7 @@ sendHighlighting highlights =
388writeHighlights :: FilePath -> Idris ()
394writeHighlights :: FilePath -> Idris ()
389writeHighlights f =
395writeHighlights f =
390 do ist <- getIState
396 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)
392 let hfile = replaceExtension f "idh"
398 let hfile = replaceExtension f "idh"
393 let annots = toSExp [ (fc, fancifyAnnots ist False annot)
399 let annots = toSExp [ (fc, fancifyAnnots ist False annot)
394 | (fc@(FC _ _ _), annot) <- hs
400 | (fc@(FC _ _ _), annot) <- hs
@@ -396,7 +402,7 @@ writeHighlights f =
396 runIO $ writeFile hfile $ sExpToString annots
402 runIO $ writeFile hfile $ sExpToString annots
397
403
398clearHighlights :: Idris ()
404clearHighlights :: Idris ()
399−clearHighlights = updateIState $ \ist -> ist { idris_highlightedRegions = [] }
405+clearHighlights = updateIState $ \ist -> ist { idris_highlightedRegions = S.empty }
400
406
401renderExternal :: OutputFmt -> Int -> Doc OutputAnnotation -> Idris String
407renderExternal :: OutputFmt -> Int -> Doc OutputAnnotation -> Idris String
402renderExternal fmt width doc
408renderExternal fmt width doc
src/Idris/Parser.hs+6−5
@@ -53,6 +53,7 @@ import qualified Data.List.Split as Spl
53import qualified Data.Map as M
53import qualified Data.Map as M
54import Data.Maybe
54import Data.Maybe
55import Data.Ord
55import Data.Ord
56+import qualified Data.Set as S
56import qualified Data.Text as T
57import qualified Data.Text as T
57import qualified System.Directory as Dir (makeAbsolute)
58import qualified System.Directory as Dir (makeAbsolute)
58import System.FilePath
59import System.FilePath
@@ -1491,7 +1492,7 @@ parseImports fname input
1491 Right (x, annots, i) ->
1492 Right (x, annots, i) ->
1492 do putIState i
1493 do putIState i
1493 fname' <- runIO $ Dir.makeAbsolute fname
1494 fname' <- runIO $ Dir.makeAbsolute fname
1494− sendHighlighting $ addPath annots fname'
1495+ sendHighlighting $ S.fromList $ addPath annots fname'
1495 return x
1496 return x
1496 where imports :: IdrisParser ((Maybe (Docstring ()), [String],
1497 where imports :: IdrisParser ((Maybe (Docstring ()), [String],
1497 [ImportInfo],
1498 [ImportInfo],
@@ -1512,11 +1513,11 @@ parseImports fname input
1512 let ps = ps_exp -- imp "Builtins" : imp "Prelude" : ps_exp
1513 let ps = ps_exp -- imp "Builtins" : imp "Prelude" : ps_exp
1513 return ((mdoc, mname, ps, mrk'), annots, i)
1514 return ((mdoc, mname, ps, mrk'), annots, i)
1514
1515
1515− addPath :: [(FC, OutputAnnotation)] -> FilePath -> [(FC, OutputAnnotation)]
1516+ addPath :: [(FC, OutputAnnotation)] -> FilePath -> [(FC', OutputAnnotation)]
1516 addPath [] _ = []
1517 addPath [] _ = []
1517 addPath ((fc, AnnNamespace ns Nothing) : annots) path =
1518 addPath ((fc, AnnNamespace ns Nothing) : annots) path =
1518− (fc, AnnNamespace ns (Just path)) : addPath annots path
1519+ (FC' fc, AnnNamespace ns (Just path)) : addPath annots path
1519− addPath (annot:annots) path = annot : addPath annots path
1520+ addPath ((fc,annot):annots) path = (FC' fc, annot) : addPath annots path
1520
1521
1521 shebang :: IdrisParser ()
1522 shebang :: IdrisParser ()
1522 shebang = string "#!" *> many (P.satisfy $ not . isEol) *> eol *> pure ()
1523 shebang = string "#!" *> many (P.satisfy $ not . isEol) *> eol *> pure ()
@@ -1664,7 +1665,7 @@ loadSource lidr f toline
1664 srcFnAbs <- case srcFn of
1665 srcFnAbs <- case srcFn of
1665 Just fn -> fmap Just (runIO $ Dir.makeAbsolute fn)
1666 Just fn -> fmap Just (runIO $ Dir.makeAbsolute fn)
1666 Nothing -> return Nothing
1667 Nothing -> return Nothing
1667− sendHighlighting [(nfc, AnnNamespace ns srcFnAbs)])
1668+ sendHighlighting $ S.fromList [(FC' nfc, AnnNamespace ns srcFnAbs)])
1668 [(re, fn, ns, nfc) | ImportInfo re fn _ ns _ nfc <- imports]
1669 [(re, fn, ns, nfc) | ImportInfo re fn _ ns _ nfc <- imports]
1669 reportParserWarnings
1670 reportParserWarnings
1670 sendParserHighlighting
1671 sendParserHighlighting
src/Idris/Parser/Helpers.hs+2−1
@@ -89,6 +89,7 @@ import Data.List
89import qualified Data.List.NonEmpty as NonEmpty
89import qualified Data.List.NonEmpty as NonEmpty
90import qualified Data.Map as M
90import qualified Data.Map as M
91import Data.Maybe
91import Data.Maybe
92+import qualified Data.Set as S
92import qualified Data.Text as T
93import qualified Data.Text as T
93import Text.Megaparsec ((<?>))
94import Text.Megaparsec ((<?>))
94import qualified Text.Megaparsec as P
95import qualified Text.Megaparsec as P
@@ -112,7 +113,7 @@ token p = trackExtent p <* whiteSpace
112highlight :: (MonadState IState m, Parsing m) => OutputAnnotation -> m a -> m a
113highlight :: (MonadState IState m, Parsing m) => OutputAnnotation -> m a -> m a
113highlight annot p = do
114highlight annot p = do
114 (result, fc) <- withExtent p
115 (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) }
116 return result
117 return result
117
118
118-- | Parse a reserved identfier, highlighting it as a keyword
119-- | 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
416getInt _ = []
416getInt _ = []
417
417
418strToInt :: IntTy -> [Const] -> Maybe Const
418strToInt :: IntTy -> [Const] -> Maybe Const
419−strToInt ity [Str x] = case reads x of
419+strToInt ity [Str x] = case reads $ dropFirstPlus x of
420 [(n,s)] -> Just $ if all isSpace s then toInt ity (n :: Integer) else I 0
420 [(n,s)] -> Just $ if all isSpace s then toInt ity (n :: Integer) else I 0
421 _ -> Just $ I 0
421 _ -> Just $ I 0
422+ where
423+ dropFirstPlus :: String -> String
424+ dropFirstPlus ('+' : str) = str
425+ dropFirstPlus str = str
422strToInt _ _ = Nothing
426strToInt _ _ = Nothing
423
427
424intToFloat :: [Const] -> Maybe Const
428intToFloat :: [Const] -> Maybe Const
src/Idris/REPL.hs+5−1
@@ -5,7 +5,7 @@ License : BSD3
5Maintainer : The Idris Community.
5Maintainer : The Idris Community.
6-}
6-}
7
7
8−{-# LANGUAGE FlexibleContexts, PatternGuards #-}
8+{-# LANGUAGE CPP, FlexibleContexts, PatternGuards #-}
9-- FIXME: {-# OPTIONS_GHC -fwarn-incomplete-patterns #-}
9-- FIXME: {-# OPTIONS_GHC -fwarn-incomplete-patterns #-}
10{-# OPTIONS_GHC -fwarn-unused-imports #-}
10{-# OPTIONS_GHC -fwarn-unused-imports #-}
11
11
@@ -82,7 +82,11 @@ import Idris.WhoCalls
82import IRTS.CodegenCommon
82import IRTS.CodegenCommon
83import IRTS.Compiler
83import IRTS.Compiler
84import Network
84import Network
85+#if (MIN_VERSION_base(4,11,0))
86+import Prelude hiding (id, (.), (<$>), (<>))
87+#else
85import Prelude hiding (id, (.), (<$>))
88import Prelude hiding (id, (.), (<$>))
89+#endif
86import System.Console.Haskeline as H
90import System.Console.Haskeline as H
87import System.Directory
91import System.Directory
88import System.Environment
92import System.Environment
src/Idris/TypeSearch.hs+17−2
@@ -5,7 +5,7 @@ Description : A Hoogle for Idris.
5License : BSD3
5License : BSD3
6Maintainer : The Idris Community.
6Maintainer : The Idris Community.
7-}
7-}
8−{-# LANGUAGE ScopedTypeVariables #-}
8+{-# LANGUAGE CPP, ScopedTypeVariables #-}
9
9
10module Idris.TypeSearch (
10module Idris.TypeSearch (
11 searchByType
11 searchByType
@@ -32,8 +32,12 @@ import Idris.Output (iPrintResult, iRenderError, iRenderOutput, iRenderResult,
32
32
33import Util.Pretty (Doc, annotate, char, text, vsep, (<>))
33import Util.Pretty (Doc, annotate, char, text, vsep, (<>))
34
34
35+#if (MIN_VERSION_base(4,11,0))
36+import Prelude hiding (Semigroup(..), pred)
37+import qualified Prelude as S (Semigroup(..))
38+#else
35import Prelude hiding (pred)
39import Prelude hiding (pred)
36−
40+#endif
37import Control.Applicative (Applicative(..), (<$>), (<*>), (<|>))
41import Control.Applicative (Applicative(..), (<$>), (<*>), (<|>))
38import Control.Arrow (first, second, (&&&), (***))
42import Control.Arrow (first, second, (&&&), (***))
39import Control.Monad (guard, when)
43import Control.Monad (guard, when)
@@ -238,6 +242,17 @@ instance Ord Score where
238 compare = comparing defaultScoreFunction
242 compare = comparing defaultScoreFunction
239
243
240
244
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+
241instance Monoid a => Monoid (Sided a) where
256instance Monoid a => Monoid (Sided a) where
242 mempty = Sided mempty mempty
257 mempty = Sided mempty mempty
243 (Sided l1 r1) `mappend` (Sided l2 r2) = Sided (l1 `mappend` l2) (r1 `mappend` r2)
258 (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
10 , withTempdir
10 , withTempdir
11 , rmFile
11 , rmFile
12 , catchIO
12 , catchIO
13+ , isDarwin
13 , isWindows
14 , isWindows
14 , writeSource
15 , writeSource
15 , writeSourceText
16 , writeSourceText
@@ -50,6 +51,9 @@ catchIO = CE.catch
50isWindows :: Bool
51isWindows :: Bool
51isWindows = os `elem` ["win32", "mingw32", "cygwin32"]
52isWindows = os `elem` ["win32", "mingw32", "cygwin32"]
52
53
54+isDarwin :: Bool
55+isDarwin = os == "darwin"
56+
53-- | Create a temp file with the extensiom ext (in the format ".xxx")
57-- | Create a temp file with the extensiom ext (in the format ".xxx")
54tempfile :: String -> IO (FilePath, Handle)
58tempfile :: String -> IO (FilePath, Handle)
55tempfile ext = do dir <- getTemporaryDirectory
59tempfile ext = do dir <- getTemporaryDirectory
stack-shell.nix+1−1
@@ -18,5 +18,5 @@ in haskell.lib.buildStackProject {
18 nativeBuildInputs = native_libs;
18 nativeBuildInputs = native_libs;
19 buildInputs = libs;
19 buildInputs = libs;
20 name = "idrisBuildEnv";
20 name = "idrisBuildEnv";
21− src = ./.;
21+ src = if lib.inNixShell then null else ./.;
22}
22}
stack.yaml+1−1
@@ -1,5 +1,5 @@
1#recheck extra-deps next on resolver or cabal file change
1#recheck extra-deps next on resolver or cabal file change
2−resolver: lts-10.4
2+resolver: lts-11.14
3
3
4packages:
4packages:
5 - location: .
5 - location: .
test/base001/Makefile+2−2
@@ -2,10 +2,10 @@
2all: exit1 sys.o
2all: exit1 sys.o
3
3
4exit1:
4exit1:
5− @gcc -Wall -o exit1 exit1.c
5+ @$(CC) -Wall -o exit1 exit1.c
6
6
7sys.o:
7sys.o:
8− @gcc -Wall -c sys.c
8+ @$(CC) -Wall -c sys.c
9
9
10clean:
10clean:
11 -@rm exit1 sys.o
11 -@rm exit1 sys.o
test/buffer002/buffer002.idr+2−2
@@ -3,8 +3,8 @@ import Data.Buffer
3main : IO ()
3main : IO ()
4main = do Just buf <- newBuffer 40
4main = do Just buf <- newBuffer 40
5 printLn (size buf)
5 printLn (size buf)
6− setInt buf 5 1234567890
6+ setInt buf 5 (-1024567890)
7− setInt buf 36 1234567890
7+ setInt buf 36 1034567890
8 setString buf 20 "Hello world!"
8 setString buf 20 "Hello world!"
9
9
10 printLn !(bufferData buf)
10 printLn !(bufferData buf)
test/buffer002/expected+4−4
@@ -1,9 +1,9 @@
140
140
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]
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−1234567890
3+-1024567890
4−4822530
4+12774997
5123.456
5123.456
6−1234567890
6+1034567890
70
70
8Hello worl
8Hello worl
9Hello world!
9Hello 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
8and
8and
9 String
9 String
10
10
11+message error
12+unification error
test/meta003/run+3−1
@@ -1,3 +1,5 @@
1#!/usr/bin/env bash
1#!/usr/bin/env bash
2${IDRIS:-idris} $@ --nocolour --check --consolewidth 70 BadDef.idr
2${IDRIS:-idris} $@ --nocolour --check --consolewidth 70 BadDef.idr
3+${IDRIS:-idris} $@ --nocolour --consolewidth 70 -o meta003 Catch.idr
4+./meta003
3−rm -f *.ibc
5+rm -f meta003 *.ibc
test/pkg008/expected+1−1
@@ -2,9 +2,9 @@ Entering directory `./src'
2Type checking ./NumOps.idr
2Type checking ./NumOps.idr
3Type checking ./Test.idr
3Type checking ./Test.idr
4Leaving directory `./src'
4Leaving directory `./src'
5+Entering directory `./src'
5Test Passed
6Test Passed
6Test Passed
7Test Passed
7−Entering directory `./src'
8Leaving directory `./src'
8Leaving directory `./src'
9Entering directory `./src'
9Entering directory `./src'
10Removed: NumOps.ibc
10Removed: 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 @@
1#!/usr/bin/env bash
1#!/usr/bin/env bash
2${IDRIS:-idris} $@ --check \
2${IDRIS:-idris} $@ --check \
3 reg001.idr reg002.idr reg003.idr reg004.lidr reg005.idr \
3 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 \
5 reg047a.idr reg053.idr reg057.idr reg058.idr reg058a.idr \
5 reg047a.idr reg053.idr reg057.idr reg058.idr reg058a.idr \
6 reg059.idr reg060.idr reg061.idr reg062.idr reg063.idr \
6 reg059.idr reg060.idr reg061.idr reg062.idr reg063.idr \
7 reg064.idr reg065.idr reg066.idr reg071.idr reg074.idr \
7 reg064.idr reg065.idr reg066.idr reg071.idr reg074.idr \