diff --git a/ceres-asm/src/lib.rs b/ceres-asm/src/lib.rs index 3bff54d..73eba5f 100644 --- a/ceres-asm/src/lib.rs +++ b/ceres-asm/src/lib.rs @@ -44,7 +44,7 @@ impl<'a> Assembler<'a> { // cases that like, actually make sense to process Token::Load => { if let Some(new_token) = self.lexer.next() { - let signifier = Signifier::from_token(new_token)?; + let signifier = Signifier::from_token(&new_token)?; machine_code.push(self.load(signifier)?); } else { return Err(CeresAsmError::NoToken); @@ -58,12 +58,26 @@ impl<'a> Assembler<'a> { Ok(machine_code) } + // wrapping for lexer.next() with changing to result + fn next(&mut self) -> Result { + if let Some(token) = self.lexer.next() { + Ok(token) + } else { + Err(CeresAsmError::NoToken) + } + } + // load instruction assembly fn load(&mut self, signifier: Signifier) -> Result { - let opcode: u32 = 0b00001; - let signifier: u32 = signifier.as_bits() as u32; - let instruction: u32 = (opcode << 27) | (signifier << 24); - Ok(instruction) + let opcode = 0b00001 as u32; + let signifier = signifier.as_bits() as u32; + + let token = self.next()?; + let register = token.register_index()? as u32; + + let token = self.next()?; + let literal = token.literal()? as u32; + Ok((opcode << 27) | (signifier << 24) | (register << 20) | (0b0000u32 << 16) | literal) } } @@ -74,12 +88,12 @@ enum Signifier { } impl Signifier { - fn from_token(token: Token) -> Result { + fn from_token(token: &Token) -> Result { match token { Token::VideoMemory => Ok(Self::VideoMemory), Token::CartMemory => Ok(Self::CartMemory), Token::Immediate => Ok(Self::Immediate), - _ => Err(CeresAsmError::LazyBadToken { token }), + _ => Err(CeresAsmError::LazyBadToken { token: token.clone() }), } } @@ -94,7 +108,7 @@ impl Signifier { } /// token -#[derive(Logos, Debug, PartialEq)] +#[derive(Logos, Debug, PartialEq, Clone, Copy)] pub enum Token { // general stuff #[regex(";.+")] @@ -186,37 +200,31 @@ impl Token { } } - // returns true if given token is a register - fn is_register(&self) -> bool { - match self { - Self::ZeroRegister - | Self::ProgramCounter - | Self::StackPointer - | Self::ReturnAddress - | Self::ArgumentZero - | Self::ArgumentOne - | Self::ArgumentTwo - | Self::ReturnZero - | Self::ReturnOne - | Self::TemporaryRegister(_) - | Self::RegisterIndex(_) => true, - _ => false, - } - } - - // returns true if given token is a literal - fn is_literal(&self) -> bool { + // returns the index of a register + fn register_index(&self) -> Result { match self { - Self::HexLiteral(_) | Self::BinaryLiteral(_) | Self::DecimalLiteral(_) => true, - _ => false, + Self::RegisterIndex(index) => Ok(index.clone() as u8), + Self::TemporaryRegister(index) => Ok(index.clone() as u8 + 9), + Self::ZeroRegister => Ok(0), + Self::ProgramCounter => Ok(1), + Self::StackPointer => Ok(2), + Self::ReturnAddress => Ok(3), + Self::ArgumentZero => Ok(4), + Self::ArgumentOne => Ok(5), + Self::ArgumentTwo => Ok(6), + Self::ReturnZero => Ok(7), + Self::ReturnOne => Ok(8), + _ => return Err(CeresAsmError::LazyBadToken { token: self.clone() }), } } - // returns true if it's a valid memory location or immediate - fn is_signifier(&self) -> bool { + // returns literals as a u16 + fn literal(&self) -> Result { match self { - Self::VideoMemory | Self::CartMemory | Self::Immediate => true, - _ => false, + Self::HexLiteral(val) => Ok(*val), + Self::BinaryLiteral(val) => Ok(*val), + Self::DecimalLiteral(val) => Ok(*val), + _ => Err(CeresAsmError::LazyBadToken { token: self.clone() }), } } } diff --git a/src/main.rs b/src/main.rs index ade010a..cb1750e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,6 +16,11 @@ fn wrapper() -> Result<()> { // initialize the system let _sys = ceres_sys::System::init(); + let data = std::fs::read_to_string("test.asm").unwrap(); + let mut assembler = ceres_asm::Assembler::new(&data); + let asm = assembler.assemble().unwrap(); + asm.iter().for_each(|instruction| println!("ob{:032b}", instruction)); + /* // create a new graphics context let mut ctx = offbrand::Context::new( diff --git a/test.asm b/test.asm index 8795a95..adca895 100644 --- a/test.asm +++ b/test.asm @@ -1,2 +1,2 @@ ; a simple test -ld:immd $t0 0x5a5a +ld:immd $t6 0xffff