String.trim
This commit is contained in:
116
src/builtin.s
116
src/builtin.s
@@ -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
|
||||
@@ -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");
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -103,7 +103,6 @@ impl Parser {
|
||||
);
|
||||
}
|
||||
|
||||
// TODO: synchronization after parse error
|
||||
if self.match_token(&[TokenType::KeywordLet]) {
|
||||
self.let_declaration()
|
||||
} else {
|
||||
|
||||
21
src/std.zr
21
src/std.zr
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user