Skip to content

Commit

Permalink
Implemented Runtime.ForOf
Browse files Browse the repository at this point in the history
  • Loading branch information
dop251 committed Jun 26, 2023
1 parent 2b3c5c7 commit ba8a63e
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 0 deletions.
31 changes: 31 additions & 0 deletions runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -2771,6 +2771,37 @@ func (ir *iteratorRecord) close() {
ir.next = nil
}

// ForOf is a Go equivalent of for-of loop. The function panics if an exception is thrown at any point
// while iterating, including if the supplied value is not iterable
// (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#the_iterable_protocol).
// When using outside of Runtime.Run (i.e. when calling directly from Go code, not from a JS function implemented
// in Go) it must be enclosed in Try. See the example.
func (r *Runtime) ForOf(iterable Value, step func(curValue Value) (continueIteration bool)) {
iter := r.getIterator(iterable, nil)
for {
value, ex := iter.step()
if ex != nil {
panic(ex)
}
if value != nil {
var continueIteration bool
ex := r.vm.try(func() {
continueIteration = step(value)
})
if ex != nil {
iter.returnIter()
panic(ex)
}
if !continueIteration {
iter.returnIter()
break
}
} else {
break
}
}
}

func (r *Runtime) createIterResultObject(value Value, done bool) Value {
o := r.NewObject()
o.self.setOwnStr("value", value, false)
Expand Down
31 changes: 31 additions & 0 deletions runtime_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2844,6 +2844,37 @@ func TestAwaitInParameters(t *testing.T) {
}
}

func ExampleRuntime_ForOf() {
r := New()
v, err := r.RunString(`
new Map().set("a", 1).set("b", 2);
`)
if err != nil {
panic(err)
}

var sb strings.Builder
ex := r.Try(func() {
r.ForOf(v, func(v Value) bool {
o := v.ToObject(r)
key := o.Get("0")
value := o.Get("1")

sb.WriteString(key.String())
sb.WriteString("=")
sb.WriteString(value.String())
sb.WriteString(",")

return true
})
})
if ex != nil {
panic(ex)
}
fmt.Println(sb.String())
// Output: a=1,b=2,
}

/*
func TestArrayConcatSparse(t *testing.T) {
function foo(a,b,c)
Expand Down

0 comments on commit ba8a63e

Please sign in to comment.