// Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com). // All rights reserved. // operator-post-inc-dec.go package expr import ( "git.portale-stac.it/go-pkg/expr/kern" "git.portale-stac.it/go-pkg/expr/scan" ) // -------- post increment term func newPostIncTerm(tk *scan.Token) *scan.Term { return &scan.Term{ Tk: *tk, Children: make([]*scan.Term, 0, 1), Position: scan.PosPostfix, Priority: scan.PriIncDec, EvalFunc: evalPostInc, } } func evalPostInc(ctx kern.ExprContext, opTerm *scan.Term) (v any, err error) { var childValue any if childValue, err = opTerm.EvalPrefix(ctx); err != nil { return } if it, ok := childValue.(kern.Iterator); ok { var namePrefix string v, err = it.Next() if opTerm.Children[0].Symbol() == scan.SymVariable { namePrefix = opTerm.Children[0].Source() } ctx.UnsafeSetVar(namePrefix+"_index", it.Index()) if c, err1 := it.Current(); err1 == nil { ctx.UnsafeSetVar(namePrefix+"_current", c) } if it.HasOperation(kern.KeyName) { if k, err1 := it.CallOperation(kern.KeyName, nil); err1 == nil { ctx.UnsafeSetVar(namePrefix+"_key", k) } } if it.HasOperation(kern.ValueName) { if v1, err1 := it.CallOperation(kern.ValueName, nil); err1 == nil { ctx.UnsafeSetVar(namePrefix+"_value", v1) } } } else if kern.IsInteger(childValue) && opTerm.Children[0].Symbol() == scan.SymVariable { v = childValue i, _ := childValue.(int64) ctx.SetVar(opTerm.Children[0].Source(), i+1) } else { err = opTerm.ErrIncompatiblePrefixPostfixType(childValue) } return } // -------- post decrement term func newPostDecTerm(tk *scan.Token) *scan.Term { return &scan.Term{ Tk: *tk, Children: make([]*scan.Term, 0, 1), Position: scan.PosPostfix, Priority: scan.PriIncDec, EvalFunc: evalPostDec, } } func evalPostDec(ctx kern.ExprContext, opTerm *scan.Term) (v any, err error) { var childValue any if childValue, err = opTerm.EvalPrefix(ctx); err != nil { return } /* if it, ok := childValue.(Iterator); ok { v, err = it.Next() } else */if kern.IsInteger(childValue) && opTerm.Children[0].Symbol() == scan.SymVariable { v = childValue i, _ := childValue.(int64) ctx.SetVar(opTerm.Children[0].Source(), i-1) } else { err = opTerm.ErrIncompatiblePrefixPostfixType(childValue) } return } // init func init() { scan.RegisterTermConstructor(scan.SymDoublePlus, newPostIncTerm) scan.RegisterTermConstructor(scan.SymDoubleMinus, newPostDecTerm) }