src/Pure/Syntax/printer.ML
changeset 2200 2538977e94fa
parent 1509 7f693bb0d7dd
child 2210 8369f3f4bb4f
equal deleted inserted replaced
2199:bcb360f80dac 2200:2538977e94fa
     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   end;
    15   end;
    15 
    16 
    16 signature PRINTER =
    17 signature PRINTER =
    17   sig
    18   sig
    18   include PRINTER0
    19   include PRINTER0
    19   val term_to_ast: (string -> (term list -> term) option) -> term -> Ast.ast
    20   val term_to_ast: (string -> (term list -> term) option) -> term -> Ast.ast
    20   val typ_to_ast: (string -> (term list -> term) option) -> typ -> Ast.ast
    21   val typ_to_ast: (string -> (term list -> term) option) -> typ -> Ast.ast
    21   type prtab
    22   type prtabs
    22   val empty_prtab: prtab
    23   val prmodes_of: prtabs -> string list
    23   val extend_prtab: prtab -> SynExt.xprod list -> prtab
    24   val empty_prtabs: prtabs
    24   val merge_prtabs: prtab -> prtab -> prtab
    25   val extend_prtabs: prtabs -> string -> SynExt.xprod list -> prtabs
    25   val pretty_term_ast: bool -> prtab -> (string -> (Ast.ast list -> Ast.ast) option)
    26   val merge_prtabs: prtabs -> prtabs -> prtabs
    26     -> Ast.ast -> Pretty.T
    27   val pretty_term_ast: bool -> prtabs
    27   val pretty_typ_ast: bool -> prtab -> (string -> (Ast.ast list -> Ast.ast) option)
    28     -> (string -> (Ast.ast list -> Ast.ast) option) -> Ast.ast -> Pretty.T
    28     -> Ast.ast -> Pretty.T
    29   val pretty_typ_ast: bool -> prtabs
       
    30     -> (string -> (Ast.ast list -> Ast.ast) option) -> Ast.ast -> Pretty.T
    29   end;
    31   end;
    30 
    32 
    31 structure Printer : PRINTER =
    33 structure Printer : PRINTER =
    32 struct
    34 struct
       
    35 
    33 open Lexicon Ast SynExt TypeExt SynTrans;
    36 open Lexicon Ast SynExt TypeExt SynTrans;
       
    37 
    34 
    38 
    35 (** options for printing **)
    39 (** options for printing **)
    36 
    40 
    37 val show_types = ref false;
    41 val show_types = ref false;
    38 val show_sorts = ref false;
    42 val show_sorts = ref false;
    39 val show_brackets = ref false;
    43 val show_brackets = ref false;
    40 val show_no_free_types = ref false;
    44 val show_no_free_types = ref false;
       
    45 val print_mode = ref ([]:string list);
    41 
    46 
    42 
    47 
    43 
    48 
    44 (** convert term or typ to ast **)
    49 (** convert term or typ to ast **)
    45 
    50 
   103 
   108 
   104 
   109 
   105 (* term_to_ast *)
   110 (* term_to_ast *)
   106 
   111 
   107 fun term_to_ast trf tm =
   112 fun term_to_ast trf tm =
   108   ast_of_term trf (!show_types orelse !show_sorts) (!show_sorts) tm;
   113   ast_of_term trf (! show_types orelse ! show_sorts) (! show_sorts) tm;
   109 
   114 
   110 
   115 
   111 (* typ_to_ast *)
   116 (* typ_to_ast *)
   112 
   117 
   113 fun typ_to_ast trf ty =
   118 fun typ_to_ast trf ty =
   114   ast_of_term trf false false (term_of_typ (! show_sorts) ty);
   119   ast_of_term trf false false (term_of_typ (! show_sorts) ty);
   115 
   120 
   116 
   121 
   117 
   122 
   118 (** type prtab **)
   123 (** type prtabs **)
   119 
   124 
   120 datatype symb =
   125 datatype symb =
   121   Arg of int |
   126   Arg of int |
   122   TypArg of int |
   127   TypArg of int |
   123   String of string |
   128   String of string |
   124   Break of int |
   129   Break of int |
   125   Block of int * symb list;
   130   Block of int * symb list;
   126 
   131 
   127 type prtab = (symb list * int * int) Symtab.table;
   132 type prtabs = (string * ((symb list * int * int) list) Symtab.table) list;
       
   133 
       
   134 val prmodes_of = filter_out (equal "") o map fst;
       
   135 
       
   136 (*find tab for mode*)
       
   137 fun get_tab prtabs mode =
       
   138   if_none (assoc (prtabs, mode)) Symtab.null;
       
   139 
       
   140 (*collect tabs for mode hierarchy (default "")*)
       
   141 fun tabs_of prtabs modes =
       
   142   mapfilter (fn mode => assoc (prtabs, mode)) (modes @ [""]);
       
   143 
       
   144 (*find formats in tab hierarchy*)
       
   145 fun get_fmts [] _ = []
       
   146   | get_fmts (tab :: tabs) a = Symtab.lookup_multi (tab, a) @ get_fmts tabs a;
   128 
   147 
   129 
   148 
   130 (* xprods_to_fmts *)
   149 (* xprods_to_fmts *)
   131 
   150 
   132 fun xprod_to_fmt (XProd (_, _, "", _)) = None
   151 fun xprod_to_fmt (XProd (_, _, "", _)) = None
   167         (case xsyms_to_syms xsymbs of
   186         (case xsyms_to_syms xsymbs of
   168           (symbs, []) => Some (const, (symbs, nargs symbs, pri))
   187           (symbs, []) => Some (const, (symbs, nargs symbs, pri))
   169         | _ => sys_error "xprod_to_fmt: unbalanced blocks")
   188         | _ => sys_error "xprod_to_fmt: unbalanced blocks")
   170       end;
   189       end;
   171 
   190 
   172 fun xprods_to_fmts xprods =
   191 fun xprods_to_fmts xprods = mapfilter xprod_to_fmt xprods;
   173   gen_distinct eq_fst (mapfilter xprod_to_fmt xprods);
       
   174 
   192 
   175 
   193 
   176 (* empty, extend, merge prtabs *)
   194 (* empty, extend, merge prtabs *)
   177 
   195 
   178 fun err_dup_fmts cs =
   196 val empty_prtabs = [];
   179   error ("Duplicate formats in printer table for " ^ commas_quote cs);
   197 
   180 
   198 fun extend_prtabs prtabs mode xprods =
   181 val empty_prtab = Symtab.null;
   199   let
   182 
   200     val fmts = xprods_to_fmts xprods;
   183 fun extend_prtab tab xprods =
   201     val tab = get_tab prtabs mode;
   184   Symtab.extend (op =) (tab, xprods_to_fmts xprods)
   202     val new_tab = generic_extend (op =) Symtab.dest_multi Symtab.make_multi tab fmts;
   185     handle Symtab.DUPS cs => err_dup_fmts cs;
   203   in overwrite (prtabs, (mode, new_tab)) end;
   186 
   204 
   187 fun merge_prtabs tab1 tab2 =
   205 fun merge_prtabs prtabs1 prtabs2 =
   188   Symtab.merge (op =) (tab1, tab2)
   206   let
   189     handle Symtab.DUPS cs => err_dup_fmts cs;
   207     val modes = distinct (map fst (prtabs1 @ prtabs2));
       
   208     fun merge mode =
       
   209       (mode,
       
   210         generic_merge (op =) Symtab.dest_multi Symtab.make_multi
       
   211           (get_tab prtabs1 mode) (get_tab prtabs2 mode));
       
   212   in
       
   213     map merge modes
       
   214   end;
   190 
   215 
   191 
   216 
   192 
   217 
   193 (** pretty term or typ asts **)
   218 (** pretty term or typ asts **)
   194 
   219 
   195 fun chain [Block (_, pr)] = chain pr
   220 fun is_chain [Block (_, pr)] = is_chain pr
   196   | chain [Arg _] = true
   221   | is_chain [Arg _] = true
   197   | chain _  = false;
   222   | is_chain _  = false;
   198 
   223 
   199 fun pretty prtab trf type_mode curried ast0 p0 =
   224 fun pretty tabs trf type_mode curried ast0 p0 =
   200   let
   225   let
   201     val trans = apply_trans "print ast translation";
   226     val trans = apply_trans "print ast translation";
   202 
   227 
   203     val appT = if type_mode then tappl_ast_tr' else
   228     (*default applications: prefix / postfix*)
   204                if curried then applC_ast_tr' else appl_ast_tr';
   229     val appT =
       
   230       if type_mode then tappl_ast_tr'
       
   231       else if curried then applC_ast_tr'
       
   232       else appl_ast_tr';
   205 
   233 
   206     fun synT ([], args) = ([], args)
   234     fun synT ([], args) = ([], args)
   207       | synT (Arg p :: symbs, t :: args) =
   235       | synT (Arg p :: symbs, t :: args) =
   208           let val (Ts, args') = synT (symbs, args);
   236           let val (Ts, args') = synT (symbs, args);
   209           in (astT (t, p) @ Ts, args') end
   237           in (astT (t, p) @ Ts, args') end
   210       | synT (TypArg p :: symbs, t :: args) =
   238       | synT (TypArg p :: symbs, t :: args) =
   211           let
   239           let
   212             val (Ts, args') = synT (symbs, args);
   240             val (Ts, args') = synT (symbs, args);
   213           in
   241           in
   214             if type_mode then (astT (t, p) @ Ts, args')
   242             if type_mode then (astT (t, p) @ Ts, args')
   215             else (pretty prtab trf true curried t p @ Ts, args')
   243             else (pretty tabs trf true curried t p @ Ts, args')
   216           end
   244           end
   217       | synT (String s :: symbs, args) =
   245       | synT (String s :: symbs, args) =
   218           let val (Ts, args') = synT (symbs, args);
   246           let val (Ts, args') = synT (symbs, args);
   219           in (Pretty.str s :: Ts, args') end
   247           in (Pretty.str s :: Ts, args') end
   220       | synT (Block (i, bsymbs) :: symbs, args) =
   248       | synT (Block (i, bsymbs) :: symbs, args) =
   227           in ((if i < 0 then Pretty.fbrk else Pretty.brk i) :: Ts, args') end
   255           in ((if i < 0 then Pretty.fbrk else Pretty.brk i) :: Ts, args') end
   228       | synT (_ :: _, []) = sys_error "synT"
   256       | synT (_ :: _, []) = sys_error "synT"
   229 
   257 
   230     and parT (pr, args, p, p': int) = #1 (synT
   258     and parT (pr, args, p, p': int) = #1 (synT
   231           (if p > p' orelse
   259           (if p > p' orelse
   232             (! show_brackets andalso p' <> max_pri andalso not (chain pr))
   260             (! show_brackets andalso p' <> max_pri andalso not (is_chain pr))
   233             then [Block (1, String "(" :: pr @ [String ")"])]
   261             then [Block (1, String "(" :: pr @ [String ")"])]
   234             else pr, args))
   262             else pr, args))
   235 
   263 
   236     and prefixT (_, a, [], _) = [Pretty.str a]
   264     and prefixT (_, a, [], _) = [Pretty.str a]
   237       | prefixT (c, _, args, p) = astT (appT (c, args), p)
   265       | prefixT (c, _, args, p) = astT (appT (c, args), p)
   239     and splitT 0 ([x], ys) = (x, ys)
   267     and splitT 0 ([x], ys) = (x, ys)
   240       | splitT 0 (rev_xs, ys) = (Appl (rev rev_xs), ys)
   268       | splitT 0 (rev_xs, ys) = (Appl (rev rev_xs), ys)
   241       | splitT n (rev_xs, y :: ys) = splitT (n - 1) (y :: rev_xs, ys)
   269       | splitT n (rev_xs, y :: ys) = splitT (n - 1) (y :: rev_xs, ys)
   242       | splitT _ _ = sys_error "splitT"
   270       | splitT _ _ = sys_error "splitT"
   243 
   271 
       
   272     and combT (tup as (c, a, args, p)) =
       
   273       let
       
   274         val nargs = length args;
       
   275 
       
   276         (*find matching table entry, or print as prefix/postfix*)
       
   277         fun prnt [] = prefixT tup
       
   278           | prnt ((pr, n, p') :: prnps) =
       
   279               if nargs = n then parT (pr, args, p, p')
       
   280               else if nargs > n andalso not type_mode then
       
   281                 astT (appT (splitT n ([c], args)), p)
       
   282               else prnt prnps;
       
   283       in
       
   284         (*try translation function first*)
       
   285         (case trf a of
       
   286           None => prnt (get_fmts tabs a)
       
   287         | Some f => (astT (trans a f args, p) handle Match => prnt (get_fmts tabs a)))
       
   288       end
       
   289 
       
   290 (* FIXME old
   244     and combT (tup as (c, a, args, p)) =
   291     and combT (tup as (c, a, args, p)) =
   245       let
   292       let
   246         val nargs = length args;
   293         val nargs = length args;
   247 
   294 
   248         fun prnt (pr, n, p') =
   295         fun prnt (pr, n, p') =
   249           if nargs = n then parT (pr, args, p, p')
   296           if nargs = n then parT (pr, args, p, p')
   250           else if nargs < n orelse type_mode then prefixT tup
   297           else if nargs < n orelse type_mode then prefixT tup
   251           else astT (appT (splitT n ([c], args)), p);
   298           else astT (appT (splitT n ([c], args)), p);
   252       in
   299       in
   253         (case (trf a, Symtab.lookup (prtab, a)) of
   300         (case (trf a, get_fmt tabs a) of
   254           (None, None) => prefixT tup
   301           (None, None) => prefixT tup
   255         | (None, Some prnp) => prnt prnp
   302         | (None, Some prnp) => prnt prnp
   256         | (Some f, None) =>
   303         | (Some f, None) =>
   257             (astT (trans a f args, p) handle Match => prefixT tup)
   304             (astT (trans a f args, p) handle Match => prefixT tup)
   258         | (Some f, Some prnp) =>
   305         | (Some f, Some prnp) =>
   259             (astT (trans a f args, p) handle Match => prnt prnp))
   306             (astT (trans a f args, p) handle Match => prnt prnp))
   260       end
   307       end
       
   308 *)
   261 
   309 
   262     and astT (c as Constant a, p) = combT (c, a, [], p)
   310     and astT (c as Constant a, p) = combT (c, a, [], p)
   263       | astT (Variable x, _) = [Pretty.str x]
   311       | astT (Variable x, _) = [Pretty.str x]
   264       | astT (Appl ((c as Constant a) :: (args as _ :: _)), p) =
   312       | astT (Appl ((c as Constant a) :: (args as _ :: _)), p) =
   265           combT (c, a, args, p)
   313           combT (c, a, args, p)
   270   end;
   318   end;
   271 
   319 
   272 
   320 
   273 (* pretty_term_ast *)
   321 (* pretty_term_ast *)
   274 
   322 
   275 fun pretty_term_ast curried prtab trf ast =
   323 fun pretty_term_ast curried prtabs trf ast =
   276   Pretty.blk (0, pretty prtab trf false curried ast 0);
   324   Pretty.blk (0, pretty (tabs_of prtabs (! print_mode)) trf false curried ast 0);
   277 
   325 
   278 
   326 
   279 (* pretty_typ_ast *)
   327 (* pretty_typ_ast *)
   280 
   328 
   281 fun pretty_typ_ast _ prtab trf ast =
   329 fun pretty_typ_ast _ prtabs trf ast =
   282   Pretty.blk (0, pretty prtab trf true false ast 0);
   330   Pretty.blk (0, pretty (tabs_of prtabs (! print_mode)) trf true false ast 0);
   283 
   331 
   284 
   332 
   285 end;
   333 end;
   286