stream api fixes, str-to-bytes, bytes-to-str

This commit is contained in:
Daniella / Tove 2023-02-25 12:41:02 +01:00
parent a8d1d78643
commit e037dbabe9
Signed by: TudbuT
GPG key ID: 7D63D5634B7C417F
8 changed files with 77 additions and 39 deletions

View file

@ -235,15 +235,13 @@ pub fn dyn_readf(stack: &mut Stack) -> OError {
}
fn wrap(f: fn(&mut Stack) -> OError) -> impl Fn(&mut Stack) -> OError {
move |stack| {
unsafe {
move |stack| unsafe {
let frame = stack.pop_frame(0);
let r = f(stack);
stack.push_frame(frame);
r
}
}
}
pub fn register(r: &mut Stack, o: Arc<Frame>) {
type Fn = fn(&mut Stack) -> OError;

View file

@ -46,7 +46,8 @@ pub fn start_file_in_runtime(path: &str) -> Result<Stack, Error> {
#[macro_export]
macro_rules! require_on_stack {
($name:tt, $type:tt, $stack:expr, $fn:literal) => {
let Value::$type($name) = $stack.pop().lock_ro().native.clone() else {
let Value::$type($name)
= $stack.pop().lock_ro().native.clone() else {
return $stack.err(ErrorKind::InvalidCall($fn.to_owned()))
};
};
@ -54,7 +55,8 @@ macro_rules! require_on_stack {
#[macro_export]
macro_rules! require_int_on_stack {
($name:tt, $stack:expr, $fn:literal) => {
let Value::Int($name) = $stack.pop().lock_ro().native.clone().try_mega_to_int() else {
let Value::Int($name)
= $stack.pop().lock_ro().native.clone().try_mega_to_int() else {
return $stack.err(ErrorKind::InvalidCall($fn.to_owned()))
};
};
@ -62,7 +64,8 @@ macro_rules! require_int_on_stack {
#[macro_export]
macro_rules! require_array {
($name:tt, $array:expr, $stack:expr, $fn:literal) => {
let Value::Array(ref $name) = $array.lock_ro().native else {
let Value::Array(ref $name)
= $array.lock_ro().native else {
return $stack.err(ErrorKind::InvalidCall($fn.to_owned()))
};
};
@ -70,7 +73,8 @@ macro_rules! require_array {
#[macro_export]
macro_rules! require_mut_array {
($name:tt, $array:expr, $stack:expr, $fn:literal) => {
let Value::Array(ref mut $name) = $array.lock().native else {
let Value::Array(ref mut $name)
= $array.lock().native else {
return $stack.err(ErrorKind::InvalidCall($fn.to_owned()))
};
};

View file

@ -6,7 +6,8 @@ use crate::{
};
use core::panic;
use std::sync::{RwLockWriteGuard, RwLockReadGuard};
use std::collections::VecDeque;
use std::sync::{RwLockReadGuard, RwLockWriteGuard};
use std::{
cell::RefCell,
collections::HashMap,
@ -14,7 +15,6 @@ use std::{
sync::Arc,
vec,
};
use std::collections::VecDeque;
use std::{env::var, mem, path::Path};
pub type AMObject = Arc<Mut<Object>>;

View file

@ -8,7 +8,7 @@ use std::{
sync::Arc,
};
use crate::{dyn_fns, mutex::Mut, runtime::*};
use crate::{dyn_fns, mutex::Mut, runtime::*, *};
#[macro_export]
macro_rules! type_err {
@ -638,6 +638,8 @@ pub fn command_wait(stack: &mut Stack) -> OError {
for item in a.into_iter() {
if let Value::Str(ref s) = item.lock_ro().native {
args.push(s.to_owned());
} else {
return stack.err(ErrorKind::InvalidCall("command".to_owned()));
}
}
if args.len() < 1 {
@ -662,9 +664,37 @@ pub fn command_wait(stack: &mut Stack) -> OError {
Ok(())
}
pub fn str_to_bytes(stack: &mut Stack) -> OError {
require_on_stack!(s, Str, stack, "str-to-bytes");
stack.push(
Value::Array(
s.bytes()
.into_iter()
.map(|x| Value::Int(x as i32).spl())
.collect(),
)
.spl(),
);
Ok(())
}
pub fn bytes_to_str(stack: &mut Stack) -> OError {
require_array_on_stack!(a, stack, "str-to-bytes");
let mut chars = Vec::new();
for item in a.into_iter() {
if let Value::Int(x) = item.lock_ro().native.clone().try_mega_to_int() {
chars.push(x as u8);
} else {
return stack.err(ErrorKind::InvalidCall("command".to_owned()));
}
}
stack.push(Value::Str(String::from_utf8_lossy(&chars[..]).into_owned()).spl());
Ok(())
}
pub fn register(r: &mut Stack, o: Arc<Frame>) {
type Fn = fn(&mut Stack) -> OError;
let fns: [(&str, Fn, u32); 46] = [
let fns: [(&str, Fn, u32); 48] = [
("pop", pop, 0),
("dup", dup, 2),
("clone", clone, 1),
@ -711,6 +741,8 @@ pub fn register(r: &mut Stack, o: Arc<Frame>) {
("readln", readln, 1),
("command", command, 0),
("command-wait", command_wait, 1),
("str-to-bytes", str_to_bytes, 1),
("bytes-to-str", bytes_to_str, 1),
];
for f in fns {
r.define_func(

View file

@ -1,10 +1,10 @@
use std::{
collections::HashMap,
fs::{OpenOptions},
fs::OpenOptions,
io::Read,
io::Write,
mem,
net::{TcpStream, Shutdown},
net::{Shutdown, TcpStream},
sync::Arc,
};
@ -58,7 +58,11 @@ impl Stream {
close,
}
}
pub fn new_split(reader: impl Read + 'static, writer: impl Write + 'static, close: fn(&mut Self)) -> Self {
pub fn new_split(
reader: impl Read + 'static,
writer: impl Write + 'static,
close: fn(&mut Self),
) -> Self {
Self {
reader: Box::new(reader),
writer: Box::new(writer),
@ -125,15 +129,9 @@ where
pub fn new_stream(stack: &mut Stack) -> OError {
require_on_stack!(s, Str, stack, "write-stream");
let stream = get_stream_type(s.clone())
.ok_or_else(|| {
stack.error(ErrorKind::VariableNotFound(format!("__stream-type-{s}")))
})?
.ok_or_else(|| stack.error(ErrorKind::VariableNotFound(format!("__stream-type-{s}"))))?
.make_stream(stack)?;
let stream = runtime_mut(move |mut rt| {
Ok(rt.register_stream(
stream
))
})?;
let stream = runtime_mut(move |mut rt| Ok(rt.register_stream(stream)))?;
stack.push(Value::Mega(stream.0 as i128).spl());
Ok(())
}
@ -200,7 +198,8 @@ pub fn read_stream(stack: &mut Stack) -> OError {
stream
.lock()
.read(&mut vec[..])
.map_err(|x| stack.error(ErrorKind::IO(format!("{x:?}"))))? as i128,
.map_err(|x| stack.error(ErrorKind::IO(format!("{x:?}"))))?
as i128,
)
.spl(),
);
@ -240,9 +239,7 @@ pub fn read_all_stream(stack: &mut Stack) -> OError {
pub fn close_stream(stack: &mut Stack) -> OError {
require_on_stack!(id, Mega, stack, "close-stream");
if let Some(stream) = runtime(|rt| {
rt.get_stream(id as u128)
}) {
if let Some(stream) = runtime(|rt| rt.get_stream(id as u128)) {
let mut stream = stream.lock();
(stream.close)(&mut stream);
}
@ -262,7 +259,7 @@ fn stream_file(stack: &mut Stack) -> Result<Stream, Error> {
.truncate(truncate)
.open(path)
.map_err(|x| stack.error(ErrorKind::IO(x.to_string())))?,
nop
nop,
))
}
@ -271,14 +268,16 @@ fn stream_tcp(stack: &mut Stack) -> Result<Stream, Error> {
require_on_stack!(ip, Str, stack, "TCP new-stream");
fn close_tcp(stream: &mut Stream) {
unsafe {
let f = ((stream.reader.as_mut() as *mut dyn Read).cast() as *mut TcpStream).as_mut().unwrap();
let f = ((stream.reader.as_mut() as *mut dyn Read).cast() as *mut TcpStream)
.as_mut()
.unwrap();
let _ = f.shutdown(Shutdown::Both);
}
}
Ok(Stream::new(
TcpStream::connect((ip, port as u16))
.map_err(|x| stack.error(ErrorKind::IO(x.to_string())))?,
close_tcp
close_tcp,
))
}

11
std.spl
View file

@ -8,9 +8,13 @@ func println { |
print "\n" print
}
{ any | with type ;
null clone type settype "construct" dyn-objcall
} "new" "str" dyn-def-method
construct _str_ext {
;
new { any | with this ;
null clone this settype "construct" dyn-objcall
}
to-bytes { [int] | str-to-bytes }
} include _str_ext in str
construct _mega-ext {
;
@ -51,6 +55,7 @@ construct _array-ext {
def i 0 =i
while { i this:len lt } { i this:get callable call i ++ =i }
}
to-str { str | bytes-to-str }
0 { any | with this ;
0 this:get
}

View file

@ -104,7 +104,7 @@ func main { int | with args ;
"testing stream" println
def file "test.txt" 1 StreamTypes:file:create =file
"hi" _array file:write-exact;
"hi\n" _:to-bytes file:write-exact;
file:close null =file
"" println