}
}
}
+ &SystemClauseType::FirstStream => {
+ let mut first_stream = None;
+ let mut null_streams = BTreeSet::new();
+
+ for stream in indices.streams.iter().cloned() {
+ if !stream.is_null_stream() {
+ first_stream = Some(stream);
+ break;
+ } else {
+ null_streams.insert(stream);
+ }
+ }
+
+ indices.streams = indices.streams.sub(&null_streams);
+
+ if let Some(first_stream) = first_stream {
+ let stream = self.heap.to_unifiable(HeapCellValue::Stream(first_stream));
+
+ let var = self.store(self.deref(self[temp_v!(1)])).as_var().unwrap();
+ self.bind(var, stream);
+ } else {
+ self.fail = true;
+ return Ok(());
+ }
+ }
+ &SystemClauseType::NextStream => {
+ let prev_stream =
+ match self.store(self.deref(self[temp_v!(1)])) {
+ Addr::Stream(h) => {
+ if let HeapCellValue::Stream(ref stream) = &self.heap[h] {
+ stream.clone()
+ } else {
+ unreachable!()
+ }
+ }
+ _ => {
+ unreachable!()
+ }
+ };
+
+ let mut next_stream = None;
+ let mut null_streams = BTreeSet::new();
+
+ for stream in indices.streams.range(prev_stream.clone() ..).skip(1).cloned() {
+ if !stream.is_null_stream() {
+ next_stream = Some(stream);
+ break;
+ } else {
+ null_streams.insert(stream);
+ }
+ }
+
+ indices.streams = indices.streams.sub(&null_streams);
+
+ if let Some(next_stream) = next_stream {
+ let var = self.store(self.deref(self[temp_v!(2)])).as_var().unwrap();
+ let next_stream = self.heap.to_unifiable(HeapCellValue::Stream(next_stream));
+
+ self.bind(var, next_stream);
+ } else {
+ self.fail = true;
+ return Ok(());
+ }
+ }
+ &SystemClauseType::FlushOutput => {
+ let mut stream =
+ self.get_stream_or_alias(self[temp_v!(1)], indices, "flush_output", 1)?;
+
+ if !stream.is_output_stream() {
+ let stub = MachineError::functor_stub(clause_name!("flush_output"), 1);
+
+ let addr = vec![
+ HeapCellValue::Stream(stream)
+ ];
+
+ let err = MachineError::permission_error(
+ self.heap.h(),
+ Permission::OutputStream,
+ "stream",
+ addr,
+ );
+
+ return Err(self.error_form(err, stub));
+ }
+
+ stream.flush().unwrap();
+ }
&SystemClauseType::GetSingleChar => {
- let c = get_single_char();
+ let ctrl_c = KeyEvent {
+ code: KeyCode::Char('c'),
+ modifiers: KeyModifiers::CONTROL
+ };
+ let key = get_key();
+ if key == ctrl_c {
+ let stub = MachineError::functor_stub(
+ clause_name!("get_single_char"),
+ 1
+ );
+ let err = MachineError::interrupt_error();
+ let err = self.error_form(err, stub);
+
+ return Err(err);
+ }
+ let c = match key.code {
+ KeyCode::Enter => '\n',
+ KeyCode::Tab => '\t',
+ KeyCode::Char(c) => c,
+ _ => unreachable!()
+ };
let a1 = self[temp_v!(1)];