1use regex::Regex;
2
3use crate::{Argument, CondCode, OpCode, Register};
4
5impl OpCode {
6 pub fn parse(mnem: &str) -> Option<(OpCode, bool, CondCode)> {
10 use OpCode::*;
11
12 let mchars = mnem.chars().collect::<Vec<char>>();
13
14 let (mut mnem, cond) = match mchars.as_slice() {
15 [.., 'n', 'z'] => (mnem.strip_suffix("nz"), CondCode::NotZero),
16 [.., 'z'] => (mnem.strip_suffix("z"), CondCode::Zero),
17 ['s', 'c'] => (Some(mnem), CondCode::Always),
18 ['s', 'c', 'c'] => (Some("sc"), CondCode::Carry),
19 [.., 'c'] => (mnem.strip_suffix("c"), CondCode::Carry),
20 [.., 'g', 't'] => (mnem.strip_suffix("gt"), CondCode::Greater),
21 [.., 'g', 'e'] => (mnem.strip_suffix("ge"), CondCode::GreaterEq),
22 [.., 'l', 't'] => (mnem.strip_suffix("lt"), CondCode::Lesser),
23 [.., 'l', 'e'] => (mnem.strip_suffix("le"), CondCode::LesserEq),
24 _ => (Some(mnem), CondCode::Always),
25 };
26
27 let mut sbit = false;
28 if mnem.unwrap().ends_with('s') {
29 sbit = true;
30 mnem = mnem.unwrap().strip_suffix("s");
31 }
32
33 let op = match mnem {
34 Some("add") => Add,
35 Some("and") => And,
36 Some("ashr") => Ashr,
37 Some("br") => Br,
38 Some("cmp") => Cmp,
39 Some("jsr") => Jsr,
40 Some("ldb") => Ldb,
41 Some("ldr") => Ldr,
42 Some("mfhi") => Mfhi,
43 Some("mov") => Mov,
44 Some("movr") => Movr,
45 Some("movt") => Movt,
46 Some("mul") => Mul,
47 Some("not") => Not,
48 Some("or") => Or,
49 Some("pop") => Pop,
50 Some("push") => Push,
51 Some("ret") => Ret,
52 Some("ror") => Ror,
53 Some("sc") => Sc,
54 Some("seg") => Seg,
55 Some("shl") => Shl,
56 Some("shr") => Shr,
57 Some("stb") => Stb,
58 Some("str") => Str,
59 Some("sub") => Sub,
60 Some("uadd") => Uadd,
61 Some("ucmp") => Ucmp,
62 Some("umul") => Umul,
63 Some("usub") => Usub,
64 Some("xor") => Xor,
65 _ => return None,
66 };
67
68 Some((op, sbit, cond))
69 }
70}
71
72impl Argument {
73 pub fn parse(arg: &str) -> Option<Self> {
75 let pattern = Regex::new(r"^[._a-zA-Z][_a-zA-Z0-9]*$").unwrap();
76
77 match arg {
78 "%a" => Some(Argument::Reg(Register::A)),
79 "%b" => Some(Argument::Reg(Register::B)),
80 "%c" => Some(Argument::Reg(Register::C)),
81 "%d" => Some(Argument::Reg(Register::D)),
82 "%e" => Some(Argument::Reg(Register::E)),
83 "%f" => Some(Argument::Reg(Register::F)),
84 "%g" => Some(Argument::Reg(Register::G)),
85 "%h" => Some(Argument::Reg(Register::H)),
86 "%r" => Some(Argument::Reg(Register::R)),
87 "%s" => Some(Argument::Reg(Register::S)),
88 "%sp" => Some(Argument::Reg(Register::SP)),
89 "%ip" => Some(Argument::Reg(Register::IP)),
90 i if i.parse::<isize>().is_ok() => Some(Argument::Imm(i.parse::<isize>().unwrap())),
91 l if pattern.is_match(l) => Some(Argument::Label(l.into())),
92 _ => None,
93 }
94 }
95}