]> Repositorios git - scryer-prolog.git/commitdiff
remove read/{1,2} as a builtin, write read options upon EOF, throw better domain...
authorMark <[email protected]>
Mon, 17 Jul 2023 22:45:03 +0000 (16:45 -0600)
committerMark <[email protected]>
Mon, 17 Jul 2023 22:45:03 +0000 (16:45 -0600)
build/instructions_template.rs
src/lib/builtins.pl
src/machine/dispatch.rs
src/machine/machine_state.rs
src/machine/mod.rs

index 62dc6146a92d000fdfcc02e065b39f933d352b34..d97410eb9a676bd72bceec2c9c48e830d67e2634 100644 (file)
@@ -101,8 +101,6 @@ enum BuiltInClauseType {
     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,
 }
@@ -1504,7 +1502,6 @@ fn generate_instruction_preface() -> TokenStream {
                     &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)])
@@ -1530,7 +1527,6 @@ fn generate_instruction_preface() -> TokenStream {
                     &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)])
@@ -1556,7 +1552,6 @@ fn generate_instruction_preface() -> TokenStream {
                     &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)])
@@ -1582,7 +1577,6 @@ fn generate_instruction_preface() -> TokenStream {
                     &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)])
index db5282f7f698992abe0cb0f24720dc2301dced43..dcc37eb01d4db1a05ef009b5b06965cefdda4fe5 100644 (file)
                      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
@@ -668,9 +668,30 @@ parse_read_term_options(Options, OptionValues, Stub) :-
     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), _)).
 
@@ -698,7 +719,11 @@ read_term(Term, Options) :-
 % 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, _)  :-
index b57e77b928e2010e770d8e867e8f1aee8d980d19..669b011b76e2a1057edc815bf166f52050b76040 100644 (file)
@@ -309,34 +309,6 @@ impl MachineState {
 }
 
 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] {
@@ -1334,19 +1306,6 @@ impl Machine {
                         }
                     }
                 }
-                &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);
@@ -1673,34 +1632,6 @@ impl Machine {
                         }
                     }
                 }
-                &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);
 
index d7b66f2e5fb36af204653014877ec77357d64726..62663ee29d0b8fec6e95fbae70d99ef25e6010be 100644 (file)
@@ -200,6 +200,27 @@ pub fn pstr_loc_and_offset(heap: &[HeapCellValue], index: usize) -> (usize, Fixn
     )
 }
 
+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,
@@ -489,28 +510,50 @@ impl MachineState {
         }
     }
 
-    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)
@@ -542,10 +585,6 @@ impl MachineState {
             }
         }
 
-        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)| {
@@ -562,6 +601,10 @@ impl MachineState {
             &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 {
@@ -571,42 +614,7 @@ impl MachineState {
             }
         }
 
-        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> {
@@ -649,6 +657,7 @@ impl MachineState {
     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(
@@ -697,7 +706,7 @@ impl MachineState {
                     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,
                             }
                         }
index 41cc4f394fc27e0d51ad041aa376e33613a84028..402c83fb125ff9787bbbf2395cba37ce2f39923e 100644 (file)
@@ -385,7 +385,6 @@ impl Machine {
             Instruction::ExecuteFunctor,
             Instruction::ExecuteGround,
             Instruction::ExecuteKeySort,
-            Instruction::ExecuteRead,
             Instruction::ExecuteSort,
             Instruction::ExecuteN(1),
             Instruction::ExecuteN(2),