(* Title: Pure/Syntax/mixfix.ML Author: Tobias Nipkow, TU Muenchen Author: Makarius
Mixfix declarations, infixes, binders.
*)
datatype mixfix =
NoSyn |
Mixfix of Input.source * int list * int * Position.range |
Infix of Input.source * int * Position.range |
Infixl of Input.source * int * Position.range |
Infixr of Input.source * int * Position.range |
Binder of Input.source * int * int * Position.range | Structureof Position.range;
signature MIXFIX = sig datatype mixfix = datatype mixfix val mixfix: string -> mixfix val is_empty: mixfix -> bool val is_infix: mixfix -> bool val equal: mixfix * mixfix -> bool val range_of: mixfix -> Position.range val pos_of: mixfix -> Position.T val reset_pos: mixfix -> mixfix val pretty_mixfix: mixfix -> Pretty.T val mixfix_args: Proof.context -> mixfix -> int val default_constraint: Proof.context -> mixfix -> typ val make_type: int -> typ val binder_name: string -> string val syn_ext_types: Proof.context -> (string * typ * mixfix) list -> Syntax_Ext.syn_ext val syn_ext_consts: Proof.context -> stringlist -> (string * typ * mixfix) list ->
Syntax_Ext.syn_ext end;
structure Mixfix: MIXFIX = struct
(** mixfix declarations **)
datatype mixfix = datatype mixfix;
fun mixfix s = Mixfix (Input.string s, [], 1000, Position.no_range);
val template = Pretty.cartouche o Pretty.str o #1 o Input.source_content; val keyword = Pretty.keyword2; val parens = Pretty.enclose "("")"; val brackets = Pretty.enclose "[""]"; val int = Pretty.str o string_of_int;
fun mixfix_template (Mixfix (sy, _, _, _)) = SOME sy
| mixfix_template (Infix (sy, _, _)) = SOME sy
| mixfix_template (Infixl (sy, _, _)) = SOME sy
| mixfix_template (Infixr (sy, _, _)) = SOME sy
| mixfix_template (Binder (sy, _, _, _)) = SOME sy
| mixfix_template _ = NONE;
fun mixfix_template_reports mx = if Options.default_bool "update_mixfix_cartouches"then
(case mixfix_template mx of
SOME sy => [((Input.pos_of sy, Markup.update), cartouche (#1 (Input.source_content sy)))]
| NONE => []) else [];
(* infix notation *)
val prefix_bg = Symbol_Pos.explode0 "'("; val prefix_en = Symbol_Pos.explode0 "')";
val infix_bg = Symbol_Pos.explode0 "("; val infix_arg1 = Symbol_Pos.explode0 "_ "; val infix_arg2 = Symbol_Pos.explode0 "/ _)";
fun binder_name c =
(if Lexicon.is_const c then Lexicon.unmark_const c elseif Lexicon.is_fixed c then Lexicon.unmark_fixed c else c) |> Lexicon.mark_binder;
val binder_bg = Symbol_Pos.explode0 "("; val binder_en = Symbol_Pos.explode0 "_./ _)";
fun binder_typ _ (Type ("fun", [Type ("fun", [_, ty2]), ty3])) =
[Type ("idts", []), ty2] ---> ty3
| binder_typ c _ = error ("Bad type of binder: " ^ quote c);
(* syn_ext_types *)
val typeT = Type ("type", []); fun make_type n = replicate n typeT ---> typeT;
fun syn_ext_types ctxt type_decls = let fun mk_infix sy ty t p1 p2 p3 pos = let val ss = Input.source_explode sy; val syms = infix_block ctxt ss @ infix_arg1 @ ss @ infix_arg2; in Syntax_Ext.Mfix (syms, ty, t, [p1, p2], p3, pos) end;
fun mfix_of (t, ty, mx) =
(case mx of
NoSyn => NONE
| Mixfix (sy, ps, p, _) =>
SOME (Syntax_Ext.Mfix (Input.source_explode sy, ty, t, ps, p, pos_of mx))
| Infix (sy, p, _) => SOME (mk_infix sy ty t (p + 1) (p + 1) p (pos_of mx))
| Infixl (sy, p, _) => SOME (mk_infix sy ty t p (p + 1) p (pos_of mx))
| Infixr (sy, p, _) => SOME (mk_infix sy ty t (p + 1) p p (pos_of mx))
| _ => error ("Bad mixfix declaration for " ^ quote t ^ Position.here (pos_of mx)));
fun check_args (_, ty, mx) (SOME (Syntax_Ext.Mfix (sy, _, _, _, _, _))) = if length (Term.binder_types ty) = Syntax_Ext.mfix_args ctxt sy then () else
error ("Bad number of type constructor arguments in mixfix annotation" ^
Position.here (pos_of mx))
| check_args _ NONE = ();
val _ = Context_Position.reports_text ctxt (maps (mixfix_template_reports o #3) type_decls);
val mfix = map mfix_of type_decls; val _ = map2 check_args type_decls mfix; val consts = map (fn (t, _, _) => (t, [])) type_decls; in Syntax_Ext.syn_ext ctxt [] (map_filter I mfix) consts ([], [], [], []) ([], []) end;
(* syn_ext_consts *)
fun syn_ext_consts ctxt logical_types const_decls = let fun mk_infix sy ty c p1 p2 p3 pos = let val ss0 = Input.source_explode (Input.reset_pos sy); val ss = Input.source_explode sy; val syms = infix_block ctxt ss @ infix_arg1 @ ss @ infix_arg2; in
[Syntax_Ext.Mfix (prefix_bg @ ss0 @ prefix_en, ty, c, [], 1000, Position.none),
Syntax_Ext.Mfix (syms, ty, c, [p1, p2], p3, pos)] end;
fun mfix_of (c, ty, mx) =
(case mx of
NoSyn => []
| Mixfix (sy, ps, p, _) => [Syntax_Ext.Mfix (Input.source_explode sy, ty, c, ps, p, pos_of mx)]
| Infix (sy, p, _) => mk_infix sy ty c (p + 1) (p + 1) p (pos_of mx)
| Infixl (sy, p, _) => mk_infix sy ty c p (p + 1) p (pos_of mx)
| Infixr (sy, p, _) => mk_infix sy ty c (p + 1) p p (pos_of mx)
| Binder (sy, p, q, _) => let val ss = Input.source_explode sy; val syms = binder_block ctxt ss @ ss @ binder_en; in [Syntax_Ext.Mfix (syms, binder_typ c ty, binder_name c, [0, p], q, pos_of mx)] end
| _ => error ("Bad mixfix declaration for " ^ quote c ^ Position.here (pos_of mx)));
fun binder (c, _, Binder _) = SOME (binder_name c, c)
| binder _ = NONE;
val _ = Context_Position.reports_text ctxt (maps (mixfix_template_reports o #3) const_decls);
val mfix = maps mfix_of const_decls; val binders = map_filter binder const_decls; val binder_trs = binders
|> map (Syntax_Ext.stamp_trfun binder_stamp o Syntax_Trans.mk_binder_tr); val binder_trs' = binders
|> map (Syntax_Ext.stamp_trfun binder_stamp o
apsnd Syntax_Trans.non_typed_tr' o Syntax_Trans.mk_binder_tr' o swap);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.