linked-list: added forgotten source files
This commit is contained in:
@@ -0,0 +1,130 @@
|
||||
// Copyright (c) 2024-2026 Celestino Amoroso (celestino.amoroso@gmail.com).
|
||||
// All rights reserved.
|
||||
|
||||
// linked-list-type.go
|
||||
package kern
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
const LinkedListTypeName = "lisked-list"
|
||||
const MaxUint64Allowed = uint64(9_223_372_036_854_775_807)
|
||||
|
||||
func IsLinkedList(v any) (ok bool) {
|
||||
_, ok = v.(*LinkedList)
|
||||
return ok
|
||||
}
|
||||
|
||||
func NewLinkedListA(listAny ...any) (list *LinkedList) {
|
||||
if listAny == nil {
|
||||
listAny = []any{}
|
||||
}
|
||||
list = NewLinkedList()
|
||||
for _, item := range listAny {
|
||||
list.PushBack(FixAnyNumber(item))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func LinkedListFromStrings(stringList []string) (list *LinkedList) {
|
||||
list = NewLinkedList()
|
||||
for _, s := range stringList {
|
||||
list.PushBack(s)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (ls *LinkedList) ToString(opt FmtOpt) (s string) {
|
||||
indent := GetFormatIndent(opt)
|
||||
flags := GetFormatFlags(opt)
|
||||
|
||||
var sb strings.Builder
|
||||
sb.WriteString("[<")
|
||||
if ls.Len() > 0 {
|
||||
innerOpt := MakeFormatOptions(flags, indent+1)
|
||||
nest := strings.Repeat(" ", indent+1)
|
||||
|
||||
if flags&MultiLine != 0 {
|
||||
sb.WriteByte('\n')
|
||||
sb.WriteString(nest)
|
||||
}
|
||||
|
||||
i := 0
|
||||
for item := ls.FirstNode(); item != nil; item = item.Next() {
|
||||
if i > 0 {
|
||||
if flags&MultiLine != 0 {
|
||||
sb.WriteString(",\n")
|
||||
sb.WriteString(nest)
|
||||
} else {
|
||||
sb.WriteString(", ")
|
||||
}
|
||||
}
|
||||
// data := item.Data()
|
||||
// if s, ok := data.(string); ok {
|
||||
// sb.WriteByte('"')
|
||||
// sb.WriteString(s)
|
||||
// sb.WriteByte('"')
|
||||
// } else if formatter, ok := data.(Formatter); ok {
|
||||
// sb.WriteString(formatter.ToString(innerOpt))
|
||||
// } else {
|
||||
// fmt.Fprintf(&sb, "%v", data)
|
||||
// }
|
||||
Format(&sb, item.Data(), innerOpt)
|
||||
i++
|
||||
}
|
||||
if flags&MultiLine != 0 {
|
||||
sb.WriteByte('\n')
|
||||
sb.WriteString(strings.Repeat(" ", indent))
|
||||
}
|
||||
}
|
||||
sb.WriteString(">]")
|
||||
s = sb.String()
|
||||
if flags&Truncate != 0 && len(s) > TruncateSize {
|
||||
s = TruncateString(s)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (ls *LinkedList) String() string {
|
||||
return ls.ToString(0)
|
||||
}
|
||||
|
||||
func (ls *LinkedList) TypeName() string {
|
||||
return LinkedListTypeName
|
||||
}
|
||||
|
||||
// func (ls *LinkedList) Contains(t *ListType) (answer bool) {
|
||||
// if len(*ls) >= len(*t) {
|
||||
// answer = true
|
||||
// for _, item := range *t {
|
||||
// if answer = ls.IndexDeepSameCmp(item) >= 0; !answer {
|
||||
// break
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return
|
||||
// }
|
||||
|
||||
func (ls1 *LinkedList) Equals(ls2 *LinkedList) (answer bool) {
|
||||
if ls2 != nil && ls1.Len() == ls2.Len() {
|
||||
answer = true
|
||||
i2 := ls2.FirstNode()
|
||||
for i1 := ls1.FirstNode(); i1 != nil; i1 = i1.Next() {
|
||||
if !Equal(i1.Data(), i2.Data()) {
|
||||
answer = false
|
||||
break
|
||||
}
|
||||
i2 = i2.Next()
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (ls1 *LinkedList) Clone() (ls2 *LinkedList) {
|
||||
ls2 = NewLinkedListA()
|
||||
for i1 := ls1.FirstNode(); i1 != nil; i1 = i1.Next() {
|
||||
ls2.PushBack(Clone(i1.Data()))
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
// Copyright (c) 2024-2026 Celestino Amoroso (celestino.amoroso@gmail.com).
|
||||
// All rights reserved.
|
||||
|
||||
// list-iterator.go
|
||||
package expr
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"slices"
|
||||
|
||||
"git.portale-stac.it/go-pkg/expr/kern"
|
||||
)
|
||||
|
||||
type LinkedListIterator struct {
|
||||
a *kern.ListType
|
||||
count int64
|
||||
index int64
|
||||
start int64
|
||||
stop int64
|
||||
step int64
|
||||
}
|
||||
|
||||
func NewLinkedListIterator(list *kern.ListType, args []any) (it *LinkedListIterator) {
|
||||
var argc int = 0
|
||||
listLen := int64(len(([]any)(*list)))
|
||||
if args != nil {
|
||||
argc = len(args)
|
||||
}
|
||||
it = &LinkedListIterator{a: list, count: 0, index: -1, start: 0, stop: listLen - 1, step: 1}
|
||||
if argc >= 1 {
|
||||
if i, err := kern.ToGoInt64(args[0], "start index"); err == nil {
|
||||
if i < 0 {
|
||||
i = listLen + i
|
||||
}
|
||||
it.start = i
|
||||
}
|
||||
if argc >= 2 {
|
||||
if i, err := kern.ToGoInt64(args[1], "stop index"); err == nil {
|
||||
if i < 0 {
|
||||
i = listLen + i
|
||||
}
|
||||
it.stop = i
|
||||
}
|
||||
if argc >= 3 {
|
||||
if i, err := kern.ToGoInt64(args[2], "step"); err == nil {
|
||||
if i < 0 {
|
||||
i = -i
|
||||
}
|
||||
if it.start > it.stop {
|
||||
it.step = -i
|
||||
} else {
|
||||
it.step = i
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
it.index = it.start - it.step
|
||||
return
|
||||
}
|
||||
|
||||
func (it *LinkedListIterator) String() string {
|
||||
var l = int64(0)
|
||||
if it.a != nil {
|
||||
l = int64(len(*it.a))
|
||||
}
|
||||
return fmt.Sprintf("$([#%d])", l)
|
||||
}
|
||||
|
||||
func (it *LinkedListIterator) TypeName() string {
|
||||
return "LinkedListIterator"
|
||||
}
|
||||
|
||||
func (it *LinkedListIterator) HasOperation(name string) bool {
|
||||
//yes := name == expr.NextName || name == expr.ResetName || name == expr.IndexName || name == expr.CountName || name == expr.CurrentName
|
||||
yes := slices.Contains([]string{kern.NextName, kern.ResetName, kern.IndexName, kern.CountName, kern.CurrentName}, name)
|
||||
return yes
|
||||
}
|
||||
|
||||
func (it *LinkedListIterator) CallOperation(name string, args map[string]any) (v any, err error) {
|
||||
switch name {
|
||||
case kern.NextName:
|
||||
v, err = it.Next()
|
||||
case kern.ResetName:
|
||||
err = it.Reset()
|
||||
case kern.CleanName:
|
||||
err = it.Clean()
|
||||
case kern.IndexName:
|
||||
v = int64(it.Index())
|
||||
case kern.CurrentName:
|
||||
v, err = it.Current()
|
||||
case kern.CountName:
|
||||
v = it.count
|
||||
default:
|
||||
err = kern.ErrNoOperation(name)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (it *LinkedListIterator) Current() (item any, err error) {
|
||||
a := *(it.a)
|
||||
if it.start <= it.stop {
|
||||
if it.stop < int64(len(a)) && it.index >= it.start && it.index <= it.stop {
|
||||
item = a[it.index]
|
||||
} else {
|
||||
err = io.EOF
|
||||
}
|
||||
} else {
|
||||
if it.start < int64(len(a)) && it.index >= it.stop && it.index <= it.start {
|
||||
item = a[it.index]
|
||||
} else {
|
||||
err = io.EOF
|
||||
}
|
||||
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (it *LinkedListIterator) Next() (item any, err error) {
|
||||
it.index += it.step
|
||||
if item, err = it.Current(); err != io.EOF {
|
||||
it.count++
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (it *LinkedListIterator) Index() int64 {
|
||||
return it.index
|
||||
}
|
||||
|
||||
func (it *LinkedListIterator) Count() int64 {
|
||||
return it.count
|
||||
}
|
||||
|
||||
func (it *LinkedListIterator) Reset() error {
|
||||
it.index = it.start - it.step
|
||||
it.count = 0
|
||||
return nil
|
||||
}
|
||||
|
||||
func (it *LinkedListIterator) Clean() error {
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
// Copyright (c) 2024-2026 Celestino Amoroso (celestino.amoroso@gmail.com).
|
||||
// All rights reserved.
|
||||
|
||||
// operand-list.go
|
||||
package expr
|
||||
|
||||
import (
|
||||
"git.portale-stac.it/go-pkg/expr/kern"
|
||||
"git.portale-stac.it/go-pkg/expr/scan"
|
||||
)
|
||||
|
||||
// -------- list term
|
||||
// func newLinkedListTermA(args ...*scan.Term) *scan.Term {
|
||||
// return newLinkedListTerm(0, 0, args)
|
||||
// }
|
||||
|
||||
func newLinkedListTerm(row, col int, args []*scan.Term) *scan.Term {
|
||||
return &scan.Term{
|
||||
Tk: *scan.NewValueToken(row, col, scan.SymLinkedList, "[<>]", args),
|
||||
Parent: nil,
|
||||
Children: nil,
|
||||
Position: scan.PosLeaf,
|
||||
Priority: scan.PriValue,
|
||||
EvalFunc: evalLinkedList,
|
||||
}
|
||||
}
|
||||
|
||||
// -------- list func
|
||||
func evalLinkedList(ctx kern.ExprContext, opTerm *scan.Term) (v any, err error) {
|
||||
list, _ := opTerm.Value().([]*scan.Term)
|
||||
items := kern.NewLinkedList()
|
||||
for _, tree := range list {
|
||||
var param any
|
||||
if param, err = tree.Compute(ctx); err != nil {
|
||||
break
|
||||
}
|
||||
items.PushBack(param)
|
||||
}
|
||||
if err == nil {
|
||||
v = items
|
||||
}
|
||||
return
|
||||
}
|
||||
Reference in New Issue
Block a user