Skip to content

Commit

Permalink
Fixed regexp operand
Browse files Browse the repository at this point in the history
  • Loading branch information
ziflex committed Apr 1, 2024
1 parent 3a0d82b commit d8eda55
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 7 deletions.
91 changes: 91 additions & 0 deletions pkg/compiler/compiler_filter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,96 @@ func TestForFilter(t *testing.T) {
[]any{map[string]any{"age": 29, "gender": "f", "name": "Mary"}, map[string]any{"age": 36, "gender": "m", "name": "Peter"}},
ShouldEqualJSON,
},
{
`
LET users = [
{
active: true,
age: 31,
gender: "m"
},
{
active: true,
age: 29,
gender: "f"
},
{
active: true,
age: 36,
gender: "m"
}
]
FOR u IN users
FILTER u.active == true
FILTER u.age < 35
RETURN u
`,
[]any{map[string]any{"active": true, "gender": "m", "age": 31}, map[string]any{"active": true, "gender": "f", "age": 29}},
ShouldEqualJSON,
},
{
`
LET users = [
{
active: true,
age: 31,
gender: "m"
},
{
active: true,
age: 29,
gender: "f"
},
{
active: true,
age: 36,
gender: "m"
},
{
active: false,
age: 69,
gender: "m"
}
]
FOR u IN users
FILTER u.active
RETURN u
`,
[]any{map[string]any{"active": true, "gender": "m", "age": 31}, map[string]any{"active": true, "gender": "f", "age": 29}, map[string]any{"active": true, "gender": "m", "age": 36}},
ShouldEqualJSON,
},
{
`
LET users = [
{
active: true,
age: 31,
gender: "m"
},
{
active: true,
age: 29,
gender: "f"
},
{
active: true,
age: 36,
gender: "m"
},
{
active: false,
age: 69,
gender: "m"
}
]
FOR u IN users
FILTER u.active == true
LIMIT 2
FILTER u.gender == "m"
RETURN u
`,
[]any{map[string]any{"active": true, "gender": "m", "age": 31}},
ShouldEqualJSON,
},
})
}
12 changes: 12 additions & 0 deletions pkg/runtime/values/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"encoding/binary"
"encoding/json"
"github.com/MontFerret/ferret/pkg/runtime/values/types"
"hash/fnv"
"reflect"
"sort"
Expand Down Expand Up @@ -412,6 +413,17 @@ func ToBinary(input core.Value) Binary {
return NewBinary([]byte(input.String()))
}

func ToRegexp(input core.Value) (*Regexp, error) {
switch r := input.(type) {
case *Regexp:
return r, nil
case String:
return NewRegexp(r)
default:
return nil, core.TypeError(input, types.String, types.Regexp)
}
}

func Hash(typename string, content []byte) uint64 {
h := fnv.New64a()

Expand Down
6 changes: 3 additions & 3 deletions pkg/runtime/values/regexp.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import (

type Regexp regexp.Regexp

func NewRegexp(pattern string) (*Regexp, error) {
r, err := regexp.Compile(pattern)
func NewRegexp(pattern String) (*Regexp, error) {
r, err := regexp.Compile(string(pattern))

if err != nil {
return nil, err
Expand Down Expand Up @@ -60,7 +60,7 @@ func (r *Regexp) Hash() uint64 {
}

func (r *Regexp) Copy() core.Value {
copied, err := NewRegexp(r.String())
copied, err := NewRegexp(String(r.String()))

// it should never happen
if err != nil {
Expand Down
22 changes: 18 additions & 4 deletions pkg/runtime/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -270,12 +270,26 @@ loop:
stack.Push(operators.Decrement(stack.Pop()))

case OpRegexpPositive:
reg := program.Constants[arg].(*values.Regexp)
stack.Push(reg.Match(stack.Pop()))
reg, err := values.ToRegexp(stack.Pop())

if err == nil {
stack.Push(reg.Match(stack.Pop()))
} else if tryCatch(vm.ip) {
stack.Push(values.False)
} else {
return nil, err
}

case OpRegexpNegative:
reg := program.Constants[arg].(*values.Regexp)
stack.Push(!reg.Match(stack.Pop()))
reg, err := values.ToRegexp(stack.Pop())

if err == nil {
stack.Push(!reg.Match(stack.Pop()))
} else if tryCatch(vm.ip) {
stack.Push(values.True)
} else {
return nil, err
}

case OpCall, OpCallSafe:
fnName := stack.Pop().String()
Expand Down

0 comments on commit d8eda55

Please sign in to comment.