src/Pure/PIDE/markup_kind.ML
author wenzelm
Sun, 22 Sep 2024 15:46:19 +0200
changeset 80920 bbe2c56fe255
parent 80919 1a52cc1c3274
child 80921 a37ed1aeb163
permissions -rw-r--r--
more uniform treatment of Markup.notation and Markup.expression: manage kinds via context;

(*  Title:      Pure/markup_kind.ML
    Author:     Makarius

Formally defined kind for Markup.notation and Markup.expression.
*)

signature MARKUP_KIND =
sig
  val get_notation_kinds: Proof.context -> string list
  val check_notation_kind: Proof.context -> xstring * Position.T -> string
  val setup_notation_kind: binding -> theory -> string * theory
  val check_notation: Proof.context -> xstring * Position.T -> Markup.T
  val setup_notation: binding -> Markup.T
  val get_expression_kinds: Proof.context -> string list
  val check_expression_kind: Proof.context -> xstring * Position.T -> string
  val setup_expression_kind: binding -> theory -> string * theory
  val check_expression: Proof.context -> xstring * Position.T -> Markup.T
  val setup_expression: binding -> Markup.T
  val markup_mixfix: Markup.T
  val markup_prefix: Markup.T
  val markup_postfix: Markup.T
  val markup_infix: Markup.T
  val markup_binder: Markup.T
  val markup_type: Markup.T
  val markup_type_application: Markup.T
  val markup_term: Markup.T
  val markup_term_application: Markup.T
  val markup_term_abstraction: Markup.T
  val markup_prop: Markup.T
  val markup_prop_application: Markup.T
  val markup_prop_abstraction: Markup.T
end;

structure Markup_Kind: MARKUP_KIND =
struct

(* theory data *)

structure Data = Theory_Data
(
  type T = unit Name_Space.table * unit Name_Space.table;
  val empty : T =
   (Name_Space.empty_table "markup_notation_kind",
    Name_Space.empty_table "markup_expression_kind");
  fun merge ((tab1, tab2), (tab1', tab2')) : T =
   (Name_Space.merge_tables (tab1, tab1'),
    Name_Space.merge_tables (tab2, tab2'));
);


(* kind *)

local

fun get_kinds which ctxt =
  which (Data.get (Proof_Context.theory_of ctxt))
  |> Name_Space.dest_table
  |> map #1
  |> sort_strings;

fun check_kind which ctxt =
  Name_Space.check (Context.Proof ctxt) (which (Data.get (Proof_Context.theory_of ctxt))) #> #1;

fun setup_kind which ap binding thy =
  let
    val context = Name_Space.map_naming (K Name_Space.global_naming) (Context.Theory thy);
    val (name, tab') = Name_Space.define context true (binding, ()) (which (Data.get thy));
  in (name, (Data.map o ap) (K tab') thy) end;

in

val get_notation_kinds = get_kinds #1;
val get_expression_kinds = get_kinds #2;

val check_notation_kind = check_kind #1;
val check_expression_kind = check_kind #2;

val setup_notation_kind = setup_kind #1 apfst;
val setup_expression_kind = setup_kind #2 apsnd;

end;


(* markup *)

fun check_notation ctxt = check_notation_kind ctxt #> Markup.notation;

fun check_expression ctxt = check_expression_kind ctxt #> Markup.expression;

fun setup_notation binding =
  Context.>>> (Context.map_theory_result (setup_notation_kind binding #>> Markup.notation));

fun setup_expression binding =
  Context.>>> (Context.map_theory_result (setup_expression_kind binding #>> Markup.expression));


(* concrete markup *)

val markup_mixfix = setup_notation (Binding.make ("mixfix", \<^here>));
val markup_prefix = setup_notation (Binding.make ("prefix", \<^here>));
val markup_postfix = setup_notation (Binding.make ("postfix", \<^here>));
val markup_infix = setup_notation (Binding.make ("infix", \<^here>));
val markup_binder = setup_notation (Binding.make ("binder", \<^here>));

val markup_type = setup_expression (Binding.make ("type", \<^here>));
val markup_type_application = setup_expression (Binding.make ("type_application", \<^here>));

val markup_term = setup_expression (Binding.make ("term", \<^here>));
val markup_term_application = setup_expression (Binding.make ("term_application", \<^here>));
val markup_term_abstraction = setup_expression (Binding.make ("term_abstraction", \<^here>));

val markup_prop = setup_expression (Binding.make ("prop", \<^here>));
val markup_prop_application = setup_expression (Binding.make ("prop_application", \<^here>));
val markup_prop_abstraction = setup_expression (Binding.make ("prop_abstraction", \<^here>));

end;