1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
pub trait Parser<IS: ParserInstSet>: Send + Sync {
    fn parse(&mut self, code: &String) -> Result<ParserResult<IS>, Vec<ParserError>>;
}

// in crate::modules::[instruction_set]::basic::interface::parser
pub trait ParserInstSet {
    type Operator: Clone + std::fmt::Debug + PartialEq + Eq;
    type Operand: Clone + std::fmt::Debug + PartialEq + Eq;
}

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Pos(pub usize, pub usize);

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ParserResult<IS: ParserInstSet> {
    pub data: Vec<ParserResultData>,
    pub text: Vec<ParserResultText<IS>>,
}

#[derive(Clone, Debug)]
pub struct ParserError {
    pub pos: Pos,
    pub msg: String,
}

pub type ParserResultData = u8;

#[derive(Clone, Debug, PartialEq, Eq)]
pub enum ParserResultText<IS: ParserInstSet> {
    Text(ParserInst<IS>),
    Align(u8),
}

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ParserInst<IS: ParserInstSet> {
    pub line: usize,
    pub op: IS::Operator,
    pub opd: Vec<IS::Operand>,
}

impl<IS: ParserInstSet> std::fmt::Display for ParserResult<IS> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.write_str(
            "ParserResult {\n\
            data:\n",
        )?;
        f.write_str("     0x")?;
        for &d in &self.data {
            write!(f, "{:02x}", d)?;
        }
        f.write_str("\n")?;
        f.write_str("text:\n")?;
        for (i, t) in self.text.iter().enumerate() {
            write!(f, "{:3} {}\n", i + 1, t.to_string())?;
        }
        Ok(())
    }
}

impl<IS: ParserInstSet> std::fmt::Display for ParserResultText<IS> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            ParserResultText::Text(inst) => {
                write!(f, "{:3}: {:?}", inst.line + 1, inst.op)?;
                for opd in &inst.opd {
                    write!(f, " {:?}", opd)?;
                }
                Ok(())
            }
            ParserResultText::Align(a) => write!(f, "Align {}", a),
        }
    }
}

impl std::fmt::Display for ParserError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(
            f,
            "line:{} col:{} {}",
            self.pos.0 + 1,
            self.pos.1 + 1,
            self.msg
        )
    }
}