Skip to content

Commit

Permalink
starlark: method map Builtins of built-in types
Browse files Browse the repository at this point in the history
  • Loading branch information
emcfarlane committed Mar 6, 2020
1 parent 5eda5aa commit 648435e
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 93 deletions.
156 changes: 71 additions & 85 deletions starlark/library.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,103 +69,89 @@ func init() {
}
}

type builtinMethod func(thread *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error)

type builtins struct {
attrs map[string]*Builtin
names []string
}
// methods of built-in types
// https://github.com/google/starlark-go/blob/master/doc/spec.md#built-in-methods
var (
dictMethods = map[string]*Builtin{
"clear": NewBuiltin("clear", dict_clear),
"get": NewBuiltin("get", dict_get),
"items": NewBuiltin("items", dict_items),
"keys": NewBuiltin("keys", dict_keys),
"pop": NewBuiltin("pop", dict_pop),
"popitem": NewBuiltin("popitem", dict_popitem),
"setdefault": NewBuiltin("setdefault", dict_setdefault),
"update": NewBuiltin("update", dict_update),
"values": NewBuiltin("values", dict_values),
}

listMethods = map[string]*Builtin{
"append": NewBuiltin("append", list_append),
"clear": NewBuiltin("clear", list_clear),
"extend": NewBuiltin("extend", list_extend),
"index": NewBuiltin("index", list_index),
"insert": NewBuiltin("insert", list_insert),
"pop": NewBuiltin("pop", list_pop),
"remove": NewBuiltin("remove", list_remove),
}

stringMethods = map[string]*Builtin{
"capitalize": NewBuiltin("capitalize", string_capitalize),
"codepoint_ords": NewBuiltin("codepoint_ords", string_iterable),
"codepoints": NewBuiltin("codepoints", string_iterable), // sic
"count": NewBuiltin("count", string_count),
"elem_ords": NewBuiltin("elem_ords", string_iterable),
"elems": NewBuiltin("elems", string_iterable), // sic
"endswith": NewBuiltin("endswith", string_startswith), // sic
"find": NewBuiltin("find", string_find),
"format": NewBuiltin("format", string_format),
"index": NewBuiltin("index", string_index),
"isalnum": NewBuiltin("isalnum", string_isalnum),
"isalpha": NewBuiltin("isalpha", string_isalpha),
"isdigit": NewBuiltin("isdigit", string_isdigit),
"islower": NewBuiltin("islower", string_islower),
"isspace": NewBuiltin("isspace", string_isspace),
"istitle": NewBuiltin("istitle", string_istitle),
"isupper": NewBuiltin("isupper", string_isupper),
"join": NewBuiltin("join", string_join),
"lower": NewBuiltin("lower", string_lower),
"lstrip": NewBuiltin("lstrip", string_strip), // sic
"partition": NewBuiltin("partition", string_partition),
"replace": NewBuiltin("replace", string_replace),
"rfind": NewBuiltin("rfind", string_rfind),
"rindex": NewBuiltin("rindex", string_rindex),
"rpartition": NewBuiltin("rpartition", string_partition), // sic
"rsplit": NewBuiltin("rsplit", string_split), // sic
"rstrip": NewBuiltin("rstrip", string_strip), // sic
"split": NewBuiltin("split", string_split),
"splitlines": NewBuiltin("splitlines", string_splitlines),
"startswith": NewBuiltin("startswith", string_startswith),
"strip": NewBuiltin("strip", string_strip),
"title": NewBuiltin("title", string_title),
"upper": NewBuiltin("upper", string_upper),
}

setMethods = map[string]*Builtin{
"union": NewBuiltin("union", set_union),
}
)

func (bs *builtins) bindAttr(recv Value, name string) (Value, error) {
b := bs.attrs[name]
func builtinAttr(recv Value, name string, methods map[string]*Builtin) (Value, error) {
b := methods[name]
if b == nil {
return nil, nil // no such method
}
return b.BindReceiver(recv), nil
}
func (bs *builtins) attrNames() []string {
names := make([]string, len(bs.names))
copy(names, bs.names)
return names
}

func newBuiltins(methods map[string]builtinMethod) *builtins {
attrs := make(map[string]*Builtin, len(methods))
func builtinAttrNames(methods map[string]*Builtin) []string {
names := make([]string, 0, len(methods))
for k, m := range methods {
attrs[k] = NewBuiltin(k, m)
names = append(names, k)
for name := range methods {
names = append(names, name)
}
sort.Strings(names)
return &builtins{attrs: attrs, names: names}
return names
}

// methods of built-in types
// https://github.com/google/starlark-go/blob/master/doc/spec.md#built-in-methods
var (
dictMethods = newBuiltins(map[string]builtinMethod{
"clear": dict_clear,
"get": dict_get,
"items": dict_items,
"keys": dict_keys,
"pop": dict_pop,
"popitem": dict_popitem,
"setdefault": dict_setdefault,
"update": dict_update,
"values": dict_values,
})

listMethods = newBuiltins(map[string]builtinMethod{
"append": list_append,
"clear": list_clear,
"extend": list_extend,
"index": list_index,
"insert": list_insert,
"pop": list_pop,
"remove": list_remove,
})

stringMethods = newBuiltins(map[string]builtinMethod{
"capitalize": string_capitalize,
"codepoint_ords": string_iterable,
"codepoints": string_iterable, // sic
"count": string_count,
"elem_ords": string_iterable,
"elems": string_iterable, // sic
"endswith": string_startswith, // sic
"find": string_find,
"format": string_format,
"index": string_index,
"isalnum": string_isalnum,
"isalpha": string_isalpha,
"isdigit": string_isdigit,
"islower": string_islower,
"isspace": string_isspace,
"istitle": string_istitle,
"isupper": string_isupper,
"join": string_join,
"lower": string_lower,
"lstrip": string_strip, // sic
"partition": string_partition,
"replace": string_replace,
"rfind": string_rfind,
"rindex": string_rindex,
"rpartition": string_partition, // sic
"rsplit": string_split, // sic
"rstrip": string_strip, // sic
"split": string_split,
"splitlines": string_splitlines,
"startswith": string_startswith,
"strip": string_strip,
"title": string_title,
"upper": string_upper,
})

setMethods = newBuiltins(map[string]builtinMethod{
"union": set_union,
})
)

// ---- built-in functions ----

// https://github.com/google/starlark-go/blob/master/doc/spec.md#all
Expand Down
16 changes: 8 additions & 8 deletions starlark/value.go
Original file line number Diff line number Diff line change
Expand Up @@ -489,8 +489,8 @@ func (s String) Slice(start, end, step int) Value {
return String(str)
}

func (s String) Attr(name string) (Value, error) { return stringMethods.bindAttr(s, name) }
func (s String) AttrNames() []string { return stringMethods.attrNames() }
func (s String) Attr(name string) (Value, error) { return builtinAttr(s, name, stringMethods) }
func (s String) AttrNames() []string { return builtinAttrNames(stringMethods) }

func (x String) CompareSameType(op syntax.Token, y_ Value, depth int) (bool, error) {
y := y_.(String)
Expand Down Expand Up @@ -708,8 +708,8 @@ func (d *Dict) Freeze() { d.ht.freeze()
func (d *Dict) Truth() Bool { return d.Len() > 0 }
func (d *Dict) Hash() (uint32, error) { return 0, fmt.Errorf("unhashable type: dict") }

func (d *Dict) Attr(name string) (Value, error) { return dictMethods.bindAttr(d, name) }
func (d *Dict) AttrNames() []string { return dictMethods.attrNames() }
func (d *Dict) Attr(name string) (Value, error) { return builtinAttr(d, name, dictMethods) }
func (d *Dict) AttrNames() []string { return builtinAttrNames(dictMethods) }

func (x *Dict) CompareSameType(op syntax.Token, y_ Value, depth int) (bool, error) {
y := y_.(*Dict)
Expand Down Expand Up @@ -796,8 +796,8 @@ func (l *List) Slice(start, end, step int) Value {
return NewList(list)
}

func (l *List) Attr(name string) (Value, error) { return listMethods.bindAttr(l, name) }
func (l *List) AttrNames() []string { return listMethods.attrNames() }
func (l *List) Attr(name string) (Value, error) { return builtinAttr(l, name, listMethods) }
func (l *List) AttrNames() []string { return builtinAttrNames(listMethods) }

func (l *List) Iterate() Iterator {
if !l.frozen {
Expand Down Expand Up @@ -975,8 +975,8 @@ func (s *Set) Freeze() { s.ht.freeze() }
func (s *Set) Hash() (uint32, error) { return 0, fmt.Errorf("unhashable type: set") }
func (s *Set) Truth() Bool { return s.Len() > 0 }

func (s *Set) Attr(name string) (Value, error) { return setMethods.bindAttr(s, name) }
func (s *Set) AttrNames() []string { return setMethods.attrNames() }
func (s *Set) Attr(name string) (Value, error) { return builtinAttr(s, name, setMethods) }
func (s *Set) AttrNames() []string { return builtinAttrNames(setMethods) }

func (x *Set) CompareSameType(op syntax.Token, y_ Value, depth int) (bool, error) {
y := y_.(*Set)
Expand Down

0 comments on commit 648435e

Please sign in to comment.