From 109feaa163b66e53133089ace07833296c243845 Mon Sep 17 00:00:00 2001 From: TudbuT Date: Wed, 4 Sep 2024 14:29:49 +0200 Subject: [PATCH] stdlib additions --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/std_fns.rs | 3 +++ src/stream.rs | 31 +++++++++++++++++++++++++++++-- std.spl | 21 +++++++++++++++++++++ stream.spl | 3 ++- 6 files changed, 57 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 38ed37d..3d8fccb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -22,7 +22,7 @@ checksum = "b03f7fbd470aa8b3ad163c85cce8bccfc11cc9c44ef12da0a4eddd98bd307352" [[package]] name = "spl" -version = "0.2.1" +version = "0.2.2" dependencies = [ "multicall", "once_cell", diff --git a/Cargo.toml b/Cargo.toml index 2ac41d7..28806e5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "spl" -version = "0.2.2" +version = "0.2.3" edition = "2021" description = "Stack Pogramming Language: A simple, concise scripting language." license = "MIT" diff --git a/src/std_fns.rs b/src/std_fns.rs index a243769..966c70b 100644 --- a/src/std_fns.rs +++ b/src/std_fns.rs @@ -103,6 +103,9 @@ pub fn array_new(stack: &mut Stack) -> OError { let Value::Mega(i) = stack.pop().lock_ro().native.clone() else { return stack.err(ErrorKind::InvalidCall("anew".to_owned())); }; + if i < 0 { + return stack.err(ErrorKind::InvalidCall("anew".to_owned())); + } stack.push(Value::Array(vec![Value::Null.spl(); i as usize]).spl()); Ok(()) } diff --git a/src/stream.rs b/src/stream.rs index bb3fa3d..eb53db9 100644 --- a/src/stream.rs +++ b/src/stream.rs @@ -1,10 +1,10 @@ use std::{ collections::HashMap, fs::OpenOptions, - io::Read, - io::Write, + io::{Read, Write}, mem, net::{Shutdown, TcpStream, UdpSocket}, + process::{self, Stdio}, sync::Arc, }; @@ -326,11 +326,38 @@ fn stream_udp(stack: &mut Stack) -> Result { Ok(Stream::new(UdpRW(sock), close_udp)) } +fn stream_cmd(stack: &mut Stack) -> Result { + require_on_stack!(a, Array, stack, "CMD new-stream"); + fn close_cmd(_stream: &mut Stream) {} + let mut args = Vec::new(); + for item in a.iter() { + if let Value::Str(ref s) = item.lock_ro().native { + args.push(s.to_owned()); + } + } + if args.is_empty() { + return stack.err(ErrorKind::InvalidCall("command".to_owned())); + } + let mut command = process::Command::new(&args[0]) + .args(&args[1..]) + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .stderr(Stdio::null()) + .spawn() + .map_err(|x| stack.error(ErrorKind::IO(x.to_string())))?; + Ok(Stream::new_split( + command.stdout.take().unwrap(), + command.stdin.take().unwrap(), + close_cmd, + )) +} + pub fn register(r: &mut Stack, o: Arc) { if !*IS_INITIALIZED.lock_ro() { register_stream_type("file", stream_file); register_stream_type("tcp", stream_tcp); register_stream_type("udp", stream_udp); + register_stream_type("cmd", stream_cmd); *IS_INITIALIZED.lock() = true; } diff --git a/std.spl b/std.spl index 0ab3f48..6b7cba4 100644 --- a/std.spl +++ b/std.spl @@ -79,6 +79,9 @@ construct _str_ext { } } ] _str } + starts-with { bool | with beginning this ; + beginning:to-bytes this:to-bytes:starts-with + } } include _str_ext in str construct _mega-ext { @@ -124,6 +127,19 @@ construct _array-ext { sub { [any] | with begin end this ; this (end begin - anew) begin 0 (end begin -) acopy } + starts-with { bool | with beginning this ; + this:len beginning:len lt if { + 0 + 2 stop + } + 0 beginning:len this:sub beginning eq + } + last { | with this ; + this:len -- this:get + } + =last { | with this ; + this:len -- this:set + } 0 { any | with this ; 0 this:get } @@ -403,6 +419,7 @@ func cache { ... | with arg-amt id body ; result } +def do-not-dump 0 =do-not-dump func handle-panic { | with msg trace ; program-name dup if { program-name print " panicked at:" println @@ -418,6 +435,10 @@ func handle-panic { | with msg trace ; null =map dyn-__dump } not if { + do-not-dump if { + "Not dumping." println + 2 stop + } "SPL_PLAIN_PANIC" map:get dup if { "Not dumping because SPL_PLAIN_PANIC is set." println } not if { diff --git a/stream.spl b/stream.spl index ff65be3..b948641 100644 --- a/stream.spl +++ b/stream.spl @@ -78,13 +78,14 @@ construct _StreamType { } func register-stream-type { | with id ; - [ stream-types:to-stack id ] =stream-types + stream-types [ id ] aadd =stream-types id _StreamType dyn-def-field } "tcp" register-stream-type "udp" register-stream-type "file" register-stream-type +"cmd" register-stream-type func StreamTypes { _StreamType | _StreamType:new