re-factor options handling of read_term into read_term_body (#1887)
This commit is contained in:
@@ -12,6 +12,7 @@ use crate::machine::machine_indices::*;
|
||||
use crate::machine::stack::*;
|
||||
use crate::machine::streams::*;
|
||||
use crate::parser::ast::*;
|
||||
use crate::read::TermWriteResult;
|
||||
use crate::types::*;
|
||||
|
||||
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
|
||||
// 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 {
|
||||
pub fn read_term_body(&mut self, mut term_write_result: TermWriteResult) -> CallResult {
|
||||
fn push_var_eq_functors<'a>(
|
||||
heap: &mut Heap,
|
||||
iter: impl Iterator<Item = (&'a VarPtr, &'a HeapCellValue)>,
|
||||
@@ -521,25 +505,6 @@ impl MachineState {
|
||||
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],
|
||||
(HeapCellValueTag::PStr | HeapCellValueTag::PStrOffset) => {
|
||||
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));
|
||||
}
|
||||
|
||||
// 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) => {
|
||||
match err {
|
||||
CompilationError::ParserError(e) if e.is_unexpected_eof() => {
|
||||
|
||||
@@ -5816,7 +5816,7 @@ impl Machine {
|
||||
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"), 2);
|
||||
let stub = functor_stub(atom!("read_from_chars"), 2);
|
||||
let e = self.machine_st.session_error(SessionError::from(e));
|
||||
|
||||
return Err(self.machine_st.error_form(e, stub));
|
||||
@@ -5837,8 +5837,31 @@ impl Machine {
|
||||
#[inline(always)]
|
||||
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]) {
|
||||
let stream = Stream::from_owned_string(atom_or_string.to_string(), &mut self.machine_st.arena);
|
||||
self.machine_st.read_term(stream, &mut self.indices)
|
||||
let chars = CharReader::new(ByteStream::from_string(atom_or_string.to_string()));
|
||||
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 {
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user