From 15c8980e598af95a53b533e602fab3d287eeeb12 Mon Sep 17 00:00:00 2001 From: farkon00 <59134591+farkon00@users.noreply.github.com> Date: Mon, 26 Jan 2026 17:56:45 +0200 Subject: [PATCH 1/5] Improved streq performance by comparing mutiple bytes at a time String manipulation functions were moved to a separate file --- std/std.cn | 131 +--------------------------------------------------- std/str.cn | 133 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 134 insertions(+), 130 deletions(-) create mode 100644 std/str.cn diff --git a/std/std.cn b/std/std.cn index 2684b2d..0681687 100644 --- a/std/std.cn +++ b/std/std.cn @@ -298,26 +298,7 @@ nproc str_to_nstr @str -> ptr: buf end -proc streq @str @str -> int: - let len data len2 data2; - len2 len == if - 0 1 - len 0 > - while - drop - let curlen; - data curlen ptr+ @8 - data2 curlen ptr+ @8 - == let res; - curlen 1 + res - curlen 1 + len < - res and - end - swap drop - else - 0 - end -end +include str.cn #if platform Platform.fasm_x86_64_linux ==; nproc exec_cmd ptr argv ptr exec: @@ -341,113 +322,3 @@ end end #endif -proc str_find @str @str -> int: - let len1 data1 len2 data2; - if len2 0 > len1 len2 >= and do - 0 - 1 while - if len2 over data1 +ptr len2 data2 streq do - 0 - else - 1 + - dup len1 len2 - <= - end - end - if dup len1 len2 - 1 + == do - drop -1 - end - else - -1 - end -end - -proc str_rfind @str @str -> int: - let len1 data1 len2 data2; - if len2 0 > len1 len2 >= and do - len1 len2 - - 1 while - if len2 over data1 +ptr len2 data2 streq do - 0 - else - 1 - - dup 0 >= - end - end - else - -1 - end -end - -proc str_count @str @str -> int: - var counter int - let len1 data1 len2 data2; - 0 - len1 0 != len1 len2 >= and while - if len2 over data1 +ptr len2 data2 streq do - *counter inc - len2 + - else - 1 + - end - dup len1 len2 - <= - end drop - counter -end - -nproc str_slice1 int start @str -> @str: - if start len >= start 0 < or do - "Index out of range for the start of the slice: " puts - start print - 1 exit - end - len start - data start ptr+ -end - -nproc str_slice2 int start int _end @str -> @str: - if start len >= start 0 < or do - "Index out of range for the start of the string slice: " puts - start print - 1 exit - end - if _end len > _end 0 < or do - "Index out of range for the end of the string slice: " puts - _end print - 1 exit - end - _end start - data start ptr+ -end - -proc str_split @str @str -> [DYNAMIC_ARRAY_SIZE] str: - let len data sep_len sep_data; - len data sep_len sep_data str_count - sizeoftype *str * malloc let res; - sizeoftype str malloc drop - res -end - -struct CursoredString - str data - int cursor - - sproc __init__ @str: - str !self.data - 0 !self.cursor - end - - nproc rest -> @str: - self.data.len self.cursor - self.data.data self.cursor ptr+ - end - - // Jumps to the CHARACTER AFTER the sub-string - // Returns a bool - // true - jumped - // false - no next line found - nproc jump_to @str -> int: - self.rest len data str_find - let offset; - offset -1 != offset len + self.data.len != and - dup if - *self.cursor offset len + incby - end - end -end \ No newline at end of file diff --git a/std/str.cn b/std/str.cn new file mode 100644 index 0000000..d4bb70a --- /dev/null +++ b/std/str.cn @@ -0,0 +1,133 @@ +include core.cn + +proc streq @str @str -> int: + let len data len2 data2; + len2 len == if + var i int + var res int = 1; + while len i - 8 >= + res and do + data @ data2 @ == res and !res + *i 8 incby + end + while i len < + res and do + data @8 data2 @8 == res and !res + *i inc + end + res + else + 0 + end +end + +proc str_find @str @str -> int: + let len1 data1 len2 data2; + if len2 0 > len1 len2 >= and do + 0 + 1 while + if len2 over data1 +ptr len2 data2 streq do + 0 + else + 1 + + dup len1 len2 - <= + end + end + if dup len1 len2 - 1 + == do + drop -1 + end + else + -1 + end +end + +proc str_rfind @str @str -> int: + let len1 data1 len2 data2; + if len2 0 > len1 len2 >= and do + len1 len2 - + 1 while + if len2 over data1 +ptr len2 data2 streq do + 0 + else + 1 - + dup 0 >= + end + end + else + -1 + end +end + +proc str_count @str @str -> int: + var counter int + let len1 data1 len2 data2; + 0 + len1 0 != len1 len2 >= and while + if len2 over data1 +ptr len2 data2 streq do + *counter inc + len2 + + else + 1 + + end + dup len1 len2 - <= + end drop + counter +end + +nproc str_slice1 int start @str -> @str: + if start len >= start 0 < or do + "Index out of range for the start of the slice: " puts + start print + 1 exit + end + len start - data start ptr+ +end + +nproc str_slice2 int start int _end @str -> @str: + if start len >= start 0 < or do + "Index out of range for the start of the string slice: " puts + start print + 1 exit + end + if _end len > _end 0 < or do + "Index out of range for the end of the string slice: " puts + _end print + 1 exit + end + _end start - data start ptr+ +end + +proc str_split @str @str -> [DYNAMIC_ARRAY_SIZE] str: + let len data sep_len sep_data; + len data sep_len sep_data str_count + sizeoftype *str * malloc let res; + sizeoftype str malloc drop + res +end + +struct CursoredString + str data + int cursor + + sproc __init__ @str: + str !self.data + 0 !self.cursor + end + + nproc rest -> @str: + self.data.len self.cursor - self.data.data self.cursor ptr+ + end + + // Jumps to the CHARACTER AFTER the sub-string + // Returns a bool + // true - jumped + // false - no next line found + nproc jump_to @str -> int: + self.rest len data str_find + let offset; + offset -1 != offset len + self.data.len != and + dup if + *self.cursor offset len + incby + end + end +end \ No newline at end of file From b1f3f04b2369291ccbb8ecf88da518ccf2a5246a Mon Sep 17 00:00:00 2001 From: farkon00 <59134591+farkon00@users.noreply.github.com> Date: Mon, 26 Jan 2026 18:08:53 +0200 Subject: [PATCH 2/5] Fixed an uninitialized variable being used in streq --- std/str.cn | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/std/str.cn b/std/str.cn index d4bb70a..848e5cb 100644 --- a/std/str.cn +++ b/std/str.cn @@ -3,7 +3,7 @@ include core.cn proc streq @str @str -> int: let len data len2 data2; len2 len == if - var i int + var i int = 0; var res int = 1; while len i - 8 >= res and do From 79400b284f1dd5816d7912d63702b682b7e53d2e Mon Sep 17 00:00:00 2001 From: farkon00 <59134591+farkon00@users.noreply.github.com> Date: Mon, 26 Jan 2026 20:43:13 +0200 Subject: [PATCH 3/5] Optimized str_find using the Z-function --- std/str.cn | 78 +++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 66 insertions(+), 12 deletions(-) diff --git a/std/str.cn b/std/str.cn index 848e5cb..911483e 100644 --- a/std/str.cn +++ b/std/str.cn @@ -21,24 +21,78 @@ proc streq @str @str -> int: end end +nproc z_array @str -> [DYNAMIC_ARRAY_SIZE] int: + var l int = 0; + var r int = 0; + len sizeoftype int * malloc ([DYNAMIC_ARRAY_SIZE]) int let z; + len 0 z *[] ! + var i int = 1; + while i len < do + var done int = 0; + if i r <= do + if i l - z [] i + r <= do + i l - z [] i z *[] ! + 1 !done + end + else + i 1 - !r + end + if done not do + i !l + if r len 1 - < do + data r 1 + ptr+ @8 data r 1 + i - ptr+ @8 == + else 0 end + while + *r inc + if r len 1 - < do + data r 1 + ptr+ @8 data r 1 + i - ptr+ @8 == + else 0 end + end + r i - 1 + i z *[] ! + end + *i inc + end + z +end + proc str_find @str @str -> int: let len1 data1 len2 data2; - if len2 0 > len1 len2 >= and do - 0 - 1 while - if len2 over data1 +ptr len2 data2 streq do + if len1 len2 >= do + if len2 16 < len1 len2 - 16 < or do + if len2 0 > len1 len2 >= and do 0 + 1 while + if len2 over data1 +ptr len2 data2 streq do + 0 + else + 1 + + dup len1 len2 - <= + end + end + if dup len1 len2 - 1 + == do + drop -1 + end else - 1 + - dup len1 len2 - <= + -1 end + else + len1 len2 + malloc let data3; + len2 data2 data3 memcpy + len1 data1 data3 len2 ptr+ memcpy + len1 len2 + data3 z_array let z; + data3 free + var i int = 0; + var res int = 0 1 -; + while i len1 < res -1 == and do + if i len2 + z [] len2 >= do + i !res + end + *i inc + end + z free + res end - if dup len1 len2 - 1 + == do - drop -1 - end - else - -1 - end + else -1 end end proc str_rfind @str @str -> int: From 39e5bb38c93082e8d5ccf712e3b0435b8a3dfa3a Mon Sep 17 00:00:00 2001 From: farkon00 <59134591+farkon00@users.noreply.github.com> Date: Mon, 26 Jan 2026 21:16:54 +0200 Subject: [PATCH 4/5] Optimized str_rfind using the Z-function --- std/str.cn | 59 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 22 deletions(-) diff --git a/std/str.cn b/std/str.cn index 911483e..9e84ec1 100644 --- a/std/str.cn +++ b/std/str.cn @@ -57,23 +57,19 @@ end proc str_find @str @str -> int: let len1 data1 len2 data2; - if len1 len2 >= do + if len2 0 > len1 len2 >= and do if len2 16 < len1 len2 - 16 < or do - if len2 0 > len1 len2 >= and do - 0 - 1 while - if len2 over data1 +ptr len2 data2 streq do - 0 - else - 1 + - dup len1 len2 - <= - end - end - if dup len1 len2 - 1 + == do - drop -1 + 0 + 1 while + if len2 over data1 +ptr len2 data2 streq do + 0 + else + 1 + + dup len1 len2 - <= end - else - -1 + end + if dup len1 len2 - 1 + == do + drop -1 end else len1 len2 + malloc let data3; @@ -98,14 +94,33 @@ end proc str_rfind @str @str -> int: let len1 data1 len2 data2; if len2 0 > len1 len2 >= and do - len1 len2 - - 1 while - if len2 over data1 +ptr len2 data2 streq do - 0 - else - 1 - - dup 0 >= + if len2 16 < len1 len2 - 16 < or do + len1 len2 - + 1 while + if len2 over data1 +ptr len2 data2 streq do + 0 + else + 1 - + dup 0 >= + end end + else + len1 len2 + malloc let data3; + len2 data2 data3 memcpy + len1 data1 data3 len2 ptr+ memcpy + len1 len2 + data3 z_array let z; + data3 free + var i int + len1 len2 - !i + var res int = 0 1 -; + while i len1 < res -1 == and do + if i len2 + z [] len2 >= do + i !res + end + *i dec + end + z free + res end else -1 From d503834fe2c86b1d38222cbfa24a66e6cc55f1aa Mon Sep 17 00:00:00 2001 From: farkon00 <59134591+farkon00@users.noreply.github.com> Date: Mon, 26 Jan 2026 21:35:08 +0200 Subject: [PATCH 5/5] Optimized str_count using the Z-function, streq fixed --- std/str.cn | 49 +++++++++++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/std/str.cn b/std/str.cn index 9e84ec1..91c5b6c 100644 --- a/std/str.cn +++ b/std/str.cn @@ -7,12 +7,12 @@ proc streq @str @str -> int: var res int = 1; while len i - 8 >= res and do - data @ data2 @ == res and !res + data i ptr+ @ data2 i ptr+ @ == res and !res *i 8 incby end while i len < res and do - data @8 data2 @8 == res and !res + data i ptr+ @8 data2 i ptr+ @8 == res and !res *i inc end res @@ -128,18 +128,35 @@ proc str_rfind @str @str -> int: end proc str_count @str @str -> int: - var counter int + var counter int = 0; let len1 data1 len2 data2; - 0 - len1 0 != len1 len2 >= and while - if len2 over data1 +ptr len2 data2 streq do - *counter inc - len2 + - else - 1 + + if len2 16 < len1 len2 - 16 < or do + 0 + len1 0 != len1 len2 >= and while + if len2 over data1 +ptr len2 data2 streq do + *counter inc + len2 + + else + 1 + + end + dup len1 len2 - <= + end drop + counter print + else + len1 len2 + malloc let data3; + len2 data2 data3 memcpy + len1 data1 data3 len2 ptr+ memcpy + len1 len2 + data3 z_array let z; + data3 free + var i int = 0; + while i len1 len2 - <= do + if i len2 + z [] len2 >= do + *counter inc + *i len2 incby + else *i inc end end - dup len1 len2 - <= - end drop + z free + end counter end @@ -166,14 +183,6 @@ nproc str_slice2 int start int _end @str -> @str: _end start - data start ptr+ end -proc str_split @str @str -> [DYNAMIC_ARRAY_SIZE] str: - let len data sep_len sep_data; - len data sep_len sep_data str_count - sizeoftype *str * malloc let res; - sizeoftype str malloc drop - res -end - struct CursoredString str data int cursor