src/Pure/Syntax/printer.ML
changeset 2384 d360b395766e
parent 2365 38295260a740
child 2507 d290b91e76b8
equal deleted inserted replaced
2383:4127499d9b52 2384:d360b395766e
     4 
     4 
     5 Pretty printing of asts, terms, types and print (ast) translation.
     5 Pretty printing of asts, terms, types and print (ast) translation.
     6 *)
     6 *)
     7 
     7 
     8 signature PRINTER0 =
     8 signature PRINTER0 =
     9   sig
     9 sig
    10   val show_brackets: bool ref
    10   val show_brackets: bool ref
    11   val show_sorts: bool ref
    11   val show_sorts: bool ref
    12   val show_types: bool ref
    12   val show_types: bool ref
    13   val show_no_free_types: bool ref
    13   val show_no_free_types: bool ref
    14   val print_mode: string list ref
    14   val print_mode: string list ref
    15   end;
    15 end;
    16 
    16 
    17 signature PRINTER =
    17 signature PRINTER =
    18   sig
    18 sig
    19   include PRINTER0
    19   include PRINTER0
    20   val term_to_ast: (string -> (term list -> term) option) -> term -> Ast.ast
    20   val term_to_ast: (string -> (typ -> term list -> term) option) -> term -> Ast.ast
    21   val typ_to_ast: (string -> (term list -> term) option) -> typ -> Ast.ast
    21   val typ_to_ast: (string -> (typ -> term list -> term) option) -> typ -> Ast.ast
    22   type prtabs
    22   type prtabs
    23   val prmodes_of: prtabs -> string list
    23   val prmodes_of: prtabs -> string list
    24   val empty_prtabs: prtabs
    24   val empty_prtabs: prtabs
    25   val extend_prtabs: prtabs -> string -> SynExt.xprod list -> prtabs
    25   val extend_prtabs: prtabs -> string -> SynExt.xprod list -> prtabs
    26   val merge_prtabs: prtabs -> prtabs -> prtabs
    26   val merge_prtabs: prtabs -> prtabs -> prtabs
    27   val pretty_term_ast: bool -> prtabs
    27   val pretty_term_ast: bool -> prtabs
    28     -> (string -> (Ast.ast list -> Ast.ast) option) -> Ast.ast -> Pretty.T
    28     -> (string -> (Ast.ast list -> Ast.ast) option) -> Ast.ast -> Pretty.T
    29   val pretty_typ_ast: bool -> prtabs
    29   val pretty_typ_ast: bool -> prtabs
    30     -> (string -> (Ast.ast list -> Ast.ast) option) -> Ast.ast -> Pretty.T
    30     -> (string -> (Ast.ast list -> Ast.ast) option) -> Ast.ast -> Pretty.T
    31   val chartrans_of: prtabs -> (string * string) list
    31 end;
    32   end;
       
    33 
    32 
    34 structure Printer: PRINTER =
    33 structure Printer: PRINTER =
    35 struct
    34 struct
    36 
    35 
    37 open Lexicon Ast SynExt TypeExt SynTrans;
    36 open Lexicon Ast SynExt TypeExt SynTrans;
    79           in
    78           in
    80             (t1' $ t2', seen'')
    79             (t1' $ t2', seen'')
    81           end;
    80           end;
    82 
    81 
    83 
    82 
    84     fun ast_of (Const (a, _)) = trans a []
    83     fun ast_of (Const (a, T)) = trans a T []
    85       | ast_of (Free (x, ty)) = constrain x (free x) ty
    84       | ast_of (Free (x, ty)) = constrain x (free x) ty
    86       | ast_of (Var (xi, ty)) = constrain (string_of_vname xi) (var xi) ty
    85       | ast_of (Var (xi, ty)) = constrain (string_of_vname xi) (var xi) ty
    87       | ast_of (Bound i) = Variable ("B." ^ string_of_int i)
    86       | ast_of (Bound i) = Variable ("B." ^ string_of_int i)
    88       | ast_of (t as Abs _) = ast_of (abs_tr' t)
    87       | ast_of (t as Abs _) = ast_of (abs_tr' t)
    89       | ast_of (t as _ $ _) =
    88       | ast_of (t as _ $ _) =
    90           (case strip_comb t of
    89           (case strip_comb t of
    91             (Const (a, _), args) => trans a args
    90             (Const (a, T), args) => trans a T args
    92           | (f, args) => Appl (map ast_of (f :: args)))
    91           | (f, args) => Appl (map ast_of (f :: args)))
    93 
    92 
    94     and trans a args =
    93     and trans a T args =
    95       (case trf a of
    94       (case trf a of
    96         Some f => ast_of (apply_trans "print translation" a f args)
    95         Some f => ast_of (apply_trans "print translation" a (uncurry f) (T, args))
    97       | None => raise Match)
    96       | None => raise Match)
    98           handle Match => mk_appl (Constant a) (map ast_of args)
    97           handle Match => mk_appl (Constant a) (map ast_of args)
    99 
    98 
   100     and constrain x t ty =
    99     and constrain x t ty =
   101       if show_types andalso ty <> dummyT then
   100       if show_types andalso ty <> dummyT then
   150 (* xprods_to_fmts *)
   149 (* xprods_to_fmts *)
   151 
   150 
   152 fun xprod_to_fmt (XProd (_, _, "", _)) = None
   151 fun xprod_to_fmt (XProd (_, _, "", _)) = None
   153   | xprod_to_fmt (XProd (_, xsymbs, const, pri)) =
   152   | xprod_to_fmt (XProd (_, xsymbs, const, pri)) =
   154       let
   153       let
       
   154         fun cons_str s (String s' :: syms) = String (s ^ s') :: syms
       
   155           | cons_str s syms = String s :: syms;
       
   156 
   155         fun arg (s, p) =
   157         fun arg (s, p) =
   156           (if s = "type" then TypArg else Arg)
   158           (if s = "type" then TypArg else Arg)
   157           (if is_terminal s then max_pri else p);
   159           (if is_terminal s then max_pri else p);
   158 
   160 
   159         fun xsyms_to_syms (Delim s :: xsyms) =
   161         fun xsyms_to_syms (Delim s :: xsyms) =
   160               apfst (cons (String s)) (xsyms_to_syms xsyms)
   162               apfst (cons_str s) (xsyms_to_syms xsyms)
   161           | xsyms_to_syms (Argument s_p :: xsyms) =
   163           | xsyms_to_syms (Argument s_p :: xsyms) =
   162               apfst (cons (arg s_p)) (xsyms_to_syms xsyms)
   164               apfst (cons (arg s_p)) (xsyms_to_syms xsyms)
   163           | xsyms_to_syms (Space s :: xsyms) =
   165           | xsyms_to_syms (Space s :: xsyms) =
   164               apfst (cons (String s)) (xsyms_to_syms xsyms)
   166               apfst (cons_str s) (xsyms_to_syms xsyms)
   165           | xsyms_to_syms (Bg i :: xsyms) =
   167           | xsyms_to_syms (Bg i :: xsyms) =
   166               let
   168               let
   167                 val (bsyms, xsyms') = xsyms_to_syms xsyms;
   169                 val (bsyms, xsyms') = xsyms_to_syms xsyms;
   168                 val (syms, xsyms'') = xsyms_to_syms xsyms';
   170                 val (syms, xsyms'') = xsyms_to_syms xsyms';
   169               in
   171               in
   258             (! show_brackets andalso p' <> max_pri andalso not (is_chain pr))
   260             (! show_brackets andalso p' <> max_pri andalso not (is_chain pr))
   259             then [Block (1, String "(" :: pr @ [String ")"])]
   261             then [Block (1, String "(" :: pr @ [String ")"])]
   260             else pr, args))
   262             else pr, args))
   261 
   263 
   262     and prefixT (_, a, [], _) = [Pretty.str a]
   264     and prefixT (_, a, [], _) = [Pretty.str a]
   263       | prefixT (c, _, args, p) = astT (appT (c, args), p)
   265       | prefixT (c, _, args, p) =
       
   266           if c = Constant "_appl" orelse c = Constant "_applC" then
       
   267             error "Syntax insufficient for printing prefix applications"
       
   268           else astT (appT (c, args), p)
   264 
   269 
   265     and splitT 0 ([x], ys) = (x, ys)
   270     and splitT 0 ([x], ys) = (x, ys)
   266       | splitT 0 (rev_xs, ys) = (Appl (rev rev_xs), ys)
   271       | splitT 0 (rev_xs, ys) = (Appl (rev rev_xs), ys)
   267       | splitT n (rev_xs, y :: ys) = splitT (n - 1) (y :: rev_xs, ys)
   272       | splitT n (rev_xs, y :: ys) = splitT (n - 1) (y :: rev_xs, ys)
   268       | splitT _ _ = sys_error "splitT"
   273       | splitT _ _ = sys_error "splitT"
   306 
   311 
   307 fun pretty_typ_ast _ prtabs trf ast =
   312 fun pretty_typ_ast _ prtabs trf ast =
   308   Pretty.blk (0, pretty (tabs_of prtabs (! print_mode)) trf true false ast 0);
   313   Pretty.blk (0, pretty (tabs_of prtabs (! print_mode)) trf true false ast 0);
   309 
   314 
   310 
   315 
   311 
       
   312 (** character translations - generated from "symbols" syntax **)
       
   313 
       
   314 (* match_symbs *)
       
   315 
       
   316 (*match with symbs pattern, ignoring spaces, breaks, blocks*)
       
   317 
       
   318 local
       
   319   exception NO_MATCH;
       
   320 
       
   321   fun strip ((sym as Arg _) :: syms) = sym :: strip syms
       
   322     | strip (TypArg p :: syms) = Arg p :: strip syms
       
   323     | strip ((sym as String s) :: syms) =
       
   324         if forall is_blank (explode s) then strip syms
       
   325         else sym :: strip syms
       
   326     | strip (Break _ :: syms) = strip syms
       
   327     | strip (Block (_, bsyms) :: syms) = strip bsyms @ strip syms
       
   328     | strip [] = [];
       
   329 
       
   330   fun match (Arg p :: syms) (Arg p' :: syms') tr =
       
   331         if p = p' then match syms syms' tr
       
   332         else raise NO_MATCH
       
   333     | match (String s :: syms) (String s' :: syms') tr =
       
   334         if s = s' then match syms syms' tr
       
   335         else if size s = 1 then match syms syms' ((s, s') :: tr)
       
   336         else raise NO_MATCH
       
   337     | match [] [] tr = tr
       
   338     | match _ _ _ = raise NO_MATCH;
       
   339 in
       
   340   fun match_symbs (syms, n, p) (syms', n', p') =
       
   341     if n = n' andalso p = p' then
       
   342       match (strip syms) (strip syms') [] handle NO_MATCH => []
       
   343     else []
       
   344 end;
   316 end;
   345 
       
   346 
       
   347 (* chartrans_of *)
       
   348 
       
   349 fun chartrans_of prtabs =
       
   350   let
       
   351     val def_tab = get_tab prtabs "";
       
   352     val sym_tab = get_tab prtabs "symbols";
       
   353 
       
   354     fun trans_of (c, symb) =
       
   355       flat (map (match_symbs symb) (Symtab.lookup_multi (def_tab, c)));
       
   356   in
       
   357     distinct (flat (map trans_of (Symtab.dest_multi sym_tab)))
       
   358 (* FIXME    Symtab.make tr handle Symtab.DUPS cs
       
   359       => error ("Ambiguous printer syntax of symbols: " ^ commas cs)  *)
       
   360   end;
       
   361 
       
   362 
       
   363 end;