Variant,
WAMInstructions,
WriteTerm,
+ WriteTermToChars,
}
impl SystemClauseType {
&SystemClauseType::CurrentInput => clause_name!("$current_input"),
&SystemClauseType::CurrentOutput => clause_name!("$current_output"),
&SystemClauseType::REPL(REPLCodePtr::CompileBatch) => clause_name!("$compile_batch"),
- &SystemClauseType::REPL(REPLCodePtr::UseModule) => clause_name!("$use_module"),
- &SystemClauseType::REPL(REPLCodePtr::UseQualifiedModule) => {
- clause_name!("$use_qualified_module")
- }
- &SystemClauseType::REPL(REPLCodePtr::UseModuleFromFile) => {
- clause_name!("$use_module_from_file")
- }
- &SystemClauseType::REPL(REPLCodePtr::UseQualifiedModuleFromFile) => {
- clause_name!("$use_qualified_module_from_file")
- }
+ &SystemClauseType::REPL(REPLCodePtr::UseModule) => clause_name!("$use_module"),
+ &SystemClauseType::REPL(REPLCodePtr::UseQualifiedModule) => {
+ clause_name!("$use_qualified_module")
+ }
+ &SystemClauseType::REPL(REPLCodePtr::UseModuleFromFile) => {
+ clause_name!("$use_module_from_file")
+ }
+ &SystemClauseType::REPL(REPLCodePtr::UseQualifiedModuleFromFile) => {
+ clause_name!("$use_qualified_module_from_file")
+ }
&SystemClauseType::CopyToLiftedHeap => clause_name!("$copy_to_lh"),
&SystemClauseType::DeleteAttribute => clause_name!("$del_attr_non_head"),
&SystemClauseType::DeleteHeadAttribute => clause_name!("$del_attr_head"),
&SystemClauseType::Variant => clause_name!("$variant"),
&SystemClauseType::WAMInstructions => clause_name!("$wam_instructions"),
&SystemClauseType::WriteTerm => clause_name!("$write_term"),
+ &SystemClauseType::WriteTermToChars => clause_name!("$write_term_to_chars"),
}
}
("$unwind_environments", 0) => Some(SystemClauseType::UnwindEnvironments),
("$unwind_stack", 0) => Some(SystemClauseType::UnwindStack),
("$unify_with_occurs_check", 2) => Some(SystemClauseType::UnifyWithOccursCheck),
- ("$use_module", 1) => Some(SystemClauseType::REPL(REPLCodePtr::UseModule)),
- ("$use_module_from_file", 1) =>
- Some(SystemClauseType::REPL(REPLCodePtr::UseModuleFromFile)),
- ("$use_qualified_module", 2) =>
- Some(SystemClauseType::REPL(REPLCodePtr::UseQualifiedModule)),
- ("$use_qualified_module_from_file", 2) =>
- Some(SystemClauseType::REPL(REPLCodePtr::UseQualifiedModuleFromFile)),
+ ("$use_module", 1) => Some(SystemClauseType::REPL(REPLCodePtr::UseModule)),
+ ("$use_module_from_file", 1) =>
+ Some(SystemClauseType::REPL(REPLCodePtr::UseModuleFromFile)),
+ ("$use_qualified_module", 2) =>
+ Some(SystemClauseType::REPL(REPLCodePtr::UseQualifiedModule)),
+ ("$use_qualified_module_from_file", 2) =>
+ Some(SystemClauseType::REPL(REPLCodePtr::UseQualifiedModuleFromFile)),
("$variant", 2) => Some(SystemClauseType::Variant),
- ("$write_term", 6) => Some(SystemClauseType::WriteTerm),
("$wam_instructions", 3) => Some(SystemClauseType::WAMInstructions),
+ ("$write_term", 6) => Some(SystemClauseType::WriteTerm),
+ ("$write_term_to_chars", 7) => Some(SystemClauseType::WriteTermToChars),
_ => None,
}
}
%% ?- use_module(library(iso_ext)).
:- module(iso_ext, [bb_b_put/2, bb_get/2, bb_put/2, call_cleanup/2,
- call_with_inference_limit/3, forall/2, maybe/0,
- partial_string/1, partial_string/3,
- partial_string_tail/2, set_random/1,
- setup_call_cleanup/3, variant/2]).
+ call_with_inference_limit/3, forall/2, maybe/0,
+ partial_string/1, partial_string/3,
+ partial_string_tail/2, set_random/1,
+ setup_call_cleanup/3, variant/2,
+ write_term_to_chars/3]).
forall(Generate, Test) :-
\+ (Generate, \+ Test).
; throw(error(instantiation_error, set_random/1))
).
+
partial_string(String, L, L0) :-
( String == [] ->
L = L0
'$partial_string_tail'(String, Tail)
; throw(error(type_error(partial_string, String), partial_string_tail/2))
).
+
+
+write_term_to_chars(_, Options, _) :-
+ var(Options), throw(error(instantiation_error, write_term_to_chars/3)).
+write_term_to_chars(Term, Options, Chars) :-
+ '$skip_max_list'(_, -1, Options, Options0),
+ ( var(Options0) ->
+ throw(error(instantiation_error, write_term_to_chars/3))
+ ; var(Term) ->
+ throw(error(instantiation_error, write_term_to_chars/3))
+ ; nonvar(Chars) ->
+ throw(error(uninstantiation_error(Chars), write_term_to_chars/3))
+ ; Options0 == [] ->
+ true
+ ;
+ throw(error(type_error(list, Options), write_term_to_chars/3))
+ ),
+ builtins:inst_member_or(Options, ignore_ops(IgnoreOps), ignore_ops(false)),
+ builtins:inst_member_or(Options, numbervars(NumberVars), numbervars(false)),
+ builtins:inst_member_or(Options, quoted(Quoted), quoted(false)),
+ builtins:inst_member_or(Options, variable_names(VarNames), variable_names([])),
+ builtins:inst_member_or(Options, max_depth(MaxDepth), max_depth(0)),
+ '$write_term_to_chars'(Term, IgnoreOps, NumberVars, Quoted, VarNames, MaxDepth, Chars).
use crate::prolog::clause_types::*;
use crate::prolog::forms::*;
+use crate::prolog::heap_print::*;
use crate::prolog::machine::attributed_variables::*;
use crate::prolog::machine::copier::*;
use crate::prolog::machine::heap::*;
use downcast::Any;
-use indexmap::IndexSet;
+use indexmap::{IndexMap, IndexSet};
use std::cmp::Ordering;
+use std::convert::TryFrom;
use std::io::Write;
use std::mem;
use std::ops::{Index, IndexMut};
}
impl MachineState {
+ pub(crate)
+ fn write_term<'a>(
+ &'a self,
+ op_dir: &'a OpDir,
+ ) -> Result<Option<HCPrinter<'a, PrinterOutputter>>, MachineStub>
+ {
+ let ignore_ops = self.store(self.deref(self[temp_v!(2)]));
+ let numbervars = self.store(self.deref(self[temp_v!(3)]));
+ let quoted = self.store(self.deref(self[temp_v!(4)]));
+ let max_depth = self.store(self.deref(self[temp_v!(6)]));
+
+ let mut printer = HCPrinter::new(&self, op_dir, PrinterOutputter::new());
+
+ if let &Addr::Con(h) = &ignore_ops {
+ if let HeapCellValue::Atom(ref name, _) = &self.heap[h] {
+ printer.ignore_ops = name.as_str() == "true";
+ } else {
+ unreachable!()
+ }
+ }
+
+ if let &Addr::Con(h) = &numbervars {
+ if let HeapCellValue::Atom(ref name, _) = &self.heap[h] {
+ printer.numbervars = name.as_str() == "true";
+ } else {
+ unreachable!()
+ }
+ }
+
+ if let &Addr::Con(h) = "ed {
+ if let HeapCellValue::Atom(ref name, _) = &self.heap[h] {
+ printer.quoted = name.as_str() == "true";
+ } else {
+ unreachable!()
+ }
+ }
+
+ match Number::try_from((max_depth, &self.heap)) {
+ Ok(Number::Fixnum(n)) => {
+ if let Ok(n) = usize::try_from(n) {
+ printer.max_depth = n;
+ } else {
+ return Ok(None);
+ }
+ }
+ Ok(Number::Integer(n)) => {
+ if let Some(n) = n.to_usize() {
+ printer.max_depth = n;
+ } else {
+ return Ok(None);
+ }
+ }
+ _ => {
+ unreachable!();
+ }
+ }
+
+ let stub = MachineError::functor_stub(clause_name!("write_term"), 2);
+
+ match self.try_from_list(temp_v!(5), stub) {
+ Ok(addrs) => {
+ let mut var_names: IndexMap<Addr, String> = IndexMap::new();
+
+ for addr in addrs {
+ match addr {
+ Addr::Str(s) => match &self.heap[s] {
+ &HeapCellValue::NamedStr(2, ref name, _)
+ if name.as_str() == "=" =>
+ {
+ let atom = self.heap[s + 1].as_addr(s + 1);
+ let var = self.heap[s + 2].as_addr(s + 2);
+
+ let atom = match self.store(self.deref(atom)) {
+ Addr::Con(h) => {
+ if let HeapCellValue::Atom(ref atom, _) = &self.heap[h] {
+ atom.to_string()
+ } else {
+ unreachable!()
+ }
+ }
+ Addr::Char(c) => c.to_string(),
+ _ => unreachable!(),
+ };
+
+ let var = self.store(self.deref(var));
+
+ if var_names.contains_key(&var) {
+ continue;
+ }
+
+ var_names.insert(var, atom);
+ }
+ _ => unreachable!(),
+ },
+ _ => unreachable!(),
+ }
+ }
+
+ printer.var_names = var_names;
+ }
+ Err(err) => {
+ return Err(err);
+ }
+ }
+
+ Ok(Some(printer))
+ }
+
#[inline]
pub(crate)
fn heap_pstr_iter<'a>(&'a self, focus: Addr) -> HeapPStrIter<'a> {
use crate::prolog::clause_types::*;
use crate::prolog::forms::*;
-use crate::prolog::heap_print::*;
use crate::prolog::instructions::*;
use crate::prolog::machine::code_repo::CodeRepo;
use crate::prolog::machine::copier::*;
use crate::prolog::machine::code_walker::*;
+use crate::prolog::heap_print::*;
use crate::prolog::machine::machine_errors::*;
use crate::prolog::machine::machine_indices::*;
use crate::prolog::machine::machine_state::*;
use crate::ref_thread_local::RefThreadLocal;
-use indexmap::{IndexMap, IndexSet};
+use indexmap::IndexSet;
use std::cmp;
use std::convert::TryFrom;
&SystemClauseType::WriteTerm => {
let addr = self[temp_v!(1)];
- let ignore_ops = self.store(self.deref(self[temp_v!(2)]));
- let numbervars = self.store(self.deref(self[temp_v!(3)]));
- let quoted = self.store(self.deref(self[temp_v!(4)]));
- let max_depth = self.store(self.deref(self[temp_v!(6)]));
-
- let mut printer = HCPrinter::new(&self, &indices.op_dir, PrinterOutputter::new());
-
- if let &Addr::Con(h) = &ignore_ops {
- if let HeapCellValue::Atom(ref name, _) = &self.heap[h] {
- printer.ignore_ops = name.as_str() == "true";
- } else {
- unreachable!()
- }
- }
-
- if let &Addr::Con(h) = &numbervars {
- if let HeapCellValue::Atom(ref name, _) = &self.heap[h] {
- printer.numbervars = name.as_str() == "true";
- } else {
- unreachable!()
- }
- }
-
- if let &Addr::Con(h) = "ed {
- if let HeapCellValue::Atom(ref name, _) = &self.heap[h] {
- printer.quoted = name.as_str() == "true";
- } else {
- unreachable!()
- }
- }
-
- match Number::try_from((max_depth, &self.heap)) {
- Ok(Number::Fixnum(n)) => {
- if let Ok(n) = usize::try_from(n) {
- printer.max_depth = n;
- } else {
+ let printer =
+ match self.write_term(&indices.op_dir)? {
+ None => {
self.fail = true;
return Ok(());
}
- }
- Ok(Number::Integer(n)) => {
- if let Some(n) = n.to_usize() {
- printer.max_depth = n;
- } else {
- self.fail = true;
- return Ok(());
+ Some(printer) => {
+ printer
}
- }
- _ => {
- unreachable!();
- }
- }
-
- let stub = MachineError::functor_stub(clause_name!("write_term"), 2);
+ };
- match self.try_from_list(temp_v!(5), stub) {
- Ok(addrs) => {
- let mut var_names: IndexMap<Addr, String> = IndexMap::new();
+ let output = printer.print(addr);
- for addr in addrs {
- match addr {
- Addr::Str(s) => match &self.heap[s] {
- &HeapCellValue::NamedStr(2, ref name, _)
- if name.as_str() == "=" =>
- {
- let atom = self.heap[s + 1].as_addr(s + 1);
- let var = self.heap[s + 2].as_addr(s + 2);
-
- let atom = match self.store(self.deref(atom)) {
- Addr::Con(h) => {
- if let HeapCellValue::Atom(ref atom, _) = &self.heap[h] {
- atom.to_string()
- } else {
- unreachable!()
- }
- }
- Addr::Char(c) => c.to_string(),
- _ => unreachable!(),
- };
+ print!("{}", output.result());
+ stdout().flush().unwrap();
+ }
+ &SystemClauseType::WriteTermToChars => {
+ let addr = self[temp_v!(1)];
- let var = self.store(self.deref(var));
+ let printer =
+ match self.write_term(&indices.op_dir)? {
+ None => {
+ self.fail = true;
+ return Ok(());
+ }
+ Some(printer) => {
+ printer
+ }
+ };
- if var_names.contains_key(&var) {
- continue;
- }
+ let result = printer.print(addr).result();
+ let chars = self.heap.put_complete_string(&result);
- var_names.insert(var, atom);
- }
- _ => unreachable!(),
- },
- _ => unreachable!(),
- }
- }
+ let result_addr = self.store(self.deref(self[temp_v!(7)]));
- printer.var_names = var_names;
- }
- Err(err) => return Err(err),
+ if let Some(var) = result_addr.as_var() {
+ self.bind(var, chars);
+ } else {
+ unreachable!()
}
-
- let output = printer.print(addr);
- print!("{}", output.result());
- stdout().flush().unwrap();
}
};