aboutsummaryrefslogtreecommitdiff
path: root/discocaml/eval.ml
diff options
context:
space:
mode:
authorNathan Ringo <nathan@remexre.com>2024-01-19 19:37:08 -0600
committerNathan Ringo <nathan@remexre.com>2024-01-19 19:37:08 -0600
commita84e462b596c24d2562d766ceb019761085390c5 (patch)
tree51a87e24426a5ad9d94bab104e21d3d3ecbbb9f1 /discocaml/eval.ml
parent401bc1c5485e26329598d59a140e51f70f58857c (diff)
Use GADTs for prims, actual redex finding.
Diffstat (limited to 'discocaml/eval.ml')
-rw-r--r--discocaml/eval.ml44
1 files changed, 41 insertions, 3 deletions
diff --git a/discocaml/eval.ml b/discocaml/eval.ml
index 816d269..9c12003 100644
--- a/discocaml/eval.ml
+++ b/discocaml/eval.ml
@@ -1,5 +1,43 @@
open Ast
-let find_redex_cbv : expr ast -> expr index option = function _ -> None
-let find_redex_cbn : expr ast -> expr index option = function _ -> None
-let reduce : expr ast -> expr index -> expr ast = fun e _ -> e
+let or_else (type a) (l : a option) (r : a option Lazy.t) : a option =
+ match l with Some x -> Some x | None -> Lazy.force r
+
+let is_redex (ast : expr ast) (i : expr index) : bool =
+ match get_subexpr ast i with
+ | App (f, _) -> (
+ match get_subexpr ast f with Lam (_, _) -> true | _ -> false)
+ | Int _ -> false
+ | Lam (_, _) -> false
+ | Prim (Add, (l, r)) | Prim (Sub, (l, r)) | Prim (Mul, (l, r)) -> (
+ match (get_subexpr ast l, get_subexpr ast r) with
+ | Int _, Int _ -> true
+ | _ -> false)
+ | Var _ -> false
+
+let find_redex_cbv_in (_ast : expr ast) (_i : expr index) : expr index option =
+ None
+
+let find_redex_cbn_in (ast : expr ast) : expr index -> expr index option =
+ let rec loop (i : expr index) : expr index option =
+ if is_redex ast i then Some i
+ else
+ match get_subexpr ast i with
+ | App (f, x) -> or_else (loop f) (lazy (loop x))
+ | Int _ -> None
+ | Lam (_, _) -> None
+ | Prim (Add, (l, r)) | Prim (Sub, (l, r)) | Prim (Mul, (l, r)) ->
+ or_else (loop l) (lazy (loop r))
+ | Var _ -> None
+ in
+ loop
+
+let find_redex_cbv (ast : expr ast) : expr index option =
+ find_redex_cbv_in ast ast.root
+
+let find_redex_cbn (ast : expr ast) : expr index option =
+ find_redex_cbn_in ast ast.root
+
+let reduce (ast : expr ast) (_i : expr index) : expr ast =
+ let ast = copy ast in
+ ast