src/Tools/code/code_target.ML
changeset 28064 d4a6460c53d1
parent 28054 2b84d34c5d02
child 28090 29af3c712d2b
equal deleted inserted replaced
28063:3533485fc7b8 28064:d4a6460c53d1
     8 signature CODE_TARGET =
     8 signature CODE_TARGET =
     9 sig
     9 sig
    10   include CODE_PRINTER
    10   include CODE_PRINTER
    11 
    11 
    12   type serializer
    12   type serializer
    13   val add_target: string * serializer -> theory -> theory
    13   val add_target: string * (serializer * literals) -> theory -> theory
    14   val extend_target: string * (string * (Code_Thingol.program -> Code_Thingol.program))
    14   val extend_target: string * (string * (Code_Thingol.program -> Code_Thingol.program))
    15     -> theory -> theory
    15     -> theory -> theory
    16   val assert_target: theory -> string -> string
    16   val assert_target: theory -> string -> string
    17 
    17 
    18   type destination
    18   type destination
    26     -> (Path.T option -> 'a -> unit)
    26     -> (Path.T option -> 'a -> unit)
    27     -> ('a -> string * string list)
    27     -> ('a -> string * string list)
    28     -> 'a -> serialization
    28     -> 'a -> serialization
    29   val serialize: theory -> string -> string option -> Args.T list
    29   val serialize: theory -> string -> string option -> Args.T list
    30     -> Code_Thingol.program -> string list -> serialization
    30     -> Code_Thingol.program -> string list -> serialization
    31   val serialize_custom: theory -> string * serializer
    31   val serialize_custom: theory -> string * (serializer * literals)
    32     -> Code_Thingol.program -> string list -> string * string list
    32     -> Code_Thingol.program -> string list -> string * string list
    33   val compile: serialization -> unit
    33   val compile: serialization -> unit
    34   val export: serialization -> unit
    34   val export: serialization -> unit
    35   val file: Path.T -> serialization -> unit
    35   val file: Path.T -> serialization -> unit
    36   val string: string list -> serialization -> string
    36   val string: string list -> serialization -> string
    49   val add_syntax_const: string -> string -> const_syntax option -> theory -> theory
    49   val add_syntax_const: string -> string -> const_syntax option -> theory -> theory
    50   val add_syntax_constP: string -> string -> OuterParse.token list
    50   val add_syntax_constP: string -> string -> OuterParse.token list
    51     -> (theory -> theory) * OuterParse.token list
    51     -> (theory -> theory) * OuterParse.token list
    52   val add_reserved: string -> string -> theory -> theory
    52   val add_reserved: string -> string -> theory -> theory
    53 
    53 
    54   val add_pretty_list: string -> string -> string -> theory -> theory
    54   val add_literal_list: string -> string -> string -> theory -> theory
    55   val add_pretty_list_string: string -> string -> string
    55   val add_literal_list_string: string -> string -> string
    56     -> string -> string list -> theory -> theory
    56     -> string -> string list -> theory -> theory
    57   val add_pretty_char: string -> string -> string list -> theory -> theory
    57   val add_literal_char: string -> string -> string list -> theory -> theory
    58   val add_pretty_numeral: string -> bool -> bool -> string -> string -> string
    58   val add_literal_numeral: string -> bool -> bool -> string -> string -> string
    59     -> string -> string -> theory -> theory
    59     -> string -> string -> theory -> theory
    60   val add_pretty_message: string -> string -> string list -> string
    60   val add_literal_message: string -> string -> string list -> string
    61     -> string -> string -> theory -> theory
    61     -> string -> string -> theory -> theory
    62 end;
    62 end;
    63 
    63 
    64 structure Code_Target : CODE_TARGET =
    64 structure Code_Target : CODE_TARGET =
    65 struct
    65 struct
   145           in case n of SOME n => SOME (2 * n + b) | NONE => NONE end
   145           in case n of SOME n => SOME (2 * n + b) | NONE => NONE end
   146       | dest_numeral _ = nerror thm "Illegal numeral expression: illegal term";
   146       | dest_numeral _ = nerror thm "Illegal numeral expression: illegal term";
   147   in dest_numeral #> the_default 0 end;
   147   in dest_numeral #> the_default 0 end;
   148 
   148 
   149 
   149 
   150 (* pretty syntax printing *)
   150 (* literal syntax printing *)
   151 
       
   152 local
       
   153 
       
   154 fun ocaml_char c =
       
   155   let
       
   156     fun chr i =
       
   157       let
       
   158         val xs = string_of_int i;
       
   159         val ys = replicate_string (3 - length (explode xs)) "0";
       
   160       in "\\" ^ ys ^ xs end;
       
   161     val i = ord c;
       
   162     val s = if i < 32 orelse i = 34 orelse i = 39 orelse i = 92 orelse i > 126
       
   163       then chr i else c
       
   164   in s end;
       
   165 
       
   166 fun haskell_char c =
       
   167   let
       
   168     val s = ML_Syntax.print_char c;
       
   169   in if s = "'" then "\\'" else s end;
       
   170 
       
   171 val pretty : (string * {
       
   172     pretty_char: string -> string,
       
   173     pretty_string: string -> string,
       
   174     pretty_numeral: bool -> int -> string,
       
   175     pretty_list: Pretty.T list -> Pretty.T,
       
   176     infix_cons: int * string
       
   177   }) list = [
       
   178   ("SML", { pretty_char = prefix "#" o quote o ML_Syntax.print_char,
       
   179       pretty_string = quote o translate_string ML_Syntax.print_char,
       
   180       pretty_numeral = fn unbounded => fn k =>
       
   181         if unbounded then "(" ^ string_of_int k ^ " : IntInf.int)"
       
   182         else string_of_int k,
       
   183       pretty_list = Pretty.enum "," "[" "]",
       
   184       infix_cons = (7, "::")}),
       
   185   ("OCaml", { pretty_char = enclose "'" "'" o ocaml_char,
       
   186       pretty_string = quote o translate_string ocaml_char,
       
   187       pretty_numeral = fn unbounded => fn k => if k >= 0 then
       
   188             if unbounded then
       
   189               "(Big_int.big_int_of_int " ^ string_of_int k ^ ")"
       
   190             else string_of_int k
       
   191           else
       
   192             if unbounded then
       
   193               "(Big_int.big_int_of_int " ^ (enclose "(" ")" o prefix "-"
       
   194                 o string_of_int o op ~) k ^ ")"
       
   195             else (enclose "(" ")" o prefix "-" o string_of_int o op ~) k,
       
   196       pretty_list = Pretty.enum ";" "[" "]",
       
   197       infix_cons = (6, "::")}),
       
   198   ("Haskell", { pretty_char = enclose "'" "'" o haskell_char,
       
   199       pretty_string = quote o translate_string haskell_char,
       
   200       pretty_numeral = fn unbounded => fn k => if k >= 0 then string_of_int k
       
   201           else enclose "(" ")" (signed_string_of_int k),
       
   202       pretty_list = Pretty.enum "," "[" "]",
       
   203       infix_cons = (5, ":")})
       
   204 ];
       
   205 
       
   206 in
       
   207 
       
   208 fun pr_pretty target = case AList.lookup (op =) pretty target
       
   209  of SOME x => x
       
   210   | NONE => error ("Unknown code target language: " ^ quote target);
       
   211 
   151 
   212 fun default_list (target_fxy, target_cons) pr fxy t1 t2 =
   152 fun default_list (target_fxy, target_cons) pr fxy t1 t2 =
   213   brackify_infix (target_fxy, R) fxy [
   153   brackify_infix (target_fxy, R) fxy [
   214     pr (INFX (target_fxy, X)) t1,
   154     pr (INFX (target_fxy, X)) t1,
   215     str target_cons,
   155     str target_cons,
   216     pr (INFX (target_fxy, R)) t2
   156     pr (INFX (target_fxy, R)) t2
   217   ];
   157   ];
   218 
   158 
   219 fun pretty_list c_nil c_cons target =
   159 fun pretty_list c_nil c_cons literals =
   220   let
   160   let
   221     val pretty_ops = pr_pretty target;
   161     val mk_list = literal_list literals;
   222     val mk_list = #pretty_list pretty_ops;
       
   223     fun pretty pr thm pat vars fxy [(t1, _), (t2, _)] =
   162     fun pretty pr thm pat vars fxy [(t1, _), (t2, _)] =
   224       case Option.map (cons t1) (implode_list c_nil c_cons t2)
   163       case Option.map (cons t1) (implode_list c_nil c_cons t2)
   225        of SOME ts => mk_list (map (pr vars NOBR) ts)
   164        of SOME ts => mk_list (map (pr vars NOBR) ts)
   226         | NONE => default_list (#infix_cons pretty_ops) (pr vars) fxy t1 t2;
   165         | NONE => default_list (infix_cons literals) (pr vars) fxy t1 t2;
   227   in (2, pretty) end;
   166   in (2, pretty) end;
   228 
   167 
   229 fun pretty_list_string c_nil c_cons c_char c_nibbles target =
   168 fun pretty_list_string c_nil c_cons c_char c_nibbles literals =
   230   let
   169   let
   231     val pretty_ops = pr_pretty target;
   170     val mk_list = literal_list literals;
   232     val mk_list = #pretty_list pretty_ops;
   171     val mk_char = literal_char literals;
   233     val mk_char = #pretty_char pretty_ops;
   172     val mk_string = literal_string literals;
   234     val mk_string = #pretty_string pretty_ops;
       
   235     fun pretty pr thm pat vars fxy [(t1, _), (t2, _)] =
   173     fun pretty pr thm pat vars fxy [(t1, _), (t2, _)] =
   236       case Option.map (cons t1) (implode_list c_nil c_cons t2)
   174       case Option.map (cons t1) (implode_list c_nil c_cons t2)
   237        of SOME ts => (case implode_string c_char c_nibbles mk_char mk_string ts
   175        of SOME ts => (case implode_string c_char c_nibbles mk_char mk_string ts
   238            of SOME p => p
   176            of SOME p => p
   239             | NONE => mk_list (map (pr vars NOBR) ts))
   177             | NONE => mk_list (map (pr vars NOBR) ts))
   240         | NONE => default_list (#infix_cons pretty_ops) (pr vars) fxy t1 t2;
   178         | NONE => default_list (infix_cons literals) (pr vars) fxy t1 t2;
   241   in (2, pretty) end;
   179   in (2, pretty) end;
   242 
   180 
   243 fun pretty_char c_char c_nibbles target =
   181 fun pretty_char c_char c_nibbles literals =
   244   let
   182   let
   245     val mk_char = #pretty_char (pr_pretty target);
   183     val mk_char = literal_char literals;
   246     fun pretty _ thm _ _ _ [(t1, _), (t2, _)] =
   184     fun pretty _ thm _ _ _ [(t1, _), (t2, _)] =
   247       case decode_char c_nibbles (t1, t2)
   185       case decode_char c_nibbles (t1, t2)
   248        of SOME c => (str o mk_char) c
   186        of SOME c => (str o mk_char) c
   249         | NONE => nerror thm "Illegal character expression";
   187         | NONE => nerror thm "Illegal character expression";
   250   in (2, pretty) end;
   188   in (2, pretty) end;
   251 
   189 
   252 fun pretty_numeral unbounded negative c_pls c_min c_bit0 c_bit1 target =
   190 fun pretty_numeral unbounded negative c_pls c_min c_bit0 c_bit1 literals =
   253   let
   191   let
   254     val mk_numeral = #pretty_numeral (pr_pretty target);
   192     val mk_numeral = literal_numeral literals;
   255     fun pretty _ thm _ _ _ [(t, _)] =
   193     fun pretty _ thm _ _ _ [(t, _)] =
   256       (str o mk_numeral unbounded o implode_numeral thm negative c_pls c_min c_bit0 c_bit1) t;
   194       (str o mk_numeral unbounded o implode_numeral thm negative c_pls c_min c_bit0 c_bit1) t;
   257   in (1, pretty) end;
   195   in (1, pretty) end;
   258 
   196 
   259 fun pretty_message c_char c_nibbles c_nil c_cons target =
   197 fun pretty_message c_char c_nibbles c_nil c_cons literals =
   260   let
   198   let
   261     val pretty_ops = pr_pretty target;
   199     val mk_char = literal_char literals;
   262     val mk_char = #pretty_char pretty_ops;
   200     val mk_string = literal_string literals;
   263     val mk_string = #pretty_string pretty_ops;
       
   264     fun pretty _ thm _ _ _ [(t, _)] =
   201     fun pretty _ thm _ _ _ [(t, _)] =
   265       case implode_list c_nil c_cons t
   202       case implode_list c_nil c_cons t
   266        of SOME ts => (case implode_string c_char c_nibbles mk_char mk_string ts
   203        of SOME ts => (case implode_string c_char c_nibbles mk_char mk_string ts
   267            of SOME p => p
   204            of SOME p => p
   268             | NONE => nerror thm "Illegal message expression")
   205             | NONE => nerror thm "Illegal message expression")
   269         | NONE => nerror thm "Illegal message expression";
   206         | NONE => nerror thm "Illegal message expression";
   270   in (1, pretty) end;
   207   in (1, pretty) end;
   271 
       
   272 end; (*local*)
       
   273 
   208 
   274 
   209 
   275 (** theory data **)
   210 (** theory data **)
   276 
   211 
   277 datatype name_syntax_table = NameSyntaxTable of {
   212 datatype name_syntax_table = NameSyntaxTable of {
   306   -> (string -> const_syntax option)
   241   -> (string -> const_syntax option)
   307   -> Code_Thingol.program
   242   -> Code_Thingol.program
   308   -> string list                        (*selected statements*)
   243   -> string list                        (*selected statements*)
   309   -> serialization;
   244   -> serialization;
   310 
   245 
   311 datatype serializer_entry = Serializer of serializer
   246 datatype serializer_entry = Serializer of serializer * literals
   312   | Extends of string * (Code_Thingol.program -> Code_Thingol.program);
   247   | Extends of string * (Code_Thingol.program -> Code_Thingol.program);
   313 
   248 
   314 datatype target = Target of {
   249 datatype target = Target of {
   315   serial: serial,
   250   serial: serial,
   316   serializer: serializer_entry,
   251   serializer: serializer_entry,
   560 fun add_syntax_tycoP target tyco = parse_syntax I
   495 fun add_syntax_tycoP target tyco = parse_syntax I
   561   >> add_syntax_tyco_cmd target tyco;
   496   >> add_syntax_tyco_cmd target tyco;
   562 fun add_syntax_constP target c = parse_syntax fst
   497 fun add_syntax_constP target c = parse_syntax fst
   563   >> (add_syntax_const_cmd target c o Code_Printer.simple_const_syntax);
   498   >> (add_syntax_const_cmd target c o Code_Printer.simple_const_syntax);
   564 
   499 
   565 fun add_pretty_list target nill cons thy =
   500 fun the_literals thy =
       
   501   let
       
   502     val (targets, _) = CodeTargetData.get thy;
       
   503     fun literals target = case Symtab.lookup targets target
       
   504      of SOME data => (case the_serializer data
       
   505          of Serializer (_, literals) => literals
       
   506           | Extends (super, _) => literals super)
       
   507       | NONE => error ("Unknown code target language: " ^ quote target);
       
   508   in literals end;
       
   509 
       
   510 fun add_literal_list target nill cons thy =
   566   let
   511   let
   567     val nil' = Code_Name.const thy nill;
   512     val nil' = Code_Name.const thy nill;
   568     val cons' = Code_Name.const thy cons;
   513     val cons' = Code_Name.const thy cons;
   569     val pr = pretty_list nil' cons' target;
   514     val pr = pretty_list nil' cons' (the_literals thy target);
   570   in
   515   in
   571     thy
   516     thy
   572     |> add_syntax_const target cons (SOME pr)
   517     |> add_syntax_const target cons (SOME pr)
   573   end;
   518   end;
   574 
   519 
   575 fun add_pretty_list_string target nill cons charr nibbles thy =
   520 fun add_literal_list_string target nill cons charr nibbles thy =
   576   let
   521   let
   577     val nil' = Code_Name.const thy nill;
   522     val nil' = Code_Name.const thy nill;
   578     val cons' = Code_Name.const thy cons;
   523     val cons' = Code_Name.const thy cons;
   579     val charr' = Code_Name.const thy charr;
   524     val charr' = Code_Name.const thy charr;
   580     val nibbles' = map (Code_Name.const thy) nibbles;
   525     val nibbles' = map (Code_Name.const thy) nibbles;
   581     val pr = pretty_list_string nil' cons' charr' nibbles' target;
   526     val pr = pretty_list_string nil' cons' charr' nibbles' (the_literals thy target);
   582   in
   527   in
   583     thy
   528     thy
   584     |> add_syntax_const target cons (SOME pr)
   529     |> add_syntax_const target cons (SOME pr)
   585   end;
   530   end;
   586 
   531 
   587 fun add_pretty_char target charr nibbles thy =
   532 fun add_literal_char target charr nibbles thy =
   588   let
   533   let
   589     val charr' = Code_Name.const thy charr;
   534     val charr' = Code_Name.const thy charr;
   590     val nibbles' = map (Code_Name.const thy) nibbles;
   535     val nibbles' = map (Code_Name.const thy) nibbles;
   591     val pr = pretty_char charr' nibbles' target;
   536     val pr = pretty_char charr' nibbles' (the_literals thy target);
   592   in
   537   in
   593     thy
   538     thy
   594     |> add_syntax_const target charr (SOME pr)
   539     |> add_syntax_const target charr (SOME pr)
   595   end;
   540   end;
   596 
   541 
   597 fun add_pretty_numeral target unbounded negative number_of pls min bit0 bit1 thy =
   542 fun add_literal_numeral target unbounded negative number_of pls min bit0 bit1 thy =
   598   let
   543   let
   599     val pls' = Code_Name.const thy pls;
   544     val pls' = Code_Name.const thy pls;
   600     val min' = Code_Name.const thy min;
   545     val min' = Code_Name.const thy min;
   601     val bit0' = Code_Name.const thy bit0;
   546     val bit0' = Code_Name.const thy bit0;
   602     val bit1' = Code_Name.const thy bit1;
   547     val bit1' = Code_Name.const thy bit1;
   603     val pr = pretty_numeral unbounded negative pls' min' bit0' bit1' target;
   548     val pr = pretty_numeral unbounded negative pls' min' bit0' bit1' (the_literals thy target);
   604   in
   549   in
   605     thy
   550     thy
   606     |> add_syntax_const target number_of (SOME pr)
   551     |> add_syntax_const target number_of (SOME pr)
   607   end;
   552   end;
   608 
   553 
   609 fun add_pretty_message target charr nibbles nill cons str thy =
   554 fun add_literal_message target charr nibbles nill cons str thy =
   610   let
   555   let
   611     val charr' = Code_Name.const thy charr;
   556     val charr' = Code_Name.const thy charr;
   612     val nibbles' = map (Code_Name.const thy) nibbles;
   557     val nibbles' = map (Code_Name.const thy) nibbles;
   613     val nil' = Code_Name.const thy nill;
   558     val nil' = Code_Name.const thy nill;
   614     val cons' = Code_Name.const thy cons;
   559     val cons' = Code_Name.const thy cons;
   615     val pr = pretty_message charr' nibbles' nil' cons' target;
   560     val pr = pretty_message charr' nibbles' nil' cons' (the_literals thy target);
   616   in
   561   in
   617     thy
   562     thy
   618     |> add_syntax_const target str (SOME pr)
   563     |> add_syntax_const target str (SOME pr)
   619   end;
   564   end;
   620 
   565 
   656         | Extends (super, modify) => let
   601         | Extends (super, modify) => let
   657             val (modify', data') = collapse_hierarchy super
   602             val (modify', data') = collapse_hierarchy super
   658           in (modify' #> modify, merge_target false target (data', data)) end
   603           in (modify' #> modify, merge_target false target (data', data)) end
   659       end;
   604       end;
   660     val (modify, data) = collapse_hierarchy target;
   605     val (modify, data) = collapse_hierarchy target;
   661     val serializer = the_default (case the_serializer data
   606     val (serializer, _) = the_default (case the_serializer data
   662      of Serializer seri => seri) alt_serializer;
   607      of Serializer seri => seri) alt_serializer;
   663     val reserved = the_reserved data;
   608     val reserved = the_reserved data;
   664     val includes = Symtab.dest (the_includes data);
   609     val includes = Symtab.dest (the_includes data);
   665     val module_alias = the_module_alias data;
   610     val module_alias = the_module_alias data;
   666     val { class, inst, tyco, const } = the_name_syntax data;
   611     val { class, inst, tyco, const } = the_name_syntax data;