From: Mark Thom Date: Sat, 9 May 2020 20:26:29 +0000 (-0600) Subject: Merge branch 'sockets-develop' X-Git-Tag: v0.8.123~57 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=b0ae44bc2525f74378fe4c5b9fea0e71cc45e37c;p=scryer-prolog.git Merge branch 'sockets-develop' --- b0ae44bc2525f74378fe4c5b9fea0e71cc45e37c diff --cc src/prolog/machine/system_calls.rs index 4d3bfef6,e01008e0..ce7c7a67 --- a/src/prolog/machine/system_calls.rs +++ b/src/prolog/machine/system_calls.rs @@@ -1646,28 -2363,95 +2358,115 @@@ impl MachineState } } } + &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)];