OSDN Git Service

get standby nodes (#355)
[bytom/vapor.git] / equity / compiler / environ.go
1 package compiler
2
3 import "fmt"
4
5 // name-binding environment
6 type environ struct {
7         entries map[string]*envEntry
8         parent  *environ
9 }
10
11 type envEntry struct {
12         t typeDesc
13         r role
14         c *Contract // if t == contractType
15 }
16
17 type role int
18
19 const (
20         roleKeyword role = 1 + iota
21         roleBuiltin
22         roleContract
23         roleContractParam
24         roleContractValue
25         roleClause
26         roleClauseParam
27         roleClauseValue
28         roleClauseVariable
29 )
30
31 var roleDesc = map[role]string{
32         roleKeyword:        "keyword",
33         roleBuiltin:        "built-in function",
34         roleContract:       "contract",
35         roleContractParam:  "contract parameter",
36         roleContractValue:  "contract value",
37         roleClause:         "clause",
38         roleClauseParam:    "clause parameter",
39         roleClauseValue:    "clause value",
40         roleClauseVariable: "clause variable",
41 }
42
43 func newEnviron(parent *environ) *environ {
44         return &environ{
45                 entries: make(map[string]*envEntry),
46                 parent:  parent,
47         }
48 }
49
50 func (e *environ) add(name string, t typeDesc, r role) error {
51         if entry := e.lookup(name); entry != nil {
52                 return fmt.Errorf("%s \"%s\" conflicts with %s", roleDesc[r], name, roleDesc[entry.r])
53         }
54         e.entries[name] = &envEntry{t: t, r: r}
55         return nil
56 }
57
58 func (e *environ) addContract(contract *Contract) error {
59         if entry := e.lookup(contract.Name); entry != nil {
60                 return fmt.Errorf("%s \"%s\" conflicts with %s", roleDesc[roleContract], contract.Name, roleDesc[entry.r])
61         }
62         e.entries[contract.Name] = &envEntry{t: contractType, r: roleContract, c: contract}
63         return nil
64 }
65
66 func (e environ) lookup(name string) *envEntry {
67         if res, ok := e.entries[name]; ok {
68                 return res
69         }
70         if e.parent != nil {
71                 return e.parent.lookup(name)
72         }
73         return nil
74 }