optimizations
This commit is contained in:
@@ -9,6 +9,7 @@ import (
|
||||
"monkey/internal/context"
|
||||
"monkey/internal/lexer"
|
||||
"monkey/internal/object"
|
||||
"monkey/internal/ops"
|
||||
"monkey/internal/parser"
|
||||
"monkey/internal/utils"
|
||||
"os"
|
||||
@@ -24,20 +25,6 @@ const (
|
||||
maxGlobals = 65536
|
||||
)
|
||||
|
||||
func isTruthy(obj object.Object) bool {
|
||||
switch obj := obj.(type) {
|
||||
|
||||
case object.Boolean:
|
||||
return obj.Value
|
||||
|
||||
case object.Null:
|
||||
return false
|
||||
|
||||
default:
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
func executeModule(name string, state *State) (object.Object, error) {
|
||||
filename := utils.FindModule(name)
|
||||
if filename == "" {
|
||||
@@ -331,131 +318,51 @@ func (vm *VM) executeMakeArray() error {
|
||||
func (vm *VM) executeAdd() error {
|
||||
right, left := vm.pop2()
|
||||
|
||||
switch obj := left.(type) {
|
||||
case object.Integer:
|
||||
val, err := obj.Add(right)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return vm.push(val)
|
||||
case object.Float:
|
||||
val, err := obj.Add(right)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return vm.push(val)
|
||||
case object.String:
|
||||
val, err := obj.Add(right)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return vm.push(val)
|
||||
case *object.Array:
|
||||
val, err := obj.Add(right)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return vm.push(val)
|
||||
case *object.Hash:
|
||||
val, err := obj.Add(right)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return vm.push(val)
|
||||
default:
|
||||
return object.NewBinaryOpError(left, right, "+")
|
||||
val, err := ops.Add(left, right)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return vm.push(val)
|
||||
}
|
||||
|
||||
func (vm *VM) executeSub() error {
|
||||
right, left := vm.pop2()
|
||||
|
||||
switch obj := left.(type) {
|
||||
case object.Integer:
|
||||
val, err := obj.Sub(right)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return vm.push(val)
|
||||
case object.Float:
|
||||
val, err := obj.Sub(right)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return vm.push(val)
|
||||
default:
|
||||
return fmt.Errorf("unsupported types for unary operation: -%s", left.Type())
|
||||
val, err := ops.Sub(left, right)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return vm.push(val)
|
||||
}
|
||||
|
||||
func (vm *VM) executeMul() error {
|
||||
right, left := vm.pop2()
|
||||
|
||||
switch obj := left.(type) {
|
||||
case *object.Array:
|
||||
val, err := obj.Mul(right)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return vm.push(val)
|
||||
case object.Integer:
|
||||
val, err := obj.Mul(right)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return vm.push(val)
|
||||
case object.Float:
|
||||
val, err := obj.Mul(right)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return vm.push(val)
|
||||
case object.String:
|
||||
val, err := obj.Mul(right)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return vm.push(val)
|
||||
default:
|
||||
return object.NewBinaryOpError(left, right, "*")
|
||||
val, err := ops.Mul(left, right)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return vm.push(val)
|
||||
}
|
||||
|
||||
func (vm *VM) executeDiv() error {
|
||||
right, left := vm.pop2()
|
||||
|
||||
switch obj := left.(type) {
|
||||
case object.Integer:
|
||||
val, err := obj.Div(right)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return vm.push(val)
|
||||
case object.Float:
|
||||
val, err := obj.Div(right)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return vm.push(val)
|
||||
default:
|
||||
return object.NewBinaryOpError(left, right, "/")
|
||||
val, err := ops.Div(left, right)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return vm.push(val)
|
||||
}
|
||||
|
||||
func (vm *VM) executeMod() error {
|
||||
right, left := vm.pop2()
|
||||
|
||||
switch obj := left.(type) {
|
||||
case object.Integer:
|
||||
val, err := obj.Mod(right)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return vm.push(val)
|
||||
default:
|
||||
return object.NewBinaryOpError(left, right, "%")
|
||||
val, err := ops.Mod(left, right)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return vm.push(val)
|
||||
}
|
||||
|
||||
func (vm *VM) executeOr() error {
|
||||
@@ -577,37 +484,25 @@ func (vm *VM) executeRightShift() error {
|
||||
func (vm *VM) executeEqual() error {
|
||||
right, left := vm.pop2()
|
||||
|
||||
if left.Compare(right) == 0 {
|
||||
return vm.push(object.TRUE)
|
||||
}
|
||||
return vm.push(object.FALSE)
|
||||
return vm.push(object.FromNativeBoolean(left.Compare(right) == 0))
|
||||
}
|
||||
|
||||
func (vm *VM) executeNotEqual() error {
|
||||
right, left := vm.pop2()
|
||||
|
||||
if left.Compare(right) != 0 {
|
||||
return vm.push(object.TRUE)
|
||||
}
|
||||
return vm.push(object.FALSE)
|
||||
return vm.push(object.FromNativeBoolean(left.Compare(right) != 0))
|
||||
}
|
||||
|
||||
func (vm *VM) executeGreaterThan() error {
|
||||
right, left := vm.pop2()
|
||||
|
||||
if left.Compare(right) == 1 {
|
||||
return vm.push(object.TRUE)
|
||||
}
|
||||
return vm.push(object.FALSE)
|
||||
return vm.push(object.FromNativeBoolean(left.Compare(right) == 1))
|
||||
}
|
||||
|
||||
func (vm *VM) executeGreaterThanOrEqual() error {
|
||||
right, left := vm.pop2()
|
||||
|
||||
if left.Compare(right) == 1 {
|
||||
return vm.push(object.TRUE)
|
||||
}
|
||||
return vm.push(object.FALSE)
|
||||
return vm.push(object.FromNativeBoolean(left.Compare(right) >= 0))
|
||||
}
|
||||
|
||||
func (vm *VM) executeNot() error {
|
||||
@@ -745,7 +640,6 @@ func (vm *VM) callClosure(cl *object.Closure, numArgs int) error {
|
||||
func (vm *VM) callBuiltin(builtin object.Builtin, numArgs int) error {
|
||||
args := vm.stack[vm.sp-numArgs : vm.sp]
|
||||
|
||||
log.Printf("args: %+v", args)
|
||||
result := builtin.Fn(vm.ctx, args...)
|
||||
vm.sp = vm.sp - numArgs - 1
|
||||
|
||||
@@ -839,7 +733,7 @@ func (vm *VM) Run() (err error) {
|
||||
|
||||
case code.OpJumpNotTruthy:
|
||||
pos := vm.currentFrame().ReadUint16()
|
||||
if !isTruthy(vm.pop()) {
|
||||
if !object.IsTruthy(vm.pop()) {
|
||||
vm.currentFrame().SetIP(pos)
|
||||
}
|
||||
|
||||
|
||||
@@ -257,6 +257,24 @@ func TestFloatingPointArithmetic(t *testing.T) {
|
||||
runVmTests(t, tests)
|
||||
}
|
||||
|
||||
func TestMixedArithmetic(t *testing.T) {
|
||||
tests := []vmTestCase{
|
||||
{"1 + 2.1", 3.1},
|
||||
{"2 - 0.5", 1.5},
|
||||
{"2 * 2.5", 5.0},
|
||||
{"5 / 2.0", 2.5},
|
||||
{"5 % 2.0", 1.0},
|
||||
|
||||
{"2.1 + 1", 3.1},
|
||||
{"2.5 - 2", 0.5},
|
||||
{"2.5 * 2", 5.0},
|
||||
{"5.0 / 2", 2.5},
|
||||
{"5.0 % 2", 1.0},
|
||||
}
|
||||
|
||||
runVmTests(t, tests)
|
||||
}
|
||||
|
||||
func TestBooleanExpressions(t *testing.T) {
|
||||
tests := []vmTestCase{
|
||||
{"true", true},
|
||||
|
||||
Reference in New Issue
Block a user