summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc Vertes <mvertes@free.fr>2026-01-23 13:05:10 +0100
committerMarc Vertes <mvertes@free.fr>2026-01-23 13:05:10 +0100
commit3113c7f058e427c49e936f82a518766ddb869c58 (patch)
treeb79e34e358514d1e0301722251cce3b195043670
parent2837dabf7818666a9366d659d2da3b9055140740 (diff)
feat: add Next2 and Pull2 instructions in vm.
These will be used for range clause assigning both key and value.
-rw-r--r--comp/compiler.go3
-rw-r--r--vm/op_string.go26
-rw-r--r--vm/vm.go19
3 files changed, 31 insertions, 17 deletions
diff --git a/comp/compiler.go b/comp/compiler.go
index ef379ea..4817914 100644
--- a/comp/compiler.go
+++ b/comp/compiler.go
@@ -128,7 +128,6 @@ func (c *Compiler) Generate(tokens parser.Tokens) (err error) {
c.emit(t, vm.Deref)
case lang.Index:
- showStack(stack)
pop()
s := pop()
if s.Type.Rtype.Kind() == reflect.Map {
@@ -361,7 +360,6 @@ func (c *Compiler) Generate(tokens parser.Tokens) (err error) {
if len(stack) < 1 {
return errorf("missing symbol")
}
- showStack(stack)
s := pop()
switch s.Kind {
case symbol.Pkg:
@@ -419,6 +417,7 @@ func (c *Compiler) Generate(tokens parser.Tokens) (err error) {
c.emit(t, vm.Next, i, k.Index)
case lang.Range:
+ showStack(stack)
// FIXME: handle all iterator types.
// set the correct type to the iterator variables.
switch t := top().Type; t.Rtype.Kind() {
diff --git a/vm/op_string.go b/vm/op_string.go
index 594bc3b..98c84a0 100644
--- a/vm/op_string.go
+++ b/vm/op_string.go
@@ -45,21 +45,23 @@ func _() {
_ = x[New-34]
_ = x[Negate-35]
_ = x[Next-36]
- _ = x[Not-37]
- _ = x[Pop-38]
- _ = x[Push-39]
- _ = x[Pull-40]
- _ = x[Return-41]
- _ = x[Slice-42]
- _ = x[Slice3-43]
- _ = x[Stop-44]
- _ = x[Sub-45]
- _ = x[Swap-46]
+ _ = x[Next2-37]
+ _ = x[Not-38]
+ _ = x[Pop-39]
+ _ = x[Push-40]
+ _ = x[Pull-41]
+ _ = x[Pull2-42]
+ _ = x[Return-43]
+ _ = x[Slice-44]
+ _ = x[Slice3-45]
+ _ = x[Stop-46]
+ _ = x[Sub-47]
+ _ = x[Swap-48]
}
-const _Op_name = "NopAddAddrAssignFassignVassignCallCallXDerefDupFdupFnewFnewEEqualEqualSetExitFieldFieldEFieldSetFieldFsetGreaterGrowIndexIndexSetJumpJumpTrueJumpFalseJumpSetTrueJumpSetFalseLenLowerMapIndexMapSetMulNewNegateNextNotPopPushPullReturnSliceSlice3StopSubSwap"
+const _Op_name = "NopAddAddrAssignFassignVassignCallCallXDerefDupFdupFnewFnewEEqualEqualSetExitFieldFieldEFieldSetFieldFsetGreaterGrowIndexIndexSetJumpJumpTrueJumpFalseJumpSetTrueJumpSetFalseLenLowerMapIndexMapSetMulNewNegateNextNext2NotPopPushPullPull2ReturnSliceSlice3StopSubSwap"
-var _Op_index = [...]uint8{0, 3, 6, 10, 16, 23, 30, 34, 39, 44, 47, 51, 55, 60, 65, 73, 77, 82, 88, 96, 105, 112, 116, 121, 129, 133, 141, 150, 161, 173, 176, 181, 189, 195, 198, 201, 207, 211, 214, 217, 221, 225, 231, 236, 242, 246, 249, 253}
+var _Op_index = [...]uint16{0, 3, 6, 10, 16, 23, 30, 34, 39, 44, 47, 51, 55, 60, 65, 73, 77, 82, 88, 96, 105, 112, 116, 121, 129, 133, 141, 150, 161, 173, 176, 181, 189, 195, 198, 201, 207, 211, 216, 219, 222, 226, 230, 235, 241, 246, 252, 256, 259, 263}
func (i Op) String() string {
idx := int(i) - 0
diff --git a/vm/vm.go b/vm/vm.go
index 7ab5a25..fac1a53 100644
--- a/vm/vm.go
+++ b/vm/vm.go
@@ -56,11 +56,13 @@ const (
Mul // n1 n2 -- prod ; prod = n1*n2
New // -- x; mem[fp+$1] = new mem[$2]
Negate // -- ; - mem[fp]
- Next // -- ; iterator next
+ Next // -- ; iterator next, set K
+ Next2 // -- ; iterator next, set K V
Not // c -- r ; r = !c
Pop // v --
Push // -- v
Pull // a -- a s n; pull iterator next and stop function
+ Pull2 // a -- a s n; pull iterator next and stop function
Return // [r1 .. ri] -- ; exit frame: sp = fp, fp = pop
Slice // a l h -- a; a = a [l:h]
Slice3 // a l h m -- a; a = a[l:h:m]
@@ -247,8 +249,16 @@ func (m *Machine) Run() (err error) {
case Negate:
mem[sp-1] = ValueOf(-mem[sp-1].Int())
case Next:
- if v, ok := mem[sp-2].Interface().(func() (reflect.Value, bool))(); ok {
- mem[c.Arg[1]].Set(v)
+ if k, ok := mem[sp-2].Interface().(func() (reflect.Value, bool))(); ok {
+ mem[c.Arg[1]].Set(k)
+ } else {
+ ip += c.Arg[0]
+ continue
+ }
+ case Next2:
+ if k, v, ok := mem[sp-2].Interface().(func() (reflect.Value, reflect.Value, bool))(); ok {
+ mem[c.Arg[1]].Set(k)
+ mem[c.Arg[2]].Set(v)
} else {
ip += c.Arg[0]
continue
@@ -263,6 +273,9 @@ func (m *Machine) Run() (err error) {
case Pull:
next, stop := iter.Pull(mem[sp-1].Seq())
mem = append(mem, ValueOf(next), ValueOf(stop))
+ case Pull2:
+ next, stop := iter.Pull2(mem[sp-1].Seq2())
+ mem = append(mem, ValueOf(next), ValueOf(stop))
case Grow:
mem = append(mem, make([]Value, c.Arg[0])...)
case Return: