analyze externs and catch undefined function calls
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
17
src/std.zr
17
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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user