diff options
Diffstat (limited to 'elab.sml')
| -rw-r--r-- | elab.sml | 21 |
1 files changed, 13 insertions, 8 deletions
@@ -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 |
