From: notoria Date: Sat, 25 Apr 2020 16:00:16 +0000 (+0200) Subject: Implemented phrase_from_file/2 and /2 X-Git-Tag: v0.8.123~106^2~5^2~1 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=d6772c5ca5359d9e5a8de15a110e10408e213275;p=scryer-prolog.git Implemented phrase_from_file/2 and /2 --- diff --git a/src/prolog/clause_types.rs b/src/prolog/clause_types.rs index 53d0f8e1..756080ca 100644 --- a/src/prolog/clause_types.rs +++ b/src/prolog/clause_types.rs @@ -178,6 +178,7 @@ pub enum SystemClauseType { ExpandTerm, FetchGlobalVar, FetchGlobalVarWithOffset, + FileToChars, GetChar, GetSingleChar, ResetAttrVarState, @@ -312,6 +313,7 @@ impl SystemClauseType { &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"), @@ -461,6 +463,7 @@ impl SystemClauseType { ("$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) => { diff --git a/src/prolog/lib/pio.pl b/src/prolog/lib/pio.pl new file mode 100644 index 00000000..c4ee0a27 --- /dev/null +++ b/src/prolog/lib/pio.pl @@ -0,0 +1,7 @@ +:- module(pio, [phrase_from_file/2]). + +:- use_module(library(dcgs)). + +phrase_from_file(NT, File) :- + '$file_to_chars'(File, Chars), + phrase(NT, Chars). diff --git a/src/prolog/machine/system_calls.rs b/src/prolog/machine/system_calls.rs index fe88f062..eec6fc89 100644 --- a/src/prolog/machine/system_calls.rs +++ b/src/prolog/machine/system_calls.rs @@ -24,8 +24,9 @@ use indexmap::IndexSet; 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; @@ -1519,6 +1520,74 @@ impl MachineState { } }; } + &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();