WAMInstructions,
#[strum_discriminants(strum(props(Arity = "2", Name = "$inlined_instructions")))]
InlinedInstructions,
- #[strum_discriminants(strum(props(Arity = "7", Name = "$write_term")))]
+ #[strum_discriminants(strum(props(Arity = "8", Name = "$write_term")))]
WriteTerm,
- #[strum_discriminants(strum(props(Arity = "7", Name = "$write_term_to_chars")))]
+ #[strum_discriminants(strum(props(Arity = "8", Name = "$write_term_to_chars")))]
WriteTermToChars,
#[strum_discriminants(strum(props(Arity = "1", Name = "$scryer_prolog_version")))]
ScryerPrologVersion,
iter: StackfulPreOrderHeapIter<'a>,
atom_tbl: &'a mut AtomTable,
op_dir: &'a OpDir,
+ flags: MachineFlags,
state_stack: Vec<TokenOrRedirect>,
toplevel_spec: Option<DirectedOp>,
last_item_idx: usize,
pub ignore_ops: bool,
pub print_strings_as_strs: bool,
pub max_depth: usize,
+ pub double_quotes: bool,
}
macro_rules! push_space_if_amb {
atom_tbl: &'a mut AtomTable,
stack: &'a mut Stack,
op_dir: &'a OpDir,
+ flags: MachineFlags,
output: Outputter,
cell: HeapCellValue,
) -> Self {
iter: stackful_preorder_iter(heap, stack, cell),
atom_tbl,
op_dir,
+ flags,
state_stack: vec![],
toplevel_spec: None,
last_item_idx: 0,
var_names: IndexMap::new(),
print_strings_as_strs: false,
max_depth: 0,
+ double_quotes: false,
}
}
let at_cdr = self.outputter.ends_with("|");
- if !at_cdr && !self.ignore_ops && end_cell.is_string_terminator(&self.iter.heap) {
- self.remove_list_children(focus.value() as usize);
- return self.print_proper_string(focus.value() as usize, max_depth);
+ if self.double_quotes && self.flags.double_quotes == DoubleQuotes::Chars {
+ if !at_cdr && !self.ignore_ops && end_cell.is_string_terminator(&self.iter.heap) {
+ self.remove_list_children(focus.value() as usize);
+ return self.print_proper_string(focus.value() as usize, max_depth);
+ }
}
if self.ignore_ops {
parse_write_options(Options, OptionValues, Stub) :-
- DefaultOptions = [ignore_ops-false, max_depth-0, numbervars-false,
+ DefaultOptions = [double_quotes-false, ignore_ops-false, max_depth-0, numbervars-false,
quoted-false, variable_names-[]],
parse_options_list(Options, builtins:parse_write_options_, DefaultOptions, OptionValues, Stub).
+
+parse_write_options_(double_quotes(DoubleQuotes), double_quotes-DoubleQuotes) :-
+ ( nonvar(DoubleQuotes),
+ lists:member(DoubleQuotes, [true, false]),
+ !
+ ; throw(error(domain_error(write_option, double_quotes(DoubleQuotes)), _))
+ ).
parse_write_options_(ignore_ops(IgnoreOps), ignore_ops-IgnoreOps) :-
( nonvar(IgnoreOps),
lists:member(IgnoreOps, [true, false]),
!
- ;
- throw(error(domain_error(write_option, ignore_ops(IgnoreOps)), _))
+ ; throw(error(domain_error(write_option, ignore_ops(IgnoreOps)), _))
).
parse_write_options_(quoted(Quoted), quoted-Quoted) :-
( nonvar(Quoted),
lists:member(Quoted, [true, false]),
!
- ;
- throw(error(domain_error(write_option, quoted(Quoted)), _))
+ ; throw(error(domain_error(write_option, quoted(Quoted)), _))
).
parse_write_options_(numbervars(NumberVars), numbervars-NumberVars) :-
( nonvar(NumberVars),
lists:member(NumberVars, [true, false]),
!
- ;
- throw(error(domain_error(write_option, numbervars(NumberVars)), _))
+ ; throw(error(domain_error(write_option, numbervars(NumberVars)), _))
).
parse_write_options_(variable_names(VNNames), variable_names-VNNames) :-
must_be_var_names_list(VNNames),
( integer(MaxDepth),
MaxDepth >= 0,
!
- ;
- throw(error(domain_error(write_option, max_depth(MaxDepth)), _))
+ ; throw(error(domain_error(write_option, max_depth(MaxDepth)), _))
).
parse_write_options_(E, _) :-
throw(error(domain_error(write_option, E), _)).
% * `max_depth(+N)` if the term is nested deeper than N, print the reminder as ellipses.
% If N = 0 (default), there's no limit.
% * `numbervars(+Boolean)` if true, replaces `$VAR(N)` variables with letters, in order. Default is false.
-% * `quoted(+Boolean)` if true, strings and atoms that need quotes to be valid Prolog synytax, are quoted. Default is false.
+% * `quoted(+Boolean)` if true, strings and atoms that need quotes to be valid Prolog syntax, are quoted. Default is false.
% * `variable_names(+List)` assign names to variables in term. List should be a list of terms of format `Name=Var`.
+% * `double_quotes(+Boolean)` if true, strings are printed in double quotes rather than with list notation. Default is false.
write_term(Stream, Term, Options) :-
- parse_write_options(Options, [IgnoreOps, MaxDepth, NumberVars, Quoted, VNNames], write_term/3),
- '$write_term'(Stream, Term, IgnoreOps, NumberVars, Quoted, VNNames, MaxDepth).
+ parse_write_options(Options, [DoubleQuotes, IgnoreOps, MaxDepth, NumberVars, Quoted, VNNames], write_term/3),
+ '$write_term'(Stream, Term, IgnoreOps, NumberVars, Quoted, VNNames, MaxDepth, DoubleQuotes).
%% write(+Term).
% Write Term to the current output stream using a syntax similar to Prolog
write(Term) :-
current_output(Stream),
- '$write_term'(Stream, Term, false, true, false, [], 0).
+ '$write_term'(Stream, Term, false, true, false, [], 0, false).
%% write(+Stream, +Term).
%
% Write Term to the stream Stream using a syntax similar to Prolog
write(Stream, Term) :-
- '$write_term'(Stream, Term, false, true, false, [], 0).
+ '$write_term'(Stream, Term, false, true, false, [], 0, false).
%% write_canonical(+Term).
%
% Write Term to the current output stream using canonical Prolog syntax. Can be read back as Prolog terms.
write_canonical(Term) :-
current_output(Stream),
- '$write_term'(Stream, Term, true, false, true, [], 0).
+ '$write_term'(Stream, Term, true, false, true, [], 0, false).
%% write_canonical(+Stream, +Term).
%
% Write Term to the stream Stream using canonical Prolog syntax. Can be read back as Prolog terms.
write_canonical(Stream, Term) :-
- '$write_term'(Stream, Term, true, false, true, [], 0).
+ '$write_term'(Stream, Term, true, false, true, [], 0, false).
%% writeq(+Term).
%
% quoted according to Prolog syntax.
writeq(Term) :-
current_output(Stream),
- '$write_term'(Stream, Term, false, true, true, [], 0).
+ '$write_term'(Stream, Term, false, true, true, [], 0, false).
%% writeq(+Stream, +Term).
%
% Write Term to the stream Stream using a syntax similar to `write/1` but quoting the atoms that need to be
% quoted according to Prolog syntax.
writeq(Stream, Term) :-
- '$write_term'(Stream, Term, false, true, true, [], 0).
+ '$write_term'(Stream, Term, false, true, true, [], 0, false).
select_rightmost_options([Option-Value | OptionPairs], OptionValues) :-
( pairs:same_key(Option, OptionPairs, OtherValues, _),
% * `max_depth(+N)` if the term is nested deeper than N, print the reminder as ellipses.
% If N = 0 (default), there's no limit.
% * `numbervars(+Boolean)` if true, replaces `$VAR(N)` variables with letters, in order. Default is false.
-% * `quoted(+Boolean)` if true, strings and atoms that need quotes to be valid Prolog synytax, are quoted. Default is false.
+% * `quoted(+Boolean)` if true, strings and atoms that need quotes to be valid Prolog syntax, are quoted. Default is false.
% * `variable_names(+List)` assign names to variables in term. List should be a list of terms of format `Name=Var`.
+% * `double_quotes(+Boolean)` if true, strings are printed in double quotes rather than with list notation. Default is false.
write_term_to_chars(_, Options, _) :-
var(Options), instantiation_error(write_term_to_chars/3).
write_term_to_chars(Term, Options, Chars) :-
builtins:parse_write_options(Options,
- [IgnoreOps, MaxDepth, NumberVars, Quoted, VNNames],
+ [DoubleQuotes, IgnoreOps, MaxDepth, NumberVars, Quoted, VNNames],
write_term_to_chars/3),
( nonvar(Chars) ->
throw(error(uninstantiation_error(Chars), write_term_to_chars/3))
),
term_variables(Term, Vars),
extend_var_list(Vars, VNNames, NewVarNames, numbervars),
- '$write_term_to_chars'(Chars, Term, IgnoreOps, NumberVars, Quoted, NewVarNames, MaxDepth).
+ '$write_term_to_chars'(Chars, Term, IgnoreOps, NumberVars, Quoted, NewVarNames, MaxDepth, DoubleQuotes).
% Encodes Ch character to list of Bytes.
char_utf8bytes(Ch, Bytes) :-
let numbervars = self.store(self.deref(self.registers[4]));
let quoted = self.store(self.deref(self.registers[5]));
let max_depth = self.store(self.deref(self.registers[7]));
+ let double_quotes = self.store(self.deref(self.registers[8]));
let term_to_be_printed = self.store(self.deref(self.registers[2]));
let stub_gen = || functor_stub(atom!("write_term"), 2);
);
let quoted = read_heap_cell!(quoted,
- (HeapCellValueTag::Atom, (name, _arity)) => {
+ (HeapCellValueTag::Atom, (name, arity)) => {
+ debug_assert_eq!(arity, 0);
+ name == atom!("true")
+ }
+ (HeapCellValueTag::Str, s) => {
+ let (name, arity) = cell_as_atom_cell!(self.heap[s])
+ .get_name_and_arity();
+
+ debug_assert_eq!(arity, 0);
+ name == atom!("true")
+ }
+ _ => {
+ unreachable!()
+ }
+ );
+
+ let double_quotes = read_heap_cell!(double_quotes,
+ (HeapCellValueTag::Atom, (name, arity)) => {
+ debug_assert_eq!(arity, 0);
name == atom!("true")
}
(HeapCellValueTag::Str, s) => {
&mut self.atom_tbl,
&mut self.stack,
op_dir,
+ self.flags,
PrinterOutputter::new(),
term_to_be_printed,
);
printer.ignore_ops = ignore_ops;
printer.numbervars = numbervars;
printer.quoted = quoted;
+ printer.double_quotes = double_quotes;
match Number::try_from(max_depth) {
Ok(Number::Fixnum(n)) => {
&mut self.machine_st.atom_tbl,
&mut self.machine_st.stack,
&self.op_dir,
+ self.machine_st.flags,
PrinterOutputter::new(),
heap_loc_as_cell!(term_write_result.heap_loc),
);
}
}
-#[derive(Debug, Clone, Copy)]
+#[derive(Debug, Clone, Copy, PartialEq)]
pub enum DoubleQuotes {
Atom,
Chars,
write(' = '),
( needs_bracketing(Value, =) ->
write('('),
- write_term(Value, [quoted(true), variable_names(NewVarList), max_depth(MaxDepth)]),
+ write_term(Value, [quoted(true), variable_names(NewVarList), max_depth(MaxDepth), double_quotes(true)]),
write(')')
- ; write_term(Value, [quoted(true), variable_names(NewVarList), max_depth(MaxDepth)])
+ ; write_term(Value, [quoted(true), variable_names(NewVarList), max_depth(MaxDepth), double_quotes(true)])
)
; G == [] ->
write('true')
- ; write_term(G, [quoted(true), variable_names(VarList), max_depth(MaxDepth)])
+ ; write_term(G, [quoted(true), variable_names(VarList), max_depth(MaxDepth), double_quotes(true)])
).
write_last_goal(G, VarList, MaxDepth) :-
write(' = '),
( needs_bracketing(Value, =) ->
write('('),
- write_term(Value, [quoted(true), variable_names(NewVarList), max_depth(MaxDepth)]),
+ write_term(Value, [quoted(true), variable_names(NewVarList), max_depth(MaxDepth), double_quotes(true)]),
write(')')
- ; write_term(Value, [quoted(true), variable_names(NewVarList), max_depth(MaxDepth)]),
+ ; write_term(Value, [quoted(true), variable_names(NewVarList), max_depth(MaxDepth), double_quotes(true)]),
( trailing_period_is_ambiguous(Value) ->
write(' ')
; true
)
; G == [] ->
write('true')
- ; write_term(G, [quoted(true), variable_names(VarList), max_depth(MaxDepth)])
+ ; write_term(G, [quoted(true), variable_names(VarList), max_depth(MaxDepth), double_quotes(true)])
).
write_eq((G1, G2), VarList, MaxDepth) :-