misc: fixed some shit thanks to Clippy, have fun with the merge conflicts lmao
This commit is contained in:
+12
-10
@@ -1,3 +1,5 @@
|
|||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
use crate::{AssembleError, parser::Opcode};
|
use crate::{AssembleError, parser::Opcode};
|
||||||
use common::prelude::Register;
|
use common::prelude::Register;
|
||||||
|
|
||||||
@@ -26,9 +28,9 @@ pub fn lexer(mut program: String) -> Result<Vec<Token>, AssembleError> {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if token.starts_with('"') {
|
if let Some(stripped) = token.strip_prefix('"') {
|
||||||
literal.push_str(&token[1..]);
|
literal.push_str(stripped);
|
||||||
println!("literal: {}", literal);
|
println!("literal: {literal}");
|
||||||
}
|
}
|
||||||
|
|
||||||
if !literal.is_empty() {
|
if !literal.is_empty() {
|
||||||
@@ -72,7 +74,7 @@ pub fn lexer(mut program: String) -> Result<Vec<Token>, AssembleError> {
|
|||||||
Ok(tokens)
|
Ok(tokens)
|
||||||
}
|
}
|
||||||
pub fn parse_register(token: &str) -> Result<Option<Token>, AssembleError> {
|
pub fn parse_register(token: &str) -> Result<Option<Token>, AssembleError> {
|
||||||
Ok(Register::try_from(token).map(|r| Token::Register(r)).ok())
|
Ok(Register::try_from(token).map(Token::Register).ok())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_opcode(token: &str) -> Result<Option<Token>, AssembleError> {
|
pub fn parse_opcode(token: &str) -> Result<Option<Token>, AssembleError> {
|
||||||
@@ -117,23 +119,23 @@ pub fn parse_binary(token: &str) -> Result<Option<Token>, AssembleError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_decimal(token: &str) -> Result<Option<Token>, AssembleError> {
|
pub fn parse_decimal(token: &str) -> Result<Option<Token>, AssembleError> {
|
||||||
if !token.parse::<u32>().is_ok() {
|
if token.parse::<u32>().is_err() {
|
||||||
return Ok(None);
|
Ok(None)
|
||||||
} else {
|
} else {
|
||||||
return Ok(Some(Token::Immediate(token.parse().unwrap())));
|
Ok(Some(Token::Immediate(token.parse().unwrap())))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_label(token: &str) -> Result<Option<Token>, AssembleError> {
|
pub fn parse_label(token: &str) -> Result<Option<Token>, AssembleError> {
|
||||||
if !token.ends_with(":") {
|
if !token.ends_with(":") {
|
||||||
return Ok(None);
|
Ok(None)
|
||||||
} else {
|
} else {
|
||||||
return Ok(Some(Token::Symbol(token[0..token.len() - 1].to_string())));
|
Ok(Some(Token::Symbol(token[0..token.len() - 1].to_string())))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_symbol(token: &str) -> Result<Option<Token>, AssembleError> {
|
pub fn parse_symbol(token: &str) -> Result<Option<Token>, AssembleError> {
|
||||||
if token.chars().nth(0).unwrap().is_numeric() {
|
if token.chars().next().unwrap().is_numeric() {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use crate::{lexer::Token, parser::TokenType};
|
|||||||
pub mod lexer;
|
pub mod lexer;
|
||||||
pub mod parser;
|
pub mod parser;
|
||||||
|
|
||||||
pub fn assemble(src: &str) -> Vec<Instruction> {
|
pub fn assemble(_src: &str) -> Vec<Instruction> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@ impl fmt::Display for AssembleError {
|
|||||||
match self {
|
match self {
|
||||||
AssembleError::Generic => write!(f, "Generic error"),
|
AssembleError::Generic => write!(f, "Generic error"),
|
||||||
AssembleError::UnexpectedToken(tok, expected) => {
|
AssembleError::UnexpectedToken(tok, expected) => {
|
||||||
write!(f, "Unexpected token {:?}, expected {:?}", tok, expected)
|
write!(f, "Unexpected token {tok:?}, expected {expected:?}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,11 +6,11 @@ fn main() {
|
|||||||
let program = fs::read_to_string("../resources/dsa/print.dsa").unwrap();
|
let program = fs::read_to_string("../resources/dsa/print.dsa").unwrap();
|
||||||
let tokens = lexer::lexer(program).unwrap();
|
let tokens = lexer::lexer(program).unwrap();
|
||||||
|
|
||||||
println!("{:?}", tokens);
|
println!("{tokens:?}");
|
||||||
|
|
||||||
let parser = Parser::new(tokens);
|
let parser = Parser::new(tokens);
|
||||||
|
|
||||||
for node in parser {
|
for node in parser {
|
||||||
println!("{:?}", node);
|
println!("{node:?}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+89
-66
@@ -1,6 +1,4 @@
|
|||||||
use std::path::Iter;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use common::prelude::Register;
|
|
||||||
|
|
||||||
use crate::AssembleError;
|
use crate::AssembleError;
|
||||||
use crate::lexer::{Symbol, Token};
|
use crate::lexer::{Symbol, Token};
|
||||||
@@ -58,6 +56,7 @@ impl TokenType {
|
|||||||
// TODO: MAKE SURE I DO THE BIT SHIFT FOR LUI CODEGEN
|
// TODO: MAKE SURE I DO THE BIT SHIFT FOR LUI CODEGEN
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
#[expect(dead_code)]
|
||||||
pub struct Node(Option<Symbol>, Opcode, Vec<Token>);
|
pub struct Node(Option<Symbol>, Opcode, Vec<Token>);
|
||||||
|
|
||||||
impl Iterator for Parser {
|
impl Iterator for Parser {
|
||||||
@@ -116,7 +115,8 @@ impl Parser {
|
|||||||
Opcode::Ldb | Opcode::Ldbs | Opcode::Ldh | Opcode::Ldhs | Opcode::Ldw => {
|
Opcode::Ldb | Opcode::Ldbs | Opcode::Ldh | Opcode::Ldhs | Opcode::Ldw => {
|
||||||
let base = self.expect_any(&[TokenType::Register, TokenType::Symbol])?;
|
let base = self.expect_any(&[TokenType::Register, TokenType::Symbol])?;
|
||||||
let dest = self.expect_any(&[TokenType::Register, TokenType::Symbol])?;
|
let dest = self.expect_any(&[TokenType::Register, TokenType::Symbol])?;
|
||||||
let offset = self.maybe_expect(&[TokenType::Register, TokenType::Immediate]);
|
let offset =
|
||||||
|
self.maybe_expect(&[TokenType::Register, TokenType::Immediate]);
|
||||||
if offset.is_some() {
|
if offset.is_some() {
|
||||||
self.tokens.pop();
|
self.tokens.pop();
|
||||||
args = vec![base, offset.unwrap(), dest];
|
args = vec![base, offset.unwrap(), dest];
|
||||||
@@ -129,7 +129,8 @@ impl Parser {
|
|||||||
let base = self.expect_any(&[TokenType::Register, TokenType::Symbol])?;
|
let base = self.expect_any(&[TokenType::Register, TokenType::Symbol])?;
|
||||||
let dest = self.expect_any(&[TokenType::Register, TokenType::Symbol])?;
|
let dest = self.expect_any(&[TokenType::Register, TokenType::Symbol])?;
|
||||||
|
|
||||||
let offset = self.maybe_expect(&[TokenType::Register, TokenType::Immediate]);
|
let offset =
|
||||||
|
self.maybe_expect(&[TokenType::Register, TokenType::Immediate]);
|
||||||
if offset.is_some() {
|
if offset.is_some() {
|
||||||
self.tokens.pop();
|
self.tokens.pop();
|
||||||
args = vec![base, offset.unwrap(), dest];
|
args = vec![base, offset.unwrap(), dest];
|
||||||
@@ -224,10 +225,13 @@ impl Parser {
|
|||||||
Ok(Node(label, opcode, args))
|
Ok(Node(label, opcode, args))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_data_definition(&mut self, opcode: Opcode) -> Result<Vec<Token>, AssembleError> {
|
fn parse_data_definition(
|
||||||
|
&mut self,
|
||||||
|
opcode: Opcode,
|
||||||
|
) -> Result<Vec<Token>, AssembleError> {
|
||||||
let mut values = Vec::new();
|
let mut values = Vec::new();
|
||||||
|
|
||||||
let name = self.expect(TokenType::Symbol)?;
|
let _name = self.expect(TokenType::Symbol)?;
|
||||||
values.push(self.tokens.pop().unwrap());
|
values.push(self.tokens.pop().unwrap());
|
||||||
|
|
||||||
match opcode {
|
match opcode {
|
||||||
@@ -301,7 +305,7 @@ impl Parser {
|
|||||||
fn maybe_expect(&mut self, types: &[TokenType]) -> Option<Token> {
|
fn maybe_expect(&mut self, types: &[TokenType]) -> Option<Token> {
|
||||||
let tok = self.tokens.last().unwrap();
|
let tok = self.tokens.last().unwrap();
|
||||||
|
|
||||||
if types.contains(&TokenType::from_token(&tok)) {
|
if types.contains(&TokenType::from_token(tok)) {
|
||||||
Some(tok.clone())
|
Some(tok.clone())
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
@@ -363,70 +367,89 @@ pub enum Opcode {
|
|||||||
Lwi,
|
Lwi,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum OpcodeFromStrError {
|
||||||
|
InvalidRegister(&'static str),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Display for OpcodeFromStrError {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
Self::InvalidRegister(reg) => write!(f, "register does not exist: {reg}"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::error::Error for OpcodeFromStrError {}
|
||||||
|
|
||||||
|
impl FromStr for Opcode {
|
||||||
|
type Err = OpcodeFromStrError;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
match s.to_lowercase().as_str() {
|
||||||
|
"nop" => Ok(Self::Nop),
|
||||||
|
"mov" => Ok(Self::Mov),
|
||||||
|
"movs" => Ok(Self::Movs),
|
||||||
|
"ldb" => Ok(Self::Ldb),
|
||||||
|
"ldbs" => Ok(Self::Ldbs),
|
||||||
|
"ldh" => Ok(Self::Ldh),
|
||||||
|
"ldhs" => Ok(Self::Ldhs),
|
||||||
|
"ldw" => Ok(Self::Ldw),
|
||||||
|
"stb" => Ok(Self::Stb),
|
||||||
|
"sth" => Ok(Self::Sth),
|
||||||
|
"stw" => Ok(Self::Stw),
|
||||||
|
"lli" => Ok(Self::Lli),
|
||||||
|
"lui" => Ok(Self::Lui),
|
||||||
|
"jmp" => Ok(Self::Jmp),
|
||||||
|
"jeq" => Ok(Self::Jeq),
|
||||||
|
"jne" => Ok(Self::Jne),
|
||||||
|
"jgt" => Ok(Self::Jgt),
|
||||||
|
"jge" => Ok(Self::Jge),
|
||||||
|
"jlt" => Ok(Self::Jlt),
|
||||||
|
"jle" => Ok(Self::Jle),
|
||||||
|
"cmp" => Ok(Self::Cmp),
|
||||||
|
"inc" => Ok(Self::Inc),
|
||||||
|
"dec" => Ok(Self::Dec),
|
||||||
|
"shl" => Ok(Self::Shl),
|
||||||
|
"shr" => Ok(Self::Shr),
|
||||||
|
"add" => Ok(Self::Add),
|
||||||
|
"sub" => Ok(Self::Sub),
|
||||||
|
"and" => Ok(Self::And),
|
||||||
|
"or" => Ok(Self::Or),
|
||||||
|
"not" => Ok(Self::Not),
|
||||||
|
"xor" => Ok(Self::Xor),
|
||||||
|
"nand" => Ok(Self::Nand),
|
||||||
|
"nor" => Ok(Self::Nor),
|
||||||
|
"xnor" => Ok(Self::Xnor),
|
||||||
|
"int" => Ok(Self::Int),
|
||||||
|
"irt" => Ok(Self::Irt),
|
||||||
|
"hlt" => Ok(Self::Hlt),
|
||||||
|
"iadd" => Ok(Self::Iadd),
|
||||||
|
"isub" => Ok(Self::Isub),
|
||||||
|
"db" => Ok(Self::Db),
|
||||||
|
"dh" => Ok(Self::Dh),
|
||||||
|
"dw" => Ok(Self::Dw),
|
||||||
|
"resb" => Ok(Self::Resb),
|
||||||
|
"resh" => Ok(Self::Resh),
|
||||||
|
"resw" => Ok(Self::Resw),
|
||||||
|
"push" => Ok(Self::Push),
|
||||||
|
"pop" => Ok(Self::Pop),
|
||||||
|
"lwi" => Ok(Self::Lwi),
|
||||||
|
_ => Err(OpcodeFromStrError::InvalidRegister("unknown opcode")),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Opcode {
|
impl Opcode {
|
||||||
pub const OPCODES: &[&str] = &[
|
pub const OPCODES: &[&str] = &[
|
||||||
// Real instructions (0x00-0x26)
|
// Real instructions (0x00-0x26)
|
||||||
"nop", "mov", "movs", "ldb", "ldbs", "ldh", "ldhs", "ldw", "stb", "sth", "stw", "lli",
|
"nop", "mov", "movs", "ldb", "ldbs", "ldh", "ldhs", "ldw", "stb", "sth", "stw",
|
||||||
"lui", "jmp", "jeq", "jne", "jgt", "jge", "jlt", "jle", "cmp", "inc", "dec", "shl", "shr",
|
"lli", "lui", "jmp", "jeq", "jne", "jgt", "jge", "jlt", "jle", "cmp", "inc",
|
||||||
"add", "sub", "and", "or", "not", "xor", "nand", "nor", "xnor", "int", "irt", "hlt",
|
"dec", "shl", "shr", "add", "sub", "and", "or", "not", "xor", "nand", "nor",
|
||||||
"iadd", "isub", // Pseudo-instructions
|
"xnor", "int", "irt", "hlt", "iadd", "isub", // Pseudo-instructions
|
||||||
"db", "dh", "dw", "resb", "resh", "resw", "push", "pop", "lwi",
|
"db", "dh", "dw", "resb", "resh", "resw", "push", "pop", "lwi",
|
||||||
];
|
];
|
||||||
|
|
||||||
pub fn from_str(s: &str) -> Option<Self> {
|
|
||||||
match s.to_lowercase().as_str() {
|
|
||||||
"nop" => Some(Self::Nop),
|
|
||||||
"mov" => Some(Self::Mov),
|
|
||||||
"movs" => Some(Self::Movs),
|
|
||||||
"ldb" => Some(Self::Ldb),
|
|
||||||
"ldbs" => Some(Self::Ldbs),
|
|
||||||
"ldh" => Some(Self::Ldh),
|
|
||||||
"ldhs" => Some(Self::Ldhs),
|
|
||||||
"ldw" => Some(Self::Ldw),
|
|
||||||
"stb" => Some(Self::Stb),
|
|
||||||
"sth" => Some(Self::Sth),
|
|
||||||
"stw" => Some(Self::Stw),
|
|
||||||
"lli" => Some(Self::Lli),
|
|
||||||
"lui" => Some(Self::Lui),
|
|
||||||
"jmp" => Some(Self::Jmp),
|
|
||||||
"jeq" => Some(Self::Jeq),
|
|
||||||
"jne" => Some(Self::Jne),
|
|
||||||
"jgt" => Some(Self::Jgt),
|
|
||||||
"jge" => Some(Self::Jge),
|
|
||||||
"jlt" => Some(Self::Jlt),
|
|
||||||
"jle" => Some(Self::Jle),
|
|
||||||
"cmp" => Some(Self::Cmp),
|
|
||||||
"inc" => Some(Self::Inc),
|
|
||||||
"dec" => Some(Self::Dec),
|
|
||||||
"shl" => Some(Self::Shl),
|
|
||||||
"shr" => Some(Self::Shr),
|
|
||||||
"add" => Some(Self::Add),
|
|
||||||
"sub" => Some(Self::Sub),
|
|
||||||
"and" => Some(Self::And),
|
|
||||||
"or" => Some(Self::Or),
|
|
||||||
"not" => Some(Self::Not),
|
|
||||||
"xor" => Some(Self::Xor),
|
|
||||||
"nand" => Some(Self::Nand),
|
|
||||||
"nor" => Some(Self::Nor),
|
|
||||||
"xnor" => Some(Self::Xnor),
|
|
||||||
"int" => Some(Self::Int),
|
|
||||||
"irt" => Some(Self::Irt),
|
|
||||||
"hlt" => Some(Self::Hlt),
|
|
||||||
"iadd" => Some(Self::Iadd),
|
|
||||||
"isub" => Some(Self::Isub),
|
|
||||||
"db" => Some(Self::Db),
|
|
||||||
"dh" => Some(Self::Dh),
|
|
||||||
"dw" => Some(Self::Dw),
|
|
||||||
"resb" => Some(Self::Resb),
|
|
||||||
"resh" => Some(Self::Resh),
|
|
||||||
"resw" => Some(Self::Resw),
|
|
||||||
"push" => Some(Self::Push),
|
|
||||||
"pop" => Some(Self::Pop),
|
|
||||||
"lwi" => Some(Self::Lwi),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn to_opcode_value(&self) -> Option<u8> {
|
pub fn to_opcode_value(&self) -> Option<u8> {
|
||||||
match self {
|
match self {
|
||||||
Self::Nop => Some(0x00),
|
Self::Nop => Some(0x00),
|
||||||
|
|||||||
@@ -59,9 +59,9 @@ impl Component for ControlPanel {
|
|||||||
|
|
||||||
// Step
|
// Step
|
||||||
if ui.button("Step").clicked() {
|
if ui.button("Step").clicked() {
|
||||||
self.sender
|
self.sender.send(Command::Step).unwrap_or_else(|_| {
|
||||||
.send(Command::Step)
|
state.error = Some("Failed to send command".to_string());
|
||||||
.unwrap_or_else(|_| state.error = Some("Failed to send command".to_string()));
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ui.separator();
|
ui.separator();
|
||||||
@@ -78,12 +78,13 @@ impl Component for ControlPanel {
|
|||||||
ui.label(format!("Instructions: {}", state.instructions));
|
ui.label(format!("Instructions: {}", state.instructions));
|
||||||
ui.label(format!("PC: 0x{:08X}", state.reg_file.get(Register::Pcx)));
|
ui.label(format!("PC: 0x{:08X}", state.reg_file.get(Register::Pcx)));
|
||||||
|
|
||||||
let instruction = match Instruction::decode(state.reg_file.get(Register::Cir)) {
|
let instruction = Instruction::decode(state.reg_file.get(Register::Cir))
|
||||||
Ok(instruction) => instruction.to_string(),
|
.map_or_else(
|
||||||
Err(_) => "Invalid Instruction".to_string(),
|
|_| "Invalid Instruction".to_string(),
|
||||||
};
|
|instruction| instruction.to_string(),
|
||||||
|
);
|
||||||
|
|
||||||
ui.label(format!("Instruction: {}", instruction));
|
ui.label(format!("Instruction: {instruction}"));
|
||||||
});
|
});
|
||||||
|
|
||||||
render_register_table(state, ui, ctx);
|
render_register_table(state, ui, ctx);
|
||||||
|
|||||||
@@ -309,7 +309,7 @@ impl Editor {
|
|||||||
self.sender
|
self.sender
|
||||||
.send(Command::Write(self.load_offset, self.output.clone()))
|
.send(Command::Write(self.load_offset, self.output.clone()))
|
||||||
.unwrap_or_else(|_| {
|
.unwrap_or_else(|_| {
|
||||||
self.error = Some("Failed to send command".to_string())
|
self.error = Some("Failed to send command".to_string());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -326,7 +326,7 @@ impl Editor {
|
|||||||
// Resets the emulator and all attached devices
|
// Resets the emulator and all attached devices
|
||||||
if ui.button("Reset Emulator").clicked() {
|
if ui.button("Reset Emulator").clicked() {
|
||||||
self.sender.send(Command::Reset).unwrap_or_else(|_| {
|
self.sender.send(Command::Reset).unwrap_or_else(|_| {
|
||||||
self.error = Some("Failed to send command".to_string())
|
self.error = Some("Failed to send command".to_string());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user