new type LinkedList, preliminary implementation

This commit is contained in:
2026-05-17 22:43:27 +02:00
parent 9efdeffcac
commit 84b255a51b
12 changed files with 273 additions and 208 deletions
+19 -8
View File
@@ -6,6 +6,7 @@ package expr
import (
"errors"
"fmt"
"slices"
"git.portale-stac.it/go-pkg/expr/scan"
@@ -164,16 +165,16 @@ func paramAlreadyDefined(args []*scan.Term, param *scan.Term) (position int) {
return
}
func (parser *parser) parseList(scanner *scan.Scanner, ctx parserContext) (listTerm *scan.Term, err error) {
func (parser *parser) parseList(scanner *scan.Scanner, ctx parserContext, termSym scan.Symbol) (listTerm *scan.Term, err error) {
r, c := scanner.LastPos()
args := make([]*scan.Term, 0)
lastSym := scan.SymUnknown
itemExpected := false
itemCtx := remFlags(ctx, allowIndex)
for lastSym != scan.SymClosedSquare && lastSym != scan.SymEos {
for lastSym != termSym && lastSym != scan.SymEos {
zeroRequired := scanner.Current().Sym == scan.SymColon
var itemTree *scan.Ast
if itemTree, err = parser.parseItem(scanner, itemCtx, scan.SymComma, scan.SymClosedSquare); err == nil {
if itemTree, err = parser.parseItem(scanner, itemCtx, scan.SymComma, termSym); err == nil {
root := itemTree.Root()
if root != nil {
if hasFlag(ctx, allowIndex) && root.Symbol() == scan.SymColon {
@@ -212,10 +213,14 @@ func (parser *parser) parseList(scanner *scan.Scanner, ctx parserContext) (listT
}
}
if err == nil {
if lastSym != scan.SymClosedSquare {
if lastSym != termSym {
err = scanner.Previous().ErrorExpectedGot("]")
} else {
} else if termSym == scan.SymClosedSquare {
listTerm = newListTerm(r, c, args)
} else if termSym == scan.SymGreaterClosedSquare {
listTerm = newLinkedListTerm(r, c, args)
} else {
err = fmt.Errorf("[%d:%d] unknown list type", r, c)
}
}
return
@@ -327,7 +332,7 @@ func (parser *parser) parseSelectorCase(scanner *scan.Scanner, ctx parserContext
err = tk.Errorf("case list in default clause")
return
}
if filterList, err = parser.parseList(scanner, remFlags(ctx, allowIndex)); err != nil {
if filterList, err = parser.parseList(scanner, remFlags(ctx, allowIndex), scan.SymClosedSquare); err != nil {
return
}
tk = parser.Next(scanner)
@@ -446,7 +451,7 @@ func (parser *parser) parseGeneral(scanner *scan.Scanner, ctx parserContext, ter
tree = scan.NewAst()
firstToken := true
// lastSym := SymUnknown
for tk = parser.Next(scanner); err == nil && tk != nil && !tk.IsTerm(termSymbols); /*&& !areSymbolsOutOfCtx(tk, selectorTerm, SymColon, SymDoubleColon)*/ tk = parser.Next(scanner) {
for tk = parser.Next(scanner); err == nil && tk != nil && !tk.IsTerm(termSymbols); tk = parser.Next(scanner) {
// if tk.Sym == SymComment {
// continue
// }
@@ -491,7 +496,13 @@ func (parser *parser) parseGeneral(scanner *scan.Scanner, ctx parserContext, ter
case scan.SymOpenSquare:
var listTerm *scan.Term
newCtx := addFlagsCond(addFlags(ctx, squareContext), allowIndex, couldBeACollection(currentTerm))
if listTerm, err = parser.parseList(scanner, newCtx); err == nil {
if listTerm, err = parser.parseList(scanner, newCtx, scan.SymClosedSquare); err == nil {
currentTerm, err = listSubTree(tree, listTerm, hasFlag(newCtx, allowIndex))
}
case scan.SymOpenSquareLess:
var listTerm *scan.Term
newCtx := addFlagsCond(addFlags(ctx, listContext), allowIndex, false)
if listTerm, err = parser.parseList(scanner, newCtx, scan.SymGreaterClosedSquare); err == nil {
currentTerm, err = listSubTree(tree, listTerm, hasFlag(newCtx, allowIndex))
}
case scan.SymOpenBrace: