new type LinkedList, preliminary implementation
This commit is contained in:
@@ -275,6 +275,16 @@ func charFunc(ctx kern.ExprContext, name string, args map[string]any) (result an
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func seqFunc(ctx kern.ExprContext, name string, args map[string]any) (result any, err error) {
|
||||||
|
list := kern.NewLinkedList()
|
||||||
|
items := args[kern.ParamValue].([]any)
|
||||||
|
for _, arg := range items {
|
||||||
|
list.PushBack(arg)
|
||||||
|
}
|
||||||
|
result = list
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
//// import
|
//// import
|
||||||
|
|
||||||
func ImportBuiltinsFuncs(ctx kern.ExprContext) {
|
func ImportBuiltinsFuncs(ctx kern.ExprContext) {
|
||||||
@@ -318,6 +328,10 @@ func ImportBuiltinsFuncs(ctx kern.ExprContext) {
|
|||||||
ctx.RegisterFunc("char", kern.NewGolangFunctor(charFunc), kern.TypeString, []kern.ExprFuncParam{
|
ctx.RegisterFunc("char", kern.NewGolangFunctor(charFunc), kern.TypeString, []kern.ExprFuncParam{
|
||||||
kern.NewFuncParam(kern.ParamValue),
|
kern.NewFuncParam(kern.ParamValue),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
ctx.RegisterFunc("seq", kern.NewGolangFunctor(seqFunc), kern.TypeLinkedList, []kern.ExprFuncParam{
|
||||||
|
kern.NewFuncParamFlag(kern.ParamValue, kern.PfRepeat),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ func Clone(v any) (c any) {
|
|||||||
c = unboxed.Clone()
|
c = unboxed.Clone()
|
||||||
case *DictType:
|
case *DictType:
|
||||||
c = unboxed.Clone()
|
c = unboxed.Clone()
|
||||||
|
case *LinkedList:
|
||||||
|
c = unboxed.Clone()
|
||||||
default:
|
default:
|
||||||
c = v
|
c = v
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,4 +20,5 @@ const (
|
|||||||
TypeDict = "dict"
|
TypeDict = "dict"
|
||||||
TypeListOf = "list-of-"
|
TypeListOf = "list-of-"
|
||||||
TypeListOfStrings = "list-of-strings"
|
TypeListOfStrings = "list-of-strings"
|
||||||
|
TypeLinkedList = "linked-list"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -20,6 +20,10 @@ func Equal(value1, value2 any) (equal bool) {
|
|||||||
d1 := value1.(*DictType)
|
d1 := value1.(*DictType)
|
||||||
d2 := value2.(*DictType)
|
d2 := value2.(*DictType)
|
||||||
equal = d1.Equals(*d2)
|
equal = d1.Equals(*d2)
|
||||||
|
} else if IsLinkedList(value1) && IsLinkedList(value2) {
|
||||||
|
ll1 := value1.(*LinkedList)
|
||||||
|
ll2 := value2.(*LinkedList)
|
||||||
|
equal = ll1.Equals(ll2)
|
||||||
} else if IsInteger(value1) && IsInteger(value2) {
|
} else if IsInteger(value1) && IsInteger(value2) {
|
||||||
equal = value1.(int64) == value2.(int64)
|
equal = value1.(int64) == value2.(int64)
|
||||||
} else if IsString(value1) && IsString(value2) {
|
} else if IsString(value1) && IsString(value2) {
|
||||||
|
|||||||
+16
-1
@@ -4,7 +4,10 @@
|
|||||||
// formatter.go
|
// formatter.go
|
||||||
package kern
|
package kern
|
||||||
|
|
||||||
import "fmt"
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
type FmtOpt uint32 // lower 16 bits hold a bit-mask, higher 16 bits hold an indentation number
|
type FmtOpt uint32 // lower 16 bits hold a bit-mask, higher 16 bits hold an indentation number
|
||||||
|
|
||||||
@@ -46,6 +49,18 @@ type Formatter interface {
|
|||||||
ToString(options FmtOpt) string
|
ToString(options FmtOpt) string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Format(sb *strings.Builder, item any, opt FmtOpt) {
|
||||||
|
if s, ok := item.(string); ok {
|
||||||
|
sb.WriteByte('"')
|
||||||
|
sb.WriteString(s)
|
||||||
|
sb.WriteByte('"')
|
||||||
|
} else if formatter, ok := item.(Formatter); ok {
|
||||||
|
sb.WriteString(formatter.ToString(opt))
|
||||||
|
} else {
|
||||||
|
fmt.Fprintf(sb, "%v", item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func GetFormatted(v any, opt FmtOpt) (text string) {
|
func GetFormatted(v any, opt FmtOpt) (text string) {
|
||||||
if v == nil {
|
if v == nil {
|
||||||
text = "(nil)"
|
text = "(nil)"
|
||||||
|
|||||||
+15
-23
@@ -73,15 +73,7 @@ func (ls *ListType) ToString(opt FmtOpt) (s string) {
|
|||||||
sb.WriteString(", ")
|
sb.WriteString(", ")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if s, ok := item.(string); ok {
|
Format(&sb, item, innerOpt)
|
||||||
sb.WriteByte('"')
|
|
||||||
sb.WriteString(s)
|
|
||||||
sb.WriteByte('"')
|
|
||||||
} else if formatter, ok := item.(Formatter); ok {
|
|
||||||
sb.WriteString(formatter.ToString(innerOpt))
|
|
||||||
} else {
|
|
||||||
sb.WriteString(fmt.Sprintf("%v", item))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if flags&MultiLine != 0 {
|
if flags&MultiLine != 0 {
|
||||||
sb.WriteByte('\n')
|
sb.WriteByte('\n')
|
||||||
@@ -104,11 +96,11 @@ func (ls *ListType) TypeName() string {
|
|||||||
return "list"
|
return "list"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dict *ListType) Contains(t *ListType) (answer bool) {
|
func (ls *ListType) Contains(t *ListType) (answer bool) {
|
||||||
if len(*dict) >= len(*t) {
|
if len(*ls) >= len(*t) {
|
||||||
answer = true
|
answer = true
|
||||||
for _, item := range *t {
|
for _, item := range *t {
|
||||||
if answer = dict.IndexDeepSameCmp(item) >= 0; !answer {
|
if answer = ls.IndexDeepSameCmp(item) >= 0; !answer {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -116,10 +108,10 @@ func (dict *ListType) Contains(t *ListType) (answer bool) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ls1 *ListType) Equals(ls2 ListType) (answer bool) {
|
func (ls *ListType) Equals(ls2 ListType) (answer bool) {
|
||||||
if ls2 != nil && len(*ls1) == len(ls2) {
|
if ls2 != nil && len(*ls) == len(ls2) {
|
||||||
answer = true
|
answer = true
|
||||||
for index, i1 := range *ls1 {
|
for index, i1 := range *ls {
|
||||||
// if !reflect.DeepEqual(i1, ls2[index]) {
|
// if !reflect.DeepEqual(i1, ls2[index]) {
|
||||||
// answer = false
|
// answer = false
|
||||||
// break
|
// break
|
||||||
@@ -142,11 +134,11 @@ func (ls1 *ListType) Clone() (ls2 *ListType) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dict *ListType) IndexDeepSameCmp(target any) (index int) {
|
func (ls *ListType) IndexDeepSameCmp(target any) (index int) {
|
||||||
var eq bool
|
var eq bool
|
||||||
var err error
|
var err error
|
||||||
index = -1
|
index = -1
|
||||||
for i, item := range *dict {
|
for i, item := range *ls {
|
||||||
if eq, err = deepSame(item, target, SameContent); err != nil {
|
if eq, err = deepSame(item, target, SameContent); err != nil {
|
||||||
break
|
break
|
||||||
} else if eq {
|
} else if eq {
|
||||||
@@ -197,15 +189,15 @@ func deepSame(a, b any, deepCmp DeepFuncTemplate) (eq bool, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dict *ListType) SetItem(index int64, value any) (err error) {
|
func (ls *ListType) SetItem(index int64, value any) (err error) {
|
||||||
if index >= 0 && index < int64(len(*dict)) {
|
if index >= 0 && index < int64(len(*ls)) {
|
||||||
(*dict)[index] = value
|
(*ls)[index] = value
|
||||||
} else {
|
} else {
|
||||||
err = fmt.Errorf("index %d out of bounds (0, %d)", index, len(*dict)-1)
|
err = fmt.Errorf("index %d out of bounds (0, %d)", index, len(*ls)-1)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dict *ListType) AppendItem(value any) {
|
func (ls *ListType) AppendItem(value any) {
|
||||||
*dict = append(*dict, value)
|
*ls = append(*ls, value)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ package expr
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"slices"
|
"slices"
|
||||||
|
|
||||||
"git.portale-stac.it/go-pkg/expr/scan"
|
"git.portale-stac.it/go-pkg/expr/scan"
|
||||||
@@ -164,16 +165,16 @@ func paramAlreadyDefined(args []*scan.Term, param *scan.Term) (position int) {
|
|||||||
return
|
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()
|
r, c := scanner.LastPos()
|
||||||
args := make([]*scan.Term, 0)
|
args := make([]*scan.Term, 0)
|
||||||
lastSym := scan.SymUnknown
|
lastSym := scan.SymUnknown
|
||||||
itemExpected := false
|
itemExpected := false
|
||||||
itemCtx := remFlags(ctx, allowIndex)
|
itemCtx := remFlags(ctx, allowIndex)
|
||||||
for lastSym != scan.SymClosedSquare && lastSym != scan.SymEos {
|
for lastSym != termSym && lastSym != scan.SymEos {
|
||||||
zeroRequired := scanner.Current().Sym == scan.SymColon
|
zeroRequired := scanner.Current().Sym == scan.SymColon
|
||||||
var itemTree *scan.Ast
|
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()
|
root := itemTree.Root()
|
||||||
if root != nil {
|
if root != nil {
|
||||||
if hasFlag(ctx, allowIndex) && root.Symbol() == scan.SymColon {
|
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 err == nil {
|
||||||
if lastSym != scan.SymClosedSquare {
|
if lastSym != termSym {
|
||||||
err = scanner.Previous().ErrorExpectedGot("]")
|
err = scanner.Previous().ErrorExpectedGot("]")
|
||||||
} else {
|
} else if termSym == scan.SymClosedSquare {
|
||||||
listTerm = newListTerm(r, c, args)
|
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
|
return
|
||||||
@@ -327,7 +332,7 @@ func (parser *parser) parseSelectorCase(scanner *scan.Scanner, ctx parserContext
|
|||||||
err = tk.Errorf("case list in default clause")
|
err = tk.Errorf("case list in default clause")
|
||||||
return
|
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
|
return
|
||||||
}
|
}
|
||||||
tk = parser.Next(scanner)
|
tk = parser.Next(scanner)
|
||||||
@@ -446,7 +451,7 @@ func (parser *parser) parseGeneral(scanner *scan.Scanner, ctx parserContext, ter
|
|||||||
tree = scan.NewAst()
|
tree = scan.NewAst()
|
||||||
firstToken := true
|
firstToken := true
|
||||||
// lastSym := SymUnknown
|
// 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 {
|
// if tk.Sym == SymComment {
|
||||||
// continue
|
// continue
|
||||||
// }
|
// }
|
||||||
@@ -491,7 +496,13 @@ func (parser *parser) parseGeneral(scanner *scan.Scanner, ctx parserContext, ter
|
|||||||
case scan.SymOpenSquare:
|
case scan.SymOpenSquare:
|
||||||
var listTerm *scan.Term
|
var listTerm *scan.Term
|
||||||
newCtx := addFlagsCond(addFlags(ctx, squareContext), allowIndex, couldBeACollection(currentTerm))
|
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))
|
currentTerm, err = listSubTree(tree, listTerm, hasFlag(newCtx, allowIndex))
|
||||||
}
|
}
|
||||||
case scan.SymOpenBrace:
|
case scan.SymOpenBrace:
|
||||||
|
|||||||
+7
-1
@@ -315,6 +315,8 @@ func (scanner *Scanner) fetchNextToken() (tk *Token) {
|
|||||||
} else {
|
} else {
|
||||||
tk = scanner.accept(SymDoubleGreater, ch, next)
|
tk = scanner.accept(SymDoubleGreater, ch, next)
|
||||||
}
|
}
|
||||||
|
} else if next == ']' {
|
||||||
|
tk = scanner.moveOn(SymGreaterClosedSquare, ch, next)
|
||||||
} else {
|
} else {
|
||||||
tk = scanner.MakeToken(SymGreater, ch)
|
tk = scanner.MakeToken(SymGreater, ch)
|
||||||
}
|
}
|
||||||
@@ -344,7 +346,11 @@ func (scanner *Scanner) fetchNextToken() (tk *Token) {
|
|||||||
case ')':
|
case ')':
|
||||||
tk = scanner.MakeToken(SymClosedRound, ch)
|
tk = scanner.MakeToken(SymClosedRound, ch)
|
||||||
case '[':
|
case '[':
|
||||||
tk = scanner.MakeToken(SymOpenSquare, ch)
|
if next, _ := scanner.peek(); next == '<' {
|
||||||
|
tk = scanner.moveOn(SymOpenSquareLess, ch, next)
|
||||||
|
} else {
|
||||||
|
tk = scanner.MakeToken(SymOpenSquare, ch)
|
||||||
|
}
|
||||||
case ']':
|
case ']':
|
||||||
tk = scanner.MakeToken(SymClosedSquare, ch)
|
tk = scanner.MakeToken(SymClosedSquare, ch)
|
||||||
case '{':
|
case '{':
|
||||||
|
|||||||
+77
-74
@@ -32,80 +32,82 @@ type symbolSpec struct {
|
|||||||
func init() {
|
func init() {
|
||||||
|
|
||||||
symbolMap = map[Symbol]symbolSpec{
|
symbolMap = map[Symbol]symbolSpec{
|
||||||
SymUnknown: {"<unknown>", SymClassOther, PosLeaf}, // -1: Unknown symbol
|
SymUnknown: {"<unknown>", SymClassOther, PosLeaf}, // -1: Unknown symbol
|
||||||
SymNone: {"<null>", SymClassOther, PosLeaf}, // 0: Null value for variable of type symbol
|
SymNone: {"<null>", SymClassOther, PosLeaf}, // 0: Null value for variable of type symbol
|
||||||
SymError: {"<error>", SymClassOther, PosLeaf}, // 1: Error reading from stream
|
SymError: {"<error>", SymClassOther, PosLeaf}, // 1: Error reading from stream
|
||||||
SymEos: {"<eos>", SymClassOther, PosLeaf}, // 2: End of stream
|
SymEos: {"<eos>", SymClassOther, PosLeaf}, // 2: End of stream
|
||||||
SymMinus: {"-", SymClassOperator, PosInfix}, // 3: '-'
|
SymMinus: {"-", SymClassOperator, PosInfix}, // 3: '-'
|
||||||
SymMinusEqual: {"-=", SymClassOperator, PosInfix}, // 4: '-='
|
SymMinusEqual: {"-=", SymClassOperator, PosInfix}, // 4: '-='
|
||||||
SymDoubleMinus: {"--", SymClassOperator, PosPostfix}, // 5: '--'
|
SymDoubleMinus: {"--", SymClassOperator, PosPostfix}, // 5: '--'
|
||||||
SymPlus: {"+", SymClassOperator, PosInfix}, // 6: '+'
|
SymPlus: {"+", SymClassOperator, PosInfix}, // 6: '+'
|
||||||
SymPlusEqual: {"+=", SymClassOperator, PosInfix}, // 7: '+='
|
SymPlusEqual: {"+=", SymClassOperator, PosInfix}, // 7: '+='
|
||||||
SymDoublePlus: {"++", SymClassOperator, PosPostfix}, // 8: '++'
|
SymDoublePlus: {"++", SymClassOperator, PosPostfix}, // 8: '++'
|
||||||
SymStar: {"*", SymClassOperator, PosInfix}, // 9: '*'
|
SymStar: {"*", SymClassOperator, PosInfix}, // 9: '*'
|
||||||
SymDoubleStar: {"**", SymClassOperator, PosInfix}, // 10: '**'
|
SymDoubleStar: {"**", SymClassOperator, PosInfix}, // 10: '**'
|
||||||
SymSlash: {"/", SymClassOperator, PosInfix}, // 11: '/'
|
SymSlash: {"/", SymClassOperator, PosInfix}, // 11: '/'
|
||||||
SymBackSlash: {"\\", SymClassOperator, PosLeaf}, // 12: '\'
|
SymBackSlash: {"\\", SymClassOperator, PosLeaf}, // 12: '\'
|
||||||
SymVertBar: {"|", SymClassOperator, PosInfix}, // 13: '|'
|
SymVertBar: {"|", SymClassOperator, PosInfix}, // 13: '|'
|
||||||
SymDoubleVertBar: {"||", SymClassOperator, PosInfix}, // 14: '||'
|
SymDoubleVertBar: {"||", SymClassOperator, PosInfix}, // 14: '||'
|
||||||
SymComma: {",", SymClassOperator, PosInfix}, // 15: ','
|
SymComma: {",", SymClassOperator, PosInfix}, // 15: ','
|
||||||
SymColon: {":", SymClassOperator, PosInfix}, // 16: ':'
|
SymColon: {":", SymClassOperator, PosInfix}, // 16: ':'
|
||||||
SymSemiColon: {";", SymClassOperator, PosInfix}, // 17: ';'
|
SymSemiColon: {";", SymClassOperator, PosInfix}, // 17: ';'
|
||||||
SymDot: {".", SymClassOperator, PosInfix}, // 18: '.'
|
SymDot: {".", SymClassOperator, PosInfix}, // 18: '.'
|
||||||
SymDotSlash: {"./", SymClassOperator, PosInfix}, // 19: './'
|
SymDotSlash: {"./", SymClassOperator, PosInfix}, // 19: './'
|
||||||
SymQuote: {"'", SymClassDelimiter, PosLeaf}, // 20: '\''
|
SymQuote: {"'", SymClassDelimiter, PosLeaf}, // 20: '\''
|
||||||
SymDoubleQuote: {"\"", SymClassDelimiter, PosLeaf}, // 21: '"'
|
SymDoubleQuote: {"\"", SymClassDelimiter, PosLeaf}, // 21: '"'
|
||||||
SymBackTick: {"`", SymClassDelimiter, PosLeaf}, // 22: '`'
|
SymBackTick: {"`", SymClassDelimiter, PosLeaf}, // 22: '`'
|
||||||
SymExclamation: {"!", SymClassOperator, PosPostfix}, // 23: '!'
|
SymExclamation: {"!", SymClassOperator, PosPostfix}, // 23: '!'
|
||||||
SymQuestion: {"?", SymClassOperator, PosInfix}, // 24: '?'
|
SymQuestion: {"?", SymClassOperator, PosInfix}, // 24: '?'
|
||||||
SymAmpersand: {"&", SymClassOperator, PosInfix}, // 25: '&'
|
SymAmpersand: {"&", SymClassOperator, PosInfix}, // 25: '&'
|
||||||
SymDoubleAmpersand: {"&&", SymClassOperator, PosInfix}, // 26: '&&'
|
SymDoubleAmpersand: {"&&", SymClassOperator, PosInfix}, // 26: '&&'
|
||||||
SymPercent: {"%", SymClassOperator, PosInfix}, // 27: '%'
|
SymPercent: {"%", SymClassOperator, PosInfix}, // 27: '%'
|
||||||
SymAt: {"@", SymClassOperator, PosPrefix}, // 28: '@'
|
SymAt: {"@", SymClassOperator, PosPrefix}, // 28: '@'
|
||||||
SymUndescore: {"_", SymClassIdentifier, PosLeaf}, // 29: '_'
|
SymUndescore: {"_", SymClassIdentifier, PosLeaf}, // 29: '_'
|
||||||
SymEqual: {"=", SymClassOperator, PosInfix}, // 30: '='
|
SymEqual: {"=", SymClassOperator, PosInfix}, // 30: '='
|
||||||
SymColonEqual: {":=", SymClassOperator, PosInfix}, // 31: ':='
|
SymColonEqual: {":=", SymClassOperator, PosInfix}, // 31: ':='
|
||||||
SymDoubleEqual: {"==", SymClassOperator, PosInfix}, // 32: '=='
|
SymDoubleEqual: {"==", SymClassOperator, PosInfix}, // 32: '=='
|
||||||
SymLess: {"<", SymClassOperator, PosInfix}, // 33: '<'
|
SymLess: {"<", SymClassOperator, PosInfix}, // 33: '<'
|
||||||
SymLessOrEqual: {"<=", SymClassOperator, PosInfix}, // 34: '<='
|
SymLessOrEqual: {"<=", SymClassOperator, PosInfix}, // 34: '<='
|
||||||
SymGreater: {">", SymClassOperator, PosInfix}, // 35: '>'
|
SymGreater: {">", SymClassOperator, PosInfix}, // 35: '>'
|
||||||
SymGreaterOrEqual: {">=", SymClassOperator, PosInfix}, // 36: '>='
|
SymGreaterOrEqual: {">=", SymClassOperator, PosInfix}, // 36: '>='
|
||||||
SymLessGreater: {"<>", SymClassOperator, PosInfix}, // 37: '<>'
|
SymLessGreater: {"<>", SymClassOperator, PosInfix}, // 37: '<>'
|
||||||
SymNotEqual: {"!=", SymClassOperator, PosInfix}, // 38: '!='
|
SymNotEqual: {"!=", SymClassOperator, PosInfix}, // 38: '!='
|
||||||
SymDollar: {"$", SymClassOperator, PosPrefix}, // 39: '$'
|
SymDollar: {"$", SymClassOperator, PosPrefix}, // 39: '$'
|
||||||
SymHash: {"#", SymClassOperator, PosPrefix}, // 40: '#'
|
SymHash: {"#", SymClassOperator, PosPrefix}, // 40: '#'
|
||||||
SymOpenRound: {"(", SymClassParenthesis, PosPrefix}, // 41: '('
|
SymOpenRound: {"(", SymClassParenthesis, PosPrefix}, // 41: '('
|
||||||
SymClosedRound: {")", SymClassParenthesis, PosPostfix}, // 42: ')'
|
SymClosedRound: {")", SymClassParenthesis, PosPostfix}, // 42: ')'
|
||||||
SymOpenSquare: {"[", SymClassParenthesis, PosPrefix}, // 43: '['
|
SymOpenSquare: {"[", SymClassParenthesis, PosPrefix}, // 43: '['
|
||||||
SymClosedSquare: {"]", SymClassParenthesis, PosPostfix}, // 44: ']'
|
SymClosedSquare: {"]", SymClassParenthesis, PosPostfix}, // 44: ']'
|
||||||
SymOpenBrace: {"{", SymClassParenthesis, PosPrefix}, // 45: '{'
|
SymOpenBrace: {"{", SymClassParenthesis, PosPrefix}, // 45: '{'
|
||||||
SymClosedBrace: {"}", SymClassParenthesis, PosPostfix}, // 46: '}'
|
SymClosedBrace: {"}", SymClassParenthesis, PosPostfix}, // 46: '}'
|
||||||
SymTilde: {"~", SymClassOperator, PosPrefix}, // 47: '~'
|
SymTilde: {"~", SymClassOperator, PosPrefix}, // 47: '~'
|
||||||
SymDoubleQuestion: {"??", SymClassOperator, PosInfix}, // 48: '??'
|
SymDoubleQuestion: {"??", SymClassOperator, PosInfix}, // 48: '??'
|
||||||
SymQuestionEqual: {"?=", SymClassOperator, PosInfix}, // 49: '?='
|
SymQuestionEqual: {"?=", SymClassOperator, PosInfix}, // 49: '?='
|
||||||
SymQuestionExclam: {"?!", SymClassOperator, PosInfix}, // 50: '?!'
|
SymQuestionExclam: {"?!", SymClassOperator, PosInfix}, // 50: '?!'
|
||||||
SymDoubleAt: {"@@", SymClassCommand, PosLeaf}, // 51: '@@'
|
SymDoubleAt: {"@@", SymClassCommand, PosLeaf}, // 51: '@@'
|
||||||
SymDoubleColon: {"::", SymClassOperator, PosInfix}, // 52: '::'
|
SymDoubleColon: {"::", SymClassOperator, PosInfix}, // 52: '::'
|
||||||
SymDoubleGreater: {">>", SymClassOperator, PosInfix}, // 53: '>>'
|
SymDoubleGreater: {">>", SymClassOperator, PosInfix}, // 53: '>>'
|
||||||
SymDoubleLess: {"<<", SymClassOperator, PosInfix}, // 54: '<<'
|
SymDoubleLess: {"<<", SymClassOperator, PosInfix}, // 54: '<<'
|
||||||
SymCaret: {"^", SymClassOperator, PosInfix}, // 55: '^'
|
SymCaret: {"^", SymClassOperator, PosInfix}, // 55: '^'
|
||||||
SymDollarRound: {"$(", SymClassOperator, PosPrefix}, // 56: '$('
|
SymDollarRound: {"$(", SymClassOperator, PosPrefix}, // 56: '$('
|
||||||
SymOpenClosedRound: {"()", SymClassOperator, PosPostfix}, // 57: '()'
|
SymOpenClosedRound: {"()", SymClassOperator, PosPostfix}, // 57: '()'
|
||||||
SymDoubleDollar: {"$$", SymClassCommand, PosLeaf}, // 58: '$$'
|
SymDoubleDollar: {"$$", SymClassCommand, PosLeaf}, // 58: '$$'
|
||||||
SymDoubleDot: {"..", SymClassOperator, PosInfix}, // 59: '..'
|
SymDoubleDot: {"..", SymClassOperator, PosInfix}, // 59: '..'
|
||||||
SymTripleDot: {"...", SymClassOperator, PosPostfix}, // 60: '...'
|
SymTripleDot: {"...", SymClassOperator, PosPostfix}, // 60: '...'
|
||||||
SymStarEqual: {"*=", SymClassOperator, PosInfix}, // 61: '*='
|
SymStarEqual: {"*=", SymClassOperator, PosInfix}, // 61: '*='
|
||||||
SymSlashEqual: {"/=", SymClassOperator, PosInfix}, // 62: '/='
|
SymSlashEqual: {"/=", SymClassOperator, PosInfix}, // 62: '/='
|
||||||
SymPercEqual: {"%=", SymClassOperator, PosInfix}, // 63: '%='
|
SymPercEqual: {"%=", SymClassOperator, PosInfix}, // 63: '%='
|
||||||
SymDoubleLessEqual: {"<<=", SymClassOperator, PosInfix}, // 64: '<<='
|
SymDoubleLessEqual: {"<<=", SymClassOperator, PosInfix}, // 64: '<<='
|
||||||
SymDoubleGreaterEqual: {">>=", SymClassOperator, PosInfix}, // 65: '>>='
|
SymDoubleGreaterEqual: {">>=", SymClassOperator, PosInfix}, // 65: '>>='
|
||||||
SymAmpersandEqual: {"&=", SymClassOperator, PosInfix}, // 66: '&='
|
SymAmpersandEqual: {"&=", SymClassOperator, PosInfix}, // 66: '&='
|
||||||
SymVertBarEqual: {"|=", SymClassOperator, PosInfix}, // 67: '|='
|
SymVertBarEqual: {"|=", SymClassOperator, PosInfix}, // 67: '|='
|
||||||
SymCaretEqual: {"^=", SymClassOperator, PosInfix}, // 68: '^='
|
SymCaretEqual: {"^=", SymClassOperator, PosInfix}, // 68: '^='
|
||||||
SymPlusGreater: {"+>", SymClassOperator, PosInfix}, // 69: '+>'
|
SymPlusGreater: {"+>", SymClassOperator, PosInfix}, // 69: '+>'
|
||||||
SymLessPlus: {"<+", SymClassOperator, PosInfix}, // 70: '<+'
|
SymLessPlus: {"<+", SymClassOperator, PosInfix}, // 70: '<+'
|
||||||
SymPreInc: {"++", SymClassOperator, PosPrefix}, // 71: '++'
|
SymPreInc: {"++", SymClassOperator, PosPrefix}, // 71: '++'
|
||||||
SymPreDec: {"--", SymClassOperator, PosPrefix}, // 72: '--'
|
SymPreDec: {"--", SymClassOperator, PosPrefix}, // 72: '--'
|
||||||
|
SymOpenSquareLess: {"[<", SymClassOperator, PosPrefix}, // 97: '[<'
|
||||||
|
SymGreaterClosedSquare: {">]", SymClassOperator, PosPostfix}, // 98: '>]'
|
||||||
// SymChangeSign
|
// SymChangeSign
|
||||||
// SymUnchangeSign
|
// SymUnchangeSign
|
||||||
// SymIdentifier
|
// SymIdentifier
|
||||||
@@ -123,6 +125,7 @@ func init() {
|
|||||||
// SymFuncCall
|
// SymFuncCall
|
||||||
// SymFuncDef
|
// SymFuncDef
|
||||||
// SymList
|
// SymList
|
||||||
|
// SymLinkedList
|
||||||
// SymDict
|
// SymDict
|
||||||
// SymIndex
|
// SymIndex
|
||||||
// SymExpression
|
// SymExpression
|
||||||
|
|||||||
+101
-98
@@ -7,104 +7,107 @@ package scan
|
|||||||
type Symbol int16
|
type Symbol int16
|
||||||
|
|
||||||
const (
|
const (
|
||||||
SymUnknown Symbol = iota - 1 // -1: Unknown symbol
|
SymUnknown Symbol = iota - 1 // -1: Unknown symbol
|
||||||
SymNone // 0: Null value for variable of type symbol
|
SymNone // 0: Null value for variable of type symbol
|
||||||
SymError // 1: Error reading from stream
|
SymError // 1: Error reading from stream
|
||||||
SymEos // 2: End of stream
|
SymEos // 2: End of stream
|
||||||
SymMinus // 3: '-'
|
SymMinus // 3: '-'
|
||||||
SymMinusEqual // 4: '-='
|
SymMinusEqual // 4: '-='
|
||||||
SymDoubleMinus // 5: '--'
|
SymDoubleMinus // 5: '--'
|
||||||
SymPlus // 6: '+'
|
SymPlus // 6: '+'
|
||||||
SymPlusEqual // 7: '+='
|
SymPlusEqual // 7: '+='
|
||||||
SymDoublePlus // 8: '++'
|
SymDoublePlus // 8: '++'
|
||||||
SymStar // 9: '*'
|
SymStar // 9: '*'
|
||||||
SymDoubleStar // 10: '**'
|
SymDoubleStar // 10: '**'
|
||||||
SymSlash // 11: '/'
|
SymSlash // 11: '/'
|
||||||
SymBackSlash // 12: '\'
|
SymBackSlash // 12: '\'
|
||||||
SymVertBar // 13: '|'
|
SymVertBar // 13: '|'
|
||||||
SymDoubleVertBar // 14: '||'
|
SymDoubleVertBar // 14: '||'
|
||||||
SymComma // 15: ','
|
SymComma // 15: ','
|
||||||
SymColon // 16: ':'
|
SymColon // 16: ':'
|
||||||
SymSemiColon // 17: ';'
|
SymSemiColon // 17: ';'
|
||||||
SymDot // 18: '.'
|
SymDot // 18: '.'
|
||||||
SymDotSlash // 19: './'
|
SymDotSlash // 19: './'
|
||||||
SymQuote // 20: '\''
|
SymQuote // 20: '\''
|
||||||
SymDoubleQuote // 21: '"'
|
SymDoubleQuote // 21: '"'
|
||||||
SymBackTick // 22: '`'
|
SymBackTick // 22: '`'
|
||||||
SymExclamation // 23: '!'
|
SymExclamation // 23: '!'
|
||||||
SymQuestion // 24: '?'
|
SymQuestion // 24: '?'
|
||||||
SymAmpersand // 25: '&'
|
SymAmpersand // 25: '&'
|
||||||
SymDoubleAmpersand // 26: '&&'
|
SymDoubleAmpersand // 26: '&&'
|
||||||
SymPercent // 27: '%'
|
SymPercent // 27: '%'
|
||||||
SymAt // 28: '@'
|
SymAt // 28: '@'
|
||||||
SymUndescore // 29: '_'
|
SymUndescore // 29: '_'
|
||||||
SymEqual // 30: '='
|
SymEqual // 30: '='
|
||||||
SymColonEqual // 31: ':='
|
SymColonEqual // 31: ':='
|
||||||
SymDoubleEqual // 32: '=='
|
SymDoubleEqual // 32: '=='
|
||||||
SymLess // 33: '<'
|
SymLess // 33: '<'
|
||||||
SymLessOrEqual // 34: '<='
|
SymLessOrEqual // 34: '<='
|
||||||
SymGreater // 35: '>'
|
SymGreater // 35: '>'
|
||||||
SymGreaterOrEqual // 36: '>='
|
SymGreaterOrEqual // 36: '>='
|
||||||
SymLessGreater // 37: '<>'
|
SymLessGreater // 37: '<>'
|
||||||
SymNotEqual // 38: '!='
|
SymNotEqual // 38: '!='
|
||||||
SymDollar // 39: '$'
|
SymDollar // 39: '$'
|
||||||
SymHash // 40: '#'
|
SymHash // 40: '#'
|
||||||
SymOpenRound // 41: '('
|
SymOpenRound // 41: '('
|
||||||
SymClosedRound // 42: ')'
|
SymClosedRound // 42: ')'
|
||||||
SymOpenSquare // 43: '['
|
SymOpenSquare // 43: '['
|
||||||
SymClosedSquare // 44: ']'
|
SymClosedSquare // 44: ']'
|
||||||
SymOpenBrace // 45: '{'
|
SymOpenBrace // 45: '{'
|
||||||
SymClosedBrace // 46: '}'
|
SymClosedBrace // 46: '}'
|
||||||
SymTilde // 47: '~'
|
SymTilde // 47: '~'
|
||||||
SymDoubleQuestion // 48: '??'
|
SymDoubleQuestion // 48: '??'
|
||||||
SymQuestionEqual // 49: '?='
|
SymQuestionEqual // 49: '?='
|
||||||
SymQuestionExclam // 50: '?!'
|
SymQuestionExclam // 50: '?!'
|
||||||
SymDoubleAt // 51: '@@'
|
SymDoubleAt // 51: '@@'
|
||||||
SymDoubleColon // 52: '::'
|
SymDoubleColon // 52: '::'
|
||||||
SymDoubleGreater // 53: '>>'
|
SymDoubleGreater // 53: '>>'
|
||||||
SymDoubleLess // 54: '<<'
|
SymDoubleLess // 54: '<<'
|
||||||
SymCaret // 55: '^'
|
SymCaret // 55: '^'
|
||||||
SymDollarRound // 56: '$('
|
SymDollarRound // 56: '$('
|
||||||
SymOpenClosedRound // 57: '()'
|
SymOpenClosedRound // 57: '()'
|
||||||
SymDoubleDollar // 58: '$$'
|
SymDoubleDollar // 58: '$$'
|
||||||
SymDoubleDot // 59: '..'
|
SymDoubleDot // 59: '..'
|
||||||
SymTripleDot // 60: '...'
|
SymTripleDot // 60: '...'
|
||||||
SymStarEqual // 61: '*='
|
SymStarEqual // 61: '*='
|
||||||
SymSlashEqual // 62: '/='
|
SymSlashEqual // 62: '/='
|
||||||
SymPercEqual // 63: '%='
|
SymPercEqual // 63: '%='
|
||||||
SymDoubleLessEqual // 64: '<<='
|
SymDoubleLessEqual // 64: '<<='
|
||||||
SymDoubleGreaterEqual // 65: '>>='
|
SymDoubleGreaterEqual // 65: '>>='
|
||||||
SymAmpersandEqual // 66: '&='
|
SymAmpersandEqual // 66: '&='
|
||||||
SymVertBarEqual // 67: '|='
|
SymVertBarEqual // 67: '|='
|
||||||
SymCaretEqual // 68: '^='
|
SymCaretEqual // 68: '^='
|
||||||
SymPlusGreater // 69: '+>'
|
SymPlusGreater // 69: '+>'
|
||||||
SymLessPlus // 70: '<+'
|
SymLessPlus // 70: '<+'
|
||||||
SymChangeSign // 71: '-'
|
SymChangeSign // 71: '-'
|
||||||
SymUnchangeSign // 72: '+''
|
SymUnchangeSign // 72: '+''
|
||||||
SymDereference // 73: '*'
|
SymDereference // 73: '*'
|
||||||
SymPreInc // 74: '++'
|
SymPreInc // 74: '++'
|
||||||
SymPreDec // 75: '--'
|
SymPreDec // 75: '--'
|
||||||
SymIdentifier // 76: identifier
|
SymIdentifier // 76: identifier
|
||||||
SymBool // 77: boolean
|
SymBool // 77: boolean
|
||||||
SymInteger // 78: integer
|
SymInteger // 78: integer
|
||||||
SymVariable // 79: variable
|
SymVariable // 79: variable
|
||||||
SymFloat // 80: float
|
SymFloat // 80: float
|
||||||
SymFraction // 81: fraction
|
SymFraction // 81: fraction
|
||||||
SymString // 82: string
|
SymString // 82: string
|
||||||
SymIterator // 83: iterator
|
SymIterator // 83: iterator
|
||||||
SymOr // 84: 'or'
|
SymOr // 84: 'or'
|
||||||
SymAnd // 85: 'and'
|
SymAnd // 85: 'and'
|
||||||
SymNot // 86: 'not'
|
SymNot // 86: 'not'
|
||||||
SymComment // 87: comment
|
SymComment // 87: comment
|
||||||
SymFuncCall // 88: function call
|
SymFuncCall // 88: function call
|
||||||
SymFuncDef // 89: function definition
|
SymFuncDef // 89: function definition
|
||||||
SymList // 90: list
|
SymList // 90: list
|
||||||
SymDict // 91: dict
|
SymDict // 91: dict
|
||||||
SymIndex // 92: index
|
SymIndex // 92: index
|
||||||
SymRange // 93: range [index : index]
|
SymRange // 93: range [index : index]
|
||||||
SymExpression // 94: expression
|
SymExpression // 94: expression
|
||||||
SymSelector // 95: selector <selector> ::= <expr> "?" <selector-case> {":" <selector-case>} ["::" <default-selector-case>]
|
SymSelector // 95: selector <selector> ::= <expr> "?" <selector-case> {":" <selector-case>} ["::" <default-selector-case>]
|
||||||
SymSelectorCase // 96: <selector-case> ::= [<list>] "{" <multi-expr> "}"
|
SymSelectorCase // 96: <selector-case> ::= [<list>] "{" <multi-expr> "}"
|
||||||
|
SymOpenSquareLess // 97: '[<'
|
||||||
|
SymGreaterClosedSquare // 98: '>]'
|
||||||
|
SymLinkedList // 99: linked-list
|
||||||
// SymOpenComment // 0: '/*'
|
// SymOpenComment // 0: '/*'
|
||||||
// SymClosedComment // 0: '*/'
|
// SymClosedComment // 0: '*/'
|
||||||
// SymOneLineComment // 0: '//'
|
// SymOneLineComment // 0: '//'
|
||||||
|
|||||||
@@ -118,8 +118,8 @@ func TestFuncBaseOthers(t *testing.T) {
|
|||||||
inputs := []inputType{
|
inputs := []inputType{
|
||||||
/* 1 */ {`set("a", 3); a`, int64(3), nil},
|
/* 1 */ {`set("a", 3); a`, int64(3), nil},
|
||||||
/* 2 */ {`set(true, 3)`, nil, `set(): the "name" parameter must be a string, got a bool (true)`},
|
/* 2 */ {`set(true, 3)`, nil, `set(): the "name" parameter must be a string, got a bool (true)`},
|
||||||
// /* 3 */ {`a=3; unset("a"); a`, nil, `undefined variable or function "a"`},
|
/* 3 */ {`seq(1,2,3)`, kern.NewLinkedListA(int64(1), int64(2), int64(3)), nil},
|
||||||
// /* 4 */ {`unset("a")`, nil, `undefined variable or function "a"`},
|
// /* 4 */ {`seq(1,2,4)`, kern.NewLinkedListA(int64(1), int64(2), int64(3)), nil},
|
||||||
}
|
}
|
||||||
|
|
||||||
// runTestSuiteSpec(t, section, inputs, 4)
|
// runTestSuiteSpec(t, section, inputs, 4)
|
||||||
|
|||||||
+15
-1
@@ -57,10 +57,24 @@ func TestListParser(t *testing.T) {
|
|||||||
/* 41 */ {`[0] << $([1,2,3,4])`, kern.NewListA(int64(0), int64(1), int64(2), int64(3), int64(4)), nil},
|
/* 41 */ {`[0] << $([1,2,3,4])`, kern.NewListA(int64(0), int64(1), int64(2), int64(3), int64(4)), nil},
|
||||||
/* 42 */ {`L=[]; [1] >> L; L`, kern.NewListA(), nil},
|
/* 42 */ {`L=[]; [1] >> L; L`, kern.NewListA(), nil},
|
||||||
/* 43 */ {`L=[]; L << [1]; L`, kern.NewListA(), nil},
|
/* 43 */ {`L=[]; L << [1]; L`, kern.NewListA(), nil},
|
||||||
|
// /* 44 */ {`[0,1,2,3,4][2:3]`, kern.NewListA(int64(20)), nil},
|
||||||
}
|
}
|
||||||
|
|
||||||
// t.Setenv("EXPR_PATH", ".")
|
// t.Setenv("EXPR_PATH", ".")
|
||||||
|
|
||||||
// runTestSuiteSpec(t, section, inputs, 42)
|
// runTestSuiteSpec(t, section, inputs, 44)
|
||||||
|
runTestSuite(t, section, inputs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLinkedListParser(t *testing.T) {
|
||||||
|
section := "Linked-List"
|
||||||
|
|
||||||
|
inputs := []inputType{
|
||||||
|
/* 1 */ {`[<1,2>]`, kern.NewLinkedListA(int64(1), int64(2)), nil},
|
||||||
|
}
|
||||||
|
|
||||||
|
// t.Setenv("EXPR_PATH", ".")
|
||||||
|
|
||||||
|
// runTestSuiteSpec(t, section, inputs, 44)
|
||||||
runTestSuite(t, section, inputs)
|
runTestSuite(t, section, inputs)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user