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",
"hbbytecode",
"lasso",
"literify",
"logos",
"paste",
]
@ -135,6 +136,26 @@ dependencies = [
"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]]
name = "log"
version = "0.4.17"

View file

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

View file

@ -3,7 +3,7 @@
extern crate alloc;
pub mod text;
pub mod text_r;
mod macros;
@ -15,25 +15,24 @@ pub struct Assembler {
sub: HashSet<usize>,
}
impl Assembler {
macros::impl_asm!(
bbbb(p0: u8, p1: u8, p2: u8, p3: u8)
macros::impl_both!(
bbbb(p0: R, p1: R, p2: R, p3: R)
=> [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],
bbdh(p0: u8, p1: u8, p2: impl Imm, p3: u16)
bbdh(p0: R, p1: R, p2: I, p3: u16)
=> [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,
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],
bd(p0: u8, p1: impl Imm)
bd(p0: R, p1: I)
=> [LI, JMP],
n()
=> [NOP, ECALL],
);
}
pub trait Imm {
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),*)
=> [$($rest)*]
);
};
}
macro_rules! gen_impl_asm_insert {
($($ty:ident),* $(,)?) => {
macro_rules! impl_asm_insert {
$(($self:expr, $id:ident, $ty) => {
$self.buf.extend($id.to_le_bytes())
};)*
($self:expr, $id:ident, $_:ty) => {
($self:expr, $id:ident, I) => {
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 {
(
$(
$ityn:ident
($($param_i:ident: $param_ty:ty),* $(,)?)
($($param_i:ident: $param_ty:ident),* $(,)?)
=> [$($opcode:ident),* $(,)?],
)*
) => {
paste::paste! {
$(
#[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);
$(macros::impl_asm_insert!(self, $param_i, $param_ty);)*
$(macros::asm::impl_asm_insert!(self, $param_i, $param_ty);)*
}
macros::impl_asm_opcodes!(
[<i_param_ $ityn>]($($param_i: $param_ty),*)
macros::asm::impl_asm_opcodes!(
[<i_param_ $ityn>]($($param_i: macros::asm::ident_map_ty!($param_ty)),*)
=> [$($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)]
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![];
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 e_code = match e.kind {
hbasm::text::ErrorKind::UnexpectedToken => 1,
hbasm::text::ErrorKind::InvalidToken => 2,
hbasm::text::ErrorKind::UnexpectedEnd => 3,
hbasm::text::ErrorKind::InvalidSymbol => 4,
hbasm::text_r::ErrorKind::UnexpectedToken => 1,
hbasm::text_r::ErrorKind::InvalidToken => 2,
hbasm::text_r::ErrorKind::UnexpectedEnd => 3,
hbasm::text_r::ErrorKind::InvalidSymbol => 4,
};
let message = match e.kind {
hbasm::text::ErrorKind::UnexpectedToken => "This token is not expected!",
hbasm::text::ErrorKind::InvalidToken => "The token is not valid!",
hbasm::text::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::UnexpectedToken => "This token is not expected!",
hbasm::text_r::ErrorKind::InvalidToken => "The token is not valid!",
hbasm::text_r::ErrorKind::UnexpectedEnd => "The assembler reached the end of input unexpectedly!",
hbasm::text_r::ErrorKind::InvalidSymbol => "This referenced symbol doesn't have a corresponding label!",
};
let a = colors.next();