String.trim

This commit is contained in:
2025-06-10 17:37:02 +02:00
parent 252efd914e
commit de65f383b3
10 changed files with 154 additions and 138 deletions

View File

@@ -1,116 +0,0 @@
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
.OS.listdir.1:
mov rdi, r14
call readdir
test rax, rax
je .OS.listdir.3
cmp byte [rax+19], 46
jne .OS.listdir.2
movzx ecx, byte [rax+20]
test ecx, ecx
je .OS.listdir.1
cmp ecx, 46
jne .OS.listdir.2
cmp byte [rax+21], 0
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 .OS.listdir.1
.OS.listdir.3:
mov rdi, r14
call closedir
mov rax, rbx
add rsp, 8
pop rbx
pop r14
ret
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 .Array.push.1
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]
.Array.push.1:
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

View File

@@ -95,7 +95,9 @@ impl CodegenX86_64 {
pub fn emit_prologue(&mut self) -> Result<(), ZernError> {
emit!(
&mut self.output,
"
"section .note.GNU-stack
db 0
section .text
extern malloc
extern calloc
@@ -124,15 +126,125 @@ extern readdir
extern closedir
extern exit
extern gettimeofday
",
);
emit!(&mut self.output, "{}", include_str!("builtin.s"));
Ok(())
}
pub fn emit_epilogue(&mut self) -> Result<(), ZernError> {
emit!(&mut self.output, "section .note.GNU-stack");
emit!(&mut self.output, " db 0");
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
.OS.listdir.1:
mov rdi, r14
call readdir
test rax, rax
je .OS.listdir.3
cmp byte [rax+19], 46
jne .OS.listdir.2
movzx ecx, byte [rax+20]
test ecx, ecx
je .OS.listdir.1
cmp ecx, 46
jne .OS.listdir.2
cmp byte [rax+21], 0
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 .OS.listdir.1
.OS.listdir.3:
mov rdi, r14
call closedir
mov rax, rbx
add rsp, 8
pop rbx
pop r14
ret
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 .Array.push.1
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]
.Array.push.1:
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
"
);
Ok(())
}
@@ -220,8 +332,9 @@ extern gettimeofday
self.compile_stmt(env, *body)?;
// TODO: default exit code only for main
emit!(&mut self.output, " mov rax, 0");
if name.lexeme == "main" {
emit!(&mut self.output, " mov rax, 0");
}
emit!(&mut self.output, " mov rsp, rbp");
emit!(&mut self.output, " pop rbp");

View File

@@ -42,7 +42,6 @@ fn compile_file(path: String) -> Result<(), ZernError> {
codegen.emit_prologue()?;
compile_file_to(&mut codegen, "std.zr", include_str!("std.zr").into())?;
compile_file_to(&mut codegen, filename, source)?;
codegen.emit_epilogue()?;
// TODO
if fs::write("out.s", codegen.get_output()).is_err() {

View File

@@ -103,7 +103,6 @@ impl Parser {
);
}
// TODO: synchronization after parse error
if self.match_token(&[TokenType::KeywordLet]) {
self.let_declaration()
} else {

View File

@@ -1,12 +1,18 @@
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: Char] : Bool
return c == 10 || c == 32 || c == 13 || c == 9
func String.concat[a: String, b: String] : String
let c: String = malloc(strlen(a) + strlen(b) + 1)
@@ -19,6 +25,18 @@ func String.substr[s: String, start: I64, length: I64] : String
strlcpy(out, s + start, length + 1)
return out
func String.trim[s: String] : String
let start: I64 = 0
let end: I64 = strlen(s) - 1
while start <= end && String.is_whitespace(String.nth(s, start))
start = start + 1
while end >= start && String.is_whitespace(String.nth(s, end))
end = end - 1
return String.substr(s, start, end - start + 1)
func String.rev[s: String] : String
let len: I64 = strlen(s)
let out: String = malloc(len + 1)
@@ -52,8 +70,9 @@ func IO.write_file[path: String, content: String] : I64
fwrite(content, 1, strlen(content), file)
fclose(file)
return 0
func Char.to_i64[c: Char]: I64
func Char.parse_i64[c: Char]: I64
return c - 48
func I64.to_string[n: I64] : String