diff --git a/hblang/README.md b/hblang/README.md index d4b6da8..68482e0 100644 --- a/hblang/README.md +++ b/hblang/README.md @@ -751,3 +751,17 @@ main := fn(): void { return } ``` + +#### integer_inference_issues +```hb +.{integer_range} := @use("random.hb") +main := fn(): void { + a := integer_range(0, 1000) + return +} + +// in module: random.hb +integer_range := fn(min: uint, max: int): uint { + return @eca(uint, 3, 4) % (@bitcast(max) - min + 1) + min +} +``` diff --git a/hblang/src/codegen.rs b/hblang/src/codegen.rs index a804cf9..2fa77b3 100644 --- a/hblang/src/codegen.rs +++ b/hblang/src/codegen.rs @@ -8,7 +8,7 @@ use { parser::{self, find_symbol, idfl, CtorField, Expr, ExprRef, FileId, Pos}, HashMap, }, - std::{collections::BTreeMap, fmt::Display, ops::Range, rc::Rc}, + std::{collections::BTreeMap, fmt::Display, ops::Range, rc::Rc, usize}, }; type Offset = u32; @@ -1094,7 +1094,7 @@ impl Output { fn emit(&mut self, (len, instr): (usize, [u8; instrs::MAX_SIZE])) { let name = instrs::NAMES[instr[0] as usize]; - log::dbg!( + log::trc!( "{:08x}: {}: {}", self.code.len(), name, @@ -1196,7 +1196,7 @@ impl hbvm::mem::Memory for LoggedMem { target: *mut u8, count: usize, ) -> Result<(), hbvm::mem::LoadError> { - log::dbg!( + log::trc!( "load: {:x} {:?}", addr.get(), core::slice::from_raw_parts(addr.get() as *const u8, count) @@ -1214,7 +1214,7 @@ impl hbvm::mem::Memory for LoggedMem { source: *const u8, count: usize, ) -> Result<(), hbvm::mem::StoreError> { - log::dbg!( + log::trc!( "store: {:x} {:?}", addr.get(), core::slice::from_raw_parts(source, count) @@ -1227,7 +1227,7 @@ impl hbvm::mem::Memory for LoggedMem { } unsafe fn prog_read(&mut self, addr: hbvm::mem::Address) -> T { - log::dbg!( + log::trc!( "read-typed: {:x} {} {:?}", addr.get(), std::any::type_name::(), @@ -1858,7 +1858,7 @@ impl Codegen { self.assign_pattern(left, value) } E::Call { func: fast, args, .. } => { - log::dbg!("call {fast}"); + log::trc!("call {fast}"); let func_ty = self.ty(fast); let ty::Kind::Func(mut func) = func_ty.expand() else { self.report(fast.pos(), "can't call this, maybe in the future"); @@ -2105,7 +2105,10 @@ impl Codegen { Some(Value { ty: ty::BOOL.into(), loc: Loc::reg(lhs) }) } E::BinOp { left, op, right } if op != T::Decl => 'ops: { - let left = self.expr(left)?; + let left = self.expr_ctx(left, Ctx { + ty: ctx.ty.filter(|_| dbg!(dbg!(op).is_homogenous())), + ..Default::default() + })?; if op == T::Assign { let value = self.expr_ctx(right, Ctx::from(left)).unwrap(); @@ -2206,7 +2209,7 @@ impl Codegen { }?; if let Some(ty) = ctx.ty { - _ = self.assert_ty(expr.pos(), value.ty, ty, "a thing"); + _ = self.assert_ty(expr.pos(), value.ty, ty, format_args!("'{expr}'")); } Some(match ctx.loc { @@ -3020,7 +3023,7 @@ impl Codegen { name: Result, lit_name: &str, ) -> ty::Kind { - log::dbg!("find_or_declare: {lit_name} {file}"); + log::trc!("find_or_declare: {lit_name} {file}"); let f = self.files[file as usize].clone(); let Some((expr, ident)) = f.find_decl(name) else { match name { @@ -3176,7 +3179,7 @@ impl Codegen { ci: ItemCtx, compile: impl FnOnce(&mut Self, &mut ItemCtx) -> Result, ) -> Result { - log::dbg!("eval"); + log::trc!("eval"); self.ct.enter(); let stash = self.pop_stash(); @@ -3227,7 +3230,7 @@ impl Codegen { self.push_stash(stash); self.ct.exit(); - log::dbg!("eval-end"); + log::trc!("eval-end"); ret } @@ -3347,8 +3350,16 @@ impl Codegen { } fn report_log(&self, pos: Pos, msg: impl std::fmt::Display) { - let (line, col) = lexer::line_col(self.cfile().file.as_bytes(), pos); + let str = &self.cfile().file; + let (line, mut col) = lexer::line_col(str.as_bytes(), pos); println!("{}:{}:{}: {}", self.cfile().path, line, col, msg); + + let line = &str[str[..pos as usize].rfind('\n').map_or(0, |i| i + 1) + ..str[pos as usize..].find('\n').unwrap_or(str.len()) + pos as usize]; + col += line.matches('\t').count() * 3; + + println!("{}", line.replace("\t", " ")); + println!("{}^", " ".repeat(col - 1)) } #[track_caller] @@ -3565,5 +3576,6 @@ mod tests { inline => README; inline_test => README; some_generic_code => README; + integer_inference_issues => README; } } diff --git a/hblang/src/lexer.rs b/hblang/src/lexer.rs index f87c683..5d69486 100644 --- a/hblang/src/lexer.rs +++ b/hblang/src/lexer.rs @@ -185,6 +185,12 @@ impl TokenKind { s => todo!("{s}"), } } + + pub fn is_homogenous(&self) -> bool { + self.precedence() != Self::Eq.precedence() + && self.precedence() != Self::Gt.precedence() + && self.precedence() != Self::Eof.precedence() + } } gen_token_kind! { diff --git a/hblang/src/son.rs b/hblang/src/son.rs index eb81a25..83b1296 100644 --- a/hblang/src/son.rs +++ b/hblang/src/son.rs @@ -18,6 +18,7 @@ use { mem, ops::{self, Range}, rc::Rc, + usize, }, }; @@ -2562,8 +2563,14 @@ impl Codegen { } fn report_log(&self, pos: Pos, msg: impl std::fmt::Display) { - let (line, col) = lexer::line_col(self.cfile().file.as_bytes(), pos); + let str = &self.cfile().file; + let (line, col) = lexer::line_col(str.as_bytes(), pos); println!("{}:{}:{}: {}", self.cfile().path, line, col, msg); + + let line = str[str[..pos as usize].rfind('\n').map_or(0, |i| i + 1) + ..str[pos as usize..].find('\n').unwrap_or(str.len())] + .replace("\t", " "); + println!("{line}"); } #[track_caller] diff --git a/hblang/tests/codegen_tests_integer_inference_issues.txt b/hblang/tests/codegen_tests_integer_inference_issues.txt new file mode 100644 index 0000000..dda9fc2 --- /dev/null +++ b/hblang/tests/codegen_tests_integer_inference_issues.txt @@ -0,0 +1,31 @@ +main: + ADDI64 r254, r254, -16d + ST r31, r254, 0a, 16h + LI64 r2, 0d + LI64 r3, 1000d + JAL r31, r0, :integer_range + CP r32, r1 + LD r31, r254, 0a, 16h + ADDI64 r254, r254, 16d + JALA r0, r31, 0a +integer_range: + ADDI64 r254, r254, -40d + ST r31, r254, 0a, 40h + CP r32, r2 + CP r33, r3 + LI64 r2, 3d + LI64 r3, 4d + ECA + CP r34, r1 + CP r35, r32 + SUB64 r33, r33, r35 + ADDI64 r33, r33, 1d + DIRU64 r0, r34, r34, r33 + ADD64 r34, r34, r32 + CP r1, r34 + LD r31, r254, 0a, 40h + ADDI64 r254, r254, 40d + JALA r0, r31, 0a +code size: 220 +ret: 42 +status: Ok(()) diff --git a/hblang/tests/son_tests_branch_assignments.txt b/hblang/tests/son_tests_branch_assignments.txt index fd50941..c3cb2f5 100644 --- a/hblang/tests/son_tests_branch_assignments.txt +++ b/hblang/tests/son_tests_branch_assignments.txt @@ -1,21 +1,18 @@ main: - ADDI64 r254, r254, -32d - ST r31, r254, 0a, 32h + ADDI64 r254, r254, -24d + ST r31, r254, 0a, 24h CP r32, r2 - LI64 r33, 1d - JNE r32, r33, :0 + LI64 r1, 1d + JNE r32, r1, :0 JMP :1 - 0: LI64 r34, 0d - JNE r32, r34, :2 - LI64 r34, 2d - JMP :3 - 2: LI64 r32, 3d - CP r34, r32 - 3: CP r33, r34 - 1: CP r1, r33 - LD r31, r254, 0a, 32h - ADDI64 r254, r254, 32d + 0: LI64 r33, 0d + JNE r32, r33, :2 + LI64 r1, 2d + JMP :1 + 2: LI64 r1, 3d + 1: LD r31, r254, 0a, 24h + ADDI64 r254, r254, 24d JALA r0, r31, 0a -code size: 139 +code size: 130 ret: 2 status: Ok(()) diff --git a/hblang/tests/son_tests_functions.txt b/hblang/tests/son_tests_functions.txt index 6256ec7..4df4a49 100644 --- a/hblang/tests/son_tests_functions.txt +++ b/hblang/tests/son_tests_functions.txt @@ -11,20 +11,20 @@ main: ADDI64 r254, r254, 16d JALA r0, r31, 0a add_two: - ADDI64 r254, r254, -16d - ST r31, r254, 0a, 16h - CP r32, r2 - ADDI64 r1, r32, 2d - LD r31, r254, 0a, 16h - ADDI64 r254, r254, 16d + ADDI64 r254, r254, -8d + ST r31, r254, 0a, 8h + CP r1, r2 + ADDI64 r1, r1, 2d + LD r31, r254, 0a, 8h + ADDI64 r254, r254, 8d JALA r0, r31, 0a add_one: - ADDI64 r254, r254, -16d - ST r31, r254, 0a, 16h - CP r32, r2 - ADDI64 r1, r32, 1d - LD r31, r254, 0a, 16h - ADDI64 r254, r254, 16d + ADDI64 r254, r254, -8d + ST r31, r254, 0a, 8h + CP r1, r2 + ADDI64 r1, r1, 1d + LD r31, r254, 0a, 8h + ADDI64 r254, r254, 8d JALA r0, r31, 0a code size: 254 ret: 33 diff --git a/hblang/tests/son_tests_loops.txt b/hblang/tests/son_tests_loops.txt index e69de29..811823c 100644 --- a/hblang/tests/son_tests_loops.txt +++ b/hblang/tests/son_tests_loops.txt @@ -0,0 +1,31 @@ +main: + ADDI64 r254, r254, -8d + ST r31, r254, 0a, 8h + LI64 r2, 10d + JAL r31, r0, :fib + LD r31, r254, 0a, 8h + ADDI64 r254, r254, 8d + JALA r0, r31, 0a +fib: + ADDI64 r254, r254, -64d + ST r31, r254, 0a, 64h + CP r32, r2 + CP r33, r32 + LI64 r34, 0d + CP r1, r34 + LI64 r35, 1d + CP r36, r35 + 2: JNE r33, r34, :0 + JMP :1 + 0: SUB64 r37, r33, r35 + ADD64 r38, r1, r36 + CP r33, r37 + CP r1, r36 + CP r36, r38 + JMP :2 + 1: LD r31, r254, 0a, 64h + ADDI64 r254, r254, 64d + JALA r0, r31, 0a +code size: 207 +ret: 55 +status: Ok(())