From 252efd914e777a2de84b437c5b57e683767ff005 Mon Sep 17 00:00:00 2001 From: Toni Date: Sat, 7 Jun 2025 13:27:22 +0200 Subject: [PATCH] array literals --- examples/arrays.zr | 2 +- examples/quicksort.zr | 14 +---------- examples/rule110.zr | 4 +-- src/builtin.s | 58 ++++++++----------------------------------- src/codegen_x86_64.rs | 13 ++++++++++ src/parser.rs | 14 +++++++++++ src/std.zr | 20 ++++++++++++++- 7 files changed, 61 insertions(+), 64 deletions(-) diff --git a/examples/arrays.zr b/examples/arrays.zr index 3af352d..263a316 100644 --- a/examples/arrays.zr +++ b/examples/arrays.zr @@ -1,5 +1,5 @@ func main[] : I64 - let xs: Array = Array.new() + let xs: Array = [5849, 3869, 2859] Array.push(xs, 5242) Array.push(xs, 6533) Array.push(xs, 4574) diff --git a/examples/quicksort.zr b/examples/quicksort.zr index ae3e0a7..c013a8c 100644 --- a/examples/quicksort.zr +++ b/examples/quicksort.zr @@ -22,19 +22,7 @@ func partition[arr: Array, low: I64, high: I64] : I64 return i + 1 func main[] : I64 - let arr: Array = Array.new() - Array.push(arr, 340) - Array.push(arr, 252) - Array.push(arr, 352) - Array.push(arr, 117) - Array.push(arr, 650) - Array.push(arr, 652) - Array.push(arr, 322) - Array.push(arr, 175) - Array.push(arr, 714) - Array.push(arr, 268) - Array.push(arr, 725) - Array.push(arr, 664) + let arr: Array = [340, 252, 352, 117, 650, 652, 322, 175, 714, 268, 725, 664] for i in 0:Array.size(arr) print_i64(Array.nth(arr, i)) diff --git a/examples/rule110.zr b/examples/rule110.zr index 3293302..4c9cee7 100644 --- a/examples/rule110.zr +++ b/examples/rule110.zr @@ -1,5 +1,5 @@ func rule110_step[state: Array] : Array - let new_state: Array = Array.new() + let new_state: Array = [] for i in 0:Array.size(state) let left: Bool = false @@ -27,7 +27,7 @@ func to_str[state: Array]: String func main[] : I64 let SIZE: I64 = 60 - let state: Array = Array.new() + let state: Array = [] for i in 0:SIZE Array.push(state, false) Array.push(state, true) diff --git a/src/builtin.s b/src/builtin.s index 3cd13c4..6661326 100644 --- a/src/builtin.s +++ b/src/builtin.s @@ -33,29 +33,29 @@ OS.listdir: mov rdi, r14 call opendir mov r14, rax -.LBB5_1: +.OS.listdir.1: mov rdi, r14 call readdir test rax, rax - je .LBB5_7 + je .OS.listdir.3 cmp byte [rax+19], 46 - jne .LBB5_6 + jne .OS.listdir.2 movzx ecx, byte [rax+20] test ecx, ecx - je .LBB5_1 + je .OS.listdir.1 cmp ecx, 46 - jne .LBB5_6 + jne .OS.listdir.2 cmp byte [rax+21], 0 - je .LBB5_1 -.LBB5_6: + je .OS.listdir.1 +.OS.listdir.2: add rax, 19 mov rdi, rax call strdup mov rsi, rax mov rdi, rbx call Array.push - jmp .LBB5_1 -.LBB5_7: + jmp .OS.listdir.1 +.OS.listdir.3: mov rdi, r14 call closedir mov rax, rbx @@ -64,11 +64,6 @@ OS.listdir: pop r14 ret -Array.new: - mov rdi, 1 - mov rsi, 24 - jmp calloc - Array.nth: mov rax, [rdi] mov rax, [rax + rsi*8] @@ -88,7 +83,7 @@ Array.push: mov rax, [rdi] mov rcx, [rdi + 16] cmp rcx, [rdi + 8] - jne .no_realloc + jne .Array.push.1 lea rdx, [rcx + rcx] mov rsi, 4 test rcx, rcx @@ -99,7 +94,7 @@ Array.push: call realloc mov [rbx], rax mov rcx, [rbx + 16] -.no_realloc: +.Array.push.1: mov [rax + rcx*8], r14 inc qword [rbx + 16] add rsp, 8 @@ -119,34 +114,3 @@ Array.free: mov rdi, rbx pop rbx jmp free - -Math.isqrt: - xor rax, rax - mov rcx, 1 - mov rbx, rdi - shl rcx, 62 -.isqrt.1: - cmp rcx, 0 - je .isqrt.5 - cmp rcx, rbx - jbe .isqrt.2 - shr rcx, 2 - jmp .isqrt.1 -.isqrt.2: - cmp rcx, 0 - je .isqrt.5 - mov rdx, rax - add rdx, rcx - cmp rbx, rdx - jb .isqrt.3 - sub rbx, rdx - shr rax, 1 - add rax, rcx - jmp .isqrt.4 -.isqrt.3: - shr rax, 1 -.isqrt.4: - shr rcx, 2 - jmp .isqrt.2 -.isqrt.5: - ret \ No newline at end of file diff --git a/src/codegen_x86_64.rs b/src/codegen_x86_64.rs index 2b8e1d6..aed488c 100644 --- a/src/codegen_x86_64.rs +++ b/src/codegen_x86_64.rs @@ -58,6 +58,7 @@ macro_rules! emit { } static REGISTERS: [&str; 6] = ["rdi", "rsi", "rdx", "rcx", "r8", "r9"]; +// TODO: currently they are all just 8 byte values static TYPES: [&str; 6] = ["I64", "String", "Bool", "Ptr", "Char", "Array"]; pub struct CodegenX86_64 { @@ -452,6 +453,18 @@ extern gettimeofday emit!(&mut self.output, " call {}", callee); } + Expr::ArrayLiteral(exprs) => { + emit!(&mut self.output, " call Array.new"); + emit!(&mut self.output, " mov r12, rax"); + + for expr in exprs { + self.compile_expr(env, expr)?; + emit!(&mut self.output, " mov rsi, rax"); + emit!(&mut self.output, " mov rdi, r12"); + emit!(&mut self.output, " call Array.push"); + } + emit!(&mut self.output, " mov rax, r12"); + } } Ok(()) } diff --git a/src/parser.rs b/src/parser.rs index 268d04f..2d93952 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -66,6 +66,7 @@ pub enum Expr { paren: Token, args: Vec, }, + ArrayLiteral(Vec), } pub struct Parser { @@ -436,6 +437,19 @@ impl Parser { let expr = self.expression()?; self.consume(TokenType::RightParen, "expected ')' after expression")?; Ok(Expr::Grouping(Box::new(expr))) + } else if self.match_token(&[TokenType::LeftBracket]) { + let mut xs = vec![]; + if !self.check(&TokenType::RightBracket) { + loop { + xs.push(self.expression()?); + if !self.match_token(&[TokenType::Comma]) { + break; + } + } + } + self.consume(TokenType::RightBracket, "expected ']' after values")?; + + Ok(Expr::ArrayLiteral(xs)) } else if self.match_token(&[TokenType::Identifier]) { Ok(Expr::Variable(self.previous().clone())) } else { diff --git a/src/std.zr b/src/std.zr index 0f08fb2..0db1b96 100644 --- a/src/std.zr +++ b/src/std.zr @@ -95,6 +95,21 @@ func Math.pow[b: I64, e: I64] : I64 func Math.lcm[a: I64, b: I64] : I64 return (a * b) / Math.gcd(a, b) +func Math.isqrt[n: I64] : I64 + if n < 0 + return -1 + if n == 0 || n == 1 + return n + + let guess: I64 = n + let next_guess: I64 = (guess + n / guess) / 2 + + while next_guess < guess + guess = next_guess + next_guess = (guess + n / guess) / 2 + + return guess + func Math.is_prime[n: I64]: I64 if n <= 1 return false @@ -108,4 +123,7 @@ func Math.is_prime[n: I64]: I64 if n % i == 0 || n % (i + 2) == 0 return false i = i + 6 - return true \ No newline at end of file + return true + +func Array.new[] : Array + return calloc(1, 24) \ No newline at end of file