assembler: use common to match registers

This commit is contained in:
2025-06-25 19:29:56 +01:00
parent d9807b5b36
commit 68e459f32b
4 changed files with 46 additions and 28 deletions
+4 -2
View File
@@ -2,6 +2,8 @@
//! easier to build from scratch and edit his code than it would be to try and wrangle it
//! into shape.
use common::prelude::*;
use crate::source::{
source_info::SourceInfo,
token_info::{
@@ -71,8 +73,8 @@ impl Token {
}
#[must_use]
pub const fn register(name: String, source_info: SourceInfo) -> Self {
Self::new(TokenType::Register(RegisterToken { name }), source_info)
pub const fn register(reg: Register, source_info: SourceInfo) -> Self {
Self::new(TokenType::Register(RegisterToken { reg }), source_info)
}
#[must_use]
+10 -1
View File
@@ -1,3 +1,5 @@
use common::prelude::Register;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct SymbolToken {
pub name: String,
@@ -15,7 +17,14 @@ pub struct DirectiveToken {
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct RegisterToken {
pub name: String,
pub reg: Register,
}
impl RegisterToken {
/// Returns the name of a valid [`Register`]
pub fn name(&self) -> String {
self.reg.to_string()
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+30 -17
View File
@@ -8,6 +8,8 @@ use std::{
use regex::Regex;
use common::prelude::*;
use crate::{
context::AssemblerContext,
error::{AssembleError, AssembleErrorKind, IoError, IoErrorKind},
@@ -36,10 +38,10 @@ pub struct Tokeniser {
// Pre-compiled regex patterns
label_regex: Regex,
register_regex: Regex,
// register_regex: Regex,
immediate_regex: Regex,
directive_regex: Regex,
instruction_regex: Regex,
// instruction_regex: Regex,
symbol_regex: Regex,
string_regex: Regex,
comment_regex: Regex,
@@ -54,18 +56,18 @@ impl Tokeniser {
label_regex: Regex::new(r"^([a-zA-Z_][a-zA-Z0-9_]*):")
.expect("Failed to compile label regex pattern"),
register_regex: Regex::new(r"^(r[0-9]+|sp|fp|pc)")
.expect("Failed to compile register regex pattern"),
// register_regex: Regex::new(r"^(r[0-9]+|sp|fp|pc)")
// .expect("Failed to compile register regex pattern"),
immediate_regex: Regex::new(
r"^(0x[0-9a-fA-F_]+|0b[0-1_]+|0o[0-7_]+|[0-9_]+)",
)
.expect("Failed to compile immediate regex pattern"),
directive_regex: Regex::new(r"^\.([a-zA-Z]+)")
.expect("Failed to compile directive regex pattern"),
instruction_regex: Regex::new(
r"^(add|sub|mul|div|jmp|call|ret|lli|nop|halt)",
)
.expect("Failed to compile instruction regex pattern"),
// instruction_regex: Regex::new(
// r"^(add|sub|mul|div|jmp|call|ret|lli|nop|halt)",
// )
// .expect("Failed to compile instruction regex pattern"),
symbol_regex: Regex::new(r"^([a-zA-Z_][a-zA-Z0-9_]*)")
.expect("Failed to compile symbol regex pattern"),
string_regex: Regex::new(r#"^"([^"]*)"#)
@@ -186,11 +188,19 @@ impl Tokeniser {
}
fn try_match_register(&self, input: &str) -> Option<(TokenType, usize)> {
let caps = self.register_regex.captures(input)?;
let name = caps.get(1)?.as_str().to_string();
let len = caps.get(0)?.len();
_ = self;
Some((TokenType::Register(RegisterToken { name }), len))
let reg = match Register::try_from(input) {
Ok(reg) => reg,
Err(_why) => {
// Probably ignore the error.
return None;
}
};
let len = input.len();
Some((TokenType::Register(RegisterToken { reg }), len))
}
fn try_match_immediate(&self, input: &str) -> Option<(TokenType, usize)> {
@@ -224,12 +234,15 @@ impl Tokeniser {
Some((TokenType::Directive(DirectiveToken { directive }), len))
}
fn try_match_instruction(&self, input: &str) -> Option<(TokenType, usize)> {
let caps = self.instruction_regex.captures(input)?;
let mnemonic = caps.get(1)?.as_str().to_string();
let len = caps.get(0)?.len();
const fn try_match_instruction(&self, _input: &str) -> Option<(TokenType, usize)> {
_ = self;
Some((TokenType::Instruction(InstructionToken { mnemonic }), len))
// let instruction =
// Some((TokenType::Instruction(InstructionToken { mnemonic }), len))
// TODO: fix me.
None
}
fn try_match_symbol(&self, input: &str) -> Option<(TokenType, usize)> {
+2 -8
View File
@@ -90,19 +90,13 @@ fn test_all_instructions() {
#[test]
fn test_registers() {
let test_cases = [
("r0", "r0"),
("r15", "r15"),
("sp", "sp"),
("fp", "fp"),
("pc", "pc"),
];
let test_cases = [("rg0", "r0"), ("rgf", "rgf"), ("pcx", "pcx")];
for (input, expected) in &test_cases {
let tokens = tokenize_source(input).expect("Failed to tokenize register");
if let TokenType::Register(reg) = &tokens[0].token_type {
assert_eq!(reg.name, *expected);
assert_eq!(reg.reg.to_string(), *expected);
} else {
panic!("Expected register token for {input}");
}