add read/2 and nl/1 (#896)

This commit is contained in:
Mark Thom
2021-05-01 15:29:41 -06:00
parent d0b25de554
commit b21a096516
8 changed files with 169 additions and 129 deletions

View File

@@ -1586,7 +1586,7 @@ impl Machine {
self.machine_st,
self.machine_st.get_stream_or_alias(
self.machine_st[temp_v!(1)],
&self.indices,
&self.indices.stream_aliases,
"$push_load_context",
2,
)

View File

@@ -24,7 +24,6 @@ use indexmap::IndexMap;
use std::cmp::Ordering;
use std::convert::TryFrom;
use std::fmt;
use std::io::Write;
use std::mem;
use std::ops::{Index, IndexMut};
use std::rc::Rc;
@@ -685,8 +684,7 @@ impl MachineState {
key: PredicateKey,
module_name: ClauseName,
_last_call: bool,
current_input_stream: &mut Stream,
current_output_stream: &mut Stream,
stream_aliases: &StreamAliasDir,
) -> CallResult {
if module_name.as_str() == "user" {
return call_policy.call_clause_type(
@@ -694,8 +692,7 @@ impl MachineState {
key,
&indices.code_dir,
&indices.op_dir,
current_input_stream,
current_output_stream,
stream_aliases,
);
} else if let Some(module) = indices.modules.get(&module_name) {
return call_policy.call_clause_type(
@@ -703,8 +700,7 @@ impl MachineState {
key,
&module.code_dir,
&module.op_dir,
current_input_stream,
current_output_stream,
stream_aliases,
);
}
@@ -1020,8 +1016,7 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
ct: &BuiltInClauseType,
_code_dir: &CodeDir,
op_dir: &OpDir,
current_input_stream: &mut Stream,
current_output_stream: &mut Stream,
stream_aliases: &StreamAliasDir,
) -> CallResult {
match ct {
&BuiltInClauseType::AcyclicTerm => {
@@ -1091,24 +1086,21 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
machine_st.compare_term(qt);
return_from_clause!(machine_st.last_call, machine_st)
}
&BuiltInClauseType::Nl => {
write!(current_output_stream, "\n").unwrap();
current_output_stream.flush().unwrap();
return_from_clause!(machine_st.last_call, machine_st)
}
&BuiltInClauseType::Read => {
match machine_st.read(
current_input_stream.clone(),
machine_st.atom_tbl.clone(),
op_dir,
) {
let stream = machine_st.get_stream_or_alias(
machine_st[temp_v!(1)],
stream_aliases,
"read",
2,
)?;
match machine_st.read(stream, machine_st.atom_tbl.clone(), op_dir) {
Ok(offset) => {
let addr = machine_st[temp_v!(1)];
let addr = machine_st[temp_v!(2)];
(machine_st.unify_fn)(machine_st, addr, Addr::HeapCell(offset.heap_loc));
}
Err(ParserError::UnexpectedEOF) => {
let addr = machine_st[temp_v!(1)];
let addr = machine_st[temp_v!(2)];
let eof = clause_name!("end_of_file".to_string(), machine_st.atom_tbl);
let atom = machine_st.heap.to_unifiable(HeapCellValue::Atom(eof, None));
@@ -1117,7 +1109,7 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
}
Err(e) => {
let h = machine_st.heap.h();
let stub = MachineError::functor_stub(clause_name!("read"), 1);
let stub = MachineError::functor_stub(clause_name!("read"), 2);
let err = MachineError::syntax_error(h, e);
let err = machine_st.error_form(err, stub);
@@ -1225,22 +1217,14 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
key: PredicateKey,
code_dir: &CodeDir,
op_dir: &OpDir,
current_input_stream: &mut Stream,
current_output_stream: &mut Stream,
stream_aliases: &StreamAliasDir,
) -> CallResult {
let (name, arity) = key;
match ClauseType::from(name.clone(), arity, None) {
ClauseType::BuiltIn(built_in) => {
machine_st.setup_built_in_call(built_in.clone());
self.call_builtin(
machine_st,
&built_in,
code_dir,
op_dir,
current_input_stream,
current_output_stream,
)?;
self.call_builtin(machine_st, &built_in, code_dir, op_dir, stream_aliases)?;
}
ClauseType::CallN => {
machine_st.handle_internal_call_n(arity);
@@ -1285,18 +1269,10 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
arity: usize,
code_dir: &CodeDir,
op_dir: &OpDir,
current_input_stream: &mut Stream,
current_output_stream: &mut Stream,
stream_aliases: &StreamAliasDir,
) -> CallResult {
if let Some(key) = machine_st.setup_call_n(arity) {
self.call_clause_type(
machine_st,
key,
code_dir,
op_dir,
current_input_stream,
current_output_stream,
)?;
self.call_clause_type(machine_st, key, code_dir, op_dir, stream_aliases)?;
}
Ok(())
@@ -1364,17 +1340,10 @@ impl CallPolicy for CWILCallPolicy {
ct: &BuiltInClauseType,
code_dir: &CodeDir,
op_dir: &OpDir,
current_input_stream: &mut Stream,
current_output_stream: &mut Stream,
stream_aliases: &StreamAliasDir,
) -> CallResult {
self.prev_policy.call_builtin(
machine_st,
ct,
code_dir,
op_dir,
current_input_stream,
current_output_stream,
)?;
self.prev_policy
.call_builtin(machine_st, ct, code_dir, op_dir, stream_aliases)?;
self.increment(machine_st)
}
@@ -1385,17 +1354,10 @@ impl CallPolicy for CWILCallPolicy {
arity: usize,
code_dir: &CodeDir,
op_dir: &OpDir,
current_input_stream: &mut Stream,
current_output_stream: &mut Stream,
stream_aliases: &StreamAliasDir,
) -> CallResult {
self.prev_policy.call_n(
machine_st,
arity,
code_dir,
op_dir,
current_input_stream,
current_output_stream,
)?;
self.prev_policy
.call_n(machine_st, arity, code_dir, op_dir, stream_aliases)?;
self.increment(machine_st)
}

View File

@@ -3101,8 +3101,7 @@ impl MachineState {
ct,
&indices.code_dir,
&indices.op_dir,
current_input_stream,
current_output_stream,
&indices.stream_aliases,
)
),
&ClauseType::CallN => try_or_fail!(
@@ -3112,8 +3111,7 @@ impl MachineState {
arity,
&indices.code_dir,
&indices.op_dir,
current_input_stream,
current_output_stream,
&indices.stream_aliases,
)
),
&ClauseType::Inlined(ref ct) => {

View File

@@ -916,14 +916,14 @@ impl MachineState {
pub(crate) fn get_stream_or_alias(
&mut self,
addr: Addr,
indices: &IndexStore,
stream_aliases: &StreamAliasDir,
caller: &'static str,
arity: usize,
) -> Result<Stream, MachineStub> {
Ok(match self.store(self.deref(addr)) {
Addr::Con(h) if self.heap.atom_at(h) => {
if let HeapCellValue::Atom(ref atom, ref spec) = self.heap.clone(h) {
match indices.stream_aliases.get(atom) {
match stream_aliases.get(atom) {
Some(stream) if !stream.is_null_stream() => stream.clone(),
_ => {
let stub = MachineError::functor_stub(clause_name!(caller), arity);

View File

@@ -1292,8 +1292,12 @@ impl MachineState {
}
}
&SystemClauseType::PeekByte => {
let mut stream =
self.get_stream_or_alias(self[temp_v!(1)], indices, "peek_byte", 2)?;
let mut stream = self.get_stream_or_alias(
self[temp_v!(1)],
&indices.stream_aliases,
"peek_byte",
2,
)?;
self.check_stream_properties(
&mut stream,
@@ -1390,8 +1394,12 @@ impl MachineState {
}
}
&SystemClauseType::PeekChar => {
let mut stream =
self.get_stream_or_alias(self[temp_v!(1)], indices, "peek_char", 2)?;
let mut stream = self.get_stream_or_alias(
self[temp_v!(1)],
&indices.stream_aliases,
"peek_char",
2,
)?;
self.check_stream_properties(
&mut stream,
@@ -1493,8 +1501,12 @@ impl MachineState {
}
}
&SystemClauseType::PeekCode => {
let mut stream =
self.get_stream_or_alias(self[temp_v!(1)], indices, "peek_code", 2)?;
let mut stream = self.get_stream_or_alias(
self[temp_v!(1)],
&indices.stream_aliases,
"peek_code",
2,
)?;
self.check_stream_properties(
&mut stream,
@@ -1874,8 +1886,12 @@ impl MachineState {
};
}
&SystemClauseType::PutCode => {
let mut stream =
self.get_stream_or_alias(self[temp_v!(1)], indices, "put_code", 2)?;
let mut stream = self.get_stream_or_alias(
self[temp_v!(1)],
&indices.stream_aliases,
"put_code",
2,
)?;
self.check_stream_properties(
&mut stream,
@@ -1928,8 +1944,12 @@ impl MachineState {
}
}
&SystemClauseType::PutChar => {
let mut stream =
self.get_stream_or_alias(self[temp_v!(1)], indices, "put_char", 2)?;
let mut stream = self.get_stream_or_alias(
self[temp_v!(1)],
&indices.stream_aliases,
"put_char",
2,
)?;
self.check_stream_properties(
&mut stream,
@@ -1975,8 +1995,12 @@ impl MachineState {
}
}
&SystemClauseType::PutChars => {
let mut stream =
self.get_stream_or_alias(self[temp_v!(1)], indices, "$put_chars", 2)?;
let mut stream = self.get_stream_or_alias(
self[temp_v!(1)],
&indices.stream_aliases,
"$put_chars",
2,
)?;
let mut bytes = Vec::new();
let string = self.heap_pstr_iter(self[temp_v!(2)]).to_string();
@@ -2023,8 +2047,12 @@ impl MachineState {
}
}
&SystemClauseType::PutByte => {
let mut stream =
self.get_stream_or_alias(self[temp_v!(1)], indices, "put_byte", 2)?;
let mut stream = self.get_stream_or_alias(
self[temp_v!(1)],
&indices.stream_aliases,
"put_byte",
2,
)?;
self.check_stream_properties(
&mut stream,
@@ -2112,8 +2140,12 @@ impl MachineState {
}
}
&SystemClauseType::GetByte => {
let mut stream =
self.get_stream_or_alias(self[temp_v!(1)], indices, "get_byte", 2)?;
let mut stream = self.get_stream_or_alias(
self[temp_v!(1)],
&indices.stream_aliases,
"get_byte",
2,
)?;
self.check_stream_properties(
&mut stream,
@@ -2195,8 +2227,12 @@ impl MachineState {
}
}
&SystemClauseType::GetChar => {
let mut stream =
self.get_stream_or_alias(self[temp_v!(1)], indices, "get_char", 2)?;
let mut stream = self.get_stream_or_alias(
self[temp_v!(1)],
&indices.stream_aliases,
"get_char",
2,
)?;
self.check_stream_properties(
&mut stream,
@@ -2298,8 +2334,12 @@ impl MachineState {
}
}
&SystemClauseType::GetNChars => {
let stream =
self.get_stream_or_alias(self[temp_v!(1)], indices, "get_n_chars", 3)?;
let stream = self.get_stream_or_alias(
self[temp_v!(1)],
&indices.stream_aliases,
"get_n_chars",
3,
)?;
let num = match Number::try_from((self[temp_v!(2)], &self.heap)) {
Ok(Number::Fixnum(n)) => usize::try_from(n).unwrap(),
@@ -2344,8 +2384,12 @@ impl MachineState {
(self.unify_fn)(self, self[temp_v!(3)], string);
}
&SystemClauseType::GetCode => {
let mut stream =
self.get_stream_or_alias(self[temp_v!(1)], indices, "get_code", 2)?;
let mut stream = self.get_stream_or_alias(
self[temp_v!(1)],
&indices.stream_aliases,
"get_code",
2,
)?;
self.check_stream_properties(
&mut stream,
@@ -2522,8 +2566,12 @@ impl MachineState {
}
}
&SystemClauseType::FlushOutput => {
let mut stream =
self.get_stream_or_alias(self[temp_v!(1)], indices, "flush_output", 1)?;
let mut stream = self.get_stream_or_alias(
self[temp_v!(1)],
&indices.stream_aliases,
"flush_output",
1,
)?;
if !stream.is_output_stream() {
let stub = MachineError::functor_stub(clause_name!("flush_output"), 1);
@@ -2589,7 +2637,12 @@ impl MachineState {
};
}
&SystemClauseType::Close => {
let mut stream = self.get_stream_or_alias(self[temp_v!(1)], indices, "close", 2)?;
let mut stream = self.get_stream_or_alias(
self[temp_v!(1)],
&indices.stream_aliases,
"close",
2,
)?;
if !stream.is_input_stream() {
stream.flush().unwrap(); // 8.11.6.1b)
@@ -2737,8 +2790,7 @@ impl MachineState {
(name, arity + narity),
module_name,
true,
current_input_stream,
current_output_stream,
&indices.stream_aliases,
);
} else {
unreachable!()
@@ -2752,8 +2804,7 @@ impl MachineState {
(name.clone(), narity),
module_name,
true,
current_input_stream,
current_output_stream,
&indices.stream_aliases,
);
} else {
unreachable!()
@@ -2766,8 +2817,7 @@ impl MachineState {
(clause_name!(c.to_string(), self.atom_tbl), narity),
module_name,
true,
current_input_stream,
current_output_stream,
&indices.stream_aliases,
);
}
addr => {
@@ -3652,7 +3702,8 @@ impl MachineState {
&SystemClauseType::SetCutPointByDefault(r) => deref_cut(self, r),
&SystemClauseType::SetInput => {
let addr = self.store(self.deref(self[temp_v!(1)]));
let stream = self.get_stream_or_alias(addr, indices, "set_input", 1)?;
let stream =
self.get_stream_or_alias(addr, &indices.stream_aliases, "set_input", 1)?;
if !stream.is_input_stream() {
let stub = MachineError::functor_stub(clause_name!("set_input"), 1);
@@ -3675,7 +3726,8 @@ impl MachineState {
}
&SystemClauseType::SetOutput => {
let addr = self.store(self.deref(self[temp_v!(1)]));
let stream = self.get_stream_or_alias(addr, indices, "set_output", 1)?;
let stream =
self.get_stream_or_alias(addr, &indices.stream_aliases, "set_output", 1)?;
if !stream.is_output_stream() {
let stub = MachineError::functor_stub(clause_name!("set_input"), 1);
@@ -3925,7 +3977,12 @@ impl MachineState {
&SystemClauseType::ReadTerm => {
readline::set_prompt(false);
let stream = self.get_stream_or_alias(self[temp_v!(1)], indices, "read_term", 3)?;
let stream = self.get_stream_or_alias(
self[temp_v!(1)],
&indices.stream_aliases,
"read_term",
3,
)?;
self.read_term(stream, indices)?;
}
@@ -4324,8 +4381,12 @@ impl MachineState {
}
}
&SystemClauseType::SetStreamPosition => {
let mut stream =
self.get_stream_or_alias(self[temp_v!(1)], indices, "set_stream_position", 2)?;
let mut stream = self.get_stream_or_alias(
self[temp_v!(1)],
&indices.stream_aliases,
"set_stream_position",
2,
)?;
if !stream.options().reposition {
let stub = MachineError::functor_stub(clause_name!("set_stream_position"), 2);
@@ -4360,8 +4421,12 @@ impl MachineState {
stream.set_position(position);
}
&SystemClauseType::StreamProperty => {
let mut stream =
self.get_stream_or_alias(self[temp_v!(1)], indices, "stream_property", 2)?;
let mut stream = self.get_stream_or_alias(
self[temp_v!(1)],
&indices.stream_aliases,
"stream_property",
2,
)?;
let property = match self.store(self.deref(self[temp_v!(2)])) {
Addr::Con(h) if self.heap.atom_at(h) => match &self.heap[h] {
@@ -4669,8 +4734,12 @@ impl MachineState {
(self.unify_fn)(self, listing, listing_var);
}
&SystemClauseType::WriteTerm => {
let mut stream =
self.get_stream_or_alias(self[temp_v!(1)], indices, "write_term", 3)?;
let mut stream = self.get_stream_or_alias(
self[temp_v!(1)],
&indices.stream_aliases,
"write_term",
3,
)?;
self.check_stream_properties(
&mut stream,
@@ -5356,8 +5425,12 @@ impl MachineState {
}
}
&SystemClauseType::DevourWhitespace => {
let stream =
self.get_stream_or_alias(self[temp_v!(1)], indices, "$devour_whitespace", 1)?;
let stream = self.get_stream_or_alias(
self[temp_v!(1)],
&indices.stream_aliases,
"$devour_whitespace",
1,
)?;
match self.devour_whitespace(stream, self.atom_tbl.clone()) {
Ok(false) => {} // not at EOF.