summaryrefslogtreecommitdiffstats
path: root/elab.sml
diff options
context:
space:
mode:
authorRose Hogenson <rosehogenson@posteo.net>2024-04-07 09:11:28 -0700
committerRose Hogenson <rosehogenson@posteo.net>2024-04-07 09:11:28 -0700
commit278ee46f0fa93a3db4ebdc6878fcd9b1d990094a (patch)
tree85cd7b4703cacea8111ea05766089ca73aac9abb /elab.sml
parentbc2fef3a2ab81270af207568706647ced919bbe6 (diff)
downloadsml-278ee46f0fa93a3db4ebdc6878fcd9b1d990094a.tar.zst
Add tests and fix variables.
Diffstat (limited to 'elab.sml')
-rw-r--r--elab.sml21
1 files changed, 13 insertions, 8 deletions
diff --git a/elab.sml b/elab.sml
index 032d1d7..52d0089 100644
--- a/elab.sml
+++ b/elab.sml
@@ -27,21 +27,26 @@ struct
| Syntax.ETyped (e, _) => elab env e
| Syntax.EAndAlso (_, _) => raise Fail "unimplemented"
| Syntax.EOrElse (_, _) => raise Fail "unimplemented"
- | Syntax.ELet (decls, body) =>
- foldr
- (fn (Syntax.DVal v, acc) =>
- Syntax.LApp (Syntax.LFn (Gensym.new (), acc), elab env v))
- (elab env body)
- decls
- | Syntax.ELambda (var, body) =>
+ | Syntax.ELet ([], body) => elab env body
+ | Syntax.ELet (Syntax.DVal (pat, v) :: decls, body) =>
+ elab env (Syntax.ECase (v, [(pat, Syntax.ELet (decls, body))]))
+ | Syntax.ELambda (pat, body) =>
let
val v = Gensym.new ()
val env' =
- case var of
+ case pat of
Syntax.PWild => env
| Syntax.PVar name => StringMap.insert name v env
in Syntax.LFn (v, elab env' body)
end
+ | Syntax.ECase (expr, []) => raise Fail "nonexhaustive match"
+ | Syntax.ECase (expr, (pat, body) :: rest) =>
+ if rest <> [] then raise Fail "redundant match" else
+ let val v = Gensym.new () in
+ case pat of
+ Syntax.PWild => Syntax.LApp (Syntax.LFn (v, elab env body), elab env expr)
+ | Syntax.PVar name => Syntax.LApp (Syntax.LFn (v, elab (StringMap.insert name v env) body), elab env expr)
+ end
fun elaborate (p : Syntax.expr) : Syntax.lexp = elab StringMap.empty p
end