misc: apply clippy lints
This commit is contained in:
+20
-23
@@ -1,11 +1,8 @@
|
||||
use common::{
|
||||
args, instructions,
|
||||
prelude::{ITypeArgs, Instruction, Interrupt, RTypeArgs, Register},
|
||||
};
|
||||
use common::{args, prelude::*};
|
||||
|
||||
use crate::{
|
||||
AssembleError, expect_token, expect_type,
|
||||
model::{Node, Opcode, Token, TokenType},
|
||||
AssembleError, expect_token,
|
||||
model::{Node, Opcode},
|
||||
};
|
||||
|
||||
pub fn codegen(nodes: Vec<Node>) -> Result<Vec<Instruction>, AssembleError> {
|
||||
@@ -25,12 +22,12 @@ fn build_instruction(node: Node) -> Result<Instruction, AssembleError> {
|
||||
match opcode {
|
||||
Opcode::Nop => Ok(Instruction::Nop),
|
||||
Opcode::Mov => {
|
||||
let src = expect_token!(args.get(0).unwrap(), Register)?;
|
||||
let src = expect_token!(args.first().unwrap(), Register)?;
|
||||
let dest = expect_token!(args.get(1).unwrap(), Register)?;
|
||||
Ok(Instruction::Mov(args!(R, sr1: src, dr: dest)))
|
||||
}
|
||||
Opcode::Movs => {
|
||||
let src = expect_token!(args.get(0).unwrap(), Register)?;
|
||||
let src = expect_token!(args.first().unwrap(), Register)?;
|
||||
let dest = expect_token!(args.get(1).unwrap(), Register)?;
|
||||
Ok(Instruction::MovSigned(args!(R, sr1: src, dr: dest)))
|
||||
}
|
||||
@@ -42,7 +39,7 @@ fn build_instruction(node: Node) -> Result<Instruction, AssembleError> {
|
||||
| Opcode::Stb
|
||||
| Opcode::Stw
|
||||
| Opcode::Sth => {
|
||||
let base = expect_token!(args.get(0).unwrap(), Register)?;
|
||||
let base = expect_token!(args.first().unwrap(), Register)?;
|
||||
let dest = expect_token!(args.get(1).unwrap(), Register)?;
|
||||
let offset = expect_token!(args.get(2).unwrap(), Immediate)?;
|
||||
let args = args!(I, immediate: offset as u16, r1: base, r2: dest);
|
||||
@@ -60,14 +57,14 @@ fn build_instruction(node: Node) -> Result<Instruction, AssembleError> {
|
||||
}
|
||||
}
|
||||
Opcode::Lli => {
|
||||
let value = expect_token!(args.get(0).unwrap(), Immediate)?;
|
||||
let value = expect_token!(args.first().unwrap(), Immediate)?;
|
||||
let dest = expect_token!(args.get(1).unwrap(), Register)?;
|
||||
let args = args!(I, immediate: value as u16, r1: dest);
|
||||
|
||||
Ok(Instruction::LoadLowerImmediate(args))
|
||||
}
|
||||
Opcode::Lui => {
|
||||
let value = expect_token!(args.get(0).unwrap(), Immediate)? >> 16;
|
||||
let value = expect_token!(args.first().unwrap(), Immediate)? >> 16;
|
||||
let dest = expect_token!(args.get(1).unwrap(), Register)?;
|
||||
let args = args!(I, immediate: value as u16, r1: dest);
|
||||
|
||||
@@ -80,7 +77,7 @@ fn build_instruction(node: Node) -> Result<Instruction, AssembleError> {
|
||||
| Opcode::Jge
|
||||
| Opcode::Jlt
|
||||
| Opcode::Jle => {
|
||||
let address = expect_token!(args.get(0).unwrap(), Immediate)?;
|
||||
let address = expect_token!(args.first().unwrap(), Immediate)?;
|
||||
let offset = expect_token!(args.get(1).unwrap(), Register)?;
|
||||
let args = args!(I, immediate: address as u16, r1: offset);
|
||||
|
||||
@@ -96,25 +93,25 @@ fn build_instruction(node: Node) -> Result<Instruction, AssembleError> {
|
||||
}
|
||||
}
|
||||
Opcode::Cmp => {
|
||||
let left = expect_token!(args.get(0).unwrap(), Register)?;
|
||||
let left = expect_token!(args.first().unwrap(), Register)?;
|
||||
let right = expect_token!(args.get(1).unwrap(), Register)?;
|
||||
Ok(Instruction::Compare(args!(R, sr1: left, sr2: right)))
|
||||
}
|
||||
Opcode::Inc => {
|
||||
let reg = expect_token!(args.get(0).unwrap(), Register)?;
|
||||
let reg = expect_token!(args.first().unwrap(), Register)?;
|
||||
Ok(Instruction::Increment(args!(R, sr1: reg)))
|
||||
}
|
||||
Opcode::Dec => {
|
||||
let reg = expect_token!(args.get(0).unwrap(), Register)?;
|
||||
let reg = expect_token!(args.first().unwrap(), Register)?;
|
||||
Ok(Instruction::Decrement(args!(R, sr1: reg)))
|
||||
}
|
||||
Opcode::Shl => {
|
||||
let reg = expect_token!(args.get(0).unwrap(), Register)?;
|
||||
let reg = expect_token!(args.first().unwrap(), Register)?;
|
||||
let amount = expect_token!(args.get(1).unwrap(), Immediate)? as u8;
|
||||
Ok(Instruction::ShiftLeft(args!(R, sr1: reg, shamt: amount)))
|
||||
}
|
||||
Opcode::Shr => {
|
||||
let reg = expect_token!(args.get(0).unwrap(), Register)?;
|
||||
let reg = expect_token!(args.first().unwrap(), Register)?;
|
||||
let amount = expect_token!(args.get(1).unwrap(), Immediate)? as u8;
|
||||
Ok(Instruction::ShiftRight(args!(R, sr1: reg, shamt: amount)))
|
||||
}
|
||||
@@ -126,7 +123,7 @@ fn build_instruction(node: Node) -> Result<Instruction, AssembleError> {
|
||||
| Opcode::Nand
|
||||
| Opcode::Nor
|
||||
| Opcode::Xnor => {
|
||||
let left = expect_token!(args.get(0).unwrap(), Register)?;
|
||||
let left = expect_token!(args.first().unwrap(), Register)?;
|
||||
let right = expect_token!(args.get(1).unwrap(), Register)?;
|
||||
let dest = expect_token!(args.get(2).unwrap(), Register)?;
|
||||
let args = args!(R, sr1: left, sr2: right, dr: dest);
|
||||
@@ -144,7 +141,7 @@ fn build_instruction(node: Node) -> Result<Instruction, AssembleError> {
|
||||
}
|
||||
}
|
||||
Opcode::Iadd | Opcode::Isub => {
|
||||
let reg = expect_token!(args.get(0).unwrap(), Register)?;
|
||||
let reg = expect_token!(args.first().unwrap(), Register)?;
|
||||
let immediate = expect_token!(args.get(1).unwrap(), Immediate)? as u16;
|
||||
let dest = expect_token!(args.get(2).unwrap(), Register)?;
|
||||
let args = args!(I, immediate: immediate, r1: reg, r2: dest);
|
||||
@@ -156,22 +153,22 @@ fn build_instruction(node: Node) -> Result<Instruction, AssembleError> {
|
||||
}
|
||||
}
|
||||
Opcode::Not => {
|
||||
let reg = expect_token!(args.get(0).unwrap(), Register)?;
|
||||
let reg = expect_token!(args.first().unwrap(), Register)?;
|
||||
let dest = expect_token!(args.get(1).unwrap(), Register)?;
|
||||
Ok(Instruction::Not(args!(R, sr1: reg, dr: dest)))
|
||||
}
|
||||
Opcode::Int => {
|
||||
let code = expect_token!(args.get(0).unwrap(), Immediate)? as u8;
|
||||
let code = expect_token!(args.first().unwrap(), Immediate)? as u8;
|
||||
Ok(Instruction::Interrupt(Interrupt::Software(code)))
|
||||
}
|
||||
Opcode::Irt => Ok(Instruction::IntReturn),
|
||||
Opcode::Hlt => Ok(Instruction::Halt),
|
||||
Opcode::Data => {
|
||||
let immediate = expect_token!(args.get(0).unwrap(), Immediate)?;
|
||||
let immediate = expect_token!(args.first().unwrap(), Immediate)?;
|
||||
Ok(Instruction::Data(immediate))
|
||||
}
|
||||
Opcode::Segment => {
|
||||
let immediate = expect_token!(args.get(0).unwrap(), Immediate)?;
|
||||
let immediate = expect_token!(args.first().unwrap(), Immediate)?;
|
||||
Ok(Instruction::Segment(immediate))
|
||||
}
|
||||
Opcode::Db
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use common::prelude::Register;
|
||||
|
||||
use crate::{
|
||||
AssembleError, dsa, expect_token, expect_type,
|
||||
model::{Node, Opcode, Token, TokenType},
|
||||
AssembleError, expect_token, expect_type,
|
||||
model::{Node, Opcode, Token},
|
||||
node,
|
||||
};
|
||||
|
||||
@@ -13,7 +13,7 @@ pub fn expand_pseudo_ops(
|
||||
let mut result = Vec::<Node>::with_capacity(nodes.len());
|
||||
|
||||
for node in nodes.iter_mut() {
|
||||
if let Err(_) = try_expand(node.clone(), &mut result, module) {
|
||||
if try_expand(node.clone(), &mut result, module).is_err() {
|
||||
result.push(node.clone());
|
||||
}
|
||||
}
|
||||
@@ -22,9 +22,9 @@ pub fn expand_pseudo_ops(
|
||||
}
|
||||
|
||||
fn try_expand(
|
||||
mut node: Node,
|
||||
node: Node,
|
||||
result: &mut Vec<Node>,
|
||||
module: u64,
|
||||
_module: u64,
|
||||
) -> Result<(), AssembleError> {
|
||||
match node.opcode() {
|
||||
Opcode::Push => expand_push(node.clone(), result)?,
|
||||
@@ -176,7 +176,7 @@ fn expand_dx(current: Node, nodes: &mut Vec<Node>) -> Result<(), AssembleError>
|
||||
let mut buffer = vec![];
|
||||
|
||||
let mut args = current.args();
|
||||
let label = args.remove(0);
|
||||
let _label = args.remove(0);
|
||||
|
||||
for word in process_dx_data(args, size)? {
|
||||
buffer.push(node!(None, Opcode::Data, Token::Immediate(word)));
|
||||
|
||||
+29
-32
@@ -6,7 +6,7 @@ use std::{
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
use common::prelude::Instruction;
|
||||
use common::prelude::*;
|
||||
|
||||
use crate::{
|
||||
codegen::codegen,
|
||||
@@ -38,7 +38,7 @@ pub fn assemble(src: &Path) -> Result<Vec<Instruction>, AssembleError> {
|
||||
|
||||
let instructions = codegen(nodes)?;
|
||||
for inst in instructions.iter() {
|
||||
println!("{}", inst);
|
||||
println!("{inst}");
|
||||
}
|
||||
|
||||
Ok(instructions)
|
||||
@@ -87,7 +87,7 @@ fn prepare_dependency(
|
||||
);
|
||||
|
||||
for n in nodes.iter() {
|
||||
println!("{}", n);
|
||||
println!("{n}");
|
||||
}
|
||||
|
||||
program.add_module(nodes);
|
||||
@@ -161,86 +161,83 @@ fn log(message: &str) {
|
||||
|
||||
// create a macro that lexes and parses the input string into Nodes
|
||||
#[macro_export]
|
||||
#[macro_use]
|
||||
macro_rules! dsa {
|
||||
// Version with formatting arguments
|
||||
($hash:expr, $input:expr, $($args:expr),+) => {{
|
||||
let input = format!($input, $($args),+);
|
||||
let tokens = crate::lexer::lexer(input, $hash)?;
|
||||
let parsed = crate::parser::Parser::parse_nodes(tokens)?;
|
||||
let tokens = $crate::lexer::lexer(input, $hash)?;
|
||||
let parsed = $crate::parser::Parser::parse_nodes(tokens)?;
|
||||
parsed
|
||||
}};
|
||||
// Version without formatting
|
||||
($hash:expr, $input:expr) => {{
|
||||
let input = String::from($input);
|
||||
let tokens = crate::lexer::lexer(input, $hash)?;
|
||||
let parsed = crate::parser::Parser::parse_nodes(tokens)?;
|
||||
let tokens = $crate::lexer::lexer(input, $hash)?;
|
||||
let parsed = $crate::parser::Parser::parse_nodes(tokens)?;
|
||||
parsed
|
||||
}};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
#[macro_use]
|
||||
macro_rules! expect_token {
|
||||
($token:expr, Symbol) => {
|
||||
match $token {
|
||||
Token::Symbol(value) => Ok(value.clone()),
|
||||
other => Err(AssembleError::UnexpectedToken(
|
||||
$crate::model::Token::Symbol(value) => Ok(value.clone()),
|
||||
other => Err($crate::AssembleError::UnexpectedToken(
|
||||
other.clone(),
|
||||
TokenType::Symbol,
|
||||
$crate::model::TokenType::Symbol,
|
||||
)),
|
||||
}
|
||||
};
|
||||
($token:expr, Register) => {
|
||||
match $token {
|
||||
Token::Register(value) => Ok(value.clone()),
|
||||
other => Err(AssembleError::UnexpectedToken(
|
||||
$crate::model::Token::Register(value) => Ok(value.clone()),
|
||||
other => Err($crate::AssembleError::UnexpectedToken(
|
||||
other.clone(),
|
||||
TokenType::Register,
|
||||
$crate::model::TokenType::Register,
|
||||
)),
|
||||
}
|
||||
};
|
||||
($token:expr, Immediate) => {
|
||||
match $token {
|
||||
Token::Immediate(value) => Ok(value.clone()),
|
||||
other => Err(AssembleError::UnexpectedToken(
|
||||
$crate::model::Token::Immediate(value) => Ok(value.clone()),
|
||||
other => Err($crate::AssembleError::UnexpectedToken(
|
||||
other.clone(),
|
||||
TokenType::Immediate,
|
||||
$crate::model::TokenType::Immediate,
|
||||
)),
|
||||
}
|
||||
};
|
||||
($token:expr, StringLit) => {
|
||||
match $token {
|
||||
Token::StringLit(value) => Ok(value.clone()),
|
||||
other => Err(AssembleError::UnexpectedToken(
|
||||
$crate::model::Token::StringLit(value) => Ok(value.clone()),
|
||||
other => Err($crate::AssembleError::UnexpectedToken(
|
||||
other.clone(),
|
||||
TokenType::StringLit,
|
||||
$crate::model::TokenType::StringLit,
|
||||
)),
|
||||
}
|
||||
};
|
||||
($token:expr, Opcode) => {
|
||||
match $token {
|
||||
Token::Opcode(value) => Ok(value.clone()),
|
||||
other => Err(AssembleError::UnexpectedToken(
|
||||
$crate::model::Token::Opcode(value) => Ok(value.clone()),
|
||||
other => Err($crate::AssembleError::UnexpectedToken(
|
||||
other.clone(),
|
||||
TokenType::Opcode,
|
||||
$crate::model::TokenType::Opcode,
|
||||
)),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
#[macro_use]
|
||||
macro_rules! expect_type {
|
||||
($token:expr, $($variant:ident),+) => {{
|
||||
let token = $token;
|
||||
match &token {
|
||||
$(
|
||||
Token::$variant(_) => Ok(token.clone()),
|
||||
$crate::model::Token::$variant(_) => Ok(token.clone()),
|
||||
)+
|
||||
other => {
|
||||
let expected_type = expect_type!(@get_first_type $($variant),+);
|
||||
Err(AssembleError::UnexpectedToken(
|
||||
Err($crate::AssembleError::UnexpectedToken(
|
||||
other.clone().clone(),
|
||||
expected_type,
|
||||
))
|
||||
@@ -248,9 +245,9 @@ macro_rules! expect_type {
|
||||
}
|
||||
}};
|
||||
|
||||
(@get_first_type Symbol $(, $rest:ident)*) => { TokenType::Symbol };
|
||||
(@get_first_type Register $(, $rest:ident)*) => { TokenType::Register };
|
||||
(@get_first_type Immediate $(, $rest:ident)*) => { TokenType::Immediate };
|
||||
(@get_first_type StringLit $(, $rest:ident)*) => { TokenType::StringLit };
|
||||
(@get_first_type Opcode $(, $rest:ident)*) => { TokenType::Opcode };
|
||||
(@get_first_type Symbol $(, $rest:ident)*) => { $crate::model::TokenType::Symbol };
|
||||
(@get_first_type Register $(, $rest:ident)*) => { $crate::model::TokenType::Register };
|
||||
(@get_first_type Immediate $(, $rest:ident)*) => { $crate::model::TokenType::Immediate };
|
||||
(@get_first_type StringLit $(, $rest:ident)*) => { $crate::model::TokenType::StringLit };
|
||||
(@get_first_type Opcode $(, $rest:ident)*) => { $crate::model::TokenType::Opcode };
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ fn main() {
|
||||
});
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("{}", e);
|
||||
eprintln!("{e}");
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ pub struct Node {
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
#[macro_use]
|
||||
macro_rules! node {
|
||||
($symbol: expr, $opcode: expr, args: $tokens: expr) => {
|
||||
Node::new($symbol.clone(), $opcode.clone(), $tokens.clone())
|
||||
@@ -55,7 +54,7 @@ impl Node {
|
||||
impl fmt::Display for Node {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let symbol = match &self.label() {
|
||||
Some(symbol) => format!("{}:\n", symbol),
|
||||
Some(symbol) => format!("{symbol}:\n"),
|
||||
None => "".to_string(),
|
||||
};
|
||||
|
||||
@@ -146,12 +145,19 @@ impl fmt::Display for Opcode {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Eq, Hash)]
|
||||
#[derive(Debug, Clone, Eq)]
|
||||
pub struct Symbol {
|
||||
pub name: String,
|
||||
pub module: Module,
|
||||
}
|
||||
|
||||
impl std::hash::Hash for Symbol {
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
self.name.hash(state);
|
||||
self.module.hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for Symbol {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.name == other.name && self.module == other.module
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use common::prelude::{Instruction, Register};
|
||||
use crate::{
|
||||
AssembleError, expect_token, expect_type,
|
||||
model::{Node, Opcode, Token, TokenType},
|
||||
node,
|
||||
};
|
||||
|
||||
use crate::model::{Module, Node, Opcode, Symbol, Token, TokenType};
|
||||
use crate::{AssembleError, dsa, expect_token, expect_type, node, quick_hash};
|
||||
use common::prelude::*;
|
||||
|
||||
pub struct Parser {
|
||||
tokens: Vec<Token>,
|
||||
@@ -93,7 +96,7 @@ impl Parser {
|
||||
|
||||
let mut offset = Token::Immediate(0);
|
||||
if let Ok(next) = self.peek_next() {
|
||||
if let Ok(_) = expect_type!(next, Immediate) {
|
||||
if expect_type!(next, Immediate).is_ok() {
|
||||
offset = self.next()?;
|
||||
}
|
||||
}
|
||||
@@ -105,7 +108,7 @@ impl Parser {
|
||||
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, Immediate) {
|
||||
if expect_type!(next, Immediate).is_ok() {
|
||||
offset = self.next()?;
|
||||
}
|
||||
}
|
||||
@@ -273,7 +276,7 @@ impl Parser {
|
||||
Token::StringLit(_) => {
|
||||
values.push(self.tokens.pop().unwrap());
|
||||
}
|
||||
Token::Immediate(val) if *val <= u32::MAX as u32 => {
|
||||
Token::Immediate(_) => {
|
||||
values.push(self.tokens.pop().unwrap());
|
||||
}
|
||||
_ => break,
|
||||
|
||||
@@ -8,8 +8,8 @@ use crate::{
|
||||
node, quick_hash,
|
||||
};
|
||||
|
||||
pub fn resolve_symbols(nodes: &mut Vec<Node>) -> Result<(), AssembleError> {
|
||||
let symbol_table = generate_symbol_table(&nodes)?;
|
||||
pub fn resolve_symbols(nodes: &mut [Node]) -> Result<(), AssembleError> {
|
||||
let symbol_table = generate_symbol_table(nodes)?;
|
||||
|
||||
for node in nodes.iter_mut() {
|
||||
match node.opcode() {
|
||||
@@ -53,9 +53,7 @@ pub fn resolve_symbols(nodes: &mut Vec<Node>) -> Result<(), AssembleError> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn generate_symbol_table(
|
||||
nodes: &Vec<Node>,
|
||||
) -> Result<HashMap<Symbol, u32>, AssembleError> {
|
||||
fn generate_symbol_table(nodes: &[Node]) -> Result<HashMap<Symbol, u32>, AssembleError> {
|
||||
let mut table = HashMap::new();
|
||||
|
||||
for (i, node) in nodes.iter().enumerate() {
|
||||
|
||||
@@ -86,7 +86,8 @@ impl TryFrom<u8> for Register {
|
||||
}
|
||||
|
||||
Ok(match idx {
|
||||
// System registers are not indexable in the reg file so they cannot be modified by instructions.
|
||||
// System registers are not indexable in the reg file so they cannot be
|
||||
// modified by instructions.
|
||||
0x0 => Self::Rg0,
|
||||
0x1 => Self::Rg1,
|
||||
0x2 => Self::Rg2,
|
||||
@@ -414,8 +415,8 @@ impl std::fmt::Display for Instruction {
|
||||
|
||||
Self::Increment(a) | Self::Decrement(a) => write!(f, " {}", a.sr1),
|
||||
Self::Interrupt(a) => write!(f, " {}", a.as_u8()),
|
||||
Self::Data(a) => write!(f, " {}", a),
|
||||
Self::Segment(x) => write!(f, " [SEGMENT {}]", x),
|
||||
Self::Data(a) => write!(f, " {a}"),
|
||||
Self::Segment(x) => write!(f, " [SEGMENT {x}]"),
|
||||
_ => Ok(()),
|
||||
}
|
||||
}
|
||||
@@ -469,7 +470,7 @@ impl TryFrom<u32> for Instruction {
|
||||
0x24 => Ok(Self::Halt),
|
||||
0x25 => Ok(Self::AddImmediate(ITypeArgs::try_from(data)?)),
|
||||
0x26 => Ok(Self::SubImmediate(ITypeArgs::try_from(data)?)),
|
||||
0x3F => Ok(Self::Segment(data as u8 as u32)),
|
||||
0x3F => Ok(Self::Segment(u32::from(data as u8))),
|
||||
_ => Err(InstructionDecodeError::InvalidOpcode(opcode)),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,8 @@ fn encode_no_args(opcode: u8) -> u32 {
|
||||
(opcode << 26) | (sr1 << 21) | (sr2 << 16) | (dr << 11) | (shamt << 6)
|
||||
}
|
||||
|
||||
/// Expands to a match statement that calls encode on instructions that implement [`Encode`]:
|
||||
/// Expands to a match statement that calls encode on instructions that implement
|
||||
/// [`Encode`]:
|
||||
///
|
||||
/// # Usage
|
||||
///
|
||||
@@ -58,7 +59,7 @@ impl Encode for Instruction {
|
||||
Self::Segment(segment) => {
|
||||
let opcode = u32::from(self.opcode());
|
||||
let segment = segment as u8;
|
||||
(opcode << 26) | (segment as u32)
|
||||
(opcode << 26) | u32::from(segment)
|
||||
}
|
||||
]
|
||||
)
|
||||
|
||||
@@ -246,7 +246,7 @@ impl CodeEditor {
|
||||
text: &mut dyn egui::TextBuffer,
|
||||
) -> TextEditOutput {
|
||||
let mut text_edit_output: Option<TextEditOutput> = None;
|
||||
let mut code_editor = |ui: &mut egui::Ui| {
|
||||
let code_editor = |ui: &mut egui::Ui| {
|
||||
ui.horizontal_top(|h| {
|
||||
self.theme.modify_style(h, self.fontsize);
|
||||
if self.numlines {
|
||||
|
||||
@@ -97,7 +97,7 @@ pub fn run_emulator(
|
||||
// Execute one cycle.
|
||||
match processor.cycle() {
|
||||
Ok((addr, instruction)) => {
|
||||
history.push((addr, instruction.clone()));
|
||||
history.push((addr, instruction));
|
||||
}
|
||||
Err(why) => {
|
||||
let pcx = processor.get(Register::Pcx);
|
||||
@@ -148,7 +148,7 @@ pub fn run_emulator(
|
||||
}
|
||||
};
|
||||
|
||||
history.push(instruction.clone());
|
||||
history.push(instruction);
|
||||
|
||||
// let instruction = match Instruction::decode(cpu_lock.get(Register::Cir))
|
||||
// {};
|
||||
|
||||
@@ -225,19 +225,13 @@ impl Default for State {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct PersistentState {
|
||||
pub history: Vec<(u32, Instruction)>,
|
||||
}
|
||||
|
||||
impl Default for PersistentState {
|
||||
fn default() -> Self {
|
||||
Self { history: vec![] }
|
||||
}
|
||||
}
|
||||
|
||||
impl PersistentState {
|
||||
pub fn update(&mut self, new_state: &PersistentState) {
|
||||
pub fn update(&mut self, new_state: &Self) {
|
||||
self.history.extend(new_state.history.clone());
|
||||
if self.history.len() > 32768 {
|
||||
let len = self.history.len() - 32768;
|
||||
|
||||
@@ -31,7 +31,7 @@ impl Processor {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn reset(&mut self) {
|
||||
pub const fn reset(&mut self) {
|
||||
// set all registers to zero
|
||||
// run memory.reset()
|
||||
self.registers.reset();
|
||||
@@ -166,8 +166,6 @@ impl Executable for Instruction {
|
||||
fn execute(self, cpu: &mut Processor) {
|
||||
match self {
|
||||
// No operation - a blank line.
|
||||
Self::Nop => {}
|
||||
|
||||
// Copies from SrcReg to a.drReg.
|
||||
Self::Mov(a) => {
|
||||
*cpu.reg(a.dr) = cpu.get(a.sr1);
|
||||
@@ -395,11 +393,9 @@ impl Executable for Instruction {
|
||||
cpu.halted = true;
|
||||
}
|
||||
|
||||
Self::Segment(_) => {}
|
||||
Self::Data(_) => {}
|
||||
|
||||
Self::Segment(_) | Self::Nop | Self::Data(_) => {}
|
||||
_ => {
|
||||
println!("unimplemented instruction: {}", self);
|
||||
eprintln!("WARN: unimplemented instruction: {self}");
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ use crate::emulator::{
|
||||
};
|
||||
|
||||
use eframe::egui;
|
||||
use egui::{Color32, FontId, Margin, RichText, Vec2};
|
||||
use egui::{Color32, FontId, Vec2};
|
||||
|
||||
const VGA_WIDTH: usize = 80;
|
||||
const VGA_HEIGHT: usize = 25;
|
||||
@@ -14,11 +14,18 @@ pub struct Display {
|
||||
}
|
||||
|
||||
impl Display {
|
||||
pub fn new() -> Self {
|
||||
#[must_use]
|
||||
pub const fn new() -> Self {
|
||||
Self { visible: false }
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Display {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl Component for Display {
|
||||
fn name(&self) -> &'static str {
|
||||
"Display"
|
||||
@@ -32,13 +39,14 @@ impl Component for Display {
|
||||
&mut self.visible
|
||||
}
|
||||
|
||||
fn render(&mut self, state: &mut State, ui: &mut egui::Ui, ctx: &egui::Context) {
|
||||
fn render(&mut self, state: &mut State, ui: &mut egui::Ui, _ctx: &egui::Context) {
|
||||
let display: Vec<u8> = state.display_view.clone();
|
||||
let font_id = FontId::monospace(12.0);
|
||||
|
||||
let char_width = ui.fonts(|f| f.glyph_width(&font_id, 'W'));
|
||||
let line_height = ui.fonts(|f| f.row_height(&font_id));
|
||||
|
||||
#[expect(clippy::cast_precision_loss)]
|
||||
let display_size = Vec2::new(
|
||||
char_width * VGA_WIDTH as f32,
|
||||
line_height * VGA_HEIGHT as f32,
|
||||
@@ -56,7 +64,7 @@ impl Component for Display {
|
||||
let index = y * VGA_WIDTH + x;
|
||||
if index < display.len() {
|
||||
let byte = display[index];
|
||||
let ch = if byte >= 32 && byte <= 126 {
|
||||
let ch = if (32..=126).contains(&byte) {
|
||||
byte as char
|
||||
} else {
|
||||
' '
|
||||
@@ -67,7 +75,9 @@ impl Component for Display {
|
||||
}
|
||||
}
|
||||
|
||||
#[expect(clippy::cast_precision_loss)]
|
||||
let text_pos = rect.min + Vec2::new(0.0, y as f32 * line_height);
|
||||
|
||||
ui.painter().text(
|
||||
text_pos,
|
||||
egui::Align2::LEFT_TOP,
|
||||
|
||||
@@ -82,7 +82,7 @@ impl Component for Editor {
|
||||
|
||||
impl Editor {
|
||||
#[must_use]
|
||||
pub fn new(sender: Sender<Command>) -> Self {
|
||||
pub const fn new(sender: Sender<Command>) -> Self {
|
||||
Self {
|
||||
path: None,
|
||||
text: String::new(),
|
||||
@@ -176,7 +176,7 @@ impl Editor {
|
||||
{
|
||||
if let Ok(contents) = std::fs::read_to_string(&path) {
|
||||
self.path = Some(path);
|
||||
self.text = contents.clone();
|
||||
self.text.clone_from(&contents);
|
||||
self.buffer = contents;
|
||||
self.unsaved = false;
|
||||
}
|
||||
@@ -294,7 +294,7 @@ impl Editor {
|
||||
editor.show(ui, &mut self.text);
|
||||
}
|
||||
|
||||
fn render_bottom_bar(&mut self, _state: &mut State, ui: &mut Ui, _ctx: &Context) {
|
||||
fn render_bottom_bar(&self, _state: &mut State, ui: &mut Ui, _ctx: &Context) {
|
||||
ui.horizontal(|ui| {
|
||||
// error display
|
||||
ui.label(
|
||||
@@ -337,22 +337,20 @@ impl Editor {
|
||||
}
|
||||
|
||||
// builds the current file
|
||||
if ui.button("Build").clicked() {
|
||||
if !self.unsaved {
|
||||
if let Some(path) = &self.path {
|
||||
let instructions = match assembler::assemble(path) {
|
||||
Ok(instructions) => instructions,
|
||||
Err(error) => {
|
||||
self.error = Some(error.to_string());
|
||||
return;
|
||||
}
|
||||
};
|
||||
if ui.button("Build").clicked() && !self.unsaved {
|
||||
if let Some(path) = &self.path {
|
||||
let instructions = match assembler::assemble(path) {
|
||||
Ok(instructions) => instructions,
|
||||
Err(error) => {
|
||||
self.error = Some(error.to_string());
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
self.output = instructions
|
||||
.iter()
|
||||
.flat_map(|i| i.encode().to_be_bytes().to_vec())
|
||||
.collect();
|
||||
}
|
||||
self.output = instructions
|
||||
.iter()
|
||||
.flat_map(|i| i.encode().to_be_bytes().to_vec())
|
||||
.collect();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ impl Component for History {
|
||||
for (idx, instruction) in
|
||||
state.persistent.history.iter().enumerate()
|
||||
{
|
||||
ui.label(format!("{}: ", idx));
|
||||
ui.label(format!("{idx}: "));
|
||||
|
||||
// Hex column
|
||||
let addr = instruction.0;
|
||||
@@ -65,9 +65,15 @@ impl Component for History {
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for History {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl History {
|
||||
#[must_use]
|
||||
pub fn new() -> Self {
|
||||
pub const fn new() -> Self {
|
||||
Self { visible: false }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
use std::io::Read;
|
||||
|
||||
use crate::emulator::{system::model::State, ui::interface::Component};
|
||||
|
||||
use common::instructions::Register;
|
||||
@@ -52,7 +50,9 @@ impl Component for StackInspector {
|
||||
for (i, value) in
|
||||
state.stack_view.chunks(4).take(32).enumerate()
|
||||
{
|
||||
let value = u32::from_be_bytes(value.try_into().unwrap());
|
||||
let value = u32::from_be_bytes(value.try_into().expect(
|
||||
"Could not read 4 byte instruction or data! Something is wrong.",
|
||||
));
|
||||
ui.label(format!(
|
||||
"{} [{}]",
|
||||
i,
|
||||
|
||||
Reference in New Issue
Block a user