| author | wenzelm | 
| Sun, 27 Oct 2024 12:54:58 +0100 | |
| changeset 81277 | 0eb96012d416 | 
| parent 81225 | 2157039256d3 | 
| child 81507 | 08574da77b4a | 
| permissions | -rw-r--r-- | 
| 42288 
2074b31650e6
discontinued special treatment of structure Syntax_Ext (formerly Syn_Ext);
 wenzelm parents: 
42268diff
changeset | 1 | (* Title: Pure/Syntax/syntax_ext.ML | 
| 80893 | 2 | Author: Makarius | 
| 240 | 3 | |
| 80893 | 4 | Syntax extension as internal record. | 
| 240 | 5 | *) | 
| 6 | ||
| 42288 
2074b31650e6
discontinued special treatment of structure Syntax_Ext (formerly Syn_Ext);
 wenzelm parents: 
42268diff
changeset | 7 | signature SYNTAX_EXT = | 
| 4050 | 8 | sig | 
| 62753 | 9 | datatype mfix = Mfix of Symbol_Pos.T list * typ * string * int list * int * Position.T | 
| 81121 
7cacedbddba7
support for pretty blocks that are "open" and thus have no impact on formatting, only on markup;
 wenzelm parents: 
80922diff
changeset | 10 | type block = | 
| 
7cacedbddba7
support for pretty blocks that are "open" and thus have no impact on formatting, only on markup;
 wenzelm parents: 
80922diff
changeset | 11 |     {markup: Markup.T list, open_block: bool, consistent: bool, unbreakable: bool, indent: int}
 | 
| 80893 | 12 | val block_indent: int -> block | 
| 81159 | 13 | val pretty_block: block -> Pretty.T list -> Pretty.T | 
| 1510 | 14 | datatype xsymb = | 
| 15 | Delim of string | | |
| 16 | Argument of string * int | | |
| 17 | Space of string | | |
| 80893 | 18 | Bg of block | | 
| 62783 | 19 | Brk of int | | 
| 20 | En | |
| 1510 | 21 | datatype xprod = XProd of string * xsymb list * string * int | 
| 22 | val chain_pri: int | |
| 77999 | 23 | val delims_of: xprod list -> Symbol.symbol list list | 
| 1510 | 24 | datatype syn_ext = | 
| 37216 
3165bc303f66
modernized some structure names, keeping a few legacy aliases;
 wenzelm parents: 
35429diff
changeset | 25 |     Syn_Ext of {
 | 
| 1510 | 26 | xprods: xprod list, | 
| 80748 
43c4817375bf
support for syntax const dependencies, with minimal integrity checks;
 wenzelm parents: 
77999diff
changeset | 27 | consts: (string * string list) list, | 
| 21772 | 28 | parse_ast_translation: (string * ((Proof.context -> Ast.ast list -> Ast.ast) * stamp)) list, | 
| 1510 | 29 | parse_rules: (Ast.ast * Ast.ast) list, | 
| 21772 | 30 | parse_translation: (string * ((Proof.context -> term list -> term) * stamp)) list, | 
| 42247 
12fe41a92cd5
typed_print_translation: discontinued show_sorts argument;
 wenzelm parents: 
42245diff
changeset | 31 | print_translation: (string * ((Proof.context -> typ -> term list -> term) * stamp)) list, | 
| 1510 | 32 | print_rules: (Ast.ast * Ast.ast) list, | 
| 42268 | 33 | print_ast_translation: (string * ((Proof.context -> Ast.ast list -> Ast.ast) * stamp)) list} | 
| 80920 
bbe2c56fe255
more uniform treatment of Markup.notation and Markup.expression: manage kinds via context;
 wenzelm parents: 
80919diff
changeset | 34 | val block_annotation: int -> Markup.T -> string -> string | 
| 80911 
8ad5e6df050b
block markup for specific notation, notably infix and binder;
 wenzelm parents: 
80909diff
changeset | 35 | val mfix_name: Proof.context -> Symbol_Pos.T list -> string | 
| 80897 
5328d67ec647
more explicit context for syn_ext/mixfix operations, but it often degenerates to background theory;
 wenzelm parents: 
80895diff
changeset | 36 | val mfix_args: Proof.context -> Symbol_Pos.T list -> int | 
| 
5328d67ec647
more explicit context for syn_ext/mixfix operations, but it often degenerates to background theory;
 wenzelm parents: 
80895diff
changeset | 37 | val mixfix_args: Proof.context -> Input.source -> int | 
| 42288 
2074b31650e6
discontinued special treatment of structure Syntax_Ext (formerly Syn_Ext);
 wenzelm parents: 
42268diff
changeset | 38 | val escape: string -> string | 
| 80897 
5328d67ec647
more explicit context for syn_ext/mixfix operations, but it often degenerates to background theory;
 wenzelm parents: 
80895diff
changeset | 39 | val syn_ext: Proof.context -> string list -> mfix list -> | 
| 80748 
43c4817375bf
support for syntax const dependencies, with minimal integrity checks;
 wenzelm parents: 
77999diff
changeset | 40 | (string * string list) list -> (string * ((Proof.context -> Ast.ast list -> Ast.ast) * stamp)) list * | 
| 21772 | 41 | (string * ((Proof.context -> term list -> term) * stamp)) list * | 
| 42247 
12fe41a92cd5
typed_print_translation: discontinued show_sorts argument;
 wenzelm parents: 
42245diff
changeset | 42 | (string * ((Proof.context -> typ -> term list -> term) * stamp)) list * | 
| 42268 | 43 | (string * ((Proof.context -> Ast.ast list -> Ast.ast) * stamp)) list -> | 
| 44 | (Ast.ast * Ast.ast) list * (Ast.ast * Ast.ast) list -> syn_ext | |
| 80897 
5328d67ec647
more explicit context for syn_ext/mixfix operations, but it often degenerates to background theory;
 wenzelm parents: 
80895diff
changeset | 45 | val syn_ext_consts: Proof.context -> (string * string list) list -> syn_ext | 
| 
5328d67ec647
more explicit context for syn_ext/mixfix operations, but it often degenerates to background theory;
 wenzelm parents: 
80895diff
changeset | 46 | val syn_ext_rules: Proof.context -> (Ast.ast * Ast.ast) list * (Ast.ast * Ast.ast) list -> syn_ext | 
| 
5328d67ec647
more explicit context for syn_ext/mixfix operations, but it often degenerates to background theory;
 wenzelm parents: 
80895diff
changeset | 47 | val syn_ext_trfuns: Proof.context -> | 
| 21772 | 48 | (string * ((Proof.context -> Ast.ast list -> Ast.ast) * stamp)) list * | 
| 49 | (string * ((Proof.context -> term list -> term) * stamp)) list * | |
| 42247 
12fe41a92cd5
typed_print_translation: discontinued show_sorts argument;
 wenzelm parents: 
42245diff
changeset | 50 | (string * ((Proof.context -> typ -> term list -> term) * stamp)) list * | 
| 21772 | 51 | (string * ((Proof.context -> Ast.ast list -> Ast.ast) * stamp)) list -> syn_ext | 
| 42288 
2074b31650e6
discontinued special treatment of structure Syntax_Ext (formerly Syn_Ext);
 wenzelm parents: 
42268diff
changeset | 52 |   val stamp_trfun: stamp -> string * 'a -> string * ('a * stamp)
 | 
| 
2074b31650e6
discontinued special treatment of structure Syntax_Ext (formerly Syn_Ext);
 wenzelm parents: 
42268diff
changeset | 53 |   val mk_trfun: string * 'a -> string * ('a * stamp)
 | 
| 
2074b31650e6
discontinued special treatment of structure Syntax_Ext (formerly Syn_Ext);
 wenzelm parents: 
42268diff
changeset | 54 |   val eq_trfun: ('a * stamp) * ('a * stamp) -> bool
 | 
| 4050 | 55 | end; | 
| 240 | 56 | |
| 42288 
2074b31650e6
discontinued special treatment of structure Syntax_Ext (formerly Syn_Ext);
 wenzelm parents: 
42268diff
changeset | 57 | structure Syntax_Ext: SYNTAX_EXT = | 
| 240 | 58 | struct | 
| 59 | ||
| 60 | (** datatype xprod **) | |
| 61 | ||
| 62 | (*Delim s: delimiter s | |
| 63 | Argument (s, p): nonterminal s requiring priority >= p, or valued token | |
| 64 | Space s: some white space for printing | |
| 65 | Bg, Brk, En: blocks and breaks for pretty printing*) | |
| 66 | ||
| 81121 
7cacedbddba7
support for pretty blocks that are "open" and thus have no impact on formatting, only on markup;
 wenzelm parents: 
80922diff
changeset | 67 | type block = | 
| 
7cacedbddba7
support for pretty blocks that are "open" and thus have no impact on formatting, only on markup;
 wenzelm parents: 
80922diff
changeset | 68 |   {markup: Markup.T list, open_block: bool, consistent: bool, unbreakable: bool, indent: int};
 | 
| 62789 | 69 | |
| 80893 | 70 | fun block_indent indent : block = | 
| 81121 
7cacedbddba7
support for pretty blocks that are "open" and thus have no impact on formatting, only on markup;
 wenzelm parents: 
80922diff
changeset | 71 |   {markup = [], open_block = false, consistent = false, unbreakable = false, indent = indent};
 | 
| 62783 | 72 | |
| 81159 | 73 | fun pretty_block {markup, open_block, consistent, indent, unbreakable} body =
 | 
| 74 | Pretty.markup_blocks | |
| 75 |     {markup = markup, open_block = open_block, consistent = consistent, indent = indent} body
 | |
| 76 | |> unbreakable ? Pretty.unbreakable; | |
| 77 | ||
| 240 | 78 | datatype xsymb = | 
| 79 | Delim of string | | |
| 80 | Argument of string * int | | |
| 81 | Space of string | | |
| 80893 | 82 | Bg of block | | 
| 62783 | 83 | Brk of int | | 
| 84 | En; | |
| 240 | 85 | |
| 12513 
0ffb824dc95c
support for ``indexed syntax'' (using "\<index>" argument instead of "_");
 wenzelm parents: 
11546diff
changeset | 86 | fun is_delim (Delim _) = true | 
| 
0ffb824dc95c
support for ``indexed syntax'' (using "\<index>" argument instead of "_");
 wenzelm parents: 
11546diff
changeset | 87 | | is_delim _ = false; | 
| 
0ffb824dc95c
support for ``indexed syntax'' (using "\<index>" argument instead of "_");
 wenzelm parents: 
11546diff
changeset | 88 | |
| 
0ffb824dc95c
support for ``indexed syntax'' (using "\<index>" argument instead of "_");
 wenzelm parents: 
11546diff
changeset | 89 | fun is_terminal (Delim _) = true | 
| 
0ffb824dc95c
support for ``indexed syntax'' (using "\<index>" argument instead of "_");
 wenzelm parents: 
11546diff
changeset | 90 | | is_terminal (Argument (s, _)) = Lexicon.is_terminal s | 
| 
0ffb824dc95c
support for ``indexed syntax'' (using "\<index>" argument instead of "_");
 wenzelm parents: 
11546diff
changeset | 91 | | is_terminal _ = false; | 
| 
0ffb824dc95c
support for ``indexed syntax'' (using "\<index>" argument instead of "_");
 wenzelm parents: 
11546diff
changeset | 92 | |
| 
0ffb824dc95c
support for ``indexed syntax'' (using "\<index>" argument instead of "_");
 wenzelm parents: 
11546diff
changeset | 93 | fun is_argument (Argument _) = true | 
| 
0ffb824dc95c
support for ``indexed syntax'' (using "\<index>" argument instead of "_");
 wenzelm parents: 
11546diff
changeset | 94 | | is_argument _ = false; | 
| 
0ffb824dc95c
support for ``indexed syntax'' (using "\<index>" argument instead of "_");
 wenzelm parents: 
11546diff
changeset | 95 | |
| 
0ffb824dc95c
support for ``indexed syntax'' (using "\<index>" argument instead of "_");
 wenzelm parents: 
11546diff
changeset | 96 | fun is_index (Argument ("index", _)) = true
 | 
| 
0ffb824dc95c
support for ``indexed syntax'' (using "\<index>" argument instead of "_");
 wenzelm parents: 
11546diff
changeset | 97 | | is_index _ = false; | 
| 
0ffb824dc95c
support for ``indexed syntax'' (using "\<index>" argument instead of "_");
 wenzelm parents: 
11546diff
changeset | 98 | |
| 
0ffb824dc95c
support for ``indexed syntax'' (using "\<index>" argument instead of "_");
 wenzelm parents: 
11546diff
changeset | 99 | val index = Argument ("index", 1000);
 | 
| 
0ffb824dc95c
support for ``indexed syntax'' (using "\<index>" argument instead of "_");
 wenzelm parents: 
11546diff
changeset | 100 | |
| 240 | 101 | |
| 102 | (*XProd (lhs, syms, c, p): | |
| 103 | lhs: name of nonterminal on the lhs of the production | |
| 104 | syms: list of symbols on the rhs of the production | |
| 105 | c: head of parse tree | |
| 106 | p: priority of this production*) | |
| 107 | ||
| 108 | datatype xprod = XProd of string * xsymb list * string * int; | |
| 109 | ||
| 110 | val chain_pri = ~1; (*dummy for chain productions*) | |
| 111 | ||
| 112 | fun delims_of xprods = | |
| 19004 | 113 | fold (fn XProd (_, xsymbs, _, _) => | 
| 114 | fold (fn Delim s => insert (op =) s | _ => I) xsymbs) xprods [] | |
| 115 | |> map Symbol.explode; | |
| 240 | 116 | |
| 117 | ||
| 118 | ||
| 119 | (** datatype mfix **) | |
| 120 | ||
| 62753 | 121 | (*Mfix (sy, ty, c, ps, p, pos): | 
| 62752 | 122 | sy: rhs of production as symbolic text | 
| 240 | 123 | ty: type description of production | 
| 124 | c: head of parse tree | |
| 125 | ps: priorities of arguments in sy | |
| 62753 | 126 | p: priority of production | 
| 127 | pos: source position*) | |
| 240 | 128 | |
| 62753 | 129 | datatype mfix = Mfix of Symbol_Pos.T list * typ * string * int list * int * Position.T; | 
| 12513 
0ffb824dc95c
support for ``indexed syntax'' (using "\<index>" argument instead of "_");
 wenzelm parents: 
11546diff
changeset | 130 | |
| 240 | 131 | |
| 62786 | 132 | (* properties *) | 
| 133 | ||
| 80920 
bbe2c56fe255
more uniform treatment of Markup.notation and Markup.expression: manage kinds via context;
 wenzelm parents: 
80919diff
changeset | 134 | fun block_annotation indent notation_markup notation_name = | 
| 
bbe2c56fe255
more uniform treatment of Markup.notation and Markup.expression: manage kinds via context;
 wenzelm parents: 
80919diff
changeset | 135 | let | 
| 
bbe2c56fe255
more uniform treatment of Markup.notation and Markup.expression: manage kinds via context;
 wenzelm parents: 
80919diff
changeset | 136 | val (elem, props) = notation_markup |> notation_name <> "" ? Markup.name notation_name; | 
| 
bbe2c56fe255
more uniform treatment of Markup.notation and Markup.expression: manage kinds via context;
 wenzelm parents: 
80919diff
changeset | 137 | val kind = Properties.get props Markup.kindN; | 
| 
bbe2c56fe255
more uniform treatment of Markup.notation and Markup.expression: manage kinds via context;
 wenzelm parents: 
80919diff
changeset | 138 | val name = Properties.get props Markup.nameN; | 
| 
bbe2c56fe255
more uniform treatment of Markup.notation and Markup.expression: manage kinds via context;
 wenzelm parents: 
80919diff
changeset | 139 | val s1 = if indent = 0 then [] else ["indent=" ^ Value.print_int indent]; | 
| 
bbe2c56fe255
more uniform treatment of Markup.notation and Markup.expression: manage kinds via context;
 wenzelm parents: 
80919diff
changeset | 140 | val s2 = | 
| 
bbe2c56fe255
more uniform treatment of Markup.notation and Markup.expression: manage kinds via context;
 wenzelm parents: 
80919diff
changeset | 141 | if elem = Markup.notationN then | 
| 
bbe2c56fe255
more uniform treatment of Markup.notation and Markup.expression: manage kinds via context;
 wenzelm parents: 
80919diff
changeset | 142 | [Properties.print_eq (elem, cartouche (implode_space (the_list kind @ the_list name)))] | 
| 
bbe2c56fe255
more uniform treatment of Markup.notation and Markup.expression: manage kinds via context;
 wenzelm parents: 
80919diff
changeset | 143 |       else raise Fail ("Bad markup element for notatio: " ^ quote elem)
 | 
| 
bbe2c56fe255
more uniform treatment of Markup.notation and Markup.expression: manage kinds via context;
 wenzelm parents: 
80919diff
changeset | 144 | in cartouche (implode_space (s1 @ s2)) end; | 
| 80911 
8ad5e6df050b
block markup for specific notation, notably infix and binder;
 wenzelm parents: 
80909diff
changeset | 145 | |
| 80904 | 146 | fun show_names names = | 
| 147 | commas_quote (map (fn (name, pos) => Markup.markup (Position.markup pos) name) names); | |
| 148 | ||
| 62786 | 149 | local | 
| 150 | ||
| 151 | open Basic_Symbol_Pos; | |
| 152 | ||
| 153 | val err_prefix = "Error in mixfix block properties: "; | |
| 62801 
f9d102ef13f1
clarified errors -- disallow cartouche fragments as delimiter;
 wenzelm parents: 
62795diff
changeset | 154 | val !!! = Symbol_Pos.!!! (fn () => err_prefix ^ "atom expected (identifier, numeral, cartouche)"); | 
| 62786 | 155 | |
| 156 | val scan_atom = | |
| 157 | Symbol_Pos.scan_ident || | |
| 158 | ($$$ "-" @@@ (Symbol_Pos.scan_float || Symbol_Pos.scan_nat)) || | |
| 159 | Symbol_Pos.scan_float || Symbol_Pos.scan_nat || | |
| 160 | Symbol_Pos.scan_cartouche_content err_prefix; | |
| 161 | ||
| 162 | val scan_blanks = Scan.many (Symbol.is_blank o Symbol_Pos.symbol); | |
| 163 | val scan_item = | |
| 164 | scan_blanks |-- scan_atom --| scan_blanks | |
| 165 | >> (fn ss => (Symbol_Pos.content ss, #1 (Symbol_Pos.range ss))); | |
| 166 | ||
| 80904 | 167 | val scan_prop = scan_item -- Scan.option ($$ "=" |-- !!! scan_item); | 
| 62786 | 168 | |
| 80904 | 169 | fun get_property default0 default1 parse name props = | 
| 170 | (case find_first (fn ((a, _), _) => a = name) props of | |
| 171 | NONE => default0 | |
| 172 | | SOME (_, NONE) => default1 | |
| 173 | | SOME ((_, pos1), SOME (b, pos2)) => | |
| 174 | (parse (b, pos2) handle Fail msg => | |
| 175 | error (msg ^ " for property " ^ quote name ^ Position.here_list [pos1, pos2]))); | |
| 62786 | 176 | |
| 80920 
bbe2c56fe255
more uniform treatment of Markup.notation and Markup.expression: manage kinds via context;
 wenzelm parents: 
80919diff
changeset | 177 | fun parse_notation ctxt (s, pos) = | 
| 80911 
8ad5e6df050b
block markup for specific notation, notably infix and binder;
 wenzelm parents: 
80909diff
changeset | 178 | let | 
| 
8ad5e6df050b
block markup for specific notation, notably infix and binder;
 wenzelm parents: 
80909diff
changeset | 179 | val (kind, name) = | 
| 
8ad5e6df050b
block markup for specific notation, notably infix and binder;
 wenzelm parents: 
80909diff
changeset | 180 | (case Symbol.explode_words s of | 
| 
8ad5e6df050b
block markup for specific notation, notably infix and binder;
 wenzelm parents: 
80909diff
changeset | 181 |         [] => ("", "")
 | 
| 
8ad5e6df050b
block markup for specific notation, notably infix and binder;
 wenzelm parents: 
80909diff
changeset | 182 | | a :: bs => (a, space_implode " " bs)); | 
| 80920 
bbe2c56fe255
more uniform treatment of Markup.notation and Markup.expression: manage kinds via context;
 wenzelm parents: 
80919diff
changeset | 183 | val markup = | 
| 
bbe2c56fe255
more uniform treatment of Markup.notation and Markup.expression: manage kinds via context;
 wenzelm parents: 
80919diff
changeset | 184 | (case try (fn () => Markup_Kind.check_notation ctxt (kind, Position.none)) () of | 
| 
bbe2c56fe255
more uniform treatment of Markup.notation and Markup.expression: manage kinds via context;
 wenzelm parents: 
80919diff
changeset | 185 | SOME m => m | 
| 
bbe2c56fe255
more uniform treatment of Markup.notation and Markup.expression: manage kinds via context;
 wenzelm parents: 
80919diff
changeset | 186 | | NONE => | 
| 
bbe2c56fe255
more uniform treatment of Markup.notation and Markup.expression: manage kinds via context;
 wenzelm parents: 
80919diff
changeset | 187 |           error ("Bad notation kind " ^ quote kind ^ Position.here pos ^
 | 
| 
bbe2c56fe255
more uniform treatment of Markup.notation and Markup.expression: manage kinds via context;
 wenzelm parents: 
80919diff
changeset | 188 | ", expected: " ^ commas_quote (Markup_Kind.get_notation_kinds ctxt))); | 
| 
bbe2c56fe255
more uniform treatment of Markup.notation and Markup.expression: manage kinds via context;
 wenzelm parents: 
80919diff
changeset | 189 | in markup |> Markup.properties (Markup.name_proper name) end; | 
| 80911 
8ad5e6df050b
block markup for specific notation, notably infix and binder;
 wenzelm parents: 
80909diff
changeset | 190 | |
| 62786 | 191 | in | 
| 192 | ||
| 193 | fun read_properties ss = | |
| 194 | let | |
| 62801 
f9d102ef13f1
clarified errors -- disallow cartouche fragments as delimiter;
 wenzelm parents: 
62795diff
changeset | 195 | val props = | 
| 
f9d102ef13f1
clarified errors -- disallow cartouche fragments as delimiter;
 wenzelm parents: 
62795diff
changeset | 196 | (case Scan.error (Scan.finite Symbol_Pos.stopper (Scan.repeat scan_prop)) ss of | 
| 
f9d102ef13f1
clarified errors -- disallow cartouche fragments as delimiter;
 wenzelm parents: 
62795diff
changeset | 197 | (props, []) => props | 
| 
f9d102ef13f1
clarified errors -- disallow cartouche fragments as delimiter;
 wenzelm parents: 
62795diff
changeset | 198 | | (_, (_, pos) :: _) => error (err_prefix ^ "bad input" ^ Position.here pos)); | 
| 80904 | 199 | fun ok (_, bs) = length bs <= 1; | 
| 62786 | 200 | val _ = | 
| 80904 | 201 | (case AList.group (eq_fst op =) props |> filter_out ok of | 
| 62786 | 202 | [] => () | 
| 80904 | 203 |       | dups => error ("Duplicate properties: " ^ show_names (map #1 dups)));
 | 
| 62786 | 204 | in props end; | 
| 205 | ||
| 80904 | 206 | val get_string = get_property "" "" #1; | 
| 207 | val get_bool = get_property false true (Value.parse_bool o #1); | |
| 208 | val get_nat = get_property 0 1 (Value.parse_nat o #1); | |
| 62786 | 209 | |
| 80920 
bbe2c56fe255
more uniform treatment of Markup.notation and Markup.expression: manage kinds via context;
 wenzelm parents: 
80919diff
changeset | 210 | fun get_notation_markup ctxt = | 
| 
bbe2c56fe255
more uniform treatment of Markup.notation and Markup.expression: manage kinds via context;
 wenzelm parents: 
80919diff
changeset | 211 | get_property NONE (SOME Markup.notation0) (SOME o parse_notation ctxt) Markup.notationN; | 
| 80911 
8ad5e6df050b
block markup for specific notation, notably infix and binder;
 wenzelm parents: 
80909diff
changeset | 212 | |
| 62786 | 213 | end; | 
| 214 | ||
| 215 | ||
| 19004 | 216 | (* read mixfix annotations *) | 
| 4050 | 217 | |
| 218 | local | |
| 19004 | 219 | |
| 80919 | 220 | val markup_block_begin = Markup_Kind.setup_expression (Binding.make ("mixfix_block_begin", \<^here>));
 | 
| 221 | val markup_block_end = Markup_Kind.setup_expression (Binding.make ("mixfix_block_end", \<^here>));
 | |
| 222 | val markup_delimiter = Markup_Kind.setup_expression (Binding.make ("mixfix_delimiter", \<^here>));
 | |
| 223 | val markup_argument = Markup_Kind.setup_expression (Binding.make ("mixfix_argument", \<^here>));
 | |
| 224 | val markup_space = Markup_Kind.setup_expression (Binding.make ("mixfix_space", \<^here>));
 | |
| 225 | val markup_break = Markup_Kind.setup_expression (Binding.make ("mixfix_break", \<^here>));
 | |
| 80889 | 226 | |
| 62752 | 227 | open Basic_Symbol_Pos; | 
| 228 | ||
| 62801 
f9d102ef13f1
clarified errors -- disallow cartouche fragments as delimiter;
 wenzelm parents: 
62795diff
changeset | 229 | val err_prefix = "Error in mixfix annotation: "; | 
| 
f9d102ef13f1
clarified errors -- disallow cartouche fragments as delimiter;
 wenzelm parents: 
62795diff
changeset | 230 | |
| 62752 | 231 | fun scan_one pred = Scan.one (pred o Symbol_Pos.symbol); | 
| 232 | fun scan_many pred = Scan.many (pred o Symbol_Pos.symbol); | |
| 233 | fun scan_many1 pred = Scan.many1 (pred o Symbol_Pos.symbol); | |
| 234 | ||
| 80889 | 235 | fun reports_of_block pos = [(pos, markup_block_begin), (pos, Markup.keyword3)]; | 
| 62806 | 236 | |
| 62808 | 237 | fun reports_of (xsym, pos) = | 
| 62806 | 238 | (case xsym of | 
| 80889 | 239 | Delim _ => [(pos, markup_delimiter), (pos, Markup.literal)] | 
| 240 | | Argument _ => [(pos, markup_argument)] | |
| 241 | | Space _ => [(pos, markup_space)] | |
| 62806 | 242 | | Bg _ => reports_of_block pos | 
| 80889 | 243 | | Brk _ => [(pos, markup_break), (pos, Markup.keyword3)] | 
| 244 | | En => [(pos, markup_block_end), (pos, Markup.keyword3)]); | |
| 62806 | 245 | |
| 80891 | 246 | fun reports_text_of (Delim s, pos) = | 
| 62808 | 247 | if Position.is_reported pos andalso exists Symbol.is_utf8 (Symbol.explode s) then | 
| 64677 
8dc24130e8fe
more uniform treatment of "bad" like other messages (with serial number);
 wenzelm parents: 
63933diff
changeset | 248 | [((pos, Markup.bad ()), | 
| 62808 | 249 | "Mixfix delimiter contains raw Unicode -- this is non-portable and unreliable")] | 
| 250 | else [] | |
| 80891 | 251 | | reports_text_of _ = []; | 
| 62808 | 252 | |
| 80905 
47793a46d06c
support for Markup.expression properties in pretty-blocks;
 wenzelm parents: 
80904diff
changeset | 253 | fun read_block_properties ctxt ss = | 
| 62786 | 254 | let | 
| 255 | val props = read_properties ss; | |
| 62783 | 256 | |
| 80922 
e0b958719301
remove specific support for "expression" block markup: prefer "notation";
 wenzelm parents: 
80920diff
changeset | 257 | val more_markups = the_list (get_notation_markup ctxt props); | 
| 80905 
47793a46d06c
support for Markup.expression properties in pretty-blocks;
 wenzelm parents: 
80904diff
changeset | 258 | |
| 62786 | 259 | val markup_name = get_string Markup.markupN props; | 
| 80904 | 260 | val markup_props = props |> map_filter (fn (a, opt_b) => | 
| 261 | if member (op =) Markup.block_properties (#1 a) then NONE | |
| 80905 
47793a46d06c
support for Markup.expression properties in pretty-blocks;
 wenzelm parents: 
80904diff
changeset | 262 |       else SOME (a, the_default ("true", Position.none) opt_b));
 | 
| 
47793a46d06c
support for Markup.expression properties in pretty-blocks;
 wenzelm parents: 
80904diff
changeset | 263 | val markups = | 
| 
47793a46d06c
support for Markup.expression properties in pretty-blocks;
 wenzelm parents: 
80904diff
changeset | 264 | if markup_name <> "" then [(markup_name, map (apply2 #1) markup_props)] | 
| 
47793a46d06c
support for Markup.expression properties in pretty-blocks;
 wenzelm parents: 
80904diff
changeset | 265 | else if null markup_props then [] | 
| 
47793a46d06c
support for Markup.expression properties in pretty-blocks;
 wenzelm parents: 
80904diff
changeset | 266 |       else error ("Markup name required for block properties: " ^ show_names (map #1 markup_props));
 | 
| 62783 | 267 | |
| 80905 
47793a46d06c
support for Markup.expression properties in pretty-blocks;
 wenzelm parents: 
80904diff
changeset | 268 | val block: block = | 
| 
47793a46d06c
support for Markup.expression properties in pretty-blocks;
 wenzelm parents: 
80904diff
changeset | 269 |      {markup = more_markups @ markups,
 | 
| 81121 
7cacedbddba7
support for pretty blocks that are "open" and thus have no impact on formatting, only on markup;
 wenzelm parents: 
80922diff
changeset | 270 | open_block = get_bool Markup.open_blockN props, | 
| 80905 
47793a46d06c
support for Markup.expression properties in pretty-blocks;
 wenzelm parents: 
80904diff
changeset | 271 | consistent = get_bool Markup.consistentN props, | 
| 
47793a46d06c
support for Markup.expression properties in pretty-blocks;
 wenzelm parents: 
80904diff
changeset | 272 | unbreakable = get_bool Markup.unbreakableN props, | 
| 
47793a46d06c
support for Markup.expression properties in pretty-blocks;
 wenzelm parents: 
80904diff
changeset | 273 | indent = get_nat Markup.indentN props}; | 
| 
47793a46d06c
support for Markup.expression properties in pretty-blocks;
 wenzelm parents: 
80904diff
changeset | 274 | in Bg block end | 
| 62806 | 275 | handle ERROR msg => | 
| 276 | let | |
| 277 | val reported_texts = | |
| 278 | reports_of_block (#1 (Symbol_Pos.range ss)) | |
| 279 | |> map (fn (p, m) => Markup.markup_report (Position.reported_text p m "")) | |
| 280 | in error (msg ^ implode reported_texts) end; | |
| 62783 | 281 | |
| 282 | val read_block_indent = | |
| 62789 | 283 | Bg o block_indent o #1 o Library.read_int o map Symbol_Pos.symbol; | 
| 62783 | 284 | |
| 71545 
b0b16088ccf2
allow slightly odd "' " in mixfix as documented (introduced in 55754d6d399c, but broken in be8a8d60d962);
 wenzelm parents: 
69584diff
changeset | 285 | val is_meta = member (op =) ["'", "(", ")", "/", "_", "\<index>", Symbol.open_, Symbol.close];
 | 
| 19004 | 286 | |
| 63933 | 287 | val scan_delim = | 
| 288 | scan_one Symbol.is_control ::: Symbol_Pos.scan_cartouche "Mixfix error: " || | |
| 289 | $$ "'" |-- scan_one ((not o Symbol.is_blank) andf Symbol.not_eof) >> single || | |
| 290 | scan_one ((not o is_meta) andf (not o Symbol.is_blank) andf Symbol.not_eof) >> single; | |
| 19004 | 291 | |
| 80905 
47793a46d06c
support for Markup.expression properties in pretty-blocks;
 wenzelm parents: 
80904diff
changeset | 292 | fun scan_symbs ctxt = | 
| 
47793a46d06c
support for Markup.expression properties in pretty-blocks;
 wenzelm parents: 
80904diff
changeset | 293 | let | 
| 
47793a46d06c
support for Markup.expression properties in pretty-blocks;
 wenzelm parents: 
80904diff
changeset | 294 | val scan_sym = | 
| 
47793a46d06c
support for Markup.expression properties in pretty-blocks;
 wenzelm parents: 
80904diff
changeset | 295 |       $$ "_" >> K (Argument ("", 0)) ||
 | 
| 
47793a46d06c
support for Markup.expression properties in pretty-blocks;
 wenzelm parents: 
80904diff
changeset | 296 | $$ "\<index>" >> K index || | 
| 
47793a46d06c
support for Markup.expression properties in pretty-blocks;
 wenzelm parents: 
80904diff
changeset | 297 |       $$ "(" |--
 | 
| 
47793a46d06c
support for Markup.expression properties in pretty-blocks;
 wenzelm parents: 
80904diff
changeset | 298 | (Symbol_Pos.scan_cartouche_content err_prefix >> read_block_properties ctxt || | 
| 
47793a46d06c
support for Markup.expression properties in pretty-blocks;
 wenzelm parents: 
80904diff
changeset | 299 | scan_many Symbol.is_digit >> read_block_indent) || | 
| 
47793a46d06c
support for Markup.expression properties in pretty-blocks;
 wenzelm parents: 
80904diff
changeset | 300 | $$ ")" >> K En || | 
| 
47793a46d06c
support for Markup.expression properties in pretty-blocks;
 wenzelm parents: 
80904diff
changeset | 301 | $$ "/" -- $$ "/" >> K (Brk ~1) || | 
| 
47793a46d06c
support for Markup.expression properties in pretty-blocks;
 wenzelm parents: 
80904diff
changeset | 302 | $$ "/" |-- scan_many Symbol.is_space >> (Brk o length) || | 
| 
47793a46d06c
support for Markup.expression properties in pretty-blocks;
 wenzelm parents: 
80904diff
changeset | 303 | scan_many1 Symbol.is_space >> (Space o Symbol_Pos.content) || | 
| 
47793a46d06c
support for Markup.expression properties in pretty-blocks;
 wenzelm parents: 
80904diff
changeset | 304 | Scan.repeat1 scan_delim >> (Delim o Symbol_Pos.content o flat); | 
| 14819 | 305 | |
| 80905 
47793a46d06c
support for Markup.expression properties in pretty-blocks;
 wenzelm parents: 
80904diff
changeset | 306 | val scan_symb = | 
| 
47793a46d06c
support for Markup.expression properties in pretty-blocks;
 wenzelm parents: 
80904diff
changeset | 307 | Scan.trace scan_sym >> (fn (syms, trace) => SOME (syms, #1 (Symbol_Pos.range trace))) || | 
| 
47793a46d06c
support for Markup.expression properties in pretty-blocks;
 wenzelm parents: 
80904diff
changeset | 308 | $$ "'" -- scan_one Symbol.is_space >> K NONE; | 
| 
47793a46d06c
support for Markup.expression properties in pretty-blocks;
 wenzelm parents: 
80904diff
changeset | 309 | in Scan.repeat scan_symb --| Scan.ahead (~$$ "'") end; | 
| 4050 | 310 | |
| 19004 | 311 | in | 
| 12513 
0ffb824dc95c
support for ``indexed syntax'' (using "\<index>" argument instead of "_");
 wenzelm parents: 
11546diff
changeset | 312 | |
| 80897 
5328d67ec647
more explicit context for syn_ext/mixfix operations, but it often degenerates to background theory;
 wenzelm parents: 
80895diff
changeset | 313 | fun read_mfix ctxt ss = | 
| 62764 | 314 | let | 
| 62801 
f9d102ef13f1
clarified errors -- disallow cartouche fragments as delimiter;
 wenzelm parents: 
62795diff
changeset | 315 | val xsymbs = | 
| 80905 
47793a46d06c
support for Markup.expression properties in pretty-blocks;
 wenzelm parents: 
80904diff
changeset | 316 | (case Scan.error (Scan.finite Symbol_Pos.stopper (scan_symbs ctxt)) ss of | 
| 62801 
f9d102ef13f1
clarified errors -- disallow cartouche fragments as delimiter;
 wenzelm parents: 
62795diff
changeset | 317 | (res, []) => map_filter I res | 
| 
f9d102ef13f1
clarified errors -- disallow cartouche fragments as delimiter;
 wenzelm parents: 
62795diff
changeset | 318 | | (_, (_, pos) :: _) => error (err_prefix ^ "bad input" ^ Position.here pos)); | 
| 80897 
5328d67ec647
more explicit context for syn_ext/mixfix operations, but it often degenerates to background theory;
 wenzelm parents: 
80895diff
changeset | 319 | val _ = Context_Position.reports ctxt (maps reports_of xsymbs); | 
| 
5328d67ec647
more explicit context for syn_ext/mixfix operations, but it often degenerates to background theory;
 wenzelm parents: 
80895diff
changeset | 320 | val _ = Context_Position.reports_text ctxt (maps reports_text_of xsymbs); | 
| 62764 | 321 | in xsymbs end; | 
| 19004 | 322 | |
| 80908 | 323 | val read_mfix0 = read_mfix o Context_Position.set_visible false; | 
| 324 | ||
| 80911 
8ad5e6df050b
block markup for specific notation, notably infix and binder;
 wenzelm parents: 
80909diff
changeset | 325 | fun mfix_name ctxt = | 
| 
8ad5e6df050b
block markup for specific notation, notably infix and binder;
 wenzelm parents: 
80909diff
changeset | 326 | read_mfix0 ctxt #> map_filter (fn (Delim s, _) => SOME s | _ => NONE) #> space_implode " "; | 
| 
8ad5e6df050b
block markup for specific notation, notably infix and binder;
 wenzelm parents: 
80909diff
changeset | 327 | |
| 80908 | 328 | fun mfix_args ctxt ss = | 
| 329 | Integer.build (read_mfix0 ctxt ss |> fold (fn (xsymb, _) => is_argument xsymb ? Integer.add 1)); | |
| 80897 
5328d67ec647
more explicit context for syn_ext/mixfix operations, but it often degenerates to background theory;
 wenzelm parents: 
80895diff
changeset | 330 | |
| 
5328d67ec647
more explicit context for syn_ext/mixfix operations, but it often degenerates to background theory;
 wenzelm parents: 
80895diff
changeset | 331 | fun mixfix_args ctxt = mfix_args ctxt o Input.source_explode; | 
| 19004 | 332 | |
| 35390 | 333 | val escape = implode o map (fn s => if is_meta s then "'" ^ s else s) o Symbol.explode; | 
| 19004 | 334 | |
| 4050 | 335 | end; | 
| 336 | ||
| 337 | ||
| 240 | 338 | (* mfix_to_xprod *) | 
| 339 | ||
| 80897 
5328d67ec647
more explicit context for syn_ext/mixfix operations, but it often degenerates to background theory;
 wenzelm parents: 
80895diff
changeset | 340 | fun mfix_to_xprod ctxt logical_types (Mfix (sy, typ, const, pris, pri, pos)) = | 
| 240 | 341 | let | 
| 80895 | 342 | val nonterm_for_lhs = the_default "logic" o try dest_Type_name; | 
| 343 | val nonterm_for_rhs = the_default "any" o try dest_Type_name; | |
| 344 | ||
| 80899 
51c338103975
proper Context_Position.report, following 5328d67ec647;
 wenzelm parents: 
80897diff
changeset | 345 | val _ = Context_Position.report ctxt pos Markup.language_mixfix; | 
| 80897 
5328d67ec647
more explicit context for syn_ext/mixfix operations, but it often degenerates to background theory;
 wenzelm parents: 
80895diff
changeset | 346 | val symbs0 = read_mfix ctxt sy; | 
| 62764 | 347 | |
| 62762 | 348 | fun err_in_mixfix msg = error (msg ^ " in mixfix annotation" ^ Position.here pos); | 
| 240 | 349 | |
| 62762 | 350 | fun check_blocks [] pending bad = pending @ bad | 
| 351 | | check_blocks ((Bg _, pos) :: rest) pending bad = check_blocks rest (pos :: pending) bad | |
| 352 | | check_blocks ((En, pos) :: rest) [] bad = check_blocks rest [] (pos :: bad) | |
| 353 | | check_blocks ((En, _) :: rest) (_ :: pending) bad = check_blocks rest pending bad | |
| 354 | | check_blocks (_ :: rest) pending bad = check_blocks rest pending bad; | |
| 240 | 355 | |
| 80895 | 356 | fun add_args [] ty [] = ([], nonterm_for_lhs ty) | 
| 62762 | 357 | | add_args [] _ _ = err_in_mixfix "Too many precedences" | 
| 358 |       | add_args ((sym as (Argument ("index", _), _)) :: syms) ty ps =
 | |
| 359 | add_args syms ty ps |>> cons sym | |
| 360 |       | add_args ((Argument _, pos) :: syms) (Type ("fun", [ty, tys])) [] =
 | |
| 80895 | 361 | add_args syms tys [] |>> cons (Argument (nonterm_for_rhs ty, 0), pos) | 
| 62762 | 362 |       | add_args ((Argument _, pos) :: syms) (Type ("fun", [ty, tys])) (p :: ps) =
 | 
| 80895 | 363 | add_args syms tys ps |>> cons (Argument (nonterm_for_rhs ty, p), pos) | 
| 62762 | 364 | | add_args ((Argument _, _) :: _) _ _ = | 
| 365 | err_in_mixfix "More arguments than in corresponding type" | |
| 366 | | add_args (sym :: syms) ty ps = add_args syms ty ps |>> cons sym; | |
| 367 | ||
| 368 | fun logical_args (a as (Argument (s, p))) = | |
| 369 |           if s <> "prop" andalso member (op =) logical_types s then Argument ("logic", p) else a
 | |
| 370 | | logical_args a = a; | |
| 240 | 371 | |
| 372 | fun rem_pri (Argument (s, _)) = Argument (s, chain_pri) | |
| 373 | | rem_pri sym = sym; | |
| 374 | ||
| 62764 | 375 | val indexes = filter (is_index o #1) symbs0; | 
| 62762 | 376 | val _ = | 
| 377 | if length indexes <= 1 then () | |
| 378 |       else error ("More than one index argument" ^ Position.here_list (map #2 indexes));
 | |
| 2364 | 379 | |
| 62764 | 380 | val args = map_filter (fn (arg as Argument _, _) => SOME arg | _ => NONE) symbs0; | 
| 44470 
6c6c31ef6bb2
more accurate treatment of index syntax constants, for proper entity references in concrete notation (e.g. infix "\<oplus>\<index>");
 wenzelm parents: 
43329diff
changeset | 381 | val (const', typ', syntax_consts, parse_rules) = | 
| 
6c6c31ef6bb2
more accurate treatment of index syntax constants, for proper entity references in concrete notation (e.g. infix "\<oplus>\<index>");
 wenzelm parents: 
43329diff
changeset | 382 | if not (exists is_index args) then (const, typ, NONE, NONE) | 
| 12513 
0ffb824dc95c
support for ``indexed syntax'' (using "\<index>" argument instead of "_");
 wenzelm parents: 
11546diff
changeset | 383 | else | 
| 
0ffb824dc95c
support for ``indexed syntax'' (using "\<index>" argument instead of "_");
 wenzelm parents: 
11546diff
changeset | 384 | let | 
| 35429 
afa8cf9e63d8
authentic syntax for classes and type constructors;
 wenzelm parents: 
35390diff
changeset | 385 | val indexed_const = | 
| 81225 
2157039256d3
clarified markers for syntax consts: avoid overlap with logical consts;
 wenzelm parents: 
81159diff
changeset | 386 | if const <> "" then Lexicon.mark_indexed const | 
| 62762 | 387 | else err_in_mixfix "Missing constant name for indexed syntax"; | 
| 14697 | 388 | val rangeT = Term.range_type typ handle Match => | 
| 62762 | 389 | err_in_mixfix "Missing structure argument for indexed syntax"; | 
| 12513 
0ffb824dc95c
support for ``indexed syntax'' (using "\<index>" argument instead of "_");
 wenzelm parents: 
11546diff
changeset | 390 | |
| 43329 
84472e198515
tuned signature: Name.invent and Name.invent_names;
 wenzelm parents: 
43323diff
changeset | 391 | val xs = map Ast.Variable (Name.invent Name.context "xa" (length args - 1)); | 
| 19012 | 392 | val (xs1, xs2) = chop (find_index is_index args) xs; | 
| 12513 
0ffb824dc95c
support for ``indexed syntax'' (using "\<index>" argument instead of "_");
 wenzelm parents: 
11546diff
changeset | 393 | val i = Ast.Variable "i"; | 
| 62762 | 394 | val lhs = | 
| 395 | Ast.mk_appl (Ast.Constant indexed_const) | |
| 396 | (xs1 @ [Ast.mk_appl (Ast.Constant "_index") [i]] @ xs2); | |
| 14697 | 397 | val rhs = Ast.mk_appl (Ast.Constant const) (i :: xs); | 
| 80748 
43c4817375bf
support for syntax const dependencies, with minimal integrity checks;
 wenzelm parents: 
77999diff
changeset | 398 | in (indexed_const, rangeT, SOME (indexed_const, [const]), SOME (lhs, rhs)) end; | 
| 12513 
0ffb824dc95c
support for ``indexed syntax'' (using "\<index>" argument instead of "_");
 wenzelm parents: 
11546diff
changeset | 399 | |
| 62764 | 400 | val (symbs1, lhs) = add_args symbs0 typ' pris; | 
| 12513 
0ffb824dc95c
support for ``indexed syntax'' (using "\<index>" argument instead of "_");
 wenzelm parents: 
11546diff
changeset | 401 | |
| 2364 | 402 | val copy_prod = | 
| 20675 | 403 | (lhs = "prop" orelse lhs = "logic") | 
| 2364 | 404 | andalso const <> "" | 
| 62764 | 405 | andalso not (null symbs1) | 
| 406 | andalso not (exists (is_delim o #1) symbs1); | |
| 2364 | 407 | val lhs' = | 
| 62764 | 408 |       if copy_prod orelse lhs = "prop" andalso map #1 symbs1 = [Argument ("prop'", 0)] then lhs
 | 
| 42293 
6cca0343ea48
renamed sprop "prop#" to "prop'" -- proper identifier;
 wenzelm parents: 
42288diff
changeset | 409 | else if lhs = "prop" then "prop'" | 
| 62762 | 410 | else if member (op =) logical_types lhs then "logic" | 
| 2364 | 411 | else lhs; | 
| 62764 | 412 | val symbs2 = map (apfst logical_args) symbs1; | 
| 240 | 413 | |
| 62762 | 414 | val _ = | 
| 415 | (pri :: pris) |> List.app (fn p => | |
| 416 | if p >= 0 andalso p <= 1000 then () | |
| 417 |         else err_in_mixfix ("Precedence " ^ string_of_int p ^ " out of range"));
 | |
| 418 | val _ = | |
| 62764 | 419 | (case check_blocks symbs2 [] [] of | 
| 62762 | 420 | [] => () | 
| 421 |       | bad => error ("Unbalanced block parentheses" ^ Position.here_list bad));
 | |
| 422 | ||
| 62764 | 423 | val xprod = XProd (lhs', map #1 symbs2, const', pri); | 
| 12513 
0ffb824dc95c
support for ``indexed syntax'' (using "\<index>" argument instead of "_");
 wenzelm parents: 
11546diff
changeset | 424 | val xprod' = | 
| 62762 | 425 | if Lexicon.is_terminal lhs' then | 
| 426 |         err_in_mixfix ("Illegal use of terminal " ^ quote lhs' ^ " as nonterminal")
 | |
| 12513 
0ffb824dc95c
support for ``indexed syntax'' (using "\<index>" argument instead of "_");
 wenzelm parents: 
11546diff
changeset | 427 | else if const <> "" then xprod | 
| 62764 | 428 | else if length (filter (is_argument o #1) symbs2) <> 1 then | 
| 62762 | 429 | err_in_mixfix "Copy production must have exactly one argument" | 
| 62764 | 430 | else if exists (is_terminal o #1) symbs2 then xprod | 
| 431 | else XProd (lhs', map (rem_pri o #1) symbs2, "", chain_pri); | |
| 12513 
0ffb824dc95c
support for ``indexed syntax'' (using "\<index>" argument instead of "_");
 wenzelm parents: 
11546diff
changeset | 432 | |
| 44470 
6c6c31ef6bb2
more accurate treatment of index syntax constants, for proper entity references in concrete notation (e.g. infix "\<oplus>\<index>");
 wenzelm parents: 
43329diff
changeset | 433 | in (xprod', syntax_consts, parse_rules) end; | 
| 12513 
0ffb824dc95c
support for ``indexed syntax'' (using "\<index>" argument instead of "_");
 wenzelm parents: 
11546diff
changeset | 434 | |
| 240 | 435 | |
| 436 | ||
| 437 | (** datatype syn_ext **) | |
| 438 | ||
| 439 | datatype syn_ext = | |
| 37216 
3165bc303f66
modernized some structure names, keeping a few legacy aliases;
 wenzelm parents: 
35429diff
changeset | 440 |   Syn_Ext of {
 | 
| 240 | 441 | xprods: xprod list, | 
| 80748 
43c4817375bf
support for syntax const dependencies, with minimal integrity checks;
 wenzelm parents: 
77999diff
changeset | 442 | consts: (string * string list) list, | 
| 21772 | 443 | parse_ast_translation: (string * ((Proof.context -> Ast.ast list -> Ast.ast) * stamp)) list, | 
| 1510 | 444 | parse_rules: (Ast.ast * Ast.ast) list, | 
| 21772 | 445 | parse_translation: (string * ((Proof.context -> term list -> term) * stamp)) list, | 
| 42247 
12fe41a92cd5
typed_print_translation: discontinued show_sorts argument;
 wenzelm parents: 
42245diff
changeset | 446 | print_translation: (string * ((Proof.context -> typ -> term list -> term) * stamp)) list, | 
| 1510 | 447 | print_rules: (Ast.ast * Ast.ast) list, | 
| 42268 | 448 | print_ast_translation: (string * ((Proof.context -> Ast.ast list -> Ast.ast) * stamp)) list}; | 
| 240 | 449 | |
| 450 | ||
| 451 | (* syn_ext *) | |
| 452 | ||
| 80897 
5328d67ec647
more explicit context for syn_ext/mixfix operations, but it often degenerates to background theory;
 wenzelm parents: 
80895diff
changeset | 453 | fun syn_ext ctxt logical_types mfixes consts trfuns (parse_rules, print_rules) = | 
| 240 | 454 | let | 
| 455 | val (parse_ast_translation, parse_translation, print_translation, | |
| 456 | print_ast_translation) = trfuns; | |
| 457 | ||
| 80897 
5328d67ec647
more explicit context for syn_ext/mixfix operations, but it often degenerates to background theory;
 wenzelm parents: 
80895diff
changeset | 458 | val xprod_results = map (mfix_to_xprod ctxt logical_types) mfixes; | 
| 44470 
6c6c31ef6bb2
more accurate treatment of index syntax constants, for proper entity references in concrete notation (e.g. infix "\<oplus>\<index>");
 wenzelm parents: 
43329diff
changeset | 459 | val xprods = map #1 xprod_results; | 
| 
6c6c31ef6bb2
more accurate treatment of index syntax constants, for proper entity references in concrete notation (e.g. infix "\<oplus>\<index>");
 wenzelm parents: 
43329diff
changeset | 460 | val consts' = map_filter #2 xprod_results; | 
| 
6c6c31ef6bb2
more accurate treatment of index syntax constants, for proper entity references in concrete notation (e.g. infix "\<oplus>\<index>");
 wenzelm parents: 
43329diff
changeset | 461 | val parse_rules' = rev (map_filter #3 xprod_results); | 
| 80748 
43c4817375bf
support for syntax const dependencies, with minimal integrity checks;
 wenzelm parents: 
77999diff
changeset | 462 | val mfix_consts = map (fn Mfix x => (#3 x, [])) mfixes @ map (fn XProd x => (#3 x, [])) xprods; | 
| 240 | 463 | in | 
| 37216 
3165bc303f66
modernized some structure names, keeping a few legacy aliases;
 wenzelm parents: 
35429diff
changeset | 464 |     Syn_Ext {
 | 
| 624 | 465 | xprods = xprods, | 
| 44470 
6c6c31ef6bb2
more accurate treatment of index syntax constants, for proper entity references in concrete notation (e.g. infix "\<oplus>\<index>");
 wenzelm parents: 
43329diff
changeset | 466 | consts = mfix_consts @ consts' @ consts, | 
| 240 | 467 | parse_ast_translation = parse_ast_translation, | 
| 12513 
0ffb824dc95c
support for ``indexed syntax'' (using "\<index>" argument instead of "_");
 wenzelm parents: 
11546diff
changeset | 468 | parse_rules = parse_rules' @ parse_rules, | 
| 240 | 469 | parse_translation = parse_translation, | 
| 470 | print_translation = print_translation, | |
| 12513 
0ffb824dc95c
support for ``indexed syntax'' (using "\<index>" argument instead of "_");
 wenzelm parents: 
11546diff
changeset | 471 | print_rules = map swap parse_rules' @ print_rules, | 
| 42268 | 472 | print_ast_translation = print_ast_translation} | 
| 240 | 473 | end; | 
| 474 | ||
| 2382 | 475 | |
| 80897 
5328d67ec647
more explicit context for syn_ext/mixfix operations, but it often degenerates to background theory;
 wenzelm parents: 
80895diff
changeset | 476 | fun syn_ext_consts ctxt consts = syn_ext ctxt [] [] consts ([], [], [], []) ([], []); | 
| 
5328d67ec647
more explicit context for syn_ext/mixfix operations, but it often degenerates to background theory;
 wenzelm parents: 
80895diff
changeset | 477 | fun syn_ext_rules ctxt rules = syn_ext ctxt [] [] [] ([], [], [], []) rules; | 
| 
5328d67ec647
more explicit context for syn_ext/mixfix operations, but it often degenerates to background theory;
 wenzelm parents: 
80895diff
changeset | 478 | fun syn_ext_trfuns ctxt trfuns = syn_ext ctxt [] [] [] trfuns ([], []); | 
| 16610 | 479 | |
| 15754 | 480 | fun stamp_trfun s (c, f) = (c, (f, s)); | 
| 481 | fun mk_trfun tr = stamp_trfun (stamp ()) tr; | |
| 29318 
6337d1cb2ba0
added numeral, which supercedes num, xnum, float;
 wenzelm parents: 
28904diff
changeset | 482 | fun eq_trfun ((_, s1: stamp), (_, s2)) = s1 = s2; | 
| 15754 | 483 | |
| 240 | 484 | end; |