src.elv.sh@v0.21.0-dev.0.20240515223629-06979efb9a2a/pkg/edit/vars.go (about)

     1  package edit
     2  
     3  import (
     4  	"strings"
     5  
     6  	"src.elv.sh/pkg/eval"
     7  	"src.elv.sh/pkg/eval/errs"
     8  	"src.elv.sh/pkg/eval/vals"
     9  )
    10  
    11  func initVarsAPI(nb eval.NsBuilder) {
    12  	nb.AddGoFns(map[string]any{
    13  		"add-var":  addVar,
    14  		"add-vars": addVars,
    15  		"del-var":  delVar,
    16  		"del-vars": delVars,
    17  	})
    18  }
    19  
    20  func addVar(fm *eval.Frame, name string, val any) error {
    21  	if !isUnqualified(name) {
    22  		return errs.BadValue{
    23  			What:  "name argument to edit:add-var",
    24  			Valid: "unqualified variable name", Actual: name}
    25  	}
    26  	variable := eval.MakeVarFromName(name)
    27  	err := variable.Set(val)
    28  	if err != nil {
    29  		return err
    30  	}
    31  	fm.Evaler.ExtendGlobal(eval.BuildNs().AddVar(name, variable))
    32  	return nil
    33  }
    34  
    35  func delVar(fm *eval.Frame, name string) error {
    36  	if !isUnqualified(name) {
    37  		return errs.BadValue{
    38  			What:  "name argument to edit:del-var",
    39  			Valid: "unqualified variable name", Actual: name}
    40  	}
    41  	fm.Evaler.DeleteFromGlobal(map[string]struct{}{name: {}})
    42  	return nil
    43  }
    44  
    45  func addVars(fm *eval.Frame, m vals.Map) error {
    46  	nb := eval.BuildNs()
    47  	for it := m.Iterator(); it.HasElem(); it.Next() {
    48  		k, val := it.Elem()
    49  		name, ok := k.(string)
    50  		if !ok {
    51  			return errs.BadValue{
    52  				What:  "key of argument to edit:add-vars",
    53  				Valid: "string", Actual: vals.Kind(k)}
    54  		}
    55  		if !isUnqualified(name) {
    56  			return errs.BadValue{
    57  				What:  "key of argument to edit:add-vars",
    58  				Valid: "unqualified variable name", Actual: name}
    59  		}
    60  		variable := eval.MakeVarFromName(name)
    61  		err := variable.Set(val)
    62  		if err != nil {
    63  			return err
    64  		}
    65  		nb.AddVar(name, variable)
    66  	}
    67  	fm.Evaler.ExtendGlobal(nb)
    68  	return nil
    69  }
    70  
    71  func delVars(fm *eval.Frame, m vals.List) error {
    72  	names := make(map[string]struct{}, m.Len())
    73  	for it := m.Iterator(); it.HasElem(); it.Next() {
    74  		n := it.Elem()
    75  		name, ok := n.(string)
    76  		if !ok {
    77  			return errs.BadValue{
    78  				What:  "element of argument to edit:del-vars",
    79  				Valid: "string", Actual: vals.Kind(n)}
    80  		}
    81  		if !isUnqualified(name) {
    82  			return errs.BadValue{
    83  				What:  "element of argument to edit:del-vars",
    84  				Valid: "unqualified variable name", Actual: name}
    85  		}
    86  		names[name] = struct{}{}
    87  	}
    88  	fm.Evaler.DeleteFromGlobal(names)
    89  	return nil
    90  }
    91  
    92  func isUnqualified(name string) bool {
    93  	i := strings.IndexByte(name, ':')
    94  	return i == -1 || i == len(name)-1
    95  }