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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
use std::fmt::{self, Display};
use std::collections::HashMap;
use scope::Scope;
use scope::symbol::SymbolTable;
use Identifier;
#[derive(Debug, Clone, PartialEq)]
pub struct SymbolMemory<Sym, Val> {
symbol: Sym,
memory: Option<Val>,
}
impl<Sym: Display, Val: Display> Display for SymbolMemory<Sym, Val> {
fn fmt(&self, f: &mut fmt::Formatter) -> ::std::result::Result<(), fmt::Error> {
match self.memory {
Some(ref mem) => write!(f, "{} {{{}}}", self.symbol, mem),
None => write!(f, "{}", self.symbol)
}
}
}
pub type MemoryScope<Sym, Val> = Scope<HashMap<Identifier, SymbolMemory<Sym, Val>>>;
impl<Sym, Val> SymbolTable<Sym> for HashMap<Identifier, SymbolMemory<Sym, Val>> {
fn symbol_set(&mut self, ident: Identifier, symbol: Sym) -> Option<Sym> {
self.insert(ident, SymbolMemory { symbol: symbol, memory: None }).map(|sm| sm.symbol)
}
fn symbol_get(&self, ident: &Identifier) -> Option<&Sym> {
self.get(ident).map(|&ref sm| &sm.symbol)
}
}
pub trait MemoryTable<Val> {
fn memory(&self, ident: &Identifier) -> Option<&Option<Val>>;
fn memory_mut(&mut self, ident: &Identifier) -> Option<&mut Option<Val>>;
}
impl<Sym, Val> MemoryTable<Val> for HashMap<Identifier, SymbolMemory<Sym, Val>> {
fn memory(&self, ident: &Identifier) -> Option<&Option<Val>> {
self.get(ident).map(|&ref sm| &sm.memory)
}
fn memory_mut(&mut self, ident: &Identifier) -> Option<&mut Option<Val>> {
self.get_mut(ident).map(|&mut ref mut sm| &mut sm.memory)
}
}
pub trait MemoryStore<Val> {
fn set(&mut self, ident: Identifier, value: Val) -> Result<Option<Val>, String>;
fn get(&self, ident: &Identifier) -> Option<Val>;
}
impl<Val: Clone, T> MemoryStore<Val> for Scope<T> where T: MemoryTable<Val> {
fn set(&mut self, ident: Identifier, value: Val) -> Result<Option<Val>, String> {
match self.item.memory_mut(&ident) {
Some(&mut ref mut curr_mem) => {
let ret = curr_mem.clone();
*curr_mem = Some(value);
Ok(ret)
},
None => {
match self.parent {
Some(ref mut parent) => parent.borrow_mut().set(ident, value),
None => Err(format!("attempt to set memory for missing symbol: {}", ident))
}
}
}
}
fn get(&self, ident: &Identifier) -> Option<Val> {
match self.item.memory(ident) {
Some(&ref curr_mem) => {
curr_mem.clone()
},
None => {
match self.parent {
Some(ref parent) => parent.borrow().get(ident),
None => None
}
}
}
}
}