go_parser/
scope.rs

1// Copyright 2022 The Goscript Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4//
5//
6// This code is adapted from the offical Go code written in Go
7// with license as follows:
8// Copyright 2013 The Go Authors. All rights reserved.
9// Use of this source code is governed by a BSD-style
10// license that can be found in the LICENSE file.
11
12use 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// An Entity describes a named language entity such as a package,
61// constant, type, variable, function (incl. methods), or label.
62#[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 {}