upgraded error messages and inference
This commit is contained in:
parent
414a07b99a
commit
4bcab25231
|
@ -751,3 +751,17 @@ main := fn(): void {
|
||||||
return
|
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
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
|
@ -8,7 +8,7 @@ use {
|
||||||
parser::{self, find_symbol, idfl, CtorField, Expr, ExprRef, FileId, Pos},
|
parser::{self, find_symbol, idfl, CtorField, Expr, ExprRef, FileId, Pos},
|
||||||
HashMap,
|
HashMap,
|
||||||
},
|
},
|
||||||
std::{collections::BTreeMap, fmt::Display, ops::Range, rc::Rc},
|
std::{collections::BTreeMap, fmt::Display, ops::Range, rc::Rc, usize},
|
||||||
};
|
};
|
||||||
|
|
||||||
type Offset = u32;
|
type Offset = u32;
|
||||||
|
@ -1094,7 +1094,7 @@ impl Output {
|
||||||
|
|
||||||
fn emit(&mut self, (len, instr): (usize, [u8; instrs::MAX_SIZE])) {
|
fn emit(&mut self, (len, instr): (usize, [u8; instrs::MAX_SIZE])) {
|
||||||
let name = instrs::NAMES[instr[0] as usize];
|
let name = instrs::NAMES[instr[0] as usize];
|
||||||
log::dbg!(
|
log::trc!(
|
||||||
"{:08x}: {}: {}",
|
"{:08x}: {}: {}",
|
||||||
self.code.len(),
|
self.code.len(),
|
||||||
name,
|
name,
|
||||||
|
@ -1196,7 +1196,7 @@ impl hbvm::mem::Memory for LoggedMem {
|
||||||
target: *mut u8,
|
target: *mut u8,
|
||||||
count: usize,
|
count: usize,
|
||||||
) -> Result<(), hbvm::mem::LoadError> {
|
) -> Result<(), hbvm::mem::LoadError> {
|
||||||
log::dbg!(
|
log::trc!(
|
||||||
"load: {:x} {:?}",
|
"load: {:x} {:?}",
|
||||||
addr.get(),
|
addr.get(),
|
||||||
core::slice::from_raw_parts(addr.get() as *const u8, count)
|
core::slice::from_raw_parts(addr.get() as *const u8, count)
|
||||||
|
@ -1214,7 +1214,7 @@ impl hbvm::mem::Memory for LoggedMem {
|
||||||
source: *const u8,
|
source: *const u8,
|
||||||
count: usize,
|
count: usize,
|
||||||
) -> Result<(), hbvm::mem::StoreError> {
|
) -> Result<(), hbvm::mem::StoreError> {
|
||||||
log::dbg!(
|
log::trc!(
|
||||||
"store: {:x} {:?}",
|
"store: {:x} {:?}",
|
||||||
addr.get(),
|
addr.get(),
|
||||||
core::slice::from_raw_parts(source, count)
|
core::slice::from_raw_parts(source, count)
|
||||||
|
@ -1227,7 +1227,7 @@ impl hbvm::mem::Memory for LoggedMem {
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn prog_read<T: Copy>(&mut self, addr: hbvm::mem::Address) -> T {
|
unsafe fn prog_read<T: Copy>(&mut self, addr: hbvm::mem::Address) -> T {
|
||||||
log::dbg!(
|
log::trc!(
|
||||||
"read-typed: {:x} {} {:?}",
|
"read-typed: {:x} {} {:?}",
|
||||||
addr.get(),
|
addr.get(),
|
||||||
std::any::type_name::<T>(),
|
std::any::type_name::<T>(),
|
||||||
|
@ -1858,7 +1858,7 @@ impl Codegen {
|
||||||
self.assign_pattern(left, value)
|
self.assign_pattern(left, value)
|
||||||
}
|
}
|
||||||
E::Call { func: fast, args, .. } => {
|
E::Call { func: fast, args, .. } => {
|
||||||
log::dbg!("call {fast}");
|
log::trc!("call {fast}");
|
||||||
let func_ty = self.ty(fast);
|
let func_ty = self.ty(fast);
|
||||||
let ty::Kind::Func(mut func) = func_ty.expand() else {
|
let ty::Kind::Func(mut func) = func_ty.expand() else {
|
||||||
self.report(fast.pos(), "can't call this, maybe in the future");
|
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) })
|
Some(Value { ty: ty::BOOL.into(), loc: Loc::reg(lhs) })
|
||||||
}
|
}
|
||||||
E::BinOp { left, op, right } if op != T::Decl => 'ops: {
|
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 {
|
if op == T::Assign {
|
||||||
let value = self.expr_ctx(right, Ctx::from(left)).unwrap();
|
let value = self.expr_ctx(right, Ctx::from(left)).unwrap();
|
||||||
|
@ -2206,7 +2209,7 @@ impl Codegen {
|
||||||
}?;
|
}?;
|
||||||
|
|
||||||
if let Some(ty) = ctx.ty {
|
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 {
|
Some(match ctx.loc {
|
||||||
|
@ -3020,7 +3023,7 @@ impl Codegen {
|
||||||
name: Result<Ident, &str>,
|
name: Result<Ident, &str>,
|
||||||
lit_name: &str,
|
lit_name: &str,
|
||||||
) -> ty::Kind {
|
) -> 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 f = self.files[file as usize].clone();
|
||||||
let Some((expr, ident)) = f.find_decl(name) else {
|
let Some((expr, ident)) = f.find_decl(name) else {
|
||||||
match name {
|
match name {
|
||||||
|
@ -3176,7 +3179,7 @@ impl Codegen {
|
||||||
ci: ItemCtx,
|
ci: ItemCtx,
|
||||||
compile: impl FnOnce(&mut Self, &mut ItemCtx) -> Result<T, E>,
|
compile: impl FnOnce(&mut Self, &mut ItemCtx) -> Result<T, E>,
|
||||||
) -> Result<T, E> {
|
) -> Result<T, E> {
|
||||||
log::dbg!("eval");
|
log::trc!("eval");
|
||||||
self.ct.enter();
|
self.ct.enter();
|
||||||
let stash = self.pop_stash();
|
let stash = self.pop_stash();
|
||||||
|
|
||||||
|
@ -3227,7 +3230,7 @@ impl Codegen {
|
||||||
self.push_stash(stash);
|
self.push_stash(stash);
|
||||||
|
|
||||||
self.ct.exit();
|
self.ct.exit();
|
||||||
log::dbg!("eval-end");
|
log::trc!("eval-end");
|
||||||
|
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
|
@ -3347,8 +3350,16 @@ impl Codegen {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn report_log(&self, pos: Pos, msg: impl std::fmt::Display) {
|
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);
|
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]
|
#[track_caller]
|
||||||
|
@ -3565,5 +3576,6 @@ mod tests {
|
||||||
inline => README;
|
inline => README;
|
||||||
inline_test => README;
|
inline_test => README;
|
||||||
some_generic_code => README;
|
some_generic_code => README;
|
||||||
|
integer_inference_issues => README;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -185,6 +185,12 @@ impl TokenKind {
|
||||||
s => todo!("{s}"),
|
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! {
|
gen_token_kind! {
|
||||||
|
|
|
@ -18,6 +18,7 @@ use {
|
||||||
mem,
|
mem,
|
||||||
ops::{self, Range},
|
ops::{self, Range},
|
||||||
rc::Rc,
|
rc::Rc,
|
||||||
|
usize,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2562,8 +2563,14 @@ impl Codegen {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn report_log(&self, pos: Pos, msg: impl std::fmt::Display) {
|
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);
|
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]
|
#[track_caller]
|
||||||
|
|
31
hblang/tests/codegen_tests_integer_inference_issues.txt
Normal file
31
hblang/tests/codegen_tests_integer_inference_issues.txt
Normal file
|
@ -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(())
|
|
@ -1,21 +1,18 @@
|
||||||
main:
|
main:
|
||||||
ADDI64 r254, r254, -32d
|
ADDI64 r254, r254, -24d
|
||||||
ST r31, r254, 0a, 32h
|
ST r31, r254, 0a, 24h
|
||||||
CP r32, r2
|
CP r32, r2
|
||||||
LI64 r33, 1d
|
LI64 r1, 1d
|
||||||
JNE r32, r33, :0
|
JNE r32, r1, :0
|
||||||
JMP :1
|
JMP :1
|
||||||
0: LI64 r34, 0d
|
0: LI64 r33, 0d
|
||||||
JNE r32, r34, :2
|
JNE r32, r33, :2
|
||||||
LI64 r34, 2d
|
LI64 r1, 2d
|
||||||
JMP :3
|
JMP :1
|
||||||
2: LI64 r32, 3d
|
2: LI64 r1, 3d
|
||||||
CP r34, r32
|
1: LD r31, r254, 0a, 24h
|
||||||
3: CP r33, r34
|
ADDI64 r254, r254, 24d
|
||||||
1: CP r1, r33
|
|
||||||
LD r31, r254, 0a, 32h
|
|
||||||
ADDI64 r254, r254, 32d
|
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
code size: 139
|
code size: 130
|
||||||
ret: 2
|
ret: 2
|
||||||
status: Ok(())
|
status: Ok(())
|
||||||
|
|
|
@ -11,20 +11,20 @@ main:
|
||||||
ADDI64 r254, r254, 16d
|
ADDI64 r254, r254, 16d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
add_two:
|
add_two:
|
||||||
ADDI64 r254, r254, -16d
|
ADDI64 r254, r254, -8d
|
||||||
ST r31, r254, 0a, 16h
|
ST r31, r254, 0a, 8h
|
||||||
CP r32, r2
|
CP r1, r2
|
||||||
ADDI64 r1, r32, 2d
|
ADDI64 r1, r1, 2d
|
||||||
LD r31, r254, 0a, 16h
|
LD r31, r254, 0a, 8h
|
||||||
ADDI64 r254, r254, 16d
|
ADDI64 r254, r254, 8d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
add_one:
|
add_one:
|
||||||
ADDI64 r254, r254, -16d
|
ADDI64 r254, r254, -8d
|
||||||
ST r31, r254, 0a, 16h
|
ST r31, r254, 0a, 8h
|
||||||
CP r32, r2
|
CP r1, r2
|
||||||
ADDI64 r1, r32, 1d
|
ADDI64 r1, r1, 1d
|
||||||
LD r31, r254, 0a, 16h
|
LD r31, r254, 0a, 8h
|
||||||
ADDI64 r254, r254, 16d
|
ADDI64 r254, r254, 8d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
code size: 254
|
code size: 254
|
||||||
ret: 33
|
ret: 33
|
||||||
|
|
|
@ -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(())
|
Loading…
Reference in a new issue