analyze externs and catch undefined function calls

This commit is contained in:
2025-12-19 15:55:31 +01:00
parent fbf28748c7
commit fdcf7eca37
3 changed files with 24 additions and 23 deletions

View File

@@ -6,7 +6,7 @@ use crate::{
};
pub struct Analyzer {
pub functions: HashMap<String, usize>,
pub functions: HashMap<String, i32>,
}
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 {

View File

@@ -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

View File

@@ -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