add put_byte/{1,2}, put_char/{1,2}
This commit is contained in:
@@ -489,7 +489,7 @@ pub enum ValidType {
|
||||
Atom,
|
||||
Atomic,
|
||||
// Boolean,
|
||||
// Byte,
|
||||
Byte,
|
||||
Callable,
|
||||
Character,
|
||||
Compound,
|
||||
@@ -512,7 +512,7 @@ impl ValidType {
|
||||
ValidType::Atom => "atom",
|
||||
ValidType::Atomic => "atomic",
|
||||
// ValidType::Boolean => "boolean",
|
||||
// ValidType::Byte => "byte",
|
||||
ValidType::Byte => "byte",
|
||||
ValidType::Callable => "callable",
|
||||
ValidType::Character => "character",
|
||||
ValidType::Compound => "compound",
|
||||
|
||||
@@ -278,6 +278,17 @@ impl Stream {
|
||||
pub(crate)
|
||||
fn close(&mut self) {
|
||||
*self.stream_inst.0.borrow_mut() = StreamInstance::Null;
|
||||
self.past_end_of_stream = true;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate)
|
||||
fn is_null_stream(&self) -> bool {
|
||||
if let StreamInstance::Null = *self.stream_inst.0.borrow() {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@@ -485,7 +496,15 @@ impl MachineState {
|
||||
}
|
||||
Addr::Stream(h) => {
|
||||
if let HeapCellValue::Stream(ref stream) = &self.heap[h] {
|
||||
stream.clone()
|
||||
if stream.is_null_stream() {
|
||||
return Err(self.open_permission_error(
|
||||
Addr::Stream(h),
|
||||
caller,
|
||||
arity,
|
||||
));
|
||||
} else {
|
||||
stream.clone()
|
||||
}
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
@@ -1592,6 +1592,109 @@ impl MachineState {
|
||||
|
||||
self.unify(complete_string, a2);
|
||||
}
|
||||
&SystemClauseType::PutChar => {
|
||||
let mut stream =
|
||||
self.get_stream_or_alias(self[temp_v!(1)], indices, "put_char", 2)?;
|
||||
|
||||
self.check_stream_properties(
|
||||
&mut stream,
|
||||
StreamType::Text,
|
||||
None,
|
||||
clause_name!("put_char"),
|
||||
2,
|
||||
)?;
|
||||
|
||||
match self.store(self.deref(self[temp_v!(2)])) {
|
||||
addr if addr.is_ref() => {
|
||||
let stub = MachineError::functor_stub(clause_name!("put_char"), 2);
|
||||
let err = MachineError::instantiation_error();
|
||||
|
||||
return Err(self.error_form(err, stub));
|
||||
}
|
||||
addr => {
|
||||
match self.store(self.deref(self[temp_v!(2)])) {
|
||||
Addr::Con(h) if self.heap.atom_at(h) => {
|
||||
match &self.heap[h] {
|
||||
HeapCellValue::Atom(ref atom, _) if atom.is_char() => {
|
||||
if let Some(c) = atom.as_str().chars().next() {
|
||||
write!(&mut stream, "{}", c).unwrap();
|
||||
return return_from_clause!(self.last_call, self);
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
}
|
||||
Addr::Char(c) => {
|
||||
write!(&mut stream, "{}", c).unwrap();
|
||||
return return_from_clause!(self.last_call, self);
|
||||
}
|
||||
_ => {
|
||||
}
|
||||
}
|
||||
|
||||
let stub = MachineError::functor_stub(clause_name!("put_char"), 2);
|
||||
let err = MachineError::type_error(
|
||||
self.heap.h(),
|
||||
ValidType::Character,
|
||||
addr,
|
||||
);
|
||||
|
||||
return Err(self.error_form(err, stub));
|
||||
}
|
||||
}
|
||||
}
|
||||
&SystemClauseType::PutByte => {
|
||||
let mut stream =
|
||||
self.get_stream_or_alias(self[temp_v!(1)], indices, "put_byte", 2)?;
|
||||
|
||||
self.check_stream_properties(
|
||||
&mut stream,
|
||||
StreamType::Binary,
|
||||
None,
|
||||
clause_name!("put_byte"),
|
||||
2,
|
||||
)?;
|
||||
|
||||
match self.store(self.deref(self[temp_v!(2)])) {
|
||||
addr if addr.is_ref() => {
|
||||
let stub = MachineError::functor_stub(clause_name!("put_byte"), 2);
|
||||
let err = MachineError::instantiation_error();
|
||||
|
||||
return Err(self.error_form(err, stub));
|
||||
}
|
||||
addr => {
|
||||
match Number::try_from((addr, &self.heap)) {
|
||||
Ok(Number::Integer(n)) => {
|
||||
if let Some(nb) = n.to_u8() {
|
||||
stream.write(&mut [nb]).unwrap();
|
||||
return return_from_clause!(self.last_call, self);
|
||||
}
|
||||
}
|
||||
Ok(Number::Fixnum(n)) => {
|
||||
if let Ok(nb) = u8::try_from(n) {
|
||||
stream.write(&mut [nb]).unwrap();
|
||||
return return_from_clause!(self.last_call, self);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
}
|
||||
}
|
||||
|
||||
let stub = MachineError::functor_stub(clause_name!("put_byte"), 2);
|
||||
let err = MachineError::type_error(
|
||||
self.heap.h(),
|
||||
ValidType::Byte,
|
||||
self[temp_v!(2)],
|
||||
);
|
||||
|
||||
return Err(self.error_form(err, stub));
|
||||
}
|
||||
}
|
||||
}
|
||||
&SystemClauseType::GetByte => {
|
||||
let mut stream =
|
||||
self.get_stream_or_alias(self[temp_v!(1)], indices, "get_byte", 2)?;
|
||||
@@ -2436,7 +2539,7 @@ impl MachineState {
|
||||
true
|
||||
}
|
||||
"write" => {
|
||||
open_options.read(false).write(true).create(true).append(false);
|
||||
open_options.read(false).write(true).truncate(true).create(true);
|
||||
false
|
||||
}
|
||||
"append" => {
|
||||
|
||||
Reference in New Issue
Block a user