From 10eec286fa89ce63fa5d8b6cf30d5fe90c4193e6 Mon Sep 17 00:00:00 2001 From: Celestino Amoroso Date: Sat, 27 Apr 2024 06:12:30 +0200 Subject: [PATCH] new operator '111123' that returns the content of the current context or the context of an iterator --- operator-context.go | 49 +++++++++++++++++++++++++++++++++++++++++++++ scanner.go | 6 ++++-- symbol.go | 3 ++- 3 files changed, 55 insertions(+), 3 deletions(-) create mode 100644 operator-context.go diff --git a/operator-context.go b/operator-context.go new file mode 100644 index 0000000..b4c0464 --- /dev/null +++ b/operator-context.go @@ -0,0 +1,49 @@ +// Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com). +// All rights reserved. + +// operator-context-value.go +package expr + +//-------- context term + +func newContextTerm(tk *Token) (inst *term) { + return &term{ + tk: *tk, + children: make([]*term, 0, 1), + position: posPrefix, + priority: priPrePost, + evalFunc: evalContextValue, + } +} + +func evalContextValue(ctx ExprContext, self *term) (v any, err error) { + var childValue any + + var sourceCtx ExprContext + if len(self.children) == 0 { + sourceCtx = ctx + } else if childValue, err = self.evalPrefix(ctx); err == nil { + if dc, ok := childValue.(*dataCursor); ok { + sourceCtx = dc.ctx + } + } else { + return + } + + if sourceCtx != nil { + keys := sourceCtx.EnumVars(func(name string) bool { return name[0] != '_' }) + d := make(map[string]any) + for _, key := range keys { + d[key], _ = sourceCtx.GetVar(key) + } + v = d + } else { + err = self.errIncompatibleType(childValue) + } + return +} + +// init +func init() { + registerTermConstructor(SymDoubleDollar, newContextTerm) +} diff --git a/scanner.go b/scanner.go index dd5c200..8a6ba93 100644 --- a/scanner.go +++ b/scanner.go @@ -242,6 +242,8 @@ func (self *scanner) fetchNextToken() (tk *Token) { if next, _ := self.peek(); next == '(' { tk = self.moveOn(SymDollarRound, ch, next) tk.source += ")" + } else if next == '$' { + tk = self.moveOn(SymDoubleDollar, ch, next) } else { tk = self.makeToken(SymDollar, ch) } @@ -249,8 +251,8 @@ func (self *scanner) fetchNextToken() (tk *Token) { if next, _ := self.peek(); next == ')' { tk = self.moveOn(SymOpenClosedRound, ch, next) } else { - tk = self.makeToken(SymOpenRound, ch) - } + tk = self.makeToken(SymOpenRound, ch) + } case ')': tk = self.makeToken(SymClosedRound, ch) case '[': diff --git a/symbol.go b/symbol.go index 5d4ea20..12132a0 100644 --- a/symbol.go +++ b/symbol.go @@ -63,7 +63,8 @@ const ( SymAppend // 52: '<<' SymCaret // 53: '^' SymDollarRound // 54: '$(' - SymOpenClosedRound // 55: '()' + SymOpenClosedRound // 55: '()' + SymDoubleDollar // 56: '$$ SymChangeSign SymUnchangeSign SymIdentifier