diff --git a/hblang/src/codegen.rs b/hblang/src/codegen.rs index 3d95aecc..7f2c99f2 100644 --- a/hblang/src/codegen.rs +++ b/hblang/src/codegen.rs @@ -1083,11 +1083,19 @@ impl Output { stash .string_data .extend(self.string_data.drain(snap.string_data..)); - stash.funcs.extend( - self.funcs.drain(snap.funcs..).inspect(|(_, rel)| { - debug_assert!(rel.offset as usize + init_code < stash.code.len()) - }), - ); + stash + .funcs + .extend(self.funcs.drain(snap.funcs..).inspect(|(_, rel)| { + #[cfg(debug_assertions)] + assert!(!rel.shifted); + debug_assert!( + rel.offset as usize + init_code < stash.code.len(), + "{} {} {}", + rel.offset, + init_code, + stash.code.len() + ) + })); stash .globals .extend(self.globals.drain(snap.globals..).inspect(|(_, rel)| { @@ -2717,8 +2725,11 @@ impl Codegen { }; let stash = s.complete_call_graph(); + s.push_stash(stash); + s.dunp_imported_fns(); + prev.vars.append(&mut s.ci.vars); s.ci.finalize(&mut s.output); s.output.emit(tx()); @@ -2732,6 +2743,9 @@ impl Codegen { } fn handle_ecall(&mut self) { + let local_pc = (self.ct.vm.pc.get() as usize - self.output.code.as_ptr() as usize) + .checked_sub(self.ci.snap.code); + let arr = self.ct.vm.pc.get() as *const Trap; let trap = unsafe { std::ptr::read_unaligned(arr) }; self.ct.vm.pc = self.ct.vm.pc.wrapping_add(std::mem::size_of::()); @@ -2767,6 +2781,14 @@ impl Codegen { self.ct.vm.write_reg(1, stru.repr() as u64); } } + + if let Some(lpc) = local_pc { + let offset = std::mem::size_of::() + + lpc + + self.ci.snap.code + + self.output.code.as_ptr() as usize; + self.ct.vm.pc = hbvm::mem::Address::new(offset as _); + } } fn find_or_declare( @@ -2898,6 +2920,15 @@ impl Codegen { } } + fn dunp_imported_fns(&mut self) { + for &(f, _) in &self.output.funcs[self.ci.snap.funcs..] { + let fnball = self.tys.funcs[f as usize]; + let file = self.files[fnball.file as usize].clone(); + let expr = fnball.expr.get(&file).unwrap(); + log::dbg!("{expr}"); + } + } + fn pop_stash(&mut self) -> Output { let mut stash = self.pool.outputs.pop().unwrap_or_default(); self.output.pop(&mut stash, &self.ci.snap); @@ -2927,6 +2958,10 @@ impl Codegen { if ret.is_ok() { self.link(); + self.output.trunc(&Snapshot { + code: self.output.code.len(), + ..self.ci.snap + }); log::dbg!("{} {}", self.output.code.len(), self.ci.snap.code); let entry = &mut self.output.code[self.ci.snap.code] as *mut _ as _; let prev_pc = std::mem::replace(&mut self.ct.vm.pc, hbvm::mem::Address::new(entry)); diff --git a/hblang/src/parser.rs b/hblang/src/parser.rs index eb3bdb3d..23eea7ac 100644 --- a/hblang/src/parser.rs +++ b/hblang/src/parser.rs @@ -840,8 +840,8 @@ impl<'a> std::fmt::Display for Expr<'a> { } } Self::UnOp { op, val, .. } => write!(f, "{op}{}", Unary(val)), - Self::Break { .. } => write!(f, "break;"), - Self::Continue { .. } => write!(f, "continue;"), + Self::Break { .. } => write!(f, "break"), + Self::Continue { .. } => write!(f, "continue"), Self::If { cond, then, else_, .. } => { @@ -857,7 +857,11 @@ impl<'a> std::fmt::Display for Expr<'a> { } => { write!(f, "fn(")?; fmt_list(f, "", args, |arg, f| write!(f, "{}: {}", arg.name, arg.ty))?; - write!(f, "): {ret} {body}") + write!(f, "): {ret} {body}")?; + if !matches!(body, Self::Block { .. }) { + write!(f, ";")?; + } + Ok(()) } Self::Call { func, @@ -871,8 +875,8 @@ impl<'a> std::fmt::Display for Expr<'a> { fmt_list(f, ")", args, std::fmt::Display::fmt) } } - Self::Return { val: Some(val), .. } => write!(f, "return {val};"), - Self::Return { val: None, .. } => write!(f, "return;"), + Self::Return { val: Some(val), .. } => write!(f, "return {val}"), + Self::Return { val: None, .. } => write!(f, "return"), Self::Ident { name, .. } => write!(f, "{name}"), Self::Block { stmts, .. } => { write!(f, "{{")?; @@ -883,8 +887,7 @@ impl<'a> std::fmt::Display for Expr<'a> { for _ in 0..INDENT.with(|i| i.get()) { write!(f, "\t")?; } - stmt.fmt(f)?; - writeln!(f)?; + writeln!(f, "{stmt};")?; } Ok(()) })(); @@ -1243,5 +1246,6 @@ mod test { some_ordinary_struct => "loft := fn(): int return loft.{a: 1, b: 2};\n"; some_ordinary_fild_per_lin_struct => "loft := fn(): int return loft.{\ \n\ta: 1,\n\tb: 2,\n};\n"; + code_block => "loft := fn(): int {\n\tloft();\n\treturn 1;\n}\n"; } }