add threads, add pure.spl, which reimplements some of std_fns.rs in pure spl
This commit is contained in:
parent
79ee784a5b
commit
2f8c50e3f0
7 changed files with 92 additions and 10 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -22,7 +22,7 @@ checksum = "b03f7fbd470aa8b3ad163c85cce8bccfc11cc9c44ef12da0a4eddd98bd307352"
|
|||
|
||||
[[package]]
|
||||
name = "spl"
|
||||
version = "0.3.1"
|
||||
version = "0.3.2"
|
||||
dependencies = [
|
||||
"multicall",
|
||||
"once_cell",
|
||||
|
|
48
pure.spl
Normal file
48
pure.spl
Normal file
|
@ -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;
|
||||
}>
|
||||
}
|
|
@ -46,6 +46,15 @@ pub fn runtime_mut<T>(f: impl FnOnce(RwLockWriteGuard<Runtime>) -> T) -> T {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn fork_runtime() -> Arc<Mut<Runtime>> {
|
||||
RUNTIME.with(|rt| {
|
||||
rt.borrow_mut()
|
||||
.as_mut()
|
||||
.expect("no runtime (use .set)")
|
||||
.clone()
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_type(name: &str) -> Option<AMType> {
|
||||
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<Box<dyn Fn(&mut Stack) -> OError>>),
|
||||
NativeDyn(Arc<Box<dyn (Fn(&mut Stack) -> OError) + Send + Sync>>),
|
||||
SPL(Words),
|
||||
}
|
||||
|
||||
|
|
|
@ -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<Frame>) {
|
||||
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<Frame>) {
|
|||
("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(
|
||||
|
|
|
@ -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<dyn Read + 'static>,
|
||||
writer: Box<dyn Write + 'static>,
|
||||
reader: Box<dyn Read + Send + Sync + 'static>,
|
||||
writer: Box<dyn Write + Send + Sync + 'static>,
|
||||
close: fn(&mut Self),
|
||||
}
|
||||
|
||||
impl Stream {
|
||||
pub fn new<T: Read + Write + 'static>(main: T, close: fn(&mut Self)) -> Self {
|
||||
pub fn new<T: Read + Write + Send + Sync + 'static>(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 {
|
||||
|
|
4
std.spl
4
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
|
||||
|
|
10
test.spl
10
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
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue