github.com/oweisse/u-root@v0.0.0-20181109060735-d005ad25fef1/cmds/elvish/eval/source.go (about)

     1  package eval
     2  
     3  import (
     4  	"fmt"
     5  	"strconv"
     6  
     7  	"github.com/u-root/u-root/cmds/elvish/eval/vals"
     8  	"github.com/u-root/u-root/cmds/elvish/parse"
     9  	"github.com/u-root/u-root/cmds/elvish/hash"
    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  }