add read_term_from_chars/3 (#637)
This commit is contained in:
@@ -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 |
|
||||
|
||||
@@ -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).
|
||||
%
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user