This commit is contained in:
Erin 2023-07-12 00:01:40 +02:00 committed by ondra05
parent 3fc6bb9171
commit 299e8e6759
8 changed files with 145 additions and 50 deletions

21
Cargo.lock generated
View file

@ -104,6 +104,7 @@ dependencies = [
"hashbrown 0.14.0", "hashbrown 0.14.0",
"hbbytecode", "hbbytecode",
"lasso", "lasso",
"literify",
"logos", "logos",
"paste", "paste",
] ]
@ -135,6 +136,26 @@ dependencies = [
"hashbrown 0.13.2", "hashbrown 0.13.2",
] ]
[[package]]
name = "literify"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54e4d365df794ed78b4ce1061886f82eae7afa8e3a98ce4c4b0bfd0c777b1175"
dependencies = [
"litrs",
"proc-macro2",
"quote",
]
[[package]]
name = "litrs"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4f17c3668f3cc1132437cdadc93dab05e52d592f06948d3f64828430c36e4a70"
dependencies = [
"proc-macro2",
]
[[package]] [[package]]
name = "log" name = "log"
version = "0.4.17" version = "0.4.17"

View file

@ -4,10 +4,11 @@ version = "0.1.0"
edition = "2021" edition = "2021"
[dependencies] [dependencies]
ariadne = "0.3.0"
hbbytecode = { path = "../hbbytecode" } hbbytecode = { path = "../hbbytecode" }
literify = "0.1"
paste = "1.0" paste = "1.0"
hashbrown = "0.14.0" hashbrown = "0.14.0"
ariadne = "0.3.0"
[dependencies.lasso] [dependencies.lasso]
version = "0.7" version = "0.7"

View file

@ -3,7 +3,7 @@
extern crate alloc; extern crate alloc;
pub mod text; pub mod text_r;
mod macros; mod macros;
@ -15,25 +15,24 @@ pub struct Assembler {
sub: HashSet<usize>, sub: HashSet<usize>,
} }
impl Assembler { macros::impl_both!(
macros::impl_asm!( bbbb(p0: R, p1: R, p2: R, p3: R)
bbbb(p0: u8, p1: u8, p2: u8, p3: u8)
=> [DIR, DIRF, FMAF], => [DIR, DIRF, FMAF],
bbb(p0: u8, p1: u8, p2: u8) bbb(p0: R, p1: R, p2: R)
=> [ADD, SUB, MUL, AND, OR, XOR, SL, SR, SRS, CMP, CMPU, BRC, ADDF, SUBF, MULF], => [ADD, SUB, MUL, AND, OR, XOR, SL, SR, SRS, CMP, CMPU, BRC, ADDF, SUBF, MULF],
bbdh(p0: u8, p1: u8, p2: impl Imm, p3: u16) bbdh(p0: R, p1: R, p2: I, p3: u16)
=> [LD, ST], => [LD, ST],
bbd(p0: u8, p1: u8, p2: impl Imm) bbd(p0: R, p1: R, p2: I)
=> [ADDI, MULI, ANDI, ORI, XORI, SLI, SRI, SRSI, CMPI, CMPUI, => [ADDI, MULI, ANDI, ORI, XORI, SLI, SRI, SRSI, CMPI, CMPUI,
BMC, JEQ, JNE, JLT, JGT, JLTU, JGTU, ADDFI, MULFI], BMC, JEQ, JNE, JLT, JGT, JLTU, JGTU, ADDFI, MULFI],
bb(p0: u8, p1: u8) bb(p0: R, p1: R)
=> [NEG, NOT, CP, SWA, NEGF, ITF, FTI], => [NEG, NOT, CP, SWA, NEGF, ITF, FTI],
bd(p0: u8, p1: impl Imm) bd(p0: R, p1: I)
=> [LI, JMP], => [LI, JMP],
n() n()
=> [NOP, ECALL], => [NOP, ECALL],
); );
}
pub trait Imm { pub trait Imm {
fn insert(&self, asm: &mut Assembler); fn insert(&self, asm: &mut Assembler);

View file

@ -18,47 +18,41 @@ macro_rules! impl_asm_opcodes {
} }
} }
macros::impl_asm_opcodes!( macros::asm::impl_asm_opcodes!(
$generic($($param_i: $param_ty),*) $generic($($param_i: $param_ty),*)
=> [$($rest)*] => [$($rest)*]
); );
}; };
} }
macro_rules! gen_impl_asm_insert { macro_rules! impl_asm_insert {
($($ty:ident),* $(,)?) => { ($self:expr, $id:ident, I) => {
macro_rules! impl_asm_insert {
$(($self:expr, $id:ident, $ty) => {
$self.buf.extend($id.to_le_bytes())
};)*
($self:expr, $id:ident, $_:ty) => {
Imm::insert(&$id, $self) Imm::insert(&$id, $self)
}; };
}
($self:expr, $id:ident, $_:ident) => {
$self.buf.extend($id.to_le_bytes())
}; };
} }
gen_impl_asm_insert!(u8, u16, u64);
macro_rules! impl_asm { macro_rules! impl_asm {
( (
$( $(
$ityn:ident $ityn:ident
($($param_i:ident: $param_ty:ty),* $(,)?) ($($param_i:ident: $param_ty:ident),* $(,)?)
=> [$($opcode:ident),* $(,)?], => [$($opcode:ident),* $(,)?],
)* )*
) => { ) => {
paste::paste! { paste::paste! {
$( $(
#[allow(dead_code)] #[allow(dead_code)]
fn [<i_param_ $ityn>](&mut self, opcode: u8, $($param_i: $param_ty),*) { fn [<i_param_ $ityn>](&mut self, opcode: u8, $($param_i: macros::asm::ident_map_ty!($param_ty)),*) {
self.buf.push(opcode); self.buf.push(opcode);
$(macros::impl_asm_insert!(self, $param_i, $param_ty);)* $(macros::asm::impl_asm_insert!(self, $param_i, $param_ty);)*
} }
macros::impl_asm_opcodes!( macros::asm::impl_asm_opcodes!(
[<i_param_ $ityn>]($($param_i: $param_ty),*) [<i_param_ $ityn>]($($param_i: macros::asm::ident_map_ty!($param_ty)),*)
=> [$($opcode,)*] => [$($opcode,)*]
); );
)* )*
@ -66,7 +60,14 @@ macro_rules! impl_asm {
}; };
} }
pub(super) use {impl_asm, impl_asm_opcodes}; #[rustfmt::skip]
macro_rules! ident_map_ty {
(R) => { u8 };
(I) => { impl Imm };
($id:ident) => { $id };
}
pub(crate) use {ident_map_ty, impl_asm, impl_asm_opcodes};
#[allow(clippy::single_component_path_imports)] #[allow(clippy::single_component_path_imports)]
pub(super) use impl_asm_insert; pub(crate) use impl_asm_insert;

14
hbasm/src/macros/mod.rs Normal file
View file

@ -0,0 +1,14 @@
pub mod asm;
pub mod text;
macro_rules! impl_both {
($($tt:tt)*) => {
impl Assembler {
$crate::macros::asm::impl_asm!($($tt)*);
}
$crate::macros::text::gen_text!($($tt)*);
};
}
pub(crate) use impl_both;

59
hbasm/src/macros/text.rs Normal file
View file

@ -0,0 +1,59 @@
macro_rules! gen_text {
(
$(
$ityn:ident
($($param_i:ident: $param_ty:ident),* $(,)?)
=> [$($opcode:ident),* $(,)?],
)*
) => {
pub mod text {
use {
lasso::{Rodeo, Spur},
logos::Logos,
};
paste::paste!(literify::literify! {
#[derive(Clone, Copy, Debug, PartialEq, Eq, Logos)]
#[logos(extras = Rodeo)]
#[logos(skip r"[ \t\t]+")]
#[logos(skip r"-- .*")]
pub enum Token {
$($(#[token(~([<$opcode:lower>]), |_| hbbytecode::opcode::[<$opcode:upper>])])*)*
Opcode(u8),
#[regex("[0-9]+", |l| l.slice().parse().ok())]
#[regex(
"-[0-9]+",
|lexer| {
Some(u64::from_ne_bytes(lexer.slice().parse::<i64>().ok()?.to_ne_bytes()))
},
)] Integer(u64),
#[regex(
"r[0-9]+",
|lexer| match lexer.slice()[1..].parse() {
Ok(n) => Some(n),
_ => None
},
)] Register(u8),
#[regex(
r"\p{XID_Start}\p{XID_Continue}*:",
|lexer| lexer.extras.get_or_intern(&lexer.slice()[..lexer.slice().len() - 1]),
)] Label(Spur),
#[regex(
r"\p{XID_Start}\p{XID_Continue}*",
|lexer| lexer.extras.get_or_intern(lexer.slice()),
)] Symbol(Spur),
#[token("\n")]
#[token(";")] ISep,
#[token(",")] PSep,
}
});
}
};
}
pub(crate) use gen_text;

View file

@ -12,20 +12,20 @@ fn main() -> Result<(), Box<dyn Error>> {
let mut buf = vec![]; let mut buf = vec![];
if let Err(e) = hbasm::text::assembly(&code, &mut buf) { if let Err(e) = hbasm::text_r::assembly(&code, &mut buf) {
let mut colors = ColorGenerator::new(); let mut colors = ColorGenerator::new();
let e_code = match e.kind { let e_code = match e.kind {
hbasm::text::ErrorKind::UnexpectedToken => 1, hbasm::text_r::ErrorKind::UnexpectedToken => 1,
hbasm::text::ErrorKind::InvalidToken => 2, hbasm::text_r::ErrorKind::InvalidToken => 2,
hbasm::text::ErrorKind::UnexpectedEnd => 3, hbasm::text_r::ErrorKind::UnexpectedEnd => 3,
hbasm::text::ErrorKind::InvalidSymbol => 4, hbasm::text_r::ErrorKind::InvalidSymbol => 4,
}; };
let message = match e.kind { let message = match e.kind {
hbasm::text::ErrorKind::UnexpectedToken => "This token is not expected!", hbasm::text_r::ErrorKind::UnexpectedToken => "This token is not expected!",
hbasm::text::ErrorKind::InvalidToken => "The token is not valid!", hbasm::text_r::ErrorKind::InvalidToken => "The token is not valid!",
hbasm::text::ErrorKind::UnexpectedEnd => "The assembler reached the end of input unexpectedly!", hbasm::text_r::ErrorKind::UnexpectedEnd => "The assembler reached the end of input unexpectedly!",
hbasm::text::ErrorKind::InvalidSymbol => "This referenced symbol doesn't have a corresponding label!", hbasm::text_r::ErrorKind::InvalidSymbol => "This referenced symbol doesn't have a corresponding label!",
}; };
let a = colors.next(); let a = colors.next();