From fdcf7eca375d9ccb9de06a41d3c7cc23025df1c6 Mon Sep 17 00:00:00 2001 From: Toni Date: Fri, 19 Dec 2025 15:55:31 +0100 Subject: [PATCH] analyze externs and catch undefined function calls --- src/analyzer.rs | 18 ++++++++++++------ src/codegen_x86_64.rs | 12 ------------ src/std.zr | 17 ++++++++++++----- 3 files changed, 24 insertions(+), 23 deletions(-) diff --git a/src/analyzer.rs b/src/analyzer.rs index 7dae999..7a4a809 100644 --- a/src/analyzer.rs +++ b/src/analyzer.rs @@ -6,7 +6,7 @@ use crate::{ }; pub struct Analyzer { - pub functions: HashMap, + pub functions: HashMap, } impl Analyzer { @@ -28,7 +28,8 @@ impl Analyzer { if self.functions.contains_key(&name.lexeme) { return error!(name.loc, format!("tried to redefine '{}'", name.lexeme)); } - self.functions.insert(name.lexeme.clone(), params.len()); + self.functions + .insert(name.lexeme.clone(), params.len() as i32); } Ok(()) } @@ -89,7 +90,12 @@ impl Analyzer { } Stmt::Break => {} Stmt::Continue => {} - Stmt::Extern(_) => {} + Stmt::Extern(name) => { + if self.functions.contains_key(&name.lexeme) { + return error!(name.loc, format!("tried to redefine '{}'", name.lexeme)); + } + self.functions.insert(name.lexeme.clone(), -1); + } } Ok(()) } @@ -120,14 +126,14 @@ impl Analyzer { }; if let Some(arity) = self.functions.get(&callee) { - if *arity != args.len() { + if *arity >= 0 && *arity != args.len() as i32 { return error!( &paren.loc, format!("expected {} arguments, got {}", arity, args.len()) ); } - } else { - // TODO: cant error here since we dont analyze externs/builtins YET + } else if !callee.starts_with("_builtin_") { + return error!(&paren.loc, format!("undefined function: {}", callee)); } for arg in args { diff --git a/src/codegen_x86_64.rs b/src/codegen_x86_64.rs index d92799e..109d9c3 100644 --- a/src/codegen_x86_64.rs +++ b/src/codegen_x86_64.rs @@ -100,18 +100,6 @@ impl CodegenX86_64 { "section .note.GNU-stack db 0 -section .text -" - ); - - for name in &["malloc", "realloc", "free", "gethostbyname"] { - emit!(&mut self.output, "extern {}", name); - emit!(&mut self.output, "c.{} equ {}", name, name); - } - - emit!( - &mut self.output, - " section .text._builtin_read8 _builtin_read8: xor rax, rax diff --git a/src/std.zr b/src/std.zr index ba1bb28..76f68d5 100644 --- a/src/std.zr +++ b/src/std.zr @@ -1,13 +1,18 @@ +extern malloc +extern realloc +extern free +extern gethostbyname + func dbg.panic[msg: String] : Void io.print("PANIC: ") io.println(msg) os.exit(1) func mem.alloc[x: I64] : Ptr - return c.malloc(x) + return malloc(x) func mem.free[x: Ptr] : Void - c.free(x) + free(x) func mem.zero[x: I64, size: I64] : Void for i in 0..size @@ -357,9 +362,11 @@ func array.new[] : Array return arr 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 array.nth_unchecked(xs, n) + +func array.nth_unchecked[xs: Array, n: I64] : I64 let data: Ptr = mem.read64(xs) return mem.read64(data + n * 8) @@ -376,7 +383,7 @@ func array.push[xs: Array, x: I64] : Void let new_capacity: I64 = 4 if capacity != 0 new_capacity = capacity * 2 - let new_data: Ptr = c.realloc(data, new_capacity * 8) + let new_data: Ptr = realloc(data, new_capacity * 8) mem.write64(xs, new_data) mem.write64(xs + 8, new_capacity) data = new_data @@ -514,7 +521,7 @@ func net.listen[port: I64] : I64 return s func net.connect[host: String, port: I64] : I64 - let he: Ptr = c.gethostbyname(host) + let he: Ptr = gethostbyname(host) if he == 0 return -1