Skip to content

Commit

Permalink
Split builtin.go out to builtin_*.go
Browse files Browse the repository at this point in the history
  • Loading branch information
robertkrimen committed Feb 20, 2013
1 parent 4e4e89c commit ec902a6
Show file tree
Hide file tree
Showing 11 changed files with 1,288 additions and 1,252 deletions.
1,252 changes: 0 additions & 1,252 deletions builtin.go

Large diffs are not rendered by default.

452 changes: 452 additions & 0 deletions builtin_array.go

Large diffs are not rendered by default.

11 changes: 11 additions & 0 deletions builtin_boolean.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package otto

// Boolean

func builtinBoolean(call FunctionCall) Value {
return toValue(toBoolean(call.Argument(0)))
}

func builtinNewBoolean(self *_object, _ Value, argumentList []Value) Value {
return toValue(self.runtime.newBoolean(valueOfArrayIndex(argumentList, 0)))
}
67 changes: 67 additions & 0 deletions builtin_date.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package otto

import (
time_ "time"
)

// Date

func builtinDate(call FunctionCall) Value {
return toValue(call.runtime.newDate(newDateTime(call.ArgumentList)))
}

func builtinNewDate(self *_object, _ Value, argumentList []Value) Value {
return toValue(self.runtime.newDate(newDateTime(argumentList)))
}

func builtinDate_toString(call FunctionCall) Value {
date := dateObjectOf(call.thisObject())
if date.isNaN {
return toValue("Invalid Date")
}
return toValue(date.Time().Local().Format(time_.RFC1123))
}

func builtinDate_toUTCString(call FunctionCall) Value {
date := dateObjectOf(call.thisObject())
if date.isNaN {
return toValue("Invalid Date")
}
return toValue(date.Time().Format(time_.RFC1123))
}

func builtinDate_getTime(call FunctionCall) Value {
date := dateObjectOf(call.thisObject())
if date.isNaN {
return NaNValue()
}
// We do this (convert away from a float) so the user
// does not get something back in exponential notation
return toValue(int64(date.Epoch()))
}

func builtinDate_setTime(call FunctionCall) Value {
date := dateObjectOf(call.thisObject())
date.Set(toFloat(call.Argument(0)))
return date.Value()
}

func _builtinDate_set(call FunctionCall, argumentCap int, dateLocal bool) (*_dateObject, *_ecmaTime) {
date := dateObjectOf(call.thisObject())
if date.isNaN {
return nil, nil
}
for index := 0; index < len(call.ArgumentList) && index < argumentCap; index++ {
value := call.Argument(index)
if value.IsNaN() {
date.SetNaN()
return date, nil
}
}
baseTime := date.Time()
if dateLocal {
baseTime = baseTime.Local()
}
ecmaTime := ecmaTime(baseTime)
return date, &ecmaTime
}
73 changes: 73 additions & 0 deletions builtin_function.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package otto

// Function

func builtinFunction(call FunctionCall) Value {
return toValue(builtinNewFunctionNative(call.runtime, call.ArgumentList))
}

func builtinNewFunction(self *_object, _ Value, argumentList []Value) Value {
return toValue(builtinNewFunctionNative(self.runtime, argumentList))
}

func builtinNewFunctionNative(runtime *_runtime, argumentList []Value) *_object {
parameterList := []string{}
bodySource := ""
argumentCount := len(argumentList)
if argumentCount > 0 {
bodySource = toString(argumentList[argumentCount-1])
argumentList = argumentList[0 : argumentCount-1]
for _, value := range argumentList {
parameterList = append(parameterList, toString(value))
}
}

parser := newParser()
parser.lexer.Source = bodySource
_programNode := parser.ParseAsFunction()
return runtime.newNodeFunction(_programNode.toFunction(parameterList), runtime.GlobalEnvironment)
}

func builtinFunction_apply(call FunctionCall) Value {
if !call.This.isCallable() {
panic(newTypeError())
}
this := call.Argument(0)
if this.IsUndefined() {
// FIXME Not ECMA5
this = toValue(call.runtime.GlobalObject)
}
argumentList := call.Argument(1)
switch argumentList._valueType {
case valueUndefined, valueNull:
return call.thisObject().Call(this, []Value{})
case valueObject:
default:
panic(newTypeError())
}

arrayObject := argumentList._object()
thisObject := call.thisObject()
length := uint(toUint32(arrayObject.get("length")))
valueArray := make([]Value, length)
for index := uint(0); index < length; index++ {
valueArray[index] = arrayObject.get(arrayIndexToString(index))
}
return thisObject.Call(this, valueArray)
}

func builtinFunction_call(call FunctionCall) Value {
if !call.This.isCallable() {
panic(newTypeError())
}
thisObject := call.thisObject()
this := call.Argument(0)
if this.IsUndefined() {
// FIXME Not ECMA5
this = toValue(call.runtime.GlobalObject)
}
if len(call.ArgumentList) >= 1 {
return thisObject.Call(this, call.ArgumentList[1:])
}
return thisObject.Call(this, []Value{})
}
79 changes: 79 additions & 0 deletions builtin_math.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package otto

import (
"math"
"math/rand"
)

// Math

func builtinMath_max(call FunctionCall) Value {
switch len(call.ArgumentList) {
case 0:
return negativeInfinityValue()
case 1:
return toValue(toFloat(call.ArgumentList[0]))
default:
result := toFloat(call.ArgumentList[0])
if math.IsNaN(result) {
return NaNValue()
}
for _, value := range call.ArgumentList[1:] {
value := toFloat(value)
if math.IsNaN(value) {
return NaNValue()
}
result = math.Max(result, value)
}
return toValue(result)
}
return UndefinedValue()
}

func builtinMath_min(call FunctionCall) Value {
switch len(call.ArgumentList) {
case 0:
return positiveInfinityValue()
case 1:
return toValue(toFloat(call.ArgumentList[0]))
default:
result := toFloat(call.ArgumentList[0])
if math.IsNaN(result) {
return NaNValue()
}
for _, value := range call.ArgumentList[1:] {
value := toFloat(value)
if math.IsNaN(value) {
return NaNValue()
}
result = math.Min(result, value)
}
return toValue(result)
}
return UndefinedValue()
}

func builtinMath_ceil(call FunctionCall) Value {
number := toFloat(call.Argument(0))
if math.IsNaN(number) {
return NaNValue()
}
return toValue(math.Ceil(number))
}

func builtinMath_floor(call FunctionCall) Value {
number := toFloat(call.Argument(0))
if math.IsNaN(number) {
return NaNValue()
}
return toValue(math.Floor(number))
}

func builtinMath_random(call FunctionCall) Value {
return toValue(rand.Float64())
}

func builtinMath_pow(call FunctionCall) Value {
// TODO Make sure this works according to the specification (15.8.2.13)
return toValue(math.Pow(toFloat(call.Argument(0)), toFloat(call.Argument(1))))
}
18 changes: 18 additions & 0 deletions builtin_number.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package otto

// Number

func numberValueFromNumberArgumentList(argumentList []Value) Value {
if len(argumentList) > 0 {
return toValue(toNumber(argumentList[0]))
}
return toValue(0)
}

func builtinNumber(call FunctionCall) Value {
return numberValueFromNumberArgumentList(call.ArgumentList)
}

func builtinNewNumber(self *_object, _ Value, argumentList []Value) Value {
return toValue(self.runtime.newNumber(numberValueFromNumberArgumentList(argumentList)))
}
97 changes: 97 additions & 0 deletions builtin_object.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package otto

import (
"fmt"
)

// Object

func builtinObject(call FunctionCall) Value {
value := call.Argument(0)
switch value._valueType {
case valueUndefined, valueNull:
return toValue(call.runtime.newObject())
}

return toValue(call.runtime.toObject(value))
}

func builtinNewObject(self *_object, _ Value, _ []Value) Value {
return toValue(self.runtime.newObject())
}

func builtinObject_toString(call FunctionCall) Value {
result := ""
if call.This.IsUndefined() {
result = "[object Undefined]"
} else if call.This.IsNull() {
result = "[object Null]"
} else {
result = fmt.Sprintf("[object %s]", call.thisObject().class)
}
return toValue(result)
}

func builtinObject_getOwnPropertyDescriptor(call FunctionCall) Value {
objectValue := call.Argument(0)
object := objectValue._object()
if object == nil {
panic(newTypeError())
}

name := toString(call.Argument(1))
descriptor := object.getOwnProperty(name)
if descriptor == nil {
return UndefinedValue()
}
return toValue(call.runtime.fromPropertyDescriptor(*descriptor))
}

func builtinObject_defineProperty(call FunctionCall) Value {
objectValue := call.Argument(0)
object := objectValue._object()
if object == nil {
panic(newTypeError())
}
name := toString(call.Argument(1))
descriptor := toPropertyDescriptor(call.Argument(2))
object.defineOwnProperty(name, descriptor, true)
return objectValue
}

func builtinObject_defineProperties(call FunctionCall) Value {
objectValue := call.Argument(0)
object := objectValue._object()
if object == nil {
panic(newTypeError())
}

properties := call.runtime.toObject(call.Argument(1))
properties.enumerate(func(name string) {
descriptor := toPropertyDescriptor(properties.get(name))
object.defineOwnProperty(name, descriptor, true)
})

return objectValue
}

func builtinObject_create(call FunctionCall) Value {
prototypeValue := call.Argument(0)
prototype := prototypeValue._object()
if prototype == nil {
panic(newTypeError())
}

object := call.runtime.newObject()

propertiesValue := call.Argument(1)
if propertiesValue.IsDefined() {
properties := call.runtime.toObject(propertiesValue)
properties.enumerate(func(name string) {
descriptor := toPropertyDescriptor(properties.get(name))
object.defineOwnProperty(name, descriptor, true)
})
}

return toValue(object)
}
48 changes: 48 additions & 0 deletions builtin_regexp.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package otto

import (
"fmt"
)

// RegExp

func builtinRegExp(call FunctionCall) Value {
return toValue(call.runtime.newRegExp(call.Argument(0), call.Argument(1)))
}

func builtinNewRegExp(self *_object, _ Value, argumentList []Value) Value {
return toValue(self.runtime.newRegExp(valueOfArrayIndex(argumentList, 0), valueOfArrayIndex(argumentList, 1)))
}

func builtinRegExp_toString(call FunctionCall) Value {
thisObject := call.thisObject()
source := toString(thisObject.get("source"))
flags := []byte{}
if toBoolean(thisObject.get("global")) {
flags = append(flags, 'g')
}
if toBoolean(thisObject.get("ignoreCase")) {
flags = append(flags, 'i')
}
if toBoolean(thisObject.get("multiline")) {
flags = append(flags, 'm')
}
return toValue(fmt.Sprintf("/%s/%s", source, flags))
}

func builtinRegExp_exec(call FunctionCall) Value {
thisObject := call.thisObject()
target := toString(call.Argument(0))
match, result := execRegExp(thisObject, target)
if !match {
return NullValue()
}
return toValue(execResultToArray(call.runtime, target, result))
}

func builtinRegExp_test(call FunctionCall) Value {
thisObject := call.thisObject()
target := toString(call.Argument(0))
match, _ := execRegExp(thisObject, target)
return toValue(match)
}
Loading

0 comments on commit ec902a6

Please sign in to comment.