-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathSexpr.idr
More file actions
44 lines (37 loc) · 1.22 KB
/
Sexpr.idr
File metadata and controls
44 lines (37 loc) · 1.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
module Sexpr
import Data.String
-- import Data.String.Parser
%default total
public export
data Sexpr = App (List Sexpr) | Atom String
isSpecial : Char -> Bool
isSpecial c = c == '(' || c == ')' || isSpace c
parseAtom : String -> Maybe (String, String)
parseAtom s with (strM s)
parseAtom "" | StrNil = Just ("", "")
parseAtom s@(strCons c str) | (StrCons c str) =
if isSpecial c
then Just ("", s)
else
let rst = parseAtom (assert_smaller s str) in
map (mapFst (strCons c)) rst
mutual
parseList : String -> Maybe (List Sexpr, String)
parseList i = (do (p, rs) <- parseSexpr i
(ps, rs) <- parseList (assert_smaller i rs)
pure (p :: ps, rs))
<|> Just ([], i)
parseSexpr : String -> Maybe (Sexpr, String)
parseSexpr s =
case strUncons s of
Nothing => Nothing
Just ('(', rst) =>
do (res, rst) <- parseList (assert_smaller s rst)
case strUncons rst of
Just (')', rst) => pure $ (App res, rst)
_ => Nothing
Just (')', rst) => Nothing
Just (c, str) =>
if isSpace c
then parseSexpr (assert_smaller s str)
else map (mapFst Atom) (parseAtom s)