@@ -18,6 +18,7 @@ import Idris.UnusedArgs
1818import Idris.Docs
1919import Idris.Help
2020import Idris.Completion
21+import Idris.IdeSlave
2122
2223import Paths_idris
2324import Util.System
@@ -80,6 +81,104 @@ repl orig mods
8081 ctrlC e = do lift $ iputStrLn (show e)
8182 repl orig mods
8283
84+-- | Run the IdeSlave
85+ideslaveStart :: IState -> [FilePath] -> Idris ()
86+ideslaveStart orig mods
87+ = do i <- getIState
88+ case idris_outputmode i of
89+ IdeSlave n ->
90+ when (mods /= []) (do liftIO $ putStrLn $ convSExp "set-prompt" (mkPrompt mods) n)
91+ ideslave orig mods
92+
93+
94+ideslave :: IState -> [FilePath] -> Idris ()
95+ideslave orig mods
96+ = do idrisCatch
97+ (do l <- liftIO $ getLine
98+ let (sexp, id) = parseMessage l
99+ i <- getIState
100+ putIState $ i { idris_outputmode = (IdeSlave id) }
101+ case sexpToCommand sexp of
102+ Just (Interpret cmd) ->
103+ do let fn = case mods of
104+ (f:_) -> f
105+ _ -> ""
106+ case parseCmd i cmd of
107+ Left err -> iFail $ show err
108+ Right cmd -> idrisCatch
109+ (do ideslaveProcess fn cmd)
110+ (\e -> do iFail $ show e)
111+ Just (REPLCompletions str) ->
112+ do (unused, compls) <- replCompletion (reverse str, "")
113+ let good = List [SymbolAtom "ok", toSExp (map replacement compls, reverse unused)]
114+ liftIO $ putStrLn $ convSExp "return" good id
115+ Just (LoadFile filename) ->
116+ do clearErr
117+ putIState (orig { idris_options = idris_options i,
118+ idris_outputmode = (IdeSlave id) })
119+ loadModule filename
120+ iucheck
121+ liftIO $ putStrLn $ convSExp "set-prompt" (mkPrompt [filename]) id
122+ -- report success! or failure!
123+ ideslave orig [filename]
124+ Nothing -> do iFail "did not understand")
125+ (\e -> do iFail $ show e)
126+ ideslave orig mods
127+
128+ideslaveProcess :: FilePath -> Command -> Idris ()
129+ideslaveProcess fn Help = process fn Help
130+ideslaveProcess fn (ChangeDirectory f) = do process fn (ChangeDirectory f)
131+ iResult "changed directory to"
132+ideslaveProcess fn (Eval t) = process fn (Eval t)
133+ideslaveProcess fn (ExecVal t) = process fn (ExecVal t)
134+ideslaveProcess fn (Check (PRef x n)) = process fn (Check (PRef x n))
135+ideslaveProcess fn (Check t) = process fn (Check t)
136+ideslaveProcess fn (DocStr n) = process fn (DocStr n)
137+ideslaveProcess fn Universes = process fn Universes
138+ideslaveProcess fn (Defn n) = do process fn (Defn n)
139+ iResult ""
140+ideslaveProcess fn (TotCheck n) = process fn (TotCheck n)
141+ideslaveProcess fn (DebugInfo n) = do process fn (DebugInfo n)
142+ iResult ""
143+ideslaveProcess fn (Info n) = process fn (Info n)
144+ideslaveProcess fn (Search t) = process fn (Search t)
145+ideslaveProcess fn (Spec t) = process fn (Spec t)
146+-- RmProof and AddProof not supported!
147+ideslaveProcess fn (ShowProof n') = process fn (ShowProof n')
148+ideslaveProcess fn (Prove n') = process fn (Prove n')
149+ideslaveProcess fn (HNF t) = process fn (HNF t)
150+--ideslaveProcess fn TTShell = process fn TTShell -- need some prove mode!
151+
152+--that most likely does not work, since we need to wrap
153+--input/output of the executed binary...
154+ideslaveProcess fn Execute = do process fn Execute
155+ iResult ""
156+ideslaveProcess fn (NewCompile f) = do process fn (NewCompile f)
157+ iResult ""
158+ideslaveProcess fn (Compile target f) = do process fn (Compile target f)
159+ iResult ""
160+ideslaveProcess fn (LogLvl i) = do process fn (LogLvl i)
161+ iResult ""
162+ideslaveProcess fn (Pattelab t) = process fn (Pattelab t)
163+ideslaveProcess fn (Missing n) = process fn (Missing n)
164+ideslaveProcess fn (DynamicLink l) = do process fn (DynamicLink l)
165+ iResult ""
166+ideslaveProcess fn ListDynamic = do process fn ListDynamic
167+ iResult ""
168+ideslaveProcess fn Metavars = process fn Metavars
169+ideslaveProcess fn (SetOpt ErrContext) = do process fn (SetOpt ErrContext)
170+ iResult ""
171+ideslaveProcess fn (UnsetOpt ErrContext) = do process fn (UnsetOpt ErrContext)
172+ iResult ""
173+ideslaveProcess fn (SetOpt ShowImpl) = do process fn (SetOpt ShowImpl)
174+ iResult ""
175+ideslaveProcess fn (UnsetOpt ShowImpl) = do process fn (UnsetOpt ShowImpl)
176+ iResult ""
177+ideslaveProcess fn (SetOpt x) = process fn (SetOpt x)
178+ideslaveProcess fn (UnsetOpt x) = process fn (UnsetOpt x)
179+ideslaveProcess fn _ = iFail "command not recognized or not supported"
180+
181+
83182-- | The prompt consists of the currently loaded modules, or "Idris" if there are none
84183mkPrompt [] = "Idris"
85184mkPrompt [x] = "*" ++ dropExtension x
@@ -173,25 +272,25 @@ proofs orig
173272
174273insertScript :: String -> [String] -> [String]
175274insertScript prf [] = "\n---------- Proofs ----------" : "" : [prf]
176−insertScript prf (p@"---------- Proofs ----------" : "" : xs)
275+insertScript prf (p@"---------- Proofs ----------" : "" : xs)
177276 = p : "" : prf : xs
178277insertScript prf (x : xs) = x : insertScript prf xs
179278
180279process :: FilePath -> Command -> Idris ()
181−process fn Help = iputStrLn displayHelp
280+process fn Help = iResult displayHelp
182281process fn (ChangeDirectory f)
183282 = do liftIO $ setCurrentDirectory f
184283 return ()
185−process fn (Eval t)
284+process fn (Eval t)
186285 = do (tm, ty) <- elabVal toplevel False t
187286 ctxt <- getContext
188− ist <- getIState
287+ ist <- getIState
189288 let tm' = normaliseAll ctxt [] tm
190289 let ty' = normaliseAll ctxt [] ty
191290 logLvl 3 $ "Raw: " ++ show (tm', ty')
192291 imp <- impShow
193− iputStrLn (showImp imp (delab ist tm') ++ " : " ++
194− showImp imp (delab ist ty'))
292+ iResult (showImp imp (delab ist tm') ++ " : " ++
293+ showImp imp (delab ist ty'))
195294process fn (ExecVal t)
196295 = do ctxt <- getContext
197296 ist <- getIState
@@ -200,30 +299,31 @@ process fn (ExecVal t)
200299 let ty' = normaliseAll ctxt [] ty
201300 res <- execute tm
202301 imp <- impShow
203− iputStrLn (showImp imp (delab ist res) ++ " : " ++
204− showImp imp (delab ist ty'))
205− return ()
302+ iResult (showImp imp (delab ist res) ++ " : " ++
303+ showImp imp (delab ist ty'))
206304process fn (Check (PRef _ n))
207305 = do ctxt <- getContext
208306 ist <- getIState
209307 imp <- impShow
210308 case lookupNames n ctxt of
211− ts@(_:_) -> mapM_ (\n -> iputStrLn $ show n ++ " : " ++
212− showImp imp (delabTy ist n)) ts
213− [] -> iputStrLn $ "No such variable " ++ show n
309+ ts@(_:_) -> do mapM_ (\n -> iputStrLn $ show n ++ " : " ++
310+ showImp imp (delabTy ist n)) ts
311+ iResult ""
312+ [] -> iFail $ "No such variable " ++ show n
214313process fn (Check t) = do (tm, ty) <- elabVal toplevel False t
215314 ctxt <- getContext
216− ist <- getIState
315+ ist <- getIState
217316 imp <- impShow
218317 let ty' = normaliseC ctxt [] ty
219− iputStrLn (showImp imp (delab ist tm) ++ " : " ++
220− showImp imp (delab ist ty))
318+ iResult (showImp imp (delab ist tm) ++ " : " ++
319+ showImp imp (delab ist ty))
221320
222321process fn (DocStr n) = do i <- getIState
223322 case lookupCtxtName n (idris_docstrings i) of
224− [] -> iputStrLn $ "No documentation for " ++ show n
225− ns -> mapM_ showDoc ns
226− where showDoc (n, d)
323+ [] -> iFail $ "No documentation for " ++ show n
324+ ns -> do mapM_ showDoc ns
325+ iResult ""
326+ where showDoc (n, d)
227327 = do doc <- getDocs n
228328 iputStrLn $ show doc
229329process fn Universes = do i <- getIState
@@ -233,8 +333,8 @@ process fn Universes = do i <- getIState
233333 let n = length cs
234334 iputStrLn $ "(" ++ show n ++ " constraints)"
235335 case ucheck cs of
236− Error e -> iputStrLn $ pshow i e
237− OK _ -> iputStrLn "Universes OK"
336+ Error e -> iFail $ pshow i e
337+ OK _ -> iResult "Universes OK"
238338process fn (Defn n) = do i <- getIState
239339 iputStrLn "Compiled patterns:\n"
240340 liftIO $ print (lookupDef n (tt_ctxt i))
@@ -245,15 +345,15 @@ process fn (Defn n) = do i <- getIState
245345 case lookupTotal n (tt_ctxt i) of
246346 [t] -> iputStrLn (showTotal t i)
247347 _ -> return ()
248− where printCase i (_, lhs, rhs)
249− = do liftIO $ putStr $ showImp True (delab i lhs)
250− liftIO $ putStr " = "
251− liftIO $ putStrLn $ showImp True (delab i rhs)
348+ where printCase i (_, lhs, rhs)
349+ = do iputStrLn (showImp True (delab i lhs) ++ " = " ++
350+ showImp True (delab i rhs))
252351process fn (TotCheck n) = do i <- getIState
253352 case lookupTotal n (tt_ctxt i) of
254− [t] -> iputStrLn (showTotal t i)
255− _ -> return ()
256−process fn (DebugInfo n)
353+ [t] -> iResult (showTotal t i)
354+ _ -> do iFail ""
355+ return ()
356+process fn (DebugInfo n)
257357 = do i <- getIState
258358 let oi = lookupCtxtName n (idris_optimisation i)
259359 when (not (null oi)) $ iputStrLn (show oi)
@@ -275,13 +375,13 @@ process fn (DebugInfo n)
275375process fn (Info n) = do i <- getIState
276376 case lookupCtxt n (idris_classes i) of
277377 [c] -> classInfo c
278− _ -> iputStrLn "Not a class"
279−process fn (Search t) = iputStrLn "Not implemented"
378+ _ -> iFail "Not a class"
379+process fn (Search t) = iFail "Not implemented"
280380process fn (Spec t) = do (tm, ty) <- elabVal toplevel False t
281381 ctxt <- getContext
282382 ist <- getIState
283383 let tm' = simplify ctxt True [] {- (idris_statics ist) -} tm
284− iputStrLn (show (delab ist tm'))
384+ iResult (show (delab ist tm'))
285385
286386process fn (RmProof n')
287387 = do i <- getIState
@@ -333,8 +433,8 @@ process fn (ShowProof n')
333433 n <- resolveProof n'
334434 let proofs = proof_list i
335435 case lookup n proofs of
336− Nothing -> iputStrLn "No proof to show"
337− Just p -> iputStrLn $ showProof False n p
436+ Nothing -> iFail "No proof to show"
437+ Just p -> iResult $ showProof False n p
338438
339439process fn (Prove n')
340440 = do ctxt <- getContext
@@ -354,13 +454,13 @@ process fn (HNF t) = do (tm, ty) <- elabVal toplevel False t
354454 ctxt <- getContext
355455 ist <- getIState
356456 let tm' = hnf ctxt [] tm
357− iputStrLn (show (delab ist tm'))
457+ iResult (show (delab ist tm'))
358458process fn TTShell = do ist <- getIState
359459 let shst = initState (tt_ctxt ist)
360460 runShell shst
361461 return ()
362−process fn Execute = do (m, _) <- elabVal toplevel False
363− (PApp fc
462+process fn Execute = do (m, _) <- elabVal toplevel False
463+ (PApp fc
364464 (PRef fc (UN "run__IO"))
365465 [pexp $ PRef fc (NS (UN "main") ["Main"])])
366466-- (PRef (FC "main" 0) (NS (UN "main") ["main"]))
@@ -370,37 +470,37 @@ process fn Execute = do (m, _) <- elabVal toplevel False
370470 compile t tmpn m
371471 liftIO $ system tmpn
372472 return ()
373− where fc = FC "main" 0
374−process fn (NewCompile f)
473+ where fc = FC "main" 0
474+process fn (NewCompile f)
375475 = do (m, _) <- elabVal toplevel False
376476 (PApp fc (PRef fc (UN "run__IO"))
377477 [pexp $ PRef fc (NS (UN "main") ["Main"])])
378478 compileEpic f m
379− where fc = FC "main" 0
380−process fn (Compile target f)
479+ where fc = FC "main" 0
480+process fn (Compile target f)
381481 = do (m, _) <- elabVal toplevel False
382482 (PApp fc (PRef fc (UN "run__IO"))
383483 [pexp $ PRef fc (NS (UN "main") ["Main"])])
384484 compile target f m
385− where fc = FC "main" 0
386−process fn (LogLvl i) = setLogLevel i
485+ where fc = FC "main" 0
486+process fn (LogLvl i) = setLogLevel i
387487-- Elaborate as if LHS of a pattern (debug command)
388−process fn (Pattelab t)
488+process fn (Pattelab t)
389489 = do (tm, ty) <- elabVal toplevel True t
390− iputStrLn $ show tm ++ "\n\n : " ++ show ty
490+ iResult $ show tm ++ "\n\n : " ++ show ty
391491
392−process fn (Missing n)
492+process fn (Missing n)
393493 = do i <- getIState
394494 case lookupCtxt n (idris_patdefs i) of
395495 [] -> return ()
396− [(_, tms)] ->
397− iputStrLn (showSep "\n" (map (showImp True) tms))
398− _ -> iputStrLn $ "Ambiguous name"
496+ [(_, tms)] ->
497+ iResult (showSep "\n" (map (showImp True) tms))
498+ _ -> iFail $ "Ambiguous name"
399499process fn (DynamicLink l) = do i <- getIState
400500 let lib = trim l
401501 handle <- lift $ tryLoadLib lib
402502 case handle of
403− Nothing -> iputStrLn $ "Could not load dynamic lib \"" ++ l ++ "\""
503+ Nothing -> iFail $ "Could not load dynamic lib \"" ++ l ++ "\""
404504 Just x -> do let libs = idris_dynamic_libs i
405505 putIState $ i { idris_dynamic_libs = x:libs }
406506 where trim = reverse . dropWhile isSpace . reverse . dropWhile isSpace
@@ -413,8 +513,8 @@ process fn Metavars
413513 = do ist <- getIState
414514 let mvs = idris_metavars ist \\ primDefs
415515 case mvs of
416− [] -> iputStrLn "No global metavariables to solve"
417− _ -> iputStrLn $ "Global metavariables:\n\t" ++ show mvs
516+ [] -> iFail "No global metavariables to solve"
517+ _ -> iResult $ "Global metavariables:\n\t" ++ show mvs
418518process fn NOP = return ()
419519
420520process fn (SetOpt ErrContext) = setErrContext True
@@ -422,8 +522,8 @@ process fn (UnsetOpt ErrContext) = setErrContext False
422522process fn (SetOpt ShowImpl) = setImpShow True
423523process fn (UnsetOpt ShowImpl) = setImpShow False
424524
425−process fn (SetOpt _) = iputStrLn "Not a valid option"
426−process fn (UnsetOpt _) = iputStrLn "Not a valid option"
525+process fn (SetOpt _) = iFail "Not a valid option"
526+process fn (UnsetOpt _) = iFail "Not a valid option"
427527
428528
429529classInfo :: ClassInfo -> Idris ()
@@ -432,6 +532,7 @@ classInfo ci = do iputStrLn "Methods:\n"
432532 iputStrLn ""
433533 iputStrLn "Instances:\n"
434534 mapM_ dumpInstance (class_instances ci)
535+ iResult ""
435536
436537dumpMethod :: (Name, (FnOpts, PTerm)) -> Idris ()
437538dumpMethod (n, (_, t)) = iputStrLn $ show n ++ " : " ++ show t
@@ -471,6 +572,7 @@ parseTarget _ = error "unknown target" -- FIXME: partial function
471572parseArgs :: [String] -> [Opt]
472573parseArgs [] = []
473574parseArgs ("--quiet":ns) = Quiet : (parseArgs ns)
575+parseArgs ("--ideslave":ns) = Ideslave : (parseArgs ns)
474576parseArgs ("--log":lvl:ns) = OLogging (read lvl) : (parseArgs ns)
475577parseArgs ("--noprelude":ns) = NoPrelude : (parseArgs ns)
476578parseArgs ("--check":ns) = NoREPL : (parseArgs ns)
@@ -524,6 +626,7 @@ idrisMain :: [Opt] -> Idris ()
524626idrisMain opts =
525627 do let inputs = opt getFile opts
526628 let quiet = Quiet `elem` opts
629+ let idesl = Ideslave `elem` opts
527630 let runrepl = not (NoREPL `elem` opts)
528631 let output = opt getOutput opts
529632 let newoutput = opt getNewOutput opts
@@ -543,6 +646,7 @@ idrisMain opts =
543646 mapM_ addLangExt (opt getLanguageExt opts)
544647 setREPL runrepl
545648 setQuiet quiet
649+ setIdeSlave idesl
546650 setVerbose runrepl
547651 setCmdLine opts
548652 setOutputTy outty
@@ -567,7 +671,7 @@ idrisMain opts =
567671 elabPrims
568672 when (not (NoPrelude `elem` opts)) $ do x <- loadModule "Prelude"
569673 return ()
570− when (runrepl && not quiet) $ iputStrLn banner
674+ when (runrepl && not quiet && not idesl) $ iputStrLn banner
571675 ist <- getIState
572676 mods <- mapM loadModule inputs
573677 ok <- noErrors
@@ -577,7 +681,8 @@ idrisMain opts =
577681 when ok $ case newoutput of
578682 [] -> return ()
579683 (o:_) -> process "" (NewCompile o)
580− when runrepl $ runInputT replSettings $ repl ist inputs
684+ when (runrepl && not idesl) $ runInputT replSettings $ repl ist inputs
685+ when (idesl) $ ideslaveStart ist inputs
581686 ok <- noErrors
582687 when (not ok) $ liftIO (exitWith (ExitFailure 1))
583688 where