From 6f2777b83a04ecb585539a7e3f3e36544648ee83 Mon Sep 17 00:00:00 2001 From: TudbuT Date: Thu, 12 Sep 2024 15:17:32 +0200 Subject: [PATCH] fix and improve some stdlib functions, add readf --- spl/http.spl | 4 ++ spl/net.spl | 2 +- spl/std.spl | 179 +++++++++++++++++++++++++++++++------------------ spl/stream.spl | 4 +- src/runtime.rs | 4 ++ src/std_fns.rs | 16 ++++- 6 files changed, 140 insertions(+), 69 deletions(-) diff --git a/spl/http.spl b/spl/http.spl index b8f577a..410ae8d 100644 --- a/spl/http.spl +++ b/spl/http.spl @@ -7,6 +7,10 @@ construct net:http namespace { Request Response help + ; + register { | with name this ; + name "net:http" register-field + } } construct net:http:Request { diff --git a/spl/net.spl b/spl/net.spl index 7125c61..d04f640 100644 --- a/spl/net.spl +++ b/spl/net.spl @@ -4,6 +4,6 @@ construct net namespace { ; register { | with name this ; - name "net" this register-field + name "net" register-field } } diff --git a/spl/std.spl b/spl/std.spl index 63abaac..171cdfa 100644 --- a/spl/std.spl +++ b/spl/std.spl @@ -36,70 +36,13 @@ construct _str_ext { } to-bytes { [int] | str-to-bytes } split { str | with splitter this ; - splitter:to-bytes =splitter - def bytes this:to-bytes =bytes - def i 0 =i - [ [ while { i bytes:len lt } { - def match 0 =match - while { match i + bytes:len lt match splitter:len lt and } { - i match + bytes:get (match splitter:get) eq dup if { - match ++ =match - } not if { - 0 =match - 3 stop - } - } - i bytes:get - match splitter:len eq if { - pop ] _str [ - i match + 1 - =i - } - i ++ =i - } ] _str ] + splitter:to-bytes this:to-bytes:split:map<{ | bytes-to-str }> } replace { str | with replacee replacement this ; - replacee:to-bytes =replacee - def bytes this:to-bytes =bytes - def i 0 =i - [ while { i bytes:len lt } { - def match 0 =match - while { match i + bytes:len lt match replacee:len lt and } { - i match + bytes:get (match replacee:get) eq dup if { - match ++ =match - } not if { - 0 =match - 3 stop - } - } - i bytes:get - match replacee:len eq if { - pop replacement:to-bytes:to-stack - i match + 1 - =i - } - i ++ =i - } ] _str + replacee:to-bytes replacement:to-bytes this:to-bytes:replace:to-str } find { idx | with search this ; - search:to-bytes =search - def bytes this:to-bytes =bytes - def i 0 =i - while { i bytes:len lt } { - def match 0 =match - while { match i + bytes:len lt match search:len lt and } { - i match + bytes:get (match search:get) eq dup if { - match ++ =match - } not if { - 0 =match - 3 stop - } - } - match search:len eq if { - i - 4 stop - } - i ++ =i - } - null + search _array this _array :find } starts-with { bool | with beginning this ; beginning:to-bytes this:to-bytes:starts-with @@ -107,6 +50,28 @@ construct _str_ext { _char { int | with this ; 0 (this _array):get } + readf { [str] | with pat this ; + !!- pat this str-readf + } + readf1 { str | with pat this ; + !!- pat this:readf 0:get + } + uppercase { str | with this ; + this _array :cmap<{ | with chr ; + chr + chr "a" :_char lt not chr "z" :_char gt not and if { + pop (chr "a" :_char -) "A" :_char + + } + }> _str + } + lowercase { str | with this ; + this _array :cmap<{ | with chr ; + chr + chr "A" :_char lt not chr "Z" :_char gt not and if { + pop (chr "A" :_char -) "a" :_char + + } + }> _str + } } include _str_ext in str construct _mega-ext { @@ -147,14 +112,85 @@ construct _array-ext { i ++ =i } } - foreach { | with callable this ; + foreach { | with callable this ; def i 0 =i while { i this:len lt } { i this:get callable call i ++ =i } } + map { | with callable this ; + def i 0 =i + while { i this:len lt } { i this:get callable call i this:set; i ++ =i } + this + } + cmap { | with callable this ; + this clone =this + def i 0 =i + while { i this:len lt } { i this:get callable call i this:set; i ++ =i } + this + } to-str { str | bytes-to-str } sub { [any] | with begin end this ; this (end begin - anew) begin 0 (end begin -) acopy } + split { arr | with splitter this ; + def i 0 =i + [ [ while { i this:len lt } { + def match 0 =match + while { match i + this:len lt match splitter:len lt and } { + i match + this:get (match splitter:get) eq dup if { + match ++ =match + } not if { + 0 =match + 3 stop + } + } + i this:get + match splitter:len eq if { + pop ] [ + i match + 1 - =i + } + i ++ =i + } ] ] + } + replace { arr | with replacee replacement this ; + def i 0 =i + [ while { i this:len lt } { + def match 0 =match + while { match i + this:len lt match replacee:len lt and } { + i match + this:get (match replacee:get) eq dup if { + match ++ =match + } not if { + 0 =match + 3 stop + } + } + i this:get + match replacee:len eq if { + pop replacement:to-stack + i match + 1 - =i + } + i ++ =i + } ] + } + find { idx | with search this ; + def i 0 =i + while { i this:len lt } { + def match 0 =match + while { match i + this:len lt match search:len lt and } { + i match + this:get (match search:get) eq dup if { + match ++ =match + } not if { + 0 =match + 3 stop + } + } + match search:len eq if { + i + 4 stop + } + i ++ =i + } + null + } starts-with { bool | with beginning this ; this:len beginning:len lt if { 0 @@ -577,8 +613,21 @@ func update-types { | update-types "Adds a field to a namespace and initially sets it to the field's name."; -func register-field { | with field-name namespace-name namespace ; - field-name namespace-name dyn-def-field; - namespace namespace-name settype ("=" namespace-name concat) dyn-call -} +func register-field { | with field-name namespace-name ; + def namespace-path + def iter + namespace-name:split<":"> =namespace-path; + + namespace-path:iter =iter + field-name namespace-name dyn-def-field; "adds the desired field to the namespace construct"; + ( + iter:next dyn-call + iter:foreach<&dyn-objcall> + ) namespace-name settype "updates and gets the namespace object"; + + ("=" namespace-path:last concat) namespace-path:=last; + namespace-path:iter =iter + iter:next dyn-call + iter:foreach<&dyn-objcall> +} diff --git a/spl/stream.spl b/spl/stream.spl index c951206..07fdd67 100644 --- a/spl/stream.spl +++ b/spl/stream.spl @@ -16,13 +16,13 @@ construct Stream { } read-one { mega | with this ; def buf 1 anew =buf - while { buf this:id read-stream not } { } + while { buf this:id read-stream pop not } { } 0 buf:get _mega } "the buffer is written to in-place."; read { mega [int] | with buf this ; buf gettype "mega" eq if { buf anew =buf } - buf this:id read-stream buf + buf this:id read-stream } "the buffer is written to in-place."; read-exact { [int] | with buf this ; diff --git a/src/runtime.rs b/src/runtime.rs index 1ddf739..c6a88ed 100644 --- a/src/runtime.rs +++ b/src/runtime.rs @@ -798,6 +798,10 @@ impl PartialOrd for Value { fn partial_cmp(&self, other: &Self) -> Option { match (self, other) { (Value::Mega(a), Value::Mega(b)) => a.partial_cmp(b), + (Value::Long(a), Value::Long(b)) => a.partial_cmp(b), + (Value::Int(a), Value::Int(b)) => a.partial_cmp(b), + (Value::Double(a), Value::Double(b)) => a.partial_cmp(b), + (Value::Float(a), Value::Float(b)) => a.partial_cmp(b), _ => panic!(), } } diff --git a/src/std_fns.rs b/src/std_fns.rs index a04b3fb..5075e1e 100644 --- a/src/std_fns.rs +++ b/src/std_fns.rs @@ -11,6 +11,8 @@ use std::{ time::{Duration, SystemTime}, }; +use readformat::readf; + use crate::{dyn_fns, mutex::Mut, runtime::*, sasm::sasm_write, *}; #[macro_export] @@ -877,9 +879,20 @@ pub fn time(stack: &mut Stack) -> OError { Ok(()) } +pub fn str_readf(stack: &mut Stack) -> OError { + require_on_stack!(string, Str, stack, "str-readf"); + require_on_stack!(pat, Str, stack, "str-readf"); + let Some(result) = readf(&pat, &string) else { + stack.push(Value::Null.spl()); + return Ok(()); + }; + stack.push(Value::Array(result.into_iter().map(::spl).collect()).spl()); + Ok(()) +} + pub fn register(r: &mut Stack, o: Arc) { type Fn = fn(&mut Stack) -> OError; - let fns: [(&str, Fn, u32); 56] = [ + let fns: [(&str, Fn, u32); 57] = [ ("pop", pop, 0), ("dup", dup, 2), ("dup2", dup2, 3), @@ -936,6 +949,7 @@ pub fn register(r: &mut Stack, o: Arc) { ("write-file-sasm", write_file_sasm, 1), ("fork", fork, 0), ("sleeptime", time, 0), + ("str-readf", str_readf, 1), ]; for f in fns { r.define_func(