]> Repositorios git - scryer-prolog.git/commitdiff
Merge branch 'sockets-develop'
authorMark Thom <[email protected]>
Sat, 9 May 2020 20:26:29 +0000 (14:26 -0600)
committerMark Thom <[email protected]>
Sat, 9 May 2020 20:26:29 +0000 (14:26 -0600)
1  2 
src/prolog/machine/compile.rs
src/prolog/machine/system_calls.rs

Simple merge
index 4d3bfef622aee625aca3e8b47371c2af0328eb25,e01008e03e94bff57032b1aac474669d4cf70bac..ce7c7a679f09094250f479605dc2f62a8ffb1a56
@@@ -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)];