aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/robertkrimen/otto/builtin_function.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/robertkrimen/otto/builtin_function.go')
-rw-r--r--vendor/github.com/robertkrimen/otto/builtin_function.go129
1 files changed, 129 insertions, 0 deletions
diff --git a/vendor/github.com/robertkrimen/otto/builtin_function.go b/vendor/github.com/robertkrimen/otto/builtin_function.go
new file mode 100644
index 000000000..3d07566c6
--- /dev/null
+++ b/vendor/github.com/robertkrimen/otto/builtin_function.go
@@ -0,0 +1,129 @@
+package otto
+
+import (
+ "fmt"
+ "regexp"
+ "strings"
+ "unicode"
+
+ "github.com/robertkrimen/otto/parser"
+)
+
+// Function
+
+func builtinFunction(call FunctionCall) Value {
+ return toValue_object(builtinNewFunctionNative(call.runtime, call.ArgumentList))
+}
+
+func builtinNewFunction(self *_object, argumentList []Value) Value {
+ return toValue_object(builtinNewFunctionNative(self.runtime, argumentList))
+}
+
+func argumentList2parameterList(argumentList []Value) []string {
+ parameterList := make([]string, 0, len(argumentList))
+ for _, value := range argumentList {
+ tmp := strings.FieldsFunc(value.string(), func(chr rune) bool {
+ return chr == ',' || unicode.IsSpace(chr)
+ })
+ parameterList = append(parameterList, tmp...)
+ }
+ return parameterList
+}
+
+var matchIdentifier = regexp.MustCompile(`^[$_\p{L}][$_\p{L}\d}]*$`)
+
+func builtinNewFunctionNative(runtime *_runtime, argumentList []Value) *_object {
+ var parameterList, body string
+ count := len(argumentList)
+ if count > 0 {
+ tmp := make([]string, 0, count-1)
+ for _, value := range argumentList[0 : count-1] {
+ tmp = append(tmp, value.string())
+ }
+ parameterList = strings.Join(tmp, ",")
+ body = argumentList[count-1].string()
+ }
+
+ // FIXME
+ function, err := parser.ParseFunction(parameterList, body)
+ runtime.parseThrow(err) // Will panic/throw appropriately
+ cmpl := _compiler{}
+ cmpl_function := cmpl.parseExpression(function)
+
+ return runtime.newNodeFunction(cmpl_function.(*_nodeFunctionLiteral), runtime.globalStash)
+}
+
+func builtinFunction_toString(call FunctionCall) Value {
+ object := call.thisClassObject("Function") // Should throw a TypeError unless Function
+ switch fn := object.value.(type) {
+ case _nativeFunctionObject:
+ return toValue_string(fmt.Sprintf("function %s() { [native code] }", fn.name))
+ case _nodeFunctionObject:
+ return toValue_string(fn.node.source)
+ case _bindFunctionObject:
+ return toValue_string("function () { [native code] }")
+ }
+
+ panic(call.runtime.panicTypeError("Function.toString()"))
+}
+
+func builtinFunction_apply(call FunctionCall) Value {
+ if !call.This.isCallable() {
+ panic(call.runtime.panicTypeError())
+ }
+ this := call.Argument(0)
+ if this.IsUndefined() {
+ // FIXME Not ECMA5
+ this = toValue_object(call.runtime.globalObject)
+ }
+ argumentList := call.Argument(1)
+ switch argumentList.kind {
+ case valueUndefined, valueNull:
+ return call.thisObject().call(this, nil, false, nativeFrame)
+ case valueObject:
+ default:
+ panic(call.runtime.panicTypeError())
+ }
+
+ arrayObject := argumentList._object()
+ thisObject := call.thisObject()
+ length := int64(toUint32(arrayObject.get("length")))
+ valueArray := make([]Value, length)
+ for index := int64(0); index < length; index++ {
+ valueArray[index] = arrayObject.get(arrayIndexToString(index))
+ }
+ return thisObject.call(this, valueArray, false, nativeFrame)
+}
+
+func builtinFunction_call(call FunctionCall) Value {
+ if !call.This.isCallable() {
+ panic(call.runtime.panicTypeError())
+ }
+ thisObject := call.thisObject()
+ this := call.Argument(0)
+ if this.IsUndefined() {
+ // FIXME Not ECMA5
+ this = toValue_object(call.runtime.globalObject)
+ }
+ if len(call.ArgumentList) >= 1 {
+ return thisObject.call(this, call.ArgumentList[1:], false, nativeFrame)
+ }
+ return thisObject.call(this, nil, false, nativeFrame)
+}
+
+func builtinFunction_bind(call FunctionCall) Value {
+ target := call.This
+ if !target.isCallable() {
+ panic(call.runtime.panicTypeError())
+ }
+ targetObject := target._object()
+
+ this := call.Argument(0)
+ argumentList := call.slice(1)
+ if this.IsUndefined() {
+ // FIXME Do this elsewhere?
+ this = toValue_object(call.runtime.globalObject)
+ }
+
+ return toValue_object(call.runtime.newBoundFunction(targetObject, this, argumentList))
+}