From a727a52ffbd9d330155bb8200a7b1b2bc94bd0b8 Mon Sep 17 00:00:00 2001 From: Toni Date: Sat, 6 Jun 2026 23:55:02 +0200 Subject: [PATCH] ptr.free --- examples/brainfuck.zr | 2 +- examples/chip8.zr | 26 ++++++++--------- examples/curl.zr | 6 ++-- examples/puzzles/euler_04.zr | 4 +-- src/parser.rs | 4 +++ src/std/net.zr | 38 ++++++++++++------------- src/std/std.zr | 55 +++++++++++++++++++++--------------- src/typechecker.rs | 14 +++------ 8 files changed, 77 insertions(+), 72 deletions(-) diff --git a/examples/brainfuck.zr b/examples/brainfuck.zr index 303044b..4f5d521 100644 --- a/examples/brainfuck.zr +++ b/examples/brainfuck.zr @@ -46,4 +46,4 @@ func main[] : i64 i += 1 - mem.free(memory) + memory->free() diff --git a/examples/chip8.zr b/examples/chip8.zr index 0980782..9770073 100644 --- a/examples/chip8.zr +++ b/examples/chip8.zr @@ -21,8 +21,7 @@ struct CHIP8 display: ptr keyboard_map: Array -func chip8_create[] : CHIP8 - c := new* CHIP8 +func CHIP8.init[c: CHIP8] : void c->memory = mem.alloc(4096) mem.zero(c->memory, 4096) c->display = mem.alloc(64*32) @@ -43,18 +42,16 @@ func chip8_create[] : CHIP8 // see KeyboardKey in raylib.h c->keyboard_map = [49, 50, 51, 52, 53, 265, 32, 263, 264, 262, 87, 69, 82, 84, 89, 85] - return c - -func chip8_free[c: CHIP8] : void - mem.free(c->memory) +func CHIP8.free[c: CHIP8] : void + c->memory->free() c->stack->free() - mem.free(c->reg) + c->reg->free() c->keyboard->free() - mem.free(c->display) + c->display->free() c->keyboard_map->free() - mem.free(c) + (c as ptr)->free() -func chip8_disassemble[c: CHIP8, ins_count: i64] : void +func CHIP8.disassemble[c: CHIP8, ins_count: i64] : void for i in 0..ins_count io.printf("0x%x: ", c->pc) @@ -153,7 +150,7 @@ func chip8_disassemble[c: CHIP8, ins_count: i64] : void else io.printf("??? (%x)\n", ins) -func chip8_step[c: CHIP8] : void +func CHIP8.step[c: CHIP8] : void high := c->memory[c->pc] as i64 low := c->memory[c->pc + 1] as i64 c->pc += 2 @@ -288,7 +285,8 @@ func main[argc: i64, argv: ptr] : i64 io.println("Usage: chip8 -d ") return 1 - c := chip8_create() + c := new CHIP8 + c->init() ~buffer, ok := io.read_binary_file(path) if !ok @@ -298,7 +296,7 @@ func main[argc: i64, argv: ptr] : i64 c->memory[0x200 + i] = buffer->data[i] if disassemble - chip8_disassemble(c, buffer->size / 2) + c->disassemble(buffer->size / 2) return 0 InitWindow(640, 320, "CHIP-8") @@ -312,7 +310,7 @@ func main[argc: i64, argv: ptr] : i64 // TODO: buzzer for i in 0..25 - chip8_step(c) + c->step() BeginDrawing() diff --git a/examples/curl.zr b/examples/curl.zr index 67d5974..1199166 100644 --- a/examples/curl.zr +++ b/examples/curl.zr @@ -41,7 +41,7 @@ func main[argc: i64, argv: ptr] : i64 req->append(host) req->append("\r\nConnection: close\r\n\r\n") net.send(s, req->data, req->size) - mem.free(req->data) + req->destroy() header_buf := mem.alloc(8192) as str header_size := 0 @@ -64,7 +64,7 @@ func main[argc: i64, argv: ptr] : i64 if end_index < header_size io.print_sized(header_buf as ptr + end_index, header_size as i64 - end_index) - mem.free(header_buf) + header_buf->free() buffer := mem.alloc(4096) while true @@ -72,6 +72,6 @@ func main[argc: i64, argv: ptr] : i64 if n <= 0 break io.print_sized(buffer, n) - mem.free(buffer) + buffer->free() net.close(s) diff --git a/examples/puzzles/euler_04.zr b/examples/puzzles/euler_04.zr index 01b4db4..a4c3991 100644 --- a/examples/puzzles/euler_04.zr +++ b/examples/puzzles/euler_04.zr @@ -8,6 +8,6 @@ func main[] : i64 s_rev := s->reverse() if s->equal(s_rev) out = a * b - mem.free(s) - mem.free(s_rev) + s->free() + s_rev->free() io.println_i64(out) diff --git a/src/parser.rs b/src/parser.rs index e9d7c61..c4b8ed7 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -583,6 +583,10 @@ impl Parser { let mut expr = self.primary()?; loop { + if self.peek().loc.line != self.previous().loc.line { + break; + } + if self.match_token(&[TokenType::LeftParen]) { let mut args = vec![]; if !self.check(&TokenType::RightParen) { diff --git a/src/std/net.zr b/src/std/net.zr index cbfd991..0305470 100644 --- a/src/std/net.zr +++ b/src/std/net.zr @@ -78,12 +78,27 @@ struct net.UDPSocket fd: i64 addr: ptr +func net.UDPSocket.receive[s: net.UDPSocket, size: i64] : net.UDPPacket + pkt := new* net.UDPPacket + pkt->data = mem.alloc(size) + pkt->source_addr = mem.alloc(16) + mem.zero(pkt->source_addr, 16) + + addrlen := 16 + pkt->size = _builtin_syscall(SYS_recvfrom, s->fd, pkt->data, size, 0, pkt->source_addr, ^addrlen) + return pkt + +func net.UDPSocket.close_and_free[s: net.UDPSocket] : void + _builtin_syscall(SYS_close, s->fd) + s->addr->free() + (s as ptr)->free() + func net.create_udp_client[packed_host: i64, port: i64] : net.UDPSocket, bool s := new* net.UDPSocket s->fd = _builtin_syscall(SYS_socket, AF_INET, SOCK_DGRAM, 0) if s->fd < 0 - mem.free(s) + s->close_and_free() return 0 as net.UDPSocket, false s->addr = mem.alloc(16) @@ -110,24 +125,9 @@ struct net.UDPPacket size: i64 func net.UDPPacket.free[pkt: net.UDPPacket] : void - mem.free(pkt->data) - mem.free(pkt->source_addr) - mem.free(pkt) - -func net.UDPSocket.receive[s: net.UDPSocket, size: i64] : net.UDPPacket - pkt := new* net.UDPPacket - pkt->data = mem.alloc(size) - pkt->source_addr = mem.alloc(16) - mem.zero(pkt->source_addr, 16) - - addrlen := 16 - pkt->size = _builtin_syscall(SYS_recvfrom, s->fd, pkt->data, size, 0, pkt->source_addr, ^addrlen) - return pkt - -func net.UDPSocket.close_and_free[s: net.UDPSocket] : void - _builtin_syscall(SYS_close, s->fd) - mem.free(s->addr) - mem.free(s) + pkt->data->free() + pkt->source_addr->free() + (pkt as ptr)->free() func net.encode_dns_name[domain: str] : Blob domain_len := domain->len() diff --git a/src/std/std.zr b/src/std/std.zr index d13338e..d082317 100644 --- a/src/std/std.zr +++ b/src/std/std.zr @@ -76,11 +76,11 @@ func mem.alloc[size: i64] : ptr return blk as ptr + MEM_BLOCK_SIZE -func mem.free[x: any] : void +func ptr.free[x: ptr] : void if x == 0 return 0 - blk := (x as ptr - MEM_BLOCK_SIZE) as mem.Block + blk := (x - MEM_BLOCK_SIZE) as mem.Block if blk->free return 0 @@ -129,7 +129,7 @@ func ptr.realloc[x: ptr, new_size: i64] : ptr panic("mem.realloc: called with negative new_size") if new_size == 0 - mem.free(x) + x->free() return 0 as ptr new_size = mem.align(new_size) @@ -157,12 +157,12 @@ func ptr.realloc[x: ptr, new_size: i64] : ptr new_ptr := mem.alloc(new_size) mem.copy(x, new_ptr, math.min(blk->size, new_size)) - mem.free(x) + x->free() return new_ptr -func mem.zero_and_free[x: ptr, size: i64] : void +func ptr.zero_and_free[x: ptr, size: i64] : void mem.zero(x, size) - mem.free(x) + x->free() func mem.zero[x: ptr, size: i64] : void i := 0 @@ -303,7 +303,7 @@ func io.read_line[] : str break b->append_char(c) s := b->build() - mem.free(b->data) + b->destroy() return s func io.file_exists[path: str] : bool @@ -331,7 +331,7 @@ func io.read_text_file[path: str] : str, bool _builtin_syscall(SYS_close, fd) if n != size - mem.free(buffer) + buffer->free() return 0 as str, false buffer[n] = 0 @@ -371,6 +371,9 @@ func io.write_binary_file[path: str, content: ptr, size: i64] : bool return false return true +func str.free[s: str] : void + (s as ptr)->free() + func str.len[s: str] : i64 i := 0 while s[i] @@ -643,6 +646,12 @@ func str.Builder.build[b: str.Builder] : str s[b->size] = 0 return s +func str.Builder.destroy[b: str.Builder] : void + if b->data != 0 + b->data->free() + b->size = 0 + b->capacity = 0 + func u8.is_whitespace[x: u8] : bool return x == ' ' || x == '\n' || x == '\t' || x == '\r' @@ -821,8 +830,8 @@ func Blob.alloc[size: i64] : Blob return buffer func Blob.free[buf: Blob] : void - mem.free(buf->data) - mem.free(buf) + buf->data->free() + (buf as ptr)->free() struct Array data: ptr @@ -861,15 +870,15 @@ func Array.push[xs: Array, x: any] : void func Array.free[xs: Array] : void if xs->data != 0 - mem.free(xs->data) - mem.free(xs) + xs->data->free() + (xs as ptr)->free() func Array.free_with_items[xs: Array] : void if xs->data != 0 for i in 0..xs->size - mem.free(xs->nth(i)) - mem.free(xs->data) - mem.free(xs) + (xs->nth(i) as ptr)->free() + xs->data->free() + (xs as ptr)->free() func Array.pop[xs: Array] : any if xs->size == 0 @@ -922,20 +931,20 @@ func Array.count[arr: Array, item: any] : i64 count += 1 return count -func Array.map[arr: Array, fn: fnptr] : Array +func Array.map[arr: Array, fn: ptr] : Array out := Array.new_preallocated_and_zeroed(arr->size) for i in 0..arr->size out->set(i, fn(arr->nth(i))) return out -func Array.filter[arr: Array, fn: fnptr] : Array +func Array.filter[arr: Array, fn: ptr] : Array out := [] for i in 0..arr->size if fn(arr->nth(i)) out->push(arr->nth(i)) return out -func Array.reduce[arr: Array, fn: fnptr, acc: any] : any +func Array.reduce[arr: Array, fn: ptr, acc: any] : any for i in 0..arr->size acc = fn(acc, arr->nth(i)) return acc @@ -994,8 +1003,8 @@ func HashMap.delete[map: HashMap, key: str] : void else map->table->set(index, current->next) - mem.free(current->key) - mem.free(current) + current->key->free() + (current as ptr)->free() return 0 prev = current @@ -1014,11 +1023,11 @@ func HashMap.free[map: HashMap] : void while current as ptr tmp := current current = current->next - mem.free(tmp->key) - mem.free(tmp) + tmp->key->free() + (tmp as ptr)->free() map->table->free() - mem.free(map) + (map as ptr)->free() func os.exit[code: i64] : void _builtin_syscall(SYS_exit, code) diff --git a/src/typechecker.rs b/src/typechecker.rs index c91968d..44fe3ed 100644 --- a/src/typechecker.rs +++ b/src/typechecker.rs @@ -33,7 +33,7 @@ macro_rules! expect_types { }; } -static BUILTIN_TYPES: [&str; 8] = ["void", "u8", "i64", "str", "bool", "ptr", "fnptr", "any"]; +static BUILTIN_TYPES: [&str; 7] = ["void", "u8", "i64", "str", "bool", "ptr", "any"]; pub struct Env { scopes: Vec>, @@ -481,7 +481,7 @@ impl<'a> TypeChecker<'a> { Ok(fn_type.return_type.clone()) } else { // its a variable containing function address - expect_type!(self.typecheck_expr(env, callee)?, "fnptr", paren.loc); + expect_type!(self.typecheck_expr(env, callee)?, "ptr", paren.loc); for arg in args { self.typecheck_expr(env, arg)?; @@ -490,7 +490,7 @@ impl<'a> TypeChecker<'a> { } } else { // its an expression that evalutes to function address - expect_type!(self.typecheck_expr(env, callee)?, "fnptr", paren.loc); + expect_type!(self.typecheck_expr(env, callee)?, "ptr", paren.loc); for arg in args { self.typecheck_expr(env, arg)?; @@ -514,13 +514,7 @@ impl<'a> TypeChecker<'a> { Ok("u8".into()) } ExprKind::AddrOf { op, expr } => match &expr.kind { - ExprKind::Variable(name) => { - if self.symbol_table.functions.contains_key(&name.lexeme) { - Ok("fnptr".into()) - } else { - Ok("ptr".into()) - } - } + ExprKind::Variable(_) => Ok("ptr".into()), _ => { error!(&op.loc, "can only take address of variables and functions") }