stream api fixes, str-to-bytes, bytes-to-str
This commit is contained in:
parent
a8d1d78643
commit
e037dbabe9
8 changed files with 77 additions and 39 deletions
|
@ -235,13 +235,11 @@ pub fn dyn_readf(stack: &mut Stack) -> OError {
|
|||
}
|
||||
|
||||
fn wrap(f: fn(&mut Stack) -> OError) -> impl Fn(&mut Stack) -> OError {
|
||||
move |stack| {
|
||||
unsafe {
|
||||
let frame = stack.pop_frame(0);
|
||||
let r = f(stack);
|
||||
stack.push_frame(frame);
|
||||
r
|
||||
}
|
||||
move |stack| unsafe {
|
||||
let frame = stack.pop_frame(0);
|
||||
let r = f(stack);
|
||||
stack.push_frame(frame);
|
||||
r
|
||||
}
|
||||
}
|
||||
|
||||
|
|
12
src/lib.rs
12
src/lib.rs
|
@ -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()))
|
||||
};
|
||||
};
|
||||
|
|
|
@ -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>>;
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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,16 +239,14 @@ 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);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn nop(_stream: &mut Stream) {}
|
||||
fn nop(_stream: &mut Stream) {}
|
||||
|
||||
fn stream_file(stack: &mut Stack) -> Result<Stream, Error> {
|
||||
let truncate = stack.pop().lock_ro().is_truthy();
|
||||
|
@ -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
11
std.spl
|
@ -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
|
||||
}
|
||||
|
|
2
test.spl
2
test.spl
|
@ -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
|
||||
|
|
2
test.txt
2
test.txt
|
@ -1 +1 @@
|
|||
hi
|
||||
hi
|
||||
|
|
Loading…
Add table
Reference in a new issue