1{-# LANGUAGE FlexibleInstances, IncoherentInstances #-}
3module Idris.IdeSlave(parseMessage, convSExp, IdeSlaveCommand(..), sexpToCommand, toSExp, SExp(..), SExpable) where
8-- import qualified Data.Text as T
13data SExp = SexpList [SExp]
20sExpToString :: SExp -> String
21sExpToString (StringAtom s) = "\"" ++ escape s ++ "\""
22sExpToString (BoolAtom True) = ":True"
23sExpToString (BoolAtom False) = ":False"
24sExpToString (IntegerAtom i) = printf "%d" i
25sExpToString (SymbolAtom s) = ":" ++ s
26sExpToString (SexpList l) = "(" ++ intercalate " " (map sExpToString l) ++ ")"
31instance SExpable SExp where
34instance SExpable Bool where
35 toSExp True = BoolAtom True
36 toSExp False = BoolAtom False
38instance SExpable String where
39 toSExp s = StringAtom s
41instance SExpable Integer where
42 toSExp n = IntegerAtom n
44instance SExpable Int where
45 toSExp n = IntegerAtom (toInteger n)
48instance SExpable Name where
49 toSExp s = StringAtom (show s)
52instance (SExpable a) => SExpable (Maybe a) where
53 toSExp Nothing = SexpList [SymbolAtom "Nothing"]
54 toSExp (Just a) = SexpList [SymbolAtom "Just", toSExp a]
56instance (SExpable a) => SExpable [a] where
57 toSExp l = SexpList (map toSExp l)
59instance (SExpable a, SExpable b) => SExpable (a, b) where
60 toSExp (l, r) = SexpList [toSExp l, toSExp r]
62instance (SExpable a, SExpable b, SExpable c) => SExpable (a, b, c) where
63 toSExp (l, m, n) = SexpList [toSExp l, toSExp m, toSExp n]
65escape :: String -> String
66escape = concatMap escapeChar
68 escapeChar '\\' = "\\\\"
69 escapeChar '"' = "\\\""
72pSExp = do xs <- between (char '(') (char ')') (pSExp `sepBy` (char ' '))
76atom = do char ':'; x <- atomC; return x
77 <|> do char '"'; xs <- many quotedChar; char '"'; return (StringAtom xs)
78 <|> do ints <- many1 digit
80 ((num, ""):_) -> return (IntegerAtom (toInteger num))
81 _ -> return (StringAtom ints)
83atomC = do string "True"; return (BoolAtom True)
84 <|> do string "False"; return (BoolAtom False)
85 <|> do xs <- many (noneOf " \n\t\r\"()"); return (SymbolAtom xs)
87quotedChar = try (string "\\\\" >> return '\\')
88 <|> try (string "\\\"" >> return '"')
91parseSExp :: String -> Either ParseError SExp
92parseSExp = parse pSExp "(unknown)"
94data IdeSlaveCommand = REPLCompletions String
99sexpToCommand :: SExp -> Maybe IdeSlaveCommand
100sexpToCommand (SexpList (x:[])) = sexpToCommand x
101sexpToCommand (SexpList [SymbolAtom "interpret", StringAtom cmd]) = Just (Interpret cmd)
102sexpToCommand (SexpList [SymbolAtom "repl-completions", StringAtom prefix]) = Just (REPLCompletions prefix)
103sexpToCommand (SexpList [SymbolAtom "load-file", StringAtom filename]) = Just (LoadFile filename)
104sexpToCommand _ = Nothing
106parseMessage :: String -> (SExp, Integer)
107parseMessage x = case receiveString x of
108 (SexpList [cmd, (IntegerAtom id)]) ->
111receiveString :: String -> SExp
113 case readHex (take 6 x) of
115 let msg = drop 6 x in
116 if (length msg) /= (num - 1)
117 then error "bad input length"
118 else (case parseSExp msg of
119 Left _ -> error "parse failure"
121 _ -> error "readHex failed"
123convSExp :: SExpable a => String -> a -> Integer -> String
125 let sex = SexpList [SymbolAtom pre, toSExp s, IntegerAtom id] in
126 let str = sExpToString sex in
127 (getHexLength str) ++ str
129getHexLength :: String -> String
130getHexLength s = printf "%06x" (1 + (length s))
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list