From b6123d25d202d3cbe1f12d24dec129a90d5051ec Mon Sep 17 00:00:00 2001 From: Adam Chlipala Date: Sun, 3 Aug 2008 13:30:27 -0400 Subject: Optimizing 'case' in Mono_reduce --- src/mono_reduce.sml | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 2 deletions(-) (limited to 'src/mono_reduce.sml') diff --git a/src/mono_reduce.sml b/src/mono_reduce.sml index 9b9d8f6a..e780d6d8 100644 --- a/src/mono_reduce.sml +++ b/src/mono_reduce.sml @@ -63,14 +63,59 @@ val subExpInExp = fun bind (env, b) = case b of U.Decl.Datatype (x, n, xncs) => E.pushDatatype env x n xncs - | U.Decl.RelE (x, t) => E.pushERel env x t + | U.Decl.RelE (x, t) => E.pushERel env x t NONE | U.Decl.NamedE (x, n, t, eo, s) => E.pushENamed env x n t eo s fun typ c = c +fun match (env, p : pat, e : exp) = + case (#1 p, #1 e) of + (PWild, _) => SOME env + | (PVar (x, t), _) => SOME (E.pushERel env x t (SOME e)) + + | (PPrim p, EPrim p') => + if Prim.equal (p, p') then + SOME env + else + NONE + + | (PCon (PConVar n1, NONE), ECon (n2, NONE)) => + if n1 = n2 then + SOME env + else + NONE + + | (PCon (PConVar n1, SOME p), ECon (n2, SOME e)) => + if n1 = n2 then + match (env, p, e) + else + NONE + + | (PRecord xps, ERecord xes) => + let + fun consider (xps, env) = + case xps of + [] => SOME env + | (x, p, _) :: rest => + case List.find (fn (x', _, _) => x' = x) xes of + NONE => NONE + | SOME (_, e, _) => + case match (env, p, e) of + NONE => NONE + | SOME env => consider (rest, env) + in + consider (xps, env) + end + + | _ => NONE + fun exp env e = case e of - ENamed n => + ERel n => + (case E.lookupERel env n of + (_, _, SOME e') => #1 e' + | _ => e) + | ENamed n => (case E.lookupENamed env n of (_, _, SOME e', _) => #1 e' | _ => e) @@ -78,6 +123,14 @@ fun exp env e = | EApp ((EAbs (_, _, _, e1), loc), e2) => #1 (reduceExp env (subExpInExp (0, e2) e1)) + | ECase (disc, pes, t) => + (case ListUtil.search (fn (p, body) => + case match (env, p, disc) of + NONE => NONE + | SOME env => SOME (#1 (reduceExp env body))) pes of + NONE => e + | SOME e' => e') + | _ => e and reduceExp env = U.Exp.mapB {typ = typ, exp = exp, bind = bind} env -- cgit v1.2.3