summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/d5/tengo/v2
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/d5/tengo/v2')
-rw-r--r--vendor/github.com/d5/tengo/v2/compiler.go7
-rw-r--r--vendor/github.com/d5/tengo/v2/parser/parser.go18
-rw-r--r--vendor/github.com/d5/tengo/v2/parser/scanner.go113
3 files changed, 61 insertions, 77 deletions
diff --git a/vendor/github.com/d5/tengo/v2/compiler.go b/vendor/github.com/d5/tengo/v2/compiler.go
index e4e04303..6591603c 100644
--- a/vendor/github.com/d5/tengo/v2/compiler.go
+++ b/vendor/github.com/d5/tengo/v2/compiler.go
@@ -1220,14 +1220,14 @@ func (c *Compiler) optimizeFunc(node parser.Node) {
iterateInstructions(c.scopes[c.scopeIndex].Instructions,
func(pos int, opcode parser.Opcode, operands []int) bool {
switch {
+ case dsts[pos]:
+ dstIdx++
+ deadCode = false
case opcode == parser.OpReturn:
if deadCode {
return true
}
deadCode = true
- case dsts[pos]:
- dstIdx++
- deadCode = false
case deadCode:
return true
}
@@ -1242,6 +1242,7 @@ func (c *Compiler) optimizeFunc(node parser.Node) {
var appendReturn bool
endPos := len(c.scopes[c.scopeIndex].Instructions)
newEndPost := len(newInsts)
+
iterateInstructions(newInsts,
func(pos int, opcode parser.Opcode, operands []int) bool {
switch opcode {
diff --git a/vendor/github.com/d5/tengo/v2/parser/parser.go b/vendor/github.com/d5/tengo/v2/parser/parser.go
index fd20423b..eaa9dc93 100644
--- a/vendor/github.com/d5/tengo/v2/parser/parser.go
+++ b/vendor/github.com/d5/tengo/v2/parser/parser.go
@@ -375,7 +375,12 @@ func (p *Parser) parseOperand() Expr {
case token.Ident:
return p.parseIdent()
case token.Int:
- v, _ := strconv.ParseInt(p.tokenLit, 10, 64)
+ v, err := strconv.ParseInt(p.tokenLit, 0, 64)
+ if err == strconv.ErrRange {
+ p.error(p.pos, "number out of range")
+ } else if err != nil {
+ p.error(p.pos, "invalid integer")
+ }
x := &IntLit{
Value: v,
ValuePos: p.pos,
@@ -383,8 +388,14 @@ func (p *Parser) parseOperand() Expr {
}
p.next()
return x
+
case token.Float:
- v, _ := strconv.ParseFloat(p.tokenLit, 64)
+ v, err := strconv.ParseFloat(p.tokenLit, 64)
+ if err == strconv.ErrRange {
+ p.error(p.pos, "number out of range")
+ } else if err != nil {
+ p.error(p.pos, "invalid float")
+ }
x := &FloatLit{
Value: v,
ValuePos: p.pos,
@@ -447,10 +458,11 @@ func (p *Parser) parseOperand() Expr {
return p.parseErrorExpr()
case token.Immutable: // immutable expression
return p.parseImmutableExpr()
+ default:
+ p.errorExpected(p.pos, "operand")
}
pos := p.pos
- p.errorExpected(pos, "operand")
p.advance(stmtStart)
return &BadExpr{From: pos, To: p.pos}
}
diff --git a/vendor/github.com/d5/tengo/v2/parser/scanner.go b/vendor/github.com/d5/tengo/v2/parser/scanner.go
index f1d820a4..5f797706 100644
--- a/vendor/github.com/d5/tengo/v2/parser/scanner.go
+++ b/vendor/github.com/d5/tengo/v2/parser/scanner.go
@@ -93,9 +93,9 @@ func (s *Scanner) Scan() (
token.Export, token.True, token.False, token.Undefined:
insertSemi = true
}
- case '0' <= ch && ch <= '9':
+ case ('0' <= ch && ch <= '9') || (ch == '.' && '0' <= s.peek() && s.peek() <= '9'):
insertSemi = true
- tok, literal = s.scanNumber(false)
+ tok, literal = s.scanNumber()
default:
s.next() // always make progress
@@ -125,16 +125,11 @@ func (s *Scanner) Scan() (
case ':':
tok = s.switch2(token.Colon, token.Define)
case '.':
- if '0' <= s.ch && s.ch <= '9' {
- insertSemi = true
- tok, literal = s.scanNumber(true)
- } else {
- tok = token.Period
- if s.ch == '.' && s.peek() == '.' {
- s.next()
- s.next() // consume last '.'
- tok = token.Ellipsis
- }
+ tok = token.Period
+ if s.ch == '.' && s.peek() == '.' {
+ s.next()
+ s.next() // consume last '.'
+ tok = token.Ellipsis
}
case ',':
tok = token.Comma
@@ -379,86 +374,58 @@ func (s *Scanner) scanIdentifier() string {
return string(s.src[offs:s.offset])
}
-func (s *Scanner) scanMantissa(base int) {
- for digitVal(s.ch) < base {
+func (s *Scanner) scanDigits(base int) {
+ for s.ch == '_' || digitVal(s.ch) < base {
s.next()
}
}
-func (s *Scanner) scanNumber(
- seenDecimalPoint bool,
-) (tok token.Token, lit string) {
- // digitVal(s.ch) < 10
+func (s *Scanner) scanNumber() (token.Token, string) {
offs := s.offset
- tok = token.Int
-
- defer func() {
- lit = string(s.src[offs:s.offset])
- }()
-
- if seenDecimalPoint {
- offs--
- tok = token.Float
- s.scanMantissa(10)
- goto exponent
- }
+ tok := token.Int
+ base := 10
- if s.ch == '0' {
- // int or float
- offs := s.offset
+ // Determine base
+ switch {
+ case s.ch == '0' && lower(s.peek()) == 'b':
+ base = 2
+ s.next()
+ s.next()
+ case s.ch == '0' && lower(s.peek()) == 'o':
+ base = 8
+ s.next()
+ s.next()
+ case s.ch == '0' && lower(s.peek()) == 'x':
+ base = 16
+ s.next()
s.next()
- if s.ch == 'x' || s.ch == 'X' {
- // hexadecimal int
- s.next()
- s.scanMantissa(16)
- if s.offset-offs <= 2 {
- // only scanned "0x" or "0X"
- s.error(offs, "illegal hexadecimal number")
- }
- } else {
- // octal int or float
- seenDecimalDigit := false
- s.scanMantissa(8)
- if s.ch == '8' || s.ch == '9' {
- // illegal octal int or float
- seenDecimalDigit = true
- s.scanMantissa(10)
- }
- if s.ch == '.' || s.ch == 'e' || s.ch == 'E' || s.ch == 'i' {
- goto fraction
- }
- // octal int
- if seenDecimalDigit {
- s.error(offs, "illegal octal number")
- }
- }
- return
}
- // decimal int or float
- s.scanMantissa(10)
+ // Scan whole number
+ s.scanDigits(base)
-fraction:
- if s.ch == '.' {
+ // Scan fractional part
+ if s.ch == '.' && (base == 10 || base == 16) {
tok = token.Float
s.next()
- s.scanMantissa(10)
+ s.scanDigits(base)
}
-exponent:
- if s.ch == 'e' || s.ch == 'E' {
+ // Scan exponent
+ if s.ch == 'e' || s.ch == 'E' || s.ch == 'p' || s.ch == 'P' {
tok = token.Float
s.next()
if s.ch == '-' || s.ch == '+' {
s.next()
}
- if digitVal(s.ch) < 10 {
- s.scanMantissa(10)
- } else {
- s.error(offs, "illegal floating-point exponent")
+ offs := s.offset
+ s.scanDigits(10)
+ if offs == s.offset {
+ s.error(offs, "exponent has no digits")
}
}
- return
+
+ return tok, string(s.src[offs:s.offset])
}
func (s *Scanner) scanEscape(quote rune) bool {
@@ -687,3 +654,7 @@ func digitVal(ch rune) int {
}
return 16 // larger than any legal digit val
}
+
+func lower(c byte) byte {
+ return c | ('x' - 'X')
+}