let prelude = import! std.prelude
let { Expr } = import! "examples/lisp/types.glu"
let char = import! std.char
let { List } = import! std.list
let { Result } = import! std.result
let string = import! std.string
let float = import! std.float
let int = import! std.int
let {
Parser,
fail,
between,
lazy_parser,
many,
one_of,
satisfy,
spaces,
token,
recognize,
take1,
skip_many,
skip_many1,
?
} =
import! std.parser
let { (<>) } = import! std.prelude
let { Applicative, (<*), (*>), map2, wrap } = import! std.applicative
let { map } = import! std.functor
let { (<|>) } = import! std.alternative
let { flat_map } = import! std.monad
let atom : Parser Expr =
let symbol = one_of "!#$%&|*+-/:<=>?@^_~"
let alpha = satisfy char.is_alphabetic
let alpha_num = satisfy char.is_alphanumeric
map (\x -> Atom x) (recognize ((alpha <|> symbol) *> skip_many (alpha_num <|> symbol)))
let parse_parser p f msg : Parser a -> (String -> Result () b) -> String -> Parser b =
do s = recognize p
match f s with
| Ok i -> wrap i
| Err _ -> fail ("Expected " <> msg)
let int_parser : Parser Expr =
map
(\i -> Int i)
(parse_parser (skip_many1 (satisfy char.is_numeric)) int.parse "integer")
let float_parser : Parser Expr =
let number = skip_many1 (satisfy char.is_numeric)
map (\f -> Float f) (parse_parser (number *> token '.' *> number) float.parse "float")
rec
let list _ : () -> Parser Expr =
let e = expr ()
between (token '(') (token ')') (spaces *> map (\x -> List x) (many e))
let expr _ : () -> Parser Expr = (atom <|> float_parser <|> int_parser <|> lazy_parser list) <* spaces
in
{
expr = spaces *> lazy_parser expr,
}