mindustry logic execution, map- and schematic- parsing and rendering
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
use crate::debug::{info::DebugInfo, printable::Printable};

use super::{
    instructions::{DrawInstr, Instr},
    lexer::Token,
};

#[derive(Debug)]
pub enum PInstr<'s> {
    Instr(Instr),
    Draw(DrawInstr),
    Code(Box<[Token<'s>]>),
    Comment(&'s str),
}

impl Printable for PInstr<'_> {
    fn print(&self, info: &DebugInfo<'_>, f: &mut impl std::fmt::Write) -> std::fmt::Result {
        match self {
            Self::Instr(i) => i.print(info, f),
            Self::Draw(i) => i.print(info, f),
            Self::Code(c) => {
                let mut toks = c.iter();
                if let Some(t) = toks.next() {
                    write!(f, "{t}")?;
                }
                for token in toks {
                    write!(f, " {token}")?;
                }
                Ok(())
            }
            Self::Comment(c) => write!(f, "{c}"),
        }
    }
}

impl Printable for Code<'_> {
    fn print(&self, info: &DebugInfo<'_>, f: &mut impl std::fmt::Write) -> std::fmt::Result {
        for instr in &*self.0 {
            instr.print(info, f)?;
            writeln!(f)?;
        }
        Ok(())
    }
}

#[repr(transparent)]
#[derive(Debug)]
pub struct Code<'s>(Box<[PInstr<'s>]>);

// Pin requires
impl<'s> std::ops::Deref for Code<'s> {
    type Target = [PInstr<'s>];

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}
impl<'s> Code<'s> {
    pub(crate) fn new(code: Box<[PInstr<'s>]>) -> Self {
        Self(code)
    }
}