1use super::ast::Node;
13use super::map::Map;
14use super::objects::*;
15use super::position;
16use std::fmt;
17
18#[derive(Debug, Clone)]
19pub enum EntityKind {
20 Bad,
21 Pkg,
22 Con,
23 Typ,
24 Var,
25 Fun,
26 Lbl,
27}
28
29impl EntityKind {
30 pub fn kind_text(&self) -> &str {
31 match self {
32 EntityKind::Bad => "bad",
33 EntityKind::Pkg => "package",
34 EntityKind::Con => "const",
35 EntityKind::Typ => "type",
36 EntityKind::Var => "var",
37 EntityKind::Fun => "func",
38 EntityKind::Lbl => "label",
39 }
40 }
41}
42
43#[derive(Debug, Clone)]
44pub enum DeclObj {
45 Field(FieldKey),
46 Spec(SpecKey),
47 FuncDecl(FuncDeclKey),
48 LabeledStmt(LabeledStmtKey),
49 AssignStmt(AssignStmtKey),
50 NoDecl,
51}
52
53#[derive(Debug, Clone)]
54pub enum EntityData {
55 PkgScope(ScopeKey),
56 ConIota(isize),
57 NoData,
58}
59
60#[derive(Debug, Clone)]
63pub struct Entity {
64 pub kind: EntityKind,
65 pub name: String,
66 pub decl: DeclObj,
67 pub data: EntityData,
68}
69
70impl Entity {
71 pub fn new(kind: EntityKind, name: String, decl: DeclObj, data: EntityData) -> Entity {
72 Entity {
73 kind,
74 name,
75 decl,
76 data,
77 }
78 }
79
80 pub fn with_no_data(kind: EntityKind, name: String, decl: DeclObj) -> Entity {
81 Entity::new(kind, name, decl, EntityData::NoData)
82 }
83
84 pub fn pos(&self, objs: &AstObjects) -> position::Pos {
85 match &self.decl {
86 DeclObj::Field(i) => i.pos(objs),
87 DeclObj::Spec(i) => objs.specs[*i].pos(objs),
88 DeclObj::FuncDecl(i) => objs.fdecls[*i].pos(objs),
89 DeclObj::LabeledStmt(i) => objs.l_stmts[*i].pos(objs),
90 DeclObj::AssignStmt(i) => objs.a_stmts[*i].pos(objs),
91 DeclObj::NoDecl => 0,
92 }
93 }
94}
95
96pub struct Scope {
97 pub outer: Option<ScopeKey>,
98 pub entities: Map<String, EntityKey>,
99}
100
101impl Scope {
102 pub fn new(outer: Option<ScopeKey>) -> Scope {
103 Scope {
104 outer: outer,
105 entities: Map::new(),
106 }
107 }
108
109 pub fn look_up(&self, name: &String) -> Option<&EntityKey> {
110 self.entities.get(name)
111 }
112
113 pub fn insert(&mut self, name: String, entity: EntityKey) -> Option<EntityKey> {
114 self.entities.insert(name, entity)
115 }
116
117 pub fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
118 match write!(f, "scope {:p} {{\n", self) {
119 Err(e) => {
120 return Err(e);
121 }
122 Ok(_) => {}
123 };
124 for (k, _) in self.entities.iter() {
125 match write!(f, "\t{}\n", k) {
126 Err(e) => {
127 return Err(e);
128 }
129 Ok(_) => {}
130 }
131 }
132 write!(f, "}}\n")
133 }
134}
135
136#[cfg(test)]
137mod test {}