gluon 0.18.2

A static, type inferred programming language for application embedding
Documentation
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,
}