diff --git a/hblang/src/codegen.rs b/hblang/src/codegen.rs index 17e105c..c1e451b 100644 --- a/hblang/src/codegen.rs +++ b/hblang/src/codegen.rs @@ -11,7 +11,8 @@ use { ty, Field, Func, Global, LoggedMem, ParamAlloc, Reloc, Sig, Struct, SymKey, TypedReloc, Types, }, - std::fmt::Display, + core::panic, + std::{fmt::Display, usize}, }; type Offset = u32; @@ -411,7 +412,6 @@ struct Loop { struct Variable { id: Ident, - uses_left: u32, value: Value, } @@ -744,7 +744,7 @@ impl Codegen { is_ct: false, id, name: "booodab", - index: u16::MAX, + is_first: false, }) .map(|expr| self.expr(&expr)) .collect::>>()?; @@ -854,13 +854,7 @@ impl Codegen { args.iter().zip(sig.args.view(&self.tys.args).to_owned()).zip(cargs) { let loc = self.expr_ctx(arg, Ctx::default().with_ty(ty))?.loc; - - let sym = parser::find_symbol(&fast.symbols, carg.id).flags; - self.ci.vars.push(Variable { - id: carg.id, - value: Value { ty, loc }, - uses_left: idfl::count(sym) as u32, - }); + self.ci.vars.push(Variable { id: carg.id, value: Value { ty, loc } }); } } @@ -1364,7 +1358,6 @@ impl Codegen { if let Some((var_index, var)) = self.ci.vars.iter_mut().enumerate().find(|(_, v)| v.id == id) => { - var.uses_left -= 1; let loc = var.value.loc.as_ref(); Some(Value { ty: self.ci.vars[var_index].value.ty, loc }) } @@ -1731,11 +1724,7 @@ impl Codegen { arg.loc }; - self.ci.vars.push(Variable { - id: carg.id, - value: Value { ty, loc }, - uses_left: idfl::count(sym.flags) as u32, - }); + self.ci.vars.push(Variable { id: carg.id, value: Value { ty, loc } }); } let args = self.pack_args(pos, arg_base); @@ -1779,7 +1768,6 @@ impl Codegen { .map(|v| Variable { id: v.id, value: Value { ty: v.value.ty, loc: v.value.loc.as_ref() }, - uses_left: v.uses_left, }) .collect(), stack_relocs: self.ci.stack_relocs.clone(), @@ -1848,15 +1836,11 @@ impl Codegen { && size <= 8 => { let loc = Loc::ct(load_value(offset, size)); - self.ci.vars.push(Variable { id, value: Value { ty, loc }, uses_left: u32::MAX }); + self.ci.vars.push(Variable { id, value: Value { ty, loc } }); true } Expr::Ident { id, .. } => { - let var = Variable { - id, - value: Value { ty, loc: Loc::ct_ptr(offset as _) }, - uses_left: u32::MAX, - }; + let var = Variable { id, value: Value { ty, loc: Loc::ct_ptr(offset as _) } }; self.ci.vars.push(var); false } @@ -1872,11 +1856,7 @@ impl Codegen { if sym & idfl::REFERENCED != 0 { loc = self.spill(loc, self.tys.size_of(right.ty)); } - self.ci.vars.push(Variable { - id, - value: Value { ty: right.ty, loc }, - uses_left: idfl::count(sym) as u32, - }); + self.ci.vars.push(Variable { id, value: Value { ty: right.ty, loc } }); } Expr::Ctor { pos, fields, .. } => { let ty::Kind::Struct(idx) = right.ty.expand() else { @@ -2089,11 +2069,7 @@ impl Codegen { true => Loc::ty(self.tys.args[sig_args.next().unwrap()]), false => self.load_arg(sym, ty, &mut parama), }; - self.ci.vars.push(Variable { - id: arg.id, - value: Value { ty, loc }, - uses_left: idfl::count(sym) as u32, - }); + self.ci.vars.push(Variable { id: arg.id, value: Value { ty, loc } }); } if self.tys.size_of(sig.ret) > 16 { @@ -2292,25 +2268,6 @@ impl Codegen { self.ci.emit(cp(dst.get(), src.get())); } } - //(lpat!(false, src, 0, None), lpat!(false, dst, off, None)) => { - // assert!(size <= 8); - // let off_rem = 8 * (off % 8); - // let freg = dst.get() + (off / 8) as u8; - // if size < 8 { - // let mask = !(((1u64 << (8 * size)) - 1) << off_rem); - // self.ci.emit(andi(freg, freg, mask)); - // if off_rem == 0 { - // self.ci.emit(or(freg, freg, src.get())); - // } else { - // let tmp = self.ci.regs.allocate(); - // self.ci.emit(slui64(tmp.get(), src.get(), off_rem as _)); - // self.ci.emit(or(freg, freg, src.get())); - // self.ci.regs.free(tmp); - // } - // } else { - // self.ci.emit(cp(freg, src.get())); - // } - //} (lpat!(true, src, soff, ref ssta), lpat!(false, dst, 0, None)) => { if size < 8 { self.ci.emit(cp(dst.get(), 0)); @@ -2366,8 +2323,8 @@ impl Codegen { let trap = Self::read_trap(self.ct.vm.pc.get()).unwrap(); self.ct.vm.pc = self.ct.vm.pc.wrapping_add(trap.size() + 1); - let mut extra_jump = 0; - let mut code_index = Some(self.ct.vm.pc.get() as usize - self.ci.code.as_ptr() as usize); + let mut code_index = self.ct.vm.pc.get() as usize - self.ct.code.as_ptr() as usize; + debug_assert!(code_index < self.ct.code.len()); match *trap { trap::Trap::MakeStruct(trap::MakeStruct { file, struct_expr }) => { @@ -2390,32 +2347,28 @@ impl Codegen { self.ci.vars.push(Variable { id, value: Value::new(ty, Loc::ct(u64::from_ne_bytes(imm))), - uses_left: u32::MAX, }); } let stru = ty::Kind::Struct(self.build_struct(fields)).compress(); self.ci.vars.truncate(prev_len); self.ct.vm.write_reg(1, stru.repr() as u64); + debug_assert_ne!(stru.expand().inner(), 1); } trap::Trap::MomizedCall(trap::MomizedCall { func }) => { let sym = SymKey { file: u32::MAX, ident: ty::Kind::Func(func).compress().repr() }; if let Some(&ty) = self.tys.syms.get(&sym) { self.ct.vm.write_reg(1, ty.repr()); - extra_jump = jal(0, 0, 0).0 + tx().0; } else { - code_index = None; self.run_vm(); self.tys.syms.insert(sym, self.ct.vm.read_reg(1).0.into()); } + code_index += jal(0, 0, 0).0 + tx().0; } } - if let Some(lpc) = code_index { - let offset = lpc + self.ci.code.as_ptr() as usize; - self.ct.vm.pc = hbvm::mem::Address::new(offset as _); - } - self.ct.vm.pc += extra_jump; + let offset = code_index + self.ct.code.as_ptr() as usize; + self.ct.vm.pc = hbvm::mem::Address::new(offset as _); } fn find_or_declare( @@ -2588,7 +2541,8 @@ impl Codegen { self.tys.dump_reachable(last_fn as _, &mut self.ct.code); let entry = &mut self.ct.code[self.tys.funcs[last_fn].offset as usize] as *mut _ as _; - let prev_pc = std::mem::replace(&mut self.ct.vm.pc, hbvm::mem::Address::new(entry)); + let prev_pc = std::mem::replace(&mut self.ct.vm.pc, hbvm::mem::Address::new(entry)) + - self.ct.code.as_ptr() as usize; #[cfg(debug_assertions)] { @@ -2600,12 +2554,12 @@ impl Codegen { }) { panic!("{e} {}", String::from_utf8(vc).unwrap()); } else { - //log::inf!("{}", String::from_utf8(vc).unwrap()); + log::trc!("{}", String::from_utf8(vc).unwrap()); } } self.run_vm(); - self.ct.vm.pc = prev_pc; + self.ct.vm.pc = prev_pc + self.ct.code.as_ptr() as usize; self.tys.funcs.pop().unwrap(); } @@ -2644,9 +2598,9 @@ impl Codegen { if let Some(res) = ty.try_upcast(expected) { res } else { - let ty = self.ty_display(ty); - let expected = self.ty_display(expected); - self.report(pos, format_args!("expected {hint} of type {expected}, got {ty}")); + let dty = self.ty_display(ty); + let dexpected = self.ty_display(expected); + self.report(pos, format_args!("expected {hint} of type {dexpected}, got {dty}",)); } } diff --git a/hblang/src/lib.rs b/hblang/src/lib.rs index 137304f..abb3b4a 100644 --- a/hblang/src/lib.rs +++ b/hblang/src/lib.rs @@ -270,7 +270,8 @@ mod ty { self.0.get() } - pub(crate) fn is_struct(&self) -> bool { + #[allow(unused)] + pub fn is_struct(&self) -> bool { matches!(self.expand(), Kind::Struct(_)) } } @@ -442,7 +443,7 @@ mod ty { } TK::Struct(idx) => { let record = &self.tys.structs[idx as usize]; - write!(f, "{{")?; + write!(f, "[{idx}]{{")?; for (i, &super::Field { ref name, ty }) in record.fields.iter().enumerate() { if i != 0 { write!(f, ", ")?; @@ -481,7 +482,7 @@ fn emit(out: &mut Vec, (len, instr): EncodedInstr) { out.extend_from_slice(&instr[..len]); } -#[derive(PartialEq, Eq, Hash)] +#[derive(PartialEq, Eq, Hash, Debug)] struct SymKey { file: u32, ident: u32, diff --git a/hblang/src/parser.rs b/hblang/src/parser.rs index 0f5fd6a..8a6ed8e 100644 --- a/hblang/src/parser.rs +++ b/hblang/src/parser.rs @@ -36,10 +36,6 @@ pub mod idfl { REFERENCED, COMPTIME, } - - pub fn count(i: IdentFlags) -> IdentIndex { - (i & !ALL) as _ - } } pub fn no_loader(_: &str, _: &str) -> io::Result { @@ -187,9 +183,8 @@ impl<'a, 'b> Parser<'a, 'b> { } fn declare_rec(&mut self, expr: &Expr, top_level: bool) { - let idx = |idx| top_level.not().then_some(idx); match *expr { - Expr::Ident { pos, id, index, .. } => self.declare(pos, id, idx(index)), + Expr::Ident { pos, id, is_first, .. } => self.declare(pos, id, is_first || top_level), Expr::Ctor { fields, .. } => { for CtorField { value, .. } in fields { self.declare_rec(value, top_level) @@ -199,10 +194,8 @@ impl<'a, 'b> Parser<'a, 'b> { } } - fn declare(&mut self, pos: Pos, id: Ident, index_to_check: Option) { - if let Some(index) = index_to_check - && index != 0 - { + fn declare(&mut self, pos: Pos, id: Ident, valid_order: bool) { + if !valid_order { self.report( pos, format_args!( @@ -221,28 +214,25 @@ impl<'a, 'b> Parser<'a, 'b> { } } - fn resolve_ident(&mut self, token: Token) -> (Ident, IdentIndex) { + fn resolve_ident(&mut self, token: Token) -> (Ident, bool) { let is_ct = token.kind == TokenKind::CtIdent; let name = self.lexer.slice(token.range()); if let Some(builtin) = crate::ty::from_str(name) { - return (builtin, 0); + return (builtin, false); } - let (i, id) = match self + let (i, id, bl) = match self .idents .iter_mut() .enumerate() .rfind(|(_, elem)| self.lexer.slice(ident::range(elem.ident)) == name) { - Some((i, elem)) => { - elem.flags += 1; - (i, elem) - } + Some((i, elem)) => (i, elem, false), None => { let id = ident::new(token.start, name.len() as _); self.idents.push(ScopeIdent { ident: id, declared: false, flags: 0 }); - (self.idents.len() - 1, self.idents.last_mut().unwrap()) + (self.idents.len() - 1, self.idents.last_mut().unwrap(), true) } }; @@ -252,7 +242,7 @@ impl<'a, 'b> Parser<'a, 'b> { self.captured.push(id.ident); } - (id.ident, idfl::count(id.flags)) + (id.ident, bl) } fn move_str(&mut self, range: Token) -> &'a str { @@ -332,9 +322,9 @@ impl<'a, 'b> Parser<'a, 'b> { trailing_comma: std::mem::take(&mut self.trailing_sep), }, T::Ident | T::CtIdent => { - let (id, index) = self.resolve_ident(token); + let (id, is_first) = self.resolve_ident(token); let name = self.move_str(token); - E::Ident { pos, is_ct: token.kind == T::CtIdent, name, id, index } + E::Ident { pos, is_ct: token.kind == T::CtIdent, name, id, is_first } } T::If => E::If { pos, @@ -359,15 +349,14 @@ impl<'a, 'b> Parser<'a, 'b> { self.expect_advance(T::LParen); self.collect_list(T::Comma, T::RParen, |s| { let name = s.advance_ident(); - let (id, index) = s.resolve_ident(name); - s.declare(name.start, id, None); + let (id, _) = s.resolve_ident(name); + s.declare(name.start, id, true); s.expect_advance(T::Colon); Arg { pos: name.start, name: s.move_str(name), is_ct: name.kind == T::CtIdent, id, - index, ty: s.expr(), } }) @@ -488,8 +477,8 @@ impl<'a, 'b> Parser<'a, 'b> { value: if s.advance_if(TokenKind::Colon) { s.expr() } else { - let (id, index) = s.resolve_ident(name_tok); - Expr::Ident { pos: name_tok.start, is_ct: false, id, name, index } + let (id, is_first) = s.resolve_ident(name_tok); + Expr::Ident { pos: name_tok.start, is_ct: false, id, name, is_first } }, } }), @@ -598,7 +587,6 @@ pub struct Arg<'a> { pub name: &'a str, pub id: Ident, pub is_ct: bool, - pub index: IdentIndex, pub ty: Expr<'a>, } @@ -710,11 +698,11 @@ generate_expr! { /// note: ':unicode:' is any utf-8 character except ascii /// `'[a-zA-Z_:unicode:][a-zA-Z0-9_:unicode:]*'` Ident { - pos: Pos, + pos: Pos, is_ct: bool, - id: Ident, - name: &'a str, - index: IdentIndex, + is_first: bool, + id: Ident, + name: &'a str, }, /// `LIST('{', [';'], '}', Expr)` Block {