src/HOL/Tools/literal.ML
author wenzelm
Fri, 26 Apr 2024 13:25:44 +0200
changeset 80150 96f60533ec1d
parent 69593 3dda49e08b9d
permissions -rw-r--r--
update Windows test machines;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
68028
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
     1
(*  Title:      HOL/Tools/literal.ML
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
     2
    Author:     Florian Haftmann, TU Muenchen
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
     3
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
     4
Logical and syntactic operations on literals (see also HOL/Tools/hologic.ML).
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
     5
*)
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
     6
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
     7
signature LITERAL =
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
     8
sig
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
     9
  val add_code: string -> theory -> theory
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    10
end
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    11
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    12
structure Literal: LITERAL =
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    13
struct
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    14
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    15
datatype character = datatype String_Syntax.character;
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    16
69593
3dda49e08b9d isabelle update -u control_cartouches;
wenzelm
parents: 68940
diff changeset
    17
fun mk_literal_syntax [] = Syntax.const \<^const_syntax>\<open>String.empty_literal\<close>
68028
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    18
  | mk_literal_syntax (c :: cs) =
69593
3dda49e08b9d isabelle update -u control_cartouches;
wenzelm
parents: 68940
diff changeset
    19
      list_comb (Syntax.const \<^const_syntax>\<open>String.Literal\<close>, String_Syntax.mk_bits_syntax 7 c)
68028
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    20
        $ mk_literal_syntax cs;
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    21
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    22
val dest_literal_syntax =
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    23
  let
69593
3dda49e08b9d isabelle update -u control_cartouches;
wenzelm
parents: 68940
diff changeset
    24
    fun dest (Const (\<^const_syntax>\<open>String.empty_literal\<close>, _)) = []
3dda49e08b9d isabelle update -u control_cartouches;
wenzelm
parents: 68940
diff changeset
    25
      | dest (Const (\<^const_syntax>\<open>String.Literal\<close>, _) $ b0 $ b1 $ b2 $ b3 $ b4 $ b5 $ b6 $ t) =
68028
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    26
          String_Syntax.classify_character (String_Syntax.dest_bits_syntax [b0, b1, b2, b3, b4, b5, b6]) :: dest t
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    27
      | dest t = raise Match;
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    28
  in dest end;
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    29
69593
3dda49e08b9d isabelle update -u control_cartouches;
wenzelm
parents: 68940
diff changeset
    30
fun ascii_tr [(c as Const (\<^syntax_const>\<open>_constrain\<close>, _)) $ t $ u] =
68028
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    31
      c $ ascii_tr [t] $ u
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    32
  | ascii_tr [Const (num, _)] =
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    33
      (mk_literal_syntax o single o (fn n => n mod 128) o #value o Lexicon.read_num) num
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    34
  | ascii_tr ts = raise TERM ("ascii_tr", ts);
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    35
69593
3dda49e08b9d isabelle update -u control_cartouches;
wenzelm
parents: 68940
diff changeset
    36
fun literal_tr [(c as Const (\<^syntax_const>\<open>_constrain\<close>, _)) $ t $ u] =
68028
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    37
      c $ literal_tr [t] $ u
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    38
  | literal_tr [Free (str, _)] =
68940
25b431feb2e9 more appropriate conversion of HOL character literals to character codes: symbolic newline is interpreted as 0x10
haftmann
parents: 68028
diff changeset
    39
      (mk_literal_syntax o map String_Syntax.ascii_ord_of o String_Syntax.plain_strings_of) str
68028
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    40
  | literal_tr ts = raise TERM ("literal_tr", ts);
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    41
69593
3dda49e08b9d isabelle update -u control_cartouches;
wenzelm
parents: 68940
diff changeset
    42
fun ascii k = Syntax.const \<^syntax_const>\<open>_Ascii\<close>
68028
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    43
  $ Syntax.free (String_Syntax.hex k);
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    44
69593
3dda49e08b9d isabelle update -u control_cartouches;
wenzelm
parents: 68940
diff changeset
    45
fun literal cs = Syntax.const \<^syntax_const>\<open>_Literal\<close>
68028
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    46
  $ Syntax.const (Lexicon.implode_str cs);
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    47
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    48
fun empty_literal_tr' _ = literal [];
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    49
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    50
fun literal_tr' [b0, b1, b2, b3, b4, b5, b6, t] =
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    51
      let
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    52
        val cs =
69593
3dda49e08b9d isabelle update -u control_cartouches;
wenzelm
parents: 68940
diff changeset
    53
          dest_literal_syntax (list_comb (Syntax.const \<^const_syntax>\<open>String.Literal\<close>, [b0, b1, b2, b3, b4, b5, b6, t]))
68028
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    54
        fun is_printable (Char _) = true
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    55
          | is_printable (Ord _) = false;
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    56
        fun the_char (Char c) = c;
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    57
        fun the_ascii [Ord i] = i;
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    58
      in
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    59
        if forall is_printable cs
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    60
        then literal (map the_char cs)
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    61
        else if length cs = 1
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    62
        then ascii (the_ascii cs)
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    63
        else raise Match
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    64
      end
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    65
  | literal_tr' _ = raise Match;
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    66
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    67
open Basic_Code_Thingol;
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    68
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    69
fun map_partial g f =
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    70
  let
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    71
    fun mapp [] = SOME []
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    72
      | mapp (x :: xs) =
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    73
          (case f x of
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    74
            NONE => NONE
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    75
          | SOME y => 
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    76
            (case mapp xs of
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    77
              NONE => NONE
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    78
            | SOME ys => SOME (y :: ys)))
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    79
  in Option.map g o mapp end;
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    80
69593
3dda49e08b9d isabelle update -u control_cartouches;
wenzelm
parents: 68940
diff changeset
    81
fun implode_bit (IConst { sym = Code_Symbol.Constant \<^const_name>\<open>False\<close>, ... }) = SOME 0
3dda49e08b9d isabelle update -u control_cartouches;
wenzelm
parents: 68940
diff changeset
    82
  | implode_bit (IConst { sym = Code_Symbol.Constant \<^const_name>\<open>True\<close>, ... }) = SOME 1
68028
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    83
  | implode_bit _ = NONE
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    84
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    85
fun implode_ascii (b0, b1, b2, b3, b4, b5, b6) =
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    86
  map_partial (chr o Integer.eval_radix 2) implode_bit [b0, b1, b2, b3, b4, b5, b6];
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    87
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    88
fun implode_literal b0 b1 b2 b3 b4 b5 b6 t =
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    89
  let
69593
3dda49e08b9d isabelle update -u control_cartouches;
wenzelm
parents: 68940
diff changeset
    90
    fun dest_literal (IConst { sym = Code_Symbol.Constant \<^const_name>\<open>String.Literal\<close>, ... }
68028
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    91
          `$ b0 `$ b1 `$ b2 `$ b3 `$ b4 `$ b5 `$ b6 `$ t) = SOME ((b0, b1, b2, b3, b4, b5, b6), t)
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    92
      | dest_literal _ = NONE;
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    93
    val (bss', t') = Code_Thingol.unfoldr dest_literal t;
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    94
    val bss = (b0, b1, b2, b3, b4, b5, b6) :: bss';
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    95
  in
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    96
    case t' of
69593
3dda49e08b9d isabelle update -u control_cartouches;
wenzelm
parents: 68940
diff changeset
    97
      IConst { sym = Code_Symbol.Constant \<^const_name>\<open>String.zero_literal_inst.zero_literal\<close>, ... }
68028
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    98
        => map_partial implode implode_ascii bss
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
    99
    | _ => NONE
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
   100
  end;
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
   101
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
   102
fun add_code target thy =
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
   103
  let
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
   104
    fun pretty literals _ thm _ _ [(b0, _), (b1, _), (b2, _), (b3, _), (b4, _), (b5, _), (b6, _), (t, _)] =
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
   105
      case implode_literal b0 b1 b2 b3 b4 b5 b6 t of
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
   106
        SOME s => (Code_Printer.str o Code_Printer.literal_string literals) s
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
   107
      | NONE => Code_Printer.eqn_error thy thm "Illegal string literal expression";
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
   108
  in
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
   109
    thy
69593
3dda49e08b9d isabelle update -u control_cartouches;
wenzelm
parents: 68940
diff changeset
   110
    |> Code_Target.set_printings (Code_Symbol.Constant (\<^const_name>\<open>String.Literal\<close>,
68028
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
   111
      [(target, SOME (Code_Printer.complex_const_syntax (8, pretty)))]))
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
   112
  end;
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
   113
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
   114
val _ =
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
   115
  Theory.setup
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
   116
   (Sign.parse_translation
69593
3dda49e08b9d isabelle update -u control_cartouches;
wenzelm
parents: 68940
diff changeset
   117
     [(\<^syntax_const>\<open>_Ascii\<close>, K ascii_tr),
3dda49e08b9d isabelle update -u control_cartouches;
wenzelm
parents: 68940
diff changeset
   118
      (\<^syntax_const>\<open>_Literal\<close>, K literal_tr)] #>
68028
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
   119
    Sign.print_translation
69593
3dda49e08b9d isabelle update -u control_cartouches;
wenzelm
parents: 68940
diff changeset
   120
     [(\<^const_syntax>\<open>String.Literal\<close>, K literal_tr'),
3dda49e08b9d isabelle update -u control_cartouches;
wenzelm
parents: 68940
diff changeset
   121
      (\<^const_syntax>\<open>String.empty_literal\<close>, K empty_literal_tr')]);
68028
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
   122
1f9f973eed2a proper datatype for 8-bit characters
haftmann
parents:
diff changeset
   123
end