diff --git a/hblang/examples/functions.hb b/hblang/examples/functions.hb new file mode 100644 index 0000000..c222971 --- /dev/null +++ b/hblang/examples/functions.hb @@ -0,0 +1,14 @@ + +main := ||: int { + return add_one(10) + add_two(20); +} + +add_two := |x: int|: int { + return x + 2; +} + +add_one := |x: int|: int { + return x + 1; +} + + diff --git a/hblang/src/codegen.rs b/hblang/src/codegen.rs index dc33360..205702d 100644 --- a/hblang/src/codegen.rs +++ b/hblang/src/codegen.rs @@ -22,9 +22,10 @@ struct Frame { } struct Reloc { - id: LabelId, + id: LabelId, offset: u32, - size: u16, + instr_offset: u16, + size: u16, } struct StackReloc { @@ -43,26 +44,27 @@ impl Func { self.code.extend_from_slice(bytes); } - pub fn offset(&mut self, id: LabelId, offset: u32, size: u16) { + pub fn offset(&mut self, id: LabelId, instr_offset: u16, size: u16) { self.relocs.push(Reloc { id, - offset: self.code.len() as u32 + offset, + offset: self.code.len() as u32, + instr_offset, size, }); } fn encode(&mut self, (len, instr): (usize, [u8; instrs::MAX_SIZE])) { - let name = instrs::NAMES[instr[0] as usize]; - println!( - "{}: {}", - name, - instr - .iter() - .take(len) - .skip(1) - .map(|b| format!("{:02x}", b)) - .collect::() - ); + // let name = instrs::NAMES[instr[0] as usize]; + // println!( + // "{}: {}", + // name, + // instr + // .iter() + // .take(len) + // .skip(1) + // .map(|b| format!("{:02x}", b)) + // .collect::() + // ); self.code.extend_from_slice(&instr[..len]); } @@ -95,7 +97,7 @@ impl Func { self.encode(instrs::tx()); } - fn relocate(&mut self, labels: &[Label], shift: i64) { + fn relocate(&mut self, labels: &[FnLabel], shift: i64) { for reloc in self.relocs.drain(..) { let label = &labels[reloc.id as usize]; let offset = if reloc.size == 8 { @@ -104,7 +106,18 @@ impl Func { label.offset as i64 - reloc.offset as i64 } + shift; - let dest = &mut self.code[reloc.offset as usize..][..reloc.size as usize]; + dbg!( + label.name.as_ref(), + offset, + reloc.size, + reloc.instr_offset, + reloc.offset, + shift, + label.offset + ); + + let dest = &mut self.code[reloc.offset as usize + reloc.instr_offset as usize..] + [..reloc.size as usize]; match reloc.size { 2 => dest.copy_from_slice(&(offset as i16).to_le_bytes()), 4 => dest.copy_from_slice(&(offset as i32).to_le_bytes()), @@ -123,9 +136,9 @@ pub struct RegAlloc { } impl RegAlloc { - fn init_caller(&mut self) { + fn init_callee(&mut self) { self.clear(); - self.free.extend(1..=31); + self.free.extend(32..=253); } fn clear(&mut self) { @@ -146,7 +159,7 @@ impl RegAlloc { } } -struct Label { +struct FnLabel { offset: u32, // TODO: use different stile of identifier that does not allocate, eg. index + length into a // file @@ -159,17 +172,23 @@ struct Variable<'a> { ty: Expr<'a>, } -pub struct Codegen<'a> { - path: &'a std::path::Path, - ret: Expr<'a>, - gpa: RegAlloc, - code: Func, - temp: Func, - labels: Vec