summaryrefslogtreecommitdiff
path: root/src/stack.rs
blob: 2862b72eea0cb53d28a4861d2113e16a25581ee7 (plain) (blame)
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
86
87
88
pub struct Stack {
    pub mem: [u8; 256],
    pub sp: u8,
}

impl Stack {
    pub fn new() -> Self {
        Self {
            mem: [0; 256],
            sp: 0,
        }
    }

    pub fn push_u8(&mut self, val: u8) {
        self.mem[self.sp as usize] = val;
        self.sp = self.sp.wrapping_add(1);
    }

    pub fn pop_u8(&mut self) -> u8 {
        self.sp = self.sp.wrapping_sub(1);
        self.mem[self.sp as usize]
    }

    pub fn push_u16(&mut self, val: u16) {
        let [byte_high, byte_low] = u16::to_be_bytes(val);
        self.push_u8(byte_high);
        self.push_u8(byte_low);
    }

    pub fn pop_u16(&mut self) -> u16 {
        self.sp = self.sp.wrapping_sub(1);
        let byte_low = self.mem[self.sp as usize];
        self.sp = self.sp.wrapping_sub(1);
        let byte_high = self.mem[self.sp as usize];
        u16::from_be_bytes([byte_high, byte_low])
    }

    pub fn get_u8(&mut self) -> u8 {
        self.mem[self.sp.wrapping_sub(1) as usize]
    }

    pub fn get_u16(&mut self) -> u16 {
        let byte_low = self.mem[self.sp.wrapping_sub(1) as usize];
        let byte_high = self.mem[self.sp.wrapping_sub(2) as usize];
        u16::from_be_bytes([byte_high, byte_low])
    }

    pub fn reset(&mut self) {
        self.mem.fill(0);
        self.sp = 0;
    }
}

use std::ops::Not;

impl Stack {
    pub fn inc_u8(&mut self) {
        let sp = self.sp.wrapping_sub(1) as usize;
        self.mem[sp] = self.mem[sp].wrapping_add(1);
    }

    pub fn dec_u8(&mut self) {
        let sp = self.sp.wrapping_sub(1) as usize;
        self.mem[sp] = self.mem[sp].wrapping_sub(1);
    }

    pub fn not_u8(&mut self) {
        let sp = self.sp.wrapping_sub(1) as usize;
        self.mem[sp] = self.mem[sp].not();
    }

    pub fn not_u16(&mut self) {
        let sp = self.sp.wrapping_sub(1) as usize;
        self.mem[sp] = self.mem[sp].not();
        let sp = self.sp.wrapping_sub(2) as usize;
        self.mem[sp] = self.mem[sp].not();
    }

    pub fn tal_u8(&mut self) {
        let sp = self.sp.wrapping_sub(1) as usize;
        self.mem[sp] = self.mem[sp].count_ones() as u8;
    }

    pub fn rev_u8(&mut self) {
        let sp = self.sp.wrapping_sub(1) as usize;
        self.mem[sp] = self.mem[sp].reverse_bits();
    }
}