| author | wenzelm | 
| Sat, 18 Mar 2017 20:35:58 +0100 | |
| changeset 65312 | 34d56ca5b548 | 
| parent 64565 | 5069ddebc937 | 
| permissions | -rw-r--r-- | 
| 6118 | 1 | (* Title: Pure/General/source.ML | 
| 6116 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 2 | Author: Markus Wenzel, TU Muenchen | 
| 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 3 | |
| 8806 | 4 | Coalgebraic data sources -- efficient purely functional input streams. | 
| 6116 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 5 | *) | 
| 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 6 | |
| 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 7 | signature SOURCE = | 
| 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 8 | sig | 
| 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 9 |   type ('a, 'b) source
 | 
| 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 10 |   val get: ('a, 'b) source -> 'a list * ('a, 'b) source
 | 
| 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 11 |   val unget: 'a list * ('a, 'b) source -> ('a, 'b) source
 | 
| 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 12 |   val get_single: ('a, 'b) source -> ('a * ('a, 'b) source) option
 | 
| 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 13 |   val exhaust: ('a, 'b) source -> 'a list
 | 
| 19485 | 14 |   val map_filter: ('a -> 'b option) -> ('a, 'c) source -> ('b, ('a, 'c) source) source
 | 
| 6116 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 15 |   val filter: ('a -> bool) -> ('a, 'b) source -> ('a, ('a, 'b) source) source
 | 
| 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 16 |   val of_list: 'a list -> ('a, 'a list) source
 | 
| 64565 | 17 | val of_string: string -> (string, string list) source | 
| 37903 
b7ae269c0d68
replaced Source.of_list_limited by slightly more economic Source.of_string_limited;
 wenzelm parents: 
29606diff
changeset | 18 |   val exhausted: ('a, 'b) source -> ('a, 'a list) source
 | 
| 27732 | 19 |   val source': 'a -> 'b Scan.stopper -> ('a * 'b list -> 'c list * ('a * 'b list)) ->
 | 
| 6116 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 20 |     ('b, 'e) source -> ('c, 'a * ('b, 'e) source) source
 | 
| 27732 | 21 |   val source: 'a Scan.stopper -> ('a list -> 'b list * 'a list) ->
 | 
| 6116 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 22 |     ('a, 'd) source -> ('b, ('a, 'd) source) source
 | 
| 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 23 | end; | 
| 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 24 | |
| 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 25 | structure Source: SOURCE = | 
| 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 26 | struct | 
| 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 27 | |
| 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 28 | |
| 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 29 | (** datatype source **) | 
| 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 30 | |
| 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 31 | datatype ('a, 'b) source =
 | 
| 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 32 | Source of | 
| 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 33 |    {buffer: 'a list,
 | 
| 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 34 | info: 'b, | 
| 58850 | 35 | drain: 'b -> 'a list * 'b}; | 
| 6116 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 36 | |
| 58850 | 37 | fun make_source buffer info drain = | 
| 38 |   Source {buffer = buffer, info = info, drain = drain};
 | |
| 6116 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 39 | |
| 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 40 | |
| 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 41 | (* get / unget *) | 
| 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 42 | |
| 58850 | 43 | fun get (Source {buffer = [], info, drain}) =
 | 
| 44 | let val (xs, info') = drain info | |
| 45 | in (xs, make_source [] info' drain) end | |
| 46 |   | get (Source {buffer, info, drain}) = (buffer, make_source [] info drain);
 | |
| 6116 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 47 | |
| 58850 | 48 | fun unget (xs, Source {buffer, info, drain}) = make_source (xs @ buffer) info drain;
 | 
| 6116 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 49 | |
| 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 50 | |
| 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 51 | (* variations on get *) | 
| 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 52 | |
| 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 53 | fun get_single src = | 
| 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 54 | (case get src of | 
| 15531 | 55 | ([], _) => NONE | 
| 56 | | (x :: xs, src') => SOME (x, unget (xs, src'))); | |
| 6116 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 57 | |
| 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 58 | fun exhaust src = | 
| 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 59 | (case get src of | 
| 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 60 | ([], _) => [] | 
| 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 61 | | (xs, src') => xs @ exhaust src'); | 
| 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 62 | |
| 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 63 | |
| 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 64 | (* (map)filter *) | 
| 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 65 | |
| 58850 | 66 | fun drain_map_filter f src = | 
| 6116 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 67 | let | 
| 58850 | 68 | val (xs, src') = get src; | 
| 19485 | 69 | val xs' = map_filter f xs; | 
| 6116 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 70 | in | 
| 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 71 | if null xs orelse not (null xs') then (xs', src') | 
| 58850 | 72 | else drain_map_filter f src' | 
| 6116 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 73 | end; | 
| 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 74 | |
| 58850 | 75 | fun map_filter f src = make_source [] src (drain_map_filter f); | 
| 19485 | 76 | fun filter pred = map_filter (fn x => if pred x then SOME x else NONE); | 
| 6116 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 77 | |
| 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 78 | |
| 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 79 | |
| 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 80 | (** build sources **) | 
| 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 81 | |
| 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 82 | (* list source *) | 
| 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 83 | |
| 58850 | 84 | fun of_list xs = make_source [] xs (fn xs => (xs, [])); | 
| 37903 
b7ae269c0d68
replaced Source.of_list_limited by slightly more economic Source.of_string_limited;
 wenzelm parents: 
29606diff
changeset | 85 | |
| 40627 
becf5d5187cc
renamed raw "explode" function to "raw_explode" to emphasize its meaning;
 wenzelm parents: 
38253diff
changeset | 86 | val of_string = of_list o raw_explode; | 
| 23875 
e22705ccc07d
added of_string_limited (more efficient for partial scans);
 wenzelm parents: 
23700diff
changeset | 87 | |
| 64565 | 88 | fun exhausted src = of_list (exhaust src); | 
| 9123 
f8f54877a18c
added exhausted: ('a, 'b) source -> ('a, 'a list) source;
 wenzelm parents: 
8806diff
changeset | 89 | |
| 6116 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 90 | |
| 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 91 | |
| 23700 
fb1102e98cd4
moved source cascading from scan.ML to source.ML;
 wenzelm parents: 
23682diff
changeset | 92 | (** cascade sources **) | 
| 6116 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 93 | |
| 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 94 | (* state-based *) | 
| 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 95 | |
| 58864 | 96 | fun drain_source' stopper scan (state, src) = | 
| 23700 
fb1102e98cd4
moved source cascading from scan.ML to source.ML;
 wenzelm parents: 
23682diff
changeset | 97 | let | 
| 58850 | 98 | val drain = Scan.drain get stopper; | 
| 99 | val (xs, s) = get src; | |
| 23700 
fb1102e98cd4
moved source cascading from scan.ML to source.ML;
 wenzelm parents: 
23682diff
changeset | 100 | val ((ys, (state', xs')), src') = | 
| 
fb1102e98cd4
moved source cascading from scan.ML to source.ML;
 wenzelm parents: 
23682diff
changeset | 101 | if null xs then (([], (state, [])), s) | 
| 58864 | 102 | else drain (Scan.error scan) ((state, xs), s); | 
| 23700 
fb1102e98cd4
moved source cascading from scan.ML to source.ML;
 wenzelm parents: 
23682diff
changeset | 103 | in (ys, (state', unget (xs', src'))) end; | 
| 
fb1102e98cd4
moved source cascading from scan.ML to source.ML;
 wenzelm parents: 
23682diff
changeset | 104 | |
| 58864 | 105 | fun source' init_state stopper scan src = | 
| 106 | make_source [] (init_state, src) (drain_source' stopper scan); | |
| 6116 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 107 | |
| 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 108 | |
| 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 109 | (* non state-based *) | 
| 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 110 | |
| 58864 | 111 | fun drain_source stopper scan = | 
| 112 | Scan.unlift (drain_source' stopper (Scan.lift scan)); | |
| 23700 
fb1102e98cd4
moved source cascading from scan.ML to source.ML;
 wenzelm parents: 
23682diff
changeset | 113 | |
| 58864 | 114 | fun source stopper scan src = | 
| 115 | make_source [] src (drain_source stopper scan); | |
| 6116 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 116 | |
| 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 wenzelm parents: diff
changeset | 117 | end; |