quicksort example, I64.parse, IO.write_file

This commit is contained in:
2025-06-03 16:10:06 +02:00
parent d8f2ff28db
commit c3badb609c
9 changed files with 222 additions and 155 deletions

View File

@@ -1,5 +1,5 @@
func main[] : I64 func main[] : I64
37107287533 + 46376937677 + 74324986199 + 91942213363 + 23067588207 + 89261670696 + 28112879812 + 44274228917 + 47451445736 + 70386486105 + 62176457141 + 64906352462 + 92575867718 + 58203565325 + 80181199384 + 35398664372 + 86515506006 + 71693888707 + 54370070576 + 53282654108 + 36123272525 + 45876576172 + 17423706905 + 81142660418 + 51934325451 + 62467221648 + 15732444386 + 55037687525 + 18336384825 + 80386287592 + 78182833757 + 16726320100 + 48403098129 + 87086987551 + 59959406895 + 69793950679 + 41052684708 + 65378607361 + 35829035317 + 94953759765 + 88902802571 + 25267680276 + 36270218540 + 24074486908 + 91430288197 + 34413065578 + 23053081172 + 11487696932 + 63783299490 + 67720186971 + 95548255300 + 76085327132 + 37774242535 + 23701913275 + 29798860272 + 18495701454 + 38298203783 + 34829543829 + 40957953066 + 29746152185 + 41698116222 + 62467957194 + 23189706772 + 86188088225 + 11306739708 + 82959174767 + 97623331044 + 42846280183 + 55121603546 + 32238195734 + 75506164965 + 62177842752 + 32924185707 + 99518671430 + 73267460800 + 76841822524 + 97142617910 + 87783646182 + 10848802521 + 71329612474 + 62184073572 + 66627891981 + 60661826293 + 85786944089 + 66024396409 + 64913982680 + 16730939319 + 94809377245 + 78639167021 + 15368713711 + 40789923115 + 44889911501 + 41503128880 + 81234880673 + 82616570773 + 22918802058 + 77158542502 + 72107838435 + 20849603980 + 53503534226 37107287533 + 46376937677 + 74324986199 + 91942213363 + 23067588207 + 89261670696 + 28112879812 + 44274228917 + 47451445736 + 70386486105 + 62176457141 + 64906352462 + 92575867718 + 58203565325 + 80181199384 + 35398664372 + 86515506006 + 71693888707 + 54370070576 + 53282654108 + 36123272525 + 45876576172 + 17423706905 + 81142660418 + 51934325451 + 62467221648 + 15732444386 + 55037687525 + 18336384825 + 80386287592 + 78182833757 + 16726320100 + 48403098129 + 87086987551 + 59959406895 + 69793950679 + 41052684708 + 65378607361 + 35829035317 + 94953759765 + 88902802571 + 25267680276 + 36270218540 + 24074486908 + 91430288197 + 34413065578 + 23053081172 + 11487696932 + 63783299490 + 67720186971 + 95548255300 + 76085327132 + 37774242535 + 23701913275 + 29798860272 + 18495701454 + 38298203783 + 34829543829 + 40957953066 + 29746152185 + 41698116222 + 62467957194 + 23189706772 + 86188088225 + 11306739708 + 82959174767 + 97623331044 + 42846280183 + 55121603546 + 32238195734 + 75506164965 + 62177842752 + 32924185707 + 99518671430 + 73267460800 + 76841822524 + 97142617910 + 87783646182 + 10848802521 + 71329612474 + 62184073572 + 66627891981 + 60661826293 + 85786944089 + 66024396409 + 64913982680 + 16730939319 + 94809377245 + 78639167021 + 15368713711 + 40789923115 + 44889911501 + 41503128880 + 81234880673 + 82616570773 + 22918802058 + 77158542502 + 72107838435 + 20849603980 + 53503534226
|> I64.to_string() |> I64.to_string()
|> substr(0, 10) |> String.substr(0, 10)
|> print() |> print()

46
examples/quicksort.zr Normal file
View File

@@ -0,0 +1,46 @@
func quicksort[arr: Array] : I64
do_quicksort(arr, 0, Array.size(arr)-1)
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)
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
if Array.nth(arr, j) <= pivot
i = i + 1
let temp: I64 = Array.nth(arr, i)
Array.set(arr, i, Array.nth(arr, j))
Array.set(arr, j, temp)
let temp: I64 = Array.nth(arr, i + 1)
Array.set(arr, i + 1, Array.nth(arr, high))
Array.set(arr, high, temp)
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)
for i in 0:Array.size(arr)
print_i64(Array.nth(arr, i))
print("------------")
quicksort(arr)
for i in 0:Array.size(arr)
print_i64(Array.nth(arr, i))

View File

@@ -19,9 +19,9 @@ func to_str[state: Array]: String
let o: String = "" let o: String = ""
for i in 0:Array.size(state) for i in 0:Array.size(state)
if Array.nth(state, i) if Array.nth(state, i)
o = concat(o, "#") o = String.concat(o, "#")
else else
o = concat(o, " ") o = String.concat(o, " ")
return o return o
func main[] : I64 func main[] : I64

View File

@@ -1,7 +1,7 @@
func main[] : I64 func main[] : I64
let a: String = I64.to_string(58394) let a: String = I64.to_string(58394)
print_i64(strlen(a)) print_i64(strlen(a))
let b: String = concat(a, "test") let b: String = String.concat(a, "test")
print_i64(strlen(b)) print_i64(strlen(b))
free(a) free(a)
free(b) free(b)

152
src/builtin.s Normal file
View File

@@ -0,0 +1,152 @@
String.nth:
movzx rax, byte [rdi + rsi]
ret
String.set:
mov [rdi + rsi], dl
ret
OS.time:
push rbx
sub rsp, 16
mov rbx, rsp
mov rdi, rbx
xor esi, esi
call gettimeofday
imul rcx, qword [rbx], 1000
mov rax, qword [rbx+8]
mov esi, 1000
cqo
idiv rsi
add rax, rcx
add rsp, 16
pop rbx
ret
OS.listdir:
push r14
push rbx
push rax
mov r14, rdi
call Array.new
mov rbx, rax
mov rdi, r14
call opendir
mov r14, rax
.LBB5_1:
mov rdi, r14
call readdir
test rax, rax
je .LBB5_7
cmp byte [rax+19], 46
jne .LBB5_6
movzx ecx, byte [rax+20]
test ecx, ecx
je .LBB5_1
cmp ecx, 46
jne .LBB5_6
cmp byte [rax+21], 0
je .LBB5_1
.LBB5_6:
add rax, 19
mov rdi, rax
call strdup
mov rsi, rax
mov rdi, rbx
call Array.push
jmp .LBB5_1
.LBB5_7:
mov rdi, r14
call closedir
mov rax, rbx
add rsp, 8
pop rbx
pop r14
ret
Array.new:
mov rdi, 1
mov rsi, 24
jmp calloc
Array.nth:
mov rax, [rdi]
mov rax, [rax + rsi*8]
ret
Array.set:
mov rax, [rdi]
mov [rax + rsi*8], rdx
ret
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 .no_realloc
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]
.no_realloc:
mov [rax + rcx*8], r14
inc qword [rbx + 16]
add rsp, 8
pop rbx
pop r14
ret
Array.size:
mov rax, [rdi + 16]
ret
Array.free:
push rbx
mov rbx, rdi
mov rdi, [rdi]
call 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

View File

@@ -102,6 +102,7 @@ extern realloc
extern free extern free
extern printf extern printf
extern sprintf extern sprintf
extern strtol
extern strlen extern strlen
extern strcmp extern strcmp
extern strcat extern strcat
@@ -113,6 +114,8 @@ extern fopen
extern fseek extern fseek
extern ftell extern ftell
extern fread extern fread
extern fwrite
extern fclose
extern rewind extern rewind
extern system extern system
extern opendir extern opendir
@@ -120,156 +123,9 @@ extern readdir
extern closedir extern closedir
extern exit extern exit
extern gettimeofday extern gettimeofday
String.nth:
movzx rax, byte [rdi + rsi]
ret
String.set:
mov [rdi + rsi], dl
ret
OS.time:
push rbx
sub rsp, 16
mov rbx, rsp
mov rdi, rbx
xor esi, esi
call gettimeofday
imul rcx, qword [rbx], 1000
mov rax, qword [rbx+8]
mov esi, 1000
cqo
idiv rsi
add rax, rcx
add rsp, 16
pop rbx
ret
OS.listdir:
push r14
push rbx
push rax
mov r14, rdi
call Array.new
mov rbx, rax
mov rdi, r14
call opendir
mov r14, rax
.LBB5_1:
mov rdi, r14
call readdir
test rax, rax
je .LBB5_7
cmp byte [rax+19], 46
jne .LBB5_6
movzx ecx, byte [rax+20]
test ecx, ecx
je .LBB5_1
cmp ecx, 46
jne .LBB5_6
cmp byte [rax+21], 0
je .LBB5_1
.LBB5_6:
add rax, 19
mov rdi, rax
call strdup
mov rsi, rax
mov rdi, rbx
call Array.push
jmp .LBB5_1
.LBB5_7:
mov rdi, r14
call closedir
mov rax, rbx
add rsp, 8
pop rbx
pop r14
ret
Array.new:
mov rdi, 1
mov rsi, 24
jmp calloc
Array.nth:
mov rax, [rdi]
mov rax, [rax + rsi*8]
ret
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 .no_realloc
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]
.no_realloc:
mov [rax + rcx*8], r14
inc qword [rbx + 16]
add rsp, 8
pop rbx
pop r14
ret
Array.size:
mov rax, [rdi + 16]
ret
Array.free:
push rbx
mov rbx, rdi
mov rdi, [rdi]
call 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
", ",
); );
emit!(&mut self.output, "{}", include_str!("builtin.s"));
Ok(()) Ok(())
} }

View File

@@ -44,6 +44,7 @@ fn compile_file(path: String) -> Result<(), ZernError> {
compile_file_to(&mut codegen, filename, source)?; compile_file_to(&mut codegen, filename, source)?;
codegen.emit_epilogue()?; codegen.emit_epilogue()?;
// TODO
if fs::write("out.s", codegen.get_output()).is_err() { if fs::write("out.s", codegen.get_output()).is_err() {
eprintln!("\x1b[91mERROR\x1b[0m: failed to write to out.s"); eprintln!("\x1b[91mERROR\x1b[0m: failed to write to out.s");
process::exit(1); process::exit(1);

View File

@@ -8,13 +8,13 @@ func print[x: String] : I64
func print_i64[x: I64] : I64 func print_i64[x: I64] : I64
printf("%ld\n", x) printf("%ld\n", x)
func concat[a: String, b: String] : String func String.concat[a: String, b: String] : String
let c: String = malloc(strlen(a) + strlen(b) + 1) let c: String = malloc(strlen(a) + strlen(b) + 1)
strcpy(c, a) strcpy(c, a)
strcat(c, b) strcat(c, b)
return c return c
func substr[s: String, start: I64, length: I64] : String func String.substr[s: String, start: I64, length: I64] : String
let out: String = malloc(length + 1) let out: String = malloc(length + 1)
strlcpy(out, s + start, length + 1) strlcpy(out, s + start, length + 1)
return out return out
@@ -42,8 +42,17 @@ func IO.read_file[path: String]: String
let n: I64 = fread(buffer, 1, size, file) let n: I64 = fread(buffer, 1, size, file)
String.set(buffer, n, 0) String.set(buffer, n, 0)
fclose(file)
return buffer return buffer
func IO.write_file[path: String, content: String] : I64
let file: Ptr = fopen(path, "wb")
if !file
panic("failed to open file")
fwrite(content, 1, strlen(content), file)
fclose(file)
func Char.to_i64[c: Char]: I64 func Char.to_i64[c: Char]: I64
return c - 48 return c - 48
@@ -52,6 +61,9 @@ func I64.to_string[n: I64] : String
sprintf(x, "%ld", n) sprintf(x, "%ld", n)
return x return x
func I64.parse[s: String] : I64
return strtol(s, 0, 0)
func Math.gcd[a: I64, b: I64] : I64 func Math.gcd[a: I64, b: I64] : I64
while b != 0 while b != 0
let tmp: I64 = b let tmp: I64 = b

View File

@@ -1,6 +1,6 @@
func run_test[x: String] : I64 func run_test[x: String] : I64
printf("\033[93mBuilding %s...\033[0m", x) printf("\033[93mBuilding %s...\033[0m", x)
let cmd: String = concat("./target/release/zern examples/", x) let cmd: String = String.concat("./target/release/zern examples/", x)
let build_start_time: I64 = OS.time() let build_start_time: I64 = OS.time()
if system(cmd) != 0 if system(cmd) != 0