use core::fmt; use std::path::PathBuf; use std::str::FromStr; use common::prelude::{Instruction, Register}; use crate::model::{Module, Node, Opcode, Symbol, Token, TokenType}; use crate::{AssembleError, dsa, expect_token, expect_type, quick_hash}; pub struct Parser { tokens: Vec, nodes: Vec, } pub struct Program { pub nodes: Vec, } impl Program { pub fn new() -> Program { Program { nodes: vec![] } } pub fn add_module(&mut self, module: Vec) { self.nodes.extend(module); } pub fn parser(&mut self) -> Parser { Parser { tokens: vec![], nodes: self.nodes.clone(), } } } impl Parser { pub fn parse_nodes(tokens: Vec) -> Result, AssembleError> { let mut self_ = Parser { tokens: tokens.into_iter().rev().collect(), nodes: vec![], }; while !self_.tokens.is_empty() { let ins = self_.parse_instruction()?; self_.nodes.push(ins); } Ok(self_.nodes.clone()) } pub fn get_dependencies(nodes: &Vec) -> Result, AssembleError> { let mut dependencies = Vec::new(); for node in nodes { if let Opcode::Include = node.1 { let path = expect_token!(node.2.get(1).unwrap(), StringLit)?; dependencies.push(PathBuf::from(path)); } } Ok(dependencies) } pub fn expand_pseudo_ops( mut nodes: Vec, module: u64, ) -> Result, AssembleError> { let mut result = Vec::::with_capacity(nodes.len()); for node in nodes.iter_mut() { match node.1 { // Opcode::Db | Opcode::Dh | Opcode::Dw => todo!(), // Opcode::Resb | Opcode::Resh | Opcode::Resw => todo!(), Opcode::Push => { // inc SPR // STW reg, SPR let label = node.0.clone(); let reg = expect_token!(node.2.get(0).unwrap(), Register)?; match label { Some(label) => result.extend(dsa!( module, "{}: iadd spr, 4\n stw {}, spr", label, reg )), None => { result.extend(dsa!(module, "iadd spr, 4\n stw {}, spr", reg)) } } } _ => result.push(node.clone()), } } Ok(result) } fn parse_instruction(&mut self) -> Result { println!("tokens: {:?}", self.tokens); if self.tokens.is_empty() { unreachable!(); } // check if the Node starts with a label let label = expect_token!(self.peek_next()?, Symbol).ok(); if label.is_some() { self.tokens.pop(); } let opcode = expect_token!(self.next()?, Opcode)?; let args: Vec; match opcode { // R-type instructions Opcode::Mov | Opcode::Movs => { let reg1 = expect_type!(self.next()?, Register, Symbol)?; let reg2 = expect_type!(self.next()?, Register, Symbol)?; args = vec![reg1, reg2]; } Opcode::Ldb | Opcode::Ldbs | Opcode::Ldh | Opcode::Ldhs | Opcode::Ldw => { let base = expect_type!(self.next()?, Register, Symbol)?; let dest = expect_type!(self.next()?, Register, Symbol)?; let mut offset = Token::Immediate(0); if let Ok(next) = self.peek_next() { if let Ok(_) = expect_type!(next, Register, Immediate) { offset = self.next()?; } } args = vec![base, offset, dest]; } Opcode::Stb | Opcode::Sth | Opcode::Stw => { let base = expect_type!(self.next()?, Register, Symbol)?; let dest = expect_type!(self.next()?, Register, Symbol)?; let mut offset = Token::Immediate(0); if let Ok(next) = self.peek_next() { if let Ok(_) = expect_type!(next, Register, Immediate) { offset = self.next()?; } } args = vec![base, offset, dest]; } Opcode::Add | Opcode::Sub | Opcode::And | Opcode::Or | Opcode::Xor | Opcode::Nand | Opcode::Nor | Opcode::Xnor => { let src1 = expect_type!(self.next()?, Register, Symbol)?; let src2 = expect_type!(self.next()?, Register, Symbol)?; let dest = expect_type!(self.next()?, Register, Symbol)?; args = vec![src1, src2, dest]; } Opcode::Not | Opcode::Cmp => { let reg1 = expect_type!(self.next()?, Register, Symbol)?; let reg2 = expect_type!(self.next()?, Register, Symbol)?; args = vec![reg1, reg2]; } Opcode::Shl | Opcode::Shr => { let reg = expect_type!(self.next()?, Register, Symbol)?; let num = expect_type!(self.next()?, Immediate)?; args = vec![reg, num]; } Opcode::Inc | Opcode::Dec => { let reg = expect_type!(self.next()?, Register, Symbol)?; args = vec![reg]; } Opcode::Include => { let mod_name = expect_type!(self.next()?, Symbol)?; let path = expect_type!(self.next()?, StringLit)?; args = vec![mod_name, path]; } // J-type instructions Opcode::Jmp | Opcode::Jeq | Opcode::Jne | Opcode::Jgt | Opcode::Jge | Opcode::Jlt | Opcode::Jle => { let imm = expect_type!(self.next()?, Immediate, Symbol)?; args = vec![imm]; } // I-type instructions Opcode::Lui | Opcode::Lli | Opcode::Lwi | Opcode::Iadd | Opcode::Isub => { let reg = expect_type!(self.next()?, Register)?; let imm = expect_type!(self.next()?, Immediate, Symbol)?; args = vec![reg, imm]; } // D-type pseudoinstructions (data definition) Opcode::Resb | Opcode::Resh | Opcode::Resw => { let num = expect_type!(self.next()?, Immediate)?; args = vec![num]; } Opcode::Db | Opcode::Dh | Opcode::Dw => { args = self.parse_data_definition(opcode.clone())?; } // E-type pseudoinstructions (stack operations) Opcode::Push => { let reg = expect_type!(self.next()?, Register, Symbol)?; args = vec![reg]; } Opcode::Pop => { let reg = expect_type!(self.next()?, Register, Symbol)?; args = vec![reg]; } // Special instructions Opcode::Int => { let val = expect_type!(self.next()?, Immediate)?; args = vec![val]; } // Instructions with no arguments Opcode::Hlt | Opcode::Nop | Opcode::Irt => { args = Vec::new(); } } Ok(Node(label, opcode, args)) } fn parse_data_definition( &mut self, opcode: Opcode, ) -> Result, AssembleError> { let mut values = Vec::new(); let _name = self.expect(TokenType::Symbol)?; values.push(self.tokens.pop().unwrap()); match opcode { Opcode::Db => { // db can take string literals or u8 immediates while !self.tokens.is_empty() { match self.tokens.last().unwrap() { Token::StringLit(_) => { values.push(self.tokens.pop().unwrap()); } Token::Immediate(val) if *val <= u8::MAX as u32 => { values.push(self.tokens.pop().unwrap()); } _ => break, } } } Opcode::Dh => { // dh can take u16 immediates while !self.tokens.is_empty() { if let Token::Immediate(val) = self.tokens.last().unwrap() { if *val <= u16::MAX as u32 { values.push(self.tokens.pop().unwrap()); } else { break; } } else { break; } } } Opcode::Dw => { // dw can take u32 immediates while !self.tokens.is_empty() { if let Token::Immediate(_) = self.tokens.last().unwrap() { values.push(self.tokens.pop().unwrap()); } else { break; } } } _ => unreachable!(), } Ok(values) } fn next(&mut self) -> Result { if self.tokens.is_empty() { Err(AssembleError::UnexpectedEof) } else { Ok(self.tokens.pop().unwrap()) } } fn peek_next(&mut self) -> Result { if self.tokens.is_empty() { Err(AssembleError::UnexpectedEof) } else { Ok(self.tokens.last().unwrap().clone()) } } fn expect(&mut self, type_: TokenType) -> Result { let tok = self.next()?; if TokenType::from_token(&tok) == type_ { Ok(tok) } else { Err(AssembleError::UnexpectedToken(tok, type_)) } } fn expect_any(&mut self, types: &[TokenType]) -> Result { let tok = self.next()?; if types.contains(&TokenType::from_token(&tok)) { Ok(tok) } else { Err(AssembleError::UnexpectedToken(tok, types[0])) } } fn maybe_expect(&mut self, types: &[TokenType]) -> Option { let tok = self.peek_next().ok()?; if types.contains(&TokenType::from_token(&tok)) { Some(tok.clone()) } else { None } } }