src/Tools/Code/code_target.ML
changeset 34152 8e5b596d8c73
parent 34081 bb01fd325c6b
child 34173 458ced35abb8
equal deleted inserted replaced
34151:8d57ce46b3f7 34152:8e5b596d8c73
     4 Serializer from intermediate language ("Thin-gol") to target languages.
     4 Serializer from intermediate language ("Thin-gol") to target languages.
     5 *)
     5 *)
     6 
     6 
     7 signature CODE_TARGET =
     7 signature CODE_TARGET =
     8 sig
     8 sig
     9   include CODE_PRINTER
       
    10 
       
    11   type serializer
     9   type serializer
       
    10   type literals = Code_Printer.literals
    12   val add_target: string * (serializer * literals) -> theory -> theory
    11   val add_target: string * (serializer * literals) -> theory -> theory
    13   val extend_target: string *
    12   val extend_target: string *
    14       (string * (Code_Thingol.naming -> Code_Thingol.program -> Code_Thingol.program))
    13       (string * (Code_Thingol.naming -> Code_Thingol.program -> Code_Thingol.program))
    15     -> theory -> theory
    14     -> theory -> theory
    16   val assert_target: theory -> string -> string
    15   val assert_target: theory -> string -> string
    37     -> string list -> (Code_Thingol.naming -> string list) -> string
    36     -> string list -> (Code_Thingol.naming -> string list) -> string
    38   val set_default_code_width: int -> theory -> theory
    37   val set_default_code_width: int -> theory -> theory
    39   val shell_command: string (*theory name*) -> string (*export_code expr*) -> unit
    38   val shell_command: string (*theory name*) -> string (*export_code expr*) -> unit
    40 
    39 
    41   val allow_abort: string -> theory -> theory
    40   val allow_abort: string -> theory -> theory
       
    41   type tyco_syntax = Code_Printer.tyco_syntax
       
    42   type proto_const_syntax = Code_Printer.proto_const_syntax
    42   val add_syntax_class: string -> class -> string option -> theory -> theory
    43   val add_syntax_class: string -> class -> string option -> theory -> theory
    43   val add_syntax_inst: string -> class * string -> unit option -> theory -> theory
    44   val add_syntax_inst: string -> class * string -> unit option -> theory -> theory
    44   val add_syntax_tyco: string -> string -> tyco_syntax option -> theory -> theory
    45   val add_syntax_tyco: string -> string -> tyco_syntax option -> theory -> theory
    45   val add_syntax_const: string -> string -> proto_const_syntax option -> theory -> theory
    46   val add_syntax_const: string -> string -> proto_const_syntax option -> theory -> theory
    46   val add_reserved: string -> string -> theory -> theory
    47   val add_reserved: string -> string -> theory -> theory
    49 
    50 
    50 structure Code_Target : CODE_TARGET =
    51 structure Code_Target : CODE_TARGET =
    51 struct
    52 struct
    52 
    53 
    53 open Basic_Code_Thingol;
    54 open Basic_Code_Thingol;
    54 open Code_Printer;
    55 
       
    56 type literals = Code_Printer.literals;
       
    57 type tyco_syntax = Code_Printer.tyco_syntax;
       
    58 type proto_const_syntax = Code_Printer.proto_const_syntax;
       
    59 
    55 
    60 
    56 (** basics **)
    61 (** basics **)
    57 
    62 
    58 datatype destination = Compile | Export | File of Path.T | String of string list;
    63 datatype destination = Compile | Export | File of Path.T | String of string list;
    59 type serialization = destination -> (string * string option list) option;
    64 type serialization = destination -> (string * string option list) option;
    76 (** theory data **)
    81 (** theory data **)
    77 
    82 
    78 datatype name_syntax_table = NameSyntaxTable of {
    83 datatype name_syntax_table = NameSyntaxTable of {
    79   class: string Symtab.table,
    84   class: string Symtab.table,
    80   instance: unit Symreltab.table,
    85   instance: unit Symreltab.table,
    81   tyco: tyco_syntax Symtab.table,
    86   tyco: Code_Printer.tyco_syntax Symtab.table,
    82   const: proto_const_syntax Symtab.table
    87   const: Code_Printer.proto_const_syntax Symtab.table
    83 };
    88 };
    84 
    89 
    85 fun mk_name_syntax_table ((class, instance), (tyco, const)) =
    90 fun mk_name_syntax_table ((class, instance), (tyco, const)) =
    86   NameSyntaxTable { class = class, instance = instance, tyco = tyco, const = const };
    91   NameSyntaxTable { class = class, instance = instance, tyco = tyco, const = const };
    87 fun map_name_syntax_table f (NameSyntaxTable { class, instance, tyco, const }) =
    92 fun map_name_syntax_table f (NameSyntaxTable { class, instance, tyco, const }) =
   101   -> (string -> string)                 (*labelled_name*)
   106   -> (string -> string)                 (*labelled_name*)
   102   -> string list                        (*reserved symbols*)
   107   -> string list                        (*reserved symbols*)
   103   -> (string * Pretty.T) list           (*includes*)
   108   -> (string * Pretty.T) list           (*includes*)
   104   -> (string -> string option)          (*module aliasses*)
   109   -> (string -> string option)          (*module aliasses*)
   105   -> (string -> string option)          (*class syntax*)
   110   -> (string -> string option)          (*class syntax*)
   106   -> (string -> tyco_syntax option)
   111   -> (string -> Code_Printer.tyco_syntax option)
   107   -> (string -> const_syntax option)
   112   -> (string -> Code_Printer.const_syntax option)
   108   -> ((Pretty.T -> string) * (Pretty.T -> unit))
   113   -> ((Pretty.T -> string) * (Pretty.T -> unit))
   109   -> Code_Thingol.program
   114   -> Code_Thingol.program
   110   -> string list                        (*selected statements*)
   115   -> string list                        (*selected statements*)
   111   -> serialization;
   116   -> serialization;
   112 
   117 
   113 datatype serializer_entry = Serializer of serializer * literals
   118 datatype serializer_entry = Serializer of serializer * Code_Printer.literals
   114   | Extends of string * (Code_Thingol.naming -> Code_Thingol.program -> Code_Thingol.program);
   119   | Extends of string * (Code_Thingol.naming -> Code_Thingol.program -> Code_Thingol.program);
   115 
   120 
   116 datatype target = Target of {
   121 datatype target = Target of {
   117   serial: serial,
   122   serial: serial,
   118   serializer: serializer_entry,
   123   serializer: serializer_entry,
   271       ^ commas (map (Sign.extern_const thy) empty_funs));
   276       ^ commas (map (Sign.extern_const thy) empty_funs));
   272   in
   277   in
   273     serializer module args (Code_Thingol.labelled_name thy program2) reserved includes
   278     serializer module args (Code_Thingol.labelled_name thy program2) reserved includes
   274       (Symtab.lookup module_alias) (Symtab.lookup class')
   279       (Symtab.lookup module_alias) (Symtab.lookup class')
   275       (Symtab.lookup tyco') (Symtab.lookup const')
   280       (Symtab.lookup tyco') (Symtab.lookup const')
   276       (string_of_pretty width, writeln_pretty width)
   281       (Code_Printer.string_of_pretty width, Code_Printer.writeln_pretty width)
   277       program4 names2
   282       program4 names2
   278   end;
   283   end;
   279 
   284 
   280 fun mount_serializer thy alt_serializer target some_width module args naming program names =
   285 fun mount_serializer thy alt_serializer target some_width module args naming program names =
   281   let
   286   let
   394   (cert_class thy class, cert_tyco thy tyco);
   399   (cert_class thy class, cert_tyco thy tyco);
   395 
   400 
   396 fun read_inst thy (raw_tyco, raw_class) =
   401 fun read_inst thy (raw_tyco, raw_class) =
   397   (read_class thy raw_class, read_tyco thy raw_tyco);
   402   (read_class thy raw_class, read_tyco thy raw_tyco);
   398 
   403 
   399 fun gen_add_syntax upd del mapp check_x get_check_syn prep target raw_x some_syn thy =
   404 fun gen_add_syntax upd del mapp check_x check_raw_syn prep_syn prep_x target raw_x some_raw_syn thy =
   400   let
   405   let
   401     val x = prep thy raw_x;
   406     val x = prep_x thy raw_x |> tap (check_x thy);
   402     fun check_syn thy syn = ();
   407     fun prep_check raw_syn = prep_syn (raw_syn |> tap (check_raw_syn thy target));
   403   in case some_syn
   408   in case some_raw_syn
   404    of SOME syn => (map_name_syntax target o mapp) (upd (x, (check_x thy x; check_syn thy syn; syn))) thy
   409    of SOME raw_syn => (map_name_syntax target o mapp) (upd (x, prep_check raw_syn)) thy
   405     | NONE => (map_name_syntax target o mapp) (del x) thy
   410     | NONE => (map_name_syntax target o mapp) (del x) thy
   406   end;
   411   end;
   407 
   412 
   408 fun gen_add_syntax_class prep =
   413 fun gen_add_syntax_class prep_class =
   409   gen_add_syntax Symtab.update Symtab.delete_safe (apfst o apfst) (K I) I prep;
   414   gen_add_syntax Symtab.update Symtab.delete_safe (apfst o apfst) (K I) ((K o K o K) ()) I prep_class;
   410 
   415 
   411 fun gen_add_syntax_inst prep =
   416 fun gen_add_syntax_inst prep_inst =
   412   gen_add_syntax Symreltab.update Symreltab.delete_safe (apfst o apsnd) (K I) I prep;
   417   gen_add_syntax Symreltab.update Symreltab.delete_safe (apfst o apsnd) (K I) ((K o K o K) ()) I prep_inst;
   413 
   418 
   414 fun gen_add_syntax_tyco prep =
   419 fun gen_add_syntax_tyco prep_tyco =
   415   gen_add_syntax Symtab.update Symtab.delete_safe (apsnd o apfst)
   420   gen_add_syntax Symtab.update Symtab.delete_safe (apsnd o apfst)
   416     (fn thy => fn tyco => fn (n, _) => if n <> Sign.arity_number thy tyco
   421     (fn thy => fn tyco => fn (n, _) => if n <> Sign.arity_number thy tyco
   417       then error ("Number of arguments mismatch in syntax for type constructor " ^ quote tyco)
   422       then error ("Number of arguments mismatch in syntax for type constructor " ^ quote tyco)
   418       else ()) I prep;
   423       else ()) ((K o K o K) ()) I prep_tyco;
   419 
   424 
   420 fun gen_add_syntax_const prep =
   425 fun gen_add_syntax_const prep_const check_raw_syn prep_syn =
   421   gen_add_syntax Symtab.update Symtab.delete_safe (apsnd o apsnd)
   426   gen_add_syntax Symtab.update Symtab.delete_safe (apsnd o apsnd)
   422     (fn thy => fn c => fn (n, _) => if n > Code.args_number thy c
   427     (fn thy => fn c => fn (n, _) => if n > Code.args_number thy c
   423       then error ("Too many arguments in syntax for constant " ^ quote c)
   428       then error ("Too many arguments in syntax for constant " ^ quote c)
   424       else ()) I prep;
   429       else ()) check_raw_syn prep_syn prep_const;
   425 
   430 
   426 fun add_reserved target =
   431 fun add_reserved target =
   427   let
   432   let
   428     fun add sym syms = if member (op =) syms sym
   433     fun add sym syms = if member (op =) syms sym
   429       then error ("Reserved symbol " ^ quote sym ^ " already declared")
   434       then error ("Reserved symbol " ^ quote sym ^ " already declared")
   436           let
   441           let
   437             val _ = if Symtab.defined incls name
   442             val _ = if Symtab.defined incls name
   438               then warning ("Overwriting existing include " ^ name)
   443               then warning ("Overwriting existing include " ^ name)
   439               else ();
   444               else ();
   440             val cs = map (read_const thy) raw_cs;
   445             val cs = map (read_const thy) raw_cs;
   441           in Symtab.update (name, (str content, cs)) incls end
   446           in Symtab.update (name, (Code_Printer.str content, cs)) incls end
   442       | add (name, NONE) incls = Symtab.delete name incls;
   447       | add (name, NONE) incls = Symtab.delete name incls;
   443   in map_includes target (add args) thy end;
   448   in map_includes target (add args) thy end;
   444 
   449 
   445 val add_include = gen_add_include (K I);
   450 val add_include = gen_add_include (K I);
   446 val add_include_cmd = gen_add_include Code.read_const;
   451 val add_include_cmd = gen_add_include Code.read_const;
   458 fun gen_allow_abort prep_const raw_c thy =
   463 fun gen_allow_abort prep_const raw_c thy =
   459   let
   464   let
   460     val c = prep_const thy raw_c;
   465     val c = prep_const thy raw_c;
   461   in thy |> (CodeTargetData.map o apfst o apsnd) (insert (op =) c) end;
   466   in thy |> (CodeTargetData.map o apfst o apsnd) (insert (op =) c) end;
   462 
   467 
       
   468 
       
   469 (* concrete syntax *)
       
   470 
       
   471 local
       
   472 
       
   473 structure P = OuterParse
       
   474 and K = OuterKeyword
       
   475 
   463 fun zip_list (x::xs) f g =
   476 fun zip_list (x::xs) f g =
   464   f
   477   f
   465   #-> (fn y =>
   478   #-> (fn y =>
   466     fold_map (fn x => g |-- f >> pair x) xs
   479     fold_map (fn x => g |-- f >> pair x) xs
   467     #-> (fn xys => pair ((x, y) :: xys)));
   480     #-> (fn xys => pair ((x, y) :: xys)));
   468 
   481 
   469 
       
   470 (* concrete syntax *)
       
   471 
       
   472 local
       
   473 
       
   474 structure P = OuterParse
       
   475 and K = OuterKeyword
       
   476 
       
   477 fun parse_multi_syntax parse_thing parse_syntax =
   482 fun parse_multi_syntax parse_thing parse_syntax =
   478   P.and_list1 parse_thing
   483   P.and_list1 parse_thing
   479   #-> (fn things => Scan.repeat1 (P.$$$ "(" |-- P.name --
   484   #-> (fn things => Scan.repeat1 (P.$$$ "(" |-- P.name --
   480         (zip_list things parse_syntax (P.$$$ "and")) --| P.$$$ ")"));
   485         (zip_list things parse_syntax (P.$$$ "and")) --| P.$$$ ")"));
   481 
   486 
   482 in
   487 in
   483 
   488 
   484 val add_syntax_class = gen_add_syntax_class cert_class;
   489 val add_syntax_class = gen_add_syntax_class cert_class;
   485 val add_syntax_inst = gen_add_syntax_inst cert_inst;
   490 val add_syntax_inst = gen_add_syntax_inst cert_inst;
   486 val add_syntax_tyco = gen_add_syntax_tyco cert_tyco;
   491 val add_syntax_tyco = gen_add_syntax_tyco cert_tyco;
   487 val add_syntax_const = gen_add_syntax_const (K I);
   492 val add_syntax_const_simple = gen_add_syntax_const (K I) ((K o K o K) ()) Code_Printer.simple_const_syntax;
       
   493 val add_syntax_const = gen_add_syntax_const (K I) ((K o K o K) ()) I;
   488 val allow_abort = gen_allow_abort (K I);
   494 val allow_abort = gen_allow_abort (K I);
   489 val add_reserved = add_reserved;
   495 val add_reserved = add_reserved;
   490 val add_include = add_include;
   496 val add_include = add_include;
   491 
   497 
   492 val add_syntax_class_cmd = gen_add_syntax_class read_class;
   498 val add_syntax_class_cmd = gen_add_syntax_class read_class;
   493 val add_syntax_inst_cmd = gen_add_syntax_inst read_inst;
   499 val add_syntax_inst_cmd = gen_add_syntax_inst read_inst;
   494 val add_syntax_tyco_cmd = gen_add_syntax_tyco read_tyco;
   500 val add_syntax_tyco_cmd = gen_add_syntax_tyco read_tyco;
   495 val add_syntax_const_cmd = gen_add_syntax_const Code.read_const;
   501 val add_syntax_const_simple_cmd = gen_add_syntax_const Code.read_const ((K o K o K) ()) Code_Printer.simple_const_syntax;
       
   502 val add_syntax_const_cmd = gen_add_syntax_const Code.read_const ((K o K o K) ()) I;
       
   503 
   496 val allow_abort_cmd = gen_allow_abort Code.read_const;
   504 val allow_abort_cmd = gen_allow_abort Code.read_const;
   497 
   505 
   498 fun parse_args f args =
   506 fun parse_args f args =
   499   case Scan.read OuterLex.stopper f args
   507   case Scan.read OuterLex.stopper f args
   500    of SOME x => x
   508    of SOME x => x
   522           fold (fn (raw_class, syn) => add_syntax_class_cmd target raw_class syn) syns)
   530           fold (fn (raw_class, syn) => add_syntax_class_cmd target raw_class syn) syns)
   523   );
   531   );
   524 
   532 
   525 val _ =
   533 val _ =
   526   OuterSyntax.command "code_instance" "define code syntax for instance" K.thy_decl (
   534   OuterSyntax.command "code_instance" "define code syntax for instance" K.thy_decl (
   527     parse_multi_syntax (P.xname --| P.$$$ "::" -- P.xname)
   535     parse_multi_syntax (P.xname --| P.$$$ "::" -- P.xname) (Scan.option (P.minus >> K ()))
   528       (Scan.option (P.minus >> K ()))
       
   529     >> (Toplevel.theory oo fold) (fn (target, syns) =>
   536     >> (Toplevel.theory oo fold) (fn (target, syns) =>
   530           fold (fn (raw_inst, add_del) => add_syntax_inst_cmd target raw_inst add_del) syns)
   537           fold (fn (raw_inst, add_del) => add_syntax_inst_cmd target raw_inst add_del) syns)
   531   );
   538   );
   532 
   539 
   533 val _ =
   540 val _ =
   534   OuterSyntax.command "code_type" "define code syntax for type constructor" K.thy_decl (
   541   OuterSyntax.command "code_type" "define code syntax for type constructor" K.thy_decl (
   535     parse_multi_syntax P.xname (parse_syntax I)
   542     parse_multi_syntax P.xname (Code_Printer.parse_syntax I)
   536     >> (Toplevel.theory oo fold) (fn (target, syns) =>
   543     >> (Toplevel.theory oo fold) (fn (target, syns) =>
   537           fold (fn (raw_tyco, syn) => add_syntax_tyco_cmd target raw_tyco syn) syns)
   544           fold (fn (raw_tyco, syn) => add_syntax_tyco_cmd target raw_tyco syn) syns)
   538   );
   545   );
   539 
   546 
   540 val _ =
   547 val _ =
   541   OuterSyntax.command "code_const" "define code syntax for constant" K.thy_decl (
   548   OuterSyntax.command "code_const" "define code syntax for constant" K.thy_decl (
   542     parse_multi_syntax P.term_group (parse_syntax fst)
   549     parse_multi_syntax P.term_group (Code_Printer.parse_syntax fst)
   543     >> (Toplevel.theory oo fold) (fn (target, syns) =>
   550     >> (Toplevel.theory oo fold) (fn (target, syns) =>
   544       fold (fn (raw_const, syn) => add_syntax_const_cmd target raw_const
   551       fold (fn (raw_const, syn) => add_syntax_const_simple_cmd target raw_const syn) syns)
   545         (Code_Printer.simple_const_syntax syn)) syns)
       
   546   );
   552   );
   547 
   553 
   548 val _ =
   554 val _ =
   549   OuterSyntax.command "code_reserved" "declare words as reserved for target language" K.thy_decl (
   555   OuterSyntax.command "code_reserved" "declare words as reserved for target language" K.thy_decl (
   550     P.name -- Scan.repeat1 P.name
   556     P.name -- Scan.repeat1 P.name