From fb2326a67a6853717024e7fcb2bd99008d694de6 Mon Sep 17 00:00:00 2001 From: faretek Date: Sun, 13 Jul 2025 12:26:31 +0100 Subject: [PATCH 01/13] feat: string startswith/endswith(from) --- string.gs | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/string.gs b/string.gs index b6386d7..ad6b292 100644 --- a/string.gs +++ b/string.gs @@ -1,4 +1,6 @@ func strcmp(string1, string2) { + # This code assumes you have costumes A-Z and a-z + # If you need to compare chars e.g ä vs Ä, then you need to add those as costumes too if length($string1) != length($string2) { return false; } @@ -14,3 +16,81 @@ func strcmp(string1, string2) { } return true; } + +func slice(string, start, end) { + local ret = ""; + local i = $start; + + until i >= $end { + ret &= $string[i]; + i++; + } + return ret; +} + +func slice_step(string, start, end, step) { + if $start == $end or $step + "" == 0 { + return ""; + } else { + local ret = ""; + local i = $start; + + if $step < 0 { + until i <= $end { + ret &= $string[i]; + i += $step; + } + return ret; + } else { + until i >= $end { + ret &= $string[i]; + i += $step; + } + return ret; + } + } +} + +func startswith(text, start) { + local i = 1; + repeat length $start { + if $text[i] != $start[i] { + return false; + } + i++; + } + return true; +} + +func startswith_from(i, text, start) { + local i = 1; + repeat length $start { + if $text[i + $i - 1] != $start[i] { + return false; + } + i++; + } + return true; +} + +func endswith(text, end) { + local i = 0; + repeat length $end { + if $text[length $text - i] != $end[length $end - i] { + return false; + } + i++; + } + return true; +} + +func endswith_from(i, text, end) { + local i = 0; + repeat length $end { + if $text[$i - i] != $end[length $end - i] { + return false; + } + i++; + } + return true; +} \ No newline at end of file From 9ebc2b09eaa7e8185e4c73219d65ae753bcd4774 Mon Sep 17 00:00:00 2001 From: faretek Date: Sun, 13 Jul 2025 12:35:06 +0100 Subject: [PATCH 02/13] fix: add newline to fix test --- string.gs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/string.gs b/string.gs index ad6b292..bcbeac4 100644 --- a/string.gs +++ b/string.gs @@ -93,4 +93,4 @@ func endswith_from(i, text, end) { i++; } return true; -} \ No newline at end of file +} From 27a96c0dc2691074ce51e038e7b8949a6bcaaa55 Mon Sep 17 00:00:00 2001 From: faretek Date: Sun, 13 Jul 2025 12:42:43 +0100 Subject: [PATCH 03/13] test: add testing for startswith/endswith (wip) --- string.gs | 2 ++ test/lib/test_string.gs | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/string.gs b/string.gs index bcbeac4..ab10246 100644 --- a/string.gs +++ b/string.gs @@ -62,6 +62,7 @@ func startswith(text, start) { return true; } +# startswith_from(1, ...) is equivalent to startswith(...) func startswith_from(i, text, start) { local i = 1; repeat length $start { @@ -84,6 +85,7 @@ func endswith(text, end) { return true; } +# endswith_from(length , , ...) is equivalent to endswith(, ...) func endswith_from(i, text, end) { local i = 0; repeat length $end { diff --git a/test/lib/test_string.gs b/test/lib/test_string.gs index 6542980..7f41ac2 100644 --- a/test/lib/test_string.gs +++ b/test/lib/test_string.gs @@ -5,4 +5,14 @@ proc test_string { if not strcmp("hello, world!", "Hello, World!") == false { error "strcmp(\"hello, world!\", \"Hello, World!\")"; } + + if not startswith("Hello, World!", "Hello") { + error "startswith(\"Hello, World!\", \"Hello\")"; + } + if not startswith_from(8, "Hello, World!", "World!") { + error "startswith(\"Hello, World!\", \"Hello\")"; + } + if not endswith("Hello, World!", "World!") { + error "endswith(\"Hello, World!\", \"World!\")"; + } } From e3eda8368ca72bb07442b5dea1ad18c515f94d28 Mon Sep 17 00:00:00 2001 From: faretek Date: Sun, 13 Jul 2025 12:44:57 +0100 Subject: [PATCH 04/13] feat: assert_true --- assert.gs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/assert.gs b/assert.gs index 867d7a4..26d1ef3 100644 --- a/assert.gs +++ b/assert.gs @@ -21,3 +21,10 @@ proc assert result, expected, message = "" { } } %endif + +# assert true +proc assert_t condition, message { + if not $condition { + error $message; + } +} From 693449013fa55ca47fd0a23ab27dbf7a89d07160 Mon Sep 17 00:00:00 2001 From: faretek Date: Sun, 13 Jul 2025 12:49:06 +0100 Subject: [PATCH 05/13] feat: assert_f --- assert.gs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/assert.gs b/assert.gs index 26d1ef3..b378dd7 100644 --- a/assert.gs +++ b/assert.gs @@ -28,3 +28,9 @@ proc assert_t condition, message { error $message; } } +# assert false +proc assert_f condition, message { + if $condition { + error $message; + } +} From e7d850a7ad894cb4469df7939393f028499f2a20 Mon Sep 17 00:00:00 2001 From: faretek Date: Sun, 13 Jul 2025 12:53:50 +0100 Subject: [PATCH 06/13] feat: test startswith/endswith --- test/lib/test_string.gs | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/test/lib/test_string.gs b/test/lib/test_string.gs index 7f41ac2..77952ec 100644 --- a/test/lib/test_string.gs +++ b/test/lib/test_string.gs @@ -1,18 +1,9 @@ proc test_string { - if not strcmp("Hello, World!", "Hello, World!") == true { - error "strcmp(\"Hello, World!\", \"Hello, World!\")"; - } - if not strcmp("hello, world!", "Hello, World!") == false { - error "strcmp(\"hello, world!\", \"Hello, World!\")"; - } + assert_t strcmp("Hello, World!", "Hello, World!"), "strcmp(\"Hello, World!\", \"Hello, World!\")"; + assert_f strcmp("hello, world!", "Hello, World!"), "strcmp(\"hello, world!\", \"Hello, World!\")"; - if not startswith("Hello, World!", "Hello") { - error "startswith(\"Hello, World!\", \"Hello\")"; - } - if not startswith_from(8, "Hello, World!", "World!") { - error "startswith(\"Hello, World!\", \"Hello\")"; - } - if not endswith("Hello, World!", "World!") { - error "endswith(\"Hello, World!\", \"World!\")"; - } + assert_t startswith("Hello, World!", "Hello"), "startswith(\"Hello, World!\", \"Hello\")"; + assert_t startswith_from(8, "Hello, World!", "World!"), "startswith_from(8, \"Hello, World!\", \"World!\")"; + assert_t endswith("Hello, World!", "World!"), "endswith(\"Hello, World!\", \"World!\")"; + assert_t endswith_from(6, "Hello, World!", "Hello,"), "endswith_from(6, \"Hello, World!\", \"Hello,\")"; } From 9a47d6fcb6cff333a60490da811f82763335136e Mon Sep 17 00:00:00 2001 From: faretek Date: Sun, 13 Jul 2025 12:55:54 +0100 Subject: [PATCH 07/13] refactor: text -> string --- string.gs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/string.gs b/string.gs index ab10246..8f09d8e 100644 --- a/string.gs +++ b/string.gs @@ -51,10 +51,10 @@ func slice_step(string, start, end, step) { } } -func startswith(text, start) { +func startswith(string, start) { local i = 1; repeat length $start { - if $text[i] != $start[i] { + if $string[i] != $start[i] { return false; } i++; @@ -63,10 +63,10 @@ func startswith(text, start) { } # startswith_from(1, ...) is equivalent to startswith(...) -func startswith_from(i, text, start) { +func startswith_from(i, string, start) { local i = 1; repeat length $start { - if $text[i + $i - 1] != $start[i] { + if $string[i + $i - 1] != $start[i] { return false; } i++; @@ -74,10 +74,10 @@ func startswith_from(i, text, start) { return true; } -func endswith(text, end) { +func endswith(string, end) { local i = 0; repeat length $end { - if $text[length $text - i] != $end[length $end - i] { + if $string[length $string - i] != $end[length $end - i] { return false; } i++; @@ -86,10 +86,10 @@ func endswith(text, end) { } # endswith_from(length , , ...) is equivalent to endswith(, ...) -func endswith_from(i, text, end) { +func endswith_from(i, string, end) { local i = 0; repeat length $end { - if $text[$i - i] != $end[length $end - i] { + if $string[$i - i] != $end[length $end - i] { return false; } i++; From be415d85887f06bed4476deac55a4aaf013c56f9 Mon Sep 17 00:00:00 2001 From: faretek Date: Sun, 13 Jul 2025 13:01:57 +0100 Subject: [PATCH 08/13] feat: zfill --- string.gs | 9 +++++++++ test/lib/test_string.gs | 1 + 2 files changed, 10 insertions(+) diff --git a/string.gs b/string.gs index 8f09d8e..6b48f3b 100644 --- a/string.gs +++ b/string.gs @@ -96,3 +96,12 @@ func endswith_from(i, string, end) { } return true; } + +# Pad '0' to the left until it reaches the specified length. +func zfill(string, len) { + local ret = $string; + repeat $len - length $string { + ret = 0 & ret; + } + return ret; +} diff --git a/test/lib/test_string.gs b/test/lib/test_string.gs index 77952ec..e02f1bf 100644 --- a/test/lib/test_string.gs +++ b/test/lib/test_string.gs @@ -6,4 +6,5 @@ proc test_string { assert_t startswith_from(8, "Hello, World!", "World!"), "startswith_from(8, \"Hello, World!\", \"World!\")"; assert_t endswith("Hello, World!", "World!"), "endswith(\"Hello, World!\", \"World!\")"; assert_t endswith_from(6, "Hello, World!", "Hello,"), "endswith_from(6, \"Hello, World!\", \"Hello,\")"; + assert zfill("FFF", 6), "000FFF", "zfill(\"FFF\", 6)"; } From 2f94ab58f657e0b0cb5b7290e4c5033f58e7ff20 Mon Sep 17 00:00:00 2001 From: faretek Date: Sun, 13 Jul 2025 13:07:40 +0100 Subject: [PATCH 09/13] feat: ljust --- string.gs | 9 +++++++++ test/lib/test_string.gs | 2 ++ 2 files changed, 11 insertions(+) diff --git a/string.gs b/string.gs index 6b48f3b..769db5f 100644 --- a/string.gs +++ b/string.gs @@ -105,3 +105,12 @@ func zfill(string, len) { } return ret; } + +# Pad ' ' to the left until it reaches the specified length. +func ljust(string, len, char = " ") { + local ret = $string; + repeat $len - length $string { + ret = $char & ret; + } + return ret; +} diff --git a/test/lib/test_string.gs b/test/lib/test_string.gs index e02f1bf..b1edc1b 100644 --- a/test/lib/test_string.gs +++ b/test/lib/test_string.gs @@ -7,4 +7,6 @@ proc test_string { assert_t endswith("Hello, World!", "World!"), "endswith(\"Hello, World!\", \"World!\")"; assert_t endswith_from(6, "Hello, World!", "Hello,"), "endswith_from(6, \"Hello, World!\", \"Hello,\")"; assert zfill("FFF", 6), "000FFF", "zfill(\"FFF\", 6)"; + assert ljust("FFF", 6), " FFF", "ljust(\"FFF\", 6)"; + assert ljust("FFF", 6, 1), "111FFF", "ljust(\"FFF\", 6, 1)"; } From e2d2cc212e517d4067878f1a8b6dd68df156fe98 Mon Sep 17 00:00:00 2001 From: faretek Date: Sun, 13 Jul 2025 13:14:27 +0100 Subject: [PATCH 10/13] feat: repstr --- string.gs | 9 +++++++++ test/lib/test_string.gs | 1 + 2 files changed, 10 insertions(+) diff --git a/string.gs b/string.gs index 769db5f..df97f75 100644 --- a/string.gs +++ b/string.gs @@ -114,3 +114,12 @@ func ljust(string, len, char = " ") { } return ret; } + +# repeat $string $times times (equivalent to int-string multiplication in python) +func repstr(string, times) { + local ret = ""; + repeat $times { + ret &= $string; + } + return ret; +} diff --git a/test/lib/test_string.gs b/test/lib/test_string.gs index b1edc1b..a8ba04a 100644 --- a/test/lib/test_string.gs +++ b/test/lib/test_string.gs @@ -9,4 +9,5 @@ proc test_string { assert zfill("FFF", 6), "000FFF", "zfill(\"FFF\", 6)"; assert ljust("FFF", 6), " FFF", "ljust(\"FFF\", 6)"; assert ljust("FFF", 6, 1), "111FFF", "ljust(\"FFF\", 6, 1)"; + assert repstr("a", 3), "aaa", "repstr(\"a\", 3)"; } From 7bf085b5949de5cbbe6f985066ec0d6183b01e4b Mon Sep 17 00:00:00 2001 From: faretek Date: Sun, 13 Jul 2025 13:19:02 +0100 Subject: [PATCH 11/13] feat: rjust --- string.gs | 9 +++++++++ test/lib/test_string.gs | 2 ++ 2 files changed, 11 insertions(+) diff --git a/string.gs b/string.gs index df97f75..1b41195 100644 --- a/string.gs +++ b/string.gs @@ -115,6 +115,15 @@ func ljust(string, len, char = " ") { return ret; } +# Pad ' ' to the right until it reaches the specified length. +func rjust(string, len, char = " ") { + local ret = $string; + repeat $len - length $string { + ret &= $char; + } + return ret; +} + # repeat $string $times times (equivalent to int-string multiplication in python) func repstr(string, times) { local ret = ""; diff --git a/test/lib/test_string.gs b/test/lib/test_string.gs index a8ba04a..021632b 100644 --- a/test/lib/test_string.gs +++ b/test/lib/test_string.gs @@ -10,4 +10,6 @@ proc test_string { assert ljust("FFF", 6), " FFF", "ljust(\"FFF\", 6)"; assert ljust("FFF", 6, 1), "111FFF", "ljust(\"FFF\", 6, 1)"; assert repstr("a", 3), "aaa", "repstr(\"a\", 3)"; + assert rjust("FFF", 6), "FFF ", "rjust(\"FFF\", 6)"; + assert rjust("FFF", 6, 0), "FFF000", "rjust(\"FFF\", 6, 1)"; } From 789851a2d8402bc7979c838c47acf26e109d6b65 Mon Sep 17 00:00:00 2001 From: faretek Date: Sun, 13 Jul 2025 13:25:55 +0100 Subject: [PATCH 12/13] feat: test slice(_step) --- test/lib/test_string.gs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/lib/test_string.gs b/test/lib/test_string.gs index 021632b..15e157d 100644 --- a/test/lib/test_string.gs +++ b/test/lib/test_string.gs @@ -12,4 +12,6 @@ proc test_string { assert repstr("a", 3), "aaa", "repstr(\"a\", 3)"; assert rjust("FFF", 6), "FFF ", "rjust(\"FFF\", 6)"; assert rjust("FFF", 6, 0), "FFF000", "rjust(\"FFF\", 6, 1)"; + assert slice("Hello, world", 2, 6), "ello", "slice(\"Hello, world\", 2, 6)"; + assert slice_step("Hello, world", 5, 0, -2), "olH", "slice_step(\"Hello, world\", 5, 0, -2)"; } From 0fe2b7676f78d76e2e26e15c200c47d149a4d369 Mon Sep 17 00:00:00 2001 From: faretek Date: Sun, 13 Jul 2025 13:39:35 +0100 Subject: [PATCH 13/13] feat: string constants --- string.gs | 10 ++++++++++ test/lib/test_string.gs | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/string.gs b/string.gs index 1b41195..8510a9f 100644 --- a/string.gs +++ b/string.gs @@ -1,3 +1,13 @@ +%define WHITESPACE " \t\n\r" +%define ASCII_LOWERCASE "abcdefghijklmnopqrstuvwxyz" +%define ASCII_UPPERCASE "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +%define ASCII_LETTERS ASCII_LOWERCASE & ASCII_UPPERCASE +%define DIGITS "0123456789" +%define HEXDIGITS DIGITS & "abcdef" & "ABCDEF" +%define OCTDIGITS "01234567" +%define PUNCTUATION "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~" +%define PRINTABLE_CHARS DIGITS & ASCII_LETTERS & PUNCTUATION & WHITESPACE + func strcmp(string1, string2) { # This code assumes you have costumes A-Z and a-z # If you need to compare chars e.g ä vs Ä, then you need to add those as costumes too diff --git a/test/lib/test_string.gs b/test/lib/test_string.gs index 15e157d..c316001 100644 --- a/test/lib/test_string.gs +++ b/test/lib/test_string.gs @@ -14,4 +14,14 @@ proc test_string { assert rjust("FFF", 6, 0), "FFF000", "rjust(\"FFF\", 6, 1)"; assert slice("Hello, world", 2, 6), "ello", "slice(\"Hello, world\", 2, 6)"; assert slice_step("Hello, world", 5, 0, -2), "olH", "slice_step(\"Hello, world\", 5, 0, -2)"; + + assert WHITESPACE, " \t\n\r", "WHITESPACE"; + assert ASCII_LETTERS, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", "ASCII_LETTERS"; + assert ASCII_LOWERCASE, "abcdefghijklmnopqrstuvwxyz", "ASCII_LOWERCASE"; + assert ASCII_UPPERCASE, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "ASCII_UPPERCASE"; + assert DIGITS, "0123456789", "DIGITS"; + assert HEXDIGITS, "0123456789abcdefABCDEF", "HEXDIGITS"; + assert OCTDIGITS, "01234567", "OCTDIGITS"; + assert PUNCTUATION, "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", "PUNCTUATION"; + assert PRINTABLE_CHARS, "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~ \t\n\r", "PRINTABLE_CHARS"; }