diff options
| author | Alasdair Armstrong | 2019-03-22 16:14:23 +0000 |
|---|---|---|
| committer | Alasdair Armstrong | 2019-03-22 16:16:16 +0000 |
| commit | c9471630ad64af00a58a3c92f4b6a22f2194e9ee (patch) | |
| tree | b3ccdf6840378de84943fc6f48b96afa33aa3422 /src | |
| parent | 2b0a4e2746e632d3f823baade49b560f79317497 (diff) | |
C: Fix as-patterns in C output
Most such patterns are re-written away by various re-writing steps,
but for those that arn't they are fairly easy to handle by just having
as patterns directly in the ANF-patterns.
Fixes #39
Diffstat (limited to 'src')
| -rw-r--r-- | src/jib/anf.ml | 8 | ||||
| -rw-r--r-- | src/jib/anf.mli | 1 | ||||
| -rw-r--r-- | src/jib/jib_compile.ml | 7 |
3 files changed, 16 insertions, 0 deletions
diff --git a/src/jib/anf.ml b/src/jib/anf.ml index c83fa8e2..5bea0988 100644 --- a/src/jib/anf.ml +++ b/src/jib/anf.ml @@ -91,6 +91,7 @@ and 'a apat_aux = | AP_global of id * 'a | AP_app of id * 'a apat * 'a | AP_cons of 'a apat * 'a apat + | AP_as of 'a apat * id * 'a | AP_nil of 'a | AP_wild of 'a @@ -113,6 +114,7 @@ let rec apat_bindings (AP_aux (apat_aux, _, _)) = | AP_global (id, _) -> IdSet.empty | AP_app (id, apat, _) -> apat_bindings apat | AP_cons (apat1, apat2) -> IdSet.union (apat_bindings apat1) (apat_bindings apat2) + | AP_as (apat, id, _) -> IdSet.add id (apat_bindings apat) | AP_nil _ -> IdSet.empty | AP_wild _ -> IdSet.empty @@ -132,6 +134,7 @@ let rec apat_types (AP_aux (apat_aux, _, _)) = | AP_global (id, _) -> Bindings.empty | AP_app (id, apat, _) -> apat_types apat | AP_cons (apat1, apat2) -> (Bindings.merge merge) (apat_types apat1) (apat_types apat2) + | AP_as (apat, id, typ) -> Bindings.add id typ (apat_types apat) | AP_nil _ -> Bindings.empty | AP_wild _ -> Bindings.empty @@ -143,6 +146,8 @@ let rec apat_rename from_id to_id (AP_aux (apat_aux, env, l)) = | AP_global (id, typ) -> AP_global (id, typ) | AP_app (ctor, apat, typ) -> AP_app (ctor, apat_rename from_id to_id apat, typ) | AP_cons (apat1, apat2) -> AP_cons (apat_rename from_id to_id apat1, apat_rename from_id to_id apat2) + | AP_as (apat, id, typ) when Id.compare id from_id = 0 -> AP_as (apat, to_id, typ) + | AP_as (apat, id, typ) -> AP_as (apat, id, typ) | AP_nil typ -> AP_nil typ | AP_wild typ -> AP_wild typ in @@ -382,6 +387,7 @@ and pp_apat (AP_aux (apat_aux, _, _)) = | AP_app (id, apat, typ) -> pp_annot typ (pp_id id ^^ parens (pp_apat apat)) | AP_nil _ -> string "[||]" | AP_cons (hd_apat, tl_apat) -> pp_apat hd_apat ^^ string " :: " ^^ pp_apat tl_apat + | AP_as (apat, id, ctyp) -> pp_apat apat ^^ string " as " ^^ pp_id id and pp_cases cases = surround 2 0 lbrace (separate_map (comma ^^ hardline) pp_case cases) rbrace @@ -445,6 +451,7 @@ let rec anf_pat ?global:(global=false) (P_aux (p_aux, annot) as pat) = | P_cons (hd_pat, tl_pat) -> mk_apat (AP_cons (anf_pat ~global:global hd_pat, anf_pat ~global:global tl_pat)) | P_list pats -> List.fold_right (fun pat apat -> mk_apat (AP_cons (anf_pat ~global:global pat, apat))) pats (mk_apat (AP_nil (typ_of_pat pat))) | P_lit (L_aux (L_unit, _)) -> mk_apat (AP_wild (typ_of_pat pat)) + | P_as (pat, id) -> mk_apat (AP_as (anf_pat ~global:global pat, id, typ_of_pat pat)) | _ -> raise (Reporting.err_unreachable (fst annot) __POS__ ("Could not convert pattern to ANF: " ^ string_of_pat pat)) @@ -456,6 +463,7 @@ let rec apat_globals (AP_aux (aux, _, _)) = | AP_tup apats -> List.concat (List.map apat_globals apats) | AP_app (_, apat, _) -> apat_globals apat | AP_cons (hd_apat, tl_apat) -> apat_globals hd_apat @ apat_globals tl_apat + | AP_as (apat, _, _) -> apat_globals apat let rec anf (E_aux (e_aux, ((l, _) as exp_annot)) as exp) = let mk_aexp aexp = AE_aux (aexp, env_of_annot exp_annot, l) in diff --git a/src/jib/anf.mli b/src/jib/anf.mli index 79fb35ca..26b847e2 100644 --- a/src/jib/anf.mli +++ b/src/jib/anf.mli @@ -111,6 +111,7 @@ and 'a apat_aux = | AP_global of id * 'a | AP_app of id * 'a apat * 'a | AP_cons of 'a apat * 'a apat + | AP_as of 'a apat * id * 'a | AP_nil of 'a | AP_wild of 'a diff --git a/src/jib/jib_compile.ml b/src/jib/jib_compile.ml index 15f945e5..c13b814f 100644 --- a/src/jib/jib_compile.ml +++ b/src/jib/jib_compile.ml @@ -416,6 +416,7 @@ let rec apat_ctyp ctx (AP_aux (apat, _, _)) = | AP_cons (apat, _) -> CT_list (apat_ctyp ctx apat) | AP_wild typ | AP_nil typ | AP_id (_, typ) -> ctyp_of_typ ctx typ | AP_app (_, _, typ) -> ctyp_of_typ ctx typ + | AP_as (_, _, typ) -> ctyp_of_typ ctx typ let rec compile_match ctx (AP_aux (apat_aux, env, l)) cval case_label = let ctx = { ctx with local_env = env } in @@ -441,6 +442,12 @@ let rec compile_match ctx (AP_aux (apat_aux, env, l)) cval case_label = let ctx = { ctx with locals = Bindings.add pid (Immutable, id_ctyp) ctx.locals } in [idecl id_ctyp (name pid); icopy l (CL_id (name pid, id_ctyp)) cval], [iclear id_ctyp (name pid)], ctx + | AP_as (apat, id, typ), _ -> + let id_ctyp = ctyp_of_typ ctx typ in + let instrs, cleanup, ctx = compile_match ctx apat cval case_label in + let ctx = { ctx with locals = Bindings.add id (Immutable, id_ctyp) ctx.locals } in + instrs @ [idecl id_ctyp (name id); icopy l (CL_id (name id, id_ctyp)) cval], iclear id_ctyp (name id) :: cleanup, ctx + | AP_tup apats, (frag, ctyp) -> begin let get_tup n ctyp = (F_field (frag, "ztup" ^ string_of_int n), ctyp) in |
