more cartouche examples, including uniform nesting of sub-languages;
authorwenzelm
Wed, 22 Jan 2014 15:11:10 +0100
changeset 55109 ecff9e26360c
parent 55108 0b7a0c1fdf7e
child 55110 917e799f19da
more cartouche examples, including uniform nesting of sub-languages;
etc/isar-keywords.el
src/HOL/ex/Cartouche_Examples.thy
--- a/etc/isar-keywords.el	Wed Jan 22 15:10:33 2014 +0100
+++ b/etc/isar-keywords.el	Wed Jan 22 15:11:10 2014 +0100
@@ -272,8 +272,10 @@
     "syntax"
     "syntax_declaration"
     "term"
+    "term_cartouche"
     "termination"
     "text"
+    "text_cartouche"
     "text_raw"
     "then"
     "theorem"
@@ -453,6 +455,7 @@
     "solve_direct"
     "spark_status"
     "term"
+    "term_cartouche"
     "thm"
     "thm_deps"
     "thy_deps"
@@ -591,6 +594,7 @@
     "syntax"
     "syntax_declaration"
     "text"
+    "text_cartouche"
     "text_raw"
     "theorems"
     "translations"
--- a/src/HOL/ex/Cartouche_Examples.thy	Wed Jan 22 15:10:33 2014 +0100
+++ b/src/HOL/ex/Cartouche_Examples.thy	Wed Jan 22 15:11:10 2014 +0100
@@ -2,10 +2,12 @@
 
 theory Cartouche_Examples
 imports Main
-keywords "cartouche" :: diag
+keywords
+  "cartouche" "term_cartouche" :: diag and
+  "text_cartouche" :: thy_decl
 begin
 
-subsection {* Outer syntax *}
+subsection {* Outer syntax: cartouche within command syntax *}
 
 ML {*
   Outer_Syntax.improper_command @{command_spec "cartouche"} ""
@@ -17,12 +19,10 @@
 cartouche \<open>abc \<open>\<alpha>\<beta>\<gamma>\<close> xzy\<close>
 
 
-subsection {* Inner syntax *}
+subsection {* Inner syntax: string literals via cartouche *}
 
-syntax "_string_cartouche" :: "cartouche_position \<Rightarrow> string"  ("STR _")
-
-parse_translation {*
-  let
+ML {*
+  local
     val mk_nib =
       Syntax.const o Lexicon.mark_const o
         fst o Term.dest_Const o HOLogic.mk_nibble;
@@ -39,27 +39,139 @@
       | mk_string (s :: ss) =
           Syntax.const @{const_syntax Cons} $ mk_char s $ mk_string ss;
 
-    fun string_tr ctxt args =
-      let fun err () = raise TERM ("string_tr", []) in
+  in
+    fun string_tr content args =
+      let fun err () = raise TERM ("string_tr", args) in
         (case args of
           [(c as Const (@{syntax_const "_constrain"}, _)) $ Free (s, _) $ p] =>
             (case Term_Position.decode_position p of
-              SOME (pos, _) =>
-                c $ mk_string (Symbol_Pos.cartouche_content (Symbol_Pos.explode (s, pos))) $ p
+              SOME (pos, _) => c $ mk_string (content (s, pos)) $ p
             | NONE => err ())
         | _ => err ())
       end;
-  in
-    [(@{syntax_const "_string_cartouche"}, string_tr)]
-  end
+  end;
+*}
+
+syntax "_STR_cartouche" :: "cartouche_position \<Rightarrow> string"  ("STR _")
+
+parse_translation {*
+  [(@{syntax_const "_STR_cartouche"},
+    K (string_tr (Symbol_Pos.cartouche_content o Symbol_Pos.explode)))]
 *}
 
 term "STR \<open>\<close>"
 term "STR \<open>abc\<close>"
-lemma "STR \<open>abc\<close> @ STR \<open>xyz\<close> = STR \<open>abcxyz\<close>" by simp
+term "STR \<open>abc\<close> @ STR \<open>xyz\<close>"
+term "STR \<open>\<newline>\<close>"
+term "STR \<open>\001\010\100\<close>"
+
+
+subsection {* Alternate outer and inner syntax: string literals *}
+
+subsubsection {* Nested quotes *}
+
+syntax "_STR_string" :: "string_position \<Rightarrow> string"  ("STR _")
+
+parse_translation {*
+  [(@{syntax_const "_STR_string"}, K (string_tr Lexicon.explode_string))]
+*}
+
+term "STR \"\""
+term "STR \"abc\""
+term "STR \"abc\" @ STR \"xyz\""
+term "STR \"\<newline>\""
+term "STR \"\001\010\100\""
+
+
+subsubsection {* Term cartouche and regular quotes *}
+
+ML {*
+  Outer_Syntax.improper_command @{command_spec "term_cartouche"} ""
+    (Parse.inner_syntax Parse.cartouche >> (fn s =>
+      Toplevel.keep (fn state =>
+        let
+          val ctxt = Toplevel.context_of state;
+          val t = Syntax.read_term ctxt s;
+        in writeln (Syntax.string_of_term ctxt t) end)))
+*}
+
+term_cartouche \<open>STR ""\<close>
+term_cartouche \<open>STR "abc"\<close>
+term_cartouche \<open>STR "abc" @ STR "xyz"\<close>
+term_cartouche \<open>STR "\<newline>"\<close>
+term_cartouche \<open>STR "\001\010\100"\<close>
 
 
-subsection {* Proof method syntax *}
+subsubsection {* Further nesting: antiquotations *}
+
+setup -- "ML antiquotation"
+{*
+  ML_Antiquote.inline @{binding term_cartouche}
+    (Args.context -- Scan.lift (Parse.inner_syntax Parse.cartouche) >>
+      (fn (ctxt, s) => ML_Syntax.atomic (ML_Syntax.print_term (Syntax.read_term ctxt s))))
+*}
+
+setup -- "document antiquotation"
+{*
+  Thy_Output.antiquotation @{binding ML_cartouche}
+    (Scan.lift Args.cartouche_source_position) (fn {context, ...} => fn (txt, pos) =>
+      let
+        val toks =
+          ML_Lex.read Position.none "fn _ => (" @
+          ML_Lex.read pos txt @
+          ML_Lex.read Position.none ");";
+        val _ = ML_Context.eval_in (SOME context) false pos toks;
+      in "" end);
+*}
+
+ML {*
+  @{term_cartouche \<open>STR ""\<close>};
+  @{term_cartouche \<open>STR "abc"\<close>};
+  @{term_cartouche \<open>STR "abc" @ STR "xyz"\<close>};
+  @{term_cartouche \<open>STR "\<newline>"\<close>};
+  @{term_cartouche \<open>STR "\001\010\100"\<close>};
+*}
+
+text {*
+  @{ML_cartouche
+    \<open>
+      (
+        @{term_cartouche \<open>STR ""\<close>};
+        @{term_cartouche \<open>STR "abc"\<close>};
+        @{term_cartouche \<open>STR "abc" @ STR "xyz"\<close>};
+        @{term_cartouche \<open>STR "\<newline>"\<close>};
+        @{term_cartouche \<open>STR "\001\010\100"\<close>}
+      )
+    \<close>
+  }
+*}
+
+
+subsubsection {* Uniform nesting of sub-languages: document source, ML, term, string literals *}
+
+ML {*
+  Outer_Syntax.markup_command Thy_Output.MarkupEnv
+    @{command_spec "text_cartouche"} ""
+    (Parse.opt_target -- Parse.source_position Parse.cartouche >> Isar_Cmd.local_theory_markup)
+*}
+
+text_cartouche
+\<open>
+  @{ML_cartouche
+    \<open>
+      (
+        @{term_cartouche \<open>STR ""\<close>};
+        @{term_cartouche \<open>STR "abc"\<close>};
+        @{term_cartouche \<open>STR "abc" @ STR "xyz"\<close>};
+        @{term_cartouche \<open>STR "\<newline>"\<close>};
+        @{term_cartouche \<open>STR "\001\010\100"\<close>}
+      )
+    \<close>
+  }
+\<close>
+
+
+subsection {* Proof method syntax: ML tactic expression *}
 
 ML {*
 structure ML_Tactic:
@@ -83,7 +195,7 @@
 *}
 
 
-subsection {* Explicit version: method with cartouche argument *}
+subsubsection {* Explicit version: method with cartouche argument *}
 
 method_setup ml_tactic = {*
   Scan.lift Args.cartouche_source_position
@@ -104,7 +216,7 @@
 text {* @{ML "@{lemma \"A \<and> B \<longrightarrow> B \<and> A\" by (ml_tactic \<open>blast_tac ctxt 1\<close>)}"} *}
 
 
-subsection {* Implicit version: method with special name "cartouche" (dynamic!) *}
+subsubsection {* Implicit version: method with special name "cartouche" (dynamic!) *}
 
 method_setup "cartouche" = {*
   Scan.lift Args.cartouche_source_position