From 7425ab256b89142f0973f6ce9bc2c2ccbab68706 Mon Sep 17 00:00:00 2001 From: Toni Date: Fri, 13 Jun 2025 16:59:22 +0200 Subject: [PATCH] double dot in for ranges --- README.md | 2 +- examples/arrays.zr | 2 +- examples/euler1.zr | 2 +- examples/euler10.zr | 2 +- examples/euler12.zr | 2 +- examples/euler14.zr | 2 +- examples/euler15.zr | 2 +- examples/euler4.zr | 4 ++-- examples/euler5.zr | 2 +- examples/euler6.zr | 4 ++-- examples/euler8.zr | 2 +- examples/euler9.zr | 4 ++-- examples/quicksort.zr | 6 +++--- examples/rule110.zr | 8 ++++---- src/codegen_x86_64.rs | 1 - src/parser.rs | 2 +- src/std.zr | 14 +++++++------- src/tokenizer.rs | 13 ++++++++++++- test.zr | 2 +- 19 files changed, 43 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index a004f0e..78a1591 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,6 @@ func fib[n: I64] : I64 return fib(n-2) + fib(n-1) func main[] : I64 - for i in 0:20 + for i in 0..20 fib(i) |> I64.to_string() |> print() ``` \ No newline at end of file diff --git a/examples/arrays.zr b/examples/arrays.zr index 263a316..d03aa0c 100644 --- a/examples/arrays.zr +++ b/examples/arrays.zr @@ -4,7 +4,7 @@ func main[] : I64 Array.push(xs, 6533) Array.push(xs, 4574) - for i in 0:Array.size(xs) + for i in 0..Array.size(xs) xs |> Array.nth(i) |> print_i64() \ No newline at end of file diff --git a/examples/euler1.zr b/examples/euler1.zr index 7bee2e8..cded008 100644 --- a/examples/euler1.zr +++ b/examples/euler1.zr @@ -1,7 +1,7 @@ func main[] : I64 let sum: I64 = 0 - for i in 0:1000 + for i in 0..1000 if i % 5 == 0 || i % 3 == 0 sum = sum + i print_i64(sum) \ No newline at end of file diff --git a/examples/euler10.zr b/examples/euler10.zr index 743fe77..57a8d68 100644 --- a/examples/euler10.zr +++ b/examples/euler10.zr @@ -1,7 +1,7 @@ func main[] : I64 let sum: I64 = 0 - for i in 0:2000000 + for i in 0..2000000 if Math.is_prime(i) sum = sum + i print_i64(sum) \ No newline at end of file diff --git a/examples/euler12.zr b/examples/euler12.zr index 2afa3d2..c4cc710 100644 --- a/examples/euler12.zr +++ b/examples/euler12.zr @@ -2,7 +2,7 @@ func num_divisors[n: I64] : I64 let end: I64 = Math.isqrt(n) let result: I64 = 0 - for i in 1:end+1 + for i in 1..end+1 if n % i == 0 result = result + 2 diff --git a/examples/euler14.zr b/examples/euler14.zr index 4f7f7a4..d570e72 100644 --- a/examples/euler14.zr +++ b/examples/euler14.zr @@ -14,7 +14,7 @@ func main[] : I64 let max: I64 = 0 let max_index: I64 = 0 - for i in 1:1000000 + for i in 1..1000000 let seq: I64 = collatz_seq(i) if seq > max max = seq diff --git a/examples/euler15.zr b/examples/euler15.zr index 835c336..defd65e 100644 --- a/examples/euler15.zr +++ b/examples/euler15.zr @@ -3,7 +3,7 @@ func main[] : I64 let r: I64 = 20 let out: I64 = 1 - for i in 1:r+1 + for i in 1..r+1 out = out * (n - (r - i)) / i print_i64(out) \ No newline at end of file diff --git a/examples/euler4.zr b/examples/euler4.zr index a77a1c1..e083b20 100644 --- a/examples/euler4.zr +++ b/examples/euler4.zr @@ -1,8 +1,8 @@ func main[] : I64 let out: I64 = 0 - for a in 500:1000 - for b in 500:1000 + for a in 500..1000 + for b in 500..1000 if a * b > out let s: String = I64.to_string(a * b) let s_rev: String = String.rev(s) diff --git a/examples/euler5.zr b/examples/euler5.zr index 60dc55a..8920438 100644 --- a/examples/euler5.zr +++ b/examples/euler5.zr @@ -1,6 +1,6 @@ func main[] : I64 let out: I64 = 1 - for i in 1:21 + for i in 1..21 out = Math.lcm(out, i) print_i64(out) \ No newline at end of file diff --git a/examples/euler6.zr b/examples/euler6.zr index b380cf6..95072be 100644 --- a/examples/euler6.zr +++ b/examples/euler6.zr @@ -1,10 +1,10 @@ func main[] : I64 let sum_of_squares: I64 = 0 - for i in 1:101 + for i in 1..101 sum_of_squares = sum_of_squares + i * i let square_of_sum: I64 = 0 - for i in 1:101 + for i in 1..101 square_of_sum = square_of_sum + i square_of_sum = square_of_sum * square_of_sum diff --git a/examples/euler8.zr b/examples/euler8.zr index 2209be9..2f55051 100644 --- a/examples/euler8.zr +++ b/examples/euler8.zr @@ -3,7 +3,7 @@ func main[] : I64 let out: I64 = 0 let max: I64 = strlen(n) - 13 - for i in 0:max + for i in 0..max let s: I64 = 1 let j: I64 = 0 while j < 13 diff --git a/examples/euler9.zr b/examples/euler9.zr index 0da5dac..8a2016d 100644 --- a/examples/euler9.zr +++ b/examples/euler9.zr @@ -1,6 +1,6 @@ func main[] : I64 - for a in 1:1000 - for b in 1:1000 + for a in 1..1000 + for b in 1..1000 let c: I64 = 1000 - b - a if a * a + b * b == c * c print_i64(a * b * c) diff --git a/examples/quicksort.zr b/examples/quicksort.zr index 98e39cb..47d4698 100644 --- a/examples/quicksort.zr +++ b/examples/quicksort.zr @@ -12,7 +12,7 @@ func do_quicksort[arr: Array, low: I64, high: I64] : I64 func partition[arr: Array, low: I64, high: I64] : I64 let pivot: I64 = Array.nth(arr, high) let i: I64 = low - 1 - for j in low:high + for j in (low)..high if Array.nth(arr, j) <= pivot i = i + 1 let temp: I64 = Array.nth(arr, i) @@ -26,11 +26,11 @@ func partition[arr: Array, low: I64, high: I64] : I64 func main[] : I64 let arr: Array = [340, 252, 352, 117, 650, 652, 322, 175, 714, 268, 725, 664] - for i in 0:Array.size(arr) + for i in 0..Array.size(arr) print_i64(Array.nth(arr, i)) print("------------") quicksort(arr) - for i in 0:Array.size(arr) + for i in 0..Array.size(arr) print_i64(Array.nth(arr, i)) \ No newline at end of file diff --git a/examples/rule110.zr b/examples/rule110.zr index 4e94cbe..b697ab3 100644 --- a/examples/rule110.zr +++ b/examples/rule110.zr @@ -1,7 +1,7 @@ func rule110_step[state: Array] : Array let new_state: Array = [] - for i in 0:Array.size(state) + for i in 0..Array.size(state) let left: Bool = false if i - 1 >= 0 left = Array.nth(state, i-1) @@ -16,7 +16,7 @@ func rule110_step[state: Array] : Array func to_str[state: Array]: String let out: String = malloc(Array.size(state)) - for i in 0:Array.size(state) + for i in 0..Array.size(state) if Array.nth(state, i) String.set(out, i, String.nth("#", 0)) else @@ -27,11 +27,11 @@ func main[] : I64 let SIZE: I64 = 60 let state: Array = [] - for i in 0:SIZE + for i in 0..SIZE Array.push(state, false) Array.push(state, true) print(to_str(state)) - for i in 0:SIZE + for i in 0..SIZE state = rule110_step(state) print(to_str(state)) \ No newline at end of file diff --git a/src/codegen_x86_64.rs b/src/codegen_x86_64.rs index b9bc8b7..81336bd 100644 --- a/src/codegen_x86_64.rs +++ b/src/codegen_x86_64.rs @@ -112,7 +112,6 @@ extern strcat extern strcpy extern strdup extern strlcpy -extern puts extern fopen extern fseek extern ftell diff --git a/src/parser.rs b/src/parser.rs index 1c4d677..9f2e69a 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -219,7 +219,7 @@ impl Parser { let var = self.consume(TokenType::Identifier, "expected variable name after 'for'")?; self.consume(TokenType::KeywordIn, "expected 'in' after variable name")?; let start = self.expression()?; - self.consume(TokenType::Colon, "expected ':' after the number")?; + self.consume(TokenType::DoubleDot, "expected '..' after the number")?; let end = self.expression()?; let body = self.block()?; diff --git a/src/std.zr b/src/std.zr index e4ede9c..7badd1a 100644 --- a/src/std.zr +++ b/src/std.zr @@ -21,7 +21,7 @@ func String.concat[a: String, b: String] : String return c func String.find[s: String, needle: U8] : I64 - for i in 0:strlen(s) + for i in 0..strlen(s) if String.nth(s, i) == needle return i return -1 @@ -47,7 +47,7 @@ func String.rev[s: String] : String let len: I64 = strlen(s) let out: String = malloc(len + 1) - for i in 0:len + for i in 0..len String.set(out, i, String.nth(s, len - i - 1)) String.set(out, len, 0) return out @@ -81,7 +81,7 @@ func U8.parse_i64[c: U8]: I64 return c - 48 func I64.to_string[n: I64] : String - let x: I64 = malloc(21) + let x: String = malloc(21) sprintf(x, "%ld", n) return x @@ -112,7 +112,7 @@ func Math.abs[n: I64] : I64 func Math.pow[b: I64, e: I64] : I64 let out: I64 = 1 - for i in 0:e + for i in 0..e out = out * b return out @@ -154,12 +154,12 @@ func Array.new[] : Array func Math.Crypto.rc4[key: String, plaintext: String]: String let S: String = malloc(256) - for i in 0:256 + for i in 0..256 String.set(S, i, i) let j: I64 = 0 let key_len: I64 = strlen(key) - for i in 0:256 + for i in 0..256 j = (j + String.nth(S, i) + String.nth(key, i % key_len)) % 256 let tmp: U8 = String.nth(S, i) String.set(S, i, String.nth(S, j)) @@ -169,7 +169,7 @@ func Math.Crypto.rc4[key: String, plaintext: String]: String j = 0 let plaintext_len: I64 = strlen(plaintext) let ciphertext: String = malloc(plaintext_len+1) - for n in 0:plaintext_len + for n in 0..plaintext_len i = (i + 1) % 256 j = (j + String.nth(S, i)) % 256 diff --git a/src/tokenizer.rs b/src/tokenizer.rs index e0e502b..d670a58 100644 --- a/src/tokenizer.rs +++ b/src/tokenizer.rs @@ -18,6 +18,7 @@ pub enum TokenType { And, Or, Pipe, + DoubleDot, Equal, DoubleEqual, @@ -147,6 +148,13 @@ impl Tokenizer { '%' => self.add_token(TokenType::Mod), '^' => self.add_token(TokenType::Xor), ':' => self.add_token(TokenType::Colon), + '.' => { + if self.match_char('.') { + self.add_token(TokenType::DoubleDot) + } else { + return error!(self.loc, "expected '.' after '.'"); + } + } '/' => { if self.match_char('/') { while !self.eof() && self.peek() != '\n' { @@ -287,7 +295,10 @@ impl Tokenizer { self.advance(); } - if self.peek() == '.' { + if self.peek() == '.' + && (self.current + 1 >= self.source.len()) + && self.source[self.current + 1].is_ascii_digit() + { self.advance(); while self.peek().is_ascii_digit() { self.advance(); diff --git a/test.zr b/test.zr index 095744e..b2a58d9 100644 --- a/test.zr +++ b/test.zr @@ -22,5 +22,5 @@ func main[] : I64 system("cargo build --release") let files: Array = OS.listdir("examples/") - for i in 0:Array.size(files) + for i in 0..Array.size(files) run_test(Array.nth(files, i)) \ No newline at end of file