quicksort example, I64.parse, IO.write_file
This commit is contained in:
152
src/builtin.s
Normal file
152
src/builtin.s
Normal 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
|
||||
@@ -102,6 +102,7 @@ extern realloc
|
||||
extern free
|
||||
extern printf
|
||||
extern sprintf
|
||||
extern strtol
|
||||
extern strlen
|
||||
extern strcmp
|
||||
extern strcat
|
||||
@@ -113,6 +114,8 @@ extern fopen
|
||||
extern fseek
|
||||
extern ftell
|
||||
extern fread
|
||||
extern fwrite
|
||||
extern fclose
|
||||
extern rewind
|
||||
extern system
|
||||
extern opendir
|
||||
@@ -120,156 +123,9 @@ extern readdir
|
||||
extern closedir
|
||||
extern exit
|
||||
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(())
|
||||
}
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@ fn compile_file(path: String) -> Result<(), ZernError> {
|
||||
compile_file_to(&mut codegen, filename, source)?;
|
||||
codegen.emit_epilogue()?;
|
||||
|
||||
// TODO
|
||||
if fs::write("out.s", codegen.get_output()).is_err() {
|
||||
eprintln!("\x1b[91mERROR\x1b[0m: failed to write to out.s");
|
||||
process::exit(1);
|
||||
|
||||
16
src/std.zr
16
src/std.zr
@@ -8,13 +8,13 @@ func print[x: String] : I64
|
||||
func print_i64[x: I64] : I64
|
||||
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)
|
||||
strcpy(c, a)
|
||||
strcat(c, b)
|
||||
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)
|
||||
strlcpy(out, s + start, length + 1)
|
||||
return out
|
||||
@@ -42,8 +42,17 @@ func IO.read_file[path: String]: String
|
||||
|
||||
let n: I64 = fread(buffer, 1, size, file)
|
||||
String.set(buffer, n, 0)
|
||||
fclose(file)
|
||||
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
|
||||
return c - 48
|
||||
|
||||
@@ -52,6 +61,9 @@ func I64.to_string[n: I64] : String
|
||||
sprintf(x, "%ld", n)
|
||||
return x
|
||||
|
||||
func I64.parse[s: String] : I64
|
||||
return strtol(s, 0, 0)
|
||||
|
||||
func Math.gcd[a: I64, b: I64] : I64
|
||||
while b != 0
|
||||
let tmp: I64 = b
|
||||
|
||||
Reference in New Issue
Block a user