Is(RegType, ArithmeticTerm),
#[strum_discriminants(strum(props(Arity = "2", Name = "keysort")))]
KeySort,
- #[strum_discriminants(strum(props(Arity = "2", Name = "read")))]
- Read,
#[strum_discriminants(strum(props(Arity = "2", Name = "sort")))]
Sort,
}
&Instruction::CallFunctor |
&Instruction::CallGround |
&Instruction::CallKeySort |
- &Instruction::CallRead |
&Instruction::CallSort => {
let (name, arity) = self.to_name_and_arity();
functor!(atom!("call"), [atom(name), fixnum(arity)])
&Instruction::ExecuteGround |
&Instruction::ExecuteIs(..) |
&Instruction::ExecuteKeySort |
- &Instruction::ExecuteRead |
&Instruction::ExecuteSort => {
let (name, arity) = self.to_name_and_arity();
functor!(atom!("execute"), [atom(name), fixnum(arity)])
&Instruction::DefaultCallGround |
&Instruction::DefaultCallIs(..) |
&Instruction::DefaultCallKeySort |
- &Instruction::DefaultCallRead |
&Instruction::DefaultCallSort => {
let (name, arity) = self.to_name_and_arity();
functor!(atom!("call_default"), [atom(name), fixnum(arity)])
&Instruction::DefaultExecuteGround |
&Instruction::DefaultExecuteIs(..) |
&Instruction::DefaultExecuteKeySort |
- &Instruction::DefaultExecuteRead |
&Instruction::DefaultExecuteSort => {
let (name, arity) = self.to_name_and_arity();
functor!(atom!("execute_default"), [atom(name), fixnum(arity)])
peek_char/1, peek_char/2, peek_code/1,
peek_code/2, put_byte/1, put_byte/2, put_code/1,
put_code/2, put_char/1, put_char/2, read/1,
- read_term/2, read_term/3, repeat/0, retract/1,
- retractall/1, set_prolog_flag/2, set_input/1,
- set_stream_position/2, set_output/1, setof/3,
- stream_property/2, sub_atom/5, subsumes_term/2,
- term_variables/2, throw/1, true/0,
- unify_with_occurs_check/2, write/1, write/2,
- write_canonical/1, write_canonical/2,
+ read/2, read_term/2, read_term/3, repeat/0,
+ retract/1, retractall/1, set_prolog_flag/2,
+ set_input/1, set_stream_position/2, set_output/1,
+ setof/3, stream_property/2, sub_atom/5,
+ subsumes_term/2, term_variables/2, throw/1,
+ true/0, unify_with_occurs_check/2, write/1,
+ write/2, write_canonical/1, write_canonical/2,
write_term/2, write_term/3, writeq/1, writeq/2]).
/** Builtin predicates
parse_options_list(Options, builtins:parse_read_term_options_, DefaultOptions, OptionValues, Stub).
-parse_read_term_options_(singletons(Vars), singletons-Vars) :- !.
-parse_read_term_options_(variables(Vars), variables-Vars) :- !.
-parse_read_term_options_(variable_names(Vars), variable_names-Vars) :- !.
+parse_read_term_options_(singletons(Vars), singletons-Vars) :-
+ ( ( var(Vars)
+ ; '$skip_max_list'(_, _, Vars, Rs),
+ Rs == []
+ ) ->
+ !
+ ; throw(error(domain_error(read_option, singletons(Vars)), read_term/2))
+ ).
+parse_read_term_options_(variables(Vars), variables-Vars) :-
+ ( ( var(Vars)
+ ; '$skip_max_list'(_, _, Vars, Rs),
+ Rs == []
+ ) ->
+ !
+ ; throw(error(domain_error(read_option, variables(Vars)), read_term/2))
+ ).
+parse_read_term_options_(variable_names(Vars), variable_names-Vars) :-
+ ( ( var(Vars)
+ ; '$skip_max_list'(_, _, Vars, Rs),
+ Rs == []
+ ) ->
+ !
+ ; throw(error(domain_error(read_option, variable_names(Vars)), read_term/2))
+ ).
parse_read_term_options_(E,_) :-
throw(error(domain_error(read_option, E), _)).
% to read input from a file or the user. Use other predicates like `phrase_from_file/2` for that.
read(Term) :-
current_input(Stream),
- read(Stream, Term).
+ read_term(Stream, Term, []).
+ % read(Stream, Term).
+
+read(Stream, Term) :-
+ read_term(Stream, Term, []).
% ensures List is either a variable or a list.
can_be_list(List, _) :-
}
impl Machine {
- fn read(&mut self) -> CallResult {
- let stream = self.machine_st.get_stream_or_alias(
- self.machine_st.registers[1],
- &self.indices.stream_aliases,
- atom!("read"),
- 2,
- )?;
-
- match self.machine_st.read(stream, &self.indices.op_dir) {
- Ok(offset) => {
- let value = self.machine_st.registers[2];
- unify_fn!(&mut self.machine_st, value, heap_loc_as_cell!(offset.heap_loc));
- }
- 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);
- }
- Err(e) => {
- let stub = functor_stub(atom!("read"), 2);
- let err = self.machine_st.syntax_error(e);
-
- return Err(self.machine_st.error_form(err, stub));
- }
- };
-
- Ok(())
- }
-
pub(super) fn find_living_dynamic_else(&self, mut p: usize) -> Option<(usize, usize)> {
loop {
match &self.code[p] {
}
}
}
- &Instruction::DefaultCallRead => {
- try_or_throw!(self.machine_st, self.read());
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::DefaultExecuteRead => {
- try_or_throw!(self.machine_st, self.read());
-
- if self.machine_st.fail {
- self.machine_st.backtrack();
- } else {
- self.machine_st.p = self.machine_st.cp;
- }
- }
&Instruction::DefaultCallCopyTerm => {
self.machine_st.copy_term(AttrVarPolicy::DeepCopy);
step_or_fail!(self, self.machine_st.p += 1);
}
}
}
- &Instruction::CallRead => {
- try_or_throw!(self.machine_st, self.read());
-
- if self.machine_st.fail {
- self.machine_st.backtrack();
- } else {
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
-
- self.machine_st.p += 1;
- }
- }
- &Instruction::ExecuteRead => {
- try_or_throw!(self.machine_st, self.read());
-
- if self.machine_st.fail {
- self.machine_st.backtrack();
- } else {
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
-
- self.machine_st.p = self.machine_st.cp;
- }
- }
&Instruction::CallCopyTerm => {
self.machine_st.copy_term(AttrVarPolicy::DeepCopy);
)
}
+fn push_var_eq_functors<'a>(
+ heap: &mut Heap,
+ iter: impl Iterator<Item = (&'a VarKey, &'a HeapCellValue)>,
+ atom_tbl: &mut AtomTable,
+) -> Vec<HeapCellValue> {
+ let mut list_of_var_eqs = vec![];
+
+ for (var, binding) in iter {
+ let var_atom = atom_tbl.build_with(&var.to_string());
+ let h = heap.len();
+
+ heap.push(atom_as_cell!(atom!("="), 2));
+ heap.push(atom_as_cell!(var_atom));
+ heap.push(*binding);
+
+ list_of_var_eqs.push(str_loc_as_cell!(h));
+ }
+
+ list_of_var_eqs
+}
+
#[derive(Debug)]
pub struct Ball {
pub(super) boundary: usize,
}
}
- 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 VarKey, &'a HeapCellValue)>,
- atom_tbl: &mut AtomTable,
- ) -> Vec<HeapCellValue> {
- let mut list_of_var_eqs = vec![];
-
- for (var, binding) in iter {
- let var_atom = atom_tbl.build_with(&var.to_string());
- let h = heap.len();
-
- heap.push(atom_as_cell!(atom!("="), 2));
- heap.push(atom_as_cell!(var_atom));
- heap.push(*binding);
-
- list_of_var_eqs.push(str_loc_as_cell!(h));
- }
+ fn write_read_term_options(
+ &mut self,
+ mut var_list: Vec<(VarKey, HeapCellValue, usize)>,
+ singleton_var_list: Vec<HeapCellValue>,
+ ) -> CallResult {
+ var_list.sort_by(|(_,_,idx_1),(_,_,idx_2)| idx_1.cmp(idx_2));
+
+ let list_of_var_eqs = push_var_eq_functors(
+ &mut self.heap,
+ var_list.iter().filter_map(|(var_name, var,_)| if var_name.is_anon() { None } else { Some((var_name,var)) }),
+ &mut self.atom_tbl,
+ );
+
+ let singleton_addr = self.registers[3];
+ let singletons_offset = heap_loc_as_cell!(
+ iter_to_heap_list(&mut self.heap, singleton_var_list.into_iter())
+ );
- list_of_var_eqs
+ unify_fn!(*self, singletons_offset, singleton_addr);
+
+ if self.fail {
+ return Ok(());
+ }
+
+ let vars_addr = self.registers[4];
+ let vars_offset = heap_loc_as_cell!(
+ iter_to_heap_list(&mut self.heap, var_list.into_iter().map(|(_,cell,_)| cell))
+ );
+
+ unify_fn!(*self, vars_offset, vars_addr);
+
+ if self.fail {
+ return Ok(());
}
+ let var_names_addr = self.registers[5];
+ let var_names_offset = heap_loc_as_cell!(
+ iter_to_heap_list(&mut self.heap, list_of_var_eqs.into_iter())
+ );
+
+ Ok(unify_fn!(*self, var_names_offset, var_names_addr))
+ }
+
+ pub fn read_term_body(&mut self, mut term_write_result: TermWriteResult) -> CallResult {
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)
}
}
- for var in term_write_result.var_dict.values_mut() {
- *var = heap_bound_deref(&self.heap, *var);
- }
-
let singleton_var_list = push_var_eq_functors(
&mut self.heap,
term_write_result.var_dict.iter().filter(|(var_name, binding)| {
&mut self.atom_tbl,
);
+ for var in term_write_result.var_dict.values_mut() {
+ *var = heap_bound_deref(&self.heap, *var);
+ }
+
let mut var_list = Vec::with_capacity(singleton_var_set.len());
for (var_name, addr) in term_write_result.var_dict {
}
}
- var_list.sort_by(|(_,_,idx_1),(_,_,idx_2)| idx_1.cmp(idx_2));
-
- let list_of_var_eqs = push_var_eq_functors(
- &mut self.heap,
- var_list.iter().filter_map(|(var_name, var,_)| if var_name.is_anon() { None } else { Some((var_name,var)) }),
- &mut self.atom_tbl,
- );
-
- let singleton_addr = self.registers[3];
- let singletons_offset = heap_loc_as_cell!(
- iter_to_heap_list(&mut self.heap, singleton_var_list.into_iter())
- );
-
- unify_fn!(*self, singletons_offset, singleton_addr);
-
- if self.fail {
- return Ok(());
- }
-
- let vars_addr = self.registers[4];
- let vars_offset = heap_loc_as_cell!(
- iter_to_heap_list(&mut self.heap, var_list.into_iter().map(|(_,cell,_)| cell))
- );
-
- unify_fn!(*self, vars_offset, vars_addr);
-
- if self.fail {
- return Ok(());
- }
-
- let var_names_addr = self.registers[5];
- let var_names_offset = heap_loc_as_cell!(
- iter_to_heap_list(&mut self.heap, list_of_var_eqs.into_iter())
- );
-
- return Ok(unify_fn!(*self, var_names_offset, var_names_addr));
+ self.write_read_term_options(var_list, singleton_var_list)
}
pub fn read_term_from_user_input_eof_handler(&mut self, stream: Stream) -> Result<OnEOF, MachineStub> {
pub fn read_term_eof_handler(&mut self, mut stream: Stream) -> Result<OnEOF, MachineStub> {
if stream.at_end_of_stream() {
unify!(self, self.registers[2], atom_as_cell!(atom!("end_of_file")));
+ stream.set_past_end_of_stream(true);
return Ok(OnEOF::Return);
} else if stream.past_end_of_stream() {
self.eof_action(
match &err {
CompilationError::ParserError(e) if e.is_unexpected_eof() => {
match eof_handler(self, stream)? {
- OnEOF::Return => return Ok(()),
+ OnEOF::Return => return self.write_read_term_options(vec![], vec![]),
OnEOF::Continue => continue,
}
}
Instruction::ExecuteFunctor,
Instruction::ExecuteGround,
Instruction::ExecuteKeySort,
- Instruction::ExecuteRead,
Instruction::ExecuteSort,
Instruction::ExecuteN(1),
Instruction::ExecuteN(2),