Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Do not merge yet] A test about untyped lambda calculus. Regression demo (stack overflow) #230

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion dune-project
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
(lang dune 1.8)
(lang dune 2.7)

(cram enable)

(name angstrom)
62 changes: 62 additions & 0 deletions lib_test/ULC.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@

open Angstrom

module Lam = struct
type t = Var of char | App of t * t | Abs of char * t
[@@deriving show { with_path = false }]

let var x = Var x
let abs x l = Abs (x, l)
let app l r = App (l, r)

let rec pp ppf =
let open Format in
function
| Var c -> fprintf ppf "%c" c
| App (l, r) ->
fprintf ppf "(%a %a)" pp l pp r
| Abs (x, b) -> fprintf ppf "(\\%c . %a)" x pp b

end

let is_space = function ' ' | '\t' -> true | _ -> false
let spaces = skip_while is_space
let varname = satisfy (function 'a' .. 'z' -> true | _ -> false)

let conde = function
| [] -> fail "empty conde"
| h :: tl -> List.fold_left ( <|> ) h tl

type dispatch = {
apps : dispatch -> Lam.t Angstrom.t;
single : dispatch -> Lam.t Angstrom.t;
}

let parse_lam =
let single pack =
fix (fun _ ->
conde
[
char '(' *> pack.apps pack <* char ')';
( (string "λ" <|> string "\\") *> spaces *> varname
<* spaces <* char '.'
>>= fun var ->
pack.apps pack >>= fun b -> return (Lam.Abs (var, b)) );
(varname <* spaces >>= fun c -> return (Lam.Var c));
])
in
let apps pack =
many1 (spaces *> pack.single pack <* spaces) >>= function
| [] -> fail "bad syntax"
| x :: xs -> return @@ List.fold_left (fun l r -> Lam.App (l, r)) x xs
in
{ single; apps }

let parse_optimistically str =
Result.get_ok
@@ Angstrom.parse_string (parse_lam.apps parse_lam) str
~consume:Angstrom.Consume.All

let _ =
Format.printf "%a%!\n" Lam.pp (parse_optimistically "a a ");

2 changes: 2 additions & 0 deletions lib_test/ULC.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
$ ./ULC.exe
(a a)
17 changes: 13 additions & 4 deletions lib_test/dune
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
(preprocess
(per_module
(future_syntax test_let_syntax_native)
((pps ppx_let) test_let_syntax_ppx))))
((pps ppx_let)
test_let_syntax_ppx))))

(executables
(libraries alcotest angstrom angstrom_test)
Expand All @@ -18,10 +19,18 @@
(modules test_json)
(names test_json))

(alias
(name runtest)
(executables
(libraries angstrom)
(modules ULC)
(names ULC))

(rule
(alias runtest)
(package angstrom)
(deps
(:< test_angstrom.exe))
(action
(run %{<})))
(run %{<})))

(cram
(deps ./ULC.exe ./test_angstrom.exe))