goscript_parser/scope.rs
1use super::ast::Node;
2use super::objects::*;
3use super::position;
4use std::collections::HashMap;
5use std::fmt;
6
7#[derive(Debug, Clone)]
8pub enum EntityKind {
9 Bad,
10 Pkg,
11 Con,
12 Typ,
13 Var,
14 Fun,
15 Lbl,
16}
17
18impl EntityKind {
19 pub fn kind_text(&self) -> &str {
20 match self {
21 EntityKind::Bad => "bad",
22 EntityKind::Pkg => "package",
23 EntityKind::Con => "const",
24 EntityKind::Typ => "type",
25 EntityKind::Var => "var",
26 EntityKind::Fun => "func",
27 EntityKind::Lbl => "label",
28 }
29 }
30}
31
32#[derive(Debug, Clone)]
33pub enum DeclObj {
34 Field(FieldKey),
35 Spec(SpecKey),
36 FuncDecl(FuncDeclKey),
37 LabeledStmt(LabeledStmtKey),
38 AssignStmt(AssignStmtKey),
39 NoDecl,
40}
41
42#[derive(Debug, Clone)]
43pub enum EntityData {
44 PkgScope(ScopeKey),
45 ConIota(isize),
46 NoData,
47}
48
49// An Entity describes a named language entity such as a package,
50// constant, type, variable, function (incl. methods), or label.
51#[derive(Debug, Clone)]
52pub struct Entity {
53 pub kind: EntityKind,
54 pub name: String,
55 pub decl: DeclObj,
56 pub data: EntityData,
57}
58
59impl Entity {
60 pub fn new(kind: EntityKind, name: String, decl: DeclObj, data: EntityData) -> Entity {
61 Entity {
62 kind: kind,
63 name: name,
64 decl: decl,
65 data: data,
66 }
67 }
68
69 pub fn with_no_data(kind: EntityKind, name: String, decl: DeclObj) -> Entity {
70 Entity::new(kind, name, decl, EntityData::NoData)
71 }
72
73 pub fn pos(&self, arena: &Objects) -> position::Pos {
74 match &self.decl {
75 DeclObj::Field(i) => i.pos(arena),
76 DeclObj::Spec(i) => arena.specs[*i].pos(arena),
77 DeclObj::FuncDecl(i) => arena.fdecls[*i].pos(arena),
78 DeclObj::LabeledStmt(i) => arena.l_stmts[*i].pos(arena),
79 DeclObj::AssignStmt(i) => arena.a_stmts[*i].pos(arena),
80 DeclObj::NoDecl => 0,
81 }
82 }
83}
84
85pub struct Scope {
86 pub outer: Option<ScopeKey>,
87 pub entities: HashMap<String, EntityKey>,
88}
89
90impl Scope {
91 pub fn new(outer: Option<ScopeKey>) -> Scope {
92 Scope {
93 outer: outer,
94 entities: HashMap::new(),
95 }
96 }
97
98 pub fn look_up(&self, name: &String) -> Option<&EntityKey> {
99 self.entities.get(name)
100 }
101
102 pub fn insert(&mut self, name: String, entity: EntityKey) -> Option<EntityKey> {
103 self.entities.insert(name, entity)
104 }
105
106 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
107 match write!(f, "scope {:p} {{\n", self) {
108 Err(e) => {
109 return Err(e);
110 }
111 Ok(_) => {}
112 };
113 for (k, _) in self.entities.iter() {
114 match write!(f, "\t{}\n", k) {
115 Err(e) => {
116 return Err(e);
117 }
118 Ok(_) => {}
119 }
120 }
121 write!(f, "}}\n")
122 }
123}
124
125#[cfg(test)]
126mod test {
127 //use super::*;
128 //use generational_arena as ar;
129
130 /*
131 pub struct ScopeDebug<'a> {
132 scope: &'a Scope,
133 arena: &'a Arena<Entity>,
134 }
135
136 impl<'a> ScopeDebug<'a> {
137 fn new(scope: &'a Scope, arena: &'a Arena<Entity>) -> ScopeDebug<'a> {
138 ScopeDebug{scope: scope, arena: arena}
139 }
140 }
141
142 impl<'a> fmt::Debug for ScopeDebug<'a> {
143 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
144 match write!(f, "scope {:p} {{\n", self.scope) {
145 Err(e) => { return Err(e); },
146 Ok(_) => {},
147 };
148 for (k, v) in self.scope.entities.iter() {
149 let entity = &self.arena[*v];
150 match write!(f, "\t{} {}\n", entity.kind.kind_text(), k) {
151 Err(e) => { return Err(e); },
152 Ok(_) => {},
153 }
154 };
155 write!(f, "}}\n")
156 }
157 }
158
159 pub fn insert_new<'a>(sel: &mut Scope, e: Entity, arena: &'a mut Arena<Entity>) ->
160 Option<&'a mut Entity> {
161 match sel.entities.get(&e.name) {
162 Some(&i) => arena.get_mut(i),
163 None => {
164 let name = e.name.to_string();
165 let index = arena.insert(e);
166 sel.entities.insert(name, index);
167 None
168 }
169 }
170 }
171 */
172
173 #[test]
174 fn test_scope() {
175 /*
176 let mut arena_s = ar::Arena::new();
177 let scope = Scope::new(None);
178 let s = arena_s.insert(scope);
179 let e = Entity::with_no_data(EntityKind::Fun, "test_entity".to_string(), DeclObj::NoDecl);
180 let mut arena = ar::Arena::new();
181 insert_new(&mut arena_s[s], e, &mut arena);
182
183 println!("scope: {:?}", ScopeDebug::new(&arena_s[s], &arena));
184 */
185 }
186}