on master help sign in
Merge branch 'master' into wip/tactical
commit3c5327f122effa567c56b18a826d7a37e6e533ee authorDavid Raymond Christiansen <david@davidchristiansen.dk> dateSat 25 Jul 2015, 13:49 (11 years ago) parentd54064f6b062be
19 files changed+291−37
docs/tutorial/interp.rst+9 docs/tutorial/typesfuns.rst+4 idris.cabal+1 jsrts/Runtime-common.js+15−12 src/IRTS/CodegenC.hs+1−1 src/IRTS/CodegenJavaScript.hs+7−6 src/IRTS/Compiler.hs+1−1 src/Idris/AbsSyntaxTree.hs+2−1 src/Idris/CmdOptions.hs+2−1 src/Idris/Core/Evaluate.hs+8−1 src/Idris/Core/TT.hs+1−1 src/Idris/Core/WHNF.hs+208 src/Idris/Delaborate.hs+1−1 src/Idris/Elab/Clause.hs+1−1 src/Idris/Elab/Type.hs+1−1 src/Idris/REPL.hs+10−3 src/Idris/REPLParser.hs+6−6 src/Util/System.hs+8−1 test/totality007/expected.msys+5
docs/tutorial/interp.rst+9
@@ -68,6 +68,15 @@ The full representation of expressions is:
6868 Lazy (Expr G a) ->
6969 Lazy (Expr G a) -> Expr G a
7070
71+The code above makes use of the ``Vect`` and ``Fin`` types from the
72+Idris standard library. We import them because they are not provided
73+in the prelude:
74+
75+.. code-block:: idris
76+
77+ import Data.Vect
78+ import Data.Fin
79+
7180Since expressions are indexed by their type, we can read the typing
7281rules of the language from the definitions of the constructors. Let us
7382look at each constructor in turn.
docs/tutorial/typesfuns.rst+4
@@ -105,6 +105,10 @@ symbols:
105105
106106 :+-*/=_.?|&><!@$%^~.
107107
108+Some operators built from these symbols can't be user defined. These are
109+``:``, ``=>``, ``->``, ``<-``, ``=``, ``?=``, ``|``, ``**``,
110+``==>``, ``\\``, ``%``, ``~``, ``?``, and ``!``.
111+
108112Functions
109113=========
110114
idris.cabal+1
@@ -785,6 +785,7 @@ Library
785785 , Idris.Core.TT
786786 , Idris.Core.Typecheck
787787 , Idris.Core.Unify
788+ , Idris.Core.WHNF
788789
789790 , Idris.Elab.Utils
790791 , Idris.Elab.Type
jsrts/Runtime-common.js+15−12
@@ -63,26 +63,29 @@ var i$CALL = function(fun,args) {
6363
6464var i$ffiWrap = function(fid,oldbase,myoldbase) {
6565 return function() {
66+ var oldstack = i$callstack;
6667 i$callstack = [];
6768
6869 var res = fid;
6970
7071 for(var i = 0; i < (arguments.length ? arguments.length : 1); ++i) {
71− i$valstack_top += 1;
72− i$valstack[i$valstack_top] = res;
73− i$valstack[i$valstack_top + 1] = arguments[i];
74− i$SLIDE(2);
75− i$valstack_top = i$valstack_base + 2;
76− i$CALL(_idris__123_APPLY0_125_,[oldbase])
77− while (i$callstack.length) {
78− var func = i$callstack.pop();
79− var args = i$callstack.pop();
80− func.apply(this,args);
72+ while (res instanceof i$CON) {
73+ i$valstack_top += 1;
74+ i$valstack[i$valstack_top] = res;
75+ i$valstack[i$valstack_top + 1] = arguments[i];
76+ i$SLIDE(2);
77+ i$valstack_top = i$valstack_base + 2;
78+ i$CALL(_idris__123_APPLY0_125_,[oldbase])
79+ while (i$callstack.length) {
80+ var func = i$callstack.pop();
81+ var args = i$callstack.pop();
82+ func.apply(this,args);
83+ }
84+ res = i$ret;
8185 }
82− res = i$ret;
8386 }
8487
85− i$callstack = i$vm.callstack;
88+ i$callstack = oldstack;
8689
8790 return i$ret;
8891 }
src/IRTS/CodegenC.hs+1−1
@@ -64,7 +64,7 @@ codegenC' defs out exec incs objs libs flags exports iface dbg
6464 (if (exec == Executable) then mprog else hi)
6565 case exec of
6666 MavenProject -> putStrLn ("FAILURE: output type not supported")
67− Raw -> writeFile out cout
67+ Raw -> writeSource out cout
6868 _ -> do
6969 (tmpn, tmph) <- tempfile
7070 hPutStr tmph cout
src/IRTS/CodegenJavaScript.hs+7−6
@@ -132,12 +132,12 @@ codegenJS_all target definitions includes libs filename outputType = do
132132 ++ idrRuntime
133133 ++ tgtRuntime
134134 )
135− TIO.writeFile filename ( T.pack runtime
136− `T.append` T.concat (map compileJS opt)
137− `T.append` T.concat (map compileJS cons)
138− `T.append` main
139− `T.append` invokeMain
140− )
135+ writeSourceText filename ( T.pack runtime
136+ `T.append` T.concat (map compileJS opt)
137+ `T.append` T.concat (map compileJS cons)
138+ `T.append` main
139+ `T.append` invokeMain
140+ )
141141 setPermissions filename (emptyPermissions { readable = True
142142 , executable = target == Node
143143 , writable = True
@@ -1331,6 +1331,7 @@ translateBC info bc
13311331 | TAILCALL n <- bc = jsTAILCALL info n
13321332 | FOREIGNCALL r _ (FStr n) args
13331333 <- bc = jsFOREIGN info r n (map fcall args)
1334+ | FOREIGNCALL _ _ _ _ <- bc = error "JS FFI call not statically known"
13341335 | TOPBASE n <- bc = jsTOPBASE info n
13351336 | BASETOP n <- bc = jsBASETOP info n
13361337 | STOREOLD <- bc = jsSTOREOLD info
src/IRTS/Compiler.hs+1−1
@@ -136,7 +136,7 @@ generate codegen mainmod ir
136136 Via "c" -> codegenC ir
137137 -- Any external code generator
138138 Via cg -> do let cmd = "idris-" ++ cg
139− args = [mainmod, "-o", outputFile ir]
139+ args = [mainmod, "-o", outputFile ir] ++ compilerFlags ir
140140 exit <- rawSystem cmd args
141141 when (exit /= ExitSuccess) $
142142 putStrLn ("FAILURE: " ++ show cmd ++ " " ++ show args)
src/Idris/AbsSyntaxTree.hs+2−1
@@ -387,7 +387,7 @@ data Command = Quit
387387 | Universes
388388 | LogLvl Int
389389 | Spec PTerm
390− | HNF PTerm
390+ | WHNF PTerm
391391 | TestInline PTerm
392392 | Defn Name
393393 | Missing Name
@@ -472,6 +472,7 @@ data Opt = Filename String
472472 | DumpDefun String
473473 | DumpCases String
474474 | UseCodegen Codegen
475+ | CodegenArgs String
475476 | OutputTy OutputType
476477 | Extension LanguageExt
477478 | InterpretScript String
src/Idris/CmdOptions.hs+2−1
@@ -126,7 +126,8 @@ parseFlags = many $
126126 <|> flag' (OutputTy MavenProject) (long "mvn" <> help "Create a maven project (for Java codegen)")
127127 <|> (DumpDefun <$> strOption (long "dumpdefuns"))
128128 <|> (DumpCases <$> strOption (long "dumpcases"))
129− <|> ((\s -> UseCodegen $ parseCodegen s) <$> strOption (long "codegen" <> metavar "TARGET" <> help "Select code generator: C, Java, bytecode"))
129+ <|> ((\s -> UseCodegen $ parseCodegen s) <$> strOption (long "codegen" <> metavar "TARGET" <> help "Select code generator: C, Javascript, Node and bytecode are bundled with Idris"))
130+ <|> (CodegenArgs <$> strOption (long "cg-opt" <> metavar "ARG" <> help "Arguments to pass to code generator"))
130131 <|> (EvalExpr <$> strOption (long "eval" <> short 'e' <> metavar "EXPR" <> help "Evaluate an expression without loading the REPL"))
131132 <|> flag' (InterpretScript "Main.main") (long "execute" <> help "Execute as idris")
132133 <|> (InterpretScript <$> strOption (long "exec" <> metavar "EXPR" <> help "Execute as idris"))
src/Idris/Core/Evaluate.hs+8−1
@@ -2,7 +2,7 @@
22 PatternGuards #-}
33{-# OPTIONS_GHC -fwarn-incomplete-patterns #-}
44
5−module Idris.Core.Evaluate(normalise, normaliseTrace, normaliseC, normaliseAll,
5+module Idris.Core.Evaluate(normalise, normaliseTrace, normaliseC, normaliseAll, toValue, quoteTerm,
66 rt_simplify, simplify, specialise, hnf, convEq, convEq',
77 Def(..), CaseInfo(..), CaseDefs(..),
88 Accessibility(..), Totality(..), PReason(..), MetaInformation(..),
@@ -92,6 +92,13 @@ normaliseTrace tr ctxt env t
9292 = evalState (do val <- eval tr ctxt [] (map finalEntry env) (finalise t) []
9393 quote 0 val) initEval
9494
95+toValue :: Context -> Env -> TT Name -> Value
96+toValue ctxt env t
97+ = evalState (eval False ctxt [] (map finalEntry env) t []) initEval
98+
99+quoteTerm :: Value -> TT Name
100+quoteTerm val = evalState (quote 0 val) initEval
101+
95102-- Return a specialised name, and an updated list of reductions available,
96103-- so that the caller can tell how much specialisation was achieved.
97104specialise :: Context -> Env -> [(Name, Int)] -> TT Name ->
src/Idris/Core/TT.hs+1−1
@@ -41,7 +41,7 @@ module Idris.Core.TT(AppStatus(..), ArithTy(..), Binder(..), Const(..), Ctxt(..)
4141 sInstanceN, sMN, sNS, spanFC, str, subst, substNames, substTerm,
4242 substV, sUN, tcname, termSmallerThan, tfail, thead, tnull,
4343 toAlist, traceWhen, txt, unApply, uniqueBinders, uniqueName,
44− uniqueNameFrom, uniqueNameSet, unList, updateDef, vToP) where
44+ uniqueNameFrom, uniqueNameSet, unList, updateDef, vToP, weakenTm) where
4545
4646-- Work around AMP without CPP
4747import Prelude (Eq(..), Show(..), Ord(..), Functor(..), Monad(..), String, Int,
src/Idris/Core/WHNF.hsnew file+208
@@ -0,0 +1,208 @@
1+{-# LANGUAGE PatternGuards #-}
2+{-# OPTIONS_GHC -fwarn-incomplete-patterns #-}
3+
4+-- Reduction to Weak Head Normal Form
5+module Idris.Core.WHNF(whnf, WEnv) where
6+
7+import Idris.Core.TT
8+import Idris.Core.CaseTree
9+import Idris.Core.Evaluate hiding (quote)
10+import qualified Idris.Core.Evaluate as Evaluate
11+
12+import Debug.Trace
13+
14+-- A stack entry consists of a term and the environment it is to be
15+-- evaluated in (i.e. it's a thunk)
16+type StackEntry = (Term, WEnv)
17+data WEnv = WEnv Int -- number of free variables
18+ [(Term, WEnv)]
19+ deriving Show
20+
21+type Stack = [StackEntry]
22+
23+-- A WHNF is a top level term evaluated in the empty environment. It is
24+-- always headed by either an irreducible expression, i.e. a constructor,
25+-- a lambda, a constant, or a postulate
26+
27+-- Every 'Term' or 'Type' in this structure is associated with the
28+-- environment it was encountered in, so that when we quote back to a term
29+-- we get the substitutions right.
30+
31+data WHNF = WDCon Int Int Bool Name (Type, WEnv) -- data constructor
32+ | WTCon Int Int Name (Type, WEnv) -- type constructor
33+ | WPRef Name (Type, WEnv) -- irreducible global (e.g. a postulate)
34+ | WBind Name (Binder Term) (Term, WEnv)
35+ | WApp WHNF (Term, WEnv)
36+ | WConstant Const
37+ | WProj WHNF Int
38+ | WType UExp
39+ | WUType Universe
40+ | WErased
41+ | WImpossible
42+
43+-- Reduce a *closed* term to weak head normal form.
44+whnf :: Context -> Term -> Term
45+whnf ctxt tm = quote (do_whnf ctxt (WEnv 0 []) tm)
46+
47+do_whnf :: Context -> WEnv -> Term -> WHNF
48+do_whnf ctxt env tm = eval env [] tm
49+ where
50+ eval :: WEnv -> Stack -> Term -> WHNF
51+ eval wenv@(WEnv d env) stk (V i)
52+ | i < length env = let (tm, env') = env !! i in
53+ eval env' stk tm
54+ | otherwise = error "Can't happen: WHNF scope error"
55+ eval wenv@(WEnv d env) stk (Bind n (Let t v) sc)
56+ = eval (WEnv d ((v, wenv) : env)) stk sc
57+ eval (WEnv d env) [] (Bind n b sc) = WBind n b (sc, WEnv (d + 1) env)
58+ eval (WEnv d env) ((tm, tenv) : stk) (Bind n b sc)
59+ = eval (WEnv d ((tm, tenv) : env)) stk sc
60+
61+ eval env stk (P nt n ty) = apply env nt n ty stk
62+ eval env stk (App _ f a) = eval env ((a, env) : stk) f
63+ eval env stk (Constant c) = unload (WConstant c) stk
64+
65+ -- Should never happen in compile time code (for now...)
66+ eval env stk (Proj tm i) = unload (WProj (eval env [] tm) i) stk
67+
68+ eval env stk Erased = unload WErased stk
69+ eval env stk Impossible = unload WImpossible stk
70+ eval env stk (TType u) = unload (WType u) stk
71+ eval env stk (UType u) = unload (WUType u) stk
72+
73+ apply :: WEnv -> NameType -> Name -> Type -> Stack -> WHNF
74+ apply env nt n ty stk
75+ = let wp = case nt of
76+ DCon t a u -> WDCon t a u n (ty, env)
77+ TCon t a -> WTCon t a n (ty, env)
78+ _ -> WPRef n (ty, env)
79+ in
80+ case lookupDefExact n ctxt of
81+ Just (CaseOp ci _ _ _ _ cd) ->
82+ let (ns, tree) = cases_compiletime cd in
83+ case evalCase env ns tree stk of
84+ Just w -> w
85+ Nothing -> unload wp stk
86+ Just (Operator _ i op) ->
87+ if i <= length stk
88+ then case runOp env op (take i stk) (drop i stk) of
89+ Just v -> v
90+ Nothing -> unload wp stk
91+ else unload wp stk
92+ _ -> unload wp stk
93+
94+ unload :: WHNF -> Stack -> WHNF
95+ unload f [] = f
96+ unload f (a : as) = unload (WApp f a) as
97+
98+ runOp :: WEnv -> ([Value] -> Maybe Value) -> Stack -> Stack -> Maybe WHNF
99+ runOp env op stk rest
100+ = do vals <- mapM tmtoValue stk
101+ case op vals of
102+ Just (VConstant c) -> Just $ unload (WConstant c) rest
103+ -- Operators run on values, so we have to convert back
104+ -- and forth. This is pretty ugly, but operators that
105+ -- aren't run on constants are themselves pretty ugly
106+ -- (it's prim__believe_me and prim__syntacticEq, for
107+ -- example) so let's not worry too much...
108+ Just val -> Just $ eval env rest (quoteTerm val)
109+ _ -> Nothing
110+
111+ tmtoValue :: (Term, WEnv) -> Maybe Value
112+ tmtoValue (tm, tenv)
113+ = case eval tenv [] tm of
114+ WConstant c -> Just (VConstant c)
115+ _ -> let tm' = quoteEnv tenv tm in
116+ Just (toValue ctxt [] tm')
117+
118+ evalCase :: WEnv -> [Name] -> SC -> Stack -> Maybe WHNF
119+ evalCase wenv@(WEnv d env) ns tree args
120+ | length ns > length args = Nothing
121+ | otherwise = let args' = take (length ns) args
122+ rest = drop (length ns) args in
123+ do (tm, amap) <- evalTree wenv (zip ns args') tree
124+ let wtm = pToVs (map fst amap) tm
125+ Just $ eval (WEnv d (map snd amap)) rest wtm
126+
127+ evalTree :: WEnv -> [(Name, (Term, WEnv))] -> SC ->
128+ Maybe (Term, [(Name, (Term, WEnv))])
129+ evalTree env amap (STerm tm) = Just (tm, amap)
130+ evalTree env amap (Case _ n alts)
131+ = case lookup n amap of
132+ Just (tm, tenv) -> findAlt env amap
133+ (deconstruct (eval tenv [] tm) []) alts
134+ _ -> Nothing
135+ evalTree _ _ _ = Nothing
136+
137+ deconstruct :: WHNF -> Stack -> (WHNF, Stack)
138+ deconstruct (WApp f arg) stk = deconstruct f (arg : stk)
139+ deconstruct t stk = (t, stk)
140+
141+ findAlt :: WEnv -> [(Name, (Term, WEnv))] -> (WHNF, Stack) ->
142+ [CaseAlt] ->
143+ Maybe (Term, [(Name, (Term, WEnv))])
144+ findAlt env amap (WDCon tag _ _ _ _, args) alts
145+ | Just (ns, sc) <- findTag tag alts
146+ = let amap' = updateAmap (zip ns args) amap in
147+ evalTree env amap' sc
148+ | Just sc <- findDefault alts
149+ = evalTree env amap sc
150+ findAlt env amap (WConstant c, []) alts
151+ | Just sc <- findConst c alts
152+ = evalTree env amap sc
153+ | Just sc <- findDefault alts
154+ = evalTree env amap sc
155+ findAlt _ _ _ _ = Nothing
156+
157+ findTag :: Int -> [CaseAlt] -> Maybe ([Name], SC)
158+ findTag i [] = Nothing
159+ findTag i (ConCase n j ns sc : xs) | i == j = Just (ns, sc)
160+ findTag i (_ : xs) = findTag i xs
161+
162+ findDefault :: [CaseAlt] -> Maybe SC
163+ findDefault [] = Nothing
164+ findDefault (DefaultCase sc : xs) = Just sc
165+ findDefault (_ : xs) = findDefault xs
166+
167+ findConst c [] = Nothing
168+ findConst c (ConstCase c' v : xs) | c == c' = Just v
169+ findConst (AType (ATInt ITNative)) (ConCase n 1 [] v : xs) = Just v
170+ findConst (AType ATFloat) (ConCase n 2 [] v : xs) = Just v
171+ findConst (AType (ATInt ITChar)) (ConCase n 3 [] v : xs) = Just v
172+ findConst StrType (ConCase n 4 [] v : xs) = Just v
173+ findConst (AType (ATInt ITBig)) (ConCase n 6 [] v : xs) = Just v
174+ findConst (AType (ATInt (ITFixed ity))) (ConCase n tag [] v : xs)
175+ | tag == 7 + fromEnum ity = Just v
176+ findConst c (_ : xs) = findConst c xs
177+
178+ updateAmap newm amap
179+ = newm ++ filter (\ (x, _) -> not (elem x (map fst newm))) amap
180+
181+quote :: WHNF -> Term
182+quote (WDCon t a u n (ty, env)) = P (DCon t a u) n (quoteEnv env ty)
183+quote (WTCon t a n (ty, env)) = P (TCon t a) n (quoteEnv env ty)
184+quote (WPRef n (ty, env)) = P Ref n (quoteEnv env ty)
185+quote (WBind n ty (sc, env)) = Bind n ty (quoteEnv env sc)
186+quote (WApp f (a, env)) = App Complete (quote f) (quoteEnv env a)
187+quote (WConstant c) = Constant c
188+quote (WProj t i) = Proj (quote t) i
189+quote (WType u) = TType u
190+quote (WUType u) = UType u
191+quote WErased = Erased
192+quote WImpossible = Impossible
193+
194+quoteEnv :: WEnv -> Term -> Term
195+quoteEnv (WEnv d ws) tm = qe' d ws tm
196+ where
197+ qe' d ts (V i)
198+ | i < d = V i
199+ | otherwise = let (tm, env) = ts !! (i - d) in
200+ quoteEnv env tm
201+ qe' d ts (Bind n b sc)
202+ = Bind n (fmap (qe' d ts) b) (qe' (d + 1) ts sc)
203+ qe' d ts (App c f a)
204+ = App c (qe' d ts f) (qe' d ts a)
205+ qe' d ts (P nt n ty) = P nt n (qe' d ts ty)
206+ qe' d ts (Proj tm i) = Proj (qe' d ts tm) i
207+ qe' d ts tm = tm
208+
src/Idris/Delaborate.hs+1−1
@@ -344,7 +344,7 @@ pprintErr' i (InvalidTCArg n t)
344344 text "(Type class arguments must be injective)"
345345pprintErr' i (CantResolveAlts as) = text "Can't disambiguate name:" <+>
346346 align (cat (punctuate (comma <> space) (map (fmap (fancifyAnnots i True) . annName) as)))
347−pprintErr' i (NoValidAlts as) = text "Can't disambiguate since no alternative is valid:" <+>
347+pprintErr' i (NoValidAlts as) = text "Can't disambiguate since no name has a suitable type:" <+>
348348 indented (align (cat (punctuate (comma <> space) (map (fmap (fancifyAnnots i True) . annName) as))))
349349pprintErr' i (NoTypeDecl n) = text "No type declaration for" <+> annName n
350350pprintErr' i (NoSuchVariable n) = text "No such variable" <+> annName n
src/Idris/Elab/Clause.hs+1−1
@@ -594,7 +594,7 @@ elabClause info opts (cnum, PClause fc fname lhs_in_as withs rhs_in_as wherebloc
594594 rep <- useREPL
595595 when rep $ do
596596 addInternalApp (fc_fname fc) (fst . fc_start $ fc) (delabMV i clhs) -- TODO: Should use span instead of line and filename?
597− addIBC (IBCLineApp (fc_fname fc) (fst . fc_start $ fc) (delabMV i clhs))
597+ addIBC (IBCLineApp (fc_fname fc) (fst . fc_start $ fc) (delabMV i clhs))
598598
599599 logLvl 5 ("Checked " ++ show clhs ++ "\n" ++ show clhsty)
600600 -- Elaborate where block
src/Idris/Elab/Type.hs+1−1
@@ -148,7 +148,7 @@ elabType' norm info syn doc argDocs fc opts n nfc ty' = {- let ty' = piBind (par
148148 rep <- useREPL
149149 when rep $ do
150150 addInternalApp (fc_fname fc) (fst . fc_start $ fc) ty' -- (mergeTy ty' (delab i nty')) -- TODO: Should use span instead of line and filename?
151− addIBC (IBCLineApp (fc_fname fc) (fst . fc_start $ fc) ty') -- (mergeTy ty' (delab i nty')))
151+ addIBC (IBCLineApp (fc_fname fc) (fst . fc_start $ fc) ty') -- (mergeTy ty' (delab i nty')))
152152
153153 let (fam, _) = unApply (getRetTy nty')
154154 let corec = case fam of
src/Idris/REPL.hs+10−3
@@ -54,6 +54,7 @@ import Idris.Core.Evaluate
5454import Idris.Core.Execute (execute)
5555import Idris.Core.TT
5656import Idris.Core.Unify
57+import Idris.Core.WHNF
5758import Idris.Core.Constraints
5859
5960import IRTS.Compiler
@@ -595,7 +596,7 @@ idemodeProcess fn (Search ps t) = process fn (Search ps t)
595596idemodeProcess fn (Spec t) = process fn (Spec t)
596597-- RmProof and AddProof not supported!
597598idemodeProcess fn (ShowProof n') = process fn (ShowProof n')
598−idemodeProcess fn (HNF t) = process fn (HNF t)
599+idemodeProcess fn (WHNF t) = process fn (WHNF t)
599600--idemodeProcess fn TTShell = process fn TTShell -- need some prove mode!
600601idemodeProcess fn (TestInline t) = process fn (TestInline t)
601602
@@ -1135,11 +1136,11 @@ process fn (Prove mode n')
11351136 mapM_ checkDeclTotality (idris_totcheck i)
11361137 warnTotality
11371138
1138−process fn (HNF t)
1139+process fn (WHNF t)
11391140 = do (tm, ty) <- elabVal recinfo ERHS t
11401141 ctxt <- getContext
11411142 ist <- getIState
1142− let tm' = hnf ctxt [] tm
1143+ let tm' = whnf ctxt tm
11431144 iPrintResult (show (delab ist tm'))
11441145process fn (TestInline t)
11451146 = do (tm, ty) <- elabVal recinfo ERHS t
@@ -1600,6 +1601,8 @@ idrisMain opts =
16001601 let cgn = case opt getCodegen opts of
16011602 [] -> Via "c"
16021603 xs -> last xs
1604+ let cgFlags = opt getCodegenArgs opts
1605+
16031606 -- Now set/unset specifically chosen optimisations
16041607 sequence_ (opt getOptimisation opts)
16051608 script <- case opt getExecScript opts of
@@ -1624,6 +1627,7 @@ idrisMain opts =
16241627 setOutputTy outty
16251628 setNoBanner nobanner
16261629 setCodegen cgn
1630+ mapM_ (addFlag cgn) cgFlags
16271631 mapM_ makeOption opts
16281632 -- if we have the --bytecode flag, drop into the bytecode assembler
16291633 case bcs of
@@ -1838,6 +1842,9 @@ getCodegen :: Opt -> Maybe Codegen
18381842getCodegen (UseCodegen x) = Just x
18391843getCodegen _ = Nothing
18401844
1845+getCodegenArgs :: Opt -> Maybe String
1846+getCodegenArgs (CodegenArgs args) = Just args
1847+getCodegenArgs _ = Nothing
18411848
18421849getConsoleWidth :: Opt -> Maybe ConsoleWidth
18431850getConsoleWidth (UseConsoleWidth x) = Just x
src/Idris/REPLParser.hs+6−6
@@ -111,7 +111,7 @@ parserCommands =
111111
112112 , exprArgCmd ["patt"] Pattelab "(Debugging) Elaborate pattern expression"
113113 , exprArgCmd ["spec"] Spec "?"
114− , exprArgCmd ["hnf"] HNF "?"
114+ , exprArgCmd ["whnf"] WHNF "(Debugging) Show weak head normal form of an expression"
115115 , exprArgCmd ["inline"] TestInline "?"
116116 , proofArgCmd ["cs", "casesplit"] CaseSplitAt
117117 ":cs <line> <name> splits the pattern variable on the line"
@@ -309,14 +309,14 @@ cmd_execute name = do
309309
310310cmd_dynamic :: String -> P.IdrisParser (Either String Command)
311311cmd_dynamic name = do
312− let emptyArgs = noArgs ListDynamic name
313−
314− let oneArg = do l <- many anyChar
315− return $ Right (DynamicLink l)
312+ let optArg = do l <- many anyChar
313+ if (l /= "")
314+ then return $ Right (DynamicLink l)
315+ else return $ Right ListDynamic
316316
317317 let failure = return $ Left $ "Usage is :" ++ name ++ " [<library>]"
318318
319− try emptyArgs <|> try oneArg <|> failure
319+ try optArg <|> failure
320320
321321cmd_pprint :: String -> P.IdrisParser (Either String Command)
322322cmd_pprint name = do
src/Util/System.hs+8−1
@@ -1,9 +1,12 @@
11{-# LANGUAGE CPP #-}
22module Util.System(tempfile,withTempdir,rmFile,catchIO, isWindows,
3− writeSource, readSource, setupBundledCC) where
3+ writeSource, writeSourceText, readSource,
4+ setupBundledCC) where
45
56-- System helper functions.
67import Control.Monad (when)
8+import qualified Data.Text as T
9+import qualified Data.Text.IO as TIO
710import System.Directory (getTemporaryDirectory
811 , removeFile
912 , removeDirectoryRecursive
@@ -44,6 +47,10 @@ readSource f = do h <- openFile f ReadMode
4447writeSource :: FilePath -> String -> IO ()
4548writeSource f s = withFile f WriteMode (\h -> hSetEncoding h utf8 >> hPutStr h s)
4649
50+-- | Write a utf-8 source file from Text
51+writeSourceText :: FilePath -> T.Text -> IO ()
52+writeSourceText f s = withFile f WriteMode (\h -> hSetEncoding h utf8 >> TIO.hPutStr h s)
53+
4754withTempdir :: String -> (FilePath -> IO a) -> IO a
4855withTempdir subdir callback
4956 = do dir <- getTemporaryDirectory
test/totality007/expected.msysnew file+5
@@ -0,0 +1,5 @@
1+Entering directory `.\src'
2+Totality.idr:4:1:
3+Totality.foo is not total as there are missing cases
4+Totality.idr:4:1:Could not build: Totality.foo is not total as there are missing cases
5+Leaving directory `.\src'