diff --git a/examples/brainfuck.zr b/examples/brainfuck.zr index f1175e2..03a1f00 100644 --- a/examples/brainfuck.zr +++ b/examples/brainfuck.zr @@ -15,15 +15,15 @@ func main[] : I64 else if op == '<' p = p - 1 else if op == '+' - str.set(memory, p, str.nth(memory, p)+1) + str.set(memory, p, mem.read8(memory + p)+1) else if op == '-' - str.set(memory, p, str.nth(memory, p)-1) + str.set(memory, p, mem.read8(memory + p)-1) else if op == '.' - c.printf("%c", str.nth(memory, p)) + c.printf("%c", mem.read8(memory + p)) else if op == ',' str.set(memory, p, c.getchar()) else if op == '[' - if !str.nth(memory, p) + if !mem.read8(memory + p) i = i + 1 let opened: I64 = 0 while i < src_len & !(str.nth(src, i) == ']' & !opened) @@ -33,7 +33,7 @@ func main[] : I64 opened = opened - 1 i = i + 1 else if op == ']' - if str.nth(memory, p) + if mem.read8(memory + p) i = i - 1 let closed: I64 = 0 while i >= 0 & !(str.nth(src, i) == '[' & !closed) diff --git a/examples/curl.zr b/examples/curl.zr index 280fe9d..e361fdb 100644 --- a/examples/curl.zr +++ b/examples/curl.zr @@ -2,7 +2,7 @@ func main[argc: I64, argv: Ptr] : I64 if argc < 2 dbg.panic("url missing") - let url: String = mem.deref64(argv + 8) + let url: String = mem.read64(argv + 8) if c.strncmp(url, "http://", 7) != 0 dbg.panic("invalid url scheme") @@ -29,7 +29,7 @@ func main[argc: I64, argv: Ptr] : I64 c.send(s, req, str.len(req), 0) mem.free(req) - let header_buf: Ptr = mem.alloc(8192) + let header_buf: String = mem.alloc(8192) let header_size: I64 = 0 let found: Bool = false let end_index: I64 = -1 @@ -41,8 +41,7 @@ func main[argc: I64, argv: Ptr] : I64 let current_size: I64 = header_size + n i = 0 while i <= current_size - 4 - let p: Ptr = header_buf + i - if str.nth(p, 0) == 13 & str.nth(p, 1) == 10 & str.nth(p, 2) == 13 & str.nth(p, 3) == 10 + if str.nth(header_buf, i) == 13 & str.nth(header_buf, i+1) == 10 & str.nth(header_buf, i+2) == 13 & str.nth(header_buf, i+3) == 10 found = true end_index = i + 4 break diff --git a/src/codegen_x86_64.rs b/src/codegen_x86_64.rs index 7f6b7cd..acb5f4a 100644 --- a/src/codegen_x86_64.rs +++ b/src/codegen_x86_64.rs @@ -112,14 +112,14 @@ section .text emit!( &mut self.output, " -section .text._builtin_deref8 -_builtin_deref8: +section .text._builtin_read8 +_builtin_read8: xor rax, rax mov al, byte [rdi] ret -section .text._builtin_deref64 -_builtin_deref64: +section .text._builtin_read64 +_builtin_read64: mov rax, qword [rdi] ret diff --git a/src/main.rs b/src/main.rs index b95b344..d33a759 100644 --- a/src/main.rs +++ b/src/main.rs @@ -82,6 +82,15 @@ fn compile_file(args: Args) -> Result<(), ZernError> { "./musl-1.2.4/root/bin/musl-gcc -static -o {} {}.o -flto -Wl,--gc-sections {}", args.out, args.out, args.cflags )); + + if args.run_exe { + run_command( + std::fs::canonicalize(args.out) + .unwrap() + .to_string_lossy() + .into_owned(), + ); + } } else { fs::write(&args.out, codegen.get_output()).unwrap(); } @@ -100,6 +109,9 @@ struct Args { #[arg(short = 'S', help = "Only generate assembly")] output_asm: bool, + #[arg(short = 'r', help = "Run the compiled executable")] + run_exe: bool, + #[arg(short = 'C', default_value = "", help = "Extra flags to pass to gcc")] cflags: String, } diff --git a/src/std.zr b/src/std.zr index 56eaec7..a3fa293 100644 --- a/src/std.zr +++ b/src/std.zr @@ -5,14 +5,14 @@ func dbg.panic[msg: String] : Void func mem.alloc[x: I64] : Ptr return c.malloc(x) -func mem.free[x: I64] : Ptr - return c.free(x) +func mem.free[x: Ptr] : Void + c.free(x) -func mem.deref8[x: Ptr] : I64 - return _builtin_deref8(x) +func mem.read8[x: Ptr] : U8 + return _builtin_read8(x) -func mem.deref64[x: Ptr] : I64 - return _builtin_deref64(x) +func mem.read64[x: Ptr] : I64 + return _builtin_read64(x) func io.print[x: String] : Void c.puts(x) @@ -37,6 +37,7 @@ func io.read_file[path: String]: String let buffer: String = mem.alloc(size + 1) + // TODO: check if works with huge files let n: I64 = c.fread(buffer, 1, size, file) str.set(buffer, n, 0) c.fclose(file) @@ -54,7 +55,7 @@ func str.len[s: String] : I64 return c.strlen(s) func str.nth[s: String, n: I64] : U8 - return mem.deref8(s + n) + return mem.read8(s + n) func str.set[s: String, n: I64, c: U8] : Void _builtin_set8(s+n, c) @@ -80,7 +81,7 @@ func str.find[s: String, c: U8] : I64 func str.substr[s: String, start: I64, length: I64] : String if start < 0 | length < 0 | start + length > str.len(s) - dbg.panic("String.substr out of bounds") + dbg.panic("str.substr out of bounds") let out: String = mem.alloc(length + 1) c.strncpy(out, s + start, length) @@ -251,7 +252,7 @@ func math.urandom[]: I64 let file: Ptr = c.fopen("/dev/urandom", "rb") c.fread(buffer, 8, 1, file) c.fclose(file) - let n: I64 = mem.deref64(buffer) + let n: I64 = mem.read64(buffer) mem.free(buffer) return n @@ -259,16 +260,19 @@ func array.new[] : Array return c.calloc(1, 24) func array.nth[xs: Array, n: I64] : I64 + // this probably should be implemented in the codegen + if n < 0 | n >= array.size(xs) + dbg.panic("array.nth out of bounds") return xs[n] func array.set[xs: Array, n: I64, x: I64] : Void - let data: Ptr = mem.deref64(xs) + let data: Ptr = mem.read64(xs) _builtin_set64(data+n*8, x) func array.push[xs: Array, x: I64] : Void - let data: Ptr = mem.deref64(xs) - let capacity: I64 = mem.deref64(xs+8) - let size: I64 = mem.deref64(xs+16) + let data: Ptr = mem.read64(xs) + let capacity: I64 = mem.read64(xs+8) + let size: I64 = mem.read64(xs+16) if size == capacity let new_capacity: I64 = 4 @@ -283,17 +287,17 @@ func array.push[xs: Array, x: I64] : Void _builtin_set64(xs+16, size + 1) func array.size[xs: Array] : I64 - return mem.deref64(xs+16) + return mem.read64(xs+16) func array.free[xs: Array] : Void - mem.free(mem.deref64(xs)) + mem.free(mem.read64(xs)) mem.free(xs) func os.time[] : I64 let tv: Ptr = mem.alloc(16) c.gettimeofday(tv, 0) - let seconds: I64 = mem.deref64(tv) - let microseconds: I64 = mem.deref64(tv+8) + let seconds: I64 = mem.read64(tv) + let microseconds: I64 = mem.read64(tv+8) mem.free(tv) return seconds * 1000 + microseconds / 1000 @@ -307,11 +311,11 @@ func os.listdir[path: String] : Array break let skip: Bool = false - if str.nth(entry, 19) == '.' - if str.nth(entry, 20) == 0 + if mem.read8(entry + 19) == '.' + if mem.read8(entry + 20) == 0 skip = true - else if str.nth(entry, 20) == '.' - if str.nth(entry, 21) == 0 + else if mem.read8(entry + 20) == '.' + if mem.read8(entry + 21) == 0 skip = true if !skip @@ -346,7 +350,7 @@ func net.connect[host: String, port: I64] : I64 if he == 0 return -1 - let ip_ptr: Ptr = mem.deref64(mem.deref64(he + 24)) + let ip_ptr: Ptr = mem.read64(mem.read64(he + 24)) let s: I64 = c.socket(2, 1, 0) if s < 0 @@ -356,10 +360,10 @@ func net.connect[host: String, port: I64] : I64 str.set(sa, 0, 2) str.set(sa, 2, (port >> 8) & 255) str.set(sa, 3, port & 255) - str.set(sa, 4, mem.deref8(ip_ptr + 0)) - str.set(sa, 5, mem.deref8(ip_ptr + 1)) - str.set(sa, 6, mem.deref8(ip_ptr + 2)) - str.set(sa, 7, mem.deref8(ip_ptr + 3)) + str.set(sa, 4, mem.read8(ip_ptr + 0)) + str.set(sa, 5, mem.read8(ip_ptr + 1)) + str.set(sa, 6, mem.read8(ip_ptr + 2)) + str.set(sa, 7, mem.read8(ip_ptr + 3)) if c.connect(s, sa, 16) < 0 mem.free(sa) diff --git a/test.zr b/test.zr index f071851..7892957 100644 --- a/test.zr +++ b/test.zr @@ -15,7 +15,7 @@ func run_test[x: String] : Void else let run_start_time: I64 = os.time() if str.equal(x, "curl.zr") - if c.system("./out http://devernay.free.fr/hacks/chip8/C8TECH10.HTM") != 0 + if c.system("./out http://example.com") != 0 c.exit(1) else if c.system("./out") != 0