github.com/Bytom/bytom@v1.1.2-0.20210127130405-ae40204c0b09/equity/compiler/environ.go (about) 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 }