From 18c7ab70ded45c76abb0b35c090b942a7bfcc3b4 Mon Sep 17 00:00:00 2001 From: Mel Date: Sun, 26 Jun 2022 21:54:38 +0200 Subject: Change arguments order in VM to match expectation --- pkg/lang/compiler/compiler.go | 18 ++++---- pkg/lang/compiler/compiler_test.go | 36 +++++++-------- pkg/lang/vm/core.go | 8 ++-- pkg/lang/vm/exec.go | 59 ++++++++++++----------- pkg/lang/vm/stack/stack.go | 13 ------ pkg/lang/vm/vm_test.go | 95 +++++++++++++++++++------------------- 6 files changed, 110 insertions(+), 119 deletions(-) (limited to 'pkg/lang') diff --git a/pkg/lang/compiler/compiler.go b/pkg/lang/compiler/compiler.go index d2b332d..4d7f4a1 100644 --- a/pkg/lang/compiler/compiler.go +++ b/pkg/lang/compiler/compiler.go @@ -103,11 +103,11 @@ func (comp *Compiler) compileBinaryExpr(expr ast.ExprBinary) error { return comp.compileAssignExpr(expr) } - if err := comp.compileExpr(expr.Right); err != nil { + if err := comp.compileExpr(expr.Left); err != nil { return err } - if err := comp.compileExpr(expr.Left); err != nil { + if err := comp.compileExpr(expr.Right); err != nil { return err } @@ -189,16 +189,16 @@ func (comp *Compiler) compileUnaryExpr(expr ast.ExprUnary) error { } func (comp *Compiler) compileCallExpr(expr ast.ExprCall) error { - for i := len(expr.Args) - 1; i >= 0; i-- { + if err := comp.compileExpr(expr.Callee); err != nil { + return err + } + + for i := 0; i < len(expr.Args); i++ { if err := comp.compileExpr(expr.Args[i]); err != nil { return err } } - if err := comp.compileExpr(expr.Callee); err != nil { - return err - } - comp.builder.AppendOp(code.OpCall) comp.builder.AppendInt(int64(len(expr.Args))) @@ -206,11 +206,11 @@ func (comp *Compiler) compileCallExpr(expr ast.ExprCall) error { } func (comp *Compiler) compileSubscriptionExpr(expr ast.ExprSubscription) error { - if err := comp.compileExpr(expr.Key); err != nil { + if err := comp.compileExpr(expr.Obj); err != nil { return err } - if err := comp.compileExpr(expr.Obj); err != nil { + if err := comp.compileExpr(expr.Key); err != nil { return err } diff --git a/pkg/lang/compiler/compiler_test.go b/pkg/lang/compiler/compiler_test.go index 5347830..cf0fee2 100644 --- a/pkg/lang/compiler/compiler_test.go +++ b/pkg/lang/compiler/compiler_test.go @@ -19,8 +19,8 @@ func TestSimpleAddExpr(t *testing.T) { ` expected := ` - push_int 2 push_int 1 + push_int 2 add ` @@ -37,12 +37,12 @@ func TestOperationOrder(t *testing.T) { ` expected := ` - push_int 4 - push_int 3 - push_int 2 push_int 1 + push_int 2 add + push_int 3 sub + push_int 4 add ` @@ -57,25 +57,25 @@ func TestNestedExpr(t *testing.T) { ` expected := ` - push_int 321 - push_int 456 - index + push_int 1 + push_int 2 + add + + push_int 3 + sub - push_string "c" - push_string "b" - push_string "a" push_int 123 + push_string "a" + push_string "b" + push_string "c" call 3 - add - - push_int 3 + push_int 456 + push_int 321 + index - push_int 2 - push_int 1 add sub - sub ` mustCompileTo(t, src, expected) @@ -95,13 +95,13 @@ func TestVars(t *testing.T) { push_int 25 - push_int 7 get_local 0 + push_int 7 add set_local 0 - get_local 1 get_local 0 + get_local 1 add ` diff --git a/pkg/lang/vm/core.go b/pkg/lang/vm/core.go index 59dcaed..7d5aefe 100644 --- a/pkg/lang/vm/core.go +++ b/pkg/lang/vm/core.go @@ -79,16 +79,16 @@ func (vm *VM) coreTypeRefIntrAddMethod(args []value.Value) (value.Value, error) return value.Value{}, err } - nameData, err := ensureType[value.StringData](args[0], value.StringType) + fn, err := ensureType[value.FunctionData](args[0], value.FunctionType) if err != nil { return value.Value{}, err } - name, err := nameData.RawString(vm.memory) + + nameData, err := ensureType[value.StringData](args[1], value.StringType) if err != nil { return value.Value{}, err } - - fn, err := ensureType[value.FunctionData](args[1], value.FunctionType) + name, err := nameData.RawString(vm.memory) if err != nil { return value.Value{}, err } diff --git a/pkg/lang/vm/exec.go b/pkg/lang/vm/exec.go index 4fbc516..93b8845 100644 --- a/pkg/lang/vm/exec.go +++ b/pkg/lang/vm/exec.go @@ -218,12 +218,12 @@ func (vm *VM) execGetMember(name string) error { } func (vm *VM) execSetMember(name string) error { - parent, err := vm.stack.Pop() + v, err := vm.stack.Pop() if err != nil { return err } - v, err := vm.stack.Pop() + parent, err := vm.stack.Pop() if err != nil { return err } @@ -394,12 +394,12 @@ func (vm *VM) execAddToEnv(localIndex int) error { } func (vm *VM) execAnchorType() error { - o, err := vm.stack.Pop() + t, err := vm.stack.Pop() if err != nil { return err } - t, err := vm.stack.Pop() + o, err := vm.stack.Pop() if err != nil { return err } @@ -433,11 +433,11 @@ func (vm *VM) execAnchorType() error { } func (vm *VM) execAdd() error { - x, err := vm.stack.Pop() + y, err := vm.stack.Pop() if err != nil { return err } - y, err := vm.stack.Pop() + x, err := vm.stack.Pop() if err != nil { return err } @@ -517,11 +517,11 @@ func (vm *VM) execAdd() error { } func (vm *VM) execSub() error { - x, err := vm.popAndDrop() + y, err := vm.popAndDrop() if err != nil { return err } - y, err := vm.popAndDrop() + x, err := vm.popAndDrop() if err != nil { return err } @@ -574,11 +574,11 @@ func (vm *VM) execSub() error { } func (vm *VM) execMod() error { - x, err := vm.popAndDrop() + y, err := vm.popAndDrop() if err != nil { return err } - y, err := vm.popAndDrop() + x, err := vm.popAndDrop() if err != nil { return err } @@ -612,11 +612,11 @@ func (vm *VM) execMod() error { } func (vm *VM) execIndex() error { - v, err := vm.popAndDrop() + i, err := vm.popAndDrop() if err != nil { return err } - i, err := vm.popAndDrop() + v, err := vm.popAndDrop() if err != nil { return err } @@ -663,11 +663,11 @@ func (vm *VM) execIndex() error { } func (vm *VM) execLte() error { - x, err := vm.popAndDrop() + y, err := vm.popAndDrop() if err != nil { return err } - y, err := vm.popAndDrop() + x, err := vm.popAndDrop() if err != nil { return err } @@ -720,6 +720,16 @@ func (vm *VM) execLte() error { } func (vm *VM) execCall(argCount uint) error { + var err error + + args := make([]value.Value, argCount) + for i := 0; i < int(argCount); i++ { + args[i], err = vm.stack.Pop() + if err != nil { + return err + } + } + f, err := vm.stack.Pop() if err != nil { return err @@ -746,19 +756,7 @@ func (vm *VM) execCall(argCount uint) error { return err } - if err = vm.stack.ShiftTopCallBase(int(argCount)); err != nil { - return err - } - if fn.Native() != nil { - args := make([]value.Value, argCount) - for i := 0; i < int(argCount); i++ { - args[i], err = vm.stack.Pop() - if err != nil { - return err - } - } - val, err := fn.Native()(args) if err != nil { return err @@ -774,6 +772,11 @@ func (vm *VM) execCall(argCount uint) error { return nil } + + for _, arg := range args { + vm.stack.Push(arg) + } + vm.pc = fn.Pc() return nil @@ -851,11 +854,11 @@ func (vm *VM) execTempArrLen() error { } func (vm *VM) execTempArrPush() error { - a, err := vm.popAndDrop() + e, err := vm.popAndDrop() if err != nil { return err } - e, err := vm.popAndDrop() + a, err := vm.popAndDrop() if err != nil { return err } diff --git a/pkg/lang/vm/stack/stack.go b/pkg/lang/vm/stack/stack.go index 314d0c6..34ca896 100644 --- a/pkg/lang/vm/stack/stack.go +++ b/pkg/lang/vm/stack/stack.go @@ -19,7 +19,6 @@ type Stack interface { PushCall(newPc, returnPc int, env mem.Ptr) error PopCall() (int, error) - ShiftTopCallBase(by int) error CurrentCallEnv() mem.Ptr CallDepth() int @@ -133,18 +132,6 @@ func (stack *stackImpl) PopCall() (int, error) { return call.returnPc, nil } -func (stack *stackImpl) ShiftTopCallBase(by int) error { - call := stack.topCall() - newBase := call.base - by - - if newBase < 0 { - return ErrCallBaseCantBeNegative - } - - call.base = newBase - return nil -} - func (stack *stackImpl) CurrentCallEnv() mem.Ptr { if stack.CallDepth() == 0 || stack.topCall().env.IsNull() { return mem.NullPtr diff --git a/pkg/lang/vm/vm_test.go b/pkg/lang/vm/vm_test.go index d63523f..fa43b02 100644 --- a/pkg/lang/vm/vm_test.go +++ b/pkg/lang/vm/vm_test.go @@ -12,8 +12,8 @@ import ( func TestSimpleSub(t *testing.T) { src := ` - push_int 1 push_int 2 + push_int 1 sub ` @@ -23,8 +23,8 @@ func TestSimpleSub(t *testing.T) { func TestGetLocal(t *testing.T) { src := ` push_int 404 - push_int 1 push_int 2 + push_int 1 add get_local 1 ` @@ -37,51 +37,51 @@ func TestFibonacci(t *testing.T) { # Array stored in local 0 push_array - push_int 1 get_local 0 + push_int 1 temp_arr_push - push_int 1 get_local 0 + push_int 1 temp_arr_push @fib_loop: - - push_int 1 - get_local 0 temp_arr_len + + push_int 1 # Index of the last element stored in local 1 sub + get_local 0 + get_local 0 # This is the last element get_local 1 - get_local 0 # Store the last element in local 2 index - push_int 1 + get_local 0 + get_local 1 + push_int 1 # Index of the second last element stored in local 2 sub - get_local 0 # Store the second last element in local 3 index add - get_local 0 temp_arr_push # Drop local 1, which was the length of the array, which we no longer need drop - push_int 10 - get_local 0 temp_arr_len + push_int 10 + # Jump if the array is larger than 10. lte jt @fib_loop @@ -123,8 +123,8 @@ func TestSimpleEnv(t *testing.T) { halt @test: + get_env 0 push_int 2 - get_env 0 add ret ` @@ -152,19 +152,19 @@ func TestEscapedEnv(t *testing.T) { push_array + get_local 1 get_local 0 call 0 - get_local 1 temp_arr_push + get_local 1 get_local 0 call 0 - get_local 1 temp_arr_push + get_local 1 get_local 0 call 0 - get_local 1 temp_arr_push halt @@ -176,8 +176,8 @@ func TestEscapedEnv(t *testing.T) { add_to_env 0 ret @create:anon_0: + get_env 0 push_int 1 - get_env 0 add set_env 0 get_env 0 @@ -191,16 +191,16 @@ func TestMember(t *testing.T) { src := ` push_array - push_int 1 get_local 0 + push_int 1 temp_arr_push - push_int 2 get_local 0 + push_int 2 temp_arr_push - push_int 3 get_local 0 + push_int 3 temp_arr_push get_member "length" @@ -214,12 +214,12 @@ func TestObject(t *testing.T) { src := ` push_object - push_string "Petronij" get_local 0 + push_string "Petronij" set_member "name" - push_int 10 get_local 0 + push_int 10 set_member "age" get_local 0 @@ -250,27 +250,27 @@ func TestTypeConstruct(t *testing.T) { # Create a new type Cat push_type "Cat" - push_function @Cat:$init - push_string "$init" - get_local 0 get_member "$add_method" + + push_string "$init" + push_function @Cat:$init call 2 - push_function @Cat:meow - push_string "meow" - get_local 0 get_member "$add_method" + push_string "meow" + push_function @Cat:meow + call 2 # Create a new instance of Cat - push_string "Kitty" - push_int 3 get_local 0 get_member "$init" + push_string "Kitty" + push_int 3 call 2 # Call the meow method @@ -280,24 +280,24 @@ func TestTypeConstruct(t *testing.T) { halt @Cat:$init: - get_env 0 push_object + get_env 0 anchor_type - get_local 0 get_local 2 + get_local 1 set_member "name" - get_local 1 get_local 2 + get_local 0 set_member "age" ret @Cat:meow: - push_string " says Meow!" - get_env 0 get_member "name" + + push_string " says Meow!" add ret @@ -308,7 +308,7 @@ func TestTypeConstruct(t *testing.T) { func TestPrimes(t *testing.T) { /* - var i = 0 + var i = 2 var primes = [] for i <= 10 { @@ -339,8 +339,8 @@ func TestPrimes(t *testing.T) { push_int 2 push_array @main_loop: - push_int 10 get_local 0 + push_int 10 lte jf @end @@ -348,47 +348,48 @@ func TestPrimes(t *testing.T) { push_int 1 @factor_loop: - get_local 0 get_local 3 + get_local 0 lte jf @prime_check - push_int 0 - - get_local 3 + get_local 0 + get_local 3 mod + + push_int 0 lte jf @factor_loop_inc - get_local 3 get_local 2 + get_local 3 temp_arr_push @factor_loop_inc: - push_int 1 get_local 3 + push_int 1 add set_local 3 jmp @factor_loop @prime_check: - push_int 2 get_local 2 get_member "length" call 0 + push_int 2 lte jf @main_loop_inc - get_local 0 get_local 1 + get_local 0 temp_arr_push @main_loop_inc: - push_int 1 get_local 0 + push_int 1 add set_local 0 -- cgit 1.4.1