Immediates and labels not implemented yet, soon be there.
This commit is contained in:
parent
299e8e6759
commit
b0b4022a85
|
@ -33,7 +33,6 @@ macros::impl_both!(
|
||||||
=> [NOP, ECALL],
|
=> [NOP, ECALL],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
pub trait Imm {
|
pub trait Imm {
|
||||||
fn insert(&self, asm: &mut Assembler);
|
fn insert(&self, asm: &mut Assembler);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,8 +8,12 @@ macro_rules! gen_text {
|
||||||
) => {
|
) => {
|
||||||
pub mod text {
|
pub mod text {
|
||||||
use {
|
use {
|
||||||
|
crate::{
|
||||||
|
Assembler,
|
||||||
|
macros::text::*,
|
||||||
|
},
|
||||||
lasso::{Rodeo, Spur},
|
lasso::{Rodeo, Spur},
|
||||||
logos::Logos,
|
logos::{Lexer, Logos, Span},
|
||||||
};
|
};
|
||||||
|
|
||||||
paste::paste!(literify::literify! {
|
paste::paste!(literify::literify! {
|
||||||
|
@ -52,8 +56,93 @@ macro_rules! gen_text {
|
||||||
#[token(",")] PSep,
|
#[token(",")] PSep,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||||
|
pub enum ErrorKind {
|
||||||
|
UnexpectedToken,
|
||||||
|
InvalidToken,
|
||||||
|
UnexpectedEnd,
|
||||||
|
InvalidSymbol,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
|
pub struct Error {
|
||||||
|
pub kind: ErrorKind,
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn assemble(asm: &mut Assembler, code: &str) -> Result<(), Error> {
|
||||||
|
fn next(lexer: &mut Lexer<Token>) -> Result<Token, ErrorKind> {
|
||||||
|
match lexer.next() {
|
||||||
|
Some(Ok(t)) => Ok(t),
|
||||||
|
Some(Err(())) => Err(ErrorKind::InvalidToken),
|
||||||
|
None => Err(ErrorKind::UnexpectedEnd),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn inner(asm: &mut Assembler, lexer: &mut Lexer<Token>) -> Result<(), ErrorKind> {
|
||||||
|
loop {
|
||||||
|
match lexer.next() {
|
||||||
|
Some(Ok(Token::Opcode(op))) => {
|
||||||
|
match op {
|
||||||
|
$(
|
||||||
|
$(hbbytecode::opcode::$opcode)|* => paste::paste!({
|
||||||
|
param_extract_iim!(lexer, $($param_i: $param_ty),*);
|
||||||
|
asm.[<i_param_ $ityn>](op, $($param_i),*);
|
||||||
|
}),
|
||||||
|
)*
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(Ok(Token::Label(_))) => {
|
||||||
|
todo!("Labels");
|
||||||
|
}
|
||||||
|
Some(Ok(Token::ISep)) => (),
|
||||||
|
Some(Ok(_)) => return Err(ErrorKind::UnexpectedToken),
|
||||||
|
Some(Err(())) => return Err(ErrorKind::InvalidToken),
|
||||||
|
None => return Ok(()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut lexer = Token::lexer(code);
|
||||||
|
inner(asm, &mut lexer)
|
||||||
|
.map_err(|kind| Error { kind, span: lexer.span() })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) use gen_text;
|
macro_rules! extract_pat {
|
||||||
|
($lexer:expr, $pat:pat) => {
|
||||||
|
let $pat = next($lexer)?
|
||||||
|
else { return Err(ErrorKind::UnexpectedToken) };
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! extract {
|
||||||
|
($lexer:expr, R, $id:ident) => {
|
||||||
|
extract_pat!($lexer, Token::Register($id));
|
||||||
|
};
|
||||||
|
($lexer:expr, I, $id:ident) => {
|
||||||
|
extract_pat!($lexer, Token::Integer($id));
|
||||||
|
};
|
||||||
|
($lexer:expr, u16, $id:ident) => {
|
||||||
|
extract_pat!($lexer, Token::Integer($id));
|
||||||
|
let $id = u16::try_from($id)
|
||||||
|
.map_err(|_| ErrorKind::InvalidToken)?;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! param_extract_iim {
|
||||||
|
($lexer:expr, $($id:ident: $ty:ident)? $(, $($tt:tt)*)?) => {
|
||||||
|
$(extract!($lexer, $ty, $id);)?
|
||||||
|
$(
|
||||||
|
extract_pat!($lexer, Token::PSep);
|
||||||
|
param_extract_iim!($lexer, $($tt)*);
|
||||||
|
)?
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) use {extract, extract_pat, gen_text, param_extract_iim};
|
||||||
|
|
Loading…
Reference in a new issue