diff --git a/examples/raylib.zr b/examples/raylib.zr index c7b7330..09e1415 100644 --- a/examples/raylib.zr +++ b/examples/raylib.zr @@ -1,16 +1,16 @@ // needs to be compiled with -m -C="/usr/local/lib/libraylib.a -lm" -func main[] : I64 - extern InitWindow - extern SetTargetFPS - extern WindowShouldClose - extern BeginDrawing - extern EndDrawing - extern ClearBackground - extern CloseWindow - extern DrawRectangle - extern IsKeyDown +extern InitWindow +extern SetTargetFPS +extern WindowShouldClose +extern BeginDrawing +extern EndDrawing +extern ClearBackground +extern CloseWindow +extern DrawRectangle +extern IsKeyDown +func main[] : I64 let x: I64 = 200 let y: I64 = 200 diff --git a/examples/sqlite_todo.zr b/examples/sqlite_todo.zr index ec8a67f..b109d4b 100644 --- a/examples/sqlite_todo.zr +++ b/examples/sqlite_todo.zr @@ -1,14 +1,13 @@ // needs to be compiled with -m -C="-lsqlite3" +extern sqlite3_open +extern sqlite3_exec +extern sqlite3_prepare_v2 +extern sqlite3_bind_text +extern sqlite3_step +extern sqlite3_errmsg +extern sqlite3_finalize func main[] : I64 - extern sqlite3_open - extern sqlite3_exec - extern sqlite3_prepare_v2 - extern sqlite3_bind_text - extern sqlite3_step - extern sqlite3_errmsg - extern sqlite3_finalize - let rc: I64 = 0 let db: Ptr = mem.alloc(8) let stmt: Ptr = mem.alloc(8) diff --git a/examples/x11.zr b/examples/x11.zr index 38dbc7c..fd90418 100644 --- a/examples/x11.zr +++ b/examples/x11.zr @@ -1,18 +1,18 @@ // needs to be compiled with -m -C="-lX11" +extern XOpenDisplay +extern XDefaultRootWindow +extern XCreateSimpleWindow +extern XMapWindow +extern XSelectInput +extern XNextEvent +extern XBlackPixel +extern XWhitePixel +extern XSetForeground +extern XCreateGC +extern XDefaultScreen +extern XDrawString func main[] : I64 - extern XOpenDisplay - extern XDefaultRootWindow - extern XCreateSimpleWindow - extern XMapWindow - extern XSelectInput - extern XNextEvent - extern XBlackPixel - extern XWhitePixel - extern XSetForeground - extern XCreateGC - extern XDefaultScreen - extern XDrawString let dpy: Ptr = XOpenDisplay(0) let screen: Ptr = XDefaultScreen(dpy) diff --git a/src/codegen_x86_64.rs b/src/codegen_x86_64.rs index f84b15e..7e2848a 100644 --- a/src/codegen_x86_64.rs +++ b/src/codegen_x86_64.rs @@ -6,7 +6,6 @@ use crate::{ }; pub struct Var { - // pub var_type: String, pub stack_offset: usize, } @@ -105,7 +104,7 @@ section .text " ); - for name in &["malloc", "realloc", "free", "system", "gethostbyname"] { + for name in &["malloc", "realloc", "free", "gethostbyname"] { emit!(&mut self.output, "extern {}", name); emit!(&mut self.output, "c.{} equ {}", name, name); } @@ -156,6 +155,12 @@ _builtin_syscall: mov r9, [rsp+8] syscall ret + +section .text._builtin_environ +_builtin_environ: + extern environ + mov rax, [rel environ] + ret " ); Ok(()) @@ -303,7 +308,7 @@ _builtin_syscall: emit!(&mut self.output, " jmp {}", env.loop_begin_label); } Stmt::Extern(name) => { - emit!(&mut self.output, " extern {}", name.lexeme); + emit!(&mut self.output, "extern {}", name.lexeme); } } Ok(()) diff --git a/src/parser.rs b/src/parser.rs index 883bdaa..16f7017 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -103,6 +103,9 @@ impl Parser { if self.match_token(&[TokenType::KeywordFunc]) { return self.func_declaration(); } + if self.match_token(&[TokenType::KeywordExtern]) { + return self.extern_declaration(); + } return error!( self.peek().loc, "statements not allowed outside function body" @@ -175,6 +178,12 @@ impl Parser { }) } + fn extern_declaration(&mut self) -> Result { + Ok(Stmt::Extern( + self.consume(TokenType::Identifier, "expected extern name")?, + )) + } + fn block(&mut self) -> Result { self.consume(TokenType::Indent, "expected an indent")?; @@ -199,10 +208,6 @@ impl Parser { Ok(Stmt::Break) } else if self.match_token(&[TokenType::KeywordContinue]) { Ok(Stmt::Continue) - } else if self.match_token(&[TokenType::KeywordExtern]) { - Ok(Stmt::Extern( - self.consume(TokenType::Identifier, "expected extern name")?, - )) } else { Ok(Stmt::Expression(self.expression()?)) } diff --git a/src/std.zr b/src/std.zr index 62afb46..0d4a898 100644 --- a/src/std.zr +++ b/src/std.zr @@ -430,6 +430,27 @@ func os.time[] : I64 mem.free(tv) return seconds * 1000 + microseconds / 1000 +// voodoo magic +func os.shell[command: String] : I64 + let pid: I64 = _builtin_syscall(57) // fork + if pid == 0 + let argv: Array = ["sh", "-c", command, 0] + _builtin_syscall(59, "/bin/sh", mem.read64(argv), _builtin_environ()) // execve + _builtin_syscall(60, 1) // exit + else + let status: Ptr = mem.alloc(4) + let wp: I64 = _builtin_syscall(61, pid, status, 0, 0) // waitpid + if wp == -1 + mem.free(status) + return -1 + let st: I64 = mem.read32(status) + mem.free(status) + + if (st & 0x7f) == 0 + return (st >> 8) & 0xff + else + return -(st & 0x7f) + func os.listdir[path: String] : Array let fd: I64 = _builtin_syscall(2, path, 0, 0) // open if fd < 0 diff --git a/test.zr b/test.zr index f74ac6d..811ac70 100644 --- a/test.zr +++ b/test.zr @@ -1,5 +1,5 @@ func run_test[x: String] : Void - if str.equal(x, "raylib.zr") | str.equal(x, "x11.zr") + if str.equal(x, "raylib.zr") | str.equal(x, "x11.zr") | str.equal(x, "sqlite_todo.zr") io.print("\033[93mSkipping ") io.print(x) io.println("...\033[0m") @@ -11,7 +11,7 @@ func run_test[x: String] : Void let cmd: String = str.concat("./target/release/zern examples/", x) let build_start_time: I64 = os.time() - if c.system(cmd) != 0 + if os.shell(cmd) != 0 os.exit(1) let build_end_time: I64 = os.time() @@ -31,10 +31,10 @@ func run_test[x: String] : Void let run_start_time: I64 = os.time() if str.equal(x, "curl.zr") - if c.system("./out http://example.com") != 0 + if os.shell("./out http://example.com") != 0 os.exit(1) else - if c.system("./out") != 0 + if os.shell("./out") != 0 os.exit(1) let run_end_time: I64 = os.time() @@ -45,7 +45,7 @@ func run_test[x: String] : Void io.println("ms") func main[] : I64 - c.system("cargo build --release") + os.shell("cargo build --release") let files: Array = os.listdir("examples/") for i in 0..array.size(files)