From daca05e637ab441d133592da165507eea119c3e3 Mon Sep 17 00:00:00 2001 From: Celestino Amoroso Date: Mon, 13 Jul 2026 14:27:18 +0200 Subject: [PATCH] linked-list: sum and in operators --- operator-in.go | 4 ++++ operator-sum.go | 2 +- t_list_test.go | 8 ++++++-- types/list/linked-list-type.go | 10 ++++++++++ types/list/linked-list.go | 21 ++++++++++++++++++--- 5 files changed, 39 insertions(+), 6 deletions(-) diff --git a/operator-in.go b/operator-in.go index beb6954..0ffc5dc 100644 --- a/operator-in.go +++ b/operator-in.go @@ -9,6 +9,7 @@ import ( "git.portale-stac.it/go-pkg/expr/scan" "git.portale-stac.it/go-pkg/expr/types/array" "git.portale-stac.it/go-pkg/expr/types/dict" + "git.portale-stac.it/go-pkg/expr/types/list" ) //-------- in term @@ -41,6 +42,9 @@ func evalIn(ctx kern.ExprContext, opTerm *scan.Term) (v any, err error) { } else if dict.IsDict(rightValue) { dict, _ := rightValue.(*dict.DictType) v = dict.HasKey(leftValue) + } else if list.IsLinkedList(rightValue) { + ls, _ := rightValue.(*list.LinkedList) + v = ls.HasValue(leftValue) } else { err = opTerm.ErrIncompatibleTypes(leftValue, rightValue) } diff --git a/operator-sum.go b/operator-sum.go index 218f238..904d727 100644 --- a/operator-sum.go +++ b/operator-sum.go @@ -55,7 +55,7 @@ func sumValues(plusTerm *scan.Term, leftValue, rightValue any) (v any, err error lsLeft := leftValue.(*list.LinkedList) lsRight := rightValue.(*list.LinkedList) ls := lsLeft.Clone() - ls.SeqPushBack(NewLinkedListIterator(lsRight, nil)) + ls.SeqClonePushBack(NewLinkedListIterator(lsRight, nil)) v = ls } else if (fract.IsFraction(leftValue) && types.IsNumber(rightValue)) || (fract.IsFraction(rightValue) && types.IsNumber(leftValue)) { if float.IsFloat(leftValue) || float.IsFloat(rightValue) { diff --git a/t_list_test.go b/t_list_test.go index 3a87455..24d040a 100644 --- a/t_list_test.go +++ b/t_list_test.go @@ -11,8 +11,8 @@ import ( "git.portale-stac.it/go-pkg/expr/types/list" ) -func TestListParser(t *testing.T) { - section := "List" +func TestArray(t *testing.T) { + section := "Array" inputs := []inputType{ /* 1 */ {`[]`, array.NewArrayA(), nil}, @@ -76,6 +76,10 @@ func TestLinkedListParser(t *testing.T) { /* 3 */ {`it=$([<1,2,3>]); #($$(it))`, int64(3), nil}, /* 4 */ {`[<1,2,3>][0]`, int64(1), nil}, /* 5 */ {`[<1,2,3>][0:2]`, list.NewLinkedListA(1, 2), nil}, + /* 6 */ {`[<1>] + [<2,3>]`, list.NewLinkedListA(1, 2, 3), nil}, + /* 7 */ {`L=[<1>] + [<2,3>]; L[0]=100; L`, list.NewLinkedListA(100, 2, 3), nil}, + /* 8 */ {`builtin "base"; L=[<1>]; isList(L)`, true, nil}, + /* 9 */ {`2 IN [<1,2,3>]`, true, nil}, } // t.Setenv("EXPR_PATH", ".") diff --git a/types/list/linked-list-type.go b/types/list/linked-list-type.go index 7a8d0ec..b0ad30d 100644 --- a/types/list/linked-list-type.go +++ b/types/list/linked-list-type.go @@ -127,3 +127,13 @@ func (ls1 *LinkedList) Clone() (ls2 *LinkedList) { } return } + +func (ls *LinkedList) HasValue(value any) (found bool) { + for node := ls.FirstNode(); node != nil; node = node.Next() { + if kern.Equal(node.Data(), value) { + found = true + break + } + } + return +} diff --git a/types/list/linked-list.go b/types/list/linked-list.go index d652187..6a93b38 100644 --- a/types/list/linked-list.go +++ b/types/list/linked-list.go @@ -85,7 +85,7 @@ func (ls *LinkedList) PushBack(data any) (node *ListNode) { func (ls *LinkedList) SeqPushBack(data any) (result *LinkedList) { switch seq := data.(type) { case kern.Iterator: - result = ls.IterPushBack(seq) + result = ls.IterPushBack(seq, false) default: ls.PushBack(data) result = ls @@ -93,9 +93,24 @@ func (ls *LinkedList) SeqPushBack(data any) (result *LinkedList) { return } -func (ls *LinkedList) IterPushBack(it kern.Iterator) *LinkedList { +func (ls *LinkedList) SeqClonePushBack(data any) (result *LinkedList) { + switch seq := data.(type) { + case kern.Iterator: + result = ls.IterPushBack(seq, true) + default: + ls.PushBack(data) + result = ls + } + return +} + +func (ls *LinkedList) IterPushBack(it kern.Iterator, clone bool) *LinkedList { for item, err1 := it.Next(); err1 == nil; item, err1 = it.Next() { - ls.PushBack(item) + if clone && kern.IsCloner(item) { + item = item.(kern.Cloner).Clone() + } else { + ls.PushBack(item) + } } return ls }