diff --git a/Cargo.lock b/Cargo.lock index 7e0d1bc..6c36619 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -22,7 +22,7 @@ checksum = "b03f7fbd470aa8b3ad163c85cce8bccfc11cc9c44ef12da0a4eddd98bd307352" [[package]] name = "spl" -version = "0.3.1" +version = "0.3.2" dependencies = [ "multicall", "once_cell", diff --git a/pure.spl b/pure.spl new file mode 100644 index 0000000..e286e40 --- /dev/null +++ b/pure.spl @@ -0,0 +1,48 @@ +"#stream.spl" import + +"uses less native functions where possible"; + +func pop { | with _ ; } + +func dup { x x | with x ; + x x +} + +func swap { b a | with a b ; + b a +} + +func not { !x | with x ; + 1 + x if { pop 0 } +} + +func and { a&&b | with a b ; + 0 + a if { b if { pop 1 } } +} + +func or { a||b | with a b ; + 0 + a if { pop 1 } + b if { pop 1 } +} + +func alit-end { array | with type ; + def array 0 anew =array + while { dup type eq not } { + 0 1 anew dup:set; array aadd =array + } + pop array +} + +func read-file { str | with path ; + def stream path 0 StreamTypes:file:create =stream + 1024 stream:read-to-end:to-str +} + +func acopy { | with from to idxsrc idxdst len ; + len:foreach<{ | with i ; + i idxsrc + from:get i idxdst + to:set; + }> +} diff --git a/src/runtime.rs b/src/runtime.rs index 9f8bbad..7004303 100644 --- a/src/runtime.rs +++ b/src/runtime.rs @@ -46,6 +46,15 @@ pub fn runtime_mut(f: impl FnOnce(RwLockWriteGuard) -> T) -> T { }) } +pub fn fork_runtime() -> Arc> { + RUNTIME.with(|rt| { + rt.borrow_mut() + .as_mut() + .expect("no runtime (use .set)") + .clone() + }) +} + pub fn get_type(name: &str) -> Option { runtime(|rt| rt.get_type_by_name(name)) } @@ -784,7 +793,7 @@ impl Words { #[derive(Clone)] pub enum FuncImpl { Native(fn(&mut Stack) -> OError), - NativeDyn(Arc OError>>), + NativeDyn(Arc OError) + Send + Sync>>), SPL(Words), } diff --git a/src/std_fns.rs b/src/std_fns.rs index 0d3c44d..d1ccaeb 100644 --- a/src/std_fns.rs +++ b/src/std_fns.rs @@ -7,6 +7,7 @@ use std::{ ops::{Add, Div, Mul, Rem, Sub}, process::{self, Stdio}, sync::Arc, + thread, }; use crate::{dyn_fns, mutex::Mut, runtime::*, sasm::sasm_write, *}; @@ -840,9 +841,22 @@ pub fn write_file_sasm(stack: &mut Stack) -> OError { Ok(()) } +pub fn fork(stack: &mut Stack) -> OError { + require_on_stack!(callable, Func, stack, "fork"); + let mut new_stack = stack.clone(); + let rt = fork_runtime(); + thread::spawn(move || { + rt.set(); + if let Some(err) = new_stack.call(&callable).err() { + println!("{err:?}"); + }; + }); + Ok(()) +} + pub fn register(r: &mut Stack, o: Arc) { type Fn = fn(&mut Stack) -> OError; - let fns: [(&str, Fn, u32); 53] = [ + let fns: [(&str, Fn, u32); 54] = [ ("pop", pop, 0), ("dup", dup, 2), ("clone", clone, 1), @@ -896,6 +910,7 @@ pub fn register(r: &mut Stack, o: Arc) { ("throw", throw, 0), ("write-sasm", write_sasm, 1), ("write-file-sasm", write_file_sasm, 1), + ("fork", fork, 0), ]; for f in fns { r.define_func( diff --git a/src/stream.rs b/src/stream.rs index eb53db9..1e14867 100644 --- a/src/stream.rs +++ b/src/stream.rs @@ -45,13 +45,13 @@ impl StreamType { /// An SPL stream, holding a reader and a writer, and a function to close it. pub struct Stream { - reader: Box, - writer: Box, + reader: Box, + writer: Box, close: fn(&mut Self), } impl Stream { - pub fn new(main: T, close: fn(&mut Self)) -> Self { + pub fn new(main: T, close: fn(&mut Self)) -> Self { let mut rw = Box::new(main); Self { // SAFETY: Because these are both in private fields on one object, they can not be @@ -63,8 +63,8 @@ impl Stream { } } pub fn new_split( - reader: impl Read + 'static, - writer: impl Write + 'static, + reader: impl Read + Send + Sync + 'static, + writer: impl Write + Send + Sync + 'static, close: fn(&mut Self), ) -> Self { Self { diff --git a/std.spl b/std.spl index 3778f31..2d2345c 100644 --- a/std.spl +++ b/std.spl @@ -12,7 +12,7 @@ func print { | } func println { | - print "\n" print + "\n" concat print } construct error { @@ -141,7 +141,7 @@ construct _array-ext { this:len -- this:get } =last { | with this ; - this:len -- this:set + this:len -- this:set; } 0 { any | with this ; 0 this:get diff --git a/test.spl b/test.spl index e5c5045..3ae0d51 100644 --- a/test.spl +++ b/test.spl @@ -150,6 +150,16 @@ func main { int | with args ; "testmsg2" bus:publish "testmsg1" bus:publish "testmsg3" bus:publish + + "" println + "testing threads" println + + def other-thread-done 0 =other-thread-done + { | + "i am in the other thread!!!" println + 1 =other-thread-done + } fork + while { other-thread-done not } { "waiting for the other thread..." println } 100 }