]> Repositorios git - scryer-prolog.git/commitdiff
add read_term_from_chars/3 (#637)
authorMark <[email protected]>
Sat, 15 Jul 2023 17:20:20 +0000 (11:20 -0600)
committerMark <[email protected]>
Sat, 15 Jul 2023 17:20:20 +0000 (11:20 -0600)
build/instructions_template.rs
src/lib/charsio.pl
src/machine/dispatch.rs
src/machine/system_calls.rs

index 5eaa542b6d93a7e241e12707a152ec259182dd3c..62dc6146a92d000fdfcc02e065b39f933d352b34 100644 (file)
@@ -418,7 +418,9 @@ enum SystemClauseType {
     CurrentTime,
     #[strum_discriminants(strum(props(Arity = "1", Name = "$quoted_token")))]
     QuotedToken,
-    #[strum_discriminants(strum(props(Arity = "2", Name = "$read_term_from_chars")))]
+    #[strum_discriminants(strum(props(Arity = "2", Name = "$read_from_chars")))]
+    ReadFromChars,
+    #[strum_discriminants(strum(props(Arity = "5", Name = "$read_term_from_chars")))]
     ReadTermFromChars,
     #[strum_discriminants(strum(props(Arity = "1", Name = "$reset_block")))]
     ResetBlock,
@@ -1735,6 +1737,7 @@ fn generate_instruction_preface() -> TokenStream {
                     &Instruction::CallStripModule |
                     &Instruction::CallCurrentTime |
                     &Instruction::CallQuotedToken |
+                    &Instruction::CallReadFromChars |
                     &Instruction::CallReadTermFromChars |
                     &Instruction::CallResetBlock |
                     &Instruction::CallResetSCCBlock |
@@ -1959,6 +1962,7 @@ fn generate_instruction_preface() -> TokenStream {
                     &Instruction::ExecuteStripModule |
                     &Instruction::ExecuteCurrentTime |
                     &Instruction::ExecuteQuotedToken |
+                    &Instruction::ExecuteReadFromChars |
                     &Instruction::ExecuteReadTermFromChars |
                     &Instruction::ExecuteResetBlock |
                     &Instruction::ExecuteResetSCCBlock |
index 128a6c5004c6c9fbee7e8189d6c453e788d15023..618416f19bc6f05a730c175fd660e2b113e093a4 100644 (file)
@@ -12,6 +12,7 @@ read and write chars.
                     get_n_chars/3,
                     get_line_to_chars/3,
                     read_from_chars/2,
+                    read_term_from_chars/3,
                     write_term_to_chars/3,
                     chars_base64/3]).
 
@@ -194,7 +195,22 @@ get_single_char(C) :-
 read_from_chars(Chars, Term) :-
     must_be(chars, Chars),
     must_be(var, Term),
-    '$read_term_from_chars'(Chars, Term).
+    '$read_from_chars'(Chars, Term).
+
+%% read_term_from_chars(+Chars, -Term, +Options).
+%
+% Like `read_from_chars`, except the reader is configured according to
+% `Options` which are those of `read_term`.
+%
+% ```
+% ?- read_term_from_chars("f(X,y).", T, [variable_names(['X'=X])]).
+%    T = f(X,y).
+% ```
+read_term_from_chars(Chars, Term, Options) :-
+    must_be(chars, Chars),
+    must_be(var, Term),
+    builtins:parse_read_term_options(Options, [Singletons, VariableNames, Variables], read_term_from_chars/3),
+    '$read_term_from_chars'(Chars, Term, Singletons, Variables, VariableNames).
 
 %% write_term_to_chars(+Term, +Options, -Chars).
 %
index afe67fb9e0785ea10291dfc69919d8aa9b84dc44..b57e77b928e2010e770d8e867e8f1aee8d980d19 100644 (file)
@@ -4270,6 +4270,14 @@ impl Machine {
                     self.quoted_token();
                     step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
                 }
+                &Instruction::CallReadFromChars => {
+                    try_or_throw!(self.machine_st, self.read_from_chars());
+                    step_or_fail!(self, self.machine_st.p += 1);
+                }
+                &Instruction::ExecuteReadFromChars => {
+                    try_or_throw!(self.machine_st, self.read_from_chars());
+                    step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+                }
                 &Instruction::CallReadTermFromChars => {
                     try_or_throw!(self.machine_st, self.read_term_from_chars());
                     step_or_fail!(self, self.machine_st.p += 1);
index d53ef79fd7868eaa011193d97786babe9c0900a7..35e019ffd1bd14e115bab0c30668b24ae39dd31f 100644 (file)
@@ -5792,7 +5792,7 @@ impl Machine {
     }
 
     #[inline(always)]
-    pub(crate) fn read_term_from_chars(&mut self) -> CallResult {
+    pub(crate) fn read_from_chars(&mut self) -> CallResult {
         if let Some(atom_or_string) = self.machine_st.value_to_str_like(self.machine_st.registers[1]) {
             let chars = CharReader::new(ByteStream::from_string(atom_or_string.to_string()));
             let mut parser = Parser::new(chars, &mut self.machine_st);
@@ -5829,6 +5829,16 @@ impl Machine {
         Ok(())
     }
 
+    #[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)
+        } else {
+            unreachable!()
+        }
+    }
+
     #[inline(always)]
     pub(crate) fn reset_block(&mut self) {
         let addr = self.deref_register(1);