112 fun exhausted src = of_list (exhaust src); |
112 fun exhausted src = of_list (exhaust src); |
113 |
113 |
114 |
114 |
115 (* stream source *) |
115 (* stream source *) |
116 |
116 |
117 fun slurp_input instream = |
117 fun slurp_input instream = CRITICAL (fn () => |
118 let |
118 let |
119 fun slurp () = |
119 fun slurp () = |
120 (case TextIO.canInput (instream, 1) handle IO.Io _ => NONE of |
120 (case TextIO.canInput (instream, 1) handle IO.Io _ => NONE of |
121 NONE => [] |
121 NONE => [] |
122 | SOME 0 => [] |
122 | SOME 0 => [] |
123 | SOME _ => TextIO.input instream :: slurp ()); |
123 | SOME _ => TextIO.input instream :: slurp ()); |
124 in maps explode (slurp ()) end; |
124 in maps explode (slurp ()) end); |
125 |
125 |
126 fun drain_stream instream outstream prompt () = |
126 fun drain_stream instream outstream prompt () = |
127 let val input = slurp_input instream in |
127 let val input = slurp_input instream in |
128 if exists (fn c => c = "\n") input then (input, ()) |
128 if exists (fn c => c = "\n") input then (input, ()) |
129 else |
129 else |
130 (TextIO.output (outstream, Output.output prompt); |
130 (case |
131 TextIO.flushOut outstream; |
131 CRITICAL (fn () => |
132 (case TextIO.inputLine instream of |
132 (TextIO.output (outstream, Output.output prompt); |
|
133 TextIO.flushOut outstream; |
|
134 TextIO.inputLine instream)) of |
133 SOME line => (input @ explode line, ()) |
135 SOME line => (input @ explode line, ()) |
134 | NONE => (input, ()))) |
136 | NONE => (input, ())) |
135 end; |
137 end; |
136 |
138 |
137 fun of_stream instream outstream = |
139 fun of_stream instream outstream = |
138 make_source [] () default_prompt (drain_stream instream outstream); |
140 make_source [] () default_prompt (drain_stream instream outstream); |
139 |
141 |