clarify EOF error across stream types and predicates (#1867, #1870)

This commit is contained in:
Mark
2023-07-08 13:38:32 -06:00
parent 2e26f37f5e
commit 067b5998ee
11 changed files with 84 additions and 71 deletions

View File

@@ -198,7 +198,7 @@ impl Machine {
let value = self.machine_st.registers[2];
unify_fn!(&mut self.machine_st, value, heap_loc_as_cell!(offset.heap_loc));
}
Err(CompilationError::ParserError(ParserError::UnexpectedEOF)) => {
Err(CompilationError::ParserError(e)) if e.is_unexpected_eof() => {
let value = self.machine_st.registers[2];
self.machine_st.unify_atom(atom!("end_of_file"), value);
}

View File

@@ -680,7 +680,6 @@ impl CompilationError {
functor!(atom!("no_such_module"), [atom(module_name)])
}
&CompilationError::InvalidRuleHead => {
functor!(atom!("invalid_head_of_rule")) // TODO: type_error(callable, _).
}
&CompilationError::InvalidUseModuleDecl => {

View File

@@ -634,21 +634,24 @@ impl MachineState {
return Ok(unify_fn!(*self, var_names_offset, var_names_addr));
}
Err(err) => {
if let CompilationError::ParserError(ParserError::UnexpectedEOF) = err {
self.eof_action(
self.registers[2],
stream,
atom!("read_term"),
3,
)?;
match err {
CompilationError::ParserError(e) if e.is_unexpected_eof() => {
self.eof_action(
self.registers[2],
stream,
atom!("read_term"),
3,
)?;
if stream.options().eof_action() == EOFAction::Reset {
if self.fail == false {
continue;
if stream.options().eof_action() == EOFAction::Reset {
if self.fail == false {
continue;
}
}
}
return Ok(());
return Ok(());
}
_ => {}
}
let stub = functor_stub(atom!("read_term"), 3);

View File

@@ -1523,20 +1523,10 @@ impl MachineState {
}
}
pub(crate) fn open_parsing_stream(
&mut self,
mut stream: Stream,
stub_name: Atom,
stub_arity: usize,
) -> Result<Stream, MachineStub> {
pub(crate) fn open_parsing_stream(&mut self, mut stream: Stream) -> Result<Stream, ParserError> {
match stream.peek_char() {
None => Ok(stream), // empty stream is handled gracefully by Lexer::eof
Some(Err(e)) => {
let err = self.session_error(SessionError::from(e));
let stub = functor_stub(stub_name, stub_arity);
Err(self.error_form(err, stub))
}
Some(Err(e)) => Err(ParserError::IO(e)),
Some(Ok(c)) => {
if c == '\u{feff}' {
// skip UTF-8 BOM

View File

@@ -925,7 +925,7 @@ impl MachineState {
loop {
match lexer.lookahead_char() {
Err(ParserError::UnexpectedEOF) => {
Err(e) if e.is_unexpected_eof() => {
let mut parser = Parser::from_lexer(lexer);
let op_dir = CompositeOpDir::new(&indices.op_dir, None);
@@ -3377,7 +3377,7 @@ impl Machine {
}
let stub_gen = || functor_stub(atom!("get_char"), 2);
let mut iter = self.machine_st.open_parsing_stream(stream, atom!("get_char"), 2)?;
let result = self.machine_st.open_parsing_stream(stream);
let addr = if addr.is_var() {
addr
@@ -3396,11 +3396,26 @@ impl Machine {
)
};
loop {
let result = iter.read_char();
let mut iter = match result {
Ok(iter) => iter,
Err(e) => {
if e.is_unexpected_eof() {
self.machine_st.unify_atom(atom!("end_of_file"), addr);
return Ok(());
} else {
let err = self.machine_st.session_error(SessionError::from(e));
return Err(self.machine_st.error_form(err, stub_gen()));
}
}
};
match result {
Some(Ok('\u{0}')) | Some(Err(_)) | None => {
loop {
match iter.read_char() {
Some(Ok(c)) => {
self.machine_st.unify_char(c, addr);
break;
}
_ => {
self.machine_st.eof_action(
self.machine_st.registers[2],
stream,
@@ -3414,10 +3429,6 @@ impl Machine {
break;
}
}
Some(Ok(c)) => {
self.machine_st.unify_char(c, addr);
break;
}
}
}
@@ -3459,7 +3470,13 @@ impl Machine {
string.push(c as char);
}
} else {
let mut iter = self.machine_st.open_parsing_stream(stream, atom!("get_n_chars"), 2)?;
let mut iter = self.machine_st.open_parsing_stream(stream)
.map_err(|e| {
let err = self.machine_st.session_error(SessionError::from(e));
let stub = functor_stub(atom!("get_n_chars"), 2);
self.machine_st.error_form(err, stub)
})?;
for _ in 0..num {
let result = iter.read_char();
@@ -3557,7 +3574,13 @@ impl Machine {
}
};
let mut iter = self.machine_st.open_parsing_stream(stream.clone(), atom!("get_code"), 2)?;
let mut iter = self.machine_st.open_parsing_stream(stream)
.map_err(|e| {
let err = self.machine_st.session_error(SessionError::from(e));
let stub = functor_stub(atom!("get_code"), 2);
self.machine_st.error_form(err, stub)
})?;
loop {
let result = iter.read_char();

View File

@@ -125,15 +125,15 @@ pub struct InlineTermStream {
impl TermStream for InlineTermStream {
fn next(&mut self, _: &CompositeOpDir) -> Result<Term, CompilationError> {
Err(CompilationError::from(ParserError::UnexpectedEOF))
Err(CompilationError::from(ParserError::unexpected_eof()))
}
fn eof(&mut self) -> Result<bool, CompilationError> {
Ok(true)
Ok(true)
}
fn listing_src(&self) -> &ListingSource {
&ListingSource::User
&ListingSource::User
}
}