src/Pure/General/xml_data.ML
changeset 43724 4e58485fa320
parent 43698 91c4d7397f0e
child 43725 bebcfcad12d4
equal deleted inserted replaced
43723:8a63c95b1d5b 43724:4e58485fa320
     4 XML as basic data representation language.
     4 XML as basic data representation language.
     5 *)
     5 *)
     6 
     6 
     7 signature XML_DATA =
     7 signature XML_DATA =
     8 sig
     8 sig
       
     9   structure Make:
       
    10   sig
       
    11     val properties: Properties.T -> XML.body
       
    12     val string: string -> XML.body
       
    13     val int: int -> XML.body
       
    14     val bool: bool -> XML.body
       
    15     val unit: unit -> XML.body
       
    16     val pair: ('a -> XML.body) -> ('b -> XML.body) -> 'a * 'b -> XML.body
       
    17     val triple: ('a -> XML.body) -> ('b -> XML.body) -> ('c -> XML.body) -> 'a * 'b * 'c -> XML.body
       
    18     val list: ('a -> XML.body) -> 'a list -> XML.body
       
    19     val option: ('a -> XML.body) -> 'a option -> XML.body
       
    20     val variant: ('a -> XML.body) list -> 'a -> XML.body
       
    21   end
     9   exception XML_ATOM of string
    22   exception XML_ATOM of string
    10   exception XML_BODY of XML.body
    23   exception XML_BODY of XML.body
    11   val make_properties: Properties.T -> XML.body
    24   structure Dest:
    12   val dest_properties: XML.body -> Properties.T
    25   sig
    13   val make_string: string -> XML.body
    26     val properties: XML.body -> Properties.T
    14   val dest_string : XML.body -> string
    27     val string : XML.body -> string
    15   val make_int: int -> XML.body
    28     val int : XML.body -> int
    16   val dest_int : XML.body -> int
    29     val bool: XML.body -> bool
    17   val make_bool: bool -> XML.body
    30     val unit: XML.body -> unit
    18   val dest_bool: XML.body -> bool
    31     val pair: (XML.body -> 'a) -> (XML.body -> 'b) -> XML.body -> 'a * 'b
    19   val make_unit: unit -> XML.body
    32     val triple: (XML.body -> 'a) -> (XML.body -> 'b) -> (XML.body -> 'c) -> XML.body -> 'a * 'b * 'c
    20   val dest_unit: XML.body -> unit
    33     val list: (XML.body -> 'a) -> XML.body -> 'a list
    21   val make_pair: ('a -> XML.body) -> ('b -> XML.body) -> 'a * 'b -> XML.body
    34     val option: (XML.body -> 'a) -> XML.body -> 'a option
    22   val dest_pair: (XML.body -> 'a) -> (XML.body -> 'b) -> XML.body -> 'a * 'b
    35     val variant: (XML.body -> 'a) list -> XML.body -> 'a
    23   val make_triple:
    36   end
    24     ('a -> XML.body) -> ('b -> XML.body) -> ('c -> XML.body) -> 'a * 'b * 'c -> XML.body
       
    25   val dest_triple:
       
    26     (XML.body -> 'a) -> (XML.body -> 'b) -> (XML.body -> 'c) -> XML.body -> 'a * 'b * 'c
       
    27   val make_list: ('a -> XML.body) -> 'a list -> XML.body
       
    28   val dest_list: (XML.body -> 'a) -> XML.body -> 'a list
       
    29   val make_option: ('a -> XML.body) -> 'a option -> XML.body
       
    30   val dest_option: (XML.body -> 'a) -> XML.body -> 'a option
       
    31   val make_variant: ('a -> XML.body) list -> 'a -> XML.body
       
    32   val dest_variant: (XML.body -> 'a) list -> XML.body -> 'a
       
    33 end;
    37 end;
    34 
    38 
    35 structure XML_Data: XML_DATA =
    39 structure XML_Data: XML_DATA =
    36 struct
    40 struct
    37 
    41 
       
    42 (** make **)
       
    43 
       
    44 structure Make =
       
    45 struct
       
    46 
    38 (* basic values *)
    47 (* basic values *)
    39 
    48 
    40 exception XML_ATOM of string;
    49 fun int_atom i = signed_string_of_int i;
       
    50 
       
    51 fun bool_atom false = "0"
       
    52   | bool_atom true = "1";
       
    53 
       
    54 fun unit_atom () = "";
    41 
    55 
    42 
    56 
    43 fun make_int_atom i = signed_string_of_int i;
    57 (* structural nodes *)
    44 
    58 
    45 fun dest_int_atom s =
    59 fun node ts = XML.Elem ((":", []), ts);
       
    60 
       
    61 fun tagged (tag, ts) = XML.Elem ((int_atom tag, []), ts);
       
    62 
       
    63 
       
    64 (* representation of standard types *)
       
    65 
       
    66 fun properties props = [XML.Elem ((":", props), [])];
       
    67 
       
    68 fun string "" = []
       
    69   | string s = [XML.Text s];
       
    70 
       
    71 val int = string o int_atom;
       
    72 
       
    73 val bool = string o bool_atom;
       
    74 
       
    75 val unit = string o unit_atom;
       
    76 
       
    77 fun pair f g (x, y) = [node (f x), node (g y)];
       
    78 
       
    79 fun triple f g h (x, y, z) = [node (f x), node (g y), node (h z)];
       
    80 
       
    81 fun list f xs = map (node o f) xs;
       
    82 
       
    83 fun option _ NONE = []
       
    84   | option f (SOME x) = [node (f x)];
       
    85 
       
    86 fun variant fs x = [tagged (the (get_index (fn f => try f x) fs))];
       
    87 
       
    88 end;
       
    89 
       
    90 
       
    91 
       
    92 (** dest **)
       
    93 
       
    94 exception XML_ATOM of string;
       
    95 exception XML_BODY of XML.tree list;
       
    96 
       
    97 structure Dest =
       
    98 struct
       
    99 
       
   100 (* basic values *)
       
   101 
       
   102 fun int_atom s =
    46   (case Int.fromString s of
   103   (case Int.fromString s of
    47     SOME i => i
   104     SOME i => i
    48   | NONE => raise XML_ATOM s);
   105   | NONE => raise XML_ATOM s);
    49 
   106 
       
   107 fun bool_atom "0" = false
       
   108   | bool_atom "1" = true
       
   109   | bool_atom s = raise XML_ATOM s;
    50 
   110 
    51 fun make_bool_atom false = "0"
   111 fun unit_atom "" = ()
    52   | make_bool_atom true = "1";
   112   | unit_atom s = raise XML_ATOM s;
    53 
       
    54 fun dest_bool_atom "0" = false
       
    55   | dest_bool_atom "1" = true
       
    56   | dest_bool_atom s = raise XML_ATOM s;
       
    57 
       
    58 
       
    59 fun make_unit_atom () = "";
       
    60 
       
    61 fun dest_unit_atom "" = ()
       
    62   | dest_unit_atom s = raise XML_ATOM s;
       
    63 
   113 
    64 
   114 
    65 (* structural nodes *)
   115 (* structural nodes *)
    66 
   116 
    67 exception XML_BODY of XML.tree list;
   117 fun node (XML.Elem ((":", []), ts)) = ts
       
   118   | node t = raise XML_BODY [t];
    68 
   119 
    69 fun make_node ts = XML.Elem ((":", []), ts);
   120 fun tagged (XML.Elem ((s, []), ts)) = (int_atom s, ts)
    70 
   121   | tagged t = raise XML_BODY [t];
    71 fun dest_node (XML.Elem ((":", []), ts)) = ts
       
    72   | dest_node t = raise XML_BODY [t];
       
    73 
       
    74 fun make_tagged (tag, ts) = XML.Elem ((make_int_atom tag, []), ts);
       
    75 
       
    76 fun dest_tagged (XML.Elem ((s, []), ts)) = (dest_int_atom s, ts)
       
    77   | dest_tagged t = raise XML_BODY [t];
       
    78 
   122 
    79 
   123 
    80 (* representation of standard types *)
   124 (* representation of standard types *)
    81 
   125 
    82 fun make_properties props = [XML.Elem ((":", props), [])];
   126 fun properties [XML.Elem ((":", props), [])] = props
       
   127   | properties ts = raise XML_BODY ts;
    83 
   128 
    84 fun dest_properties [XML.Elem ((":", props), [])] = props
   129 fun string [] = ""
    85   | dest_properties ts = raise XML_BODY ts;
   130   | string [XML.Text s] = s
       
   131   | string ts = raise XML_BODY ts;
    86 
   132 
       
   133 val int = int_atom o string;
    87 
   134 
    88 fun make_string "" = []
   135 val bool = bool_atom o string;
    89   | make_string s = [XML.Text s];
       
    90 
   136 
    91 fun dest_string [] = ""
   137 val unit = unit_atom o string;
    92   | dest_string [XML.Text s] = s
       
    93   | dest_string ts = raise XML_BODY ts;
       
    94 
   138 
       
   139 fun pair f g [t1, t2] = (f (node t1), g (node t2))
       
   140   | pair _ _ ts = raise XML_BODY ts;
    95 
   141 
    96 val make_int = make_string o make_int_atom;
   142 fun triple f g h [t1, t2, t3] = (f (node t1), g (node t2), h (node t3))
    97 val dest_int = dest_int_atom o dest_string;
   143   | triple _ _ _ ts = raise XML_BODY ts;
    98 
   144 
    99 val make_bool = make_string o make_bool_atom;
   145 fun list f ts = map (f o node) ts;
   100 val dest_bool = dest_bool_atom o dest_string;
       
   101 
   146 
   102 val make_unit = make_string o make_unit_atom;
   147 fun option _ [] = NONE
   103 val dest_unit = dest_unit_atom o dest_string;
   148   | option f [t] = SOME (f (node t))
       
   149   | option _ ts = raise XML_BODY ts;
   104 
   150 
   105 
   151 fun variant fs [t] = uncurry (nth fs) (tagged t)
   106 fun make_pair make1 make2 (x, y) = [make_node (make1 x), make_node (make2 y)];
   152   | variant _ ts = raise XML_BODY ts;
   107 
       
   108 fun dest_pair dest1 dest2 [t1, t2] = (dest1 (dest_node t1), dest2 (dest_node t2))
       
   109   | dest_pair _ _ ts = raise XML_BODY ts;
       
   110 
       
   111 
       
   112 fun make_triple make1 make2 make3 (x, y, z) =
       
   113   [make_node (make1 x), make_node (make2 y), make_node (make3 z)];
       
   114 
       
   115 fun dest_triple dest1 dest2 dest3 [t1, t2, t3] =
       
   116       (dest1 (dest_node t1), dest2 (dest_node t2), dest3 (dest_node t3))
       
   117   | dest_triple _ _ _ ts = raise XML_BODY ts;
       
   118 
       
   119 
       
   120 fun make_list make xs = map (make_node o make) xs;
       
   121 
       
   122 fun dest_list dest ts = map (dest o dest_node) ts;
       
   123 
       
   124 
       
   125 fun make_option _ NONE = []
       
   126   | make_option make (SOME x) = [make_node (make x)];
       
   127 
       
   128 fun dest_option _ [] = NONE
       
   129   | dest_option dest [t] = SOME (dest (dest_node t))
       
   130   | dest_option _ ts = raise XML_BODY ts;
       
   131 
       
   132 
       
   133 fun make_variant makes x =
       
   134   [make_tagged (the (get_index (fn make => try make x) makes))];
       
   135 
       
   136 fun dest_variant dests [t] =
       
   137       let val (tag, ts) = dest_tagged t
       
   138       in nth dests tag ts end
       
   139   | dest_variant _ ts = raise XML_BODY ts;
       
   140 
   153 
   141 end;
   154 end;
   142 
   155 
       
   156 end;
       
   157