|
|
- include import "./lang.ml"
- include import "./lexer.ml"
- open import "prelude.ml"
-
- let parse = lex
-
- let laid_out_block p = between obrace cbrace (sep_end_by_1 semi p)
-
- let rec atom : forall 'm. monad 'm => parser_t 'm expr =
- map Ref (try varid)
- <|> map Ref (try conid)
- <|> map Lit (try integer)
- <+> between (try oparen) cparen expr
- and fexp : forall 'm. monad 'm => parser_t 'm expr =
- let! a = atom
- let! ats = many atom
- pure (foldl (curry App) a ats)
- and expr : forall 'm. monad 'm => parser_t 'm expr =
- let lam =
- let! _ = back
- let! vs = many (try varid)
- let! _ = arrow
- let! b = expr
- pure (foldr ((Lam #) # curry id) b vs)
- let case =
- let! _ = keyword "case"
- let! e = fexp
- let! _ = keyword "of"
- let! arms =
- laid_out_block (
- let! c = conid
- let! vs = many (try varid)
- let! _ = arrow
- let! e = expr
- pure (c, vs, e)
- )
- pure (Case (e, arms))
- let hslet =
- let binding =
- let! c = varid
- let! vs = many (try varid)
- let! _ = equals
- let! e = expr
- pure (c, foldr ((Lam #) # curry id) e vs)
- let! _ = keyword "let"
- let! bs = laid_out_block binding
- let! _ = keyword "in"
- let! b = expr
- pure (Let (bs, b))
- try lam <|> try case <|> try hslet <+> fexp
-
- let rec ty_atom : forall 'm. monad 'm => parser_t 'm hstype =
- map Tyvar (try varid)
- <|> map Tycon (try conid)
- <+> between (try oparen) cparen ty_tup
- and ty_fexp : forall 'm. monad 'm => parser_t 'm hstype =
- let! a = ty_atom
- let! ats = many ty_atom
- pure (foldl (curry Tyapp) a ats)
- and ty_exp : forall 'm. monad 'm => parser_t 'm hstype =
- chainr1 ty_fexp (map (const (curry Tyarr)) arrow)
- and ty_tup : forall 'm. monad 'm => parser_t 'm hstype =
- let tytup = function
- | [x] -> x
- | x -> Tytup x
- tytup <$> sep_by comma ty_exp
-
- let datadec : forall 'm. monad 'm => parser_t 'm decl =
- let! _ = try (keyword "data")
- let datacon =
- let! nm = conid
- let! args = many ty_atom
- pure (Constr (nm, args))
- let! nm = conid
- let! args = many (try varid)
- let! cs = optionally (
- let! _ = equals
- sep_by_1 pipe (try datacon)
- )
- pure (Data (nm, args, match cs with | Some cs -> cs | None -> []))
-
- let fdecl : forall 'm. monad 'm => parser_t 'm fdecl =
- let! _ = try (keyword "import")
- let! cc =
- ( (Lua <$ try (keyword "lua"))
- <|> (Prim <$ try (keyword "prim"))
- )
- let! fent = string
- let! var = varid
- let! _ = dcolon
- let! ftype = ty_exp
- pure (Fimport { cc, fent, var, ftype })
-
- let func : forall 'm. monad 'm => parser_t 'm decl =
- let! nm = varid
- let! args = many (try varid)
- let! _ = equals
- map (fun e -> Decl (nm, args, e)) expr
-
- let dec : forall 'm. monad 'm => parser_t 'm decl =
- let foreign =
- let! _ = try (keyword "foreign")
- map Foreign fdecl
- try datadec <|> try foreign <|> func
-
- let prog : forall 'm. monad 'm => parser_t 'm prog =
- sep_end_by_1 semi dec <* eof
|