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) |