add objects.Callable

This commit is contained in:
Daniel Kang 2019-01-09 19:07:03 -08:00
parent c2305f3cce
commit b638f0db87
3 changed files with 26 additions and 13 deletions

View file

@ -4,28 +4,34 @@ import (
"github.com/d5/tengo/token" "github.com/d5/tengo/token"
) )
type BuiltinFunction BuiltinFunc type BuiltinFunction struct {
Value BuiltinFunc
}
func (o BuiltinFunction) TypeName() string { func (o *BuiltinFunction) TypeName() string {
return "builtin-function" return "builtin-function"
} }
func (o BuiltinFunction) String() string { func (o *BuiltinFunction) String() string {
return "<builtin-function>" return "<builtin-function>"
} }
func (o BuiltinFunction) BinaryOp(op token.Token, rhs Object) (Object, error) { func (o *BuiltinFunction) BinaryOp(op token.Token, rhs Object) (Object, error) {
return nil, ErrInvalidOperator return nil, ErrInvalidOperator
} }
func (o BuiltinFunction) Copy() Object { func (o *BuiltinFunction) Copy() Object {
return BuiltinFunction(o) return &BuiltinFunction{Value: o.Value}
} }
func (o BuiltinFunction) IsFalsy() bool { func (o *BuiltinFunction) IsFalsy() bool {
return false return false
} }
func (o BuiltinFunction) Equals(x Object) bool { func (o *BuiltinFunction) Equals(x Object) bool {
return false return false
} }
func (o *BuiltinFunction) Call(args ...Object) (Object, error) {
return o.Value(args...)
}

5
objects/callable.go Normal file
View file

@ -0,0 +1,5 @@
package objects
type Callable interface {
Call(args ...Object) (ret Object, err error)
}

View file

@ -840,8 +840,8 @@ func (v *VM) executeCall(numArgs int) error {
return v.callFunction(callee.Fn, callee.Free, numArgs) return v.callFunction(callee.Fn, callee.Free, numArgs)
case *objects.CompiledFunction: case *objects.CompiledFunction:
return v.callFunction(callee, nil, numArgs) return v.callFunction(callee, nil, numArgs)
case objects.BuiltinFunction: case objects.Callable:
return v.callBuiltinFunction(callee, numArgs) return v.callCallable(callee, numArgs)
default: default:
return fmt.Errorf("calling non-function: %s", callee.TypeName()) return fmt.Errorf("calling non-function: %s", callee.TypeName())
} }
@ -864,19 +864,21 @@ func (v *VM) callFunction(fn *objects.CompiledFunction, freeVars []*objects.Obje
return nil return nil
} }
func (v *VM) callBuiltinFunction(builtin objects.BuiltinFunction, numArgs int) error { func (v *VM) callCallable(callable objects.Callable, numArgs int) error {
var args []objects.Object var args []objects.Object
for _, arg := range v.stack[v.sp-numArgs : v.sp] { for _, arg := range v.stack[v.sp-numArgs : v.sp] {
args = append(args, *arg) args = append(args, *arg)
} }
res, err := builtin(args...) res, err := callable.Call(args...)
v.sp -= numArgs + 1 v.sp -= numArgs + 1
// runtime error
if err != nil { if err != nil {
return err return err
} }
// nil return -> undefined
if res == nil { if res == nil {
res = undefinedObj res = undefinedObj
} }
@ -933,6 +935,6 @@ func selectorAssign(dst, src *objects.Object, selectors []interface{}) error {
func init() { func init() {
builtinFuncs = make([]objects.Object, len(objects.Builtins)) builtinFuncs = make([]objects.Object, len(objects.Builtins))
for i, b := range objects.Builtins { for i, b := range objects.Builtins {
builtinFuncs[i] = objects.BuiltinFunction(b.Func) builtinFuncs[i] = &objects.BuiltinFunction{Value: b.Func}
} }
} }