typecheck chained pointer operations
This commit is contained in:
@@ -8,6 +8,7 @@ use crate::{
|
|||||||
|
|
||||||
struct Var {
|
struct Var {
|
||||||
pub stack_offset: usize,
|
pub stack_offset: usize,
|
||||||
|
#[allow(unused)]
|
||||||
pub var_type: String,
|
pub var_type: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -599,7 +600,7 @@ _builtin_environ:
|
|||||||
ExprKind::MemberAccess { left, field } => {
|
ExprKind::MemberAccess { left, field } => {
|
||||||
emit!(&mut self.output, " push rax");
|
emit!(&mut self.output, " push rax");
|
||||||
|
|
||||||
let offset = self.get_field_offset(env, left, field)?;
|
let offset = self.get_field_offset(left, field)?;
|
||||||
|
|
||||||
self.compile_expr(env, left)?;
|
self.compile_expr(env, left)?;
|
||||||
emit!(&mut self.output, " pop rbx");
|
emit!(&mut self.output, " pop rbx");
|
||||||
@@ -742,7 +743,7 @@ _builtin_environ:
|
|||||||
emit!(&mut self.output, " pop rax");
|
emit!(&mut self.output, " pop rax");
|
||||||
}
|
}
|
||||||
ExprKind::MemberAccess { left, field } => {
|
ExprKind::MemberAccess { left, field } => {
|
||||||
let offset = self.get_field_offset(env, left, field)?;
|
let offset = self.get_field_offset(left, field)?;
|
||||||
self.compile_expr(env, left)?;
|
self.compile_expr(env, left)?;
|
||||||
emit!(&mut self.output, " mov rax, QWORD [rax+{}]", offset);
|
emit!(&mut self.output, " mov rax, QWORD [rax+{}]", offset);
|
||||||
}
|
}
|
||||||
@@ -753,28 +754,10 @@ _builtin_environ:
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_field_offset(
|
fn get_field_offset(&self, left: &Expr, field: &Token) -> Result<usize, ZernError> {
|
||||||
&self,
|
let struct_name = &self.expr_types[&left.id];
|
||||||
env: &mut Env,
|
|
||||||
left: &Expr,
|
|
||||||
field: &Token,
|
|
||||||
) -> Result<usize, ZernError> {
|
|
||||||
let struct_name = match &left.kind {
|
|
||||||
ExprKind::Variable(name) => match env.get_var(&name.lexeme) {
|
|
||||||
Some(v) => v.var_type.clone(),
|
|
||||||
None => {
|
|
||||||
return error!(name.loc, format!("undefined variable: {}", &name.lexeme));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
_ => {
|
|
||||||
return error!(
|
|
||||||
&field.loc,
|
|
||||||
"cannot determine struct type for member assignment"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let fields = match self.symbol_table.structs.get(&struct_name) {
|
let fields = match self.symbol_table.structs.get(struct_name) {
|
||||||
Some(f) => f,
|
Some(f) => f,
|
||||||
None => {
|
None => {
|
||||||
return error!(&field.loc, format!("unknown struct type: {}", struct_name));
|
return error!(&field.loc, format!("unknown struct type: {}", struct_name));
|
||||||
|
|||||||
@@ -55,8 +55,7 @@ func mem._split_block[blk: mem.Block, needed: i64] : void
|
|||||||
new_blk->prev = blk
|
new_blk->prev = blk
|
||||||
|
|
||||||
if blk->next as ptr
|
if blk->next as ptr
|
||||||
let next = blk->next
|
blk->next->prev = new_blk
|
||||||
next->prev = new_blk
|
|
||||||
else
|
else
|
||||||
mem.write64(_builtin_heap_tail(), new_blk)
|
mem.write64(_builtin_heap_tail(), new_blk)
|
||||||
|
|
||||||
@@ -133,8 +132,7 @@ func mem.free[x: any] : void
|
|||||||
blk->size = blk->size + MEM_BLOCK_SIZE + next->size
|
blk->size = blk->size + MEM_BLOCK_SIZE + next->size
|
||||||
blk->next = next->next
|
blk->next = next->next
|
||||||
if next->next as ptr
|
if next->next as ptr
|
||||||
let b = next->next
|
next->next->prev = blk
|
||||||
b->prev = blk
|
|
||||||
if mem.read64(_builtin_heap_tail()) == next as ptr
|
if mem.read64(_builtin_heap_tail()) == next as ptr
|
||||||
mem.write64(_builtin_heap_tail(), blk)
|
mem.write64(_builtin_heap_tail(), blk)
|
||||||
|
|
||||||
@@ -145,8 +143,7 @@ func mem.free[x: any] : void
|
|||||||
prev->size = prev->size + MEM_BLOCK_SIZE + blk->size
|
prev->size = prev->size + MEM_BLOCK_SIZE + blk->size
|
||||||
prev->next = blk->next
|
prev->next = blk->next
|
||||||
if blk->next as ptr
|
if blk->next as ptr
|
||||||
let b = blk->next
|
blk->next->prev = prev
|
||||||
b->prev = prev
|
|
||||||
if mem.read64(_builtin_heap_tail()) == blk as ptr
|
if mem.read64(_builtin_heap_tail()) == blk as ptr
|
||||||
mem.write64(_builtin_heap_tail(), prev)
|
mem.write64(_builtin_heap_tail(), prev)
|
||||||
blk = prev
|
blk = prev
|
||||||
@@ -154,13 +151,11 @@ func mem.free[x: any] : void
|
|||||||
let block_total = blk->size + MEM_BLOCK_SIZE
|
let block_total = blk->size + MEM_BLOCK_SIZE
|
||||||
if (blk as i64 & 4095) == 0 && (block_total & 4095) == 0
|
if (blk as i64 & 4095) == 0 && (block_total & 4095) == 0
|
||||||
if blk->prev as ptr
|
if blk->prev as ptr
|
||||||
let b = blk->prev
|
blk->prev->next = blk->next
|
||||||
b->next = blk->next
|
|
||||||
else
|
else
|
||||||
mem.write64(_builtin_heap_head(), blk->next)
|
mem.write64(_builtin_heap_head(), blk->next)
|
||||||
if blk->next as ptr
|
if blk->next as ptr
|
||||||
let b = blk->next
|
blk->next->prev = blk->prev
|
||||||
b->prev = blk->prev
|
|
||||||
else
|
else
|
||||||
mem.write64(_builtin_heap_tail(), blk->prev)
|
mem.write64(_builtin_heap_tail(), blk->prev)
|
||||||
_builtin_syscall(SYS_munmap, blk, block_total)
|
_builtin_syscall(SYS_munmap, blk, block_total)
|
||||||
@@ -194,8 +189,7 @@ func mem.realloc?[x: ptr, new_size: i64] : ptr
|
|||||||
blk->size = combined
|
blk->size = combined
|
||||||
blk->next = next->next
|
blk->next = next->next
|
||||||
if next->next as ptr
|
if next->next as ptr
|
||||||
let b = next->next
|
next->next->prev = blk
|
||||||
b->prev = blk
|
|
||||||
if mem.read64(_builtin_heap_tail()) == next as ptr
|
if mem.read64(_builtin_heap_tail()) == next as ptr
|
||||||
mem.write64(_builtin_heap_tail(), blk)
|
mem.write64(_builtin_heap_tail(), blk)
|
||||||
mem._split_block(blk, new_size)
|
mem._split_block(blk, new_size)
|
||||||
|
|||||||
Reference in New Issue
Block a user