summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlasdair Armstrong2019-03-22 16:14:23 +0000
committerAlasdair Armstrong2019-03-22 16:16:16 +0000
commitc9471630ad64af00a58a3c92f4b6a22f2194e9ee (patch)
treeb3ccdf6840378de84943fc6f48b96afa33aa3422 /src
parent2b0a4e2746e632d3f823baade49b560f79317497 (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.ml8
-rw-r--r--src/jib/anf.mli1
-rw-r--r--src/jib/jib_compile.ml7
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