src/Pure/Isar/antiquote.ML
changeset 22114 560c5b5dda1c
parent 19305 5c16895d548b
child 23677 1114cc909800
equal deleted inserted replaced
22113:4a65d2f4d0b5 22114:560c5b5dda1c
     8 signature ANTIQUOTE =
     8 signature ANTIQUOTE =
     9 sig
     9 sig
    10   exception ANTIQUOTE_FAIL of (string * Position.T) * exn
    10   exception ANTIQUOTE_FAIL of (string * Position.T) * exn
    11   datatype antiquote = Text of string | Antiq of string * Position.T
    11   datatype antiquote = Text of string | Antiq of string * Position.T
    12   val is_antiq: antiquote -> bool
    12   val is_antiq: antiquote -> bool
    13   val antiquotes_of: string * Position.T -> antiquote list
    13   val scan_antiquotes: string * Position.T -> antiquote list
       
    14   val scan_arguments: Scan.lexicon -> (OuterLex.token list -> 'a * OuterLex.token list) ->
       
    15     string * Position.T -> 'a
    14 end;
    16 end;
    15 
    17 
    16 structure Antiquote: ANTIQUOTE =
    18 structure Antiquote: ANTIQUOTE =
    17 struct
    19 struct
    18 
    20 
    28   | is_antiq (Antiq _) = true;
    30   | is_antiq (Antiq _) = true;
    29 
    31 
    30 
    32 
    31 (* scan_antiquote *)
    33 (* scan_antiquote *)
    32 
    34 
       
    35 structure T = OuterLex;
       
    36 
    33 local
    37 local
    34 
       
    35 structure T = OuterLex;
       
    36 
    38 
    37 val scan_txt =
    39 val scan_txt =
    38   T.scan_blank ||
    40   T.scan_blank ||
    39   T.keep_line ($$ "@" --| Scan.ahead (~$$ "{")) ||
    41   T.keep_line ($$ "@" --| Scan.ahead (~$$ "{")) ||
    40   T.keep_line (Scan.one (fn s => s <> "@" andalso Symbol.not_sync s andalso Symbol.not_eof s));
    42   T.keep_line (Scan.one (fn s => s <> "@" andalso Symbol.not_sync s andalso Symbol.not_eof s));
    62     scan_antiq >> (fn s => Antiq (s, pos)));
    64     scan_antiq >> (fn s => Antiq (s, pos)));
    63 
    65 
    64 end;
    66 end;
    65 
    67 
    66 
    68 
    67 (* antiquotes_of *)
    69 (* scan_antiquotes *)
    68 
    70 
    69 fun antiquotes_of (s, pos) =
    71 fun scan_antiquotes (s, pos) =
    70   (case Scan.error (Scan.finite' Symbol.stopper (Scan.repeat scan_antiquote))
    72   (case Scan.error (Scan.finite' Symbol.stopper (Scan.repeat scan_antiquote))
    71       (pos, Symbol.explode s) of
    73       (pos, Symbol.explode s) of
    72     (xs, (_, [])) => xs
    74     (xs, (_, [])) => xs
    73   | (_, (pos', ss)) => error ("Malformed quotation/antiquotation text at: " ^
    75   | (_, (pos', ss)) => error ("Malformed quotation/antiquotation source at: " ^
    74       quote (Symbol.beginning 10 ss) ^ Position.str_of pos'));
    76       quote (Symbol.beginning 10 ss) ^ Position.str_of pos'));
    75 
    77 
    76 
    78 
       
    79 (* scan_arguments *)
       
    80 
       
    81 fun scan_arguments lex antiq (s, pos) =
       
    82   let
       
    83     fun err msg = cat_error msg
       
    84       ("Malformed antiquotation: " ^ quote ("@{" ^ s ^ "}") ^ Position.str_of pos);
       
    85 
       
    86     val res =
       
    87       Source.of_string s
       
    88       |> Symbol.source false
       
    89       |> T.source false (K (lex, Scan.empty_lexicon)) pos
       
    90       |> T.source_proper
       
    91       |> Source.source T.stopper (Scan.error (Scan.bulk antiq)) NONE
       
    92       |> Source.exhaust;
       
    93   in (case res of [x] => x | _ => err "") handle ERROR msg => err msg end;
       
    94 
    77 end;
    95 end;