1
0
mirror of https://github.com/robertkrimen/otto synced 2025-10-12 20:27:30 +08:00
otto/type_reference.go
Robert Krimen 5f407353c2 Implementation (and use) of _declarativeEnvironment
No longer masquerading via _objectEnvironment
2012-11-05 17:14:56 -08:00

145 lines
2.8 KiB
Go

package otto
type _reference interface {
GetBase() *_object
GetValue() Value
PutValue(Value) bool
Name() string
Strict() bool
Delete() bool
}
// Reference
type _reference_ struct {
name string
strict bool
}
func (self _reference_) GetBase() *_object {
return nil
}
func (self _reference_) Name() string {
return self.name
}
func (self _reference_) Strict() bool {
return self.strict
}
func (self _reference_) Delete() {
panic(hereBeDragons())
}
// PropertyReference
type _propertyReference struct {
_reference_
Base *_object
node _node
}
func newPropertyReference(base *_object, name string, strict bool, node _node) *_propertyReference {
return &_propertyReference{
Base: base,
_reference_: _reference_{
name: name,
strict: strict,
},
node: node,
}
}
func (self *_propertyReference) GetBase() *_object {
return self.Base
}
func (self *_propertyReference) GetValue() Value {
if self.Base == nil {
panic(newReferenceError("notDefined", self.name, self.node))
}
return self.Base.get(self.name)
}
func (self *_propertyReference) PutValue(value Value) bool {
if self.Base == nil {
return false
}
self.Base.set(self.name, value, self.Strict())
return true
}
func (self *_propertyReference) Delete() bool {
if self.Base == nil {
// ?
return false
}
return self.Base.delete(self.name, self.Strict())
}
// ArgumentReference
func newArgumentReference(base *_object, name string, strict bool) *_propertyReference {
if base == nil {
panic(hereBeDragons())
}
return newPropertyReference(base, name, strict, nil)
}
type _environmentReference struct {
_reference_
Base _environment
node _node
}
func newEnvironmentReference(base _environment, name string, strict bool, node _node) *_environmentReference {
return &_environmentReference{
Base: base,
_reference_: _reference_{
name: name,
strict: strict,
},
node: node,
}
}
func (self *_environmentReference) GetBase() *_object {
return nil // FIXME
}
func (self *_environmentReference) GetValue() Value {
if self.Base == nil {
panic(newReferenceError("notDefined", self.name, self.node))
}
return self.Base.GetValue(self.name, self.Strict())
}
func (self *_environmentReference) PutValue(value Value) bool {
if self.Base == nil {
return false
}
self.Base.SetValue(self.name, value, self.Strict())
return true
}
func (self *_environmentReference) Delete() bool {
if self.Base == nil {
// ?
return false
}
return self.Base.DeleteBinding(self.name)
}
// getIdentifierReference
func getIdentifierReference(environment _environment, name string, strict bool, node _node) _reference {
if environment == nil {
return newPropertyReference(nil, name, strict, node)
}
if environment.HasBinding(name) {
return environment.newReference(name, strict)
}
return getIdentifierReference(environment.Outer(), name, strict, node)
}