| author | wenzelm | 
| Tue, 24 Oct 2017 10:59:15 +0200 | |
| changeset 66911 | d122c24a93d6 | 
| parent 62959 | 19c2a58623ed | 
| child 67398 | 5eb932e604a2 | 
| permissions | -rw-r--r-- | 
| 384 | 1 | (* Title: Pure/Syntax/mixfix.ML | 
| 551 | 2 | Author: Tobias Nipkow and Markus Wenzel, TU Muenchen | 
| 384 | 3 | |
| 18719 
dca3ae4f6dd6
moved pure syntax to Syntax/syntax.ML and pure_thy.ML;
 wenzelm parents: 
18673diff
changeset | 4 | Mixfix declarations, infixes, binders. | 
| 384 | 5 | *) | 
| 6 | ||
| 42287 
d98eb048a2e4
discontinued special treatment of structure Mixfix;
 wenzelm parents: 
42284diff
changeset | 7 | signature BASIC_MIXFIX = | 
| 2199 
bcb360f80dac
added Infixl/rName: specify infix name independently from syntax;
 wenzelm parents: 
1952diff
changeset | 8 | sig | 
| 384 | 9 | datatype mixfix = | 
| 10 | NoSyn | | |
| 62752 | 11 | Mixfix of Input.source * int list * int * Position.range | | 
| 12 | Infix of Input.source * int * Position.range | | |
| 13 | Infixl of Input.source * int * Position.range | | |
| 14 | Infixr of Input.source * int * Position.range | | |
| 15 | Binder of Input.source * int * int * Position.range | | |
| 16 | Structure of Position.range | |
| 2199 
bcb360f80dac
added Infixl/rName: specify infix name independently from syntax;
 wenzelm parents: 
1952diff
changeset | 17 | end; | 
| 384 | 18 | |
| 42287 
d98eb048a2e4
discontinued special treatment of structure Mixfix;
 wenzelm parents: 
42284diff
changeset | 19 | signature MIXFIX = | 
| 2199 
bcb360f80dac
added Infixl/rName: specify infix name independently from syntax;
 wenzelm parents: 
1952diff
changeset | 20 | sig | 
| 42287 
d98eb048a2e4
discontinued special treatment of structure Mixfix;
 wenzelm parents: 
42284diff
changeset | 21 | include BASIC_MIXFIX | 
| 62761 | 22 | val mixfix: string -> mixfix | 
| 62752 | 23 | val is_empty: mixfix -> bool | 
| 24 | val equal: mixfix * mixfix -> bool | |
| 25 | val range_of: mixfix -> Position.range | |
| 26 | val pos_of: mixfix -> Position.T | |
| 62759 | 27 | val reset_pos: mixfix -> mixfix | 
| 19271 | 28 | val pretty_mixfix: mixfix -> Pretty.T | 
| 4823 | 29 | val mixfix_args: mixfix -> int | 
| 62959 
19c2a58623ed
back to static Mixfix.default_constraint without any special tricks (reverting e6443edaebff);
 wenzelm parents: 
62797diff
changeset | 30 | val default_constraint: mixfix -> typ | 
| 35412 
b8dead547d9e
more uniform treatment of syntax for types vs. consts;
 wenzelm parents: 
35390diff
changeset | 31 | val make_type: int -> typ | 
| 42287 
d98eb048a2e4
discontinued special treatment of structure Mixfix;
 wenzelm parents: 
42284diff
changeset | 32 | val binder_name: string -> string | 
| 42288 
2074b31650e6
discontinued special treatment of structure Syntax_Ext (formerly Syn_Ext);
 wenzelm parents: 
42287diff
changeset | 33 | val syn_ext_types: (string * typ * mixfix) list -> Syntax_Ext.syn_ext | 
| 59841 | 34 | val syn_ext_consts: string list -> (string * typ * mixfix) list -> Syntax_Ext.syn_ext | 
| 2199 
bcb360f80dac
added Infixl/rName: specify infix name independently from syntax;
 wenzelm parents: 
1952diff
changeset | 35 | end; | 
| 
bcb360f80dac
added Infixl/rName: specify infix name independently from syntax;
 wenzelm parents: 
1952diff
changeset | 36 | |
| 15751 
65e4790c7914
identify binder translations only once (admits remove);
 wenzelm parents: 
15570diff
changeset | 37 | structure Mixfix: MIXFIX = | 
| 384 | 38 | struct | 
| 39 | ||
| 40 | (** mixfix declarations **) | |
| 41 | ||
| 42 | datatype mixfix = | |
| 43 | NoSyn | | |
| 62752 | 44 | Mixfix of Input.source * int list * int * Position.range | | 
| 45 | Infix of Input.source * int * Position.range | | |
| 46 | Infixl of Input.source * int * Position.range | | |
| 47 | Infixr of Input.source * int * Position.range | | |
| 48 | Binder of Input.source * int * int * Position.range | | |
| 49 | Structure of Position.range; | |
| 50 | ||
| 62761 | 51 | fun mixfix s = Mixfix (Input.string s, [], 1000, Position.no_range); | 
| 52 | ||
| 62752 | 53 | fun is_empty NoSyn = true | 
| 54 | | is_empty _ = false; | |
| 55 | ||
| 56 | fun equal (NoSyn, NoSyn) = true | |
| 57 | | equal (Mixfix (sy, ps, p, _), Mixfix (sy', ps', p', _)) = | |
| 58 | Input.equal_content (sy, sy') andalso ps = ps' andalso p = p' | |
| 59 | | equal (Infix (sy, p, _), Infix (sy', p', _)) = Input.equal_content (sy, sy') andalso p = p' | |
| 60 | | equal (Infixl (sy, p, _), Infixl (sy', p', _)) = Input.equal_content (sy, sy') andalso p = p' | |
| 61 | | equal (Infixr (sy, p, _), Infixr (sy', p', _)) = Input.equal_content (sy, sy') andalso p = p' | |
| 62 | | equal (Binder (sy, p, q, _), Binder (sy', p', q', _)) = | |
| 63 | Input.equal_content (sy, sy') andalso p = p' andalso q = q' | |
| 64 | | equal (Structure _, Structure _) = true | |
| 65 | | equal _ = false; | |
| 66 | ||
| 67 | fun range_of NoSyn = Position.no_range | |
| 68 | | range_of (Mixfix (_, _, _, range)) = range | |
| 69 | | range_of (Infix (_, _, range)) = range | |
| 70 | | range_of (Infixl (_, _, range)) = range | |
| 71 | | range_of (Infixr (_, _, range)) = range | |
| 72 | | range_of (Binder (_, _, _, range)) = range | |
| 73 | | range_of (Structure range) = range; | |
| 74 | ||
| 62797 | 75 | val pos_of = Position.range_position o range_of; | 
| 384 | 76 | |
| 62759 | 77 | fun reset_pos NoSyn = NoSyn | 
| 78 | | reset_pos (Mixfix (sy, ps, p, _)) = Mixfix (Input.reset_pos sy, ps, p, Position.no_range) | |
| 79 | | reset_pos (Infix (sy, p, _)) = Infix (Input.reset_pos sy, p, Position.no_range) | |
| 80 | | reset_pos (Infixl (sy, p, _)) = Infixl (Input.reset_pos sy, p, Position.no_range) | |
| 81 | | reset_pos (Infixr (sy, p, _)) = Infixr (Input.reset_pos sy, p, Position.no_range) | |
| 82 | | reset_pos (Binder (sy, p, q, _)) = Binder (Input.reset_pos sy, p, q, Position.no_range) | |
| 83 | | reset_pos (Structure _) = Structure Position.no_range; | |
| 84 | ||
| 384 | 85 | |
| 19271 | 86 | (* pretty_mixfix *) | 
| 87 | ||
| 88 | local | |
| 11920 | 89 | |
| 62752 | 90 | val quoted = Pretty.quote o Pretty.str o Input.source_content; | 
| 55763 | 91 | val keyword = Pretty.keyword2; | 
| 19271 | 92 | val parens = Pretty.enclose "(" ")";
 | 
| 93 | val brackets = Pretty.enclose "[" "]"; | |
| 94 | val int = Pretty.str o string_of_int; | |
| 95 | ||
| 96 | in | |
| 11920 | 97 | |
| 19271 | 98 | fun pretty_mixfix NoSyn = Pretty.str "" | 
| 62752 | 99 | | pretty_mixfix (Mixfix (s, ps, p, _)) = | 
| 19271 | 100 | parens (Pretty.breaks [quoted s, brackets (Pretty.commas (map int ps)), int p]) | 
| 62752 | 101 | | pretty_mixfix (Infix (s, p, _)) = parens (Pretty.breaks [keyword "infix", quoted s, int p]) | 
| 102 | | pretty_mixfix (Infixl (s, p, _)) = parens (Pretty.breaks [keyword "infixl", quoted s, int p]) | |
| 103 | | pretty_mixfix (Infixr (s, p, _)) = parens (Pretty.breaks [keyword "infixl", quoted s, int p]) | |
| 104 | | pretty_mixfix (Binder (s, p1, p2, _)) = | |
| 19271 | 105 | parens (Pretty.breaks [keyword "binder", quoted s, brackets [int p1], int p2]) | 
| 62752 | 106 | | pretty_mixfix (Structure _) = parens [keyword "structure"]; | 
| 19271 | 107 | |
| 108 | end; | |
| 11920 | 109 | |
| 110 | ||
| 12531 | 111 | (* syntax specifications *) | 
| 384 | 112 | |
| 4053 | 113 | fun mixfix_args NoSyn = 0 | 
| 62752 | 114 | | mixfix_args (Mixfix (sy, _, _, _)) = Syntax_Ext.mixfix_args sy | 
| 115 | | mixfix_args (Infix (sy, _, _)) = 2 + Syntax_Ext.mixfix_args sy | |
| 116 | | mixfix_args (Infixl (sy, _, _)) = 2 + Syntax_Ext.mixfix_args sy | |
| 117 | | mixfix_args (Infixr (sy, _, _)) = 2 + Syntax_Ext.mixfix_args sy | |
| 18673 | 118 | | mixfix_args (Binder _) = 1 | 
| 62752 | 119 | | mixfix_args (Structure _) = 0; | 
| 4053 | 120 | |
| 121 | ||
| 62959 
19c2a58623ed
back to static Mixfix.default_constraint without any special tricks (reverting e6443edaebff);
 wenzelm parents: 
62797diff
changeset | 122 | (* default type constraint *) | 
| 
19c2a58623ed
back to static Mixfix.default_constraint without any special tricks (reverting e6443edaebff);
 wenzelm parents: 
62797diff
changeset | 123 | |
| 
19c2a58623ed
back to static Mixfix.default_constraint without any special tricks (reverting e6443edaebff);
 wenzelm parents: 
62797diff
changeset | 124 | fun default_constraint (Binder _) = (dummyT --> dummyT) --> dummyT | 
| 
19c2a58623ed
back to static Mixfix.default_constraint without any special tricks (reverting e6443edaebff);
 wenzelm parents: 
62797diff
changeset | 125 | | default_constraint mx = replicate (mixfix_args mx) dummyT ---> dummyT; | 
| 
19c2a58623ed
back to static Mixfix.default_constraint without any special tricks (reverting e6443edaebff);
 wenzelm parents: 
62797diff
changeset | 126 | |
| 
19c2a58623ed
back to static Mixfix.default_constraint without any special tricks (reverting e6443edaebff);
 wenzelm parents: 
62797diff
changeset | 127 | |
| 384 | 128 | (* syn_ext_types *) | 
| 129 | ||
| 42293 
6cca0343ea48
renamed sprop "prop#" to "prop'" -- proper identifier;
 wenzelm parents: 
42288diff
changeset | 130 | val typeT = Type ("type", []);
 | 
| 
6cca0343ea48
renamed sprop "prop#" to "prop'" -- proper identifier;
 wenzelm parents: 
42288diff
changeset | 131 | fun make_type n = replicate n typeT ---> typeT; | 
| 35412 
b8dead547d9e
more uniform treatment of syntax for types vs. consts;
 wenzelm parents: 
35390diff
changeset | 132 | |
| 14903 | 133 | fun syn_ext_types type_decls = | 
| 384 | 134 | let | 
| 62796 | 135 | fun mk_infix sy ty t p1 p2 p3 pos = | 
| 62752 | 136 | Syntax_Ext.Mfix | 
| 137 | (Symbol_Pos.explode0 "(_ " @ Input.source_explode sy @ Symbol_Pos.explode0 "/ _)", | |
| 62796 | 138 | ty, t, [p1, p2], p3, pos); | 
| 384 | 139 | |
| 62796 | 140 | fun mfix_of (mfix as (_, _, mx)) = | 
| 141 | (case mfix of | |
| 142 | (_, _, NoSyn) => NONE | |
| 143 | | (t, ty, Mixfix (sy, ps, p, _)) => | |
| 144 | SOME (Syntax_Ext.Mfix (Input.source_explode sy, ty, t, ps, p, pos_of mx)) | |
| 145 | | (t, ty, Infix (sy, p, _)) => SOME (mk_infix sy ty t (p + 1) (p + 1) p (pos_of mx)) | |
| 146 | | (t, ty, Infixl (sy, p, _)) => SOME (mk_infix sy ty t p (p + 1) p (pos_of mx)) | |
| 147 | | (t, ty, Infixr (sy, p, _)) => SOME (mk_infix sy ty t (p + 1) p p (pos_of mx)) | |
| 148 |       | (t, _, _) => error ("Bad mixfix declaration for " ^ quote t ^ Position.here (pos_of mx)));
 | |
| 384 | 149 | |
| 62753 | 150 | fun check_args (_, ty, mx) (SOME (Syntax_Ext.Mfix (sy, _, _, _, _, _))) = | 
| 42288 
2074b31650e6
discontinued special treatment of structure Syntax_Ext (formerly Syn_Ext);
 wenzelm parents: 
42287diff
changeset | 151 | if length (Term.binder_types ty) = Syntax_Ext.mfix_args sy then () | 
| 62752 | 152 | else | 
| 153 |             error ("Bad number of type constructor arguments in mixfix annotation" ^
 | |
| 154 | Position.here (pos_of mx)) | |
| 35351 
7425aece4ee3
allow general mixfix syntax for type constructors;
 wenzelm parents: 
35130diff
changeset | 155 | | check_args _ NONE = (); | 
| 
7425aece4ee3
allow general mixfix syntax for type constructors;
 wenzelm parents: 
35130diff
changeset | 156 | |
| 
7425aece4ee3
allow general mixfix syntax for type constructors;
 wenzelm parents: 
35130diff
changeset | 157 | val mfix = map mfix_of type_decls; | 
| 
7425aece4ee3
allow general mixfix syntax for type constructors;
 wenzelm parents: 
35130diff
changeset | 158 | val _ = map2 check_args type_decls mfix; | 
| 42298 
d622145603ee
more accurate markup for syntax consts, notably binders which point back to the original logical entity;
 wenzelm parents: 
42297diff
changeset | 159 | val consts = map (fn (t, _, _) => (t, "")) type_decls; | 
| 
d622145603ee
more accurate markup for syntax consts, notably binders which point back to the original logical entity;
 wenzelm parents: 
42297diff
changeset | 160 | in Syntax_Ext.syn_ext (map_filter I mfix) consts ([], [], [], []) ([], []) end; | 
| 384 | 161 | |
| 162 | ||
| 163 | (* syn_ext_consts *) | |
| 164 | ||
| 15751 
65e4790c7914
identify binder translations only once (admits remove);
 wenzelm parents: 
15570diff
changeset | 165 | val binder_stamp = stamp (); | 
| 21534 
68f805e9db0b
Binder: syntax const is determined by binder_name, not its syntax;
 wenzelm parents: 
20892diff
changeset | 166 | val binder_name = suffix "_binder"; | 
| 15751 
65e4790c7914
identify binder translations only once (admits remove);
 wenzelm parents: 
15570diff
changeset | 167 | |
| 59841 | 168 | fun syn_ext_consts logical_types const_decls = | 
| 384 | 169 | let | 
| 62796 | 170 | fun mk_infix sy ty c p1 p2 p3 pos = | 
| 62752 | 171 | [Syntax_Ext.Mfix | 
| 62766 | 172 | (Symbol_Pos.explode0 "op " @ Input.source_explode (Input.reset_pos sy), | 
| 173 | ty, c, [], 1000, Position.none), | |
| 62752 | 174 | Syntax_Ext.Mfix | 
| 175 | (Symbol_Pos.explode0 "(_ " @ Input.source_explode sy @ Symbol_Pos.explode0 "/ _)", | |
| 62796 | 176 | ty, c, [p1, p2], p3, pos)]; | 
| 384 | 177 | |
| 178 |     fun binder_typ _ (Type ("fun", [Type ("fun", [_, ty2]), ty3])) =
 | |
| 179 |           [Type ("idts", []), ty2] ---> ty3
 | |
| 14903 | 180 |       | binder_typ c _ = error ("Bad type of binder: " ^ quote c);
 | 
| 384 | 181 | |
| 62796 | 182 | fun mfix_of (mfix as (_, _, mx)) = | 
| 183 | (case mfix of | |
| 184 | (_, _, NoSyn) => [] | |
| 185 | | (c, ty, Mixfix (sy, ps, p, _)) => | |
| 186 | [Syntax_Ext.Mfix (Input.source_explode sy, ty, c, ps, p, pos_of mx)] | |
| 187 | | (c, ty, Infix (sy, p, _)) => mk_infix sy ty c (p + 1) (p + 1) p (pos_of mx) | |
| 188 | | (c, ty, Infixl (sy, p, _)) => mk_infix sy ty c p (p + 1) p (pos_of mx) | |
| 189 | | (c, ty, Infixr (sy, p, _)) => mk_infix sy ty c (p + 1) p p (pos_of mx) | |
| 190 | | (c, ty, Binder (sy, p, q, _)) => | |
| 62752 | 191 | [Syntax_Ext.Mfix | 
| 192 | (Symbol_Pos.explode0 "(3" @ Input.source_explode sy @ Symbol_Pos.explode0 "_./ _)", | |
| 62796 | 193 | binder_typ c ty, (binder_name c), [0, p], q, pos_of mx)] | 
| 194 | | (c, _, mx) => | |
| 195 |           error ("Bad mixfix declaration for " ^ quote c ^ Position.here (pos_of mx)));
 | |
| 384 | 196 | |
| 21534 
68f805e9db0b
Binder: syntax const is determined by binder_name, not its syntax;
 wenzelm parents: 
20892diff
changeset | 197 | fun binder (c, _, Binder _) = SOME (binder_name c, c) | 
| 15531 | 198 | | binder _ = NONE; | 
| 384 | 199 | |
| 19482 
9f11af8f7ef9
tuned basic list operators (flat, maps, map_filter);
 wenzelm parents: 
19467diff
changeset | 200 | val mfix = maps mfix_of const_decls; | 
| 
9f11af8f7ef9
tuned basic list operators (flat, maps, map_filter);
 wenzelm parents: 
19467diff
changeset | 201 | val binders = map_filter binder const_decls; | 
| 35129 | 202 | val binder_trs = binders | 
| 52143 | 203 | |> map (Syntax_Ext.stamp_trfun binder_stamp o Syntax_Trans.mk_binder_tr); | 
| 35129 | 204 | val binder_trs' = binders | 
| 42288 
2074b31650e6
discontinued special treatment of structure Syntax_Ext (formerly Syn_Ext);
 wenzelm parents: 
42287diff
changeset | 205 | |> map (Syntax_Ext.stamp_trfun binder_stamp o | 
| 52143 | 206 | apsnd Syntax_Trans.non_typed_tr' o Syntax_Trans.mk_binder_tr' o swap); | 
| 42298 
d622145603ee
more accurate markup for syntax consts, notably binders which point back to the original logical entity;
 wenzelm parents: 
42297diff
changeset | 207 | |
| 
d622145603ee
more accurate markup for syntax consts, notably binders which point back to the original logical entity;
 wenzelm parents: 
42297diff
changeset | 208 | val consts = binders @ map (fn (c, _, _) => (c, "")) const_decls; | 
| 14903 | 209 | in | 
| 59841 | 210 | Syntax_Ext.syn_ext' logical_types mfix consts ([], binder_trs, binder_trs', []) ([], []) | 
| 14903 | 211 | end; | 
| 384 | 212 | |
| 213 | end; | |
| 42287 
d98eb048a2e4
discontinued special treatment of structure Mixfix;
 wenzelm parents: 
42284diff
changeset | 214 | |
| 
d98eb048a2e4
discontinued special treatment of structure Mixfix;
 wenzelm parents: 
42284diff
changeset | 215 | structure Basic_Mixfix: BASIC_MIXFIX = Mixfix; | 
| 
d98eb048a2e4
discontinued special treatment of structure Mixfix;
 wenzelm parents: 
42284diff
changeset | 216 | open Basic_Mixfix; |