aboutsummaryrefslogtreecommitdiff
path: root/src/boot/fe
diff options
context:
space:
mode:
authorGraydon Hoare <[email protected]>2010-09-09 15:59:29 -0700
committerGraydon Hoare <[email protected]>2010-09-09 15:59:29 -0700
commita9e2327a18e782df524c14dc42910d61a4785324 (patch)
tree8763224ac3a4c11275dd64257aac47036c97c48d /src/boot/fe
parentFixed lost signal notifications. (diff)
downloadrust-a9e2327a18e782df524c14dc42910d61a4785324.tar.xz
rust-a9e2327a18e782df524c14dc42910d61a4785324.zip
Switch tags to purely nominal, removing TY_iso and TY_idx. Seems to mostly work, possibly a little bumpy. Changes a lot.
Diffstat (limited to 'src/boot/fe')
-rw-r--r--src/boot/fe/ast.ml113
-rw-r--r--src/boot/fe/cexp.ml8
-rw-r--r--src/boot/fe/item.ml235
-rw-r--r--src/boot/fe/pexp.ml18
4 files changed, 145 insertions, 229 deletions
diff --git a/src/boot/fe/ast.ml b/src/boot/fe/ast.ml
index 3ea89171..6e6483e3 100644
--- a/src/boot/fe/ast.ml
+++ b/src/boot/fe/ast.ml
@@ -73,13 +73,8 @@ and ty =
| TY_vec of ty
| TY_rec of ty_rec
- (*
- * Note that ty_idx is only valid inside a ty of a ty_iso group, not
- * in a general type term.
- *)
+ (* NB: non-denotable. *)
| TY_tag of ty_tag
- | TY_iso of ty_iso
- | TY_idx of int
| TY_fn of ty_fn
| TY_chan of ty
@@ -113,6 +108,9 @@ and slot = { slot_mode: mode;
and ty_tup = ty array
+and ty_tag = { tag_id: opaque_id;
+ tag_args: ty array }
+
(* In closed type terms a constraint may refer to components of the term by
* anchoring off the "formal symbol" '*', which represents "the term this
* constraint is attached to".
@@ -156,21 +154,6 @@ and constrs = constr array
and ty_rec = (ident * ty) array
-(* ty_tag is a sum type.
- *
- * a tag type expression either normalizes to a TY_tag or a TY_iso,
- * which (like in ocaml) is an indexed projection from an iso-recursive
- * group of TY_tags.
- *)
-
-and ty_tag = (name, ty_tup) Hashtbl.t
-
-and ty_iso =
- {
- iso_index: int;
- iso_group: ty_tag array
- }
-
and ty_sig =
{
sig_input_slots: slot array;
@@ -428,7 +411,7 @@ and ty_param = ident * (ty_param_idx * effect)
and mod_item' =
MOD_ITEM_type of (effect * ty)
- | MOD_ITEM_tag of (header_tup * ty_tag * node_id)
+ | MOD_ITEM_tag of (header_slots * opaque_id * int)
| MOD_ITEM_mod of (mod_view * mod_items)
| MOD_ITEM_fn of fn
| MOD_ITEM_obj of obj
@@ -626,34 +609,6 @@ and fmt_ty_fn
fmt ff " -> ";
fmt_slot ff tsig.sig_output_slot;
-and fmt_tag (ff:Format.formatter) (ttag:ty_tag) : unit =
- fmt ff "@[tag(@[";
- let first = ref true in
- Hashtbl.iter
- begin
- fun name ttup ->
- (if !first
- then first := false
- else fmt ff ",@ ");
- fmt_name ff name;
- fmt_tys ff ttup
- end
- ttag;
- fmt ff "@])@]"
-
-and fmt_iso (ff:Format.formatter) (tiso:ty_iso) : unit =
- fmt ff "@[iso [@[";
- for i = 0 to (Array.length tiso.iso_group) - 1
- do
- if i != 0
- then fmt ff ",@ ";
- if i == tiso.iso_index
- then fmt ff "<%d>: " i
- else fmt ff "%d: " i;
- fmt_tag ff tiso.iso_group.(i);
- done;
- fmt ff "@]]@]"
-
and fmt_constrained ff (ty, constrs) : unit =
fmt ff "@[";
fmt_ty ff ty;
@@ -702,9 +657,11 @@ and fmt_ty (ff:Format.formatter) (t:ty) : unit =
| TY_fn tfn -> fmt_ty_fn ff None tfn
| TY_task -> fmt ff "task"
- | TY_tag ttag -> fmt_tag ff ttag
- | TY_iso tiso -> fmt_iso ff tiso
- | TY_idx idx -> fmt ff "<idx#%d>" idx
+ | TY_tag ttag ->
+ fmt ff "<tag#%d" (int_of_opaque ttag.tag_id);
+ fmt_arr_sep "," fmt_ty ff ttag.tag_args;
+ fmt ff ">";
+
| TY_constrained ctrd -> fmt_constrained ff ctrd
| TY_obj (effect, fns) ->
@@ -1363,16 +1320,7 @@ and fmt_decl_params (ff:Format.formatter) (params:ty_param array) : unit =
if Array.length params = 0
then ()
else
- begin
- fmt ff "[";
- for i = 0 to (Array.length params) - 1
- do
- if i <> 0
- then fmt ff ", ";
- fmt_decl_param ff params.(i)
- done;
- fmt ff "]"
- end;
+ fmt_bracketed_arr_sep "[" "]" "," fmt_decl_param ff params
and fmt_header_slots (ff:Format.formatter) (hslots:header_slots) : unit =
fmt_slots ff
@@ -1462,13 +1410,17 @@ and fmt_mod_item (ff:Format.formatter) (id:ident) (item:mod_item) : unit =
fmt_ty ff ty;
fmt ff ";";
- | MOD_ITEM_tag (hdr, ttag, _) ->
+ | MOD_ITEM_tag (hdr, tid, _) ->
fmt ff "fn ";
fmt_ident_and_params ff id params;
- fmt_header_slots ff
- (Array.mapi (fun i s -> (s,(Printf.sprintf "_%d" i))) hdr);
+ fmt_header_slots ff hdr;
fmt ff " -> ";
- fmt_ty ff (TY_tag ttag);
+ fmt_ty ff (TY_tag
+ { tag_id = tid;
+ tag_args =
+ Array.map
+ (fun (_,p) -> TY_param p)
+ params });
fmt ff ";";
| MOD_ITEM_mod (view,items) ->
@@ -1513,32 +1465,6 @@ and fmt_crate (ff:Format.formatter) (c:crate) : unit =
fmt_mod_items ff items
;;
-let ty_children (ty:ty) : ty array =
- let children_of_ty_tag ty_tag = Array.concat (htab_vals ty_tag) in
- let children_of_ty_fn ty_fn =
- let (ty_sig, _) = ty_fn in
- let in_slots = ty_sig.sig_input_slots in
- let slots = Array.append in_slots [| ty_sig.sig_output_slot |] in
- arr_filter_some (Array.map (fun slot -> slot.slot_ty) slots)
- in
- match ty with
- TY_tup tys -> tys
- | TY_vec ty' | TY_chan ty' | TY_port ty' | TY_box ty' | TY_mutable ty'
- | TY_constrained (ty', _) ->
- [| ty' |]
- | TY_rec fields -> Array.map snd fields
- | TY_tag ty_tag -> children_of_ty_tag ty_tag
- | TY_iso ty_iso ->
- children_of_ty_tag (ty_iso.iso_group.(ty_iso.iso_index))
- | TY_fn ty_fn -> children_of_ty_fn ty_fn
- | TY_obj (_, methods) ->
- Array.concat (List.map children_of_ty_fn (htab_vals methods))
- | TY_any | TY_nil | TY_bool | TY_mach _ | TY_int | TY_uint | TY_char
- | TY_str | TY_idx _ | TY_task | TY_native _ | TY_param _
- | TY_named _ | TY_type ->
- [| |]
-;;
-
let sprintf_binop = sprintf_fmt fmt_binop;;
let sprintf_expr = sprintf_fmt fmt_expr;;
let sprintf_name = sprintf_fmt fmt_name;;
@@ -1549,7 +1475,6 @@ let sprintf_slot = sprintf_fmt fmt_slot;;
let sprintf_slot_key = sprintf_fmt fmt_slot_key;;
let sprintf_ty = sprintf_fmt fmt_ty;;
let sprintf_effect = sprintf_fmt fmt_effect;;
-let sprintf_tag = sprintf_fmt fmt_tag;;
let sprintf_carg = sprintf_fmt fmt_carg;;
let sprintf_constr = sprintf_fmt fmt_constr;;
let sprintf_mod_item =
diff --git a/src/boot/fe/cexp.ml b/src/boot/fe/cexp.ml
index e14bda51..1fe2641b 100644
--- a/src/boot/fe/cexp.ml
+++ b/src/boot/fe/cexp.ml
@@ -176,8 +176,12 @@ and parse_cexp (ps:pstate) : cexp =
let path = ctxt "native mod: path" parse_eq_pexp_opt ps in
let items = Hashtbl.create 0 in
let get_item ps =
- let (ident, item) = Item.parse_mod_item_from_signature ps in
- htab_put items ident item;
+ Array.map
+ begin
+ fun (ident, item) ->
+ htab_put items ident item
+ end
+ (Item.parse_mod_item_from_signature ps)
in
ignore (bracketed_zero_or_more
LBRACE RBRACE None get_item ps);
diff --git a/src/boot/fe/item.ml b/src/boot/fe/item.ml
index a0275be1..a74952cc 100644
--- a/src/boot/fe/item.ml
+++ b/src/boot/fe/item.ml
@@ -231,7 +231,7 @@ and parse_stmts (ps:pstate) : Ast.stmt array =
let apos = lexpos ps in
let name = Pexp.parse_name ps in
let bpos = lexpos ps in
-
+
if peek ps != LPAREN then
begin
match name with
@@ -240,32 +240,32 @@ and parse_stmts (ps:pstate) : Ast.stmt array =
{ Ast.slot_mode = Ast.MODE_local;
Ast.slot_ty = None }
in
- Left
- (Ast.PAT_slot ((span ps apos bpos slot),
+ Left
+ (Ast.PAT_slot ((span ps apos bpos slot),
ident))
|_ -> raise (unexpected ps)
end
else
let lv = name_to_lval apos bpos name in
let parse_pat ps = either_get_left (parse_pat ps) in
- Left
+ Left
(Ast.PAT_tag (lv, paren_comma_list parse_pat ps))
-
+
| LIT_INT _
| LIT_UINT _
| LIT_CHAR _
| LIT_BOOL _ ->
Left (Ast.PAT_lit (Pexp.parse_lit ps))
-
+
| UNDERSCORE -> bump ps; Left (Ast.PAT_wild)
-
+
| tok -> raise (Parse_err (ps,
"Expected pattern but found '" ^
(string_of_tok tok) ^ "'"))
in
let rec parse_arms ps parse_case =
- match peek ps with
- CASE ->
+ match peek ps with
+ CASE ->
bump ps;
let case = parse_case ps in
let blk = parse_block ps in
@@ -283,15 +283,15 @@ and parse_stmts (ps:pstate) : Ast.stmt array =
in
let parse_alt_block ps str parse_case make_stmt =
let br_parse_case = bracketed LPAREN RPAREN parse_case in
- let arms = (ctxt (String.concat " " ["alt"; str; "arms"])
+ let arms = (ctxt (String.concat " " ["alt"; str; "arms"])
(fun ps -> parse_arms ps br_parse_case) ps) in
- make_stmt (fst arms) (snd arms)
+ make_stmt (fst arms) (snd arms)
in
- let which_alt = match peek ps with
+ let which_alt = match peek ps with
TYPE -> "type" | LPAREN -> "tag" | _ -> raise (unexpected ps)
in
- let (stmts, lval) = if which_alt = "type" then bump ps;
- bracketed LPAREN RPAREN parse_lval ps
+ let (stmts, lval) = if which_alt = "type" then bump ps;
+ bracketed LPAREN RPAREN parse_lval ps
in
let make_alt_tag_stmt val_arms dflt_arm =
assert (not (bool_of_option dflt_arm));
@@ -301,7 +301,7 @@ and parse_stmts (ps:pstate) : Ast.stmt array =
Ast.alt_tag_arms = Array.of_list val_arms;
}
end
- in
+ in
let make_alt_type_stmt val_arms dflt_arm =
spans ps stmts apos begin
Ast.STMT_alt_type {
@@ -314,8 +314,8 @@ and parse_stmts (ps:pstate) : Ast.stmt array =
let parse_slot_and_ident ps =
match peek ps with
UNDERSCORE -> Right ()
- | _ -> Left (pair_rev (Pexp.parse_slot_and_ident false ps))
-
+ | _ -> Left (pair_rev (Pexp.parse_slot_and_ident false ps))
+
in
let parse_alt_tag_block ps =
parse_alt_block ps
@@ -399,7 +399,7 @@ and parse_stmts (ps:pstate) : Ast.stmt array =
in
let bpos = lexpos ps in
let head_block =
- (*
+ (*
* Slightly weird, but we put an extra nesting level of
* block here to separate the part that lives in our frame
* (the iter slot) from the part that lives in the callee
@@ -550,11 +550,16 @@ and parse_stmts (ps:pstate) : Ast.stmt array =
expect ps SEMI;
spans ps stmts apos (Ast.STMT_join lval)
- | IO | STATE | UNSAFE | MOD | OBJ | TYPE | FN | USE | NATIVE ->
- let (ident, item) = ctxt "stmt: decl" parse_mod_item ps in
- let decl = Ast.DECL_mod_item (ident, item) in
- let stmts = expand_tags_to_stmts ps item in
- spans ps stmts apos (Ast.STMT_decl decl)
+ | IO | STATE | UNSAFE | MOD | OBJ | TAG | TYPE | FN | USE | NATIVE ->
+ let items = ctxt "stmt: decl" parse_mod_item ps in
+ let bpos = lexpos ps in
+ Array.map
+ begin
+ fun (ident, item) ->
+ let decl = Ast.DECL_mod_item (ident, item) in
+ span ps apos bpos (Ast.STMT_decl decl)
+ end
+ items
| token ->
if token = SPAWN then
@@ -817,6 +822,68 @@ and parse_obj_item
span ps apos bpos
(decl params (Ast.MOD_ITEM_obj obj)))
+and parse_tag_item
+ (ps:pstate)
+ (apos:pos)
+ (effect:Ast.effect)
+ : (Ast.ident * Ast.mod_item) array =
+ expect ps TAG;
+ let (ident, params) = parse_ident_and_params ps "tag" in
+ let tag_id = next_opaque_id ps in
+ let i = ref 0 in
+ let parse_tag_ctor ps =
+ let apos = lexpos ps in
+ let ident = Pexp.parse_ident ps in
+ let hdr =
+ let j = ref 0 in
+ let parse_ctor_slot ps =
+ let apos = lexpos ps in
+ let t = Pexp.parse_ty ps in
+ let s = { Ast.slot_mode = Ast.MODE_local;
+ Ast.slot_ty = Some t }
+ in
+ let bpos = lexpos ps in
+ incr j;
+ ((span ps apos bpos s), "_" ^ string_of_int (!j))
+ in
+ let res = match peek ps with
+ LPAREN -> paren_comma_list parse_ctor_slot ps
+ | _ -> raise (err "tag variant missing argument list" ps)
+ in
+ expect ps SEMI;
+ res
+ in
+ let n = !i in
+ let bpos = lexpos ps in
+ let params =
+ Array.map (fun p -> Parser.clone_span ps p p.node) params
+ in
+ incr i;
+ (ident,
+ span ps apos bpos
+ (decl params
+ (Ast.MOD_ITEM_tag (hdr, tag_id, n))))
+ in
+ let constructors =
+ bracketed_one_or_more LBRACE RBRACE
+ None (ctxt "tag: ctor" parse_tag_ctor) ps
+ in
+ let bpos = lexpos ps in
+ let ty =
+ Ast.TY_tag
+ { Ast.tag_id = tag_id;
+ Ast.tag_args =
+ Array.map
+ (fun p -> Ast.TY_param (snd p.node))
+ params }
+ in
+ let ty_item =
+ (ident,
+ span ps apos bpos
+ (decl params (Ast.MOD_ITEM_type (effect, ty))))
+ in
+ Array.append [| ty_item |] constructors
+
and parse_type_item
(ps:pstate)
(apos:pos)
@@ -831,7 +898,8 @@ and parse_type_item
let item = Ast.MOD_ITEM_type (effect, ty) in
(ident, span ps apos bpos (decl params item))
-and parse_mod_item (ps:pstate) : (Ast.ident * Ast.mod_item) =
+and parse_mod_item (ps:pstate)
+ : (Ast.ident * Ast.mod_item) array =
let apos = lexpos ps in
let parse_lib_name ident =
match peek ps with
@@ -856,12 +924,13 @@ and parse_mod_item (ps:pstate) : (Ast.ident * Ast.mod_item) =
match peek ps with
- IO | STATE | UNSAFE | TYPE | OBJ | FN | ITER ->
+ IO | STATE | UNSAFE | TYPE | OBJ | TAG | FN | ITER ->
let effect = Pexp.parse_effect ps in
begin
match peek ps with
- OBJ -> parse_obj_item ps apos effect
- | TYPE -> parse_type_item ps apos effect
+ OBJ -> [| parse_obj_item ps apos effect |]
+ | TAG -> parse_tag_item ps apos effect
+ | TYPE -> [| parse_type_item ps apos effect |]
| _ ->
let is_iter = (peek ps) = ITER in
bump ps;
@@ -870,9 +939,9 @@ and parse_mod_item (ps:pstate) : (Ast.ident * Ast.mod_item) =
ctxt "mod fn item: fn" (parse_fn is_iter effect) ps
in
let bpos = lexpos ps in
- (ident,
- span ps apos bpos
- (decl params (Ast.MOD_ITEM_fn fn)))
+ [| (ident,
+ span ps apos bpos
+ (decl params (Ast.MOD_ITEM_fn fn))) |]
end
| MOD ->
@@ -881,9 +950,9 @@ and parse_mod_item (ps:pstate) : (Ast.ident * Ast.mod_item) =
expect ps LBRACE;
let items = parse_mod_items ps RBRACE in
let bpos = lexpos ps in
- (ident,
- span ps apos bpos
- (decl params (Ast.MOD_ITEM_mod items)))
+ [| (ident,
+ span ps apos bpos
+ (decl params (Ast.MOD_ITEM_mod items))) |]
| NATIVE ->
begin
@@ -910,7 +979,7 @@ and parse_mod_item (ps:pstate) : (Ast.ident * Ast.mod_item) =
let item = decl [||] (Ast.MOD_ITEM_mod items) in
let item = span ps apos bpos item in
note_required_mod ps {lo=apos; hi=bpos} conv rlib item;
- (ident, item)
+ [| (ident, item) |]
end
| _ -> raise (unexpected ps)
@@ -934,16 +1003,17 @@ and parse_mod_items_from_signature
let items = Hashtbl.create 0 in
while not (peek ps = RBRACE)
do
- let (ident,item) = ctxt "mod items from sig: mod item"
- parse_mod_item_from_signature ps
- in
- htab_put items ident item;
+ Array.iter
+ (fun (ident, item) ->
+ htab_put items ident item)
+ (ctxt "mod items from sig: mod item"
+ parse_mod_item_from_signature ps)
done;
expect ps RBRACE;
(view,items)
and parse_mod_item_from_signature (ps:pstate)
- : (Ast.ident * Ast.mod_item) =
+ : (Ast.ident * Ast.mod_item) array =
let apos = lexpos ps in
match peek ps with
MOD ->
@@ -951,7 +1021,8 @@ and parse_mod_item_from_signature (ps:pstate)
let (ident, params) = parse_ident_and_params ps "mod signature" in
let items = parse_mod_items_from_signature ps in
let bpos = lexpos ps in
- (ident, span ps apos bpos (decl params (Ast.MOD_ITEM_mod items)))
+ [| (ident,
+ span ps apos bpos (decl params (Ast.MOD_ITEM_mod items))) |]
| IO | STATE | UNSAFE | FN | ITER ->
let effect = Pexp.parse_effect ps in
@@ -985,7 +1056,7 @@ and parse_mod_item_from_signature (ps:pstate)
| _ -> ()
end;
expect ps SEMI;
- (ident, node)
+ [| (ident, node) |]
| TYPE ->
bump ps;
@@ -997,77 +1068,11 @@ and parse_mod_item_from_signature (ps:pstate)
in
expect ps SEMI;
let bpos = lexpos ps in
- (ident, span ps apos bpos
- (decl params (Ast.MOD_ITEM_type (Ast.UNSAFE, t))))
+ [| (ident, span ps apos bpos
+ (decl params (Ast.MOD_ITEM_type (Ast.UNSAFE, t)))) |]
| _ -> raise (unexpected ps)
-
-and expand_tags
- (ps:pstate)
- (item:Ast.mod_item)
- : (Ast.ident * Ast.mod_item) array =
- let handle_ty_tag id ttag =
- let tags = ref [] in
- Hashtbl.iter
- begin
- fun name tup ->
- let ident = match name with
- Ast.NAME_base (Ast.BASE_ident ident) -> ident
- | _ ->
- raise (Parse_err
- (ps, "unexpected name type while expanding tag"))
- in
- let header =
- Array.map (fun ty -> (clone_span ps item
- { Ast.slot_mode = Ast.MODE_alias;
- Ast.slot_ty = Some ty})) tup
- in
- let tag_item' = Ast.MOD_ITEM_tag (header, ttag, id) in
- let cloned_params =
- Array.map (fun p -> clone_span ps p p.node)
- item.node.Ast.decl_params
- in
- let tag_item =
- clone_span ps item (decl cloned_params tag_item')
- in
- tags := (ident, tag_item) :: (!tags)
- end
- ttag;
- arr (!tags)
- in
- let handle_ty_decl id tyd =
- match tyd with
- Ast.TY_tag ttag -> handle_ty_tag id ttag
- | _ -> [| |]
- in
- match item.node.Ast.decl_item with
- Ast.MOD_ITEM_type (_, tyd) -> handle_ty_decl item.id tyd
- | _ -> [| |]
-
-
-and expand_tags_to_stmts
- (ps:pstate)
- (item:Ast.mod_item)
- : Ast.stmt array =
- let id_items = expand_tags ps item in
- Array.map
- (fun (ident, tag_item) ->
- clone_span ps item
- (Ast.STMT_decl
- (Ast.DECL_mod_item (ident, tag_item))))
- id_items
-
-and expand_tags_to_items
- (ps:pstate)
- (item:Ast.mod_item)
- (items:Ast.mod_items)
- : unit =
- let id_items = expand_tags ps item in
- Array.iter
- (fun (ident, item) -> htab_put items ident item)
- id_items
-
and note_required_mod
(ps:pstate)
(sp:span)
@@ -1118,7 +1123,7 @@ and parse_import
bump ps;
match peek ps with
EQ ->
- (*
+ (*
* import x = ...
*)
bump ps;
@@ -1149,7 +1154,7 @@ and parse_export
and parse_use
(ps:pstate)
- : (Ast.ident * Ast.mod_item) =
+ : (Ast.ident * Ast.mod_item) array =
bump ps;
let ident = ctxt "use mod: ident" Pexp.parse_ident ps in
let meta =
@@ -1182,12 +1187,12 @@ and parse_use
let item = decl [||] (Ast.MOD_ITEM_mod (empty_view, items)) in
let item = span ps apos bpos item in
note_required_mod ps {lo=apos; hi=bpos} CONV_rust rlib item;
- (ident, item)
+ [| (ident, item) |]
and parse_item_decl ps items fn =
- let (ident, item) = fn ps in
- htab_put items ident item;
- expand_tags_to_items ps item items
+ Array.iter
+ (fun (id,it) -> htab_put items id it)
+ (fn ps);
and parse_mod_header (ps:pstate)
: (Ast.mod_view * Ast.mod_items) =
diff --git a/src/boot/fe/pexp.ml b/src/boot/fe/pexp.ml
index 75983c7f..1f04e5eb 100644
--- a/src/boot/fe/pexp.ml
+++ b/src/boot/fe/pexp.ml
@@ -270,24 +270,6 @@ and parse_atomic_ty (ps:pstate) : Ast.ty =
| IDENT _ -> Ast.TY_named (parse_name ps)
- | TAG ->
- bump ps;
- let htab = Hashtbl.create 4 in
- let parse_tag_entry ps =
- let ident = parse_ident ps in
- let tup =
- match peek ps with
- LPAREN -> paren_comma_list parse_ty ps
- | _ -> raise (err "tag variant missing argument list" ps)
- in
- htab_put htab (Ast.NAME_base (Ast.BASE_ident ident)) tup
- in
- let _ =
- bracketed_one_or_more LPAREN RPAREN
- (Some COMMA) (ctxt "tag: variant" parse_tag_entry) ps
- in
- Ast.TY_tag htab
-
| REC ->
bump ps;
let parse_rec_entry ps =