1
0
mirror of https://github.com/MontFerret/ferret.git synced 2025-03-21 21:47:43 +02:00
ferret/pkg/compiler/compiler_for_while_test.go
Tim Voronov bd07b84736
Feature/#262 while loop (#567)
* Added new syntax and iterator

* Added FOR-WHILE loop

* Added 'FOR-DO-WHILE loop'
2020-11-10 19:16:22 -05:00

240 lines
5.1 KiB
Go

package compiler_test
import (
"context"
"github.com/MontFerret/ferret/pkg/compiler"
"github.com/MontFerret/ferret/pkg/runtime"
"github.com/MontFerret/ferret/pkg/runtime/core"
"github.com/MontFerret/ferret/pkg/runtime/values"
. "github.com/smartystreets/goconvey/convey"
"testing"
)
func TestForWhile(t *testing.T) {
Convey("FOR WHILE", t, func() {
Convey("WHILE", func() {
Convey("Should compile FOR i WHILE false RETURN i", func() {
c := compiler.New()
p, err := c.Compile(`
FOR i WHILE false
RETURN i
`)
So(err, ShouldBeNil)
So(p, ShouldHaveSameTypeAs, &runtime.Program{})
out, err := p.Run(context.Background())
So(err, ShouldBeNil)
So(string(out), ShouldEqual, "[]")
})
Convey("Should compile FOR i WHILE [] RETURN i", func() {
c := compiler.New()
p, err := c.Compile(`
FOR i WHILE []
RETURN i
`)
So(err, ShouldBeNil)
So(p, ShouldHaveSameTypeAs, &runtime.Program{})
out, err := p.Run(context.Background())
So(err, ShouldBeNil)
So(string(out), ShouldEqual, "[]")
})
Convey("Should compile FOR i WHILE F() < 10 RETURN i", func() {
c := compiler.New()
counter := -1
c.RegisterFunction("F", func(ctx context.Context, args ...core.Value) (core.Value, error) {
counter++
return values.NewInt(counter), nil
})
p, err := c.Compile(`
FOR i WHILE F() < 10
RETURN i
`)
So(err, ShouldBeNil)
So(p, ShouldHaveSameTypeAs, &runtime.Program{})
out, err := p.Run(context.Background())
So(err, ShouldBeNil)
So(string(out), ShouldEqual, "[0,1,2,3,4,5,6,7,8,9]")
})
Convey("Should compile FOR i WHILE F() RETURN i", func() {
c := compiler.New()
counter := -1
c.RegisterFunction("F", func(ctx context.Context, args ...core.Value) (core.Value, error) {
counter++
if counter == 10 {
return values.False, nil
}
return values.True, nil
})
p, err := c.Compile(`
FOR i WHILE F()
RETURN i
`)
So(err, ShouldBeNil)
So(p, ShouldHaveSameTypeAs, &runtime.Program{})
out, err := p.Run(context.Background())
So(err, ShouldBeNil)
So(string(out), ShouldEqual, "[0,1,2,3,4,5,6,7,8,9]")
})
Convey("Should compile nested FOR operators", func() {
c := compiler.New()
counter := -1
c.RegisterFunction("F", func(ctx context.Context, args ...core.Value) (core.Value, error) {
counter++
return values.NewInt(counter), nil
})
p, err := c.Compile(`
FOR i WHILE F() < 5
LET y = i + 1
FOR x IN 1..y
RETURN i * x
`)
So(err, ShouldBeNil)
out, err := p.Run(context.Background())
So(err, ShouldBeNil)
So(string(out), ShouldEqual, "[0,1,2,2,4,6,3,6,9,12,4,8,12,16,20]")
})
})
Convey("DO-WHILE", func() {
Convey("Should compile FOR i DO WHILE false RETURN i", func() {
c := compiler.New()
p, err := c.Compile(`
FOR i DO WHILE false
RETURN i
`)
So(err, ShouldBeNil)
So(p, ShouldHaveSameTypeAs, &runtime.Program{})
out, err := p.Run(context.Background())
So(err, ShouldBeNil)
So(string(out), ShouldEqual, "[0]")
})
Convey("Should compile FOR i DO WHILE [] RETURN i", func() {
c := compiler.New()
p, err := c.Compile(`
FOR i DO WHILE []
RETURN i
`)
So(err, ShouldBeNil)
So(p, ShouldHaveSameTypeAs, &runtime.Program{})
out, err := p.Run(context.Background())
So(err, ShouldBeNil)
So(string(out), ShouldEqual, "[0]")
})
Convey("Should compile FOR i DO WHILE F() < 10 RETURN i", func() {
c := compiler.New()
counter := -1
c.RegisterFunction("F", func(ctx context.Context, args ...core.Value) (core.Value, error) {
counter++
return values.NewInt(counter), nil
})
p, err := c.Compile(`
FOR i DO WHILE F() < 10
RETURN i
`)
So(err, ShouldBeNil)
So(p, ShouldHaveSameTypeAs, &runtime.Program{})
out, err := p.Run(context.Background())
So(err, ShouldBeNil)
So(string(out), ShouldEqual, "[0,1,2,3,4,5,6,7,8,9,10]")
})
Convey("Should compile FOR i WHILE F() RETURN i", func() {
c := compiler.New()
counter := -1
c.RegisterFunction("F", func(ctx context.Context, args ...core.Value) (core.Value, error) {
counter++
if counter == 10 {
return values.False, nil
}
return values.True, nil
})
p, err := c.Compile(`
FOR i WHILE F()
RETURN i
`)
So(err, ShouldBeNil)
So(p, ShouldHaveSameTypeAs, &runtime.Program{})
out, err := p.Run(context.Background())
So(err, ShouldBeNil)
So(string(out), ShouldEqual, "[0,1,2,3,4,5,6,7,8,9]")
})
Convey("Should compile nested FOR operators", func() {
c := compiler.New()
counter := -1
c.RegisterFunction("F", func(ctx context.Context, args ...core.Value) (core.Value, error) {
counter++
return values.NewInt(counter), nil
})
p, err := c.Compile(`
FOR i WHILE F() < 5
LET y = i + 1
FOR x IN 1..y
RETURN i * x
`)
So(err, ShouldBeNil)
out, err := p.Run(context.Background())
So(err, ShouldBeNil)
So(string(out), ShouldEqual, "[0,1,2,2,4,6,3,6,9,12,4,8,12,16,20]")
})
})
})
}