90 lines
2.2 KiB
Go
90 lines
2.2 KiB
Go
// Copyright (c) 2024-2026 Celestino Amoroso (celestino.amoroso@gmail.com).
|
|
// All rights reserved.
|
|
|
|
// operator-context-value.go
|
|
package expr
|
|
|
|
import (
|
|
"io"
|
|
|
|
"git.portale-stac.it/go-pkg/expr/kern"
|
|
"git.portale-stac.it/go-pkg/expr/scan"
|
|
)
|
|
|
|
//-------- context term
|
|
|
|
func newContextTerm(tk *scan.Token) (inst *scan.Term) {
|
|
return &scan.Term{
|
|
Tk: *tk,
|
|
Children: make([]*scan.Term, 0, 1),
|
|
Position: scan.PosPrefix,
|
|
Priority: scan.PriIncDec,
|
|
EvalFunc: evalContextValue,
|
|
}
|
|
}
|
|
|
|
func evalContextValue(ctx kern.ExprContext, opTerm *scan.Term) (v any, err error) {
|
|
var childValue any
|
|
var sourceCtx kern.ExprContext
|
|
|
|
if len(opTerm.Children) == 0 {
|
|
sourceCtx = ctx
|
|
} else if opTerm.Children[0].Symbol() == scan.SymVariable && opTerm.Children[0].Source() == "global" {
|
|
sourceCtx = ctx.GetGlobal()
|
|
} else if childValue, err = opTerm.EvalPrefix(ctx); err == nil {
|
|
if dc, ok := childValue.(*dataCursor); ok {
|
|
sourceCtx = dc.ctx
|
|
}
|
|
} else {
|
|
return
|
|
}
|
|
|
|
if sourceCtx != nil {
|
|
if formatter, ok := sourceCtx.(kern.DictFormat); ok {
|
|
v = formatter.ToDict()
|
|
} else if formatter, ok := sourceCtx.(kern.Formatter); ok {
|
|
v = formatter.ToString(0)
|
|
} else {
|
|
// keys := sourceCtx.EnumVars(func(name string) bool { return name[0] != '_' })
|
|
keys := sourceCtx.EnumVars(nil)
|
|
d := make(map[string]any)
|
|
for _, key := range keys {
|
|
d[key], _ = sourceCtx.GetVar(key)
|
|
}
|
|
keys = sourceCtx.EnumFuncs(func(name string) bool { return true })
|
|
for _, key := range keys {
|
|
d[key], _ = sourceCtx.GetFuncInfo(key)
|
|
}
|
|
v = d
|
|
}
|
|
} else if childValue != nil {
|
|
it, ok := childValue.(kern.Iterator)
|
|
if !ok {
|
|
it, err = NewIterator(ctx, childValue, nil)
|
|
}
|
|
if err == nil {
|
|
var item any
|
|
// values := kern.NewListA()
|
|
values := kern.NewLinkedListA()
|
|
for item, err = it.Next(); err == nil; item, err = it.Next() {
|
|
// values.AppendItem(item)
|
|
values.PushBack(item)
|
|
}
|
|
if err == io.EOF {
|
|
err = nil
|
|
v = values
|
|
}
|
|
// } else {
|
|
// err = opTerm.ErrIncompatiblePrefixPostfixType(childValue)
|
|
}
|
|
} else {
|
|
err = opTerm.ErrIncompatiblePrefixPostfixType(childValue)
|
|
}
|
|
return
|
|
}
|
|
|
|
// init
|
|
func init() {
|
|
scan.RegisterTermConstructor(scan.SymDoubleDollar, newContextTerm)
|
|
}
|