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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
use std::fmt;
use std::cell::RefCell;
use std::rc::Rc;
use PType;
use Symbol;
use value::Value;
use sindra::{Type, Typed, Identifier};
use sindra::scope::{Scope, Scoped, MemoryScope, SymbolStore, MemoryStore};
use sindra::value::Coerce;
#[derive(Debug, Clone, PartialEq)]
pub struct Annotation {
scope: Option<Rc<RefCell<MemoryScope<Symbol, Value>>>>,
pub ty: Option<PType>,
pub promote_ty: Option<PType>,
}
impl Default for Annotation {
fn default() -> Annotation {
Annotation {
scope: None,
ty: None,
promote_ty: None,
}
}
}
impl Typed<PType> for Annotation {
fn ty(&self) -> Option<PType> { self.ty.clone() }
fn set_type(&mut self, ty: Option<PType>) { self.ty = ty; }
fn promote_type(&self) -> Option<PType> { self.promote_ty.clone() }
fn set_promote_type(&mut self, ty: Option<PType>) { self.promote_ty = ty; }
fn promoted(&self) -> Option<PType> { self.ty().map(|ty| ty.coerce(self.promote_type())) }
}
impl Scoped<MemoryScope<Symbol, Value>> for Annotation {
fn scope(&self) -> Option<Rc<RefCell<MemoryScope<Symbol, Value>>>> {
match self.scope {
Some(ref sc) => Some(Rc::clone(&sc)),
None => None
}
}
fn set_scope(&mut self, scope: Option<Rc<RefCell<MemoryScope<Symbol, Value>>>>) {
self.scope = scope;
}
}
impl SymbolStore<Symbol> for Annotation {
fn define(&mut self, ident: Identifier, symbol: Symbol) -> Option<Symbol> {
match self.scope {
Some(ref mut scope) => {
scope.borrow_mut().define(ident, symbol)
},
None => None
}
}
fn resolve(&self, ident: &Identifier) -> Option<Symbol> {
match self.scope {
Some(ref scope) => {
scope.borrow().resolve(ident)
},
None => None
}
}
}
impl MemoryStore<Value> for Annotation {
fn set(&mut self, ident: Identifier, value: Value) -> Result<Option<Value>, String> {
match self.scope {
Some(ref mut scope) => {
scope.borrow_mut().set(ident, value)
},
None => Err(format!("variable not found: {}", ident))
}
}
fn get(&self, ident: &Identifier) -> Option<Value> {
match self.scope {
Some(ref scope) => {
scope.borrow().get(ident)
},
None => None
}
}
}
impl fmt::Display for Annotation {
fn fmt(&self, f: &mut fmt::Formatter) -> ::std::result::Result<(), fmt::Error> {
match self.scope {
Some(ref sc) => {
write!(f, "scope:[")?;
write!(f, "{{table}}")?;
fn print_parents<T>(f: &mut fmt::Formatter,
parent: &Rc<RefCell<Scope<T>>>)
-> ::std::result::Result<(), fmt::Error> {
write!(f, "↑[")?;
write!(f, "{{table}}")?;
if let Some(ref p) = parent.borrow().parent {
print_parents(f, &p)?;
}
Ok(())
}
if let Some(ref parent) = sc.borrow().parent {
print_parents(f, &parent)?;
}
write!(f, "]")?;
},
None => {
write!(f, "scope:none")?;
}
};
match self.ty {
Some(ty) => { write!(f, " type:{}", ty.name()) },
None => { write!(f, " type:none") },
}
}
}