remove intermediate enum / directly encode assembly

This commit is contained in:
2026-06-11 21:49:04 -04:00
parent 91f5db6950
commit b03f755252
11 changed files with 414 additions and 668 deletions
+2 -2
View File
@@ -1,12 +1,12 @@
use crate::{
arch::x86_64::Asm,
arch::x86_64::Code,
parser::{Node, cursor::Token},
};
pub mod x86_64;
pub enum AsmBlock {
X86_64(Asm),
X86_64(Code),
}
impl Node for AsmBlock {
+8 -8
View File
@@ -7,9 +7,9 @@ use crate::{
},
};
impl Node for Asm {
impl Node for Code {
fn parse(ctx: &mut crate::parser::ParseCtx) -> Result<Self, crate::io::CompilerMsg> {
let mut instrs = Vec::new();
let mut c = Code::default();
while let Some(Token::Ident(next)) = ctx.peek() {
match next.as_str() {
"mov" => {
@@ -17,7 +17,7 @@ impl Node for Asm {
let dst = parse_reg(ctx)?;
ctx.expect(Token::Comma)?;
let src = parse_rmi(ctx)?;
instrs.push(mov(dst, src)?);
c.mov(dst, src)?;
}
"int" => {
ctx.next();
@@ -27,7 +27,7 @@ impl Node for Asm {
let code = parse_imm(&num, ctx.span)?
.try_into()
.map_err(|_| CompilerMsg::from("Immediate must be a u8"))?;
instrs.push(Instr::Int(code));
c.int(code);
}
_ => {
let msg = format!("Unknown instruction {next}");
@@ -39,7 +39,7 @@ impl Node for Asm {
}
}
}
Ok(Self { instrs })
Ok(c)
}
fn fmt(&self, f: &mut std::fmt::Formatter, ctx: crate::parser::DisplayCtx) -> std::fmt::Result {
@@ -60,17 +60,17 @@ pub fn parse_rmi(ctx: &mut crate::parser::ParseCtx) -> Result<RegImmMem, Compile
let next = ctx.expect_next()?;
let err = || CompilerMsg::unexpected_token(&next, ctx.span, "a register or immediate");
Ok(match &next {
Token::Ident(ident) => RegImmMem::Reg(RegWH::parse(ident).ok_or_else(err)?),
Token::Ident(ident) => RegImmMem::Reg(Reg::parse(ident).ok_or_else(err)?),
Token::Lit(LitTy::Number(num)) => RegImmMem::Imm(parse_imm(num, ctx.span)?),
_ => return Err(err()),
})
}
pub fn parse_reg(ctx: &mut crate::parser::ParseCtx) -> Result<RegWH, CompilerMsg> {
pub fn parse_reg(ctx: &mut crate::parser::ParseCtx) -> Result<Reg, CompilerMsg> {
let next = ctx.expect_next()?;
let err = || CompilerMsg::unexpected_token(&next, ctx.span, "a register");
let Token::Ident(next) = &next else {
return Err(err());
};
RegWH::parse(next).ok_or_else(err)
Reg::parse(next).ok_or_else(err)
}