Maybe,
QuotedToken,
RawInputReadChar,
+ ReadTermFromChars,
ResetBlock,
ReturnFromVerifyAttr,
SetBall,
&SystemClauseType::NextEP => clause_name!("$nextEP"),
&SystemClauseType::ReadQueryTerm => clause_name!("$read_query_term"),
&SystemClauseType::ReadTerm => clause_name!("$read_term"),
+ &SystemClauseType::ReadTermFromChars => clause_name!("$read_term_from_chars"),
&SystemClauseType::ResetGlobalVarAtKey => clause_name!("$reset_global_var_at_key"),
&SystemClauseType::ResetGlobalVarAtOffset => clause_name!("$reset_global_var_at_offset"),
&SystemClauseType::RetractClause => clause_name!("$retract_clause"),
("$nextEP", 3) => Some(SystemClauseType::NextEP),
("$read_query_term", 2) => Some(SystemClauseType::ReadQueryTerm),
("$read_term", 2) => Some(SystemClauseType::ReadTerm),
+ ("$read_term_from_chars", 2) => Some(SystemClauseType::ReadTermFromChars),
("$reset_block", 1) => Some(SystemClauseType::ResetBlock),
("$reset_cont_marker", 0) => Some(SystemClauseType::ResetContinuationMarker),
("$reset_global_var_at_key", 1) => Some(SystemClauseType::ResetGlobalVarAtKey),
-:- module(charsio, [write_term_to_chars/3]).
+:- module(charsio, [read_term_from_chars/2,
+ write_term_to_chars/3]).
+
+:- use_module(library(iso_ext)).
+
+read_term_from_chars(Chars, Term) :-
+ ( var(Chars) ->
+ throw(error(instantiation_error, read_term_from_chars/2))
+ ; nonvar(Term) ->
+ throw(error(uninstantiation_error(Term), read_term_from_chars/2))
+ ; '$skip_max_list'(_, -1, Chars, Chars0),
+ Chars0 == [],
+ partial_string(Chars) ->
+ true
+ ;
+ throw(error(type_error(complete_string, Chars), read_term_from_chars/2))
+ ),
+ '$read_term_from_chars'(Chars, Term).
+
write_term_to_chars(_, Options, _) :-
var(Options), throw(error(instantiation_error, write_term_to_chars/3)).
}
impl MachineError {
- pub(super) fn functor_stub(name: ClauseName, arity: usize) -> MachineStub {
+ pub(super)
+ fn functor_stub(name: ClauseName, arity: usize) -> MachineStub {
functor!(
"/",
SharedOpDesc::new(400, YFX),
)
}
- pub(super) fn evaluation_error(eval_error: EvalError) -> Self {
+ pub(super)
+ fn evaluation_error(eval_error: EvalError) -> Self {
let stub = functor!("evaluation_error", [atom(eval_error.as_str())]);
MachineError {
}
}
+ pub(super)
+ fn uninstantiation_error(culprit: Addr) -> Self {
+ let stub = functor!(
+ "uninstantiation_error",
+ [addr(culprit)]
+ );
+
+ MachineError {
+ stub,
+ location: None,
+ from: ErrorProvenance::Received,
+ }
+ }
+
pub(super)
fn session_error(h: usize, err: SessionError) -> Self {
match err {
use prolog_parser::ast::*;
+use prolog_parser::tabled_rc::*;
use crate::prolog::clause_types::*;
use crate::prolog::forms::*;
use crate::prolog::machine::modules::*;
use crate::prolog::machine::stack::*;
use crate::prolog::machine::streams::*;
+use crate::prolog::read::readline;
use crate::prolog::rug::Integer;
use downcast::Any;
}
impl MachineState {
+ pub(crate)
+ fn read_term(
+ &mut self,
+ current_input_stream: &mut Stream,
+ indices: &mut IndexStore,
+ ) -> CallResult {
+ match self.read(
+ &mut parsing_stream(current_input_stream.clone()),
+ indices.atom_tbl.clone(),
+ &indices.op_dir,
+ ) {
+ Ok(term_write_result) => {
+ let a1 = self[temp_v!(1)];
+ self.unify(Addr::HeapCell(term_write_result.heap_loc), a1);
+
+ if self.fail {
+ return Ok(());
+ }
+
+ let mut list_of_var_eqs = vec![];
+
+ for (var, binding) in term_write_result.var_dict.into_iter().rev() {
+ let var_atom = clause_name!(var.to_string(), indices.atom_tbl);
+
+ let h = self.heap.h();
+ let spec = fetch_atom_op_spec(clause_name!("="), None, &indices.op_dir);
+
+ self.heap.push(HeapCellValue::NamedStr(2, clause_name!("="), spec));
+ self.heap.push(HeapCellValue::Atom(var_atom, None));
+ self.heap.push(HeapCellValue::Addr(binding));
+
+ list_of_var_eqs.push(Addr::Str(h));
+ }
+
+ let a2 = self[temp_v!(2)];
+ let list_offset =
+ Addr::HeapCell(self.heap.to_list(list_of_var_eqs.into_iter()));
+
+ Ok(self.unify(list_offset, a2))
+ }
+ Err(err) => {
+ if let ParserError::UnexpectedEOF = err {
+ std::process::exit(0);
+ }
+
+ // reset the input stream after an input failure.
+ *current_input_stream = readline::input_stream();
+
+ let h = self.heap.h();
+ let syntax_error = MachineError::syntax_error(h, err);
+ let stub = MachineError::functor_stub(clause_name!("read_term"), 2);
+
+ Err(self.error_form(syntax_error, stub))
+ }
+ }
+ }
+
pub(crate)
fn write_term<'a>(
&'a self,
})
}
- fn read_term(
- &mut self,
- current_input_stream: &mut Stream,
- indices: &mut IndexStore,
- ) -> CallResult {
- match self.read(
- &mut parsing_stream(current_input_stream.clone()),
- indices.atom_tbl.clone(),
- &indices.op_dir,
- ) {
- Ok(term_write_result) => {
- let a1 = self[temp_v!(1)];
- self.unify(Addr::HeapCell(term_write_result.heap_loc), a1);
-
- if self.fail {
- return Ok(());
- }
-
- let mut list_of_var_eqs = vec![];
-
- for (var, binding) in term_write_result.var_dict.into_iter().rev() {
- let var_atom = clause_name!(var.to_string(), indices.atom_tbl);
-
- let h = self.heap.h();
- let spec = fetch_atom_op_spec(clause_name!("="), None, &indices.op_dir);
-
- self.heap.push(HeapCellValue::NamedStr(2, clause_name!("="), spec));
- self.heap.push(HeapCellValue::Atom(var_atom, None));
- self.heap.push(HeapCellValue::Addr(binding));
-
- list_of_var_eqs.push(Addr::Str(h));
- }
-
- let a2 = self[temp_v!(2)];
- let list_offset =
- Addr::HeapCell(self.heap.to_list(list_of_var_eqs.into_iter()));
-
- Ok(self.unify(list_offset, a2))
- }
- Err(err) => {
- if let ParserError::UnexpectedEOF = err {
- std::process::exit(0);
- }
-
- // reset the input stream after an input failure.
- *current_input_stream = readline::input_stream();
-
- let h = self.heap.h();
- let syntax_error = MachineError::syntax_error(h, err);
- let stub = MachineError::functor_stub(clause_name!("read_term"), 2);
-
- Err(self.error_form(syntax_error, stub))
- }
- }
- }
-
#[inline]
fn install_new_block(&mut self, r: RegType) -> usize {
self.block = self.b;
self.unify(target, module);
}
+ HeapCellValue::Addr(addr) if addr.is_ref() => {
+ let err = MachineError::uninstantiation_error(addr);
+ let stub = MachineError::functor_stub(
+ clause_name!("$module_of"),
+ 2,
+ );
+
+ return Err(self.error_form(err, stub));
+ }
_ => {
unreachable!()
}
readline::set_prompt(false);
self.read_term(current_input_stream, indices)?;
}
+ &SystemClauseType::ReadTermFromChars => {
+ let mut heap_pstr_iter = self.heap_pstr_iter(self[temp_v!(1)]);
+ let chars = heap_pstr_iter.to_string();
+
+ if let Addr::EmptyList = heap_pstr_iter.focus() {
+ let term_write_result =
+ match self.read(
+ &mut parsing_stream(Stream::from(chars)),
+ indices.atom_tbl.clone(),
+ &indices.op_dir,
+ ) {
+ Ok(term_write_result) => {
+ term_write_result
+ }
+ Err(e) => {
+ let stub = MachineError::functor_stub(
+ clause_name!("read_term_from_chars"),
+ 2,
+ );
+
+ let h = self.heap.h();
+ let e = MachineError::session_error(h, SessionError::from(e));
+
+ return Err(self.error_form(e, stub));
+ }
+ };
+
+ let result = Addr::HeapCell(term_write_result.heap_loc);
+
+ if let Some(var) = self.store(self.deref(self[temp_v!(2)])).as_var() {
+ self.bind(var, result);
+ } else {
+ unreachable!()
+ }
+ } else {
+ unreachable!()
+ }
+ }
&SystemClauseType::ResetBlock => {
let addr = self.deref(self[temp_v!(1)]);
self.reset_block(addr);
&TermRef::AnonVar(Level::Root) | &TermRef::Constant(Level::Root, ..) |
&TermRef::Var(Level::Root, ..) => {
let addr = self.term_as_addr(&term, h);
-
- if !addr.is_heap_bound() {
- self.machine_st.heap.push(HeapCellValue::Addr(addr));
- }
+ self.machine_st.heap.push(HeapCellValue::Addr(addr));
}
&TermRef::AnonVar(_) => {
if let Some((arity, site_h)) = self.queue.pop_front() {