diff --git a/lang/README.md b/lang/README.md index aa4743e..8c21031 100644 --- a/lang/README.md +++ b/lang/README.md @@ -388,6 +388,56 @@ main := fn(major: int, minor: int): OemIdent { ### Incomplete Examples +#### wired_mem_swap +```hb +Color := struct {x: int} + +put_trisquare := fn(pos: Vec2(int), size: Vec2(int), color: Color): void { + step := Vec2(int).(1, 1) + if size.x < 0 { + step.x = -1 + } + if size.y < 0 { + step.y = -1 + } + + target := pos + size + + loop if pos.x == target.x break else { + put_vline(pos.x, pos.y, target.y, color) + pos.x += step.x + } + + return +} + +put_vline := fn(x: int, y0: int, y1: int, color: Color): void { + return +} + + +Vec2 := fn($Expr: type): type { + return struct {x: Expr, y: Expr} +} + +MemSwap := fn($Expr: type): type { + return struct {a: Expr, b: Expr} +} + +memswap := fn($Expr: type, a: ^Expr, b: ^Expr): void { + MemSwap(Expr).(b, a) = MemSwap(Expr).(*a, *b) + return +} + +main := fn(): int { + put_trisquare(.(0, 0), .(0, 0), .(0)) + a := 10 + b := 50 + //memswap(int, a, b) + return a +} +``` + #### comptime_pointers ```hb main := fn(): int { diff --git a/lang/src/codegen.rs b/lang/src/codegen.rs index e834976..87b0ea4 100644 --- a/lang/src/codegen.rs +++ b/lang/src/codegen.rs @@ -1151,6 +1151,7 @@ impl Codegen { us to construct '{}' with struct constructor", ); }; + for &CtorField { pos, name, ref value, .. } in fields { let Some((offset, ty)) = OffsetIter::offset_of(&self.tys, stru, name) else { self.report(pos, format_args!("field not found: {name:?}")); @@ -1178,6 +1179,12 @@ impl Codegen { let loc = loc.as_ref().offset(offset); let ctx = Ctx::default().with_loc(loc).with_ty(ty); let value = self.expr_ctx(field, ctx)?; + std::println!( + "{} {} {}", + self.ty_display(ty), + self.ty_display(value.ty), + self.ast_display(field) + ); self.ci.free_loc(value.loc); } } @@ -1283,6 +1290,7 @@ impl Codegen { } E::UnOp { op: T::Xor, val, .. } => { let val = self.ty(val); + let ptr = self.tys.make_ptr(val); Some(Value::ty(self.tys.make_ptr(val))) } E::UnOp { op: T::Band, val, pos } => { @@ -1725,7 +1733,7 @@ impl Codegen { }?; if let Some(ty) = ctx.ty { - _ = self.assert_ty(expr.pos(), value.ty, ty, "somehow"); + _ = self.assert_ty(expr.pos(), value.ty, ty, "something"); } Some(match ctx.loc { @@ -1947,6 +1955,10 @@ impl Codegen { self.report(pos, "expected type, (it cannot be inferred)"); }; + if let Some(expected) = ctx.ty { + _ = self.assert_ty(pos, ty, expected, "struct"); + } + match ty.expand() { ty::Kind::Struct(stru) => { let field_count = self.tys.struct_field_range(stru).len(); @@ -2500,7 +2512,7 @@ impl Codegen { for arg in args { let sym = find_symbol(&self.files[file as usize].symbols, arg.id); if sym.flags & idfl::COMPTIME != 0 { - self.tys.ins.args.truncate(arg_base); + self.tys.tmp.args.truncate(arg_base); break 'b None; } let ty = self.ty(&arg.ty); @@ -2810,6 +2822,7 @@ mod tests { struct_return_from_module_function; //comptime_pointers; sort_something_viredly; + wired_mem_swap; hex_octal_binary_literals; //comptime_min_reg_leak; // structs_in_registers; diff --git a/lang/src/lib.rs b/lang/src/lib.rs index 8ca7853..c1620a3 100644 --- a/lang/src/lib.rs +++ b/lang/src/lib.rs @@ -41,6 +41,7 @@ use { core::{cell::Cell, ops::Range}, hashbrown::hash_map, hbbytecode as instrs, + std::println, }; #[macro_use] @@ -248,7 +249,7 @@ mod ty { lexer::TokenKind, parser::{self, Pos}, }, - core::{num::NonZeroU32, ops::Range}, + core::{fmt::Write, num::NonZeroU32, ops::Range}, }; pub type ArrayLen = u32; @@ -544,7 +545,10 @@ mod ty { f.write_str("]") } TK::Builtin(ty) => f.write_str(to_str(ty)), - TK::Ptr(ty) => self.rety(self.tys.ins.ptrs[ty as usize].base).fmt(f), + TK::Ptr(ty) => { + f.write_str("^")?; + self.rety(self.tys.ins.ptrs[ty as usize].base).fmt(f) + } TK::Struct(idx) => { let record = &self.tys.ins.structs[idx as usize]; if ident::is_null(record.name) { @@ -1069,6 +1073,7 @@ impl Types { match entry { hash_map::RawEntryMut::Occupied(o) => o.get_key_value().0.value, hash_map::RawEntryMut::Vacant(v) => { + println!("waht"); self.ins.ptrs.push(ptr); v.insert( ctx_map::Key { diff --git a/lang/tests/codegen_tests_wired_mem_swap.txt b/lang/tests/codegen_tests_wired_mem_swap.txt new file mode 100644 index 0000000..e69de29