The plus and minus operators now support lists for join and difference respectively

This commit is contained in:
Celestino Amoroso 2024-03-30 07:05:22 +01:00
parent f540ec28e8
commit 85fb007a2b
2 changed files with 44 additions and 38 deletions

View File

@ -6,6 +6,7 @@ package expr
import (
"fmt"
"slices"
)
//-------- plus term
@ -39,6 +40,23 @@ func evalPlus(ctx exprContext, self *term) (v any, err error) {
rightInt, _ := rightValue.(int64)
v = leftInt + rightInt
}
} else if isList(leftValue) || isList(rightValue) {
var leftList, rightList []any
var ok bool
if leftList, ok = leftValue.([]any); !ok {
leftList = []any{leftValue}
}
if rightList, ok = rightValue.([]any); !ok {
rightList = []any{rightValue}
}
sumList := make([]any, 0, len(leftList)+len(rightList))
for _, item := range leftList {
sumList = append(sumList, item)
}
for _, item := range rightList {
sumList = append(sumList, item)
}
v = sumList
} else {
err = self.errIncompatibleTypes(leftValue, rightValue)
}
@ -74,6 +92,16 @@ func evalMinus(ctx exprContext, self *term) (v any, err error) {
rightInt, _ := rightValue.(int64)
v = leftInt - rightInt
}
} else if isList(leftValue) && isList(rightValue) {
leftList, _ := leftValue.([]any)
rightList, _ := rightValue.([]any)
diffList := make([]any, 0, len(leftList)-len(rightList))
for _, item := range leftList {
if slices.Index(rightList, item) < 0 {
diffList = append(diffList, item)
}
}
v = diffList
} else {
err = self.errIncompatibleTypes(leftValue, rightValue)
}

View File

@ -11,38 +11,6 @@ import (
"testing"
)
func addFunc(ctx exprContext, name string, args []any) (result any, err error) {
var sumAsFloat = false
var floatSum float64 = 0.0
var intSum int64 = 0
for i, v := range args {
if !isNumber(v) {
err = fmt.Errorf("add(): param nr %d has wrong type %T, number expected", i+1, v)
break
}
if !sumAsFloat && isFloat(v) {
sumAsFloat = true
floatSum = float64(intSum)
}
if sumAsFloat {
floatSum += numAsFloat(v)
} else {
iv, _ := v.(int64)
intSum += iv
}
}
if err == nil {
if sumAsFloat {
result = floatSum
} else {
result = intSum
}
}
return
}
func TestParser(t *testing.T) {
type inputType struct {
source string
@ -54,7 +22,8 @@ func TestParser(t *testing.T) {
ctx := NewSimpleFuncStore()
ctx.SetValue("var1", int64(123))
ctx.SetValue("var2", "abc")
ctx.addFunc("add", addFunc)
// ctx.addFunc("add", addFunc)
importMathFuncs(ctx)
// inputs1 := []inputType{
// {`add(1,2,3)`, int64(6), nil},
@ -94,10 +63,10 @@ func TestParser(t *testing.T) {
/* 31 */ {"(1+1)*5", int64(10), nil},
/* 32 */ {"200 / (1+1) - 1", int64(99), nil},
/* 33 */ {`add(1,2,3)`, int64(6), nil},
/* 34 */ {`mul(1,2,3)`, nil, errors.New(`unknown function "mul"`)},
/* 34 */ {`mulX(1,2,3)`, nil, errors.New(`unknown function mulX()`)},
/* 35 */ {`add(1+4,3+2,5*(3-2))`, int64(15), nil},
/* 36 */ {`add(add(1+4),3+2,5*(3-2))`, int64(15), nil},
/* 37 */ {`add(add(1+4),/*3+2,*/5*(3-2))`, int64(10), nil},
/* 37 */ {`add(add(1,4),/*3+2,*/5*(3-2))`, int64(10), nil},
/* 38 */ {`1+(1+(1+(1)+1)+1)+1`, int64(7), nil},
/* 39 */ {`(((1)))`, int64(1), nil},
/* 40 */ {`"uno_" + var2`, `uno_abc`, nil},
@ -209,7 +178,8 @@ func TestListParser(t *testing.T) {
ctx := NewSimpleFuncStore()
ctx.SetValue("var1", int64(123))
ctx.SetValue("var2", "abc")
ctx.addFunc("add", addFunc)
// ctx.addFunc("add", addFunc)
importMathFuncs(ctx)
// inputs1 := []inputType{
// {`add(1,2,3)`, int64(6), nil},
@ -220,6 +190,14 @@ func TestListParser(t *testing.T) {
/* 2 */ {`[1,2,3]`, []any{int64(1), int64(2), int64(3)}, nil},
/* 3 */ {`[1,2,"hello"]`, []any{int64(1), int64(2), "hello"}, nil},
/* 4 */ {`[1+2, not true, "hello"]`, []any{int64(3), false, "hello"}, nil},
/* 5 */ {`[1,2]+[3]`, []any{int64(1), int64(2), int64(3)}, nil},
/* 6 */ {`[1,4,3,2]-[3]`, []any{int64(1), int64(4), int64(2)}, nil},
/* 7 */ {`add([1,4,3,2])`, int64(10), nil},
/* 8 */ {`add([1,[2,2],3,2])`, int64(10), nil},
/* 9 */ {`mul([1,4,3.0,2])`, float64(24.0), nil},
/* 10 */ {`add([1,"hello"])`, nil, errors.New(`add(): param nr 2 has wrong type string, number expected`)},
// /* 8 */ {`[int(x)|x=csv("test.csv",1,all(),1)]`, []any{int64(10), int64(40), int64(20)}, nil},
// /* 9 */ {`sum(@[int(x)|x=csv("test.csv",1,all(),1)])`, []any{int64(10), int64(40), int64(20)}, nil},
}
succeeded := 0
@ -232,9 +210,9 @@ func TestListParser(t *testing.T) {
var gotErr error
if input.wantErr == nil {
t.Log(fmt.Sprintf("[+]Test nr %2d -- %q", i+1, input.source))
t.Log(fmt.Sprintf("[+]Test nr %2d -- %q --> %v", i+1, input.source, input.wantResult))
} else {
t.Log(fmt.Sprintf("[-]Test nr %2d -- %q", i+1, input.source))
t.Log(fmt.Sprintf("[-]Test nr %2d -- %q --> %v", i+1, input.source, input.wantResult))
}
r := strings.NewReader(input.source)