From d84c0f36afcde4e5af2907d70931de75957d5277 Mon Sep 17 00:00:00 2001 From: Mel Date: Tue, 16 Aug 2022 20:33:41 +0000 Subject: Implement setting values at index in an array --- pkg/lang/compiler/compiler.go | 15 ++++++++++++++ pkg/lang/compiler/compiler_test.go | 40 ++++++++++++++++++++++++++++++++++++ pkg/lang/modules/core/compiled.go | 2 +- pkg/lang/vm/code/op.go | 1 + pkg/lang/vm/exec.go | 42 ++++++++++++++++++++++++++++++++++++++ pkg/lang/vm/text/decompiler.go | 1 + pkg/lang/vm/text/op.go | 1 + pkg/lang/vm/value/data.go | 14 +++++++++++++ pkg/lang/vm/vm.go | 3 +++ pkg/lang/vm/vm_test.go | 27 ++++++++++++++++++++++++ 10 files changed, 145 insertions(+), 1 deletion(-) (limited to 'pkg') diff --git a/pkg/lang/compiler/compiler.go b/pkg/lang/compiler/compiler.go index d1b98da..193cd90 100644 --- a/pkg/lang/compiler/compiler.go +++ b/pkg/lang/compiler/compiler.go @@ -759,6 +759,21 @@ func (comp *Compiler) compileAssignExpr(t *code.Builder, expr ast.ExprBinary) er t.AppendOp(code.OpSetMember) t.AppendString(name) + case ast.ExprKindSubscription: + subscriptionExpr := expr.Left.Value.(ast.ExprSubscription) + if err := comp.compileExpr(t, subscriptionExpr.Obj); err != nil { + return err + } + + if err := comp.compileExpr(t, subscriptionExpr.Key); err != nil { + return err + } + + if err := comp.compileExpr(t, expr.Right); err != nil { + return err + } + + t.AppendOp(code.OpSetAtIndex) default: return fmt.Errorf("invalid left-hand side of assignment to %v", expr.Left.Kind) } diff --git a/pkg/lang/compiler/compiler_test.go b/pkg/lang/compiler/compiler_test.go index e40d98e..2e4e6e7 100644 --- a/pkg/lang/compiler/compiler_test.go +++ b/pkg/lang/compiler/compiler_test.go @@ -629,6 +629,46 @@ func TestGlobals(t *testing.T) { mustCompileTo(t, src, expected) } +func TestLvalueAssign(t *testing.T) { + src := ` + var v = 1 + var obj = null + var arr = [1] + + v = 2 + obj.x = 2 + arr[0] = 2 + ` + + expected := ` + push_int 1 + + push_null + + push_array + get_local 2 + get_member "push" + push_int 1 + call 1 + drop 1 + + push_int 2 + set_local 0 + + get_local 1 + push_int 2 + set_member "x" + + get_local 2 + push_int 0 + push_int 2 + set_at_index + halt + ` + + mustCompileTo(t, src, expected) +} + func mustCompileTo(t *testing.T, src, expected string) { scanner := scanner.New(strings.NewReader(src)) tokens, err := scanner.Scan() diff --git a/pkg/lang/modules/core/compiled.go b/pkg/lang/modules/core/compiled.go index ae34cf4..5068720 100644 --- a/pkg/lang/modules/core/compiled.go +++ b/pkg/lang/modules/core/compiled.go @@ -6,7 +6,7 @@ import ( ) var moduleCompiled = []byte{ - 0xb, 0x54, 0x79, 0x70, 0x65, 0x0, 0xe, 0x3a, 0x63, 0x6f, 0x72, 0x65, 0x3a, 0x73, 0x65, 0x74, 0x75, 0x70, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x23, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x24, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0x54, 0x79, 0x70, 0x65, 0x0, 0xb, 0x4e, 0x75, 0x6c, 0x6c, 0x0, 0x10, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x12, 0x24, 0x61, 0x64, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x0, 0x4, 0x24, 0x69, 0x6e, 0x69, 0x74, 0x0, 0x9, 0x5a, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x24, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0x49, 0x6e, 0x74, 0x0, 0x10, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x12, 0x24, 0x61, 0x64, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x0, 0x4, 0x24, 0x69, 0x6e, 0x69, 0x74, 0x0, 0x9, 0x9a, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x24, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x0, 0x10, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x12, 0x24, 0x61, 0x64, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x0, 0x4, 0x24, 0x69, 0x6e, 0x69, 0x74, 0x0, 0x9, 0xd9, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x24, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x0, 0x10, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x12, 0x24, 0x61, 0x64, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x0, 0x4, 0x24, 0x69, 0x6e, 0x69, 0x74, 0x0, 0x9, 0x1a, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x24, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0x42, 0x6f, 0x6f, 0x6c, 0x0, 0x10, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x12, 0x24, 0x61, 0x64, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x0, 0x4, 0x24, 0x69, 0x6e, 0x69, 0x74, 0x0, 0x9, 0x5c, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x24, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0x41, 0x72, 0x72, 0x61, 0x79, 0x0, 0x10, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x12, 0x24, 0x61, 0x64, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x0, 0x4, 0x24, 0x69, 0x6e, 0x69, 0x74, 0x0, 0x9, 0x9c, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x24, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x12, 0x24, 0x61, 0x64, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x0, 0x4, 0x70, 0x75, 0x73, 0x68, 0x0, 0x9, 0xdd, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x24, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x12, 0x24, 0x61, 0x64, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x0, 0x4, 0x70, 0x6f, 0x70, 0x0, 0x9, 0x1c, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x24, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x12, 0x24, 0x61, 0x64, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x0, 0x4, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x0, 0x9, 0x47, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x24, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x0, 0x10, 0x7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x12, 0x24, 0x61, 0x64, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x0, 0x4, 0x24, 0x69, 0x6e, 0x69, 0x74, 0x0, 0x9, 0x75, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x24, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, 0xb9, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, 0xe8, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0x4e, 0x75, 0x6c, 0x6c, 0x0, 0x10, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0x49, 0x6e, 0x74, 0x0, 0x10, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x0, 0x10, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x0, 0x10, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0x42, 0x6f, 0x6f, 0x6c, 0x0, 0x10, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0x41, 0x72, 0x72, 0x61, 0x79, 0x0, 0x10, 0x7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x0, 0x10, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0x73, 0x61, 0x79, 0x0, 0x10, 0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0x70, 0x69, 0x6e, 0x67, 0x0, 0x1, 0xa, 0x14, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x17, 0xe, 0x3a, 0x63, 0x6f, 0x72, 0x65, 0x3a, 0x4e, 0x75, 0x6c, 0x6c, 0x3a, 0x24, 0x69, 0x6e, 0x69, 0x74, 0x23, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x0, 0x24, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x28, 0xa, 0x14, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x17, 0xe, 0x3a, 0x63, 0x6f, 0x72, 0x65, 0x3a, 0x49, 0x6e, 0x74, 0x3a, 0x24, 0x69, 0x6e, 0x69, 0x74, 0x23, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x0, 0x24, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x28, 0xa, 0x14, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x17, 0xe, 0x3a, 0x63, 0x6f, 0x72, 0x65, 0x3a, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x3a, 0x24, 0x69, 0x6e, 0x69, 0x74, 0x23, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x0, 0x24, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x28, 0xa, 0x14, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x17, 0xe, 0x3a, 0x63, 0x6f, 0x72, 0x65, 0x3a, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3a, 0x24, 0x69, 0x6e, 0x69, 0x74, 0x23, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x0, 0x24, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x28, 0xa, 0x14, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x17, 0xe, 0x3a, 0x63, 0x6f, 0x72, 0x65, 0x3a, 0x42, 0x6f, 0x6f, 0x6c, 0x3a, 0x24, 0x69, 0x6e, 0x69, 0x74, 0x23, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x0, 0x24, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x28, 0xa, 0x14, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x17, 0xe, 0x3a, 0x63, 0x6f, 0x72, 0x65, 0x3a, 0x41, 0x72, 0x72, 0x61, 0x79, 0x3a, 0x24, 0x69, 0x6e, 0x69, 0x74, 0x23, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x0, 0x24, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x28, 0xe, 0x3a, 0x63, 0x6f, 0x72, 0x65, 0x3a, 0x41, 0x72, 0x72, 0x61, 0x79, 0x3a, 0x70, 0x75, 0x73, 0x68, 0x23, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x0, 0x14, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x24, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0x28, 0xe, 0x3a, 0x63, 0x6f, 0x72, 0x65, 0x3a, 0x41, 0x72, 0x72, 0x61, 0x79, 0x3a, 0x70, 0x6f, 0x70, 0x23, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x0, 0x14, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x24, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x28, 0xe, 0x3a, 0x63, 0x6f, 0x72, 0x65, 0x3a, 0x41, 0x72, 0x72, 0x61, 0x79, 0x3a, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x23, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x0, 0x14, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x24, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x28, 0xa, 0x14, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x17, 0xe, 0x3a, 0x63, 0x6f, 0x72, 0x65, 0x3a, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x24, 0x69, 0x6e, 0x69, 0x74, 0x23, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x0, 0x24, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x28, 0xe, 0x3a, 0x63, 0x6f, 0x72, 0x65, 0x3a, 0x73, 0x61, 0x79, 0x23, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x24, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0x28, 0x4, 0x50, 0x6f, 0x6e, 0x67, 0x21, 0x0, 0x28, + 0xb, 0x54, 0x79, 0x70, 0x65, 0x0, 0xe, 0x3a, 0x63, 0x6f, 0x72, 0x65, 0x3a, 0x73, 0x65, 0x74, 0x75, 0x70, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x23, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x25, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0x54, 0x79, 0x70, 0x65, 0x0, 0xb, 0x4e, 0x75, 0x6c, 0x6c, 0x0, 0x10, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x12, 0x24, 0x61, 0x64, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x0, 0x4, 0x24, 0x69, 0x6e, 0x69, 0x74, 0x0, 0x9, 0x5a, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x25, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0x49, 0x6e, 0x74, 0x0, 0x10, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x12, 0x24, 0x61, 0x64, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x0, 0x4, 0x24, 0x69, 0x6e, 0x69, 0x74, 0x0, 0x9, 0x9a, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x25, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x0, 0x10, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x12, 0x24, 0x61, 0x64, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x0, 0x4, 0x24, 0x69, 0x6e, 0x69, 0x74, 0x0, 0x9, 0xd9, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x25, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x0, 0x10, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x12, 0x24, 0x61, 0x64, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x0, 0x4, 0x24, 0x69, 0x6e, 0x69, 0x74, 0x0, 0x9, 0x1a, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x25, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0x42, 0x6f, 0x6f, 0x6c, 0x0, 0x10, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x12, 0x24, 0x61, 0x64, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x0, 0x4, 0x24, 0x69, 0x6e, 0x69, 0x74, 0x0, 0x9, 0x5c, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x25, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0x41, 0x72, 0x72, 0x61, 0x79, 0x0, 0x10, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x12, 0x24, 0x61, 0x64, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x0, 0x4, 0x24, 0x69, 0x6e, 0x69, 0x74, 0x0, 0x9, 0x9c, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x25, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x12, 0x24, 0x61, 0x64, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x0, 0x4, 0x70, 0x75, 0x73, 0x68, 0x0, 0x9, 0xdd, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x25, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x12, 0x24, 0x61, 0x64, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x0, 0x4, 0x70, 0x6f, 0x70, 0x0, 0x9, 0x1c, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x25, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x12, 0x24, 0x61, 0x64, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x0, 0x4, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x0, 0x9, 0x47, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x25, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x0, 0x10, 0x7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x12, 0x24, 0x61, 0x64, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x0, 0x4, 0x24, 0x69, 0x6e, 0x69, 0x74, 0x0, 0x9, 0x75, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x25, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, 0xb9, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, 0xe8, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0x4e, 0x75, 0x6c, 0x6c, 0x0, 0x10, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0x49, 0x6e, 0x74, 0x0, 0x10, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x0, 0x10, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x0, 0x10, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0x42, 0x6f, 0x6f, 0x6c, 0x0, 0x10, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0x41, 0x72, 0x72, 0x61, 0x79, 0x0, 0x10, 0x7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x0, 0x10, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0x73, 0x61, 0x79, 0x0, 0x10, 0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0x70, 0x69, 0x6e, 0x67, 0x0, 0x1, 0xa, 0x14, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x17, 0xe, 0x3a, 0x63, 0x6f, 0x72, 0x65, 0x3a, 0x4e, 0x75, 0x6c, 0x6c, 0x3a, 0x24, 0x69, 0x6e, 0x69, 0x74, 0x23, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x0, 0x25, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x29, 0xa, 0x14, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x17, 0xe, 0x3a, 0x63, 0x6f, 0x72, 0x65, 0x3a, 0x49, 0x6e, 0x74, 0x3a, 0x24, 0x69, 0x6e, 0x69, 0x74, 0x23, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x0, 0x25, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x29, 0xa, 0x14, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x17, 0xe, 0x3a, 0x63, 0x6f, 0x72, 0x65, 0x3a, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x3a, 0x24, 0x69, 0x6e, 0x69, 0x74, 0x23, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x0, 0x25, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x29, 0xa, 0x14, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x17, 0xe, 0x3a, 0x63, 0x6f, 0x72, 0x65, 0x3a, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3a, 0x24, 0x69, 0x6e, 0x69, 0x74, 0x23, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x0, 0x25, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x29, 0xa, 0x14, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x17, 0xe, 0x3a, 0x63, 0x6f, 0x72, 0x65, 0x3a, 0x42, 0x6f, 0x6f, 0x6c, 0x3a, 0x24, 0x69, 0x6e, 0x69, 0x74, 0x23, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x0, 0x25, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x29, 0xa, 0x14, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x17, 0xe, 0x3a, 0x63, 0x6f, 0x72, 0x65, 0x3a, 0x41, 0x72, 0x72, 0x61, 0x79, 0x3a, 0x24, 0x69, 0x6e, 0x69, 0x74, 0x23, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x0, 0x25, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x29, 0xe, 0x3a, 0x63, 0x6f, 0x72, 0x65, 0x3a, 0x41, 0x72, 0x72, 0x61, 0x79, 0x3a, 0x70, 0x75, 0x73, 0x68, 0x23, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x0, 0x14, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x25, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0x29, 0xe, 0x3a, 0x63, 0x6f, 0x72, 0x65, 0x3a, 0x41, 0x72, 0x72, 0x61, 0x79, 0x3a, 0x70, 0x6f, 0x70, 0x23, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x0, 0x14, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x25, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x29, 0xe, 0x3a, 0x63, 0x6f, 0x72, 0x65, 0x3a, 0x41, 0x72, 0x72, 0x61, 0x79, 0x3a, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x23, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x0, 0x14, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x25, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x29, 0xa, 0x14, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x17, 0xe, 0x3a, 0x63, 0x6f, 0x72, 0x65, 0x3a, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x24, 0x69, 0x6e, 0x69, 0x74, 0x23, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x0, 0x25, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x29, 0xe, 0x3a, 0x63, 0x6f, 0x72, 0x65, 0x3a, 0x73, 0x61, 0x79, 0x23, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x25, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0x29, 0x4, 0x50, 0x6f, 0x6e, 0x67, 0x21, 0x0, 0x29, } var moduleCode = code.New(code.Raw(moduleCompiled), code.NewDebugInfo("core")) diff --git a/pkg/lang/vm/code/op.go b/pkg/lang/vm/code/op.go index b4c172a..8a5c6b5 100644 --- a/pkg/lang/vm/code/op.go +++ b/pkg/lang/vm/code/op.go @@ -47,6 +47,7 @@ const ( OpGte OpIndex + OpSetAtIndex OpCall OpJmp diff --git a/pkg/lang/vm/exec.go b/pkg/lang/vm/exec.go index 34cf444..a64751a 100644 --- a/pkg/lang/vm/exec.go +++ b/pkg/lang/vm/exec.go @@ -832,6 +832,48 @@ func (vm *VM) execIndex() error { return nil } +func (vm *VM) execSetAtIndex() error { + e, err := vm.popAndDrop() + if err != nil { + return err + } + + i, err := vm.popAndDrop() + if err != nil { + return err + } + + v, err := vm.popAndDrop() + if err != nil { + return err + } + + if i.Type() != value.IntType || v.Type() != value.ArrayType { + return ErrInvalidOperandTypes{ + Op: code.OpSetAtIndex, + X: v.Type(), + Y: i.Type(), + } + } + + arr := v.Data().(value.ArrayData) + idx := i.Data().(value.IntData).Get() + + len, err := arr.Len(vm.memory) + if err != nil { + return err + } + + if idx < 0 || idx >= int64(len) { + return ErrArrayIndexOutOfBounds{ + Index: int(idx), + Len: int(len), + } + } + + return arr.Set(vm.memory, int(idx), e) +} + func (vm *VM) execCall(argCount uint) error { var err error diff --git a/pkg/lang/vm/text/decompiler.go b/pkg/lang/vm/text/decompiler.go index 8a85d49..df9e1ed 100644 --- a/pkg/lang/vm/text/decompiler.go +++ b/pkg/lang/vm/text/decompiler.go @@ -67,6 +67,7 @@ func (d *Decompiler) decompileInstruction(bc code.Raw) (string, code.Raw) { code.OpLte, code.OpGte, code.OpIndex, + code.OpSetAtIndex, code.OpRet, code.OpTempArrLen, code.OpTempArrPush: diff --git a/pkg/lang/vm/text/op.go b/pkg/lang/vm/text/op.go index ff3c568..213656b 100644 --- a/pkg/lang/vm/text/op.go +++ b/pkg/lang/vm/text/op.go @@ -40,6 +40,7 @@ var ( code.OpLte: "lte", code.OpGte: "gte", code.OpIndex: "index", + code.OpSetAtIndex: "set_at_index", code.OpCall: "call", code.OpJmp: "jmp", code.OpJt: "jt", diff --git a/pkg/lang/vm/value/data.go b/pkg/lang/vm/value/data.go index 1cd258b..59e4742 100644 --- a/pkg/lang/vm/value/data.go +++ b/pkg/lang/vm/value/data.go @@ -108,6 +108,20 @@ func (a ArrayData) At(m mem.Mem, i int) (Value, error) { return arr[i], nil } +func (a ArrayData) Set(m mem.Mem, i int, v Value) error { + data, err := m.Get(a.data) + if err != nil { + return err + } + arr := data.(ArrayCell).Get() + arr[i] = v + + if err := m.Set(a.data, ArrayCell(arr)); err != nil { + return err + } + return nil +} + func (a ArrayData) Push(m mem.Mem, v Value) error { data, err := m.Get(a.data) if err != nil { diff --git a/pkg/lang/vm/vm.go b/pkg/lang/vm/vm.go index 4b40633..f24095d 100644 --- a/pkg/lang/vm/vm.go +++ b/pkg/lang/vm/vm.go @@ -270,6 +270,9 @@ func (vm *VM) step(module *code.Code, op code.Op) (stepDecision, error) { case code.OpIndex: err = vm.execIndex() + case code.OpSetAtIndex: + err = vm.execSetAtIndex() + case code.OpCall: argCount, advance := module.GetUint(vm.pc()) vm.advancePC(advance) diff --git a/pkg/lang/vm/vm_test.go b/pkg/lang/vm/vm_test.go index 178d756..8f961ef 100644 --- a/pkg/lang/vm/vm_test.go +++ b/pkg/lang/vm/vm_test.go @@ -510,6 +510,33 @@ func TestCoreSay(t *testing.T) { require.Equal(t, "\"Meow!!\"", string(result)) } +func TestSetAtArray(t *testing.T) { + src := ` + push_array + + get_local 0 + get_member "push" + push_int 1 + call 1 + drop 1 + + get_local 0 + get_member "push" + push_int 2 + call 1 + drop 1 + + get_local 0 + push_int 0 + push_int 2 + set_at_index + + get_local 0 + ` + + test(t, src, "[2, 2]") +} + func test(t *testing.T, src string, expected string) { bc := compile(t, src) vm := vm.New(modules.NewUnknownModule(&bc)) -- cgit 1.4.1