src/Pure/Syntax/sextension.ML
changeset 238 6af40e3a2bcb
parent 165 793be9f1e88e
child 259 9c648760dba3
equal deleted inserted replaced
237:a7d3e712767a 238:6af40e3a2bcb
     4 
     4 
     5 Syntax extensions (external interface): mixfix declarations, infixes,
     5 Syntax extensions (external interface): mixfix declarations, infixes,
     6 binders, translation rules / functions and the Pure syntax.
     6 binders, translation rules / functions and the Pure syntax.
     7 
     7 
     8 TODO:
     8 TODO:
     9   move ast_to_term (?)
     9   move ast_to_term, pt_to_ast (?)
    10 *)
    10 *)
    11 
    11 
    12 infix |-> <-| <->;
    12 infix |-> <-| <->;
    13 
    13 
    14 signature SEXTENSION0 =
    14 signature SEXTENSION0 =
    15 sig
    15 sig
    16   structure Ast: AST
    16   structure Parser: PARSER
    17   local open Ast in
    17   local open Parser.SynExt.Ast in
    18     datatype mixfix =
    18     datatype mixfix =
    19       Mixfix of string * string * string * int list * int |
    19       Mixfix of string * string * string * int list * int |
    20       Delimfix of string * string * string |
    20       Delimfix of string * string * string |
    21       Infixl of string * string * int |
    21       Infixl of string * string * int |
    22       Infixr of string * string * int |
    22       Infixr of string * string * int |
    59 end;
    59 end;
    60 
    60 
    61 signature SEXTENSION =
    61 signature SEXTENSION =
    62 sig
    62 sig
    63   include SEXTENSION1
    63   include SEXTENSION1
    64   structure Extension: EXTENSION
    64   local open Parser Parser.SynExt Parser.SynExt.Ast in
    65   sharing Extension.XGram.Ast = Ast
       
    66   local open Extension Ast in
       
    67     val xrules_of: sext -> xrule list
    65     val xrules_of: sext -> xrule list
    68     val abs_tr': term -> term
    66     val abs_tr': term -> term
    69     val appl_ast_tr': ast * ast list -> ast
    67     val appl_ast_tr': ast * ast list -> ast
    70     val ext_of_sext: string list -> string list -> (string -> typ) -> sext -> ext
    68     val syn_ext_of_sext: string list -> string list -> (string -> typ) -> sext -> syn_ext
       
    69     val pt_to_ast: (string -> (ast list -> ast) option) -> parsetree -> ast
    71     val ast_to_term: (string -> (term list -> term) option) -> ast -> term
    70     val ast_to_term: (string -> (term list -> term) option) -> ast -> term
    72     val constrainIdtC: string
       
    73     val apropC: string
    71     val apropC: string
    74   end
    72   end
    75 end;
    73 end;
    76 
    74 
    77 functor SExtensionFun(structure TypeExt: TYPE_EXT and Lexicon: LEXICON): SEXTENSION =
    75 functor SExtensionFun(Parser: PARSER): SEXTENSION =
    78 struct
    76 struct
    79 
    77 
    80 structure Extension = TypeExt.Extension;
    78 structure Parser = Parser;
    81 structure Ast = Extension.XGram.Ast;
    79 open Parser.Lexicon Parser.SynExt.Ast Parser.SynExt Parser;
    82 open Lexicon Extension Extension.XGram Ast;
       
    83 
    80 
    84 
    81 
    85 (** datatype sext **)
    82 (** datatype sext **)
    86 
    83 
    87 datatype mixfix =
    84 datatype mixfix =
   212 fun bigimpl_ast_tr (*"_bigimpl"*) [asms, concl] =
   209 fun bigimpl_ast_tr (*"_bigimpl"*) [asms, concl] =
   213       fold_ast_p "==>" (unfold_ast "_asms" asms, concl)
   210       fold_ast_p "==>" (unfold_ast "_asms" asms, concl)
   214   | bigimpl_ast_tr (*"_bigimpl"*) asts = raise_ast "bigimpl_ast_tr" asts;
   211   | bigimpl_ast_tr (*"_bigimpl"*) asts = raise_ast "bigimpl_ast_tr" asts;
   215 
   212 
   216 
   213 
       
   214 (* explode atoms *)  (* FIXME check, leading 0s (?) *)
       
   215 
       
   216 fun explode_tr (*"_explode"*) [consC, nilC, bit0, bit1, Free (str, _)] =
       
   217       let
       
   218         fun mk_list [] = nilC
       
   219           | mk_list (t :: ts) = consC $ t $ mk_list ts;
       
   220 
       
   221         fun encode_bit 0 = bit0
       
   222           | encode_bit 1 = bit1
       
   223           | encode_bit _ = sys_error "encode_bit";
       
   224 
       
   225         fun encode_char c =
       
   226           mk_list (map encode_bit (radixpand (2, (ord c))));
       
   227       in
       
   228         mk_list (map encode_char (explode str))
       
   229       end
       
   230   | explode_tr (*"_explode"*) ts = raise_term "explode_tr" ts;
       
   231 
       
   232 
   217 
   233 
   218 (** print (ast) translations **)
   234 (** print (ast) translations **)
   219 
   235 
   220 (* application *)
   236 (* application *)
   221 
   237 
   317         in list_comb (Const (q, dummyT) $ Free (x', T) $ A $ B', ts) end
   333         in list_comb (Const (q, dummyT) $ Free (x', T) $ A $ B', ts) end
   318       else list_comb (Const (r, dummyT) $ A $ B, ts)
   334       else list_comb (Const (r, dummyT) $ A $ B, ts)
   319   | dependent_tr' _ _ = raise Match;
   335   | dependent_tr' _ _ = raise Match;
   320 
   336 
   321 
   337 
   322 
   338 (* implode atoms *)  (* FIXME check *)
   323 (** ext_of_sext **)
   339 
       
   340 fun implode_ast_tr' (*"_implode"*) (asts as [Constant cons_name, nilC,
       
   341     bit0, bit1, bitss]) =
       
   342       let
       
   343         fun fail () = raise_ast "implode_ast_tr'" asts;
       
   344 
       
   345         fun strip_list lst =
       
   346           let val (xs, y) = unfold_ast_p cons_name lst
       
   347           in if y = nilC then xs else fail ()
       
   348           end;
       
   349 
       
   350         fun decode_bit bit =
       
   351           if bit = bit0 then "0" else if bit = bit1 then "1" else fail ();
       
   352 
       
   353         fun decode_char bits =
       
   354           chr (#1 (scan_radixint (2, map decode_bit (strip_list bits))));
       
   355       in
       
   356         Variable (implode (map decode_char (strip_list bitss)))
       
   357       end
       
   358   | implode_ast_tr' (*"_implode"*) asts = raise_ast "implode_ast_tr'" asts;
       
   359 
       
   360 
       
   361 
       
   362 (** syn_ext_of_sext **)
   324 
   363 
   325 fun strip_esc str =
   364 fun strip_esc str =
   326   let
   365   let
   327     fun strip ("'" :: c :: cs) = c :: strip cs
   366     fun strip ("'" :: c :: cs) = c :: strip cs
   328       | strip ["'"] = []
   367       | strip ["'"] = []
   333   end;
   372   end;
   334 
   373 
   335 fun infix_name sy = "op " ^ strip_esc sy;
   374 fun infix_name sy = "op " ^ strip_esc sy;
   336 
   375 
   337 
   376 
   338 fun ext_of_sext roots xconsts read_typ sext =
   377 fun syn_ext_of_sext roots xconsts read_typ sext =
   339   let
   378   let
   340     val {mixfix, parse_ast_translation, parse_translation, print_translation,
   379     val {mixfix, parse_ast_translation, parse_translation, print_translation,
   341       print_ast_translation, ...} = sext_components sext;
   380       print_ast_translation, ...} = sext_components sext;
   342 
   381 
   343     val tinfixT = [typeT, typeT] ---> typeT;
   382     val tinfixT = [typeT, typeT] ---> typeT;
   349       (case read_typ ty of
   388       (case read_typ ty of
   350         Type ("fun", [Type ("fun", [_, T2]), T3]) =>
   389         Type ("fun", [Type ("fun", [_, T2]), T3]) =>
   351           [Type ("idts", []), T2] ---> T3
   390           [Type ("idts", []), T2] ---> T3
   352       | _ => error ("Illegal binder type " ^ quote ty));
   391       | _ => error ("Illegal binder type " ^ quote ty));
   353 
   392 
   354     fun mk_infix sy T c p1 p2 p3 =
   393     fun mk_infix sy ty c p1 p2 p3 =
   355       [Mfix ("op " ^ sy, T, c, [], max_pri),
   394       [Mfix ("(_ " ^ sy ^ "/ _)", ty, c, [p1, p2], p3),
   356        Mfix ("(_ " ^ sy ^ "/ _)", T, c, [p1, p2], p3)];
   395        Mfix ("op " ^ sy, ty, c, [], max_pri)];
   357 
   396 
   358     fun mfix_of (Mixfix (sy, ty, c, ps, p)) = [Mfix (sy, read_typ ty, c, ps, p)]
   397     fun mfix_of (Mixfix (sy, ty, c, ps, p)) = [Mfix (sy, read_typ ty, c, ps, p)]
   359       | mfix_of (Delimfix (sy, ty, c)) = [Mfix (sy, read_typ ty, c, [], max_pri)]
   398       | mfix_of (Delimfix (sy, ty, c)) = [Mfix (sy, read_typ ty, c, [], max_pri)]
   360       | mfix_of (Infixl (sy, ty, p)) =
   399       | mfix_of (Infixl (sy, ty, p)) =
   361           mk_infix sy (read_typ ty) (infix_name sy) p (p + 1) p
   400           mk_infix sy (read_typ ty) (infix_name sy) p (p + 1) p
   369           [Mfix ("(_ " ^ s ^ "/ _)", tinfixT, c, [p + 1, p], p)];
   408           [Mfix ("(_ " ^ s ^ "/ _)", tinfixT, c, [p + 1, p], p)];
   370 
   409 
   371     val mfix = flat (map mfix_of mixfix);
   410     val mfix = flat (map mfix_of mixfix);
   372     val binders = mapfilter binder mixfix;
   411     val binders = mapfilter binder mixfix;
   373     val bparses = map mk_binder_tr binders;
   412     val bparses = map mk_binder_tr binders;
   374     val bprints = map (mk_binder_tr' o (fn (x, y) => (y, x))) binders;
   413     val bprints = map (mk_binder_tr' o swap) binders;
   375   in
   414   in
   376     Ext {
   415     syn_ext roots mfix (distinct (filter is_xid xconsts))
   377       roots = roots, mfix = mfix,
   416       (parse_ast_translation,
   378       extra_consts = distinct (filter is_xid xconsts),
   417         bparses @ parse_translation,
   379       parse_ast_translation = parse_ast_translation,
   418         bprints @ print_translation,
   380       parse_translation = bparses @ parse_translation,
   419         print_ast_translation)
   381       print_translation = bprints @ print_translation,
   420       ([], [])
   382       print_ast_translation = print_ast_translation}
       
   383   end;
   421   end;
   384 
   422 
   385 
   423 
   386 
   424 
   387 (** constants **)
   425 (** constants **)
   394       | consts (Infixr (c, ty, _)) = ([infix_name c], ty)
   432       | consts (Infixr (c, ty, _)) = ([infix_name c], ty)
   395       | consts (Binder (_, ty, c, _, _)) = ([c], ty)
   433       | consts (Binder (_, ty, c, _, _)) = ([c], ty)
   396       | consts _ = ([""], "");    (*is filtered out below*)
   434       | consts _ = ([""], "");    (*is filtered out below*)
   397   in
   435   in
   398     distinct (filter_out (fn (l, _) => l = [""]) (map consts (mixfix_of sext)))
   436     distinct (filter_out (fn (l, _) => l = [""]) (map consts (mixfix_of sext)))
       
   437   end;
       
   438 
       
   439 
       
   440 
       
   441 (** pt_to_ast **)
       
   442 
       
   443 fun pt_to_ast trf pt =
       
   444   let
       
   445     fun trans a args =
       
   446       (case trf a of
       
   447         None => mk_appl (Constant a) args
       
   448       | Some f => f args handle exn
       
   449           => (writeln ("Error in parse ast translation for " ^ quote a); raise exn));
       
   450 
       
   451     fun ast_of (Node (a, pts)) = trans a (map ast_of pts)
       
   452       | ast_of (Tip tok) = Variable (str_of_token tok);
       
   453   in
       
   454     ast_of pt
   399   end;
   455   end;
   400 
   456 
   401 
   457 
   402 
   458 
   403 (** ast_to_term **)
   459 (** ast_to_term **)
   436       Delimfix ("'(_')",      "idt => idt",                    ""),
   492       Delimfix ("'(_')",      "idt => idt",                    ""),
   437       Delimfix ("_",          "idt => idts",                   ""),
   493       Delimfix ("_",          "idt => idts",                   ""),
   438       Mixfix   ("_/ _",       "[idt, idts] => idts",           "_idts", [1, 0], 0),
   494       Mixfix   ("_/ _",       "[idt, idts] => idts",           "_idts", [1, 0], 0),
   439       Delimfix ("_",          "id => aprop",                   ""),
   495       Delimfix ("_",          "id => aprop",                   ""),
   440       Delimfix ("_",          "var => aprop",                  ""),
   496       Delimfix ("_",          "var => aprop",                  ""),
   441       Mixfix   ("(1_/(1'(_')))", "[('b => 'a), " ^ args ^ "] => aprop", applC, [max_pri, 0], 0),
   497       Mixfix   ("(1_/(1'(_')))", "[('b => 'a), " ^ args ^ "] => aprop", applC, [max_pri, 0], max_pri),  (* FIXME lhs pri: 0 vs. max_pri *)
   442       Delimfix ("PROP _",     "aprop => prop",                 "_aprop"),
   498       Delimfix ("PROP _",     "aprop => prop",                 "_aprop"),
   443       Delimfix ("_",          "prop => asms",                  ""),
   499       Delimfix ("_",          "prop => asms",                  ""),
   444       Delimfix ("_;/ _",      "[prop, asms] => asms",          "_asms"),
   500       Delimfix ("_;/ _",      "[prop, asms] => asms",          "_asms"),
   445       Mixfix   ("((3[| _ |]) ==>/ _)", "[asms, prop] => prop", "_bigimpl", [0, 1], 1),
   501       Mixfix   ("((3[| _ |]) ==>/ _)", "[asms, prop] => prop", "_bigimpl", [0, 1], 1),
   446       Mixfix   ("(_ ==/ _)",  "['a::{}, 'a] => prop",          "==", [3, 2], 2),
   502       Mixfix   ("(_ ==/ _)",  "['a::{}, 'a] => prop",          "==", [3, 2], 2),
   447       Mixfix   ("(_ =?=/ _)", "['a::{}, 'a] => prop",          "=?=", [3, 2], 2),
   503       Mixfix   ("(_ =?=/ _)", "['a::{}, 'a] => prop",          "=?=", [3, 2], 2),
   448       Mixfix   ("(_ ==>/ _)", "[prop, prop] => prop",          "==>", [2, 1], 1),
   504       Mixfix   ("(_ ==>/ _)", "[prop, prop] => prop",          "==>", [2, 1], 1),
   449       Binder   ("!!",         "('a::logic => prop) => prop",   "all", 0, 0)],
   505       Binder   ("!!",         "('a::logic => prop) => prop",   "all", 0, 0)],
   450     xrules = [],
   506     xrules = [],
   451     parse_ast_translation =
   507     parse_ast_translation = [(applC, appl_ast_tr), ("_lambda", lambda_ast_tr),
   452       [(applC, appl_ast_tr), ("_lambda", lambda_ast_tr), ("_idtyp", idtyp_ast_tr),
   508       ("_idtyp", idtyp_ast_tr), ("_bigimpl", bigimpl_ast_tr)],
   453         ("_bigimpl", bigimpl_ast_tr)],
   509     parse_translation = [("_abs", abs_tr), ("_aprop", aprop_tr), ("_K", k_tr),
   454     parse_translation = [("_abs", abs_tr), ("_K", k_tr), ("_aprop", aprop_tr)],
   510       ("_explode", explode_tr)],
   455     print_translation = [],
   511     print_translation = [],
   456     print_ast_translation = [("_abs", abs_ast_tr'), ("_idts", idts_ast_tr'),
   512     print_ast_translation = [("_abs", abs_ast_tr'), ("_idts", idts_ast_tr'),
   457       ("==>", impl_ast_tr')]};
   513       ("==>", impl_ast_tr'), ("_implode", implode_ast_tr')]};
   458 
   514 
   459 val syntax_types = [id, var, tfree, tvar, logic, "type", "types", "sort",
   515 val syntax_types = terminals @ [logic, "type", "types", "sort", "classes",
   460   "classes", args, "idt", "idts", "aprop", "asms"];
   516   args, "idt", "idts", "aprop", "asms"];
   461 
   517 
   462 val constrainIdtC = "_idtyp";
       
   463 val constrainAbsC = "_constrainAbs";
   518 val constrainAbsC = "_constrainAbs";
   464 val apropC = "_aprop";
   519 val apropC = "_aprop";
   465 
   520 
   466 
   521 
   467 end;
   522 end;