From b5304a3cf1a60c0a03dbc91dcb8a499a0bc76cb0 Mon Sep 17 00:00:00 2001 From: Toni Date: Tue, 8 Jul 2025 14:26:41 +0200 Subject: [PATCH] rewrite array builtins in zern --- examples/brainfuck.zr | 1 + examples/quicksort.zr | 4 +-- examples/tcp_client.zr | 2 +- src/codegen_x86_64.rs | 65 +++++++----------------------------------- src/parser.rs | 2 +- src/std.zr | 41 +++++++++++++++++++------- test.zr | 2 +- 7 files changed, 46 insertions(+), 71 deletions(-) diff --git a/examples/brainfuck.zr b/examples/brainfuck.zr index f076fb1..028d061 100644 --- a/examples/brainfuck.zr +++ b/examples/brainfuck.zr @@ -1,4 +1,5 @@ func main[] : I64 + // https://brainfuck.org/sierpinski.b let src: String = "++++++++[>+>++++<<-]>++>>+<[-[>>+<<-]+>>]>+[-<<<[->[+[-]+>++>>>-<<]<[<]>>++++++[<<+++++>>-]+<<++.[-]<<]>.>+[>>]>+]" let src_len: I64 = strlen(src) let i: I64 = 0 diff --git a/examples/quicksort.zr b/examples/quicksort.zr index aa7d9e5..70b0a4e 100644 --- a/examples/quicksort.zr +++ b/examples/quicksort.zr @@ -1,7 +1,7 @@ -func quicksort[arr: Array] : I64 +func quicksort[arr: Array] : Void do_quicksort(arr, 0, Array.size(arr)-1) -func do_quicksort[arr: Array, low: I64, high: I64] : I64 +func do_quicksort[arr: Array, low: I64, high: I64] : Void if low < high let i: I64 = partition(arr, low, high) do_quicksort(arr, low, i - 1) diff --git a/examples/tcp_client.zr b/examples/tcp_client.zr index f07ba39..edab374 100644 --- a/examples/tcp_client.zr +++ b/examples/tcp_client.zr @@ -9,7 +9,7 @@ func main[] : I64 String.set(sa, 1, 0) String.set(sa, 2, Bit.rshift(port, 8) && 255) String.set(sa, 3, port && 255) - // 23.192.228.80 + // 23.192.228.80 (example.com) String.set(sa, 4, 23) String.set(sa, 5, 192) String.set(sa, 6, 228) diff --git a/src/codegen_x86_64.rs b/src/codegen_x86_64.rs index 116d6e7..dd59e16 100644 --- a/src/codegen_x86_64.rs +++ b/src/codegen_x86_64.rs @@ -150,6 +150,16 @@ _builtin_deref64: mov rax, qword [rdi] ret +section .text._builtin_set8 +_builtin_set8: + mov [rdi], sil + ret + +section .text._builtin_set64 +_builtin_set64: + mov [rdi], rsi + ret + section .text._builtin_stdin _builtin_stdin: mov rax, [rel stdin] @@ -169,11 +179,6 @@ _builtin_rshift: sar rax, cl ret -section .text._builtin_string_set -_builtin_string_set: - mov [rdi + rsi], dl - ret - section .text._builtin_listdir _builtin_listdir: push r14 @@ -215,56 +220,6 @@ _builtin_listdir: pop rbx pop r14 ret - -section .text._builtin_array_set -_builtin_array_set: - mov rax, [rdi] - mov [rax + rsi*8], rdx - ret - -section .text._builtin_array_push -_builtin_array_push: - push r14 - push rbx - push rax - mov r14, rsi - mov rbx, rdi - mov rax, [rdi] - mov rcx, [rdi + 16] - cmp rcx, [rdi + 8] - jne ._builtin_array_push.1 - lea rdx, [rcx + rcx] - mov rsi, 4 - test rcx, rcx - cmovnz rsi, rdx - mov [rbx + 8], rsi - shl rsi, 3 - mov rdi, rax - call realloc - mov [rbx], rax - mov rcx, [rbx + 16] -._builtin_array_push.1: - mov [rax + rcx*8], r14 - inc qword [rbx + 16] - add rsp, 8 - pop rbx - pop r14 - ret - -section .text._builtin_array_size -_builtin_array_size: - mov rax, [rdi + 16] - ret - -section .text._builtin_array_free -_builtin_array_free: - push rbx - mov rbx, rdi - mov rdi, [rdi] - call free - mov rdi, rbx - pop rbx - jmp free " ); Ok(()) diff --git a/src/parser.rs b/src/parser.rs index 27359f6..0d4380a 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -72,7 +72,7 @@ pub enum Expr { } // TODO: currently they are all just 8 byte values -static TYPES: [&str; 6] = ["U8", "I64", "String", "Bool", "Ptr", "Array"]; +static TYPES: [&str; 7] = ["Void", "U8", "I64", "String", "Bool", "Ptr", "Array"]; pub struct Parser { tokens: Vec, diff --git a/src/std.zr b/src/std.zr index c118a68..72a5880 100644 --- a/src/std.zr +++ b/src/std.zr @@ -1,18 +1,18 @@ -func panic[msg: String] : I64 +func panic[msg: String] : Void printf("PANIC: %s\n", msg) exit(1) -func print[x: String] : I64 +func print[x: String] : Void printf("%s\n", x) -func print_i64[x: I64] : I64 +func print_i64[x: I64] : Void printf("%ld\n", x) func String.nth[s: String, n: I64] : U8 return _builtin_deref8(s + n) -func String.set[s: String, n: I64, c: U8] : I64 - _builtin_string_set(s, n, c) +func String.set[s: String, n: I64, c: U8] : Void + _builtin_set8(s+n, c) func String.is_whitespace[c: U8] : Bool return c == ' ' || c == 10 || c == 13 || c == 9 @@ -84,7 +84,7 @@ func IO.read_file[path: String]: String fclose(file) return buffer -func IO.write_file[path: String, content: String] : I64 +func IO.write_file[path: String, content: String] : Void let file: Ptr = fopen(path, "wb") if !file panic("failed to open file") @@ -176,14 +176,33 @@ func Math.urandom[]: I64 func Array.new[] : Array return calloc(1, 24) -func Array.set[xs: Array, n: I64, x: I64] : I64 - _builtin_array_set(xs, n, x) +func Array.set[xs: Array, n: I64, x: I64] : Void + let data: Ptr = _builtin_deref64(xs) + _builtin_set64(data+n*8, x) -func Array.push[xs: Array, x: I64] : I64 - return _builtin_array_push(xs, x) +func Array.push[xs: Array, x: I64] : Void + let data: Ptr = _builtin_deref64(xs) + let capacity: I64 = _builtin_deref64(xs+8) + let size: I64 = _builtin_deref64(xs+16) + + if size == capacity + let new_capacity: I64 = 4 + if capacity != 0 + new_capacity = capacity * 2 + let new_data: Ptr = realloc(data, new_capacity * 8) + _builtin_set64(xs, new_data) + _builtin_set64(xs+8, new_capacity) + data = new_data + + _builtin_set64(data+size*8, x) + _builtin_set64(xs+16, size + 1) func Array.size[xs: Array] : I64 - return _builtin_array_size(xs) + return _builtin_deref64(xs+16) + +func Array.free[xs: Array] : Void + free(_builtin_deref64(xs)) + free(xs) func OS.time[] : I64 let tv: Ptr = malloc(16) diff --git a/test.zr b/test.zr index 9d2fe03..f53eb54 100644 --- a/test.zr +++ b/test.zr @@ -1,4 +1,4 @@ -func run_test[x: String] : I64 +func run_test[x: String] : Void printf("\033[93mBuilding %s...\033[0m", x) let cmd: String = String.concat("./target/release/zern examples/", x)