re-factor options handling of read_term into read_term_body (#1887)

This commit is contained in:
Mark
2023-07-15 21:52:54 -06:00
parent 65a8ce8e22
commit de10ccfdee
2 changed files with 141 additions and 115 deletions

View File

@@ -12,6 +12,7 @@ use crate::machine::machine_indices::*;
use crate::machine::stack::*; use crate::machine::stack::*;
use crate::machine::streams::*; use crate::machine::streams::*;
use crate::parser::ast::*; use crate::parser::ast::*;
use crate::read::TermWriteResult;
use crate::types::*; use crate::types::*;
use crate::parser::rug::Integer; use crate::parser::rug::Integer;
@@ -482,24 +483,7 @@ impl MachineState {
} }
} }
// Safety: the atom_tbl lives for the lifetime of the machine, as does the helper, so the ptr pub fn read_term_body(&mut self, mut term_write_result: TermWriteResult) -> CallResult {
// will always be valid.
pub fn read_term_from_user_input(&mut self, stream: Stream, indices: &mut IndexStore) -> CallResult {
let atoms_ptr = (&self.atom_tbl.table) as *const indexmap::IndexSet<Atom>;
if let Stream::Readline(ptr) = stream {
unsafe {
let readline = ptr.as_ptr().as_mut().unwrap();
readline.set_atoms_for_completion(atoms_ptr);
let ret = self.read_term(stream, indices);
return ret
}
}
unreachable!("Stream must be a Stream::Readline(_)")
}
pub fn read_term(&mut self, stream: Stream, indices: &mut IndexStore) -> CallResult {
fn push_var_eq_functors<'a>( fn push_var_eq_functors<'a>(
heap: &mut Heap, heap: &mut Heap,
iter: impl Iterator<Item = (&'a VarPtr, &'a HeapCellValue)>, iter: impl Iterator<Item = (&'a VarPtr, &'a HeapCellValue)>,
@@ -521,25 +505,6 @@ impl MachineState {
list_of_var_eqs list_of_var_eqs
} }
self.check_stream_properties(
stream,
StreamType::Text,
Some(self.registers[2]),
atom!("read_term"),
3,
)?;
if stream.past_end_of_stream() {
if EOFAction::Reset != stream.options().eof_action() {
return Ok(());
} else if self.fail {
return Ok(());
}
}
loop {
match self.read(stream, &indices.op_dir) {
Ok(mut term_write_result) => {
let heap_loc = read_heap_cell!(self.heap[term_write_result.heap_loc], let heap_loc = read_heap_cell!(self.heap[term_write_result.heap_loc],
(HeapCellValueTag::PStr | HeapCellValueTag::PStrOffset) => { (HeapCellValueTag::PStr | HeapCellValueTag::PStrOffset) => {
pstr_loc_as_cell!(term_write_result.heap_loc) pstr_loc_as_cell!(term_write_result.heap_loc)
@@ -633,6 +598,44 @@ impl MachineState {
return Ok(unify_fn!(*self, var_names_offset, var_names_addr)); return Ok(unify_fn!(*self, var_names_offset, var_names_addr));
} }
// Safety: the atom_tbl lives for the lifetime of the machine, as does the helper, so the ptr
// will always be valid.
pub fn read_term_from_user_input(&mut self, stream: Stream, indices: &mut IndexStore) -> CallResult {
let atoms_ptr = (&self.atom_tbl.table) as *const indexmap::IndexSet<Atom>;
if let Stream::Readline(ptr) = stream {
unsafe {
let readline = ptr.as_ptr().as_mut().unwrap();
readline.set_atoms_for_completion(atoms_ptr);
let ret = self.read_term(stream, indices);
return ret
}
}
unreachable!("Stream must be a Stream::Readline(_)")
}
pub fn read_term(&mut self, stream: Stream, indices: &mut IndexStore) -> CallResult {
self.check_stream_properties(
stream,
StreamType::Text,
Some(self.registers[2]),
atom!("read_term"),
3,
)?;
if stream.past_end_of_stream() {
if EOFAction::Reset != stream.options().eof_action() {
return Ok(());
} else if self.fail {
return Ok(());
}
}
loop {
match self.read(stream, &indices.op_dir) {
Ok(term_write_result) => return self.read_term_body(term_write_result),
Err(err) => { Err(err) => {
match err { match err {
CompilationError::ParserError(e) if e.is_unexpected_eof() => { CompilationError::ParserError(e) if e.is_unexpected_eof() => {

View File

@@ -5816,7 +5816,7 @@ impl Machine {
let term_write_result = match term_write_result { let term_write_result = match term_write_result {
Ok(term_write_result) => term_write_result, Ok(term_write_result) => term_write_result,
Err(e) => { Err(e) => {
let stub = functor_stub(atom!("read_term_from_chars"), 2); let stub = functor_stub(atom!("read_from_chars"), 2);
let e = self.machine_st.session_error(SessionError::from(e)); let e = self.machine_st.session_error(SessionError::from(e));
return Err(self.machine_st.error_form(e, stub)); return Err(self.machine_st.error_form(e, stub));
@@ -5837,8 +5837,31 @@ impl Machine {
#[inline(always)] #[inline(always)]
pub(crate) fn read_term_from_chars(&mut self) -> CallResult { pub(crate) fn read_term_from_chars(&mut self) -> CallResult {
if let Some(atom_or_string) = self.machine_st.value_to_str_like(self.machine_st.registers[1]) { if let Some(atom_or_string) = self.machine_st.value_to_str_like(self.machine_st.registers[1]) {
let stream = Stream::from_owned_string(atom_or_string.to_string(), &mut self.machine_st.arena); let chars = CharReader::new(ByteStream::from_string(atom_or_string.to_string()));
self.machine_st.read_term(stream, &mut self.indices) let mut parser = Parser::new(chars, &mut self.machine_st);
let op_dir = CompositeOpDir::new(&self.indices.op_dir, None);
let term_write_result = parser.read_term(&op_dir, Tokens::Default)
.map_err(CompilationError::from)
.and_then(|term| {
write_term_to_heap(
&term,
&mut self.machine_st.heap,
&mut self.machine_st.atom_tbl,
)
});
let term_write_result = match term_write_result {
Ok(term_write_result) => term_write_result,
Err(e) => {
let stub = functor_stub(atom!("read_term_from_chars"), 3);
let e = self.machine_st.session_error(SessionError::from(e));
return Err(self.machine_st.error_form(e, stub));
}
};
self.machine_st.read_term_body(term_write_result)
} else { } else {
unreachable!() unreachable!()
} }