9 sig |
9 sig |
10 datatype antiquote = |
10 datatype antiquote = |
11 Text of string | Antiq of (string * Position.T) * Position.T | |
11 Text of string | Antiq of (string * Position.T) * Position.T | |
12 Open of Position.T | Close of Position.T |
12 Open of Position.T | Close of Position.T |
13 val is_antiq: antiquote -> bool |
13 val is_antiq: antiquote -> bool |
14 val scan_antiquotes: string * Position.T -> antiquote list |
14 val read: string * Position.T -> antiquote list |
15 val scan_arguments: Scan.lexicon -> (OuterLex.token list -> 'a * OuterLex.token list) -> |
15 val read_arguments: Scan.lexicon -> (OuterLex.token list -> 'a * OuterLex.token list) -> |
16 string * Position.T -> 'a |
16 string * Position.T -> 'a |
17 end; |
17 end; |
18 |
18 |
19 structure Antiquote: ANTIQUOTE = |
19 structure Antiquote: ANTIQUOTE = |
20 struct |
20 struct |
47 in check antiqs [] end; |
47 in check antiqs [] end; |
48 |
48 |
49 |
49 |
50 (* scan_antiquote *) |
50 (* scan_antiquote *) |
51 |
51 |
|
52 open BasicSymbolPos; |
52 structure T = OuterLex; |
53 structure T = OuterLex; |
53 |
54 |
54 local |
55 local |
55 |
56 |
56 fun count scan = Scan.depend (fn pos => scan >> (fn x => (Position.advance [x] pos, x))); |
|
57 |
|
58 val scan_txt = |
57 val scan_txt = |
59 count ($$ "@" --| Scan.ahead (~$$ "{")) || |
58 $$$ "@" --| Scan.ahead (~$$$ "{") || |
60 count (Scan.one (fn s => |
59 Scan.one (fn (s, _) => s <> "@" andalso s <> "\\<lbrace>" andalso s <> "\\<rbrace>" |
61 s <> "@" andalso s <> "\\<lbrace>" andalso s <> "\\<rbrace>" andalso Symbol.is_regular s)); |
60 andalso Symbol.is_regular s) >> single; |
62 |
61 |
63 val scan_ant = |
62 val scan_ant = |
64 T.scan_quoted >> implode || |
63 T.scan_quoted || |
65 count (Scan.one (fn s => s <> "}" andalso Symbol.is_regular s)); |
64 Scan.one (fn (s, _) => s <> "}" andalso Symbol.is_regular s) >> single; |
66 |
65 |
67 val scan_antiq = |
66 val scan_antiq = |
68 Scan.state -- (count ($$ "@") |-- count ($$ "{") |-- |
67 SymbolPos.scan_position -- ($$$ "@" |-- $$$ "{" |-- |
69 T.!!! "missing closing brace of antiquotation" |
68 T.!!! "missing closing brace of antiquotation" |
70 (Scan.state -- Scan.repeat scan_ant -- Scan.state -- (count ($$ "}") |-- Scan.state))) |
69 (SymbolPos.scan_position -- Scan.repeat scan_ant -- SymbolPos.scan_position -- |
|
70 ($$$ "}" |-- SymbolPos.scan_position))) |
71 >> (fn (pos1, (((pos2, body), pos3), pos4)) => |
71 >> (fn (pos1, (((pos2, body), pos3), pos4)) => |
72 Antiq ((implode body, Position.encode_range (pos2, pos3)), Position.encode_range (pos1, pos4))); |
72 Antiq ((implode (map symbol (flat body)), |
|
73 Position.encode_range (pos2, pos3)), Position.encode_range (pos1, pos4))); |
73 |
74 |
74 in |
75 in |
75 |
76 |
76 val scan_antiquote = |
77 val scan_antiquote = T.!!! "malformed quotation/antiquotation" |
77 Scan.repeat1 scan_txt >> (Text o implode) || |
78 (Scan.repeat1 scan_txt >> (Text o implode o map symbol o flat) || |
78 scan_antiq || |
79 scan_antiq || |
79 Scan.state --| count ($$ "\\<lbrace>") >> Open || |
80 SymbolPos.scan_position --| $$$ "\\<lbrace>" >> Open || |
80 Scan.state --| count ($$ "\\<rbrace>") >> Close; |
81 SymbolPos.scan_position --| $$$ "\\<rbrace>" >> Close); |
81 |
82 |
82 end; |
83 end; |
83 |
84 |
84 |
85 |
85 (* scan_antiquotes *) |
86 (* read *) |
86 |
87 |
87 fun scan_antiquotes (s, pos) = |
88 fun read ("", _) = [] |
88 (case Scan.error (Scan.finite' Symbol.stopper (Scan.repeat scan_antiquote)) |
89 | read (s, pos) = |
89 (pos, Symbol.explode s) of |
90 (case Scan.read SymbolPos.stopper (Scan.bulk scan_antiquote) (SymbolPos.explode (s, pos)) of |
90 (xs, (_, [])) => (check_nesting xs; xs) |
91 SOME xs => (check_nesting xs; xs) |
91 | (_, (pos', ss)) => error ("Malformed quotation/antiquotation source at: " ^ |
92 | NONE => error ("Malformed quotation/antiquotation source" ^ Position.str_of pos)); |
92 quote (Symbol.beginning 10 ss) ^ Position.str_of pos')); |
|
93 |
93 |
94 |
94 |
95 (* scan_arguments *) |
95 (* scan_arguments *) |
96 |
96 |
97 fun scan_arguments lex antiq (s, pos) = |
97 fun read_arguments lex scan (s, pos) = |
98 let |
98 let |
99 fun err msg = cat_error msg |
99 fun err msg = cat_error msg |
100 ("Malformed antiquotation: " ^ quote ("@{" ^ s ^ "}") ^ Position.str_of pos); |
100 ("Malformed antiquotation: " ^ quote ("@{" ^ s ^ "}") ^ Position.str_of pos); |
101 |
101 |
102 val res = |
102 val res = |
103 Source.of_string s |
103 Source.of_string s |
104 |> Symbol.source false |
104 |> Symbol.source false |
105 |> T.source NONE (K (lex, Scan.empty_lexicon)) pos |
105 |> T.source NONE (K (lex, Scan.empty_lexicon)) pos |
106 |> T.source_proper |
106 |> T.source_proper |
107 |> Source.source T.stopper (Scan.error (Scan.bulk antiq)) NONE |
107 |> Source.source T.stopper (Scan.error (Scan.bulk scan)) NONE |
108 |> Source.exhaust; |
108 |> Source.exhaust; |
109 in (case res of [x] => x | _ => err "") handle ERROR msg => err msg end; |
109 in (case res of [x] => x | _ => err "") handle ERROR msg => err msg end; |
110 |
110 |
111 end; |
111 end; |