diff options
| author | Alasdair Armstrong | 2017-10-04 11:42:07 +0100 |
|---|---|---|
| committer | Alasdair Armstrong | 2017-10-04 11:42:07 +0100 |
| commit | 4feedbf27c5a204806bb5f1297bd9cd2505e3c26 (patch) | |
| tree | 3c8e8e8972f7a0944432ac082f1398e617e8cbef /src/pretty_print_sail2.ml | |
| parent | a41d08d4f33f778eee98aa4094eaa4f94fc134c0 (diff) | |
Add pretty printer for menhir parser
Diffstat (limited to 'src/pretty_print_sail2.ml')
| -rw-r--r-- | src/pretty_print_sail2.ml | 212 |
1 files changed, 212 insertions, 0 deletions
diff --git a/src/pretty_print_sail2.ml b/src/pretty_print_sail2.ml new file mode 100644 index 00000000..dfbeaaf8 --- /dev/null +++ b/src/pretty_print_sail2.ml @@ -0,0 +1,212 @@ + +open Ast +open Ast_util +open PPrint + +let doc_op symb a b = infix 2 1 symb a b + +let doc_id (Id_aux (id_aux, _)) = + string (match id_aux with + | Id v -> v + | DeIid op -> "op " ^ op) + +let doc_kid kid = string (Ast_util.string_of_kid kid) + +let doc_int n = string (string_of_int n) + +let doc_ord (Ord_aux(o,_)) = match o with + | Ord_var v -> doc_kid v + | Ord_inc -> string "inc" + | Ord_dec -> string "dec" + +let rec doc_nexp (Nexp_aux (n_aux, _)) = + match n_aux with + | Nexp_constant c -> string (string_of_int c) + | Nexp_id id -> doc_id id + | Nexp_var kid -> doc_kid kid + | _ -> string "NEXP" + +let doc_nc = + let rec atomic_nc (NC_aux (nc_aux, _) as nc) = + match nc_aux with + | NC_true -> string "true" + | NC_false -> string "false" + | NC_set (kid, ints) -> + separate space [doc_kid kid; string "in"; braces (separate_map (comma ^^ space) doc_int ints)] + | _ -> parens (nc0 nc) + and nc0 (NC_aux (nc_aux, _)) = string "NC0" + in + atomic_nc + +let rec doc_typ (Typ_aux (typ_aux, _)) = + match typ_aux with + | Typ_id id -> doc_id id + | Typ_app (id, []) -> doc_id id + | Typ_app (Id_aux (DeIid str, _), [x; y]) -> + separate space [doc_typ_arg x; doc_typ_arg y] + | Typ_app (id, typs) -> doc_id id ^^ parens (separate_map (string ", ") doc_typ_arg typs) + | Typ_tup typs -> parens (separate_map (string ", ") doc_typ typs) + | Typ_var kid -> doc_kid kid + | Typ_wild -> assert false + (* Resugar set types like {|1, 2, 3|} *) + | Typ_exist ([kid1], NC_aux (NC_set (kid2, ints), _), Typ_aux (Typ_app (id, [Typ_arg_aux (Typ_arg_typ (Typ_aux (Typ_var kid3, _)), _)]), _)) + when Kid.compare kid1 kid2 == 0 && Kid.compare kid2 kid3 == 0 -> + enclose (string "{|") (string "|}") (separate_map (string ", ") doc_int ints) + | Typ_exist (kids, nc, typ) -> + braces (separate_map space doc_kid kids ^^ comma ^^ space ^^ doc_nc nc ^^ dot ^^ space ^^ doc_typ typ) + | Typ_fn (typ1, typ2, eff) -> + separate space [doc_typ typ1; string "->"; doc_typ typ2] +and doc_typ_arg (Typ_arg_aux (ta_aux, _)) = + match ta_aux with + | Typ_arg_typ typ -> doc_typ typ + | Typ_arg_nexp nexp -> doc_nexp nexp + | Typ_arg_order o -> doc_ord o + +let doc_typschm (TypSchm_aux (TypSchm_ts (TypQ_aux (tq_aux, _), typ), _)) = + match tq_aux with + | TypQ_no_forall -> doc_typ typ + | TypQ_tq [] -> doc_typ typ + | TypQ_tq qs -> string "QI" ^^ dot ^^ space ^^ doc_typ typ + +let doc_typschm_typ (TypSchm_aux (TypSchm_ts (TypQ_aux (tq_aux, _), typ), _)) = doc_typ typ + +let doc_lit (L_aux(l,_)) = + utf8string (match l with + | L_unit -> "()" + | L_zero -> "bitzero" + | L_one -> "bitone" + | L_true -> "true" + | L_false -> "false" + | L_num i -> string_of_int i + | L_hex n -> "0x" ^ n + | L_bin n -> "0b" ^ n + | L_real r -> r + | L_undef -> "undefined" + | L_string s -> "\"" ^ String.escaped s ^ "\"") + +let rec doc_pat (P_aux (p_aux, _)) = + match p_aux with + | P_id id -> doc_id id + | P_tup pats -> lparen ^^ separate_map (comma ^^ space) doc_pat pats ^^ rparen + | P_app (id, pats) -> doc_id id ^^ lparen ^^ separate_map (comma ^^ space) doc_pat pats ^^ rparen + | P_typ (typ, pat) -> separate space [doc_pat pat; colon; doc_typ typ] + | P_lit lit -> doc_lit lit + | P_var (pat, kid) -> separate space [doc_pat pat; string "as"; doc_kid kid] + | P_vector_concat pats -> separate_map (space ^^ string "@" ^^ space) doc_pat pats + | P_wild -> string "_" + | _ -> string "PAT" + +let rec doc_exp (E_aux (e_aux, _) as exp) = + match e_aux with + | E_block exps -> surround 2 0 lbrace (doc_block exps) rbrace + | E_nondet exps -> assert false + | E_id id -> doc_id id + | E_lit lit -> doc_lit lit + | E_cast (typ, exp) -> + separate space [doc_exp exp; colon; doc_typ typ] + | E_app (id, exps) -> assert false + | E_app_infix (x, id, y) -> doc_op (doc_id id) (doc_exp x) (doc_exp y) + | E_tuple exps -> assert false + | E_if (if_exp, then_exp, else_exp) -> assert false + | E_for (id, exp1, exp2, exp3, order, exp4) -> assert false + | E_vector exps -> assert false + | E_vector_access (exp1, exp2) -> assert false + | E_vector_subrange (exp1, exp2, exp3) -> doc_exp exp1 ^^ brackets (separate space [doc_exp exp2; string ".."; doc_exp exp3]) + | E_vector_update (exp1, exp2, exp3) -> assert false + | E_vector_update_subrange (exp1, exp2, exp3, exp4) -> assert false + | E_list exps -> assert false + | E_cons (exp1, exp2) -> assert false + | E_record fexps -> assert false + | E_record_update (exp, fexps) -> assert false + | E_field (exp, id) -> assert false + | E_case (exp, pexps) -> + separate space [string "match"; doc_exp exp; doc_pexps pexps] + | E_let (lb, exp) -> assert false + | E_assign (lexp, exp) -> + separate space [doc_lexp lexp; equals; doc_exp exp] + | E_sizeof nexp -> assert false + | E_constraint nc -> assert false + | E_exit exp -> assert false + | E_throw exp -> assert false + | E_try (exp, pexps) -> assert false + | E_return exp -> assert false +and doc_block = function + | [] -> assert false + | [exp] -> doc_exp exp + | exp :: exps -> doc_exp exp ^^ semi ^^ break 1 ^^ doc_block exps +and doc_lexp (LEXP_aux (l_aux, _)) = + match l_aux with + | LEXP_id id -> doc_id id + | LEXP_tup lexps -> lparen ^^ separate_map (comma ^^ space) doc_lexp lexps ^^ rparen + | _ -> string "LEXP" +and doc_pexps pexps = surround 2 0 lbrace (separate_map (semi ^^ hardline) doc_pexp pexps) rbrace +and doc_pexp (Pat_aux (pat_aux, _)) = + match pat_aux with + | Pat_exp (pat, exp) -> separate space [doc_pat pat; string "=>"; doc_exp exp] + | Pat_when (pat, wh, exp) -> + separate space [doc_pat pat; string "if"; doc_exp wh; string "=>"; doc_exp exp] +and doc_letbind (LB_aux (lb_aux, _)) = + match lb_aux with + | LB_val (pat, exp) -> + separate space [doc_pat pat; equals; doc_exp exp] + +let doc_funcl funcl = string "FUNCL" + +let doc_funcl (FCL_aux (FCL_Funcl (id, pat, exp), _)) = + group (separate space [doc_id id; doc_pat pat; equals; doc_exp exp]) + +let doc_default (DT_aux(df,_)) = match df with + | DT_kind(bk,v) -> string "DT_kind" (* separate space [string "default"; doc_bkind bk; doc_var v] *) + | DT_typ(ts,id) -> separate space [string "default"; doc_typschm ts; doc_id id] + | DT_order(ord) -> separate space [string "default"; string "Order"; doc_ord ord] + +let doc_fundef (FD_aux (FD_function (r, typa, efa, funcls), _)) = + match funcls with + | [] -> failwith "Empty function list" + | _ -> + let sep = hardline ^^ string "and" ^^ space in + let clauses = separate_map sep doc_funcl funcls in + string "function" ^^ space ^^ clauses + +let doc_dec (DEC_aux (reg,_)) = + match reg with + | DEC_reg (typ, id) -> separate space [string "register"; doc_id id; colon; doc_typ typ] + | DEC_alias(id,alspec) -> string "ALIAS" + | DEC_typ_alias(typ,id,alspec) -> string "ALIAS" + +let doc_typdef (TD_aux(td,_)) = match td with + | TD_abbrev(id, _, typschm) -> + doc_op equals (concat [string "type"; space; doc_id id]) (doc_typschm_typ typschm) + | _ -> string "TYPEDEF" + +let doc_spec (VS_aux(v,_)) = match v with + | VS_val_spec(ts,id,_,_) -> + separate space [string "val"; doc_id id; colon; doc_typschm ts] + | _ -> string "VS?" +(* + | VS_cast_spec (ts, id) -> + separate space [string "val"; string "cast"; doc_typscm ts; doc_id id] + | VS_extern_no_rename(ts,id) -> + separate space [string "val"; string "extern"; doc_typscm ts; doc_id id] + | VS_extern_spec(ts,id,s) -> + separate space [string "val"; string "extern"; doc_typscm ts; doc_op equals (doc_id id) (dquotes (string s))] + *) +let rec doc_def def = group (match def with + | DEF_default df -> doc_default df + | DEF_spec v_spec -> doc_spec v_spec + | DEF_type t_def -> doc_typdef t_def + | DEF_kind k_def -> string "TOPLEVEL" + | DEF_fundef f_def -> doc_fundef f_def + | DEF_val lbind -> string "let" ^^ space ^^ doc_letbind lbind + | DEF_reg_dec dec -> doc_dec dec + | DEF_scattered sdef -> string "TOPLEVEL" + | DEF_overload (id, ids) -> + string "TOPLEVEL" + | DEF_comm (DC_comm s) -> string "TOPLEVEL" + | DEF_comm (DC_comm_struct d) -> string "TOPLEVEL" + ) ^^ hardline + +let doc_defs (Defs(defs)) = + separate_map hardline doc_def defs + +let pp_defs f d = ToChannel.pretty 1. 120 f (doc_defs d) |
