From 1dce63794be9686844226a65998200fabbc77a4b Mon Sep 17 00:00:00 2001 From: TudbuT Date: Sat, 8 Apr 2023 09:51:40 +0200 Subject: [PATCH] Deprecate _ function, Add section on postfix args to README, Add nconcat function. --- README.md | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- http.spl | 12 ++++++------ std.spl | 38 ++++++++++++++++++++++++------------ test.spl | 6 +++--- 4 files changed, 90 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index b143aef..8dbba52 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ func main { mega | with args ; { str | " " concat } swap:map &print swap:foreach "" println + println <{ "and with that, we're done" } 0 } ``` @@ -130,9 +131,7 @@ func main { mega | with args ; It sure does look like it, doesn't it? `swap` swaps the topmost two values on the stack. `a b -> b a`. That means we are actually calling to our iterator. The closure and the iterator are swapped before the call is made. `swap:map` - is a more concise way of writing `swap _:map`. The underscore is used as a - placeholder for the topmost value of the stack when making method calls, - because `swap :map` would try to call map on an empty expression. + is a more concise way of writing `swap :map`. The map function on the iterator (which is available through `:iter` on most collection constructs) is used to apply a function to all items in the @@ -176,5 +175,58 @@ func main { mega | with args ; ```java for(int i = 0; i < 5; i++) { println((String) i * 5); } ``` +- SPL actually isn't fully concatenative. It supports postfix arguments as well: + ```js + println <{ "and with that, we're done" } + ``` + This is actually not a special interpreter feature, more so is it a special + lexer feature. This is 100% equivalent with the non-postfix version, where the + string is right before the `println`. + + The same can be done for object calls. Let's rewrite the previous code with + postfix: + ```js + Range:new <{ 0 5 } + :iter + :map <{ { | 5 * } } + :foreach <{ { | _str println } } + ``` + + I lied. This is now no longer 100% equivalent. Let's look at what happens + under the hood. + + ```asm + call Range + objpush + const mega 0 + const mega 5 + objpop + objcall new + objcall iter + objpush + const func 0 + const mega 5 + call * + end + objpop + objcall map + objpush + const func 0 + call _str + call println + end + objpop + call foreach + ``` + + You can see there are now `objpush` and `objpop` instructions. This is doing + the job that `swap` used to do in our previous example. However, swap can only + swap the topmost values, but postfix arguments allow any amount. That's why + there is a special instruction just for that. It can also be used through AST + modifications, but there is no way to get it in normal language use as it can + cause interpreter panics when they are used wrongly. + + `objpush` and `objpop` operate on a separate stack, called the objcall stack, + as opposed to the main object stack. More of this tutorial to follow. diff --git a/http.spl b/http.spl index 3aa14f9..b8f577a 100644 --- a/http.spl +++ b/http.spl @@ -37,24 +37,24 @@ construct net:http:Request { def response net:http:Response:new =response this:method:to-bytes stream:write-exact; - " " _:to-bytes stream:write-exact; + " " :to-bytes stream:write-exact; this:path:to-bytes stream:write-exact; - " HTTP/1.0\r\n" _:to-bytes stream:write-exact; + " HTTP/1.0\r\n" :to-bytes stream:write-exact; - "Host: " _:to-bytes stream:write-exact; + "Host: " :to-bytes stream:write-exact; this:host:to-bytes stream:write-exact; "\r\nConnection: Close\r\nUser-Agent: http.spl v0.1 2023-03 (spl@mail.tudbut.de)\r\n" - _:to-bytes stream:write-exact; + :to-bytes stream:write-exact; { | with header ; header:to-bytes stream:write-exact; "\r\n" stream:write-exact; } this:headers:foreach - "Content-Length: " _:to-bytes stream:write-exact; + "Content-Length: " :to-bytes stream:write-exact; def body this:body:to-bytes =body body:len _str:to-bytes stream:write-exact; - "\r\n\r\n" _:to-bytes stream:write-exact; + "\r\n\r\n" :to-bytes stream:write-exact; body stream:write-exact; stream:flush; diff --git a/std.spl b/std.spl index 8608da0..2755c2d 100644 --- a/std.spl +++ b/std.spl @@ -124,14 +124,14 @@ construct List { array this:=array this } - foreach { | _:array:foreach } - get { any | _:array:get } - sget { any|null | _:array:sget } - len { mega | _:array:len } - set { any | _:array:set } - to-stack { .. | _:array:to-stack } - to-str { str | _:array:to-str } - sub { [any] | _:array:sub } + foreach { | :array:foreach } + get { any | :array:get } + sget { any|null | :array:sget } + len { mega | :array:len } + set { any | :array:set } + to-stack { .. | :array:to-stack } + to-str { str | :array:to-str } + sub { [any] | :array:sub } } construct _GrowingArray { ; @@ -216,7 +216,7 @@ construct MicroMap { get-entry { [any,any]|null | with key this ; this:pairs:iter { mega | 0 swap:get key eq } swap:filter - _:next + :next } get-or-create-entry { [any,any] | with key this ; { [any,any] | @@ -227,7 +227,7 @@ construct MicroMap { this:pairs:iter { mega | 0 swap:get key eq } swap:filter { any | 1 swap:get } swap:map - _:next + :next } set { any | with key val this ; val 1 (key this:get-or-create-entry):set @@ -235,7 +235,7 @@ construct MicroMap { remove { any | with key this ; this:pairs:iter { mega | 0 swap:get key eq not } swap:filter - _:collect + :collect List:new:from =pairs } @@ -310,6 +310,14 @@ func concat { str | with a b ; a _array b _array aadd _str } +func nconcat { str | with amt ; + _array + (amt 1 -):foreach <{ { | pop + swap _array swap aadd + } } + _str +} + func handle-panic { | with msg trace ; program-name dup if { program-name print " panicked at:" println @@ -381,7 +389,13 @@ func -- { mega | 1 - } -func _ { | } +def _'has-been-called 0 =_'has-been-called +func _ { | + _'has-been-called not if { + "WARN: The _ function is deprecated!" println + 1 =_'has-been-called + } +} func call-main-on-file { | with file ; catch { diff --git a/test.spl b/test.spl index ba3a20f..5448e31 100644 --- a/test.spl +++ b/test.spl @@ -75,7 +75,7 @@ func main { int | with args ; 0 5 Range:new:iter { | pop 10 } swap:map - _:sum + :sum _str println "" println @@ -104,12 +104,12 @@ func main { int | with args ; "testing stream" println def file "test.txt" 1 StreamTypes:file:create =file - "hi\n" _:to-bytes file:write-exact; + "hi\n" :to-bytes file:write-exact; file:close null =file "" println "testing split" println - { | println } (" " "hello how are you" _:split):foreach + { | println } (" " "hello how are you" :split):foreach "" println catch {