avra_lib/
context.rs

1use crate::{device::Device, expr::Expr, instruction::register::Reg8, parser::SegmentType};
2
3use std::{cell::RefCell, collections::HashMap, rc::Rc};
4
5use maplit::hashmap;
6
7pub trait Context {
8    fn get_define(&self, _name: &String) -> Option<Expr>;
9    fn get_equ(&self, _name: &String) -> Option<Expr>;
10    fn get_label(&self, _name: &String) -> Option<(SegmentType, u32)>;
11    fn get_def(&self, _name: &String) -> Option<Reg8>;
12    fn get_set(&self, _name: &String) -> Option<Expr>;
13    fn get_special(&self, _name: &String) -> Option<Expr>;
14    fn get_device(&self) -> Device;
15
16    fn set_define(&self, _name: String, _value: Expr) -> Option<Expr>;
17    fn set_equ(&self, _name: String, _value: Expr) -> Option<Expr>;
18    fn set_label(&self, _name: String, _value: (SegmentType, u32)) -> Option<(SegmentType, u32)>;
19    fn set_def(&self, _name: String, _value: Reg8) -> Option<Reg8>;
20    fn set_special(&self, _name: String, _value: Expr) -> Option<Expr>;
21
22    fn get_expr(&self, name: &String) -> Option<Expr> {
23        if let Some(expr) = self.get_define(name) {
24            Some(expr)
25        } else if let Some(expr) = self.get_equ(name) {
26            Some(expr)
27        } else if let Some(expr) = self.get_set(name) {
28            Some(expr)
29        } else if let Some(expr) = self.get_special(name) {
30            Some(expr)
31        } else {
32            self.get_label(name).map(|x| Expr::Const(x.1 as i64))
33        }
34    }
35
36    fn exist(&self, name: &String) -> bool {
37        if let Some(_) = self.get_expr(name) {
38            true
39        } else if let Some(_) = self.get_def(name) {
40            true
41        } else {
42            false
43        }
44    }
45}
46
47#[derive(Clone, PartialEq, Eq, Debug)]
48pub struct CommonContext {
49    // defines
50    pub defines: Rc<RefCell<HashMap<String, Expr>>>,
51    // equals
52    pub equs: Rc<RefCell<HashMap<String, Expr>>>,
53    // labels
54    pub labels: Rc<RefCell<HashMap<String, (SegmentType, u32)>>>,
55    // defs
56    pub defs: Rc<RefCell<HashMap<String, Reg8>>>,
57    // sets
58    pub sets: Rc<RefCell<HashMap<String, Expr>>>,
59    // special
60    pub special: Rc<RefCell<HashMap<String, Expr>>>,
61    // device
62    pub device: Rc<RefCell<Option<Device>>>,
63}
64
65impl CommonContext {
66    pub fn new() -> Self {
67        Self {
68            defines: Rc::new(RefCell::new(hashmap! {})),
69            equs: Rc::new(RefCell::new(hashmap! {})),
70            labels: Rc::new(RefCell::new(hashmap! {})),
71            defs: Rc::new(RefCell::new(hashmap! {})),
72            sets: Rc::new(RefCell::new(hashmap! {})),
73            special: Rc::new(RefCell::new(hashmap! {})),
74            device: Rc::new(RefCell::new(Some(Device::new(0)))),
75        }
76    }
77}
78
79impl Context for CommonContext {
80    fn get_define(&self, name: &String) -> Option<Expr> {
81        self.defines.borrow().get(name).map(|x| x.clone())
82    }
83
84    fn get_equ(&self, name: &String) -> Option<Expr> {
85        self.equs
86            .borrow()
87            .get(&name.to_lowercase())
88            .map(|x| x.clone())
89    }
90
91    fn get_label(&self, name: &String) -> Option<(SegmentType, u32)> {
92        self.labels
93            .borrow()
94            .get(&name.to_lowercase())
95            .map(|x| x.clone())
96    }
97
98    fn get_def(&self, name: &String) -> Option<Reg8> {
99        self.defs
100            .borrow()
101            .get(&name.to_lowercase())
102            .map(|x| x.clone())
103    }
104
105    fn get_set(&self, name: &String) -> Option<Expr> {
106        self.sets.borrow().get(name).map(|x| x.clone())
107    }
108
109    fn get_special(&self, name: &String) -> Option<Expr> {
110        self.special
111            .borrow()
112            .get(&name.to_lowercase())
113            .map(|x| x.clone())
114    }
115
116    fn get_device(&self) -> Device {
117        self.device
118            .borrow()
119            .as_ref()
120            .unwrap_or(&Device::new(0))
121            .clone()
122    }
123
124    fn set_define(&self, name: String, expr: Expr) -> Option<Expr> {
125        self.defines.borrow_mut().insert(name, expr)
126    }
127
128    fn set_equ(&self, name: String, expr: Expr) -> Option<Expr> {
129        self.equs.borrow_mut().insert(name.to_lowercase(), expr)
130    }
131
132    fn set_label(&self, name: String, value: (SegmentType, u32)) -> Option<(SegmentType, u32)> {
133        self.labels.borrow_mut().insert(name, value)
134    }
135
136    fn set_def(&self, name: String, value: Reg8) -> Option<Reg8> {
137        if self.exist(&name) {
138            None
139        } else {
140            self.defs.borrow_mut().insert(name.to_lowercase(), value)
141        }
142    }
143
144    fn set_special(&self, name: String, value: Expr) -> Option<Expr> {
145        self.special.borrow_mut().insert(name, value)
146    }
147}