optimizations
Some checks failed
Build / build (push) Successful in 10m47s
Publish Image / publish (push) Failing after 33s
Test / build (push) Failing after 6m42s

This commit is contained in:
Chuck Smith
2024-04-02 14:54:08 -04:00
parent 88e3330856
commit f08b458325
9 changed files with 313 additions and 355 deletions

View File

@@ -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)
}

View File

@@ -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},