|
@@ -0,0 +1,141 @@
|
|
|
+package muesli
|
|
|
+
|
|
|
+type ObjectGetter func() Value
|
|
|
+type ObjectSetter func(Value) Value
|
|
|
+type ObjectMethod func(...Value) []Value
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+type Object interface {
|
|
|
+ Value
|
|
|
+ Get(key string) Value
|
|
|
+ Set(key string, to Value) Value
|
|
|
+ Invoke(key string, args... Value) []Value
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+type BasicObject struct {
|
|
|
+ RedispatchCallable
|
|
|
+ Parent * BasicObject
|
|
|
+ Object interface{}
|
|
|
+ Getters map[string] ObjectGetter
|
|
|
+ Setters map[string] ObjectSetter
|
|
|
+ Methods map[string] ObjectMethod
|
|
|
+}
|
|
|
+
|
|
|
+const ObjectType = TypeValue("Object")
|
|
|
+
|
|
|
+func (v BasicObject) Type() TypeValue { return ObjectType }
|
|
|
+
|
|
|
+func (val BasicObject) String() string {
|
|
|
+ res := "{"
|
|
|
+ sep := ""
|
|
|
+ for k, v := range val.Getters {
|
|
|
+ res = res + sep + k + "=>" + v().String()
|
|
|
+ sep = ", "
|
|
|
+ }
|
|
|
+ res += "}"
|
|
|
+ return res
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+func (o *BasicObject) Getter(name string, getter ObjectGetter) *BasicObject {
|
|
|
+ o.Getters[name] = getter
|
|
|
+ return o
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+func (o *BasicObject) Setter(name string, setter ObjectSetter) *BasicObject {
|
|
|
+ o.Setters[name] = setter
|
|
|
+ return o
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+func (o *BasicObject) Method(name string, method ObjectMethod) *BasicObject {
|
|
|
+ o.Methods[name] = method
|
|
|
+ return o
|
|
|
+}
|
|
|
+
|
|
|
+func NewBasicObject(object interface {}, parent *BasicObject) *BasicObject {
|
|
|
+ mv := &BasicObject{Object:object,
|
|
|
+ Parent: parent,
|
|
|
+ Getters: make(map[string] ObjectGetter),
|
|
|
+ Setters: make(map[string] ObjectSetter),
|
|
|
+ Methods: make(map[string] ObjectMethod),
|
|
|
+ }
|
|
|
+ mv.RedispatchCallable = NewRedispatchCallable("Object", mv)
|
|
|
+ return mv
|
|
|
+}
|
|
|
+
|
|
|
+func (m *BasicObject) Get(key string) Value {
|
|
|
+ var res ObjectGetter
|
|
|
+ var ok bool
|
|
|
+ if res, ok = m.Getters[key] ; !ok {
|
|
|
+ if m.Parent != nil {
|
|
|
+ return m.Parent.Get(key)
|
|
|
+ }
|
|
|
+ return NilValue
|
|
|
+ }
|
|
|
+ return res()
|
|
|
+}
|
|
|
+
|
|
|
+func (m *BasicObject) Set(key string, to Value) Value {
|
|
|
+ var res ObjectSetter
|
|
|
+ var ok bool
|
|
|
+ if res, ok = m.Setters[key] ; !ok {
|
|
|
+ if m.Parent != nil {
|
|
|
+ return m.Parent.Set(key, to)
|
|
|
+ }
|
|
|
+ return NilValue
|
|
|
+ }
|
|
|
+ return res(to)
|
|
|
+}
|
|
|
+
|
|
|
+func (m *BasicObject) Invoke(key string, args... Value) []Value {
|
|
|
+ var res ObjectMethod
|
|
|
+ var ok bool
|
|
|
+ if res, ok = m.Methods[key] ; !ok {
|
|
|
+ if m.Parent != nil {
|
|
|
+ return m.Parent.Invoke(key, args...)
|
|
|
+ }
|
|
|
+ return Fail(NewErrorValuef("No such method %s", key))
|
|
|
+ }
|
|
|
+ return res(args...)
|
|
|
+}
|
|
|
+
|
|
|
+func (from *BasicObject) Convert(to interface{}) error {
|
|
|
+ switch toPtr := to.(type) {
|
|
|
+ case **BasicObject:
|
|
|
+ (*toPtr) = from
|
|
|
+ case *Value:
|
|
|
+ (*toPtr) = from
|
|
|
+ default:
|
|
|
+ return NewErrorValuef("Cannot convert value %v to %v", from, to)
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+var _ Object = &BasicObject{}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+type Flex struct {
|
|
|
+ Fields map [string]Value
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|