From 26598fe6f2d5569f01a4b955755f0008dcb9b00e Mon Sep 17 00:00:00 2001 From: Toni Date: Mon, 23 Jun 2025 17:00:58 +0200 Subject: [PATCH] small fixes --- examples/euler12.zr | 8 +++---- examples/quicksort.zr | 2 -- examples/strings.zr | 7 ------ src/codegen_x86_64.rs | 5 +++- src/std.zr | 53 +++++++++++++++++++------------------------ test.zr | 7 ++++-- 6 files changed, 36 insertions(+), 46 deletions(-) delete mode 100644 examples/strings.zr diff --git a/examples/euler12.zr b/examples/euler12.zr index c4cc710..53617d7 100644 --- a/examples/euler12.zr +++ b/examples/euler12.zr @@ -1,14 +1,14 @@ func num_divisors[n: I64] : I64 let end: I64 = Math.isqrt(n) - let result: I64 = 0 + let out: I64 = 0 for i in 1..end+1 if n % i == 0 - result = result + 2 + out = out + 2 if end * end == n - result = result - 1 - return result + out = out - 1 + return out func main[] : I64 let n: I64 = 0 diff --git a/examples/quicksort.zr b/examples/quicksort.zr index 47d4698..9994087 100644 --- a/examples/quicksort.zr +++ b/examples/quicksort.zr @@ -1,13 +1,11 @@ func quicksort[arr: Array] : I64 do_quicksort(arr, 0, Array.size(arr)-1) - return 0 func do_quicksort[arr: Array, low: I64, high: I64] : I64 if low < high let i: I64 = partition(arr, low, high) do_quicksort(arr, low, i - 1) do_quicksort(arr, i + 1, high) - return 0 func partition[arr: Array, low: I64, high: I64] : I64 let pivot: I64 = Array.nth(arr, high) diff --git a/examples/strings.zr b/examples/strings.zr deleted file mode 100644 index 70d7b61..0000000 --- a/examples/strings.zr +++ /dev/null @@ -1,7 +0,0 @@ -func main[] : I64 - let a: String = I64.to_string(58394) - print_i64(strlen(a)) - let b: String = String.concat(a, "test") - print_i64(strlen(b)) - free(a) - free(b) \ No newline at end of file diff --git a/src/codegen_x86_64.rs b/src/codegen_x86_64.rs index 31e1018..1edac7f 100644 --- a/src/codegen_x86_64.rs +++ b/src/codegen_x86_64.rs @@ -112,7 +112,7 @@ extern strcmp extern strcat extern strcpy extern strdup -extern strlcpy +extern strncpy extern fgets extern fopen extern fseek @@ -360,6 +360,9 @@ Array.free: // TODO if name.lexeme == "main" { emit!(&mut self.output, "global {}", name.lexeme); + if return_type.lexeme != "I64" { + return error!(&name.loc, "main must return I64"); + } } emit!(&mut self.output, "section .text.{}", name.lexeme); emit!(&mut self.output, "{}:", name.lexeme); diff --git a/src/std.zr b/src/std.zr index c1ee3bf..7707243 100644 --- a/src/std.zr +++ b/src/std.zr @@ -1,15 +1,12 @@ func panic[msg: String] : I64 printf("PANIC: %s\n", msg) exit(1) - return 0 func print[x: String] : I64 printf("%s\n", x) - return 0 func print_i64[x: I64] : I64 printf("%ld\n", x) - return 0 func String.is_whitespace[c: U8] : Bool return c == ' ' || c == 10 || c == 13 || c == 9 @@ -21,14 +18,19 @@ func String.concat[a: String, b: String] : String return c func String.find[s: String, needle: U8] : I64 - for i in 0..strlen(s) + let s_len: I64 = strlen(s) + for i in 0..s_len if String.nth(s, i) == needle return i return -1 func String.substr[s: String, start: I64, length: I64] : String + if start < 0 || length < 0 || start + length > strlen(s) + panic("String.substr out of bounds") + let out: String = malloc(length + 1) - strlcpy(out, s + start, length + 1) + strncpy(out, s + start, length) + String.set(out, length, 0) return out func String.trim[s: String] : String @@ -80,7 +82,6 @@ func IO.write_file[path: String, content: String] : I64 fwrite(content, 1, strlen(content), file) fclose(file) - return 0 func U8.parse_i64[c: U8]: I64 return c - '0' @@ -139,7 +140,7 @@ func Math.isqrt[n: I64] : I64 return guess -func Math.is_prime[n: I64]: I64 +func Math.is_prime[n: I64]: Bool if n <= 1 return false if n == 2 || n == 3 @@ -156,7 +157,7 @@ func Math.is_prime[n: I64]: I64 func Math.urandom[]: I64 let buffer: Ptr = malloc(8) - let file: Ptr = fopen("/dev/urandom", "r") + let file: Ptr = fopen("/dev/urandom", "rb") fread(buffer, 8, 1, file) fclose(file) let n: I64 = deref(buffer) @@ -183,18 +184,10 @@ func Crypto.hex_encode[s: String] : String return out func Crypto.from_hex_digit[d: U8] : I64 - if d == 'a' - return 10 - if d == 'b' - return 11 - if d == 'c' - return 12 - if d == 'd' - return 13 - if d == 'e' - return 14 - if d == 'f' - return 15 + if d >= 'a' && d <= 'f' + return d - 'a' + 10 + if d >= 'A' && d <= 'F' + return d - 'A' + 10 return U8.parse_i64(d) func Crypto.hex_decode[s: String] : String @@ -246,7 +239,7 @@ func Crypto.rc4[key: String, plaintext: String]: String func Crypto.base64_encode[s: String] : String let chars: String = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" let s_len: I64 = strlen(s) - let output: String = malloc(s_len*2) + let out: String = malloc(s_len*2) let i: I64 = 0 let j: I64 = 0 @@ -261,21 +254,21 @@ func Crypto.base64_encode[s: String] : String i = i + 3 let triple: I64 = Bit.or(Bit.or(Bit.lshift(b1, 16), Bit.lshift(b2, 8)), b3) - String.set(output, j, String.nth(chars, Bit.and(Bit.rshift(triple, 18), 63))) - String.set(output, j+1, String.nth(chars, Bit.and(Bit.rshift(triple, 12), 63))) - String.set(output, j+2, String.nth(chars, Bit.and(Bit.rshift(triple, 6), 63))) - String.set(output, j+3, String.nth(chars, Bit.and(triple, 63))) + String.set(out, j, String.nth(chars, Bit.and(Bit.rshift(triple, 18), 63))) + String.set(out, j+1, String.nth(chars, Bit.and(Bit.rshift(triple, 12), 63))) + String.set(out, j+2, String.nth(chars, Bit.and(Bit.rshift(triple, 6), 63))) + String.set(out, j+3, String.nth(chars, Bit.and(triple, 63))) j = j + 4 let padding: I64 = s_len % 3 if padding == 1 - String.set(output, j-2, '=') - String.set(output, j-1, '=') + String.set(out, j-2, '=') + String.set(out, j-1, '=') else if padding == 2 - String.set(output, j-1, '=') + String.set(out, j-1, '=') - String.set(output, j, 0) - return output + String.set(out, j, 0) + return out func Crypto.base64_decode[s: String] : String let chars: String = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" diff --git a/test.zr b/test.zr index b2a58d9..41eefff 100644 --- a/test.zr +++ b/test.zr @@ -1,4 +1,8 @@ func run_test[x: String] : I64 + // requires stdin + if strcmp(x, "guess_number.zr") == 0 + return 0 + printf("\033[93mBuilding %s...\033[0m", x) let cmd: String = String.concat("./target/release/zern examples/", x) @@ -14,9 +18,8 @@ func run_test[x: String] : I64 if system("./out") != 0 exit(1) let run_end_time: I64 = OS.time() - + printf("\033[93mRunning %s...\033[0m %ldms\n", x, run_end_time - run_start_time) - return 0 func main[] : I64 system("cargo build --release")