ExpandTerm,
FetchGlobalVar,
FetchGlobalVarWithOffset,
+ FileToChars,
GetChar,
GetSingleChar,
ResetAttrVarState,
&SystemClauseType::FetchGlobalVarWithOffset => {
clause_name!("$fetch_global_var_with_offset")
}
+ &SystemClauseType::FileToChars => clause_name!("$file_to_chars"),
&SystemClauseType::GetChar => clause_name!("$get_char"),
&SystemClauseType::GetSingleChar => clause_name!("$get_single_char"),
&SystemClauseType::ResetAttrVarState => clause_name!("$reset_attr_var_state"),
("$expand_goal", 2) => Some(SystemClauseType::ExpandGoal),
("$fetch_global_var", 2) => Some(SystemClauseType::FetchGlobalVar),
("$fetch_global_var_with_offset", 3) => Some(SystemClauseType::FetchGlobalVarWithOffset),
+ ("$file_to_chars", 2) => Some(SystemClauseType::FileToChars),
("$get_char", 1) => Some(SystemClauseType::GetChar),
("$get_single_char", 1) => Some(SystemClauseType::GetSingleChar),
("$points_to_cont_reset_marker", 1) => {
use std::cmp;
use std::convert::TryFrom;
-use std::io::{stdout, Write};
+use std::io::{stdout, Read, Write};
use std::iter::once;
+use std::fs::File;
use std::rc::Rc;
use std::time::Duration;
}
};
}
+ &SystemClauseType::FileToChars => {
+ let a1 = self.store(self.deref(self[temp_v!(1)]));
+ let a2 = self.store(self.deref(self[temp_v!(2)]));
+
+ let file_name = match a1 {
+ Addr::Con(h) if self.heap.atom_at(h) => {
+ if let HeapCellValue::Atom(name, _) = &self.heap[h] {
+ name.as_str().to_string()
+ }
+ else {
+ unreachable!()
+ }
+ }
+ Addr::Char(c) => {
+ c.to_string()
+ }
+ _ => unreachable!()
+ };
+ let name = clause_name!("$file_to_chars");
+ let mut file = match File::open(&file_name) {
+ Ok(f) => f,
+ Err(_e) => {
+ let file_name_ = clause_name!(file_name.clone(),
+ indices.atom_tbl.clone());
+ let arity = 2;
+ let stub = MachineError::functor_stub(name.clone(), arity);
+ let h = self.heap.h();
+
+ let err = MachineError::existence_error(
+ h,
+ ExistenceError::SourceSink(
+ ModuleSource::File(file_name_)
+ ),
+ );
+ let err = self.error_form(err, stub);
+
+ self.throw_exception(err);
+ return Ok(());
+ }
+ };
+ let mut buffer = String::new();
+ let _ = match file.read_to_string(&mut buffer) {
+ Ok(size) => size,
+ Err(_e) => {
+ // TODO: Distinguish the case/error.
+ let file_name_ = clause_name!(file_name.clone(),
+ indices.atom_tbl.clone());
+ let arity = 2;
+ let stub = MachineError::functor_stub(name.clone(), arity);
+ let h = self.heap.h();
+
+ let err = MachineError::existence_error(
+ h,
+ ExistenceError::SourceSink(
+ ModuleSource::File(file_name_)
+ ),
+ );
+ let err = self.error_form(err, stub);
+
+ self.throw_exception(err);
+ return Ok(());
+ }
+ };
+ let chars = buffer.trim().chars().map(|c| Addr::Char(c));
+ let char_list = Addr::HeapCell(self.heap.to_list(chars));
+
+ self.unify(char_list, a2);
+ }
&SystemClauseType::GetChar => {
let mut iter = parsing_stream(current_input_stream.clone());
let result = iter.next();