on master help sign in
Merge branch 'master' of github.com:idris-lang/Idris-dev
9ac4fdcScott Bonds
Setup.hs+33−18
@@ -1,11 +1,15 @@
1{-# LANGUAGE CPP #-}
1{-# LANGUAGE CPP #-}
2
2
3+#if !defined(MIN_VERSION_Cabal)
4+# define MIN_VERSION_Cabal(x,y,z) 0
5+#endif
6+
3import Control.Monad
7import Control.Monad
4import Data.IORef
8import Data.IORef
5import Control.Exception (SomeException, catch)
9import Control.Exception (SomeException, catch)
6
10
7import Distribution.Simple
11import Distribution.Simple
8−import Distribution.Simple.BuildPaths (autogenModulesDir)
12+import Distribution.Simple.BuildPaths
9import Distribution.Simple.InstallDirs as I
13import Distribution.Simple.InstallDirs as I
10import Distribution.Simple.LocalBuildInfo as L
14import Distribution.Simple.LocalBuildInfo as L
11import qualified Distribution.Simple.Setup as S
15import qualified Distribution.Simple.Setup as S
@@ -56,32 +60,37 @@ windres verbosity = P.runProgramInvocation verbosity . P.simpleProgramInvocation
56
60
57usesGMP :: S.ConfigFlags -> Bool
61usesGMP :: S.ConfigFlags -> Bool
58usesGMP flags =
62usesGMP flags =
59− case lookup (FlagName "gmp") (S.configConfigurationsFlags flags) of
63+ case lookup (mkFlagName "gmp") (S.configConfigurationsFlags flags) of
60 Just True -> True
64 Just True -> True
61 Just False -> False
65 Just False -> False
62 Nothing -> False
66 Nothing -> False
63
67
64execOnly :: S.ConfigFlags -> Bool
68execOnly :: S.ConfigFlags -> Bool
65execOnly flags =
69execOnly flags =
66− case lookup (FlagName "execonly") (S.configConfigurationsFlags flags) of
70+ case lookup (mkFlagName "execonly") (S.configConfigurationsFlags flags) of
67 Just True -> True
71 Just True -> True
68 Just False -> False
72 Just False -> False
69 Nothing -> False
73 Nothing -> False
70
74
71isRelease :: S.ConfigFlags -> Bool
75isRelease :: S.ConfigFlags -> Bool
72isRelease flags =
76isRelease flags =
73− case lookup (FlagName "release") (S.configConfigurationsFlags flags) of
77+ case lookup (mkFlagName "release") (S.configConfigurationsFlags flags) of
74 Just True -> True
78 Just True -> True
75 Just False -> False
79 Just False -> False
76 Nothing -> False
80 Nothing -> False
77
81
78isFreestanding :: S.ConfigFlags -> Bool
82isFreestanding :: S.ConfigFlags -> Bool
79isFreestanding flags =
83isFreestanding flags =
80− case lookup (FlagName "freestanding") (S.configConfigurationsFlags flags) of
84+ case lookup (mkFlagName "freestanding") (S.configConfigurationsFlags flags) of
81 Just True -> True
85 Just True -> True
82 Just False -> False
86 Just False -> False
83 Nothing -> False
87 Nothing -> False
84
88
89+#if !(MIN_VERSION_Cabal(2,0,0))
90+mkFlagName :: String -> FlagName
91+mkFlagName = FlagName
92+#endif
93+
85-- -----------------------------------------------------------------------------
94-- -----------------------------------------------------------------------------
86-- Clean
95-- Clean
87
96
@@ -151,20 +160,22 @@ generateToolchainModule verbosity srcDir toolDir = do
151 createDirectoryIfMissingVerbose verbosity True srcDir
160 createDirectoryIfMissingVerbose verbosity True srcDir
152 rewriteFile toolPath (commonContent ++ toolContent)
161 rewriteFile toolPath (commonContent ++ toolContent)
153
162
154−idrisConfigure _ flags _ local = do
163+idrisConfigure _ flags pkgdesc local = do
155 configureRTS
164 configureRTS
165+ withLibLBI pkgdesc local $ \_ libcfg -> do
166+ let libAutogenDir = autogenComponentModulesDir local libcfg
156− generateVersionModule verbosity (autogenModulesDir local) (isRelease (configFlags local))
167+ generateVersionModule verbosity libAutogenDir (isRelease (configFlags local))
157− if isFreestanding $ configFlags local
168+ if isFreestanding $ configFlags local
158− then do
169+ then do
159− toolDir <- lookupEnv "IDRIS_TOOLCHAIN_DIR"
170+ toolDir <- lookupEnv "IDRIS_TOOLCHAIN_DIR"
160− generateToolchainModule verbosity (autogenModulesDir local) toolDir
171+ generateToolchainModule verbosity libAutogenDir toolDir
161− targetDir <- lookupEnv "IDRIS_LIB_DIR"
172+ targetDir <- lookupEnv "IDRIS_LIB_DIR"
162− case targetDir of
173+ case targetDir of
163− Just d -> generateTargetModule verbosity (autogenModulesDir local) d
174+ Just d -> generateTargetModule verbosity libAutogenDir d
164− Nothing -> error $ "Trying to build freestanding without a target directory."
175+ Nothing -> error $ "Trying to build freestanding without a target directory."
165− ++ " Set it by defining IDRIS_LIB_DIR."
176+ ++ " Set it by defining IDRIS_LIB_DIR."
166− else
177+ else
167− generateToolchainModule verbosity (autogenModulesDir local) Nothing
178+ generateToolchainModule verbosity libAutogenDir Nothing
168 where
179 where
169 verbosity = S.fromFlag $ S.configVerbosity flags
180 verbosity = S.fromFlag $ S.configVerbosity flags
170 version = pkgVersion . package $ localPkgDescr local
181 version = pkgVersion . package $ localPkgDescr local
@@ -175,6 +186,10 @@ idrisConfigure _ flags _ local = do
175 -- the file after configure.
186 -- the file after configure.
176 configureRTS = make verbosity ["-C", "rts", "clean"]
187 configureRTS = make verbosity ["-C", "rts", "clean"]
177
188
189+#if !(MIN_VERSION_Cabal(2,0,0))
190+ autogenComponentModulesDir lbi _ = autogenModulesDir lbi
191+#endif
192+
178idrisPreSDist args flags = do
193idrisPreSDist args flags = do
179 let dir = S.fromFlag (S.sDistDirectory flags)
194 let dir = S.fromFlag (S.sDistDirectory flags)
180 let verb = S.fromFlag (S.sDistVerbosity flags)
195 let verb = S.fromFlag (S.sDistVerbosity flags)
docs/reference/partial-evaluation.rst+10−10
@@ -4,15 +4,15 @@ Static Arguments and Partial Evaluation
4
4
5As of version 0.9.15, Idris has support for *partial evaluation* of
5As of version 0.9.15, Idris has support for *partial evaluation* of
6statically known arguments. This involves creating specialised versions
6statically known arguments. This involves creating specialised versions
7−of functions with arguments annotated as ``[static]``.
7+of functions with arguments annotated as ``%static``.
8
8
9(This is an implementation of the partial evaluator described in `this
9(This is an implementation of the partial evaluator described in `this
10ICFP 2010
10ICFP 2010
11paper <http://eb.host.cs.st-andrews.ac.uk/writings/icfp10.pdf>`__.
11paper <http://eb.host.cs.st-andrews.ac.uk/writings/icfp10.pdf>`__.
12Please refer to this for more precise definitions of what follows.)
12Please refer to this for more precise definitions of what follows.)
13
13
14−Partial evaluation is switched on by default. It can be disabled with
14+Partial evaluation is switched off by default since Idris 1.0. It can
15−the ``--no-partial-eval`` flag.
15+be enabled with the ``--partial-eval`` flag.
16
16
17Introductory Example
17Introductory Example
18--------------------
18--------------------
@@ -66,18 +66,18 @@ Automatic specialisation of ``pow``
66~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
66~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
67
67
68The trick is to mark the statically known arguments with the
68The trick is to mark the statically known arguments with the
69−``[static]`` flag:
69+``%static`` flag:
70
70
71::
71::
72
72
73− my_pow : Nat -> [static] Nat -> Nat
73+ my_pow : Nat -> %static Nat -> Nat
74 my_pow k Z = 1
74 my_pow k Z = 1
75 my_pow k (S j) = mult k (my_pow k j)
75 my_pow k (S j) = mult k (my_pow k j)
76
76
77When an argument is annotated in this way, Idris will try to create a
77When an argument is annotated in this way, Idris will try to create a
78specialised version whenever it accounts a call with a concrete value
78specialised version whenever it accounts a call with a concrete value
79(i.e. a constant, constructor form, or globally defined function) in a
79(i.e. a constant, constructor form, or globally defined function) in a
80−``[static]`` position. If ``my_pow`` is defined this way, and ``powFn``
80+``%static`` position. If ``my_pow`` is defined this way, and ``powFn``
81defined as above, we can see the effect by typing ``:printdef powFn`` at
81defined as above, we can see the effect by typing ``:printdef powFn`` at
82the REPL:
82the REPL:
83
83
@@ -108,7 +108,7 @@ Specialising Type Classes
108-------------------------
108-------------------------
109
109
110Type class dictionaries are very often statically known, so Idris
110Type class dictionaries are very often statically known, so Idris
111−automatically marks any type class constraint as ``[static]`` and builds
111+automatically marks any type class constraint as ``%static`` and builds
112specialised versions of top level functions where the class is
112specialised versions of top level functions where the class is
113instantiated. For example, given:
113instantiated. For example, given:
114
114
@@ -177,7 +177,7 @@ writing ``map`` as follows:
177
177
178::
178::
179
179
180− my_map : [static] (a -> b) -> List a -> List b
180+ my_map : %static (a -> b) -> List a -> List b
181 my_map f [] = []
181 my_map f [] = []
182 my_map f (x :: xs) = f x :: my_map f xs
182 my_map f (x :: xs) = f x :: my_map f xs
183
183
@@ -246,11 +246,11 @@ Then, a function which calculates the factorial of its input:
246 (App (App eMult (App eFac (Op (-) x (Val 1)))) x))
246 (App (App eMult (App eFac (Op (-) x (Val 1)))) x))
247
247
248The interpreter's type is written as follows, marking the expression to
248The interpreter's type is written as follows, marking the expression to
249−be evaluated as ``[static]``:
249+be evaluated as ``%static``:
250
250
251::
251::
252
252
253− interp : (env : Env gamma) -> [static] (e : Expr gamma t) -> interpTy t
253+ interp : (env : Env gamma) -> %static (e : Expr gamma t) -> interpTy t
254
254
255This means that if we write an Idris program to calculate a factorial by
255This means that if we write an Idris program to calculate a factorial by
256calling ``interp`` on ``eFac``, the resulting definition will be
256calling ``interp`` on ``eFac``, the resulting definition will be
idris.cabal+10−2
@@ -97,6 +97,14 @@ source-repository head
97 type: git
97 type: git
98 location: git://github.com/idris-lang/Idris-dev.git
98 location: git://github.com/idris-lang/Idris-dev.git
99
99
100+custom-setup
101+ setup-depends:
102+ Cabal >= 1.10 && <2.1,
103+ base >= 4 && <5,
104+ directory,
105+ filepath,
106+ process
107+
100Flag FFI
108Flag FFI
101 Description: Build support for libffi
109 Description: Build support for libffi
102 Default: False
110 Default: False
@@ -265,11 +273,11 @@ Library
265 , ansi-wl-pprint < 0.7
273 , ansi-wl-pprint < 0.7
266 , array >= 0.4.0.1 && < 0.6
274 , array >= 0.4.0.1 && < 0.6
267 , base64-bytestring < 1.1
275 , base64-bytestring < 1.1
268− , binary >= 0.7 && < 0.9
276+ , binary >= 0.8.4.1 && < 0.9
269 , blaze-html >= 0.6.1.3 && < 0.10
277 , blaze-html >= 0.6.1.3 && < 0.10
270 , blaze-markup >= 0.5.2.1 && < 0.9
278 , blaze-markup >= 0.5.2.1 && < 0.9
271 , bytestring < 0.11
279 , bytestring < 0.11
272− , cheapskate < 0.1.1
280+ , cheapskate >= 0.1.1 && < 0.2
273 , code-page >= 0.1 && < 0.2
281 , code-page >= 0.1 && < 0.2
274 , containers >= 0.5 && < 0.6
282 , containers >= 0.5 && < 0.6
275 , deepseq < 1.5
283 , deepseq < 1.5
libs/contrib/Text/Lexer.idr+27−17
@@ -23,11 +23,11 @@ public export
23inf : Bool -> Type -> Type
23inf : Bool -> Type -> Type
24inf True t = Inf t
24inf True t = Inf t
25inf False t = t
25inf False t = t
26−
26+
27||| Sequence two recognisers. If either consumes a character, the sequence
27||| Sequence two recognisers. If either consumes a character, the sequence
28||| is guaranteed to consume a character.
28||| is guaranteed to consume a character.
29export %inline
29export %inline
30−(<+>) : {c1 : Bool} ->
30+(<+>) : {c1 : Bool} ->
31 Recognise c1 -> inf c1 (Recognise c2) -> Recognise (c1 || c2)
31 Recognise c1 -> inf c1 (Recognise c2) -> Recognise (c1 || c2)
32(<+>) {c1 = False} = SeqEmpty
32(<+>) {c1 = False} = SeqEmpty
33(<+>) {c1 = True} = SeqEat
33(<+>) {c1 = True} = SeqEat
@@ -59,6 +59,17 @@ export
59many : Lexer -> Recognise False
59many : Lexer -> Recognise False
60many l = some l <|> Empty
60many l = some l <|> Empty
61
61
62+||| Recognise many instances of `l` until an instance of `end` is
63+||| encountered.
64+|||
65+||| Useful for defining comments.
66+export
67+manyTill : (l : Lexer)
68+ -> (end : Lexer) -> Recognise False
69+manyTill l end = end
70+ <|> (l <+> manyTill l end)
71+ <|> Empty
72+
62||| Recognise any character
73||| Recognise any character
63export
74export
64any : Lexer
75any : Lexer
@@ -86,7 +97,7 @@ getString : StrLen -> String
86getString (MkStrLen str n) = str
97getString (MkStrLen str n) = str
87
98
88strIndex : StrLen -> Nat -> Maybe Char
99strIndex : StrLen -> Nat -> Maybe Char
89−strIndex (MkStrLen str len) i
100+strIndex (MkStrLen str len) i
90 = if i >= len then Nothing
101 = if i >= len then Nothing
91 else Just (assert_total (prim__strIndex str (cast i)))
102 else Just (assert_total (prim__strIndex str (cast i)))
92
103
@@ -102,25 +113,25 @@ strTail start (MkStrLen str len)
102scan : Recognise c -> Nat -> StrLen -> Maybe Nat
113scan : Recognise c -> Nat -> StrLen -> Maybe Nat
103scan Empty idx str = pure idx
114scan Empty idx str = pure idx
104scan Fail idx str = Nothing
115scan Fail idx str = Nothing
105−scan (Pred f) idx str
116+scan (Pred f) idx str
106 = do c <- strIndex str idx
117 = do c <- strIndex str idx
107 if f c
118 if f c
108 then Just (idx + 1)
119 then Just (idx + 1)
109 else Nothing
120 else Nothing
110−scan (SeqEat r1 r2) idx str
121+scan (SeqEat r1 r2) idx str
111 = do idx' <- scan r1 idx str
122 = do idx' <- scan r1 idx str
112 -- TODO: Can we prove totality instead by showing idx has increased?
123 -- TODO: Can we prove totality instead by showing idx has increased?
113 assert_total (scan r2 idx' str)
124 assert_total (scan r2 idx' str)
114−scan (SeqEmpty r1 r2) idx str
125+scan (SeqEmpty r1 r2) idx str
115 = do idx' <- scan r1 idx str
126 = do idx' <- scan r1 idx str
116 scan r2 idx' str
127 scan r2 idx' str
117−scan (Alt r1 r2) idx str
128+scan (Alt r1 r2) idx str
118 = case scan r1 idx str of
129 = case scan r1 idx str of
119 Nothing => scan r2 idx str
130 Nothing => scan r2 idx str
120 Just idx => Just idx
131 Just idx => Just idx
121
132
122takeToken : Lexer -> StrLen -> Maybe (String, StrLen)
133takeToken : Lexer -> StrLen -> Maybe (String, StrLen)
123−takeToken lex str
134+takeToken lex str
124 = do i <- scan lex 0 str -- i must be > 0 if successful
135 = do i <- scan lex 0 str -- i must be > 0 if successful
125 pure (substr 0 i (getString str), strTail i str)
136 pure (substr 0 i (getString str), strTail i str)
126
137
@@ -134,7 +145,7 @@ export
134exact : String -> Lexer
145exact : String -> Lexer
135exact str with (unpack str)
146exact str with (unpack str)
136 exact str | [] = Fail -- Not allowed, Lexer has to consume
147 exact str | [] = Fail -- Not allowed, Lexer has to consume
137− exact str | (x :: xs)
148+ exact str | (x :: xs)
138 = foldl SeqEmpty (is x) (map is xs)
149 = foldl SeqEmpty (is x) (map is xs)
139
150
140||| Recognise a whitespace character
151||| Recognise a whitespace character
@@ -185,8 +196,8 @@ record TokenData a where
185
196
186fspanEnd : Nat -> (Char -> Bool) -> String -> (Nat, String)
197fspanEnd : Nat -> (Char -> Bool) -> String -> (Nat, String)
187fspanEnd k p "" = (k, "")
198fspanEnd k p "" = (k, "")
188−fspanEnd k p xxs
199+fspanEnd k p xxs
189− = assert_total $
200+ = assert_total $
190 let x = prim__strHead xxs
201 let x = prim__strHead xxs
191 xs = prim__strTail xxs in
202 xs = prim__strTail xxs in
192 if p x then fspanEnd (S k) p xs
203 if p x then fspanEnd (S k) p xs
@@ -195,14 +206,14 @@ fspanEnd k p xxs
195-- Faster version of 'span' from the prelude (avoids unpacking)
206-- Faster version of 'span' from the prelude (avoids unpacking)
196export
207export
197fspan : (Char -> Bool) -> String -> (String, String)
208fspan : (Char -> Bool) -> String -> (String, String)
198−fspan p xs
209+fspan p xs
199 = let (end, rest) = fspanEnd 0 p xs in
210 = let (end, rest) = fspanEnd 0 p xs in
200 (substr 0 end xs, rest)
211 (substr 0 end xs, rest)
201
212
202tokenise : (line : Int) -> (col : Int) ->
213tokenise : (line : Int) -> (col : Int) ->
203− List (TokenData a) -> TokenMap a ->
214+ List (TokenData a) -> TokenMap a ->
204 StrLen -> (List (TokenData a), (Int, Int, StrLen))
215 StrLen -> (List (TokenData a), (Int, Int, StrLen))
205−tokenise line col acc tmap str
216+tokenise line col acc tmap str
206 = case getFirstToken tmap str of
217 = case getFirstToken tmap str of
207 Just (tok, line', col', rest) =>
218 Just (tok, line', col', rest) =>
208 -- assert total because getFirstToken must consume something
219 -- assert total because getFirstToken must consume something
@@ -213,7 +224,7 @@ tokenise line col acc tmap str
213 countNLs str = List.length (filter (== '\n') str)
224 countNLs str = List.length (filter (== '\n') str)
214
225
215 getCols : String -> Int -> Int
226 getCols : String -> Int -> Int
216− getCols x c
227+ getCols x c
217 = case fspan (/= '\n') (reverse x) of
228 = case fspan (/= '\n') (reverse x) of
218 (incol, "") => c + cast (length incol)
229 (incol, "") => c + cast (length incol)
219 (incol, _) => cast (length incol)
230 (incol, _) => cast (length incol)
@@ -223,7 +234,7 @@ tokenise line col acc tmap str
223 getFirstToken ((lex, fn) :: ts) str
234 getFirstToken ((lex, fn) :: ts) str
224 = case takeToken lex str of
235 = case takeToken lex str of
225 Just (tok, rest) => Just (MkToken line col (fn tok),
236 Just (tok, rest) => Just (MkToken line col (fn tok),
226− line + cast (countNLs (unpack tok)),
237+ line + cast (countNLs (unpack tok)),
227 getCols tok col, rest)
238 getCols tok col, rest)
228 Nothing => getFirstToken ts str
239 Nothing => getFirstToken ts str
229
240
@@ -235,4 +246,3 @@ export
235lex : TokenMap a -> String -> (List (TokenData a), (Int, Int, String))
246lex : TokenMap a -> String -> (List (TokenData a), (Int, Int, String))
236lex tmap str = let (ts, (l, c, str')) = tokenise 0 0 [] tmap (mkStr str) in
247lex tmap str = let (ts, (l, c, str')) = tokenise 0 0 [] tmap (mkStr str) in
237 (ts, (l, c, getString str'))
248 (ts, (l, c, getString str'))
238−
libs/contrib/Text/Parser.idr+67−26
@@ -3,7 +3,7 @@ module Text.Parser
3%default total
3%default total
4
4
5-- TODO: Add some primitives for helping with error messages.
5-- TODO: Add some primitives for helping with error messages.
6−-- e.g. perhaps set a string to state what we're currently trying to
6+-- e.g. perhaps set a string to state what we're currently trying to
7-- parse, or to say what the next expected token is in words
7-- parse, or to say what the next expected token is in words
8
8
9||| Description of a language's grammar. The `tok` parameter is the type
9||| Description of a language's grammar. The `tok` parameter is the type
@@ -26,14 +26,14 @@ data Grammar : (tok : Type) -> (consumes : Bool) -> Type -> Type where
26 Grammar tok c1 a -> (a -> Grammar tok c2 b) ->
26 Grammar tok c1 a -> (a -> Grammar tok c2 b) ->
27 Grammar tok (c1 || c2) b
27 Grammar tok (c1 || c2) b
28 Alt : {c1, c2 : Bool} ->
28 Alt : {c1, c2 : Bool} ->
29− Grammar tok c1 ty -> Grammar tok c2 ty ->
29+ Grammar tok c1 ty -> Grammar tok c2 ty ->
30 Grammar tok (c1 && c2) ty
30 Grammar tok (c1 && c2) ty
31
31
32public export
32public export
33inf : Bool -> Type -> Type
33inf : Bool -> Type -> Type
34inf True t = Inf t
34inf True t = Inf t
35inf False t = t
35inf False t = t
36−
36+
37||| Sequence two grammars. If either consumes some input, the sequence is
37||| Sequence two grammars. If either consumes some input, the sequence is
38||| guaranteed to consume some input. If the first one consumes input, the
38||| guaranteed to consume some input. If the first one consumes input, the
39||| second is allowed to be recursive (because it means some input has been
39||| second is allowed to be recursive (because it means some input has been
@@ -44,11 +44,11 @@ export %inline
44 Grammar tok (c1 || c2) b
44 Grammar tok (c1 || c2) b
45(>>=) {c1 = False} = SeqEmpty
45(>>=) {c1 = False} = SeqEmpty
46(>>=) {c1 = True} = SeqEat
46(>>=) {c1 = True} = SeqEat
47−
47+
48||| Give two alternative grammars. If both consume, the combination is
48||| Give two alternative grammars. If both consume, the combination is
49||| guaranteed to consume.
49||| guaranteed to consume.
50export
50export
51−(<|>) : Grammar tok c1 ty -> Grammar tok c2 ty ->
51+(<|>) : Grammar tok c1 ty -> Grammar tok c2 ty ->
52 Grammar tok (c1 && c2) ty
52 Grammar tok (c1 && c2) ty
53(<|>) = Alt
53(<|>) = Alt
54
54
@@ -82,21 +82,21 @@ export
82eof : Grammar tok False ()
82eof : Grammar tok False ()
83eof = EOF
83eof = EOF
84
84
85−||| Commit to an alternative; if the current branch of an alternative
85+||| Commit to an alternative; if the current branch of an alternative
86||| fails to parse, no more branches will be tried
86||| fails to parse, no more branches will be tried
87export
87export
88commit : Grammar tok False ()
88commit : Grammar tok False ()
89commit = Commit
89commit = Commit
90
90
91data ParseResult : List tok -> (consumes : Bool) -> Type -> Type where
91data ParseResult : List tok -> (consumes : Bool) -> Type -> Type where
92− Failure : {xs : List tok} ->
92+ Failure : {xs : List tok} ->
93 (committed : Bool) ->
93 (committed : Bool) ->
94 (err : String) -> (rest : List tok) -> ParseResult xs c ty
94 (err : String) -> (rest : List tok) -> ParseResult xs c ty
95 EmptyRes : (committed : Bool) ->
95 EmptyRes : (committed : Bool) ->
96 (val : ty) -> (more : List tok) -> ParseResult more False ty
96 (val : ty) -> (more : List tok) -> ParseResult more False ty
97 NonEmptyRes : (committed : Bool) ->
97 NonEmptyRes : (committed : Bool) ->
98 (val : ty) -> (more : List tok) ->
98 (val : ty) -> (more : List tok) ->
99− ParseResult (x :: xs ++ more) c ty
99+ ParseResult (x :: xs ++ more) c ty
100
100
101weakenRes : {whatever, c : Bool} -> {xs : List tok} ->
101weakenRes : {whatever, c : Bool} -> {xs : List tok} ->
102 ParseResult xs c ty -> ParseResult xs (whatever && c) ty
102 ParseResult xs c ty -> ParseResult xs (whatever && c) ty
@@ -105,13 +105,13 @@ weakenRes {whatever=True} (EmptyRes com val xs) = EmptyRes com val xs
105weakenRes {whatever=False} (EmptyRes com val xs) = EmptyRes com val xs
105weakenRes {whatever=False} (EmptyRes com val xs) = EmptyRes com val xs
106weakenRes (NonEmptyRes com val more) = NonEmptyRes com val more
106weakenRes (NonEmptyRes com val more) = NonEmptyRes com val more
107
107
108−shorter : (more : List tok) -> .(ys : List tok) ->
108+shorter : (more : List tok) -> .(ys : List tok) ->
109 LTE (S (length more)) (S (length (ys ++ more)))
109 LTE (S (length more)) (S (length (ys ++ more)))
110shorter more [] = lteRefl
110shorter more [] = lteRefl
111shorter more (x :: xs) = LTESucc (lteSuccLeft (shorter more xs))
111shorter more (x :: xs) = LTESucc (lteSuccLeft (shorter more xs))
112
112
113doParse : {c : Bool} ->
113doParse : {c : Bool} ->
114− (commit : Bool) -> (xs : List tok) -> (act : Grammar tok c ty) ->
114+ (commit : Bool) -> (xs : List tok) -> (act : Grammar tok c ty) ->
115 ParseResult xs c ty
115 ParseResult xs c ty
116doParse com xs act with (sizeAccessible xs)
116doParse com xs act with (sizeAccessible xs)
117 doParse com xs (Empty val) | sml = EmptyRes com val xs
117 doParse com xs (Empty val) | sml = EmptyRes com val xs
@@ -120,17 +120,17 @@ doParse com xs act with (sizeAccessible xs)
120 doParse com xs Commit | sml = EmptyRes True () xs
120 doParse com xs Commit | sml = EmptyRes True () xs
121
121
122 doParse com [] (Terminal f) | sml = Failure com "End of input" []
122 doParse com [] (Terminal f) | sml = Failure com "End of input" []
123− doParse com (x :: xs) (Terminal f) | sml
123+ doParse com (x :: xs) (Terminal f) | sml
124 = maybe
124 = maybe
125 (Failure com "Unrecognised token" (x :: xs))
125 (Failure com "Unrecognised token" (x :: xs))
126 (\a => NonEmptyRes com {xs=[]} a xs)
126 (\a => NonEmptyRes com {xs=[]} a xs)
127 (f x)
127 (f x)
128 doParse com [] EOF | sml = EmptyRes com () []
128 doParse com [] EOF | sml = EmptyRes com () []
129− doParse com (x :: xs) EOF | sml
129+ doParse com (x :: xs) EOF | sml
130 = Failure com "Expected end of input" (x :: xs)
130 = Failure com "Expected end of input" (x :: xs)
131 doParse com [] (NextIs f) | sml = Failure com "End of input" []
131 doParse com [] (NextIs f) | sml = Failure com "End of input" []
132− doParse com (x :: xs) (NextIs f) | sml
132+ doParse com (x :: xs) (NextIs f) | sml
133− = if f x
133+ = if f x
134 then EmptyRes com x (x :: xs)
134 then EmptyRes com x (x :: xs)
135 else Failure com "Unrecognised token" (x :: xs)
135 else Failure com "Unrecognised token" (x :: xs)
136 doParse com xs (Alt x y) | sml with (doParse False xs x | sml)
136 doParse com xs (Alt x y) | sml with (doParse False xs x | sml)
@@ -140,19 +140,19 @@ doParse com xs act with (sizeAccessible xs)
140 then Failure com msg ts
140 then Failure com msg ts
141 else weakenRes (doParse False xs y | sml)
141 else weakenRes (doParse False xs y | sml)
142 -- Successfully parsed the first option, so use the outer commit flag
142 -- Successfully parsed the first option, so use the outer commit flag
143− doParse com xs (Alt x y) | sml | (EmptyRes _ val xs)
143+ doParse com xs (Alt x y) | sml | (EmptyRes _ val xs)
144 = EmptyRes com val xs
144 = EmptyRes com val xs
145− doParse com (z :: (ys ++ more)) (Alt x y) | sml | (NonEmptyRes _ val more)
145+ doParse com (z :: (ys ++ more)) (Alt x y) | sml | (NonEmptyRes _ val more)
146 = NonEmptyRes com val more
146 = NonEmptyRes com val more
147 doParse com xs (SeqEmpty act next) | (Access morerec)
147 doParse com xs (SeqEmpty act next) | (Access morerec)
148 = case doParse com xs act | Access morerec of
148 = case doParse com xs act | Access morerec of
149 Failure com msg ts => Failure com msg ts
149 Failure com msg ts => Failure com msg ts
150− EmptyRes com val xs =>
150+ EmptyRes com val xs =>
151 case doParse com xs (next val) | (Access morerec) of
151 case doParse com xs (next val) | (Access morerec) of
152 Failure com' msg ts => Failure com' msg ts
152 Failure com' msg ts => Failure com' msg ts
153 EmptyRes com' val xs => EmptyRes com' val xs
153 EmptyRes com' val xs => EmptyRes com' val xs
154 NonEmptyRes com' val more => NonEmptyRes com' val more
154 NonEmptyRes com' val more => NonEmptyRes com' val more
155− NonEmptyRes {x} {xs=ys} com val more =>
155+ NonEmptyRes {x} {xs=ys} com val more =>
156 case (doParse com more (next val) | morerec _ (shorter more ys)) of
156 case (doParse com more (next val) | morerec _ (shorter more ys)) of
157 Failure com' msg ts => Failure com' msg ts
157 Failure com' msg ts => Failure com' msg ts
158 EmptyRes com' val _ => NonEmptyRes com' val more
158 EmptyRes com' val _ => NonEmptyRes com' val more
@@ -160,13 +160,13 @@ doParse com xs act with (sizeAccessible xs)
160 rewrite appendAssociative (x :: ys) (x1 :: xs1) more' in
160 rewrite appendAssociative (x :: ys) (x1 :: xs1) more' in
161 NonEmptyRes com' val more'
161 NonEmptyRes com' val more'
162 doParse com xs (SeqEat act next) | sml with (doParse com xs act | sml)
162 doParse com xs (SeqEat act next) | sml with (doParse com xs act | sml)
163− doParse com xs (SeqEat act next) | sml | Failure com' msg ts
163+ doParse com xs (SeqEat act next) | sml | Failure com' msg ts
164 = Failure com' msg ts
164 = Failure com' msg ts
165− doParse com (x :: (ys ++ more)) (SeqEat act next) | (Access morerec) | (NonEmptyRes com' val more)
165+ doParse com (x :: (ys ++ more)) (SeqEat act next) | (Access morerec) | (NonEmptyRes com' val more)
166 = case doParse com' more (next val) | morerec _ (shorter more ys) of
166 = case doParse com' more (next val) | morerec _ (shorter more ys) of
167 Failure com' msg ts => Failure com' msg ts
167 Failure com' msg ts => Failure com' msg ts
168 EmptyRes com' val _ => NonEmptyRes com' val more
168 EmptyRes com' val _ => NonEmptyRes com' val more
169− NonEmptyRes {x=x1} {xs=xs1} com' val more' =>
169+ NonEmptyRes {x=x1} {xs=xs1} com' val more' =>
170 rewrite appendAssociative (x :: ys) (x1 :: xs1) more' in
170 rewrite appendAssociative (x :: ys) (x1 :: xs1) more' in
171 NonEmptyRes com' val more'
171 NonEmptyRes com' val more'
172 -- This next line is not strictly necessary, but it stops the coverage
172 -- This next line is not strictly necessary, but it stops the coverage
@@ -180,7 +180,7 @@ data ParseError tok = Error String (List tok)
180||| returns a pair of the parse result and the unparsed tokens (the remaining
180||| returns a pair of the parse result and the unparsed tokens (the remaining
181||| input).
181||| input).
182export
182export
183−parse : (xs : List tok) -> (act : Grammar tok c ty) ->
183+parse : (xs : List tok) -> (act : Grammar tok c ty) ->
184 Either (ParseError tok) (ty, List tok)
184 Either (ParseError tok) (ty, List tok)
185parse xs act
185parse xs act
186 = case doParse False xs act of
186 = case doParse False xs act of
@@ -190,7 +190,7 @@ parse xs act
190
190
191||| Parse one or more things
191||| Parse one or more things
192export
192export
193−some : Grammar tok True a ->
193+some : Grammar tok True a ->
194 Grammar tok True (List a)
194 Grammar tok True (List a)
195some p = do x <- p
195some p = do x <- p
196 (do xs <- some p
196 (do xs <- some p
@@ -198,14 +198,14 @@ some p = do x <- p
198
198
199||| Parse zero or more things (may match the empty input)
199||| Parse zero or more things (may match the empty input)
200export
200export
201−many : Grammar tok True a ->
201+many : Grammar tok True a ->
202 Grammar tok False (List a)
202 Grammar tok False (List a)
203many p = some p
203many p = some p
204 <|> pure []
204 <|> pure []
205
205
206||| Parse one or more things, separated by another thing
206||| Parse one or more things, separated by another thing
207export
207export
208−sepBy1 : Grammar tok True () -> Grammar tok True a ->
208+sepBy1 : Grammar tok True () -> Grammar tok True a ->
209 Grammar tok True (List a)
209 Grammar tok True (List a)
210sepBy1 sep p = do x <- p
210sepBy1 sep p = do x <- p
211 (do sep
211 (do sep
@@ -215,7 +215,7 @@ sepBy1 sep p = do x <- p
215||| Parse zero or more things, separated by another thing. May
215||| Parse zero or more things, separated by another thing. May
216||| match the empty input.
216||| match the empty input.
217export
217export
218−sepBy : Grammar tok True () -> Grammar tok True a ->
218+sepBy : Grammar tok True () -> Grammar tok True a ->
219 Grammar tok False (List a)
219 Grammar tok False (List a)
220sepBy sep p = sepBy1 sep p <|> pure []
220sepBy sep p = sepBy1 sep p <|> pure []
221
221
@@ -227,3 +227,44 @@ optional : Grammar tok True a -> (ifNothing : a) ->
227optional p def = p <|> pure def
227optional p def = p <|> pure def
228
228
229
229
230+||| Parse an instance of `p` that is between `left` and `right`.
231+export
232+between : (left : Grammar tok True ())
233+ -> (right : Grammar tok True ())
234+ -> (p : Grammar tok True a)
235+ -> Grammar tok True a
236+between left right contents = do
237+ left
238+ res <- contents
239+ right
240+ pure res
241+
242+||| Parse one or more instances of `p` separated by `s`, returning the
243+||| parsed items and proof the resulting list is non-empty.
244+export
245+sepBy1' : (sep : Grammar tok True ())
246+ -> (p : Grammar tok True a)
247+ -> Grammar tok True (xs : List a ** NonEmpty xs)
248+sepBy1' sep p
249+ = do x <- p
250+ (do sep
251+ xs <- sepBy1 sep p
252+ pure (x :: xs ** IsNonEmpty)) <|> pure ([x] ** IsNonEmpty)
253+
254+||| Parse one or more instances of `p`, returning the parsed items and proof the resulting list is non-empty.
255+export
256+some' : (p : Grammar tok True a)
257+ -> Grammar tok True (xs : List a ** NonEmpty xs)
258+some' p = do
259+ x <- p
260+ (do xs <- some p
261+ pure (x::xs ** IsNonEmpty)) <|> pure ([x] ** IsNonEmpty)
262+
263+
264+||| Optionally parse a thing. If the grammar provides a default use `optional` instead.
265+export
266+maybe : Grammar tok True a
267+ -> Grammar tok False (Maybe a)
268+maybe p =
269+ (do res <- p; pure $ Just res)
270+ <|> pure Nothing
libs/contrib/Text/PrettyPrint/WL/Characters.idr+2−2
@@ -69,8 +69,8 @@ bang = char '!'
69tick : Doc
69tick : Doc
70tick = char '`'
70tick = char '`'
71
71
72−tilda : Doc
72+tilde : Doc
73−tilda = char '~'
73+tilde = char '~'
74
74
75hash : Doc
75hash : Doc
76hash = char '#'
76hash = char '#'
libs/contrib/Text/PrettyPrint/WL/Core.idr+4−4
@@ -128,10 +128,10 @@ showPrettyDoc : (doc : PrettyDoc) -> String
128showPrettyDoc doc = showPrettyDocS doc ""
128showPrettyDoc doc = showPrettyDocS doc ""
129 where
129 where
130 showPrettyDocS : (doc : PrettyDoc) -> (acc : String) -> String
130 showPrettyDocS : (doc : PrettyDoc) -> (acc : String) -> String
131− showPrettyDocS Empty = id
131+ showPrettyDocS Empty acc = acc
132− showPrettyDocS (Chara c rest) = strCons c . showPrettyDocS rest
132+ showPrettyDocS (Chara c rest) acc = strCons c (showPrettyDocS rest acc)
133− showPrettyDocS (Text len str rest) = (str ++) . showPrettyDocS rest
133+ showPrettyDocS (Text len str rest) acc = str ++ (showPrettyDocS rest acc)
134− showPrettyDocS (Line lvl rest) = (('\n' `strCons` indentation lvl) ++) . showPrettyDocS rest
134+ showPrettyDocS (Line lvl rest) acc = (strCons '\n' (indentation lvl)) ++ showPrettyDocS rest acc
135
135
136private
136private
137fits : (w : Int) -> (x : PrettyDoc) -> Bool
137fits : (w : Int) -> (x : PrettyDoc) -> Bool
src/IRTS/CodegenC.hs+116−233
@@ -9,7 +9,7 @@ Maintainer : The Idris Community.
9
9
10module IRTS.CodegenC (codegenC) where
10module IRTS.CodegenC (codegenC) where
11
11
12−import Idris.AbsSyntax hiding (getBC)
12+import Idris.AbsSyntax
13import Idris.Core.TT
13import Idris.Core.TT
14import IRTS.Bytecode
14import IRTS.Bytecode
15import IRTS.CodegenCommon
15import IRTS.CodegenCommon
@@ -21,12 +21,10 @@ import IRTS.System
21import Util.System
21import Util.System
22
22
23import Control.Monad
23import Control.Monad
24−import Control.Monad
25−import Control.Monad.RWS
26import Data.Bits
24import Data.Bits
27import Data.Char
25import Data.Char
28−import Data.List (find, intercalate, nubBy, partition)
26+import Data.List (intercalate, nubBy)
29−import qualified Data.Text as T
27+import Debug.Trace
30import Numeric
28import Numeric
31import System.Directory
29import System.Directory
32import System.Exit
30import System.Exit
@@ -34,8 +32,6 @@ import System.FilePath ((<.>), (</>))
34import System.IO
32import System.IO
35import System.Process
33import System.Process
36
34
37−import Debug.Trace
38−
39codegenC :: CodeGenerator
35codegenC :: CodeGenerator
40codegenC ci = do codegenC' (simpleDecls ci)
36codegenC ci = do codegenC' (simpleDecls ci)
41 (outputFile ci)
37 (outputFile ci)
@@ -70,9 +66,7 @@ codegenC' defs out exec incs objs libs flags exports iface dbg
70 let bc = map toBC defs
66 let bc = map toBC defs
71 let wrappers = genWrappers bc
67 let wrappers = genWrappers bc
72 let h = concatMap toDecl (map fst bc)
68 let h = concatMap toDecl (map fst bc)
73− let (state, cc) = execRWS (generateSrc bc) 0
69+ let cc = concatMap (uncurry toC) bc
74− (CS { fnName = Nothing,
75− level = 1 })
76 let hi = concatMap ifaceC (concatMap getExp exports)
70 let hi = concatMap ifaceC (concatMap getExp exports)
77 d <- getIdrisCRTSDir
71 d <- getIdrisCRTSDir
78 mprog <- readFile (d </> "idris_main" <.> "c")
72 mprog <- readFile (d </> "idris_main" <.> "c")
@@ -142,17 +136,12 @@ creg Tmp = "REG1"
142toDecl :: Name -> String
136toDecl :: Name -> String
143toDecl f = "void " ++ cname f ++ "(VM*, VAL*);\n"
137toDecl f = "void " ++ cname f ++ "(VM*, VAL*);\n"
144
138
145−generateSrc :: [(Name, [BC])] -> RWS Int String CState ()
139+toC :: Name -> [BC] -> String
146−generateSrc bc = mapM_ toC bc
147−
148−toC :: (Name, [BC]) -> RWS Int String CState ()
149−toC (f, code) = do
140+toC f code
150− modify (\s -> s { fnName = Just f })
141+ = -- "/* " ++ show code ++ "*/\n\n" ++
151− s <- get
152− tell $ "void " ++ cname f ++ "(VM* vm, VAL* oldbase) {\n"
142+ "void " ++ cname f ++ "(VM* vm, VAL* oldbase) {\n" ++
153− tell $ indent (level s) ++ "INITFRAME;\n"
143+ indent 1 ++ "INITFRAME;\n" ++
154− bcc code
144+ concatMap (bcc 1) code ++ "}\n\n"
155− tell $ "}\n\n"
156
145
157showCStr :: String -> String
146showCStr :: String -> String
158showCStr s = '"' : foldr ((++) . showChar) "\"" s
147showCStr s = '"' : foldr ((++) . showChar) "\"" s
@@ -188,27 +177,15 @@ showCStr s = '"' : foldr ((++) . showChar) "\"" s
188 2 -> s
177 2 -> s
189 _ -> error $ "Can't happen: String of invalid length " ++ show s
178 _ -> error $ "Can't happen: String of invalid length " ++ show s
190
179
191−data CState = CS {
192− fnName :: Maybe Name,
193− level :: Int
194−}
195−
196−
197−bcc :: [BC] -> RWS Int String CState ()
180+bcc :: Int -> BC -> String
198−bcc [] = return ()
199−bcc ((ASSIGN l r):xs) = do
200− i <- get
201− tell $ indent (level i) ++ creg l ++ " = " ++ creg r ++ ";\n"
181+bcc i (ASSIGN l r) = indent i ++ creg l ++ " = " ++ creg r ++ ";\n"
202− bcc xs
203−bcc ((ASSIGNCONST l c):xs) = do
182+bcc i (ASSIGNCONST l c)
204− i <- get
205− tell $ indent (level i) ++ creg l ++ " = " ++ mkConst c ++ ";\n"
183+ = indent i ++ creg l ++ " = " ++ mkConst c ++ ";\n"
206− bcc xs
207 where
184 where
208 mkConst (I i) = "MKINT(" ++ show i ++ ")"
185 mkConst (I i) = "MKINT(" ++ show i ++ ")"
209 mkConst (BI i) | i < (2^30) = "MKINT(" ++ show i ++ ")"
186 mkConst (BI i) | i < (2^30) = "MKINT(" ++ show i ++ ")"
210 | otherwise = "MKBIGC(vm,\"" ++ show i ++ "\")"
187 | otherwise = "MKBIGC(vm,\"" ++ show i ++ "\")"
211− mkConst (Fl f) = "MKFLOAT(vm, " ++ show f ++ ")"
188+ mkConst (Fl f) = "MKFLOAT(vm, " ++ (map toUpper $ show f) ++ ")"
212 mkConst (Ch c) = "MKINT(" ++ show (fromEnum c) ++ ")"
189 mkConst (Ch c) = "MKINT(" ++ show (fromEnum c) ++ ")"
213 mkConst (Str s) = "MKSTR(vm, " ++ showCStr s ++ ")"
190 mkConst (Str s) = "MKSTR(vm, " ++ showCStr s ++ ")"
214 mkConst (B8 x) = "idris_b8const(vm, " ++ show x ++ "U)"
191 mkConst (B8 x) = "idris_b8const(vm, " ++ show x ++ "U)"
@@ -221,21 +198,16 @@ bcc ((ASSIGNCONST l c):xs) = do
221 mkConst c | isTypeConst c = "MKINT(42424242)"
198 mkConst c | isTypeConst c = "MKINT(42424242)"
222 mkConst c = error $ "mkConst of (" ++ show c ++ ") not implemented"
199 mkConst c = error $ "mkConst of (" ++ show c ++ ") not implemented"
223
200
224−bcc ((UPDATE l r):xs) = do
225− i <- get
226− tell $ indent (level i) ++ creg l ++ " = " ++ creg r ++ ";\n"
201+bcc i (UPDATE l r) = indent i ++ creg l ++ " = " ++ creg r ++ ";\n"
227− bcc xs
228−bcc ((MKCON l loc tag []):xs) | tag < 256 = do
202+bcc i (MKCON l loc tag []) | tag < 256
229− i <- get
230− tell $ indent (level i) ++ creg l ++ " = NULL_CON(" ++ show tag ++ ");\n"
203+ = indent i ++ creg l ++ " = NULL_CON(" ++ show tag ++ ");\n"
231− bcc xs
232−bcc ((MKCON l loc tag args):xs) = do
204+bcc i (MKCON l loc tag args)
233− i <- get
234− let tab = indent (level i)
235− tell $ tab ++ alloc loc tag ++
205+ = indent i ++ alloc loc tag ++
236− tab ++ setArgs 0 args ++ "\n" ++
206+ indent i ++ setArgs 0 args ++ "\n" ++
237− tab ++ creg l ++ " = " ++ creg Tmp ++ ";\n"
207+ indent i ++ creg l ++ " = " ++ creg Tmp ++ ";\n"
238− bcc xs
208+
209+-- "MKCON(vm, " ++ creg l ++ ", " ++ show tag ++ ", " ++
210+-- show (length args) ++ concatMap showArg args ++ ");\n"
239 where showArg r = ", " ++ creg r
211 where showArg r = ", " ++ creg r
240 setArgs i [] = ""
212 setArgs i [] = ""
241 setArgs i (x : xs) = "SETARG(" ++ creg Tmp ++ ", " ++ show i ++ ", " ++ creg x ++
213 setArgs i (x : xs) = "SETARG(" ++ creg Tmp ++ ", " ++ show i ++ ", " ++ creg x ++
@@ -247,94 +219,52 @@ bcc ((MKCON l loc tag args):xs) = do
247 = "updateCon(" ++ creg Tmp ++ ", " ++ creg old ++ ", " ++ show tag ++ ", " ++
219 = "updateCon(" ++ creg Tmp ++ ", " ++ creg old ++ ", " ++ show tag ++ ", " ++
248 show (length args) ++ ");\n"
220 show (length args) ++ ");\n"
249
221
250−bcc ((PROJECT l loc a):xs) = do
251− i <- get
252− tell $ indent (level i) ++ "PROJECT(vm, " ++ creg l ++ ", "
222+bcc i (PROJECT l loc a) = indent i ++ "PROJECT(vm, " ++ creg l ++ ", " ++ show loc ++
253− ++ show loc ++ ", " ++ show a ++ ");\n"
223+ ", " ++ show a ++ ");\n"
254− bcc xs
255−bcc ((PROJECTINTO r t idx):xs) = do
224+bcc i (PROJECTINTO r t idx)
256− i <- get
257− tell $ indent (level i) ++ creg r ++ " = GETARG(" ++ creg t
225+ = indent i ++ creg r ++ " = GETARG(" ++ creg t ++ ", " ++ show idx ++ ");\n"
258− ++ ", " ++ show idx ++ ");\n"
259− bcc xs
260−bcc ((CASE True r code def):xs)
226+bcc i (CASE True r code def)
261− | length code < 4 = do
227+ | length code < 4 = showCase i def code
262− showCases def code
263− bcc xs
264 where
228 where
265− showCode bc = do
229+ showCode :: Int -> [BC] -> String
266− w <- getBC bc xs
230+ showCode i bc = "{\n" ++ concatMap (bcc (i + 1)) bc ++
267− i <- get
231+ indent i ++ "}\n"
268− tell $ "{\n" ++ w ++ indent (level i) ++ "}\n"
232+
269−
233+ showCase :: Int -> Maybe [BC] -> [(Int, [BC])] -> String
270− showCases Nothing [(t, c)] = do
234+ showCase i Nothing [(t, c)] = indent i ++ showCode i c
271− i <- get
235+ showCase i (Just def) [] = indent i ++ showCode i def
272− tell $ indent (level i)
273− showCode c
274− showCases (Just def) [] = do
275− i <- get
276− tell $ indent (level i)
277− showCode def
278− showCases def ((t, c) : cs) = do
236+ showCase i def ((t, c) : cs)
279− i <- get
280− tell $ indent (level i) ++ "if (CTAG(" ++ creg r ++ ") == "
237+ = indent i ++ "if (CTAG(" ++ creg r ++ ") == " ++ show t ++ ") " ++ showCode i c
281− ++ show t ++ ") "
282− showCode c
283− tell $ indent (level i) ++ "else\n"
238+ ++ indent i ++ "else\n" ++ showCase i def cs
284− showCases def cs
239+
285−
286−bcc ((CASE safe r code def):xs) = do
240+bcc i (CASE safe r code def)
287− i <- get
288− tell $ indent (level i) ++ "switch(" ++ ctag safe ++ "(" ++ creg r ++ ")) {\n"
241+ = indent i ++ "switch(" ++ ctag safe ++ "(" ++ creg r ++ ")) {\n" ++
289− mapM showCase code
242+ concatMap (showCase i) code ++
290− showDef def
243+ showDef i def ++
291− tell $ indent (level i) ++ "}\n"
244+ indent i ++ "}\n"
292− bcc xs
293 where
245 where
294 ctag True = "CTAG"
246 ctag True = "CTAG"
295 ctag False = "TAG"
247 ctag False = "TAG"
296
248
297− showCase (t, bc) = do
298− w <- getBC bc xs
299− is <- get
300− let i = level is
301− tell $ indent i ++ "case " ++ show t ++ ":\n"
249+ showCase i (t, bc) = indent i ++ "case " ++ show t ++ ":\n"
302− ++ w ++ indent (i + 1) ++ "break;\n"
250+ ++ concatMap (bcc (i+1)) bc ++ indent (i + 1) ++ "break;\n"
303− showDef Nothing = return $ ()
251+ showDef i Nothing = ""
304− showDef (Just c) = do
252+ showDef i (Just c) = indent i ++ "default:\n"
305− w <- getBC c xs
306− is <- get
307− let i = level is
308− tell $ indent i ++ "default:\n" ++ w ++ indent (i + 1) ++ "break;\n"
253+ ++ concatMap (bcc (i+1)) c ++ indent (i + 1) ++ "break;\n"
309−
310−bcc ((CONSTCASE r code def):xs)
254+bcc i (CONSTCASE r code def)
311 | intConsts code
255 | intConsts code
312− = do
256+-- = indent i ++ "switch(GETINT(" ++ creg r ++ ")) {\n" ++
313− is <- get
257+-- concatMap (showCase i) code ++
314− let i = level is
258+-- showDef i def ++
315− codes <- mapM getCode code
259+-- indent i ++ "}\n"
316− defs <- showDefS def
317− tell $ concatMap (iCase i (creg r)) codes
260+ = concatMap (iCase (creg r)) code ++
318− tell $ indent i ++ "{\n" ++ defs ++ indent i ++ "}\n"
261+ indent i ++ "{\n" ++ showDefS i def ++ indent i ++ "}\n"
319− bcc xs
320 | strConsts code
262 | strConsts code
321− = do
322− is <- get
323− let i = level is
324− codes <- mapM getCode code
325− defs <- showDefS def
326− tell $ concatMap (strCase i ("GETSTR(" ++ creg r ++ ")")) codes
263+ = concatMap (strCase ("GETSTR(" ++ creg r ++ ")")) code ++
327− ++ indent i ++ "{\n" ++ defs ++ indent i ++ "}\n"
264+ indent i ++ "{\n" ++ showDefS i def ++ indent i ++ "}\n"
328− bcc xs
329 | bigintConsts code
265 | bigintConsts code
330− = do
331− is <- get
332− let i = level is
333− codes <- mapM getCode code
334− defs <- showDefS def
335− tell $ concatMap (biCase i (creg r)) codes ++
266+ = concatMap (biCase (creg r)) code ++
336− indent i ++ "{\n" ++ defs ++ indent i ++ "}\n"
267+ indent i ++ "{\n" ++ showDefS i def ++ indent i ++ "}\n"
337− bcc xs
338 | otherwise = error $ "Can't happen: Can't compile const case " ++ show code
268 | otherwise = error $ "Can't happen: Can't compile const case " ++ show code
339 where
269 where
340 intConsts ((I _, _ ) : _) = True
270 intConsts ((I _, _ ) : _) = True
@@ -351,119 +281,72 @@ bcc ((CONSTCASE r code def):xs)
351 strConsts ((Str _, _ ) : _) = True
281 strConsts ((Str _, _ ) : _) = True
352 strConsts _ = False
282 strConsts _ = False
353
283
354− getCode (x, code) = do
355− c <- getBC code xs
356− return (x, c)
357−
358− strCase i sv (s, bc) =
284+ strCase sv (s, bc) =
359 indent i ++ "if (strcmp(" ++ sv ++ ", " ++ show s ++ ") == 0) {\n" ++
285 indent i ++ "if (strcmp(" ++ sv ++ ", " ++ show s ++ ") == 0) {\n" ++
360− bc ++ indent i ++ "} else\n"
286+ concatMap (bcc (i+1)) bc ++ indent i ++ "} else\n"
361− biCase i bv (BI b, bc) =
287+ biCase bv (BI b, bc) =
362 indent i ++ "if (bigEqConst(" ++ bv ++ ", " ++ show b ++ ")) {\n"
288 indent i ++ "if (bigEqConst(" ++ bv ++ ", " ++ show b ++ ")) {\n"
363− ++ bc ++ indent i ++ "} else\n"
289+ ++ concatMap (bcc (i+1)) bc ++ indent i ++ "} else\n"
364− iCase i v (I b, bc) =
290+ iCase v (I b, bc) =
365 indent i ++ "if (GETINT(" ++ v ++ ") == " ++ show b ++ ") {\n"
291 indent i ++ "if (GETINT(" ++ v ++ ") == " ++ show b ++ ") {\n"
366− ++ bc ++ indent i ++ "} else\n"
292+ ++ concatMap (bcc (i+1)) bc ++ indent i ++ "} else\n"
367− iCase i v (Ch b, bc) =
293+ iCase v (Ch b, bc) =
368 indent i ++ "if (GETINT(" ++ v ++ ") == " ++ show (fromEnum b) ++ ") {\n"
294 indent i ++ "if (GETINT(" ++ v ++ ") == " ++ show (fromEnum b) ++ ") {\n"
369− ++ bc ++ indent i ++ "} else\n"
295+ ++ concatMap (bcc (i+1)) bc ++ indent i ++ "} else\n"
370− iCase i v (B8 w, bc) =
296+ iCase v (B8 w, bc) =
371 indent i ++ "if (GETBITS8(" ++ v ++ ") == " ++ show (fromEnum w) ++ ") {\n"
297 indent i ++ "if (GETBITS8(" ++ v ++ ") == " ++ show (fromEnum w) ++ ") {\n"
372− ++ bc ++ indent i ++ "} else\n"
298+ ++ concatMap (bcc (i+1)) bc ++ indent i ++ "} else\n"
373− iCase i v (B16 w, bc) =
299+ iCase v (B16 w, bc) =
374 indent i ++ "if (GETBITS16(" ++ v ++ ") == " ++ show (fromEnum w) ++ ") {\n"
300 indent i ++ "if (GETBITS16(" ++ v ++ ") == " ++ show (fromEnum w) ++ ") {\n"
375− ++ bc ++ indent i ++ "} else\n"
301+ ++ concatMap (bcc (i+1)) bc ++ indent i ++ "} else\n"
376− iCase i v (B32 w, bc) =
302+ iCase v (B32 w, bc) =
377 indent i ++ "if (GETBITS32(" ++ v ++ ") == " ++ show (fromEnum w) ++ ") {\n"
303 indent i ++ "if (GETBITS32(" ++ v ++ ") == " ++ show (fromEnum w) ++ ") {\n"
378− ++ bc ++ indent i ++ "} else\n"
304+ ++ concatMap (bcc (i+1)) bc ++ indent i ++ "} else\n"
379− iCase i v (B64 w, bc) =
305+ iCase v (B64 w, bc) =
380 indent i ++ "if (GETBITS64(" ++ v ++ ") == " ++ show (fromEnum w) ++ ") {\n"
306 indent i ++ "if (GETBITS64(" ++ v ++ ") == " ++ show (fromEnum w) ++ ") {\n"
381− ++ bc ++ indent i ++ "} else\n"
307+ ++ concatMap (bcc (i+1)) bc ++ indent i ++ "} else\n"
382−
308+ showCase i (t, bc) = indent i ++ "case " ++ show t ++ ":\n"
383− showDefS Nothing = return ""
309+ ++ concatMap (bcc (i+1)) bc ++
384− showDefS (Just c) = getBC c xs
310+ indent (i + 1) ++ "break;\n"
385−
311+ showDef i Nothing = ""
386−bcc (CALL n:xs) = do
312+ showDef i (Just c) = indent i ++ "default:\n"
387− i <- get
313+ ++ concatMap (bcc (i+1)) c ++
314+ indent (i + 1) ++ "break;\n"
315+ showDefS i Nothing = ""
316+ showDefS i (Just c) = concatMap (bcc (i+1)) c
317+
388− tell $ indent (level i) ++ "CALL(" ++ cname n ++ ");\n"
318+bcc i (CALL n) = indent i ++ "CALL(" ++ cname n ++ ");\n"
389− bcc xs
390−bcc (TAILCALL n:xs) = do
391− i <- get
392− tell $ indent (level i) ++ "TAILCALL(" ++ cname n ++ ");\n"
319+bcc i (TAILCALL n) = indent i ++ "TAILCALL(" ++ cname n ++ ");\n"
393− bcc xs
394−bcc ((SLIDE n):xs) = do
395− i <- get
396− tell $ indent (level i) ++ "SLIDE(vm, " ++ show n ++ ");\n"
320+bcc i (SLIDE n) = indent i ++ "SLIDE(vm, " ++ show n ++ ");\n"
397− bcc xs
398−bcc (REBASE:xs) = do
399− i <- get
400− tell $ indent (level i)++ "REBASE;\n"
321+bcc i REBASE = indent i ++ "REBASE;\n"
401− bcc xs
402−bcc ((RESERVE 0):xs) = bcc xs
322+bcc i (RESERVE 0) = ""
403−bcc ((RESERVE n):xs) = do
404− i <- get
405− tell $ indent (level i) ++ "RESERVE(" ++ show n ++ ");\n"
323+bcc i (RESERVE n) = indent i ++ "RESERVE(" ++ show n ++ ");\n"
406− bcc xs
407−bcc ((ADDTOP 0):xs) = bcc xs
324+bcc i (ADDTOP 0) = ""
408−bcc ((ADDTOP n):xs) = do
409− i <- get
410− tell $ indent (level i) ++ "ADDTOP(" ++ show n ++ ");\n"
325+bcc i (ADDTOP n) = indent i ++ "ADDTOP(" ++ show n ++ ");\n"
411− bcc xs
412−bcc ((TOPBASE n):xs) = do
413− i <- get
414− tell $ indent (level i) ++ "TOPBASE(" ++ show n ++ ");\n"
326+bcc i (TOPBASE n) = indent i ++ "TOPBASE(" ++ show n ++ ");\n"
415− bcc xs
416−bcc ((BASETOP n):xs) = do
417− i <- get
418− tell $ indent (level i) ++ "BASETOP(" ++ show n ++ ");\n"
327+bcc i (BASETOP n) = indent i ++ "BASETOP(" ++ show n ++ ");\n"
419− bcc xs
420−bcc (STOREOLD:xs) = do
421− i <- get
422− tell $ indent (level i) ++ "STOREOLD;\n"
328+bcc i STOREOLD = indent i ++ "STOREOLD;\n"
423− bcc xs
424−bcc ((OP l fn args):xs) = do
425− i <- get
426− tell $ indent (level i) ++ doOp (creg l ++ " = ") fn args ++ ";\n"
329+bcc i (OP l fn args) = indent i ++ doOp (creg l ++ " = ") fn args ++ ";\n"
427− bcc xs
428−bcc ((FOREIGNCALL l rty (FStr fn@('&':name)) []):xs) = do
330+bcc i (FOREIGNCALL l rty (FStr fn@('&':name)) [])
429− i <- get
331+ = indent i ++
430− tell $ indent (level i) ++ c_irts (toFType rty) (creg l ++ " = ") fn ++ ";\n"
332+ c_irts (toFType rty) (creg l ++ " = ") fn ++ ";\n"
431− bcc xs
432−bcc ((FOREIGNCALL l rty (FStr fn) (x:xs)):zs) | fn == "%wrapper"
333+bcc i (FOREIGNCALL l rty (FStr fn) (x:xs)) | fn == "%wrapper"
433− = do
334+ = indent i ++
434− i <- get
435− tell $ indent (level i) ++ c_irts (toFType rty) (creg l ++ " = ")
335+ c_irts (toFType rty) (creg l ++ " = ")
436 ("_idris_get_wrapper(" ++ creg (snd x) ++ ")") ++ ";\n"
336 ("_idris_get_wrapper(" ++ creg (snd x) ++ ")") ++ ";\n"
437− bcc zs
438−bcc ((FOREIGNCALL l rty (FStr fn) (x:xs)):zs) | fn == "%dynamic"
337+bcc i (FOREIGNCALL l rty (FStr fn) (x:xs)) | fn == "%dynamic"
439− = do
440− i <- get
441− tell $ indent (level i) ++ c_irts (toFType rty) (creg l ++ " = ")
338+ = indent i ++ c_irts (toFType rty) (creg l ++ " = ")
442 ("(*(" ++ cFnSig "" rty xs ++ ") GETPTR(" ++ creg (snd x) ++ "))" ++
339 ("(*(" ++ cFnSig "" rty xs ++ ") GETPTR(" ++ creg (snd x) ++ "))" ++
443 "(" ++ showSep "," (map fcall xs) ++ ")") ++ ";\n"
340 "(" ++ showSep "," (map fcall xs) ++ ")") ++ ";\n"
444− bcc zs
445−bcc ((FOREIGNCALL l rty (FStr fn) args):xs) = do
341+bcc i (FOREIGNCALL l rty (FStr fn) args)
446− i <- get
342+ = indent i ++
447− tell $ indent (level i) ++ c_irts (toFType rty) (creg l ++ " = ")
343+ c_irts (toFType rty) (creg l ++ " = ")
448− (fn ++ "(" ++ showSep "," (map fcall args) ++ ")") ++ ";\n"
344+ (fn ++ "(" ++ showSep "," (map fcall args) ++ ")") ++ ";\n"
449− bcc xs
450−bcc ((FOREIGNCALL l rty _ args):_) = error "Foreign Function calls cannot be partially applied, without being inlined."
345+bcc i (FOREIGNCALL l rty _ args) = error "Foreign Function calls cannot be partially applied, without being inlined."
451−bcc ((NULL r):xs) = do
452− i <- get
453− tell $ indent (level i) ++ creg r ++ " = NULL;\n" -- clear, so it'll be GCed
346+bcc i (NULL r) = indent i ++ creg r ++ " = NULL;\n" -- clear, so it'll be GCed
454− bcc xs
455−bcc ((ERROR str):xs) = do
456− i <- get
457− tell $ indent (level i) ++ "fprintf(stderr, "
458− ++ show str ++ "); fprintf(stderr, \"\\n\"); exit(-1);\n"
347+bcc i (ERROR str) = indent i ++ "fprintf(stderr, " ++ show str ++ "); fprintf(stderr, \"\\n\"); exit(-1);\n"
459− bcc xs
460-- bcc i c = error (show c) -- indent i ++ "// not done yet\n"
348-- bcc i c = error (show c) -- indent i ++ "// not done yet\n"
461
349
462−getBC code xs = do
463− i <- get
464− let (a, s, w) = runRWS (bcc code) 0 (i { level = level i + 1 })
465− return w
466−
467fcall (t, arg) = irts_c (toFType t) (creg arg)
350fcall (t, arg) = irts_c (toFType t) (creg arg)
468-- Deconstruct the Foreign type in the defunctionalised expression and build
351-- Deconstruct the Foreign type in the defunctionalised expression and build
469-- a foreign type description for c_irts and irts_c
352-- a foreign type description for c_irts and irts_c
src/IRTS/Compiler.hs+2
@@ -63,6 +63,8 @@ compile codegen f mtm = do
63 Nothing -> []
63 Nothing -> []
64 Just t -> freeNames t
64 Just t -> freeNames t
65
65
66+ logCodeGen 1 "Running Erasure Analysis"
67+ iReport 3 "Running Erasure Analysis"
66 reachableNames <- performUsageAnalysis
68 reachableNames <- performUsageAnalysis
67 (rootNames ++ getExpNames exports)
69 (rootNames ++ getExpNames exports)
68 maindef <- case mtm of
70 maindef <- case mtm of
src/Idris/Core/Binary.hs+4−2
@@ -16,6 +16,8 @@ import Control.Applicative ((<$>), (<*>))
16import Control.DeepSeq (($!!))
16import Control.DeepSeq (($!!))
17import Control.Monad (liftM2)
17import Control.Monad (liftM2)
18import Data.Binary
18import Data.Binary
19+import Data.Binary.Get
20+import Data.Binary.Put
19import qualified Data.Text as T
21import qualified Data.Text as T
20import qualified Data.Text.Encoding as E
22import qualified Data.Text.Encoding as E
21import Data.Vector.Binary
23import Data.Vector.Binary
@@ -400,7 +402,7 @@ instance Binary Const where
400 BI x1 -> do putWord8 1
402 BI x1 -> do putWord8 1
401 put x1
403 put x1
402 Fl x1 -> do putWord8 2
404 Fl x1 -> do putWord8 2
403− put x1
405+ putDoublele x1
404 Ch x1 -> do putWord8 3
406 Ch x1 -> do putWord8 3
405 put x1
407 put x1
406 Str x1 -> do putWord8 4
408 Str x1 -> do putWord8 4
@@ -427,7 +429,7 @@ instance Binary Const where
427 return (I x1)
429 return (I x1)
428 1 -> do x1 <- get
430 1 -> do x1 <- get
429 return (BI x1)
431 return (BI x1)
430− 2 -> do x1 <- get
432+ 2 -> do x1 <- getDoublele
431 return (Fl x1)
433 return (Fl x1)
432 3 -> do x1 <- get
434 3 -> do x1 <- get
433 return (Ch x1)
435 return (Ch x1)
src/Idris/DeepSeq.hs−14
@@ -29,20 +29,6 @@ import Control.DeepSeq
29import Network.Socket (PortNumber)
29import Network.Socket (PortNumber)
30
30
31-- These types don't have Generic instances
31-- These types don't have Generic instances
32−instance NFData CT.Options where
33− rnf (CT.Options x1 x2 x3 x4) = rnf x1 `seq` rnf x2 `seq` rnf x3 `seq` rnf x4 `seq` ()
34−
35−instance NFData CT.ListType where
36− rnf (CT.Bullet c) = rnf c `seq` ()
37− rnf (CT.Numbered nw i) = rnf nw `seq` rnf i `seq` ()
38−
39−instance NFData CT.CodeAttr where
40− rnf (CT.CodeAttr a b) = rnf a `seq` rnf b `seq` ()
41−
42−instance NFData CT.NumWrapper where
43− rnf CT.PeriodFollowing = ()
44− rnf CT.ParenFollowing = ()
45−
46instance NFData DynamicLib where
32instance NFData DynamicLib where
47 rnf (Lib x _) = rnf x `seq` ()
33 rnf (Lib x _) = rnf x `seq` ()
48
34
src/Idris/IBC.hs+1−1
@@ -48,7 +48,7 @@ import System.Directory
48import System.FilePath
48import System.FilePath
49
49
50ibcVersion :: Word16
50ibcVersion :: Word16
51−ibcVersion = 161
51+ibcVersion = 162
52
52
53-- | When IBC is being loaded - we'll load different things (and omit
53-- | When IBC is being loaded - we'll load different things (and omit
54-- different structures/definitions) depending on which phase we're in.
54-- different structures/definitions) depending on which phase we're in.