diff --git a/iter-factory.go b/iter-factory.go index f3e1dc2..0b47d18 100644 --- a/iter-factory.go +++ b/iter-factory.go @@ -11,6 +11,15 @@ import ( "git.portale-stac.it/go-pkg/expr/scan" ) +func NewFormalIterator(value any) (it kern.Iterator) { + if value == nil { + it = NewArrayIterator([]any{}) + } else { + it = NewArrayIterator([]any{value}) + } + return +} + func NewIterator(ctx kern.ExprContext, value any, ops []*scan.Term) (it kern.Iterator, err error) { if value == nil { return NewArrayIterator([]any{}), nil diff --git a/operator-insert.go b/operator-insert.go index 15039d7..70459e8 100644 --- a/operator-insert.go +++ b/operator-insert.go @@ -31,13 +31,11 @@ func newAppendTerm(tk *scan.Token) (inst *scan.Term) { } } -func prependToList(ctx kern.ExprContext, opTerm *scan.Term, leftValue, rightValue any) (result any, err error) { +func prependToList(opTerm *scan.Term, leftValue, rightValue any) (result any, err error) { if list, ok := rightValue.(*kern.ListType); ok { var it kern.Iterator if it, ok = leftValue.(kern.Iterator); !ok { - if it, err = NewIterator(ctx, leftValue, nil); err != nil { - return - } + it = NewFormalIterator(leftValue) } ls := kern.NewLinkedList() @@ -54,12 +52,13 @@ func prependToList(ctx kern.ExprContext, opTerm *scan.Term, leftValue, rightValu newList = append(newList, item) } result = &newList + } else if list, ok := rightValue.(*kern.LinkedList); ok { + var it kern.Iterator + if it, ok = leftValue.(kern.Iterator); !ok { + it = NewFormalIterator(leftValue) + } - // ***** EVENTUALMENTE ABILITARE LA MODIFICA DELLA VARIABILE - // ***** CON UN OPERATORE SPECIFICO - // if opTerm.Children[1].Symbol() == scan.SymVariable { - // ctx.UnsafeSetVar(opTerm.Children[1].Source(), result) - // } + result = list.SeqPushBack(it) } else { err = opTerm.ErrIncompatibleTypes(leftValue, rightValue) } @@ -73,17 +72,15 @@ func evalPrepend(ctx kern.ExprContext, opTerm *scan.Term) (v any, err error) { return } - v, err = prependToList(ctx, opTerm, leftValue, rightValue) + v, err = prependToList(opTerm, leftValue, rightValue) return } -func appendToList(ctx kern.ExprContext, opTerm *scan.Term, leftValue, rightValue any) (result any, err error) { +func appendToList(opTerm *scan.Term, leftValue, rightValue any) (result any, err error) { if list, ok := leftValue.(*kern.ListType); ok { var it kern.Iterator if it, ok = rightValue.(kern.Iterator); !ok { - if it, err = NewIterator(ctx, rightValue, nil); err != nil { - return - } + it = NewFormalIterator(rightValue) } ls := kern.NewLinkedList() @@ -100,12 +97,13 @@ func appendToList(ctx kern.ExprContext, opTerm *scan.Term, leftValue, rightValue newList = append(newList, node.Data()) } result = &newList + } else if list, ok := leftValue.(*kern.LinkedList); ok { + var it kern.Iterator + if it, ok = rightValue.(kern.Iterator); !ok { + it = NewFormalIterator(rightValue) + } - // ***** EVENTUALMENTE ABILITARE LA MODIFICA DELLA VARIABILE - // ***** CON UN OPERATORE SPECIFICO - // if opTerm.Children[0].Symbol() == scan.SymVariable { - // ctx.UnsafeSetVar(opTerm.Children[0].Source(), result) - // } + result = list.SeqPushBack(it) } else { err = opTerm.ErrIncompatibleTypes(leftValue, rightValue) } @@ -119,7 +117,7 @@ func evalAppend(ctx kern.ExprContext, opTerm *scan.Term) (v any, err error) { return } - v, err = appendToList(ctx, opTerm, leftValue, rightValue) + v, err = appendToList(opTerm, leftValue, rightValue) return } diff --git a/operator-shift.go b/operator-shift.go index d8ad99e..3c9f247 100644 --- a/operator-shift.go +++ b/operator-shift.go @@ -40,7 +40,7 @@ func evalRightShift(ctx kern.ExprContext, opTerm *scan.Term) (v any, err error) } if v, err = bitRightShift(opTerm, leftValue, rightValue); err != nil { - v, err = prependToList(ctx, opTerm, leftValue, rightValue) + v, err = prependToList(opTerm, leftValue, rightValue) } return } @@ -74,7 +74,7 @@ func evalLeftShift(ctx kern.ExprContext, opTerm *scan.Term) (v any, err error) { } if v, err = bitLeftShift(opTerm, leftValue, rightValue); err != nil { - v, err = appendToList(ctx, opTerm, leftValue, rightValue) + v, err = appendToList(opTerm, leftValue, rightValue) } return } diff --git a/t_operator_test.go b/t_operator_test.go index 4ad67e5..1c62bbb 100644 --- a/t_operator_test.go +++ b/t_operator_test.go @@ -53,15 +53,25 @@ func TestOperatorInsert(t *testing.T) { section := "Operator-Insert" inputs := []inputType{ /* 1 */ {`["a", "b"] << nil`, kern.NewListA("a", "b"), nil}, - /* 2 */ {`["a", "b"] << []`, kern.NewListA("a", "b"), nil}, - /* 3 */ {`["a", "b"] << 3`, kern.NewListA("a", "b", int64(3)), nil}, - /* 4 */ {`3 << ["a", "b"]`, nil, `[1:5] left operand '3' [integer] and right operand '["a", "b"]' [list] are not compatible with operator "<<"`}, - /* 5 */ {`nil >> ["a", "b"]`, kern.NewListA("a", "b"), nil}, - /* 6 */ {`[] >> ["a", "b"]`, kern.NewListA("a", "b"), nil}, - /* 7 */ {`["a", "b"] << $([1,2,3])`, kern.NewListA("a", "b", int64(1), int64(2), int64(3)), nil}, - /* 8 */ {`L=["a", "b"]; L << $([1,2,3])`, kern.NewListA("a", "b", int64(1), int64(2), int64(3)), nil}, - /* 9 */ {`L=["a", "b"]; L << $([1,2,3]); L`, kern.NewListA("a", "b"), nil}, - /* 10 */ {`L << $([1,2,3])`, nil, `undefined variable or function "L"`}, + /* 2 */ {`["a", "b"] << []`, kern.NewListA("a", "b", kern.NewListA()), nil}, + /* 3 */ {`["a", "b"] << $([])`, kern.NewListA("a", "b"), nil}, + /* 4 */ {`["a", "b"] << 3`, kern.NewListA("a", "b", int64(3)), nil}, + /* 5 */ {`3 << ["a", "b"]`, nil, `[1:5] left operand '3' [integer] and right operand '["a", "b"]' [list] are not compatible with operator "<<"`}, + /* 6 */ {`nil >> ["a", "b"]`, kern.NewListA("a", "b"), nil}, + /* 7 */ {`[] >> ["a", "b"]`, kern.NewListA(kern.NewListA(), "a", "b"), nil}, + /* 8 */ {`$([]) >> ["a", "b"]`, kern.NewListA("a", "b"), nil}, + /* 9 */ {`["a", "b"] << $([1,2,3])`, kern.NewListA("a", "b", int64(1), int64(2), int64(3)), nil}, + /* 10 */ {`L=["a", "b"]; L << $([1,2,3])`, kern.NewListA("a", "b", int64(1), int64(2), int64(3)), nil}, + /* 11 */ {`L=["a", "b"]; L << $([1,2,3]); L`, kern.NewListA("a", "b"), nil}, + /* 12 */ {`L << $([1,2,3])`, nil, `undefined variable or function "L"`}, + /* 13 */ {`[<>] << 1`, kern.NewLinkedListA(1), nil}, + /* 14 */ {`[<>] << [1,2]`, kern.NewLinkedListA(kern.NewListA(int64(1), int64(2))), nil}, + /* 15 */ {`[<>] << [<1,2>]`, kern.NewLinkedListA(kern.NewLinkedListA(1, 2)), nil}, + /* 16 */ {`1 >> [<>]`, kern.NewLinkedListA(1), nil}, + /* 17 */ {`[1,2] >> [<>]`, kern.NewLinkedListA(kern.NewListA(int64(1), int64(2))), nil}, + /* 18 */ {`[<1,2>] >> [<>]`, kern.NewLinkedListA(kern.NewLinkedListA(1, 2)), nil}, + /* 19 */ {`$([1,2]) >> [<>]`, kern.NewLinkedListA(1, 2), nil}, + /* 20 */ {`$([<1,2>]) >> [<>]`, kern.NewLinkedListA(1, 2), nil}, } // runTestSuiteSpec(t, section, inputs, 9)