From 24a87c5275cd547b1779eb5d9dcff61c7ec6f230 Mon Sep 17 00:00:00 2001 From: wanggy Date: Mon, 13 Dec 2021 23:29:16 +0800 Subject: [PATCH 1/3] fixed:non-numeric type ,Inc/Dec --- parser/parser.go | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/parser/parser.go b/parser/parser.go index fd20423b..3ad35de9 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -2,11 +2,10 @@ package parser import ( "fmt" + "github.com/d5/tengo/v2/token" "io" "sort" "strconv" - - "github.com/d5/tengo/v2/token" ) type bailout struct{} @@ -1001,12 +1000,23 @@ func (p *Parser) parseSimpleStmt(forIn bool) Stmt { } case token.Inc, token.Dec: // increment or decrement statement + if !IsNumeric(x[0]) { + p.errorExpected(x[0].Pos(), "invalid operation:(non-numeric type)") + } s := &IncDecStmt{Expr: x[0], Token: p.token, TokenPos: p.pos} p.next() return s } return &ExprStmt{Expr: x[0]} } +func IsNumeric(val interface{}) bool { + switch val.(type) { + case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64: + case float32, float64, complex64, complex128: + return true + } + return false +} func (p *Parser) parseExprList() (list []Expr) { if p.trace { From ea1c260ebb5409aa219808d06d29ecaa822ac93b Mon Sep 17 00:00:00 2001 From: wanggy Date: Tue, 14 Dec 2021 16:52:50 +0800 Subject: [PATCH 2/3] fixed:non-numeric type ,Inc/Dec --- compiler.go | 14 +++++++++++++- parser/parser.go | 4 ---- symbol_table.go | 8 +++++++- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/compiler.go b/compiler.go index 53cc7d38..82b86d03 100644 --- a/compiler.go +++ b/compiler.go @@ -664,11 +664,23 @@ func (c *Compiler) compileAssign( if depth == 0 && exists { return c.errorf(node, "'%s' redeclared in this block", ident) } - symbol = c.symbolTable.Define(ident) + symbol = c.symbolTable.Define(ident, rhs[0]) } else { if !exists { return c.errorf(node, "unresolved reference '%s'", ident) + } else { + symbol, ok := c.symbolTable.store[ident] + if ok { + switch symbol.Expr.(type) { + case *parser.IntLit, *parser.FloatLit, *parser.CharLit: + break + default: + return c.errorf(node, "invalid operation: ++/-- (non-numeric type)") + + } + } } + } // +=, -=, *=, /= diff --git a/parser/parser.go b/parser/parser.go index 3ad35de9..cf21a42a 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -999,10 +999,6 @@ func (p *Parser) parseSimpleStmt(forIn bool) Stmt { TokenPos: pos, } case token.Inc, token.Dec: - // increment or decrement statement - if !IsNumeric(x[0]) { - p.errorExpected(x[0].Pos(), "invalid operation:(non-numeric type)") - } s := &IncDecStmt{Expr: x[0], Token: p.token, TokenPos: p.pos} p.next() return s diff --git a/symbol_table.go b/symbol_table.go index 73aaad3b..4caf0ca7 100644 --- a/symbol_table.go +++ b/symbol_table.go @@ -1,5 +1,7 @@ package tengo +import "github.com/d5/tengo/v2/parser" + // SymbolScope represents a symbol scope. type SymbolScope string @@ -17,6 +19,7 @@ type Symbol struct { Scope SymbolScope Index int LocalAssigned bool // if the local symbol is assigned at least once + Expr parser.Expr } // SymbolTable represents a symbol table. @@ -38,7 +41,7 @@ func NewSymbolTable() *SymbolTable { } // Define adds a new symbol in the current scope. -func (t *SymbolTable) Define(name string) *Symbol { +func (t *SymbolTable) Define(name string, expr ...parser.Expr) *Symbol { symbol := &Symbol{Name: name, Index: t.nextIndex()} t.numDefinition++ @@ -58,6 +61,9 @@ func (t *SymbolTable) Define(name string) *Symbol { } else { symbol.Scope = ScopeLocal } + if len(expr) > 0 { + symbol.Expr = expr[0] + } t.store[name] = symbol t.updateMaxDefs(symbol.Index + 1) return symbol From aa136c73e7101b29a0ae84bd4a55f137ce4be532 Mon Sep 17 00:00:00 2001 From: wanggy Date: Tue, 14 Dec 2021 17:06:00 +0800 Subject: [PATCH 3/3] Revert "fixed:non-numeric type ,Inc/Dec" This reverts commit 24a87c5275cd547b1779eb5d9dcff61c7ec6f230. --- parser/parser.go | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/parser/parser.go b/parser/parser.go index 3ad35de9..fd20423b 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -2,10 +2,11 @@ package parser import ( "fmt" - "github.com/d5/tengo/v2/token" "io" "sort" "strconv" + + "github.com/d5/tengo/v2/token" ) type bailout struct{} @@ -1000,23 +1001,12 @@ func (p *Parser) parseSimpleStmt(forIn bool) Stmt { } case token.Inc, token.Dec: // increment or decrement statement - if !IsNumeric(x[0]) { - p.errorExpected(x[0].Pos(), "invalid operation:(non-numeric type)") - } s := &IncDecStmt{Expr: x[0], Token: p.token, TokenPos: p.pos} p.next() return s } return &ExprStmt{Expr: x[0]} } -func IsNumeric(val interface{}) bool { - switch val.(type) { - case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64: - case float32, float64, complex64, complex128: - return true - } - return false -} func (p *Parser) parseExprList() (list []Expr) { if p.trace {