diff --git a/operator-post-inc.go b/operator-post-inc-dec.go similarity index 98% rename from operator-post-inc.go rename to operator-post-inc-dec.go index bb3a9d4..8b79c4d 100644 --- a/operator-post-inc.go +++ b/operator-post-inc-dec.go @@ -1,7 +1,7 @@ // Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com). // All rights reserved. -// operator-post-inc.go +// operator-post-inc-dec.go package expr // -------- post increment term diff --git a/operator-pre-inc-dec.go b/operator-pre-inc-dec.go new file mode 100644 index 0000000..807f3e6 --- /dev/null +++ b/operator-pre-inc-dec.go @@ -0,0 +1,69 @@ +// Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com). +// All rights reserved. + +// operator-pre-inc-dec.go +package expr + +// -------- pre increment term + +func newPreIncTerm(tk *Token) *term { + return &term{ + tk: *tk, + parent: nil, + children: make([]*term, 0, 1), + position: posPrefix, + priority: priIncDec, + evalFunc: evalPreInc, + } +} + +func evalPreInc(ctx ExprContext, opTerm *term) (v any, err error) { + var childValue any + if childValue, err = opTerm.evalPrefix(ctx); err != nil { + return + } + + if IsInteger(childValue) && opTerm.children[0].symbol() == SymVariable { + i := childValue.(int64) + 1 + ctx.SetVar(opTerm.children[0].source(), i) + v = i + } else { + err = opTerm.errIncompatibleType(childValue) + } + return +} + +// -------- pre decrement term + +func newPreDecTerm(tk *Token) *term { + return &term{ + tk: *tk, + parent: nil, + children: make([]*term, 0, 1), + position: posPrefix, + priority: priIncDec, + evalFunc: evalPreDec, + } +} + +func evalPreDec(ctx ExprContext, opTerm *term) (v any, err error) { + var childValue any + if childValue, err = opTerm.evalPrefix(ctx); err != nil { + return + } + + if IsInteger(childValue) && opTerm.children[0].symbol() == SymVariable { + i := childValue.(int64) - 1 + ctx.SetVar(opTerm.children[0].source(), i) + v = i + } else { + err = opTerm.errIncompatibleType(childValue) + } + return +} + +// init +func init() { + registerTermConstructor(SymPreInc, newPreIncTerm) + registerTermConstructor(SymPreDec, newPreDecTerm) +} diff --git a/parser.go b/parser.go index 2859b65..7a81a9e 100644 --- a/parser.go +++ b/parser.go @@ -409,6 +409,23 @@ func listSubTree(tree *ast, listTerm *term, allowIndeces bool) (root *term, err return } +func changePrefix(tk *Token) { + switch tk.Sym { + case SymMinus: + tk.SetSymbol(SymChangeSign) + case SymPlus: + tk.SetSymbol(SymUnchangeSign) + case SymStar: + tk.SetSymbol(SymDereference) + case SymExclamation: + tk.SetSymbol(SymNot) + case SymDoublePlus: + tk.SetSymbol(SymPreInc) + case SymDoubleMinus: + tk.SetSymbol(SymPreDec) + } +} + func (parser *parser) parseGeneral(scanner *scanner, ctx parserContext, termSymbols ...Symbol) (tree *ast, err error) { var selectorTerm *term = nil var currentTerm *term = nil @@ -437,15 +454,16 @@ func (parser *parser) parseGeneral(scanner *scanner, ctx parserContext, termSymb //fmt.Println("Token:", tk) if firstToken { - if tk.Sym == SymMinus { - tk.Sym = SymChangeSign - } else if tk.Sym == SymPlus { - tk.Sym = SymUnchangeSign - } else if tk.IsSymbol(SymStar) { - tk.SetSymbol(SymDereference) - } else if tk.IsSymbol(SymExclamation) { - tk.SetSymbol(SymNot) - } + changePrefix(tk) + // if tk.Sym == SymMinus { + // tk.Sym = SymChangeSign + // } else if tk.Sym == SymPlus { + // tk.Sym = SymUnchangeSign + // } else if tk.IsSymbol(SymStar) { + // tk.SetSymbol(SymDereference) + // } else if tk.IsSymbol(SymExclamation) { + // tk.SetSymbol(SymNot) + // } firstToken = false } diff --git a/symbol-map.go b/symbol-map.go index 6aed2ba..9e0e3c7 100644 --- a/symbol-map.go +++ b/symbol-map.go @@ -103,6 +103,8 @@ func init() { SymCaretEqual: {"^=", symClassOperator, posInfix}, // 66: '^=' SymPlusGreater: {"+>", symClassOperator, posInfix}, // 67: '+>' SymLessPlus: {"<+", symClassOperator, posInfix}, // 68: '<+' + SymPreInc: {"++", symClassOperator, posPrefix}, // : '++' + SymPreDec: {"--", symClassOperator, posPrefix}, // : '--' // SymChangeSign // SymUnchangeSign // SymIdentifier diff --git a/symbol.go b/symbol.go index 02eb6f8..02ceaae 100644 --- a/symbol.go +++ b/symbol.go @@ -81,6 +81,8 @@ const ( SymChangeSign SymUnchangeSign SymDereference + SymPreInc + SymPreDec SymIdentifier SymBool SymInteger