assembler: use common to match registers
This commit is contained in:
@@ -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]
|
||||
|
||||
@@ -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)]
|
||||
|
||||
@@ -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)> {
|
||||
|
||||
@@ -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}");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user