github.com/u-root/u-root@v7.0.1-0.20200915234505-ad7babab0a8e+incompatible/cmds/core/elvish/eval/source.go (about) 1 package eval 2 3 import ( 4 "fmt" 5 "strconv" 6 7 "github.com/u-root/u-root/cmds/core/elvish/eval/vals" 8 "github.com/u-root/u-root/cmds/core/elvish/hash" 9 "github.com/u-root/u-root/cmds/core/elvish/parse" 10 ) 11 12 // Source describes a piece of source code. 13 type Source struct { 14 typ SrcType 15 name string 16 path string 17 code string 18 } 19 20 // NewInteractiveSource returns a Source for a piece of code entered 21 // interactively. 22 func NewInteractiveSource(code string) *Source { 23 return &Source{SrcInteractive, "", "", code} 24 } 25 26 // NewScriptSource returns a Source for a piece of code used as a script. 27 func NewScriptSource(name, path, code string) *Source { 28 return &Source{SrcScript, name, path, code} 29 } 30 31 // NewModuleSource returns a Source for a piece of code used as a module. 32 func NewModuleSource(name, path, code string) *Source { 33 return &Source{SrcModule, name, path, code} 34 } 35 36 func NewInternalSource(name string) *Source { 37 return &Source{SrcInternal, name, name, ""} 38 } 39 40 func (src *Source) describePath() string { 41 if src.typ == SrcInteractive { 42 return "[tty]" 43 } 44 return src.path 45 } 46 47 var ( 48 _ vals.Indexer = (*Source)(nil) 49 ) 50 51 func (src *Source) Kind() string { 52 return "map" 53 } 54 55 func (src *Source) Hash() uint32 { 56 return hash.DJB(hash.Hash(src.typ), 57 hash.Hash(src.name), hash.Hash(src.path), hash.Hash(src.code)) 58 } 59 60 func (src *Source) Equal(other interface{}) bool { 61 if src2, ok := other.(*Source); ok { 62 return *src == *src2 63 } 64 return false 65 } 66 67 func (src *Source) Repr(int) string { 68 return fmt.Sprintf("<src type:%s name:%s path:%s code:...>", 69 src.typ, parse.Quote(src.name), parse.Quote(src.path)) 70 } 71 72 func (src *Source) Index(k interface{}) (interface{}, bool) { 73 ret := "" 74 switch k { 75 case "type": 76 ret = src.typ.String() 77 case "name": 78 ret = src.name 79 case "path": 80 ret = src.path 81 case "code": 82 ret = src.code 83 default: 84 return nil, false 85 } 86 return ret, true 87 } 88 89 func (src *Source) IterateKeys(f func(interface{}) bool) { 90 vals.Feed(f, "type", "name", "path", "code") 91 } 92 93 // SrcType records the type of a piece of source code. 94 type SrcType int 95 96 const ( 97 // SrcInternal is a special SrcType for internal operations. 98 SrcInternal SrcType = iota 99 // SrcInteractive is the type of source code entered interactively. 100 SrcInteractive 101 // SrcScript is the type of source code used as a script. 102 SrcScript 103 // SrcModule is the type of source code used as a module. 104 SrcModule 105 ) 106 107 func (t SrcType) String() string { 108 switch t { 109 case SrcInternal: 110 return "internal" 111 case SrcInteractive: 112 return "interactive" 113 case SrcScript: 114 return "script" 115 case SrcModule: 116 return "module" 117 default: 118 return "bad type " + strconv.Itoa(int(t)) 119 } 120 }