on master help sign in
initial ideslave
commite0783ef097215a8de0fb90359ddbebd4927675a5 authorHannes Mehnert <hannes@mehnert.org> dateSun 7 Apr 2013, 16:36 (14 years ago) parent56bd9a1
5 files changed+146−4
idris.cabal+1−1 src/Idris/AbsSyntax.hs+6 src/Idris/AbsSyntaxTree.hs+3−1 src/Idris/IdeSlave.hs+119 src/Idris/REPL.hs+17−2
idris.cabal+1−1
@@ -90,7 +90,7 @@ Executable idris
9090 Core.CaseTree, Core.Constraints,
9191
9292 Idris.AbsSyntax, Idris.AbsSyntaxTree,
93− Idris.Parser, Idris.Help, Idris.REPL,
93+ Idris.Parser, Idris.Help, Idris.IdeSlave, Idris.REPL,
9494 Idris.REPLParser, Idris.ElabDecls, Idris.Error,
9595 Idris.Delaborate, Idris.Primitives, Idris.Imports,
9696 Idris.Compiler, Idris.Prover, Idris.ElabTerm,
src/Idris/AbsSyntax.hs+6
@@ -299,6 +299,12 @@ setQuiet q = do i <- getIState
299299 let opt' = opts { opt_quiet = q }
300300 putIState $ i { idris_options = opt' }
301301
302+setIdeSlave :: Bool -> Idris ()
303+setIdeSlave s = do i <- getIState
304+ let opts = idris_options i
305+ let opt' = opts { opt_ideslave = s }
306+ putIState $ i { idris_options = opt' }
307+
302308setTarget :: Target -> Idris ()
303309setTarget t = do i <- getIState
304310 let opts = idris_options i
src/Idris/AbsSyntaxTree.hs+3−1
@@ -33,6 +33,7 @@ data IOption = IOption { opt_logLevel :: Int,
3333 opt_repl :: Bool,
3434 opt_verbose :: Bool,
3535 opt_quiet :: Bool,
36+ opt_ideslave :: Bool,
3637 opt_target :: Target,
3738 opt_outputTy :: OutputType,
3839 opt_ibcsubdir :: FilePath,
@@ -41,7 +42,7 @@ data IOption = IOption { opt_logLevel :: Int,
4142 }
4243 deriving (Show, Eq)
4344
44−defaultOpts = IOption 0 False False True False False True True False ViaC Executable "" [] []
45+defaultOpts = IOption 0 False False True False False True True False False ViaC Executable "" [] []
4546
4647data LanguageExt = TypeProviders deriving (Show, Eq, Read, Ord)
4748
@@ -202,6 +203,7 @@ data Opt = Filename String
202203 | Ver
203204 | Usage
204205 | Quiet
206+ | IdeSlave
205207 | ShowLibs
206208 | ShowLibdir
207209 | ShowIncs
src/Idris/IdeSlave.hsnew file+119
@@ -0,0 +1,119 @@
1+{-# LANGUAGE FlexibleInstances, IncoherentInstances #-}
2+
3+module Idris.IdeSlave(receiveMessage, sendMessage) where
4+
5+import Text.Printf
6+import Numeric
7+import Data.List
8+
9+import Text.Parsec
10+
11+data SExp = List [SExp]
12+ | StringAtom String
13+ | BoolAtom Bool
14+ | IntegerAtom Integer
15+ | SymbolAtom String
16+ deriving ( Eq, Show )
17+
18+sExpToString :: SExp -> String
19+sExpToString (StringAtom s) = "\"" ++ escape s ++ "\""
20+sExpToString (BoolAtom True) = ":True"
21+sExpToString (BoolAtom False) = ":False"
22+sExpToString (IntegerAtom i) = printf "%d" i
23+sExpToString (SymbolAtom s) = ":" ++ s
24+sExpToString (List l) = "(" ++ intercalate " " (map sExpToString l) ++ ")"
25+
26+class SExpable a where
27+ toSExp :: a -> SExp
28+
29+instance SExpable Bool where
30+ toSExp True = BoolAtom True
31+ toSExp False = BoolAtom False
32+
33+instance SExpable String where
34+ toSExp s = StringAtom s
35+
36+instance SExpable Integer where
37+ toSExp n = IntegerAtom n
38+
39+instance SExpable Int where
40+ toSExp n = IntegerAtom (toInteger n)
41+
42+instance (SExpable a) => SExpable (Maybe a) where
43+ toSExp Nothing = List [SymbolAtom "Nothing"]
44+ toSExp (Just a) = List ((SymbolAtom "Just") : [toSExp a])
45+
46+instance (SExpable a) => SExpable [a] where
47+ toSExp l = List (map toSExp l)
48+
49+escape :: String -> String
50+escape = concatMap escapeChar
51+ where
52+ escapeChar '\\' = "\\\\"
53+ escapeChar '"' = "\\\""
54+ escapeChar c = [c]
55+
56+pSExp = do xs <- between (char '(') (char ')') (pSExp `sepBy` (char ' '))
57+ return (List xs)
58+ <|> atom
59+
60+atom = do char ':'; x <- atomC; return x
61+ <|> do char '"'; xs <- many quotedChar; char '"'; return (StringAtom xs)
62+ <|> do ints <- many1 digit
63+ case readDec ints of
64+ ((num, ""):_) -> return (IntegerAtom (toInteger num))
65+ _ -> return (StringAtom ints)
66+
67+atomC = do string "True"; return (BoolAtom True)
68+ <|> do string "False"; return (BoolAtom False)
69+ <|> do xs <- many (noneOf " \n\"()"); return (SymbolAtom xs)
70+
71+quotedChar = noneOf "\""
72+ <|> try (string "\\\"" >> return '"')
73+
74+parseSExp :: String -> Either ParseError SExp
75+parseSExp input = parse pSExp "(unknown)" input
76+
77+data Command = Version
78+ deriving Show
79+
80+sexpToCommand :: SExp -> Maybe Command
81+sexpToCommand (List (x:[])) = sexpToCommand x
82+sexpToCommand (SymbolAtom "version") = Just Version
83+sexpToCommand _ = Nothing
84+
85+receiveMessage :: IO (Maybe Command)
86+receiveMessage
87+ = do x <- getLine
88+ return (receiveString x)
89+
90+receiveString :: String -> Maybe Command
91+receiveString x =
92+ case readHex (take 6 x) of
93+ ((num, ""):_) ->
94+ let msg = drop 6 x in
95+ if (length msg) /= (num - 1)
96+ then error "bad input"
97+ else parseSExpToCommand msg
98+ _ -> error "blah"
99+
100+parseSExpToCommand :: String -> Maybe Command
101+parseSExpToCommand msg =
102+ case parseSExp msg of
103+ Left _ -> Nothing
104+ Right r -> sexpToCommand r
105+
106+sendMessage :: SExpable a => a -> IO ()
107+sendMessage s =
108+ do let str = convertToSExpString s
109+ putStrLn $ (getHexLength str) ++ str
110+
111+convertToSExpString :: SExpable a => a -> String
112+convertToSExpString s =
113+ let str = sExpToString (toSExp s) in
114+ if (str !! 0) == '('
115+ then str
116+ else "(" ++ str ++ ")"
117+
118+getHexLength :: String -> String
119+getHexLength s = printf "%06x" (1 + (length s))
src/Idris/REPL.hs+17−2
@@ -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,16 @@ repl orig mods
8081 ctrlC e = do lift $ iputStrLn (show e)
8182 repl orig mods
8283
84+-- | Run the IdeSlave
85+ideslave :: IState -> [FilePath] -> InputT Idris ()
86+ideslave orig mods
87+ = do x <- liftIO $ receiveMessage
88+ case x of
89+ Nothing -> do liftIO $ sendMessage (Just "did not understand")
90+ Just y -> do liftIO $ sendMessage (Just "understood you!")
91+ liftIO $ sendMessage (Just "Hello world")
92+ ideslave orig mods
93+
8394-- | The prompt consists of the currently loaded modules, or "Idris" if there are none
8495mkPrompt [] = "Idris"
8596mkPrompt [x] = "*" ++ dropExtension x
@@ -471,6 +482,7 @@ parseTarget _ = error "unknown target" -- FIXME: partial function
471482parseArgs :: [String] -> [Opt]
472483parseArgs [] = []
473484parseArgs ("--quiet":ns) = Quiet : (parseArgs ns)
485+parseArgs ("--ideslave":ns) = IdeSlave : (parseArgs ns)
474486parseArgs ("--log":lvl:ns) = OLogging (read lvl) : (parseArgs ns)
475487parseArgs ("--noprelude":ns) = NoPrelude : (parseArgs ns)
476488parseArgs ("--check":ns) = NoREPL : (parseArgs ns)
@@ -524,6 +536,7 @@ idrisMain :: [Opt] -> Idris ()
524536idrisMain opts =
525537 do let inputs = opt getFile opts
526538 let quiet = Quiet `elem` opts
539+ let idesl = IdeSlave `elem` opts
527540 let runrepl = not (NoREPL `elem` opts)
528541 let output = opt getOutput opts
529542 let newoutput = opt getNewOutput opts
@@ -543,6 +556,7 @@ idrisMain opts =
543556 mapM_ addLangExt (opt getLanguageExt opts)
544557 setREPL runrepl
545558 setQuiet quiet
559+ setIdeSlave idesl
546560 setVerbose runrepl
547561 setCmdLine opts
548562 setOutputTy outty
@@ -567,7 +581,7 @@ idrisMain opts =
567581 elabPrims
568582 when (not (NoPrelude `elem` opts)) $ do x <- loadModule "Prelude"
569583 return ()
570− when (runrepl && not quiet) $ iputStrLn banner
584+ when (runrepl && not quiet && not idesl) $ iputStrLn banner
571585 ist <- getIState
572586 mods <- mapM loadModule inputs
573587 ok <- noErrors
@@ -577,7 +591,8 @@ idrisMain opts =
577591 when ok $ case newoutput of
578592 [] -> return ()
579593 (o:_) -> process "" (NewCompile o)
580− when runrepl $ runInputT replSettings $ repl ist inputs
594+ when (runrepl && not idesl) $ runInputT replSettings $ repl ist inputs
595+ when (idesl) $ runInputT replSettings $ ideslave ist inputs
581596 ok <- noErrors
582597 when (not ok) $ liftIO (exitWith (ExitFailure 1))
583598 where