diff options
Diffstat (limited to 'vendor/github.com/d5/tengo/compiler')
76 files changed, 0 insertions, 5849 deletions
diff --git a/vendor/github.com/d5/tengo/compiler/ast/array_lit.go b/vendor/github.com/d5/tengo/compiler/ast/array_lit.go deleted file mode 100644 index 9fb4ed67..00000000 --- a/vendor/github.com/d5/tengo/compiler/ast/array_lit.go +++ /dev/null @@ -1,35 +0,0 @@ -package ast - -import ( - "strings" - - "github.com/d5/tengo/compiler/source" -) - -// ArrayLit represents an array literal. -type ArrayLit struct { - Elements []Expr - LBrack source.Pos - RBrack source.Pos -} - -func (e *ArrayLit) exprNode() {} - -// Pos returns the position of first character belonging to the node. -func (e *ArrayLit) Pos() source.Pos { - return e.LBrack -} - -// End returns the position of first character immediately after the node. -func (e *ArrayLit) End() source.Pos { - return e.RBrack + 1 -} - -func (e *ArrayLit) String() string { - var elements []string - for _, m := range e.Elements { - elements = append(elements, m.String()) - } - - return "[" + strings.Join(elements, ", ") + "]" -} diff --git a/vendor/github.com/d5/tengo/compiler/ast/assign_stmt.go b/vendor/github.com/d5/tengo/compiler/ast/assign_stmt.go deleted file mode 100644 index e129114e..00000000 --- a/vendor/github.com/d5/tengo/compiler/ast/assign_stmt.go +++ /dev/null @@ -1,40 +0,0 @@ -package ast - -import ( - "strings" - - "github.com/d5/tengo/compiler/source" - "github.com/d5/tengo/compiler/token" -) - -// AssignStmt represents an assignment statement. -type AssignStmt struct { - LHS []Expr - RHS []Expr - Token token.Token - TokenPos source.Pos -} - -func (s *AssignStmt) stmtNode() {} - -// Pos returns the position of first character belonging to the node. -func (s *AssignStmt) Pos() source.Pos { - return s.LHS[0].Pos() -} - -// End returns the position of first character immediately after the node. -func (s *AssignStmt) End() source.Pos { - return s.RHS[len(s.RHS)-1].End() -} - -func (s *AssignStmt) String() string { - var lhs, rhs []string - for _, e := range s.LHS { - lhs = append(lhs, e.String()) - } - for _, e := range s.RHS { - rhs = append(rhs, e.String()) - } - - return strings.Join(lhs, ", ") + " " + s.Token.String() + " " + strings.Join(rhs, ", ") -} diff --git a/vendor/github.com/d5/tengo/compiler/ast/ast.go b/vendor/github.com/d5/tengo/compiler/ast/ast.go deleted file mode 100644 index 9fd06728..00000000 --- a/vendor/github.com/d5/tengo/compiler/ast/ast.go +++ /dev/null @@ -1,5 +0,0 @@ -package ast - -const ( - nullRep = "<null>" -) diff --git a/vendor/github.com/d5/tengo/compiler/ast/bad_expr.go b/vendor/github.com/d5/tengo/compiler/ast/bad_expr.go deleted file mode 100644 index 771f26fd..00000000 --- a/vendor/github.com/d5/tengo/compiler/ast/bad_expr.go +++ /dev/null @@ -1,25 +0,0 @@ -package ast - -import "github.com/d5/tengo/compiler/source" - -// BadExpr represents a bad expression. -type BadExpr struct { - From source.Pos - To source.Pos -} - -func (e *BadExpr) exprNode() {} - -// Pos returns the position of first character belonging to the node. -func (e *BadExpr) Pos() source.Pos { - return e.From -} - -// End returns the position of first character immediately after the node. -func (e *BadExpr) End() source.Pos { - return e.To -} - -func (e *BadExpr) String() string { - return "<bad expression>" -} diff --git a/vendor/github.com/d5/tengo/compiler/ast/bad_stmt.go b/vendor/github.com/d5/tengo/compiler/ast/bad_stmt.go deleted file mode 100644 index c2d0ae9a..00000000 --- a/vendor/github.com/d5/tengo/compiler/ast/bad_stmt.go +++ /dev/null @@ -1,25 +0,0 @@ -package ast - -import "github.com/d5/tengo/compiler/source" - -// BadStmt represents a bad statement. -type BadStmt struct { - From source.Pos - To source.Pos -} - -func (s *BadStmt) stmtNode() {} - -// Pos returns the position of first character belonging to the node. -func (s *BadStmt) Pos() source.Pos { - return s.From -} - -// End returns the position of first character immediately after the node. -func (s *BadStmt) End() source.Pos { - return s.To -} - -func (s *BadStmt) String() string { - return "<bad statement>" -} diff --git a/vendor/github.com/d5/tengo/compiler/ast/binary_expr.go b/vendor/github.com/d5/tengo/compiler/ast/binary_expr.go deleted file mode 100644 index 0cc5bba8..00000000 --- a/vendor/github.com/d5/tengo/compiler/ast/binary_expr.go +++ /dev/null @@ -1,30 +0,0 @@ -package ast - -import ( - "github.com/d5/tengo/compiler/source" - "github.com/d5/tengo/compiler/token" -) - -// BinaryExpr represents a binary operator expression. -type BinaryExpr struct { - LHS Expr - RHS Expr - Token token.Token - TokenPos source.Pos -} - -func (e *BinaryExpr) exprNode() {} - -// Pos returns the position of first character belonging to the node. -func (e *BinaryExpr) Pos() source.Pos { - return e.LHS.Pos() -} - -// End returns the position of first character immediately after the node. -func (e *BinaryExpr) End() source.Pos { - return e.RHS.End() -} - -func (e *BinaryExpr) String() string { - return "(" + e.LHS.String() + " " + e.Token.String() + " " + e.RHS.String() + ")" -} diff --git a/vendor/github.com/d5/tengo/compiler/ast/block_stmt.go b/vendor/github.com/d5/tengo/compiler/ast/block_stmt.go deleted file mode 100644 index 9bde9fa3..00000000 --- a/vendor/github.com/d5/tengo/compiler/ast/block_stmt.go +++ /dev/null @@ -1,35 +0,0 @@ -package ast - -import ( - "strings" - - "github.com/d5/tengo/compiler/source" -) - -// BlockStmt represents a block statement. -type BlockStmt struct { - Stmts []Stmt - LBrace source.Pos - RBrace source.Pos -} - -func (s *BlockStmt) stmtNode() {} - -// Pos returns the position of first character belonging to the node. -func (s *BlockStmt) Pos() source.Pos { - return s.LBrace -} - -// End returns the position of first character immediately after the node. -func (s *BlockStmt) End() source.Pos { - return s.RBrace + 1 -} - -func (s *BlockStmt) String() string { - var list []string - for _, e := range s.Stmts { - list = append(list, e.String()) - } - - return "{" + strings.Join(list, "; ") + "}" -} diff --git a/vendor/github.com/d5/tengo/compiler/ast/bool_lit.go b/vendor/github.com/d5/tengo/compiler/ast/bool_lit.go deleted file mode 100644 index e667a5c8..00000000 --- a/vendor/github.com/d5/tengo/compiler/ast/bool_lit.go +++ /dev/null @@ -1,26 +0,0 @@ -package ast - -import "github.com/d5/tengo/compiler/source" - -// BoolLit represents a boolean literal. -type BoolLit struct { - Value bool - ValuePos source.Pos - Literal string -} - -func (e *BoolLit) exprNode() {} - -// Pos returns the position of first character belonging to the node. -func (e *BoolLit) Pos() source.Pos { - return e.ValuePos -} - -// End returns the position of first character immediately after the node. -func (e *BoolLit) End() source.Pos { - return source.Pos(int(e.ValuePos) + len(e.Literal)) -} - -func (e *BoolLit) String() string { - return e.Literal -} diff --git a/vendor/github.com/d5/tengo/compiler/ast/branch_stmt.go b/vendor/github.com/d5/tengo/compiler/ast/branch_stmt.go deleted file mode 100644 index f6c7fdea..00000000 --- a/vendor/github.com/d5/tengo/compiler/ast/branch_stmt.go +++ /dev/null @@ -1,38 +0,0 @@ -package ast - -import ( - "github.com/d5/tengo/compiler/source" - "github.com/d5/tengo/compiler/token" -) - -// BranchStmt represents a branch statement. -type BranchStmt struct { - Token token.Token - TokenPos source.Pos - Label *Ident -} - -func (s *BranchStmt) stmtNode() {} - -// Pos returns the position of first character belonging to the node. -func (s *BranchStmt) Pos() source.Pos { - return s.TokenPos -} - -// End returns the position of first character immediately after the node. -func (s *BranchStmt) End() source.Pos { - if s.Label != nil { - return s.Label.End() - } - - return source.Pos(int(s.TokenPos) + len(s.Token.String())) -} - -func (s *BranchStmt) String() string { - var label string - if s.Label != nil { - label = " " + s.Label.Name - } - - return s.Token.String() + label -} diff --git a/vendor/github.com/d5/tengo/compiler/ast/call_expr.go b/vendor/github.com/d5/tengo/compiler/ast/call_expr.go deleted file mode 100644 index 0219d7c9..00000000 --- a/vendor/github.com/d5/tengo/compiler/ast/call_expr.go +++ /dev/null @@ -1,36 +0,0 @@ -package ast - -import ( - "strings" - - "github.com/d5/tengo/compiler/source" -) - -// CallExpr represents a function call expression. -type CallExpr struct { - Func Expr - LParen source.Pos - Args []Expr - RParen source.Pos -} - -func (e *CallExpr) exprNode() {} - -// Pos returns the position of first character belonging to the node. -func (e *CallExpr) Pos() source.Pos { - return e.Func.Pos() -} - -// End returns the position of first character immediately after the node. -func (e *CallExpr) End() source.Pos { - return e.RParen + 1 -} - -func (e *CallExpr) String() string { - var args []string - for _, e := range e.Args { - args = append(args, e.String()) - } - - return e.Func.String() + "(" + strings.Join(args, ", ") + ")" -} diff --git a/vendor/github.com/d5/tengo/compiler/ast/char_lit.go b/vendor/github.com/d5/tengo/compiler/ast/char_lit.go deleted file mode 100644 index 592f8744..00000000 --- a/vendor/github.com/d5/tengo/compiler/ast/char_lit.go +++ /dev/null @@ -1,26 +0,0 @@ -package ast - -import "github.com/d5/tengo/compiler/source" - -// CharLit represents a character literal. -type CharLit struct { - Value rune - ValuePos source.Pos - Literal string -} - -func (e *CharLit) exprNode() {} - -// Pos returns the position of first character belonging to the node. -func (e *CharLit) Pos() source.Pos { - return e.ValuePos -} - -// End returns the position of first character immediately after the node. -func (e *CharLit) End() source.Pos { - return source.Pos(int(e.ValuePos) + len(e.Literal)) -} - -func (e *CharLit) String() string { - return e.Literal -} diff --git a/vendor/github.com/d5/tengo/compiler/ast/cond_expr.go b/vendor/github.com/d5/tengo/compiler/ast/cond_expr.go deleted file mode 100644 index bb1db849..00000000 --- a/vendor/github.com/d5/tengo/compiler/ast/cond_expr.go +++ /dev/null @@ -1,30 +0,0 @@ -package ast - -import ( - "github.com/d5/tengo/compiler/source" -) - -// CondExpr represents a ternary conditional expression. -type CondExpr struct { - Cond Expr - True Expr - False Expr - QuestionPos source.Pos - ColonPos source.Pos -} - -func (e *CondExpr) exprNode() {} - -// Pos returns the position of first character belonging to the node. -func (e *CondExpr) Pos() source.Pos { - return e.Cond.Pos() -} - -// End returns the position of first character immediately after the node. -func (e *CondExpr) End() source.Pos { - return e.False.End() -} - -func (e *CondExpr) String() string { - return "(" + e.Cond.String() + " ? " + e.True.String() + " : " + e.False.String() + ")" -} diff --git a/vendor/github.com/d5/tengo/compiler/ast/empty_stmt.go b/vendor/github.com/d5/tengo/compiler/ast/empty_stmt.go deleted file mode 100644 index a2ac6ffe..00000000 --- a/vendor/github.com/d5/tengo/compiler/ast/empty_stmt.go +++ /dev/null @@ -1,29 +0,0 @@ -package ast - -import "github.com/d5/tengo/compiler/source" - -// EmptyStmt represents an empty statement. -type EmptyStmt struct { - Semicolon source.Pos - Implicit bool -} - -func (s *EmptyStmt) stmtNode() {} - -// Pos returns the position of first character belonging to the node. -func (s *EmptyStmt) Pos() source.Pos { - return s.Semicolon -} - -// End returns the position of first character immediately after the node. -func (s *EmptyStmt) End() source.Pos { - if s.Implicit { - return s.Semicolon - } - - return s.Semicolon + 1 -} - -func (s *EmptyStmt) String() string { - return ";" -} diff --git a/vendor/github.com/d5/tengo/compiler/ast/error_expr.go b/vendor/github.com/d5/tengo/compiler/ast/error_expr.go deleted file mode 100644 index 7ce5667e..00000000 --- a/vendor/github.com/d5/tengo/compiler/ast/error_expr.go +++ /dev/null @@ -1,29 +0,0 @@ -package ast - -import ( - "github.com/d5/tengo/compiler/source" -) - -// ErrorExpr represents an error expression -type ErrorExpr struct { - Expr Expr - ErrorPos source.Pos - LParen source.Pos - RParen source.Pos -} - -func (e *ErrorExpr) exprNode() {} - -// Pos returns the position of first character belonging to the node. -func (e *ErrorExpr) Pos() source.Pos { - return e.ErrorPos -} - -// End returns the position of first character immediately after the node. -func (e *ErrorExpr) End() source.Pos { - return e.RParen -} - -func (e *ErrorExpr) String() string { - return "error(" + e.Expr.String() + ")" -} diff --git a/vendor/github.com/d5/tengo/compiler/ast/export_stmt.go b/vendor/github.com/d5/tengo/compiler/ast/export_stmt.go deleted file mode 100644 index 64eb7606..00000000 --- a/vendor/github.com/d5/tengo/compiler/ast/export_stmt.go +++ /dev/null @@ -1,27 +0,0 @@ -package ast - -import ( - "github.com/d5/tengo/compiler/source" -) - -// ExportStmt represents an export statement. -type ExportStmt struct { - ExportPos source.Pos - Result Expr -} - -func (s *ExportStmt) stmtNode() {} - -// Pos returns the position of first character belonging to the node. -func (s *ExportStmt) Pos() source.Pos { - return s.ExportPos -} - -// End returns the position of first character immediately after the node. -func (s *ExportStmt) End() source.Pos { - return s.Result.End() -} - -func (s *ExportStmt) String() string { - return "export " + s.Result.String() -} diff --git a/vendor/github.com/d5/tengo/compiler/ast/expr.go b/vendor/github.com/d5/tengo/compiler/ast/expr.go deleted file mode 100644 index 764bacec..00000000 --- a/vendor/github.com/d5/tengo/compiler/ast/expr.go +++ /dev/null @@ -1,7 +0,0 @@ -package ast - -// Expr represents an expression node in the AST. -type Expr interface { - Node - exprNode() -} diff --git a/vendor/github.com/d5/tengo/compiler/ast/expr_stmt.go b/vendor/github.com/d5/tengo/compiler/ast/expr_stmt.go deleted file mode 100644 index 095a3ad5..00000000 --- a/vendor/github.com/d5/tengo/compiler/ast/expr_stmt.go +++ /dev/null @@ -1,24 +0,0 @@ -package ast - -import "github.com/d5/tengo/compiler/source" - -// ExprStmt represents an expression statement. -type ExprStmt struct { - Expr Expr -} - -func (s *ExprStmt) stmtNode() {} - -// Pos returns the position of first character belonging to the node. -func (s *ExprStmt) Pos() source.Pos { - return s.Expr.Pos() -} - -// End returns the position of first character immediately after the node. -func (s *ExprStmt) End() source.Pos { - return s.Expr.End() -} - -func (s *ExprStmt) String() string { - return s.Expr.String() -} diff --git a/vendor/github.com/d5/tengo/compiler/ast/file.go b/vendor/github.com/d5/tengo/compiler/ast/file.go deleted file mode 100644 index fc18b2d7..00000000 --- a/vendor/github.com/d5/tengo/compiler/ast/file.go +++ /dev/null @@ -1,32 +0,0 @@ -package ast - -import ( - "strings" - - "github.com/d5/tengo/compiler/source" -) - -// File represents a file unit. -type File struct { - InputFile *source.File - Stmts []Stmt -} - -// Pos returns the position of first character belonging to the node. -func (n *File) Pos() source.Pos { - return source.Pos(n.InputFile.Base) -} - -// End returns the position of first character immediately after the node. -func (n *File) End() source.Pos { - return source.Pos(n.InputFile.Base + n.InputFile.Size) -} - -func (n *File) String() string { - var stmts []string - for _, e := range n.Stmts { - stmts = append(stmts, e.String()) - } - - return strings.Join(stmts, "; ") -} diff --git a/vendor/github.com/d5/tengo/compiler/ast/float_lit.go b/vendor/github.com/d5/tengo/compiler/ast/float_lit.go deleted file mode 100644 index 670f744b..00000000 --- a/vendor/github.com/d5/tengo/compiler/ast/float_lit.go +++ /dev/null @@ -1,26 +0,0 @@ -package ast - -import "github.com/d5/tengo/compiler/source" - -// FloatLit represents a floating point literal. -type FloatLit struct { - Value float64 - ValuePos source.Pos - Literal string -} - -func (e *FloatLit) exprNode() {} - -// Pos returns the position of first character belonging to the node. -func (e *FloatLit) Pos() source.Pos { - return e.ValuePos -} - -// End returns the position of first character immediately after the node. -func (e *FloatLit) End() source.Pos { - return source.Pos(int(e.ValuePos) + len(e.Literal)) -} - -func (e *FloatLit) String() string { - return e.Literal -} diff --git a/vendor/github.com/d5/tengo/compiler/ast/for_in_stmt.go b/vendor/github.com/d5/tengo/compiler/ast/for_in_stmt.go deleted file mode 100644 index 18020b56..00000000 --- a/vendor/github.com/d5/tengo/compiler/ast/for_in_stmt.go +++ /dev/null @@ -1,32 +0,0 @@ -package ast - -import "github.com/d5/tengo/compiler/source" - -// ForInStmt represents a for-in statement. -type ForInStmt struct { - ForPos source.Pos - Key *Ident - Value *Ident - Iterable Expr - Body *BlockStmt -} - -func (s *ForInStmt) stmtNode() {} - -// Pos returns the position of first character belonging to the node. -func (s *ForInStmt) Pos() source.Pos { - return s.ForPos -} - -// End returns the position of first character immediately after the node. -func (s *ForInStmt) End() source.Pos { - return s.Body.End() -} - -func (s *ForInStmt) String() string { - if s.Value != nil { - return "for " + s.Key.String() + ", " + s.Value.String() + " in " + s.Iterable.String() + " " + s.Body.String() - } - - return "for " + s.Key.String() + " in " + s.Iterable.String() + " " + s.Body.String() -} diff --git a/vendor/github.com/d5/tengo/compiler/ast/for_stmt.go b/vendor/github.com/d5/tengo/compiler/ast/for_stmt.go deleted file mode 100644 index 4b5a0a17..00000000 --- a/vendor/github.com/d5/tengo/compiler/ast/for_stmt.go +++ /dev/null @@ -1,43 +0,0 @@ -package ast - -import "github.com/d5/tengo/compiler/source" - -// ForStmt represents a for statement. -type ForStmt struct { - ForPos source.Pos - Init Stmt - Cond Expr - Post Stmt - Body *BlockStmt -} - -func (s *ForStmt) stmtNode() {} - -// Pos returns the position of first character belonging to the node. -func (s *ForStmt) Pos() source.Pos { - return s.ForPos -} - -// End returns the position of first character immediately after the node. -func (s *ForStmt) End() source.Pos { - return s.Body.End() -} - -func (s *ForStmt) String() string { - var init, cond, post string - if s.Init != nil { - init = s.Init.String() - } - if s.Cond != nil { - cond = s.Cond.String() + " " - } - if s.Post != nil { - post = s.Post.String() - } - - if init != "" || post != "" { - return "for " + init + " ; " + cond + " ; " + post + s.Body.String() - } - - return "for " + cond + s.Body.String() -} diff --git a/vendor/github.com/d5/tengo/compiler/ast/func_lit.go b/vendor/github.com/d5/tengo/compiler/ast/func_lit.go deleted file mode 100644 index 2e90ed2b..00000000 --- a/vendor/github.com/d5/tengo/compiler/ast/func_lit.go +++ /dev/null @@ -1,25 +0,0 @@ -package ast - -import "github.com/d5/tengo/compiler/source" - -// FuncLit represents a function literal. -type FuncLit struct { - Type *FuncType - Body *BlockStmt -} - -func (e *FuncLit) exprNode() {} - -// Pos returns the position of first character belonging to the node. -func (e *FuncLit) Pos() source.Pos { - return e.Type.Pos() -} - -// End returns the position of first character immediately after the node. -func (e *FuncLit) End() source.Pos { - return e.Body.End() -} - -func (e *FuncLit) String() string { - return "func" + e.Type.Params.String() + " " + e.Body.String() -} diff --git a/vendor/github.com/d5/tengo/compiler/ast/func_type.go b/vendor/github.com/d5/tengo/compiler/ast/func_type.go deleted file mode 100644 index 2afaabb1..00000000 --- a/vendor/github.com/d5/tengo/compiler/ast/func_type.go +++ /dev/null @@ -1,25 +0,0 @@ -package ast - -import "github.com/d5/tengo/compiler/source" - -// FuncType represents a function type definition. -type FuncType struct { - FuncPos source.Pos - Params *IdentList -} - -func (e *FuncType) exprNode() {} - -// Pos returns the position of first character belonging to the node. -func (e *FuncType) Pos() source.Pos { - return e.FuncPos -} - -// End returns the position of first character immediately after the node. -func (e *FuncType) End() source.Pos { - return e.Params.End() -} - -func (e *FuncType) String() string { - return "func" + e.Params.String() -} diff --git a/vendor/github.com/d5/tengo/compiler/ast/ident.go b/vendor/github.com/d5/tengo/compiler/ast/ident.go deleted file mode 100644 index 33b7ff76..00000000 --- a/vendor/github.com/d5/tengo/compiler/ast/ident.go +++ /dev/null @@ -1,29 +0,0 @@ -package ast - -import "github.com/d5/tengo/compiler/source" - -// Ident represents an identifier. -type Ident struct { - Name string - NamePos source.Pos -} - -func (e *Ident) exprNode() {} - -// Pos returns the position of first character belonging to the node. -func (e *Ident) Pos() source.Pos { - return e.NamePos -} - -// End returns the position of first character immediately after the node. -func (e *Ident) End() source.Pos { - return source.Pos(int(e.NamePos) + len(e.Name)) -} - -func (e *Ident) String() string { - if e != nil { - return e.Name - } - - return nullRep -} diff --git a/vendor/github.com/d5/tengo/compiler/ast/ident_list.go b/vendor/github.com/d5/tengo/compiler/ast/ident_list.go deleted file mode 100644 index 8dd6d307..00000000 --- a/vendor/github.com/d5/tengo/compiler/ast/ident_list.go +++ /dev/null @@ -1,63 +0,0 @@ -package ast - -import ( - "strings" - - "github.com/d5/tengo/compiler/source" -) - -// IdentList represents a list of identifiers. -type IdentList struct { - LParen source.Pos - VarArgs bool - List []*Ident - RParen source.Pos -} - -// Pos returns the position of first character belonging to the node. -func (n *IdentList) Pos() source.Pos { - if n.LParen.IsValid() { - return n.LParen - } - - if len(n.List) > 0 { - return n.List[0].Pos() - } - - return source.NoPos -} - -// End returns the position of first character immediately after the node. -func (n *IdentList) End() source.Pos { - if n.RParen.IsValid() { - return n.RParen + 1 - } - - if l := len(n.List); l > 0 { - return n.List[l-1].End() - } - - return source.NoPos -} - -// NumFields returns the number of fields. -func (n *IdentList) NumFields() int { - if n == nil { - return 0 - } - - return len(n.List) -} - -func (n *IdentList) String() string { - var list []string - for i, e := range n.List { - if n.VarArgs && i == len(n.List)-1 { - list = append(list, "..."+e.String()) - } else { - list = append(list, e.String()) - } - } - - return "(" + strings.Join(list, ", ") + ")" -} diff --git a/vendor/github.com/d5/tengo/compiler/ast/if_stmt.go b/vendor/github.com/d5/tengo/compiler/ast/if_stmt.go deleted file mode 100644 index b3d65606..00000000 --- a/vendor/github.com/d5/tengo/compiler/ast/if_stmt.go +++ /dev/null @@ -1,40 +0,0 @@ -package ast - -import "github.com/d5/tengo/compiler/source" - -// IfStmt represents an if statement. -type IfStmt struct { - IfPos source.Pos - Init Stmt - Cond Expr - Body *BlockStmt - Else Stmt // else branch; or nil -} - -func (s *IfStmt) stmtNode() {} - -// Pos returns the position of first character belonging to the node. -func (s *IfStmt) Pos() source.Pos { - return s.IfPos -} - -// End returns the position of first character immediately after the node. -func (s *IfStmt) End() source.Pos { - if s.Else != nil { - return s.Else.End() - } - - return s.Body.End() -} - -func (s *IfStmt) String() string { - var initStmt, elseStmt string - if s.Init != nil { - initStmt = s.Init.String() + "; " - } - if s.Else != nil { - elseStmt = " else " + s.Else.String() - } - - return "if " + initStmt + s.Cond.String() + " " + s.Body.String() + elseStmt -} diff --git a/vendor/github.com/d5/tengo/compiler/ast/immutable_expr.go b/vendor/github.com/d5/tengo/compiler/ast/immutable_expr.go deleted file mode 100644 index f9843b50..00000000 --- a/vendor/github.com/d5/tengo/compiler/ast/immutable_expr.go +++ /dev/null @@ -1,29 +0,0 @@ -package ast - -import ( - "github.com/d5/tengo/compiler/source" -) - -// ImmutableExpr represents an immutable expression -type ImmutableExpr struct { - Expr Expr - ErrorPos source.Pos - LParen source.Pos - RParen source.Pos -} - -func (e *ImmutableExpr) exprNode() {} - -// Pos returns the position of first character belonging to the node. -func (e *ImmutableExpr) Pos() source.Pos { - return e.ErrorPos -} - -// End returns the position of first character immediately after the node. -func (e *ImmutableExpr) End() source.Pos { - return e.RParen -} - -func (e *ImmutableExpr) String() string { - return "immutable(" + e.Expr.String() + ")" -} diff --git a/vendor/github.com/d5/tengo/compiler/ast/import_expr.go b/vendor/github.com/d5/tengo/compiler/ast/import_expr.go deleted file mode 100644 index 6eff74a9..00000000 --- a/vendor/github.com/d5/tengo/compiler/ast/import_expr.go +++ /dev/null @@ -1,29 +0,0 @@ -package ast - -import ( - "github.com/d5/tengo/compiler/source" - "github.com/d5/tengo/compiler/token" -) - -// ImportExpr represents an import expression -type ImportExpr struct { - ModuleName string - Token token.Token - TokenPos source.Pos -} - -func (e *ImportExpr) exprNode() {} - -// Pos returns the position of first character belonging to the node. -func (e *ImportExpr) Pos() source.Pos { - return e.TokenPos -} - -// End returns the position of first character immediately after the node. -func (e *ImportExpr) End() source.Pos { - return source.Pos(int(e.TokenPos) + 10 + len(e.ModuleName)) // import("moduleName") -} - -func (e *ImportExpr) String() string { - return `import("` + e.ModuleName + `")"` -} diff --git a/vendor/github.com/d5/tengo/compiler/ast/inc_dec_stmt.go b/vendor/github.com/d5/tengo/compiler/ast/inc_dec_stmt.go deleted file mode 100644 index e4e7f92c..00000000 --- a/vendor/github.com/d5/tengo/compiler/ast/inc_dec_stmt.go +++ /dev/null @@ -1,29 +0,0 @@ -package ast - -import ( - "github.com/d5/tengo/compiler/source" - "github.com/d5/tengo/compiler/token" -) - -// IncDecStmt represents increment or decrement statement. -type IncDecStmt struct { - Expr Expr - Token token.Token - TokenPos source.Pos -} - -func (s *IncDecStmt) stmtNode() {} - -// Pos returns the position of first character belonging to the node. -func (s *IncDecStmt) Pos() source.Pos { - return s.Expr.Pos() -} - -// End returns the position of first character immediately after the node. -func (s *IncDecStmt) End() source.Pos { - return source.Pos(int(s.TokenPos) + 2) -} - -func (s *IncDecStmt) String() string { - return s.Expr.String() + s.Token.String() -} diff --git a/vendor/github.com/d5/tengo/compiler/ast/index_expr.go b/vendor/github.com/d5/tengo/compiler/ast/index_expr.go deleted file mode 100644 index bc0992a3..00000000 --- a/vendor/github.com/d5/tengo/compiler/ast/index_expr.go +++ /dev/null @@ -1,32 +0,0 @@ -package ast - -import "github.com/d5/tengo/compiler/source" - -// IndexExpr represents an index expression. -type IndexExpr struct { - Expr Expr - LBrack source.Pos - Index Expr - RBrack source.Pos -} - -func (e *IndexExpr) exprNode() {} - -// Pos returns the position of first character belonging to the node. -func (e *IndexExpr) Pos() source.Pos { - return e.Expr.Pos() -} - -// End returns the position of first character immediately after the node. -func (e *IndexExpr) End() source.Pos { - return e.RBrack + 1 -} - -func (e *IndexExpr) String() string { - var index string - if e.Index != nil { - index = e.Index.String() - } - - return e.Expr.String() + "[" + index + "]" -} diff --git a/vendor/github.com/d5/tengo/compiler/ast/int_lit.go b/vendor/github.com/d5/tengo/compiler/ast/int_lit.go deleted file mode 100644 index 3e1fd98b..00000000 --- a/vendor/github.com/d5/tengo/compiler/ast/int_lit.go +++ /dev/null @@ -1,26 +0,0 @@ -package ast - -import "github.com/d5/tengo/compiler/source" - -// IntLit represents an integer literal. -type IntLit struct { - Value int64 - ValuePos source.Pos - Literal string -} - -func (e *IntLit) exprNode() {} - -// Pos returns the position of first character belonging to the node. -func (e *IntLit) Pos() source.Pos { - return e.ValuePos -} - -// End returns the position of first character immediately after the node. -func (e *IntLit) End() source.Pos { - return source.Pos(int(e.ValuePos) + len(e.Literal)) -} - -func (e *IntLit) String() string { - return e.Literal -} diff --git a/vendor/github.com/d5/tengo/compiler/ast/map_element_lit.go b/vendor/github.com/d5/tengo/compiler/ast/map_element_lit.go deleted file mode 100644 index 3d7fca9e..00000000 --- a/vendor/github.com/d5/tengo/compiler/ast/map_element_lit.go +++ /dev/null @@ -1,27 +0,0 @@ -package ast - -import "github.com/d5/tengo/compiler/source" - -// MapElementLit represents a map element. -type MapElementLit struct { - Key string - KeyPos source.Pos - ColonPos source.Pos - Value Expr -} - -func (e *MapElementLit) exprNode() {} - -// Pos returns the position of first character belonging to the node. -func (e *MapElementLit) Pos() source.Pos { - return e.KeyPos -} - -// End returns the position of first character immediately after the node. -func (e *MapElementLit) End() source.Pos { - return e.Value.End() -} - -func (e *MapElementLit) String() string { - return e.Key + ": " + e.Value.String() -} diff --git a/vendor/github.com/d5/tengo/compiler/ast/map_lit.go b/vendor/github.com/d5/tengo/compiler/ast/map_lit.go deleted file mode 100644 index a228224d..00000000 --- a/vendor/github.com/d5/tengo/compiler/ast/map_lit.go +++ /dev/null @@ -1,35 +0,0 @@ -package ast - -import ( - "strings" - - "github.com/d5/tengo/compiler/source" -) - -// MapLit represents a map literal. -type MapLit struct { - LBrace source.Pos - Elements []*MapElementLit - RBrace source.Pos -} - -func (e *MapLit) exprNode() {} - -// Pos returns the position of first character belonging to the node. -func (e *MapLit) Pos() source.Pos { - return e.LBrace -} - -// End returns the position of first character immediately after the node. -func (e *MapLit) End() source.Pos { - return e.RBrace + 1 -} - -func (e *MapLit) String() string { - var elements []string - for _, m := range e.Elements { - elements = append(elements, m.String()) - } - - return "{" + strings.Join(elements, ", ") + "}" -} diff --git a/vendor/github.com/d5/tengo/compiler/ast/node.go b/vendor/github.com/d5/tengo/compiler/ast/node.go deleted file mode 100644 index 44677b47..00000000 --- a/vendor/github.com/d5/tengo/compiler/ast/node.go +++ /dev/null @@ -1,13 +0,0 @@ -package ast - -import "github.com/d5/tengo/compiler/source" - -// Node represents a node in the AST. -type Node interface { - // Pos returns the position of first character belonging to the node. - Pos() source.Pos - // End returns the position of first character immediately after the node. - End() source.Pos - // String returns a string representation of the node. - String() string -} diff --git a/vendor/github.com/d5/tengo/compiler/ast/paren_expr.go b/vendor/github.com/d5/tengo/compiler/ast/paren_expr.go deleted file mode 100644 index 8db4ac02..00000000 --- a/vendor/github.com/d5/tengo/compiler/ast/paren_expr.go +++ /dev/null @@ -1,26 +0,0 @@ -package ast - -import "github.com/d5/tengo/compiler/source" - -// ParenExpr represents a parenthesis wrapped expression. -type ParenExpr struct { - Expr Expr - LParen source.Pos - RParen source.Pos -} - -func (e *ParenExpr) exprNode() {} - -// Pos returns the position of first character belonging to the node. -func (e *ParenExpr) Pos() source.Pos { - return e.LParen -} - -// End returns the position of first character immediately after the node. -func (e *ParenExpr) End() source.Pos { - return e.RParen + 1 -} - -func (e *ParenExpr) String() string { - return "(" + e.Expr.String() + ")" -} diff --git a/vendor/github.com/d5/tengo/compiler/ast/return_stmt.go b/vendor/github.com/d5/tengo/compiler/ast/return_stmt.go deleted file mode 100644 index 592d45b8..00000000 --- a/vendor/github.com/d5/tengo/compiler/ast/return_stmt.go +++ /dev/null @@ -1,35 +0,0 @@ -package ast - -import ( - "github.com/d5/tengo/compiler/source" -) - -// ReturnStmt represents a return statement. -type ReturnStmt struct { - ReturnPos source.Pos - Result Expr -} - -func (s *ReturnStmt) stmtNode() {} - -// Pos returns the position of first character belonging to the node. -func (s *ReturnStmt) Pos() source.Pos { - return s.ReturnPos -} - -// End returns the position of first character immediately after the node. -func (s *ReturnStmt) End() source.Pos { - if s.Result != nil { - return s.Result.End() - } - - return s.ReturnPos + 6 -} - -func (s *ReturnStmt) String() string { - if s.Result != nil { - return "return " + s.Result.String() - } - - return "return" -} diff --git a/vendor/github.com/d5/tengo/compiler/ast/selector_expr.go b/vendor/github.com/d5/tengo/compiler/ast/selector_expr.go deleted file mode 100644 index 31d2e6d1..00000000 --- a/vendor/github.com/d5/tengo/compiler/ast/selector_expr.go +++ /dev/null @@ -1,25 +0,0 @@ -package ast - -import "github.com/d5/tengo/compiler/source" - -// SelectorExpr represents a selector expression. -type SelectorExpr struct { - Expr Expr - Sel Expr -} - -func (e *SelectorExpr) exprNode() {} - -// Pos returns the position of first character belonging to the node. -func (e *SelectorExpr) Pos() source.Pos { - return e.Expr.Pos() -} - -// End returns the position of first character immediately after the node. -func (e *SelectorExpr) End() source.Pos { - return e.Sel.End() -} - -func (e *SelectorExpr) String() string { - return e.Expr.String() + "." + e.Sel.String() -} diff --git a/vendor/github.com/d5/tengo/compiler/ast/slice_expr.go b/vendor/github.com/d5/tengo/compiler/ast/slice_expr.go deleted file mode 100644 index e7e2e05b..00000000 --- a/vendor/github.com/d5/tengo/compiler/ast/slice_expr.go +++ /dev/null @@ -1,36 +0,0 @@ -package ast - -import "github.com/d5/tengo/compiler/source" - -// SliceExpr represents a slice expression. -type SliceExpr struct { - Expr Expr - LBrack source.Pos - Low Expr - High Expr - RBrack source.Pos -} - -func (e *SliceExpr) exprNode() {} - -// Pos returns the position of first character belonging to the node. -func (e *SliceExpr) Pos() source.Pos { - return e.Expr.Pos() -} - -// End returns the position of first character immediately after the node. -func (e *SliceExpr) End() source.Pos { - return e.RBrack + 1 -} - -func (e *SliceExpr) String() string { - var low, high string - if e.Low != nil { - low = e.Low.String() - } - if e.High != nil { - high = e.High.String() - } - - return e.Expr.String() + "[" + low + ":" + high + "]" -} diff --git a/vendor/github.com/d5/tengo/compiler/ast/stmt.go b/vendor/github.com/d5/tengo/compiler/ast/stmt.go deleted file mode 100644 index 6b26ba88..00000000 --- a/vendor/github.com/d5/tengo/compiler/ast/stmt.go +++ /dev/null @@ -1,7 +0,0 @@ -package ast - -// Stmt represents a statement in the AST. -type Stmt interface { - Node - stmtNode() -} diff --git a/vendor/github.com/d5/tengo/compiler/ast/string_lit.go b/vendor/github.com/d5/tengo/compiler/ast/string_lit.go deleted file mode 100644 index 2119d34b..00000000 --- a/vendor/github.com/d5/tengo/compiler/ast/string_lit.go +++ /dev/null @@ -1,26 +0,0 @@ -package ast - -import "github.com/d5/tengo/compiler/source" - -// StringLit represents a string literal. -type StringLit struct { - Value string - ValuePos source.Pos - Literal string -} - -func (e *StringLit) exprNode() {} - -// Pos returns the position of first character belonging to the node. -func (e *StringLit) Pos() source.Pos { - return e.ValuePos -} - -// End returns the position of first character immediately after the node. -func (e *StringLit) End() source.Pos { - return source.Pos(int(e.ValuePos) + len(e.Literal)) -} - -func (e *StringLit) String() string { - return e.Literal -} diff --git a/vendor/github.com/d5/tengo/compiler/ast/unary_expr.go b/vendor/github.com/d5/tengo/compiler/ast/unary_expr.go deleted file mode 100644 index 53236146..00000000 --- a/vendor/github.com/d5/tengo/compiler/ast/unary_expr.go +++ /dev/null @@ -1,29 +0,0 @@ -package ast - -import ( - "github.com/d5/tengo/compiler/source" - "github.com/d5/tengo/compiler/token" -) - -// UnaryExpr represents an unary operator expression. -type UnaryExpr struct { - Expr Expr - Token token.Token - TokenPos source.Pos -} - -func (e *UnaryExpr) exprNode() {} - -// Pos returns the position of first character belonging to the node. -func (e *UnaryExpr) Pos() source.Pos { - return e.Expr.Pos() -} - -// End returns the position of first character immediately after the node. -func (e *UnaryExpr) End() source.Pos { - return e.Expr.End() -} - -func (e *UnaryExpr) String() string { - return "(" + e.Token.String() + e.Expr.String() + ")" -} diff --git a/vendor/github.com/d5/tengo/compiler/ast/undefined_lit.go b/vendor/github.com/d5/tengo/compiler/ast/undefined_lit.go deleted file mode 100644 index 8e51b113..00000000 --- a/vendor/github.com/d5/tengo/compiler/ast/undefined_lit.go +++ /dev/null @@ -1,24 +0,0 @@ -package ast - -import "github.com/d5/tengo/compiler/source" - -// UndefinedLit represents an undefined literal. -type UndefinedLit struct { - TokenPos source.Pos -} - -func (e *UndefinedLit) exprNode() {} - -// Pos returns the position of first character belonging to the node. -func (e *UndefinedLit) Pos() source.Pos { - return e.TokenPos -} - -// End returns the position of first character immediately after the node. -func (e *UndefinedLit) End() source.Pos { - return e.TokenPos + 9 // len(undefined) == 9 -} - -func (e *UndefinedLit) String() string { - return "undefined" -} diff --git a/vendor/github.com/d5/tengo/compiler/bytecode.go b/vendor/github.com/d5/tengo/compiler/bytecode.go deleted file mode 100644 index 35f36c0a..00000000 --- a/vendor/github.com/d5/tengo/compiler/bytecode.go +++ /dev/null @@ -1,90 +0,0 @@ -package compiler - -import ( - "encoding/gob" - "fmt" - "io" - "reflect" - - "github.com/d5/tengo/compiler/source" - "github.com/d5/tengo/objects" -) - -// Bytecode is a compiled instructions and constants. -type Bytecode struct { - FileSet *source.FileSet - MainFunction *objects.CompiledFunction - Constants []objects.Object -} - -// Encode writes Bytecode data to the writer. -func (b *Bytecode) Encode(w io.Writer) error { - enc := gob.NewEncoder(w) - - if err := enc.Encode(b.FileSet); err != nil { - return err - } - - if err := enc.Encode(b.MainFunction); err != nil { - return err - } - - // constants - return enc.Encode(b.Constants) -} - -// CountObjects returns the number of objects found in Constants. -func (b *Bytecode) CountObjects() int { - n := 0 - - for _, c := range b.Constants { - n += objects.CountObjects(c) - } - - return n -} - -// FormatInstructions returns human readable string representations of -// compiled instructions. -func (b *Bytecode) FormatInstructions() []string { - return FormatInstructions(b.MainFunction.Instructions, 0) -} - -// FormatConstants returns human readable string representations of -// compiled constants. -func (b *Bytecode) FormatConstants() (output []string) { - for cidx, cn := range b.Constants { - switch cn := cn.(type) { - case *objects.CompiledFunction: - output = append(output, fmt.Sprintf("[% 3d] (Compiled Function|%p)", cidx, &cn)) - for _, l := range FormatInstructions(cn.Instructions, 0) { - output = append(output, fmt.Sprintf(" %s", l)) - } - default: - output = append(output, fmt.Sprintf("[% 3d] %s (%s|%p)", cidx, cn, reflect.TypeOf(cn).Elem().Name(), &cn)) - } - } - - return -} - -func init() { - gob.Register(&source.FileSet{}) - gob.Register(&source.File{}) - gob.Register(&objects.Array{}) - gob.Register(&objects.Bool{}) - gob.Register(&objects.Bytes{}) - gob.Register(&objects.Char{}) - gob.Register(&objects.Closure{}) - gob.Register(&objects.CompiledFunction{}) - gob.Register(&objects.Error{}) - gob.Register(&objects.Float{}) - gob.Register(&objects.ImmutableArray{}) - gob.Register(&objects.ImmutableMap{}) - gob.Register(&objects.Int{}) - gob.Register(&objects.Map{}) - gob.Register(&objects.String{}) - gob.Register(&objects.Time{}) - gob.Register(&objects.Undefined{}) - gob.Register(&objects.UserFunction{}) -} diff --git a/vendor/github.com/d5/tengo/compiler/bytecode_decode.go b/vendor/github.com/d5/tengo/compiler/bytecode_decode.go deleted file mode 100644 index b3b32a64..00000000 --- a/vendor/github.com/d5/tengo/compiler/bytecode_decode.go +++ /dev/null @@ -1,97 +0,0 @@ -package compiler - -import ( - "encoding/gob" - "fmt" - "io" - - "github.com/d5/tengo/objects" -) - -// Decode reads Bytecode data from the reader. -func (b *Bytecode) Decode(r io.Reader, modules *objects.ModuleMap) error { - if modules == nil { - modules = objects.NewModuleMap() - } - - dec := gob.NewDecoder(r) - - if err := dec.Decode(&b.FileSet); err != nil { - return err - } - // TODO: files in b.FileSet.File does not have their 'set' field properly set to b.FileSet - // as it's private field and not serialized by gob encoder/decoder. - - if err := dec.Decode(&b.MainFunction); err != nil { - return err - } - - if err := dec.Decode(&b.Constants); err != nil { - return err - } - for i, v := range b.Constants { - fv, err := fixDecoded(v, modules) - if err != nil { - return err - } - b.Constants[i] = fv - } - - return nil -} - -func fixDecoded(o objects.Object, modules *objects.ModuleMap) (objects.Object, error) { - switch o := o.(type) { - case *objects.Bool: - if o.IsFalsy() { - return objects.FalseValue, nil - } - return objects.TrueValue, nil - case *objects.Undefined: - return objects.UndefinedValue, nil - case *objects.Array: - for i, v := range o.Value { - fv, err := fixDecoded(v, modules) - if err != nil { - return nil, err - } - o.Value[i] = fv - } - case *objects.ImmutableArray: - for i, v := range o.Value { - fv, err := fixDecoded(v, modules) - if err != nil { - return nil, err - } - o.Value[i] = fv - } - case *objects.Map: - for k, v := range o.Value { - fv, err := fixDecoded(v, modules) - if err != nil { - return nil, err - } - o.Value[k] = fv - } - case *objects.ImmutableMap: - modName := moduleName(o) - if mod := modules.GetBuiltinModule(modName); mod != nil { - return mod.AsImmutableMap(modName), nil - } - - for k, v := range o.Value { - // encoding of user function not supported - if _, isUserFunction := v.(*objects.UserFunction); isUserFunction { - return nil, fmt.Errorf("user function not decodable") - } - - fv, err := fixDecoded(v, modules) - if err != nil { - return nil, err - } - o.Value[k] = fv - } - } - - return o, nil -} diff --git a/vendor/github.com/d5/tengo/compiler/bytecode_optimize.go b/vendor/github.com/d5/tengo/compiler/bytecode_optimize.go deleted file mode 100644 index 9526de2e..00000000 --- a/vendor/github.com/d5/tengo/compiler/bytecode_optimize.go +++ /dev/null @@ -1,129 +0,0 @@ -package compiler - -import ( - "fmt" - - "github.com/d5/tengo/objects" -) - -// RemoveDuplicates finds and remove the duplicate values in Constants. -// Note this function mutates Bytecode. -func (b *Bytecode) RemoveDuplicates() { - var deduped []objects.Object - - indexMap := make(map[int]int) // mapping from old constant index to new index - ints := make(map[int64]int) - strings := make(map[string]int) - floats := make(map[float64]int) - chars := make(map[rune]int) - immutableMaps := make(map[string]int) // for modules - - for curIdx, c := range b.Constants { - switch c := c.(type) { - case *objects.CompiledFunction: - // add to deduped list - indexMap[curIdx] = len(deduped) - deduped = append(deduped, c) - case *objects.ImmutableMap: - modName := moduleName(c) - newIdx, ok := immutableMaps[modName] - if modName != "" && ok { - indexMap[curIdx] = newIdx - } else { - newIdx = len(deduped) - immutableMaps[modName] = newIdx - indexMap[curIdx] = newIdx - deduped = append(deduped, c) - } - case *objects.Int: - if newIdx, ok := ints[c.Value]; ok { - indexMap[curIdx] = newIdx - } else { - newIdx = len(deduped) - ints[c.Value] = newIdx - indexMap[curIdx] = newIdx - deduped = append(deduped, c) - } - case *objects.String: - if newIdx, ok := strings[c.Value]; ok { - indexMap[curIdx] = newIdx - } else { - newIdx = len(deduped) - strings[c.Value] = newIdx - indexMap[curIdx] = newIdx - deduped = append(deduped, c) - } - case *objects.Float: - if newIdx, ok := floats[c.Value]; ok { - indexMap[curIdx] = newIdx - } else { - newIdx = len(deduped) - floats[c.Value] = newIdx - indexMap[curIdx] = newIdx - deduped = append(deduped, c) - } - case *objects.Char: - if newIdx, ok := chars[c.Value]; ok { - indexMap[curIdx] = newIdx - } else { - newIdx = len(deduped) - chars[c.Value] = newIdx - indexMap[curIdx] = newIdx - deduped = append(deduped, c) - } - default: - panic(fmt.Errorf("unsupported top-level constant type: %s", c.TypeName())) - } - } - - // replace with de-duplicated constants - b.Constants = deduped - - // update CONST instructions with new indexes - // main function - updateConstIndexes(b.MainFunction.Instructions, indexMap) - // other compiled functions in constants - for _, c := range b.Constants { - switch c := c.(type) { - case *objects.CompiledFunction: - updateConstIndexes(c.Instructions, indexMap) - } - } -} - -func updateConstIndexes(insts []byte, indexMap map[int]int) { - i := 0 - for i < len(insts) { - op := insts[i] - numOperands := OpcodeOperands[op] - _, read := ReadOperands(numOperands, insts[i+1:]) - - switch op { - case OpConstant: - curIdx := int(insts[i+2]) | int(insts[i+1])<<8 - newIdx, ok := indexMap[curIdx] - if !ok { - panic(fmt.Errorf("constant index not found: %d", curIdx)) - } - copy(insts[i:], MakeInstruction(op, newIdx)) - case OpClosure: - curIdx := int(insts[i+2]) | int(insts[i+1])<<8 - numFree := int(insts[i+3]) - newIdx, ok := indexMap[curIdx] - if !ok { - panic(fmt.Errorf("constant index not found: %d", curIdx)) - } - copy(insts[i:], MakeInstruction(op, newIdx, numFree)) - } - - i += 1 + read - } -} - -func moduleName(mod *objects.ImmutableMap) string { - if modName, ok := mod.Value["__module_name__"].(*objects.String); ok { - return modName.Value - } - - return "" -} diff --git a/vendor/github.com/d5/tengo/compiler/compilation_scope.go b/vendor/github.com/d5/tengo/compiler/compilation_scope.go deleted file mode 100644 index 41e7876b..00000000 --- a/vendor/github.com/d5/tengo/compiler/compilation_scope.go +++ /dev/null @@ -1,11 +0,0 @@ -package compiler - -import "github.com/d5/tengo/compiler/source" - -// CompilationScope represents a compiled instructions -// and the last two instructions that were emitted. -type CompilationScope struct { - instructions []byte - symbolInit map[string]bool - sourceMap map[int]source.Pos -} diff --git a/vendor/github.com/d5/tengo/compiler/compiler.go b/vendor/github.com/d5/tengo/compiler/compiler.go deleted file mode 100644 index 8bde5dc9..00000000 --- a/vendor/github.com/d5/tengo/compiler/compiler.go +++ /dev/null @@ -1,846 +0,0 @@ -package compiler - -import ( - "fmt" - "io" - "io/ioutil" - "path/filepath" - "reflect" - "strings" - - "github.com/d5/tengo" - "github.com/d5/tengo/compiler/ast" - "github.com/d5/tengo/compiler/source" - "github.com/d5/tengo/compiler/token" - "github.com/d5/tengo/objects" -) - -// Compiler compiles the AST into a bytecode. -type Compiler struct { - file *source.File - parent *Compiler - modulePath string - constants []objects.Object - symbolTable *SymbolTable - scopes []CompilationScope - scopeIndex int - modules *objects.ModuleMap - compiledModules map[string]*objects.CompiledFunction - allowFileImport bool - loops []*Loop - loopIndex int - trace io.Writer - indent int -} - -// NewCompiler creates a Compiler. -func NewCompiler(file *source.File, symbolTable *SymbolTable, constants []objects.Object, modules *objects.ModuleMap, trace io.Writer) *Compiler { - mainScope := CompilationScope{ - symbolInit: make(map[string]bool), - sourceMap: make(map[int]source.Pos), - } - - // symbol table - if symbolTable == nil { - symbolTable = NewSymbolTable() - } - - // add builtin functions to the symbol table - for idx, fn := range objects.Builtins { - symbolTable.DefineBuiltin(idx, fn.Name) - } - - // builtin modules - if modules == nil { - modules = objects.NewModuleMap() - } - - return &Compiler{ - file: file, - symbolTable: symbolTable, - constants: constants, - scopes: []CompilationScope{mainScope}, - scopeIndex: 0, - loopIndex: -1, - trace: trace, - modules: modules, - compiledModules: make(map[string]*objects.CompiledFunction), - } -} - -// Compile compiles the AST node. -func (c *Compiler) Compile(node ast.Node) error { - if c.trace != nil { - if node != nil { - defer un(trace(c, fmt.Sprintf("%s (%s)", node.String(), reflect.TypeOf(node).Elem().Name()))) - } else { - defer un(trace(c, "<nil>")) - } - } - - switch node := node.(type) { - case *ast.File: - for _, stmt := range node.Stmts { - if err := c.Compile(stmt); err != nil { - return err - } - } - - case *ast.ExprStmt: - if err := c.Compile(node.Expr); err != nil { - return err - } - c.emit(node, OpPop) - - case *ast.IncDecStmt: - op := token.AddAssign - if node.Token == token.Dec { - op = token.SubAssign - } - - return c.compileAssign(node, []ast.Expr{node.Expr}, []ast.Expr{&ast.IntLit{Value: 1}}, op) - - case *ast.ParenExpr: - if err := c.Compile(node.Expr); err != nil { - return err - } - - case *ast.BinaryExpr: - if node.Token == token.LAnd || node.Token == token.LOr { - return c.compileLogical(node) - } - - if node.Token == token.Less { - if err := c.Compile(node.RHS); err != nil { - return err - } - - if err := c.Compile(node.LHS); err != nil { - return err - } - - c.emit(node, OpBinaryOp, int(token.Greater)) - - return nil - } else if node.Token == token.LessEq { - if err := c.Compile(node.RHS); err != nil { - return err - } - if err := c.Compile(node.LHS); err != nil { - return err - } - - c.emit(node, OpBinaryOp, int(token.GreaterEq)) - - return nil - } - - if err := c.Compile(node.LHS); err != nil { - return err - } - if err := c.Compile(node.RHS); err != nil { - return err - } - - switch node.Token { - case token.Add: - c.emit(node, OpBinaryOp, int(token.Add)) - case token.Sub: - c.emit(node, OpBinaryOp, int(token.Sub)) - case token.Mul: - c.emit(node, OpBinaryOp, int(token.Mul)) - case token.Quo: - c.emit(node, OpBinaryOp, int(token.Quo)) - case token.Rem: - c.emit(node, OpBinaryOp, int(token.Rem)) - case token.Greater: - c.emit(node, OpBinaryOp, int(token.Greater)) - case token.GreaterEq: - c.emit(node, OpBinaryOp, int(token.GreaterEq)) - case token.Equal: - c.emit(node, OpEqual) - case token.NotEqual: - c.emit(node, OpNotEqual) - case token.And: - c.emit(node, OpBinaryOp, int(token.And)) - case token.Or: - c.emit(node, OpBinaryOp, int(token.Or)) - case token.Xor: - c.emit(node, OpBinaryOp, int(token.Xor)) - case token.AndNot: - c.emit(node, OpBinaryOp, int(token.AndNot)) - case token.Shl: - c.emit(node, OpBinaryOp, int(token.Shl)) - case token.Shr: - c.emit(node, OpBinaryOp, int(token.Shr)) - default: - return c.errorf(node, "invalid binary operator: %s", node.Token.String()) - } - - case *ast.IntLit: - c.emit(node, OpConstant, c.addConstant(&objects.Int{Value: node.Value})) - - case *ast.FloatLit: - c.emit(node, OpConstant, c.addConstant(&objects.Float{Value: node.Value})) - - case *ast.BoolLit: - if node.Value { - c.emit(node, OpTrue) - } else { - c.emit(node, OpFalse) - } - - case *ast.StringLit: - if len(node.Value) > tengo.MaxStringLen { - return c.error(node, objects.ErrStringLimit) - } - - c.emit(node, OpConstant, c.addConstant(&objects.String{Value: node.Value})) - - case *ast.CharLit: - c.emit(node, OpConstant, c.addConstant(&objects.Char{Value: node.Value})) - - case *ast.UndefinedLit: - c.emit(node, OpNull) - - case *ast.UnaryExpr: - if err := c.Compile(node.Expr); err != nil { - return err - } - - switch node.Token { - case token.Not: - c.emit(node, OpLNot) - case token.Sub: - c.emit(node, OpMinus) - case token.Xor: - c.emit(node, OpBComplement) - case token.Add: - // do nothing? - default: - return c.errorf(node, "invalid unary operator: %s", node.Token.String()) - } - - case *ast.IfStmt: - // open new symbol table for the statement - c.symbolTable = c.symbolTable.Fork(true) - defer func() { - c.symbolTable = c.symbolTable.Parent(false) - }() - - if node.Init != nil { - if err := c.Compile(node.Init); err != nil { - return err - } - } - - if err := c.Compile(node.Cond); err != nil { - return err - } - - // first jump placeholder - jumpPos1 := c.emit(node, OpJumpFalsy, 0) - - if err := c.Compile(node.Body); err != nil { - return err - } - - if node.Else != nil { - // second jump placeholder - jumpPos2 := c.emit(node, OpJump, 0) - - // update first jump offset - curPos := len(c.currentInstructions()) - c.changeOperand(jumpPos1, curPos) - - if err := c.Compile(node.Else); err != nil { - return err - } - - // update second jump offset - curPos = len(c.currentInstructions()) - c.changeOperand(jumpPos2, curPos) - } else { - // update first jump offset - curPos := len(c.currentInstructions()) - c.changeOperand(jumpPos1, curPos) - } - - case *ast.ForStmt: - return c.compileForStmt(node) - - case *ast.ForInStmt: - return c.compileForInStmt(node) - - case *ast.BranchStmt: - if node.Token == token.Break { - curLoop := c.currentLoop() - if curLoop == nil { - return c.errorf(node, "break not allowed outside loop") - } - pos := c.emit(node, OpJump, 0) - curLoop.Breaks = append(curLoop.Breaks, pos) - } else if node.Token == token.Continue { - curLoop := c.currentLoop() - if curLoop == nil { - return c.errorf(node, "continue not allowed outside loop") - } - pos := c.emit(node, OpJump, 0) - curLoop.Continues = append(curLoop.Continues, pos) - } else { - panic(fmt.Errorf("invalid branch statement: %s", node.Token.String())) - } - - case *ast.BlockStmt: - if len(node.Stmts) == 0 { - return nil - } - - c.symbolTable = c.symbolTable.Fork(true) - defer func() { - c.symbolTable = c.symbolTable.Parent(false) - }() - - for _, stmt := range node.Stmts { - if err := c.Compile(stmt); err != nil { - return err - } - } - - case *ast.AssignStmt: - if err := c.compileAssign(node, node.LHS, node.RHS, node.Token); err != nil { - return err - } - - case *ast.Ident: - symbol, _, ok := c.symbolTable.Resolve(node.Name) - if !ok { - return c.errorf(node, "unresolved reference '%s'", node.Name) - } - - switch symbol.Scope { - case ScopeGlobal: - c.emit(node, OpGetGlobal, symbol.Index) - case ScopeLocal: - c.emit(node, OpGetLocal, symbol.Index) - case ScopeBuiltin: - c.emit(node, OpGetBuiltin, symbol.Index) - case ScopeFree: - c.emit(node, OpGetFree, symbol.Index) - } - - case *ast.ArrayLit: - for _, elem := range node.Elements { - if err := c.Compile(elem); err != nil { - return err - } - } - - c.emit(node, OpArray, len(node.Elements)) - - case *ast.MapLit: - for _, elt := range node.Elements { - // key - if len(elt.Key) > tengo.MaxStringLen { - return c.error(node, objects.ErrStringLimit) - } - c.emit(node, OpConstant, c.addConstant(&objects.String{Value: elt.Key})) - - // value - if err := c.Compile(elt.Value); err != nil { - return err - } - } - - c.emit(node, OpMap, len(node.Elements)*2) - - case *ast.SelectorExpr: // selector on RHS side - if err := c.Compile(node.Expr); err != nil { - return err - } - - if err := c.Compile(node.Sel); err != nil { - return err - } - - c.emit(node, OpIndex) - - case *ast.IndexExpr: - if err := c.Compile(node.Expr); err != nil { - return err - } - - if err := c.Compile(node.Index); err != nil { - return err - } - - c.emit(node, OpIndex) - - case *ast.SliceExpr: - if err := c.Compile(node.Expr); err != nil { - return err - } - - if node.Low != nil { - if err := c.Compile(node.Low); err != nil { - return err - } - } else { - c.emit(node, OpNull) - } - - if node.High != nil { - if err := c.Compile(node.High); err != nil { - return err - } - } else { - c.emit(node, OpNull) - } - - c.emit(node, OpSliceIndex) - - case *ast.FuncLit: - c.enterScope() - - for _, p := range node.Type.Params.List { - s := c.symbolTable.Define(p.Name) - - // function arguments is not assigned directly. - s.LocalAssigned = true - } - - if err := c.Compile(node.Body); err != nil { - return err - } - - // code optimization - c.optimizeFunc(node) - - freeSymbols := c.symbolTable.FreeSymbols() - numLocals := c.symbolTable.MaxSymbols() - instructions, sourceMap := c.leaveScope() - - for _, s := range freeSymbols { - switch s.Scope { - case ScopeLocal: - if !s.LocalAssigned { - // Here, the closure is capturing a local variable that's not yet assigned its value. - // One example is a local recursive function: - // - // func() { - // foo := func(x) { - // // .. - // return foo(x-1) - // } - // } - // - // which translate into - // - // 0000 GETL 0 - // 0002 CLOSURE ? 1 - // 0006 DEFL 0 - // - // . So the local variable (0) is being captured before it's assigned the value. - // - // Solution is to transform the code into something like this: - // - // func() { - // foo := undefined - // foo = func(x) { - // // .. - // return foo(x-1) - // } - // } - // - // that is equivalent to - // - // 0000 NULL - // 0001 DEFL 0 - // 0003 GETL 0 - // 0005 CLOSURE ? 1 - // 0009 SETL 0 - // - - c.emit(node, OpNull) - c.emit(node, OpDefineLocal, s.Index) - - s.LocalAssigned = true - } - - c.emit(node, OpGetLocalPtr, s.Index) - case ScopeFree: - c.emit(node, OpGetFreePtr, s.Index) - } - } - - compiledFunction := &objects.CompiledFunction{ - Instructions: instructions, - NumLocals: numLocals, - NumParameters: len(node.Type.Params.List), - VarArgs: node.Type.Params.VarArgs, - SourceMap: sourceMap, - } - - if len(freeSymbols) > 0 { - c.emit(node, OpClosure, c.addConstant(compiledFunction), len(freeSymbols)) - } else { - c.emit(node, OpConstant, c.addConstant(compiledFunction)) - } - - case *ast.ReturnStmt: - if c.symbolTable.Parent(true) == nil { - // outside the function - return c.errorf(node, "return not allowed outside function") - } - - if node.Result == nil { - c.emit(node, OpReturn, 0) - } else { - if err := c.Compile(node.Result); err != nil { - return err - } - - c.emit(node, OpReturn, 1) - } - - case *ast.CallExpr: - if err := c.Compile(node.Func); err != nil { - return err - } - - for _, arg := range node.Args { - if err := c.Compile(arg); err != nil { - return err - } - } - - c.emit(node, OpCall, len(node.Args)) - - case *ast.ImportExpr: - if node.ModuleName == "" { - return c.errorf(node, "empty module name") - } - - if mod := c.modules.Get(node.ModuleName); mod != nil { - v, err := mod.Import(node.ModuleName) - if err != nil { - return err - } - - switch v := v.(type) { - case []byte: // module written in Tengo - compiled, err := c.compileModule(node, node.ModuleName, node.ModuleName, v) - if err != nil { - return err - } - c.emit(node, OpConstant, c.addConstant(compiled)) - c.emit(node, OpCall, 0) - case objects.Object: // builtin module - c.emit(node, OpConstant, c.addConstant(v)) - default: - panic(fmt.Errorf("invalid import value type: %T", v)) - } - } else if c.allowFileImport { - moduleName := node.ModuleName - if !strings.HasSuffix(moduleName, ".tengo") { - moduleName += ".tengo" - } - - modulePath, err := filepath.Abs(moduleName) - if err != nil { - return c.errorf(node, "module file path error: %s", err.Error()) - } - - if err := c.checkCyclicImports(node, modulePath); err != nil { - return err - } - - moduleSrc, err := ioutil.ReadFile(moduleName) - if err != nil { - return c.errorf(node, "module file read error: %s", err.Error()) - } - - compiled, err := c.compileModule(node, moduleName, modulePath, moduleSrc) - if err != nil { - return err - } - c.emit(node, OpConstant, c.addConstant(compiled)) - c.emit(node, OpCall, 0) - } else { - return c.errorf(node, "module '%s' not found", node.ModuleName) - } - - case *ast.ExportStmt: - // export statement must be in top-level scope - if c.scopeIndex != 0 { - return c.errorf(node, "export not allowed inside function") - } - - // export statement is simply ignore when compiling non-module code - if c.parent == nil { - break - } - - if err := c.Compile(node.Result); err != nil { - return err - } - - c.emit(node, OpImmutable) - c.emit(node, OpReturn, 1) - - case *ast.ErrorExpr: - if err := c.Compile(node.Expr); err != nil { - return err - } - - c.emit(node, OpError) - - case *ast.ImmutableExpr: - if err := c.Compile(node.Expr); err != nil { - return err - } - - c.emit(node, OpImmutable) - - case *ast.CondExpr: - if err := c.Compile(node.Cond); err != nil { - return err - } - - // first jump placeholder - jumpPos1 := c.emit(node, OpJumpFalsy, 0) - - if err := c.Compile(node.True); err != nil { - return err - } - - // second jump placeholder - jumpPos2 := c.emit(node, OpJump, 0) - - // update first jump offset - curPos := len(c.currentInstructions()) - c.changeOperand(jumpPos1, curPos) - - if err := c.Compile(node.False); err != nil { - return err - } - - // update second jump offset - curPos = len(c.currentInstructions()) - c.changeOperand(jumpPos2, curPos) - } - - return nil -} - -// Bytecode returns a compiled bytecode. -func (c *Compiler) Bytecode() *Bytecode { - return &Bytecode{ - FileSet: c.file.Set(), - MainFunction: &objects.CompiledFunction{ - Instructions: c.currentInstructions(), - SourceMap: c.currentSourceMap(), - }, - Constants: c.constants, - } -} - -// EnableFileImport enables or disables module loading from local files. -// Local file modules are disabled by default. -func (c *Compiler) EnableFileImport(enable bool) { - c.allowFileImport = enable -} - -func (c *Compiler) fork(file *source.File, modulePath string, symbolTable *SymbolTable) *Compiler { - child := NewCompiler(file, symbolTable, nil, c.modules, c.trace) - child.modulePath = modulePath // module file path - child.parent = c // parent to set to current compiler - - return child -} - -func (c *Compiler) error(node ast.Node, err error) error { - return &Error{ - fileSet: c.file.Set(), - node: node, - error: err, - } -} - -func (c *Compiler) errorf(node ast.Node, format string, args ...interface{}) error { - return &Error{ - fileSet: c.file.Set(), - node: node, - error: fmt.Errorf(format, args...), - } -} - -func (c *Compiler) addConstant(o objects.Object) int { - if c.parent != nil { - // module compilers will use their parent's constants array - return c.parent.addConstant(o) - } - - c.constants = append(c.constants, o) - - if c.trace != nil { - c.printTrace(fmt.Sprintf("CONST %04d %s", len(c.constants)-1, o)) - } - - return len(c.constants) - 1 -} - -func (c *Compiler) addInstruction(b []byte) int { - posNewIns := len(c.currentInstructions()) - - c.scopes[c.scopeIndex].instructions = append(c.currentInstructions(), b...) - - return posNewIns -} - -func (c *Compiler) replaceInstruction(pos int, inst []byte) { - copy(c.currentInstructions()[pos:], inst) - - if c.trace != nil { - c.printTrace(fmt.Sprintf("REPLC %s", - FormatInstructions(c.scopes[c.scopeIndex].instructions[pos:], pos)[0])) - } -} - -func (c *Compiler) changeOperand(opPos int, operand ...int) { - op := Opcode(c.currentInstructions()[opPos]) - inst := MakeInstruction(op, operand...) - - c.replaceInstruction(opPos, inst) -} - -// optimizeFunc performs some code-level optimization for the current function instructions -// it removes unreachable (dead code) instructions and adds "returns" instruction if needed. -func (c *Compiler) optimizeFunc(node ast.Node) { - // any instructions between RETURN and the function end - // or instructions between RETURN and jump target position - // are considered as unreachable. - - // pass 1. identify all jump destinations - dsts := make(map[int]bool) - iterateInstructions(c.scopes[c.scopeIndex].instructions, func(pos int, opcode Opcode, operands []int) bool { - switch opcode { - case OpJump, OpJumpFalsy, OpAndJump, OpOrJump: - dsts[operands[0]] = true - } - - return true - }) - - var newInsts []byte - - // pass 2. eliminate dead code - posMap := make(map[int]int) // old position to new position - var dstIdx int - var deadCode bool - iterateInstructions(c.scopes[c.scopeIndex].instructions, func(pos int, opcode Opcode, operands []int) bool { - switch { - case opcode == OpReturn: - if deadCode { - return true - } - deadCode = true - case dsts[pos]: - dstIdx++ - deadCode = false - case deadCode: - return true - } - - posMap[pos] = len(newInsts) - newInsts = append(newInsts, MakeInstruction(opcode, operands...)...) - return true - }) - - // pass 3. update jump positions - var lastOp Opcode - var appendReturn bool - endPos := len(c.scopes[c.scopeIndex].instructions) - iterateInstructions(newInsts, func(pos int, opcode Opcode, operands []int) bool { - switch opcode { - case OpJump, OpJumpFalsy, OpAndJump, OpOrJump: - newDst, ok := posMap[operands[0]] - if ok { - copy(newInsts[pos:], MakeInstruction(opcode, newDst)) - } else if endPos == operands[0] { - // there's a jump instruction that jumps to the end of function - // compiler should append "return". - appendReturn = true - } else { - panic(fmt.Errorf("invalid jump position: %d", newDst)) - } - } - lastOp = opcode - return true - }) - if lastOp != OpReturn { - appendReturn = true - } - - // pass 4. update source map - newSourceMap := make(map[int]source.Pos) - for pos, srcPos := range c.scopes[c.scopeIndex].sourceMap { - newPos, ok := posMap[pos] - if ok { - newSourceMap[newPos] = srcPos - } - } - - c.scopes[c.scopeIndex].instructions = newInsts - c.scopes[c.scopeIndex].sourceMap = newSourceMap - - // append "return" - if appendReturn { - c.emit(node, OpReturn, 0) - } -} - -func (c *Compiler) emit(node ast.Node, opcode Opcode, operands ...int) int { - filePos := source.NoPos - if node != nil { - filePos = node.Pos() - } - - inst := MakeInstruction(opcode, operands...) - pos := c.addInstruction(inst) - c.scopes[c.scopeIndex].sourceMap[pos] = filePos - - if c.trace != nil { - c.printTrace(fmt.Sprintf("EMIT %s", - FormatInstructions(c.scopes[c.scopeIndex].instructions[pos:], pos)[0])) - } - - return pos -} - -func (c *Compiler) printTrace(a ...interface{}) { - const ( - dots = ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . " - n = len(dots) - ) - - i := 2 * c.indent - for i > n { - _, _ = fmt.Fprint(c.trace, dots) - i -= n - } - _, _ = fmt.Fprint(c.trace, dots[0:i]) - _, _ = fmt.Fprintln(c.trace, a...) -} - -func trace(c *Compiler, msg string) *Compiler { - c.printTrace(msg, "{") - c.indent++ - - return c -} - -func un(c *Compiler) { - c.indent-- - c.printTrace("}") -} diff --git a/vendor/github.com/d5/tengo/compiler/compiler_assign.go b/vendor/github.com/d5/tengo/compiler/compiler_assign.go deleted file mode 100644 index 59296f6f..00000000 --- a/vendor/github.com/d5/tengo/compiler/compiler_assign.go +++ /dev/null @@ -1,133 +0,0 @@ -package compiler - -import ( - "fmt" - - "github.com/d5/tengo/compiler/ast" - "github.com/d5/tengo/compiler/token" -) - -func (c *Compiler) compileAssign(node ast.Node, lhs, rhs []ast.Expr, op token.Token) error { - numLHS, numRHS := len(lhs), len(rhs) - if numLHS > 1 || numRHS > 1 { - return c.errorf(node, "tuple assignment not allowed") - } - - // resolve and compile left-hand side - ident, selectors := resolveAssignLHS(lhs[0]) - numSel := len(selectors) - - if op == token.Define && numSel > 0 { - // using selector on new variable does not make sense - return c.errorf(node, "operator ':=' not allowed with selector") - } - - symbol, depth, exists := c.symbolTable.Resolve(ident) - if op == token.Define { - if depth == 0 && exists { - return c.errorf(node, "'%s' redeclared in this block", ident) - } - - symbol = c.symbolTable.Define(ident) - } else { - if !exists { - return c.errorf(node, "unresolved reference '%s'", ident) - } - } - - // +=, -=, *=, /= - if op != token.Assign && op != token.Define { - if err := c.Compile(lhs[0]); err != nil { - return err - } - } - - // compile RHSs - for _, expr := range rhs { - if err := c.Compile(expr); err != nil { - return err - } - } - - switch op { - case token.AddAssign: - c.emit(node, OpBinaryOp, int(token.Add)) - case token.SubAssign: - c.emit(node, OpBinaryOp, int(token.Sub)) - case token.MulAssign: - c.emit(node, OpBinaryOp, int(token.Mul)) - case token.QuoAssign: - c.emit(node, OpBinaryOp, int(token.Quo)) - case token.RemAssign: - c.emit(node, OpBinaryOp, int(token.Rem)) - case token.AndAssign: - c.emit(node, OpBinaryOp, int(token.And)) - case token.OrAssign: - c.emit(node, OpBinaryOp, int(token.Or)) - case token.AndNotAssign: - c.emit(node, OpBinaryOp, int(token.AndNot)) - case token.XorAssign: - c.emit(node, OpBinaryOp, int(token.Xor)) - case token.ShlAssign: - c.emit(node, OpBinaryOp, int(token.Shl)) - case token.ShrAssign: - c.emit(node, OpBinaryOp, int(token.Shr)) - } - - // compile selector expressions (right to left) - for i := numSel - 1; i >= 0; i-- { - if err := c.Compile(selectors[i]); err != nil { - return err - } - } - - switch symbol.Scope { - case ScopeGlobal: - if numSel > 0 { - c.emit(node, OpSetSelGlobal, symbol.Index, numSel) - } else { - c.emit(node, OpSetGlobal, symbol.Index) - } - case ScopeLocal: - if numSel > 0 { - c.emit(node, OpSetSelLocal, symbol.Index, numSel) - } else { - if op == token.Define && !symbol.LocalAssigned { - c.emit(node, OpDefineLocal, symbol.Index) - } else { - c.emit(node, OpSetLocal, symbol.Index) - } - } - - // mark the symbol as local-assigned - symbol.LocalAssigned = true - case ScopeFree: - if numSel > 0 { - c.emit(node, OpSetSelFree, symbol.Index, numSel) - } else { - c.emit(node, OpSetFree, symbol.Index) - } - default: - panic(fmt.Errorf("invalid assignment variable scope: %s", symbol.Scope)) - } - - return nil -} - -func resolveAssignLHS(expr ast.Expr) (name string, selectors []ast.Expr) { - switch term := expr.(type) { - case *ast.SelectorExpr: - name, selectors = resolveAssignLHS(term.Expr) - selectors = append(selectors, term.Sel) - return - - case *ast.IndexExpr: - name, selectors = resolveAssignLHS(term.Expr) - selectors = append(selectors, term.Index) - - case *ast.Ident: - name = term.Name - } - - return -} diff --git a/vendor/github.com/d5/tengo/compiler/compiler_for.go b/vendor/github.com/d5/tengo/compiler/compiler_for.go deleted file mode 100644 index e7b7b5f1..00000000 --- a/vendor/github.com/d5/tengo/compiler/compiler_for.go +++ /dev/null @@ -1,181 +0,0 @@ -package compiler - -import ( - "github.com/d5/tengo/compiler/ast" -) - -func (c *Compiler) compileForStmt(stmt *ast.ForStmt) error { - c.symbolTable = c.symbolTable.Fork(true) - defer func() { - c.symbolTable = c.symbolTable.Parent(false) - }() - - // init statement - if stmt.Init != nil { - if err := c.Compile(stmt.Init); err != nil { - return err - } - } - - // pre-condition position - preCondPos := len(c.currentInstructions()) - - // condition expression - postCondPos := -1 - if stmt.Cond != nil { - if err := c.Compile(stmt.Cond); err != nil { - return err - } - // condition jump position - postCondPos = c.emit(stmt, OpJumpFalsy, 0) - } - - // enter loop - loop := c.enterLoop() - - // body statement - if err := c.Compile(stmt.Body); err != nil { - c.leaveLoop() - return err - } - - c.leaveLoop() - - // post-body position - postBodyPos := len(c.currentInstructions()) - - // post statement - if stmt.Post != nil { - if err := c.Compile(stmt.Post); err != nil { - return err - } - } - - // back to condition - c.emit(stmt, OpJump, preCondPos) - - // post-statement position - postStmtPos := len(c.currentInstructions()) - if postCondPos >= 0 { - c.changeOperand(postCondPos, postStmtPos) - } - - // update all break/continue jump positions - for _, pos := range loop.Breaks { - c.changeOperand(pos, postStmtPos) - } - for _, pos := range loop.Continues { - c.changeOperand(pos, postBodyPos) - } - - return nil -} - -func (c *Compiler) compileForInStmt(stmt *ast.ForInStmt) error { - c.symbolTable = c.symbolTable.Fork(true) - defer func() { - c.symbolTable = c.symbolTable.Parent(false) - }() - - // for-in statement is compiled like following: - // - // for :it := iterator(iterable); :it.next(); { - // k, v := :it.get() // DEFINE operator - // - // ... body ... - // } - // - // ":it" is a local variable but will be conflict with other user variables - // because character ":" is not allowed. - - // init - // :it = iterator(iterable) - itSymbol := c.symbolTable.Define(":it") - if err := c.Compile(stmt.Iterable); err != nil { - return err - } - c.emit(stmt, OpIteratorInit) - if itSymbol.Scope == ScopeGlobal { - c.emit(stmt, OpSetGlobal, itSymbol.Index) - } else { - c.emit(stmt, OpDefineLocal, itSymbol.Index) - } - - // pre-condition position - preCondPos := len(c.currentInstructions()) - - // condition - // :it.HasMore() - if itSymbol.Scope == ScopeGlobal { - c.emit(stmt, OpGetGlobal, itSymbol.Index) - } else { - c.emit(stmt, OpGetLocal, itSymbol.Index) - } - c.emit(stmt, OpIteratorNext) - - // condition jump position - postCondPos := c.emit(stmt, OpJumpFalsy, 0) - - // enter loop - loop := c.enterLoop() - - // assign key variable - if stmt.Key.Name != "_" { - keySymbol := c.symbolTable.Define(stmt.Key.Name) - if itSymbol.Scope == ScopeGlobal { - c.emit(stmt, OpGetGlobal, itSymbol.Index) - } else { - c.emit(stmt, OpGetLocal, itSymbol.Index) - } - c.emit(stmt, OpIteratorKey) - if keySymbol.Scope == ScopeGlobal { - c.emit(stmt, OpSetGlobal, keySymbol.Index) - } else { - c.emit(stmt, OpDefineLocal, keySymbol.Index) - } - } - - // assign value variable - if stmt.Value.Name != "_" { - valueSymbol := c.symbolTable.Define(stmt.Value.Name) - if itSymbol.Scope == ScopeGlobal { - c.emit(stmt, OpGetGlobal, itSymbol.Index) - } else { - c.emit(stmt, OpGetLocal, itSymbol.Index) - } - c.emit(stmt, OpIteratorValue) - if valueSymbol.Scope == ScopeGlobal { - c.emit(stmt, OpSetGlobal, valueSymbol.Index) - } else { - c.emit(stmt, OpDefineLocal, valueSymbol.Index) - } - } - - // body statement - if err := c.Compile(stmt.Body); err != nil { - c.leaveLoop() - return err - } - - c.leaveLoop() - - // post-body position - postBodyPos := len(c.currentInstructions()) - - // back to condition - c.emit(stmt, OpJump, preCondPos) - - // post-statement position - postStmtPos := len(c.currentInstructions()) - c.changeOperand(postCondPos, postStmtPos) - - // update all break/continue jump positions - for _, pos := range loop.Breaks { - c.changeOperand(pos, postStmtPos) - } - for _, pos := range loop.Continues { - c.changeOperand(pos, postBodyPos) - } - - return nil -} diff --git a/vendor/github.com/d5/tengo/compiler/compiler_logical.go b/vendor/github.com/d5/tengo/compiler/compiler_logical.go deleted file mode 100644 index 68c96759..00000000 --- a/vendor/github.com/d5/tengo/compiler/compiler_logical.go +++ /dev/null @@ -1,30 +0,0 @@ -package compiler - -import ( - "github.com/d5/tengo/compiler/ast" - "github.com/d5/tengo/compiler/token" -) - -func (c *Compiler) compileLogical(node *ast.BinaryExpr) error { - // left side term - if err := c.Compile(node.LHS); err != nil { - return err - } - - // jump position - var jumpPos int - if node.Token == token.LAnd { - jumpPos = c.emit(node, OpAndJump, 0) - } else { - jumpPos = c.emit(node, OpOrJump, 0) - } - - // right side term - if err := c.Compile(node.RHS); err != nil { - return err - } - - c.changeOperand(jumpPos, len(c.currentInstructions())) - - return nil -} diff --git a/vendor/github.com/d5/tengo/compiler/compiler_loops.go b/vendor/github.com/d5/tengo/compiler/compiler_loops.go deleted file mode 100644 index 0659ce73..00000000 --- a/vendor/github.com/d5/tengo/compiler/compiler_loops.go +++ /dev/null @@ -1,31 +0,0 @@ -package compiler - -func (c *Compiler) enterLoop() *Loop { - loop := &Loop{} - - c.loops = append(c.loops, loop) - c.loopIndex++ - - if c.trace != nil { - c.printTrace("LOOPE", c.loopIndex) - } - - return loop -} - -func (c *Compiler) leaveLoop() { - if c.trace != nil { - c.printTrace("LOOPL", c.loopIndex) - } - - c.loops = c.loops[:len(c.loops)-1] - c.loopIndex-- -} - -func (c *Compiler) currentLoop() *Loop { - if c.loopIndex >= 0 { - return c.loops[c.loopIndex] - } - - return nil -} diff --git a/vendor/github.com/d5/tengo/compiler/compiler_module.go b/vendor/github.com/d5/tengo/compiler/compiler_module.go deleted file mode 100644 index 8a3671ce..00000000 --- a/vendor/github.com/d5/tengo/compiler/compiler_module.go +++ /dev/null @@ -1,79 +0,0 @@ -package compiler - -import ( - "github.com/d5/tengo/compiler/ast" - "github.com/d5/tengo/compiler/parser" - "github.com/d5/tengo/objects" -) - -func (c *Compiler) checkCyclicImports(node ast.Node, modulePath string) error { - if c.modulePath == modulePath { - return c.errorf(node, "cyclic module import: %s", modulePath) - } else if c.parent != nil { - return c.parent.checkCyclicImports(node, modulePath) - } - - return nil -} - -func (c *Compiler) compileModule(node ast.Node, moduleName, modulePath string, src []byte) (*objects.CompiledFunction, error) { - if err := c.checkCyclicImports(node, modulePath); err != nil { - return nil, err - } - - compiledModule, exists := c.loadCompiledModule(modulePath) - if exists { - return compiledModule, nil - } - - modFile := c.file.Set().AddFile(moduleName, -1, len(src)) - p := parser.NewParser(modFile, src, nil) - file, err := p.ParseFile() - if err != nil { - return nil, err - } - - symbolTable := NewSymbolTable() - - // inherit builtin functions - for _, sym := range c.symbolTable.BuiltinSymbols() { - symbolTable.DefineBuiltin(sym.Index, sym.Name) - } - - // no global scope for the module - symbolTable = symbolTable.Fork(false) - - // compile module - moduleCompiler := c.fork(modFile, modulePath, symbolTable) - if err := moduleCompiler.Compile(file); err != nil { - return nil, err - } - - // code optimization - moduleCompiler.optimizeFunc(node) - - compiledFunc := moduleCompiler.Bytecode().MainFunction - compiledFunc.NumLocals = symbolTable.MaxSymbols() - - c.storeCompiledModule(modulePath, compiledFunc) - - return compiledFunc, nil -} - -func (c *Compiler) loadCompiledModule(modulePath string) (mod *objects.CompiledFunction, ok bool) { - if c.parent != nil { - return c.parent.loadCompiledModule(modulePath) - } - - mod, ok = c.compiledModules[modulePath] - - return -} - -func (c *Compiler) storeCompiledModule(modulePath string, module *objects.CompiledFunction) { - if c.parent != nil { - c.parent.storeCompiledModule(modulePath, module) - } - - c.compiledModules[modulePath] = module -} diff --git a/vendor/github.com/d5/tengo/compiler/compiler_scopes.go b/vendor/github.com/d5/tengo/compiler/compiler_scopes.go deleted file mode 100644 index b63f915a..00000000 --- a/vendor/github.com/d5/tengo/compiler/compiler_scopes.go +++ /dev/null @@ -1,43 +0,0 @@ -package compiler - -import "github.com/d5/tengo/compiler/source" - -func (c *Compiler) currentInstructions() []byte { - return c.scopes[c.scopeIndex].instructions -} - -func (c *Compiler) currentSourceMap() map[int]source.Pos { - return c.scopes[c.scopeIndex].sourceMap -} - -func (c *Compiler) enterScope() { - scope := CompilationScope{ - symbolInit: make(map[string]bool), - sourceMap: make(map[int]source.Pos), - } - - c.scopes = append(c.scopes, scope) - c.scopeIndex++ - - c.symbolTable = c.symbolTable.Fork(false) - - if c.trace != nil { - c.printTrace("SCOPE", c.scopeIndex) - } -} - -func (c *Compiler) leaveScope() (instructions []byte, sourceMap map[int]source.Pos) { - instructions = c.currentInstructions() - sourceMap = c.currentSourceMap() - - c.scopes = c.scopes[:len(c.scopes)-1] - c.scopeIndex-- - - c.symbolTable = c.symbolTable.Parent(true) - - if c.trace != nil { - c.printTrace("SCOPL", c.scopeIndex) - } - - return -} diff --git a/vendor/github.com/d5/tengo/compiler/emitted_instruction.go b/vendor/github.com/d5/tengo/compiler/emitted_instruction.go deleted file mode 100644 index 8572fb0a..00000000 --- a/vendor/github.com/d5/tengo/compiler/emitted_instruction.go +++ /dev/null @@ -1,8 +0,0 @@ -package compiler - -// EmittedInstruction represents an opcode -// with its emitted position. -type EmittedInstruction struct { - Opcode Opcode - Position int -} diff --git a/vendor/github.com/d5/tengo/compiler/error.go b/vendor/github.com/d5/tengo/compiler/error.go deleted file mode 100644 index 6ac33d42..00000000 --- a/vendor/github.com/d5/tengo/compiler/error.go +++ /dev/null @@ -1,20 +0,0 @@ -package compiler - -import ( - "fmt" - - "github.com/d5/tengo/compiler/ast" - "github.com/d5/tengo/compiler/source" -) - -// Error represents a compiler error. -type Error struct { - fileSet *source.FileSet - node ast.Node - error error -} - -func (e *Error) Error() string { - filePos := e.fileSet.Position(e.node.Pos()) - return fmt.Sprintf("Compile Error: %s\n\tat %s", e.error.Error(), filePos) -} diff --git a/vendor/github.com/d5/tengo/compiler/instructions.go b/vendor/github.com/d5/tengo/compiler/instructions.go deleted file mode 100644 index 14dde1d8..00000000 --- a/vendor/github.com/d5/tengo/compiler/instructions.go +++ /dev/null @@ -1,72 +0,0 @@ -package compiler - -import ( - "fmt" -) - -// MakeInstruction returns a bytecode for an opcode and the operands. -func MakeInstruction(opcode Opcode, operands ...int) []byte { - numOperands := OpcodeOperands[opcode] - - totalLen := 1 - for _, w := range numOperands { - totalLen += w - } - - instruction := make([]byte, totalLen) - instruction[0] = byte(opcode) - - offset := 1 - for i, o := range operands { - width := numOperands[i] - switch width { - case 1: - instruction[offset] = byte(o) - case 2: - n := uint16(o) - instruction[offset] = byte(n >> 8) - instruction[offset+1] = byte(n) - } - offset += width - } - - return instruction -} - -// FormatInstructions returns string representation of -// bytecode instructions. -func FormatInstructions(b []byte, posOffset int) []string { - var out []string - - i := 0 - for i < len(b) { - numOperands := OpcodeOperands[Opcode(b[i])] - operands, read := ReadOperands(numOperands, b[i+1:]) - - switch len(numOperands) { - case 0: - out = append(out, fmt.Sprintf("%04d %-7s", posOffset+i, OpcodeNames[Opcode(b[i])])) - case 1: - out = append(out, fmt.Sprintf("%04d %-7s %-5d", posOffset+i, OpcodeNames[Opcode(b[i])], operands[0])) - case 2: - out = append(out, fmt.Sprintf("%04d %-7s %-5d %-5d", posOffset+i, OpcodeNames[Opcode(b[i])], operands[0], operands[1])) - } - - i += 1 + read - } - - return out -} - -func iterateInstructions(b []byte, fn func(pos int, opcode Opcode, operands []int) bool) { - for i := 0; i < len(b); i++ { - numOperands := OpcodeOperands[Opcode(b[i])] - operands, read := ReadOperands(numOperands, b[i+1:]) - - if !fn(i, b[i], operands) { - break - } - - i += read - } -} diff --git a/vendor/github.com/d5/tengo/compiler/loop.go b/vendor/github.com/d5/tengo/compiler/loop.go deleted file mode 100644 index e27cb096..00000000 --- a/vendor/github.com/d5/tengo/compiler/loop.go +++ /dev/null @@ -1,8 +0,0 @@ -package compiler - -// Loop represents a loop construct that -// the compiler uses to track the current loop. -type Loop struct { - Continues []int - Breaks []int -} diff --git a/vendor/github.com/d5/tengo/compiler/module_loader.go b/vendor/github.com/d5/tengo/compiler/module_loader.go deleted file mode 100644 index b050474d..00000000 --- a/vendor/github.com/d5/tengo/compiler/module_loader.go +++ /dev/null @@ -1,4 +0,0 @@ -package compiler - -// ModuleLoader should take a module name and return the module data. -type ModuleLoader func(moduleName string) ([]byte, error) diff --git a/vendor/github.com/d5/tengo/compiler/opcodes.go b/vendor/github.com/d5/tengo/compiler/opcodes.go deleted file mode 100644 index d832ee17..00000000 --- a/vendor/github.com/d5/tengo/compiler/opcodes.go +++ /dev/null @@ -1,155 +0,0 @@ -package compiler - -// Opcode represents a single byte operation code. -type Opcode = byte - -// List of opcodes -const ( - OpConstant Opcode = iota // Load constant - OpBComplement // bitwise complement - OpPop // Pop - OpTrue // Push true - OpFalse // Push false - OpEqual // Equal == - OpNotEqual // Not equal != - OpMinus // Minus - - OpLNot // Logical not ! - OpJumpFalsy // Jump if falsy - OpAndJump // Logical AND jump - OpOrJump // Logical OR jump - OpJump // Jump - OpNull // Push null - OpArray // Array object - OpMap // Map object - OpError // Error object - OpImmutable // Immutable object - OpIndex // Index operation - OpSliceIndex // Slice operation - OpCall // Call function - OpReturn // Return - OpGetGlobal // Get global variable - OpSetGlobal // Set global variable - OpSetSelGlobal // Set global variable using selectors - OpGetLocal // Get local variable - OpSetLocal // Set local variable - OpDefineLocal // Define local variable - OpSetSelLocal // Set local variable using selectors - OpGetFreePtr // Get free variable pointer object - OpGetFree // Get free variables - OpSetFree // Set free variables - OpGetLocalPtr // Get local variable as a pointer - OpSetSelFree // Set free variables using selectors - OpGetBuiltin // Get builtin function - OpClosure // Push closure - OpIteratorInit // Iterator init - OpIteratorNext // Iterator next - OpIteratorKey // Iterator key - OpIteratorValue // Iterator value - OpBinaryOp // Binary Operation -) - -// OpcodeNames is opcode names. -var OpcodeNames = [...]string{ - OpConstant: "CONST", - OpPop: "POP", - OpTrue: "TRUE", - OpFalse: "FALSE", - OpBComplement: "NEG", - OpEqual: "EQL", - OpNotEqual: "NEQ", - OpMinus: "NEG", - OpLNot: "NOT", - OpJumpFalsy: "JMPF", - OpAndJump: "ANDJMP", - OpOrJump: "ORJMP", - OpJump: "JMP", - OpNull: "NULL", - OpGetGlobal: "GETG", - OpSetGlobal: "SETG", - OpSetSelGlobal: "SETSG", - OpArray: "ARR", - OpMap: "MAP", - OpError: "ERROR", - OpImmutable: "IMMUT", - OpIndex: "INDEX", - OpSliceIndex: "SLICE", - OpCall: "CALL", - OpReturn: "RET", - OpGetLocal: "GETL", - OpSetLocal: "SETL", - OpDefineLocal: "DEFL", - OpSetSelLocal: "SETSL", - OpGetBuiltin: "BUILTIN", - OpClosure: "CLOSURE", - OpGetFreePtr: "GETFP", - OpGetFree: "GETF", - OpSetFree: "SETF", - OpGetLocalPtr: "GETLP", - OpSetSelFree: "SETSF", - OpIteratorInit: "ITER", - OpIteratorNext: "ITNXT", - OpIteratorKey: "ITKEY", - OpIteratorValue: "ITVAL", - OpBinaryOp: "BINARYOP", -} - -// OpcodeOperands is the number of operands. -var OpcodeOperands = [...][]int{ - OpConstant: {2}, - OpPop: {}, - OpTrue: {}, - OpFalse: {}, - OpBComplement: {}, - OpEqual: {}, - OpNotEqual: {}, - OpMinus: {}, - OpLNot: {}, - OpJumpFalsy: {2}, - OpAndJump: {2}, - OpOrJump: {2}, - OpJump: {2}, - OpNull: {}, - OpGetGlobal: {2}, - OpSetGlobal: {2}, - OpSetSelGlobal: {2, 1}, - OpArray: {2}, - OpMap: {2}, - OpError: {}, - OpImmutable: {}, - OpIndex: {}, - OpSliceIndex: {}, - OpCall: {1}, - OpReturn: {1}, - OpGetLocal: {1}, - OpSetLocal: {1}, - OpDefineLocal: {1}, - OpSetSelLocal: {1, 1}, - OpGetBuiltin: {1}, - OpClosure: {2, 1}, - OpGetFreePtr: {1}, - OpGetFree: {1}, - OpSetFree: {1}, - OpGetLocalPtr: {1}, - OpSetSelFree: {1, 1}, - OpIteratorInit: {}, - OpIteratorNext: {}, - OpIteratorKey: {}, - OpIteratorValue: {}, - OpBinaryOp: {1}, -} - -// ReadOperands reads operands from the bytecode. -func ReadOperands(numOperands []int, ins []byte) (operands []int, offset int) { - for _, width := range numOperands { - switch width { - case 1: - operands = append(operands, int(ins[offset])) - case 2: - operands = append(operands, int(ins[offset+1])|int(ins[offset])<<8) - } - - offset += width - } - - return -} diff --git a/vendor/github.com/d5/tengo/compiler/parser/error.go b/vendor/github.com/d5/tengo/compiler/parser/error.go deleted file mode 100644 index 80544fbd..00000000 --- a/vendor/github.com/d5/tengo/compiler/parser/error.go +++ /dev/null @@ -1,21 +0,0 @@ -package parser - -import ( - "fmt" - - "github.com/d5/tengo/compiler/source" -) - -// Error represents a parser error. -type Error struct { - Pos source.FilePos - Msg string -} - -func (e Error) Error() string { - if e.Pos.Filename != "" || e.Pos.IsValid() { - return fmt.Sprintf("Parse Error: %s\n\tat %s", e.Msg, e.Pos) - } - - return fmt.Sprintf("Parse Error: %s", e.Msg) -} diff --git a/vendor/github.com/d5/tengo/compiler/parser/error_list.go b/vendor/github.com/d5/tengo/compiler/parser/error_list.go deleted file mode 100644 index 599eaf7d..00000000 --- a/vendor/github.com/d5/tengo/compiler/parser/error_list.go +++ /dev/null @@ -1,68 +0,0 @@ -package parser - -import ( - "fmt" - "sort" - - "github.com/d5/tengo/compiler/source" -) - -// ErrorList is a collection of parser errors. -type ErrorList []*Error - -// Add adds a new parser error to the collection. -func (p *ErrorList) Add(pos source.FilePos, msg string) { - *p = append(*p, &Error{pos, msg}) -} - -// Len returns the number of elements in the collection. -func (p ErrorList) Len() int { - return len(p) -} - -func (p ErrorList) Swap(i, j int) { - p[i], p[j] = p[j], p[i] -} - -func (p ErrorList) Less(i, j int) bool { - e := &p[i].Pos - f := &p[j].Pos - - if e.Filename != f.Filename { - return e.Filename < f.Filename - } - - if e.Line != f.Line { - return e.Line < f.Line - } - - if e.Column != f.Column { - return e.Column < f.Column - } - - return p[i].Msg < p[j].Msg -} - -// Sort sorts the collection. -func (p ErrorList) Sort() { - sort.Sort(p) -} - -func (p ErrorList) Error() string { - switch len(p) { - case 0: - return "no errors" - case 1: - return p[0].Error() - } - return fmt.Sprintf("%s (and %d more errors)", p[0], len(p)-1) -} - -// Err returns an error. -func (p ErrorList) Err() error { - if len(p) == 0 { - return nil - } - - return p -} diff --git a/vendor/github.com/d5/tengo/compiler/parser/parse_source.go b/vendor/github.com/d5/tengo/compiler/parser/parse_source.go deleted file mode 100644 index 5c71436d..00000000 --- a/vendor/github.com/d5/tengo/compiler/parser/parse_source.go +++ /dev/null @@ -1,17 +0,0 @@ -package parser - -import ( - "io" - - "github.com/d5/tengo/compiler/ast" - "github.com/d5/tengo/compiler/source" -) - -// ParseSource parses source code 'src' and builds an AST. -func ParseSource(filename string, src []byte, trace io.Writer) (res *ast.File, err error) { - fileSet := source.NewFileSet() - file := fileSet.AddFile(filename, -1, len(src)) - - p := NewParser(file, src, trace) - return p.ParseFile() -} diff --git a/vendor/github.com/d5/tengo/compiler/parser/parser.go b/vendor/github.com/d5/tengo/compiler/parser/parser.go deleted file mode 100644 index 27dd48f0..00000000 --- a/vendor/github.com/d5/tengo/compiler/parser/parser.go +++ /dev/null @@ -1,1216 +0,0 @@ -/* - Parser parses the Tengo source files. - - Parser is a modified version of Go's parser implementation. - - Copyright 2009 The Go Authors. All rights reserved. - Use of this source code is governed by a BSD-style - license that can be found in the LICENSE file. -*/ - -package parser - -import ( - "fmt" - "io" - "strconv" - - "github.com/d5/tengo/compiler/ast" - "github.com/d5/tengo/compiler/scanner" - "github.com/d5/tengo/compiler/source" - "github.com/d5/tengo/compiler/token" -) - -type bailout struct{} - -// Parser parses the Tengo source files. -type Parser struct { - file *source.File - errors ErrorList - scanner *scanner.Scanner - pos source.Pos - token token.Token - tokenLit string - exprLevel int // < 0: in control clause, >= 0: in expression - syncPos source.Pos // last sync position - syncCount int // number of advance calls without progress - trace bool - indent int - traceOut io.Writer -} - -// NewParser creates a Parser. -func NewParser(file *source.File, src []byte, trace io.Writer) *Parser { - p := &Parser{ - file: file, - trace: trace != nil, - traceOut: trace, - } - - p.scanner = scanner.NewScanner(p.file, src, func(pos source.FilePos, msg string) { - p.errors.Add(pos, msg) - }, 0) - - p.next() - - return p -} - -// ParseFile parses the source and returns an AST file unit. -func (p *Parser) ParseFile() (file *ast.File, err error) { - defer func() { - if e := recover(); e != nil { - if _, ok := e.(bailout); !ok { - panic(e) - } - } - - p.errors.Sort() - err = p.errors.Err() - }() - - if p.trace { - defer un(trace(p, "File")) - } - - if p.errors.Len() > 0 { - return nil, p.errors.Err() - } - - stmts := p.parseStmtList() - if p.errors.Len() > 0 { - return nil, p.errors.Err() - } - - file = &ast.File{ - InputFile: p.file, - Stmts: stmts, - } - - return -} - -func (p *Parser) parseExpr() ast.Expr { - if p.trace { - defer un(trace(p, "Expression")) - } - - expr := p.parseBinaryExpr(token.LowestPrec + 1) - - // ternary conditional expression - if p.token == token.Question { - return p.parseCondExpr(expr) - } - - return expr -} - -func (p *Parser) parseBinaryExpr(prec1 int) ast.Expr { - if p.trace { - defer un(trace(p, "BinaryExpression")) - } - - x := p.parseUnaryExpr() - - for { - op, prec := p.token, p.token.Precedence() - if prec < prec1 { - return x - } - - pos := p.expect(op) - - y := p.parseBinaryExpr(prec + 1) - - x = &ast.BinaryExpr{ - LHS: x, - RHS: y, - Token: op, - TokenPos: pos, - } - } -} - -func (p *Parser) parseCondExpr(cond ast.Expr) ast.Expr { - questionPos := p.expect(token.Question) - - trueExpr := p.parseExpr() - - colonPos := p.expect(token.Colon) - - falseExpr := p.parseExpr() - - return &ast.CondExpr{ - Cond: cond, - True: trueExpr, - False: falseExpr, - QuestionPos: questionPos, - ColonPos: colonPos, - } -} - -func (p *Parser) parseUnaryExpr() ast.Expr { - if p.trace { - defer un(trace(p, "UnaryExpression")) - } - - switch p.token { - case token.Add, token.Sub, token.Not, token.Xor: - pos, op := p.pos, p.token - p.next() - x := p.parseUnaryExpr() - return &ast.UnaryExpr{ - Token: op, - TokenPos: pos, - Expr: x, - } - } - - return p.parsePrimaryExpr() -} - -func (p *Parser) parsePrimaryExpr() ast.Expr { - if p.trace { - defer un(trace(p, "PrimaryExpression")) - } - - x := p.parseOperand() - -L: - for { - switch p.token { - case token.Period: - p.next() - - switch p.token { - case token.Ident: - x = p.parseSelector(x) - default: - pos := p.pos - p.errorExpected(pos, "selector") - p.advance(stmtStart) - return &ast.BadExpr{From: pos, To: p.pos} - } - case token.LBrack: - x = p.parseIndexOrSlice(x) - case token.LParen: - x = p.parseCall(x) - default: - break L - } - } - - return x -} - -func (p *Parser) parseCall(x ast.Expr) *ast.CallExpr { - if p.trace { - defer un(trace(p, "Call")) - } - - lparen := p.expect(token.LParen) - p.exprLevel++ - - var list []ast.Expr - for p.token != token.RParen && p.token != token.EOF { - list = append(list, p.parseExpr()) - - if !p.expectComma(token.RParen, "call argument") { - break - } - } - - p.exprLevel-- - rparen := p.expect(token.RParen) - - return &ast.CallExpr{ - Func: x, - LParen: lparen, - RParen: rparen, - Args: list, - } -} - -func (p *Parser) expectComma(closing token.Token, want string) bool { - if p.token == token.Comma { - p.next() - - if p.token == closing { - p.errorExpected(p.pos, want) - return false - } - - return true - } - - if p.token == token.Semicolon && p.tokenLit == "\n" { - p.next() - } - - return false -} - -func (p *Parser) parseIndexOrSlice(x ast.Expr) ast.Expr { - if p.trace { - defer un(trace(p, "IndexOrSlice")) - } - - lbrack := p.expect(token.LBrack) - p.exprLevel++ - - var index [2]ast.Expr - if p.token != token.Colon { - index[0] = p.parseExpr() - } - numColons := 0 - if p.token == token.Colon { - numColons++ - p.next() - - if p.token != token.RBrack && p.token != token.EOF { - index[1] = p.parseExpr() - } - } - - p.exprLevel-- - rbrack := p.expect(token.RBrack) - - if numColons > 0 { - // slice expression - return &ast.SliceExpr{ - Expr: x, - LBrack: lbrack, - RBrack: rbrack, - Low: index[0], - High: index[1], - } - } - - return &ast.IndexExpr{ - Expr: x, - LBrack: lbrack, - RBrack: rbrack, - Index: index[0], - } -} - -func (p *Parser) parseSelector(x ast.Expr) ast.Expr { - if p.trace { - defer un(trace(p, "Selector")) - } - - sel := p.parseIdent() - - return &ast.SelectorExpr{Expr: x, Sel: &ast.StringLit{ - Value: sel.Name, - ValuePos: sel.NamePos, - Literal: sel.Name, - }} -} - -func (p *Parser) parseOperand() ast.Expr { - if p.trace { - defer un(trace(p, "Operand")) - } - - switch p.token { - case token.Ident: - return p.parseIdent() - - case token.Int: - v, _ := strconv.ParseInt(p.tokenLit, 10, 64) - x := &ast.IntLit{ - Value: v, - ValuePos: p.pos, - Literal: p.tokenLit, - } - p.next() - return x - - case token.Float: - v, _ := strconv.ParseFloat(p.tokenLit, 64) - x := &ast.FloatLit{ - Value: v, - ValuePos: p.pos, - Literal: p.tokenLit, - } - p.next() - return x - - case token.Char: - return p.parseCharLit() - - case token.String: - v, _ := strconv.Unquote(p.tokenLit) - x := &ast.StringLit{ - Value: v, - ValuePos: p.pos, - Literal: p.tokenLit, - } - p.next() - return x - - case token.True: - x := &ast.BoolLit{ - Value: true, - ValuePos: p.pos, - Literal: p.tokenLit, - } - p.next() - return x - - case token.False: - x := &ast.BoolLit{ - Value: false, - ValuePos: p.pos, - Literal: p.tokenLit, - } - p.next() - return x - - case token.Undefined: - x := &ast.UndefinedLit{TokenPos: p.pos} - p.next() - return x - - case token.Import: - return p.parseImportExpr() - - case token.LParen: - lparen := p.pos - p.next() - p.exprLevel++ - x := p.parseExpr() - p.exprLevel-- - rparen := p.expect(token.RParen) - return &ast.ParenExpr{ - LParen: lparen, - Expr: x, - RParen: rparen, - } - - case token.LBrack: // array literal - return p.parseArrayLit() - - case token.LBrace: // map literal - return p.parseMapLit() - - case token.Func: // function literal - return p.parseFuncLit() - - case token.Error: // error expression - return p.parseErrorExpr() - - case token.Immutable: // immutable expression - return p.parseImmutableExpr() - } - - pos := p.pos - p.errorExpected(pos, "operand") - p.advance(stmtStart) - return &ast.BadExpr{From: pos, To: p.pos} -} - -func (p *Parser) parseImportExpr() ast.Expr { - pos := p.pos - - p.next() - - p.expect(token.LParen) - - if p.token != token.String { - p.errorExpected(p.pos, "module name") - p.advance(stmtStart) - return &ast.BadExpr{From: pos, To: p.pos} - } - - // module name - moduleName, _ := strconv.Unquote(p.tokenLit) - - expr := &ast.ImportExpr{ - ModuleName: moduleName, - Token: token.Import, - TokenPos: pos, - } - - p.next() - - p.expect(token.RParen) - - return expr -} - -func (p *Parser) parseCharLit() ast.Expr { - if n := len(p.tokenLit); n >= 3 { - if code, _, _, err := strconv.UnquoteChar(p.tokenLit[1:n-1], '\''); err == nil { - x := &ast.CharLit{ - Value: rune(code), - ValuePos: p.pos, - Literal: p.tokenLit, - } - p.next() - return x - } - } - - pos := p.pos - p.error(pos, "illegal char literal") - p.next() - return &ast.BadExpr{ - From: pos, - To: p.pos, - } -} - -func (p *Parser) parseFuncLit() ast.Expr { - if p.trace { - defer un(trace(p, "FuncLit")) - } - - typ := p.parseFuncType() - - p.exprLevel++ - body := p.parseBody() - p.exprLevel-- - - return &ast.FuncLit{ - Type: typ, - Body: body, - } -} - -func (p *Parser) parseArrayLit() ast.Expr { - if p.trace { - defer un(trace(p, "ArrayLit")) - } - - lbrack := p.expect(token.LBrack) - p.exprLevel++ - - var elements []ast.Expr - for p.token != token.RBrack && p.token != token.EOF { - elements = append(elements, p.parseExpr()) - - if !p.expectComma(token.RBrack, "array element") { - break - } - } - - p.exprLevel-- - rbrack := p.expect(token.RBrack) - - return &ast.ArrayLit{ - Elements: elements, - LBrack: lbrack, - RBrack: rbrack, - } -} - -func (p *Parser) parseErrorExpr() ast.Expr { - pos := p.pos - - p.next() - - lparen := p.expect(token.LParen) - value := p.parseExpr() - rparen := p.expect(token.RParen) - - expr := &ast.ErrorExpr{ - ErrorPos: pos, - Expr: value, - LParen: lparen, - RParen: rparen, - } - - return expr -} - -func (p *Parser) parseImmutableExpr() ast.Expr { - pos := p.pos - - p.next() - - lparen := p.expect(token.LParen) - value := p.parseExpr() - rparen := p.expect(token.RParen) - - expr := &ast.ImmutableExpr{ - ErrorPos: pos, - Expr: value, - LParen: lparen, - RParen: rparen, - } - - return expr -} - -func (p *Parser) parseFuncType() *ast.FuncType { - if p.trace { - defer un(trace(p, "FuncType")) - } - - pos := p.expect(token.Func) - params := p.parseIdentList() - - return &ast.FuncType{ - FuncPos: pos, - Params: params, - } -} - -func (p *Parser) parseBody() *ast.BlockStmt { - if p.trace { - defer un(trace(p, "Body")) - } - - lbrace := p.expect(token.LBrace) - list := p.parseStmtList() - rbrace := p.expect(token.RBrace) - - return &ast.BlockStmt{ - LBrace: lbrace, - RBrace: rbrace, - Stmts: list, - } -} - -func (p *Parser) parseStmtList() (list []ast.Stmt) { - if p.trace { - defer un(trace(p, "StatementList")) - } - - for p.token != token.RBrace && p.token != token.EOF { - list = append(list, p.parseStmt()) - } - - return -} - -func (p *Parser) parseIdent() *ast.Ident { - pos := p.pos - name := "_" - - if p.token == token.Ident { - name = p.tokenLit - p.next() - } else { - p.expect(token.Ident) - } - - return &ast.Ident{ - NamePos: pos, - Name: name, - } -} - -func (p *Parser) parseIdentList() *ast.IdentList { - if p.trace { - defer un(trace(p, "IdentList")) - } - - var params []*ast.Ident - lparen := p.expect(token.LParen) - isVarArgs := false - if p.token != token.RParen { - if p.token == token.Ellipsis { - isVarArgs = true - p.next() - } - - params = append(params, p.parseIdent()) - for !isVarArgs && p.token == token.Comma { - p.next() - if p.token == token.Ellipsis { - isVarArgs = true - p.next() - } - params = append(params, p.parseIdent()) - } - } - - rparen := p.expect(token.RParen) - - return &ast.IdentList{ - LParen: lparen, - RParen: rparen, - VarArgs: isVarArgs, - List: params, - } -} - -func (p *Parser) parseStmt() (stmt ast.Stmt) { - if p.trace { - defer un(trace(p, "Statement")) - } - - switch p.token { - case // simple statements - token.Func, token.Error, token.Immutable, token.Ident, token.Int, token.Float, token.Char, token.String, token.True, token.False, - token.Undefined, token.Import, token.LParen, token.LBrace, token.LBrack, - token.Add, token.Sub, token.Mul, token.And, token.Xor, token.Not: - s := p.parseSimpleStmt(false) - p.expectSemi() - return s - case token.Return: - return p.parseReturnStmt() - case token.Export: - return p.parseExportStmt() - case token.If: - return p.parseIfStmt() - case token.For: - return p.parseForStmt() - case token.Break, token.Continue: - return p.parseBranchStmt(p.token) - case token.Semicolon: - s := &ast.EmptyStmt{Semicolon: p.pos, Implicit: p.tokenLit == "\n"} - p.next() - return s - case token.RBrace: - // semicolon may be omitted before a closing "}" - return &ast.EmptyStmt{Semicolon: p.pos, Implicit: true} - default: - pos := p.pos - p.errorExpected(pos, "statement") - p.advance(stmtStart) - return &ast.BadStmt{From: pos, To: p.pos} - } -} - -func (p *Parser) parseForStmt() ast.Stmt { - if p.trace { - defer un(trace(p, "ForStmt")) - } - - pos := p.expect(token.For) - - // for {} - if p.token == token.LBrace { - body := p.parseBlockStmt() - p.expectSemi() - - return &ast.ForStmt{ - ForPos: pos, - Body: body, - } - } - - prevLevel := p.exprLevel - p.exprLevel = -1 - - var s1 ast.Stmt - if p.token != token.Semicolon { // skipping init - s1 = p.parseSimpleStmt(true) - } - - // for _ in seq {} or - // for value in seq {} or - // for key, value in seq {} - if forInStmt, isForIn := s1.(*ast.ForInStmt); isForIn { - forInStmt.ForPos = pos - p.exprLevel = prevLevel - forInStmt.Body = p.parseBlockStmt() - p.expectSemi() - return forInStmt - } - - // for init; cond; post {} - var s2, s3 ast.Stmt - if p.token == token.Semicolon { - p.next() - if p.token != token.Semicolon { - s2 = p.parseSimpleStmt(false) // cond - } - p.expect(token.Semicolon) - if p.token != token.LBrace { - s3 = p.parseSimpleStmt(false) // post - } - } else { - // for cond {} - s2 = s1 - s1 = nil - } - - // body - p.exprLevel = prevLevel - body := p.parseBlockStmt() - p.expectSemi() - - cond := p.makeExpr(s2, "condition expression") - - return &ast.ForStmt{ - ForPos: pos, - Init: s1, - Cond: cond, - Post: s3, - Body: body, - } - -} - -func (p *Parser) parseBranchStmt(tok token.Token) ast.Stmt { - if p.trace { - defer un(trace(p, "BranchStmt")) - } - - pos := p.expect(tok) - - var label *ast.Ident - if p.token == token.Ident { - label = p.parseIdent() - } - p.expectSemi() - - return &ast.BranchStmt{ - Token: tok, - TokenPos: pos, - Label: label, - } -} - -func (p *Parser) parseIfStmt() ast.Stmt { - if p.trace { - defer un(trace(p, "IfStmt")) - } - - pos := p.expect(token.If) - - init, cond := p.parseIfHeader() - body := p.parseBlockStmt() - - var elseStmt ast.Stmt - if p.token == token.Else { - p.next() - - switch p.token { - case token.If: - elseStmt = p.parseIfStmt() - case token.LBrace: - elseStmt = p.parseBlockStmt() - p.expectSemi() - default: - p.errorExpected(p.pos, "if or {") - elseStmt = &ast.BadStmt{From: p.pos, To: p.pos} - } - } else { - p.expectSemi() - } - - return &ast.IfStmt{ - IfPos: pos, - Init: init, - Cond: cond, - Body: body, - Else: elseStmt, - } -} - -func (p *Parser) parseBlockStmt() *ast.BlockStmt { - if p.trace { - defer un(trace(p, "BlockStmt")) - } - - lbrace := p.expect(token.LBrace) - list := p.parseStmtList() - rbrace := p.expect(token.RBrace) - - return &ast.BlockStmt{ - LBrace: lbrace, - RBrace: rbrace, - Stmts: list, - } -} - -func (p *Parser) parseIfHeader() (init ast.Stmt, cond ast.Expr) { - if p.token == token.LBrace { - p.error(p.pos, "missing condition in if statement") - cond = &ast.BadExpr{From: p.pos, To: p.pos} - return - } - - outer := p.exprLevel - p.exprLevel = -1 - - if p.token == token.Semicolon { - p.error(p.pos, "missing init in if statement") - return - } - - init = p.parseSimpleStmt(false) - - var condStmt ast.Stmt - if p.token == token.LBrace { - condStmt = init - init = nil - } else if p.token == token.Semicolon { - p.next() - - condStmt = p.parseSimpleStmt(false) - } else { - p.error(p.pos, "missing condition in if statement") - } - - if condStmt != nil { - cond = p.makeExpr(condStmt, "boolean expression") - } - - if cond == nil { - cond = &ast.BadExpr{From: p.pos, To: p.pos} - } - - p.exprLevel = outer - - return -} - -func (p *Parser) makeExpr(s ast.Stmt, want string) ast.Expr { - if s == nil { - return nil - } - - if es, isExpr := s.(*ast.ExprStmt); isExpr { - return es.Expr - } - - found := "simple statement" - if _, isAss := s.(*ast.AssignStmt); isAss { - found = "assignment" - } - - p.error(s.Pos(), fmt.Sprintf("expected %s, found %s", want, found)) - - return &ast.BadExpr{From: s.Pos(), To: p.safePos(s.End())} -} - -func (p *Parser) parseReturnStmt() ast.Stmt { - if p.trace { - defer un(trace(p, "ReturnStmt")) - } - - pos := p.pos - p.expect(token.Return) - - var x ast.Expr - if p.token != token.Semicolon && p.token != token.RBrace { - x = p.parseExpr() - } - p.expectSemi() - - return &ast.ReturnStmt{ - ReturnPos: pos, - Result: x, - } -} - -func (p *Parser) parseExportStmt() ast.Stmt { - if p.trace { - defer un(trace(p, "ExportStmt")) - } - - pos := p.pos - p.expect(token.Export) - - x := p.parseExpr() - p.expectSemi() - - return &ast.ExportStmt{ - ExportPos: pos, - Result: x, - } -} - -func (p *Parser) parseSimpleStmt(forIn bool) ast.Stmt { - if p.trace { - defer un(trace(p, "SimpleStmt")) - } - - x := p.parseExprList() - - switch p.token { - case token.Assign, token.Define: // assignment statement - pos, tok := p.pos, p.token - p.next() - - y := p.parseExprList() - - return &ast.AssignStmt{ - LHS: x, - RHS: y, - Token: tok, - TokenPos: pos, - } - case token.In: - if forIn { - p.next() - - y := p.parseExpr() - - var key, value *ast.Ident - var ok bool - - switch len(x) { - case 1: - key = &ast.Ident{Name: "_", NamePos: x[0].Pos()} - - value, ok = x[0].(*ast.Ident) - if !ok { - p.errorExpected(x[0].Pos(), "identifier") - value = &ast.Ident{Name: "_", NamePos: x[0].Pos()} - } - case 2: - key, ok = x[0].(*ast.Ident) - if !ok { - p.errorExpected(x[0].Pos(), "identifier") - key = &ast.Ident{Name: "_", NamePos: x[0].Pos()} - } - value, ok = x[1].(*ast.Ident) - if !ok { - p.errorExpected(x[1].Pos(), "identifier") - value = &ast.Ident{Name: "_", NamePos: x[1].Pos()} - } - } - - return &ast.ForInStmt{ - Key: key, - Value: value, - Iterable: y, - } - } - } - - if len(x) > 1 { - p.errorExpected(x[0].Pos(), "1 expression") - // continue with first expression - } - - switch p.token { - case token.Define, - token.AddAssign, token.SubAssign, token.MulAssign, token.QuoAssign, token.RemAssign, - token.AndAssign, token.OrAssign, token.XorAssign, token.ShlAssign, token.ShrAssign, token.AndNotAssign: - pos, tok := p.pos, p.token - p.next() - - y := p.parseExpr() - - return &ast.AssignStmt{ - LHS: []ast.Expr{x[0]}, - RHS: []ast.Expr{y}, - Token: tok, - TokenPos: pos, - } - case token.Inc, token.Dec: - // increment or decrement statement - s := &ast.IncDecStmt{Expr: x[0], Token: p.token, TokenPos: p.pos} - p.next() - return s - } - - // expression statement - return &ast.ExprStmt{Expr: x[0]} -} - -func (p *Parser) parseExprList() (list []ast.Expr) { - if p.trace { - defer un(trace(p, "ExpressionList")) - } - - list = append(list, p.parseExpr()) - for p.token == token.Comma { - p.next() - list = append(list, p.parseExpr()) - } - - return -} - -func (p *Parser) parseMapElementLit() *ast.MapElementLit { - if p.trace { - defer un(trace(p, "MapElementLit")) - } - - pos := p.pos - name := "_" - - if p.token == token.Ident { - name = p.tokenLit - } else if p.token == token.String { - v, _ := strconv.Unquote(p.tokenLit) - name = v - } else { - p.errorExpected(pos, "map key") - } - - p.next() - - colonPos := p.expect(token.Colon) - valueExpr := p.parseExpr() - - return &ast.MapElementLit{ - Key: name, - KeyPos: pos, - ColonPos: colonPos, - Value: valueExpr, - } -} - -func (p *Parser) parseMapLit() *ast.MapLit { - if p.trace { - defer un(trace(p, "MapLit")) - } - - lbrace := p.expect(token.LBrace) - p.exprLevel++ - - var elements []*ast.MapElementLit - for p.token != token.RBrace && p.token != token.EOF { - elements = append(elements, p.parseMapElementLit()) - - if !p.expectComma(token.RBrace, "map element") { - break - } - } - - p.exprLevel-- - rbrace := p.expect(token.RBrace) - - return &ast.MapLit{ - LBrace: lbrace, - RBrace: rbrace, - Elements: elements, - } -} - -func (p *Parser) expect(token token.Token) source.Pos { - pos := p.pos - - if p.token != token { - p.errorExpected(pos, "'"+token.String()+"'") - } - p.next() - - return pos -} - -func (p *Parser) expectSemi() { - switch p.token { - case token.RParen, token.RBrace: - // semicolon is optional before a closing ')' or '}' - case token.Comma: - // permit a ',' instead of a ';' but complain - p.errorExpected(p.pos, "';'") - fallthrough - case token.Semicolon: - p.next() - default: - p.errorExpected(p.pos, "';'") - p.advance(stmtStart) - } - -} - -func (p *Parser) advance(to map[token.Token]bool) { - for ; p.token != token.EOF; p.next() { - if to[p.token] { - if p.pos == p.syncPos && p.syncCount < 10 { - p.syncCount++ - return - } - - if p.pos > p.syncPos { - p.syncPos = p.pos - p.syncCount = 0 - return - } - } - } -} - -func (p *Parser) error(pos source.Pos, msg string) { - filePos := p.file.Position(pos) - - n := len(p.errors) - if n > 0 && p.errors[n-1].Pos.Line == filePos.Line { - // discard errors reported on the same line - return - } - - if n > 10 { - // too many errors; terminate early - panic(bailout{}) - } - - p.errors.Add(filePos, msg) -} - -func (p *Parser) errorExpected(pos source.Pos, msg string) { - msg = "expected " + msg - if pos == p.pos { - // error happened at the current position: provide more specific - switch { - case p.token == token.Semicolon && p.tokenLit == "\n": - msg += ", found newline" - case p.token.IsLiteral(): - msg += ", found " + p.tokenLit - default: - msg += ", found '" + p.token.String() + "'" - } - } - - p.error(pos, msg) -} - -func (p *Parser) next() { - if p.trace && p.pos.IsValid() { - s := p.token.String() - switch { - case p.token.IsLiteral(): - p.printTrace(s, p.tokenLit) - case p.token.IsOperator(), p.token.IsKeyword(): - p.printTrace(`"` + s + `"`) - default: - p.printTrace(s) - } - } - - p.token, p.tokenLit, p.pos = p.scanner.Scan() -} - -func (p *Parser) printTrace(a ...interface{}) { - const ( - dots = ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . " - n = len(dots) - ) - - filePos := p.file.Position(p.pos) - _, _ = fmt.Fprintf(p.traceOut, "%5d: %5d:%3d: ", p.pos, filePos.Line, filePos.Column) - - i := 2 * p.indent - for i > n { - _, _ = fmt.Fprint(p.traceOut, dots) - i -= n - } - _, _ = fmt.Fprint(p.traceOut, dots[0:i]) - _, _ = fmt.Fprintln(p.traceOut, a...) -} - -func (p *Parser) safePos(pos source.Pos) source.Pos { - fileBase := p.file.Base - fileSize := p.file.Size - - if int(pos) < fileBase || int(pos) > fileBase+fileSize { - return source.Pos(fileBase + fileSize) - } - - return pos -} - -func trace(p *Parser, msg string) *Parser { - p.printTrace(msg, "(") - p.indent++ - - return p -} - -func un(p *Parser) { - p.indent-- - p.printTrace(")") -} diff --git a/vendor/github.com/d5/tengo/compiler/parser/sync.go b/vendor/github.com/d5/tengo/compiler/parser/sync.go deleted file mode 100644 index e68d623a..00000000 --- a/vendor/github.com/d5/tengo/compiler/parser/sync.go +++ /dev/null @@ -1,12 +0,0 @@ -package parser - -import "github.com/d5/tengo/compiler/token" - -var stmtStart = map[token.Token]bool{ - token.Break: true, - token.Continue: true, - token.For: true, - token.If: true, - token.Return: true, - token.Export: true, -} diff --git a/vendor/github.com/d5/tengo/compiler/scanner/error_handler.go b/vendor/github.com/d5/tengo/compiler/scanner/error_handler.go deleted file mode 100644 index 379f0196..00000000 --- a/vendor/github.com/d5/tengo/compiler/scanner/error_handler.go +++ /dev/null @@ -1,6 +0,0 @@ -package scanner - -import "github.com/d5/tengo/compiler/source" - -// ErrorHandler is an error handler for the scanner. -type ErrorHandler func(pos source.FilePos, msg string) diff --git a/vendor/github.com/d5/tengo/compiler/scanner/mode.go b/vendor/github.com/d5/tengo/compiler/scanner/mode.go deleted file mode 100644 index f67ceaf8..00000000 --- a/vendor/github.com/d5/tengo/compiler/scanner/mode.go +++ /dev/null @@ -1,10 +0,0 @@ -package scanner - -// Mode represents a scanner mode. -type Mode int - -// List of scanner modes. -const ( - ScanComments Mode = 1 << iota - DontInsertSemis -) diff --git a/vendor/github.com/d5/tengo/compiler/scanner/scanner.go b/vendor/github.com/d5/tengo/compiler/scanner/scanner.go deleted file mode 100644 index 387cd8ee..00000000 --- a/vendor/github.com/d5/tengo/compiler/scanner/scanner.go +++ /dev/null @@ -1,680 +0,0 @@ -/* - Scanner reads the Tengo source text and tokenize them. - - Scanner is a modified version of Go's scanner implementation. - - Copyright 2009 The Go Authors. All rights reserved. - Use of this source code is governed by a BSD-style - license that can be found in the LICENSE file. -*/ - -package scanner - -import ( - "fmt" - "unicode" - "unicode/utf8" - - "github.com/d5/tengo/compiler/source" - "github.com/d5/tengo/compiler/token" -) - -// byte order mark -const bom = 0xFEFF - -// Scanner reads the Tengo source text. -type Scanner struct { - file *source.File // source file handle - src []byte // source - ch rune // current character - offset int // character offset - readOffset int // reading offset (position after current character) - lineOffset int // current line offset - insertSemi bool // insert a semicolon before next newline - errorHandler ErrorHandler // error reporting; or nil - errorCount int // number of errors encountered - mode Mode -} - -// NewScanner creates a Scanner. -func NewScanner(file *source.File, src []byte, errorHandler ErrorHandler, mode Mode) *Scanner { - if file.Size != len(src) { - panic(fmt.Sprintf("file size (%d) does not match src len (%d)", file.Size, len(src))) - } - - s := &Scanner{ - file: file, - src: src, - errorHandler: errorHandler, - ch: ' ', - mode: mode, - } - - s.next() - if s.ch == bom { - s.next() // ignore BOM at file beginning - } - - return s -} - -// ErrorCount returns the number of errors. -func (s *Scanner) ErrorCount() int { - return s.errorCount -} - -// Scan returns a token, token literal and its position. -func (s *Scanner) Scan() (tok token.Token, literal string, pos source.Pos) { - s.skipWhitespace() - - pos = s.file.FileSetPos(s.offset) - - insertSemi := false - - // determine token value - switch ch := s.ch; { - case isLetter(ch): - literal = s.scanIdentifier() - tok = token.Lookup(literal) - switch tok { - case token.Ident, token.Break, token.Continue, token.Return, token.Export, token.True, token.False, token.Undefined: - insertSemi = true - } - case '0' <= ch && ch <= '9': - insertSemi = true - tok, literal = s.scanNumber(false) - default: - s.next() // always make progress - - switch ch { - case -1: // EOF - if s.insertSemi { - s.insertSemi = false // EOF consumed - return token.Semicolon, "\n", pos - } - tok = token.EOF - case '\n': - // we only reach here if s.insertSemi was set in the first place - s.insertSemi = false // newline consumed - return token.Semicolon, "\n", pos - case '"': - insertSemi = true - tok = token.String - literal = s.scanString() - case '\'': - insertSemi = true - tok = token.Char - literal = s.scanRune() - case '`': - insertSemi = true - tok = token.String - literal = s.scanRawString() - 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 - } - } - case ',': - tok = token.Comma - case '?': - tok = token.Question - case ';': - tok = token.Semicolon - literal = ";" - case '(': - tok = token.LParen - case ')': - insertSemi = true - tok = token.RParen - case '[': - tok = token.LBrack - case ']': - insertSemi = true - tok = token.RBrack - case '{': - tok = token.LBrace - case '}': - insertSemi = true - tok = token.RBrace - case '+': - tok = s.switch3(token.Add, token.AddAssign, '+', token.Inc) - if tok == token.Inc { - insertSemi = true - } - case '-': - tok = s.switch3(token.Sub, token.SubAssign, '-', token.Dec) - if tok == token.Dec { - insertSemi = true - } - case '*': - tok = s.switch2(token.Mul, token.MulAssign) - case '/': - if s.ch == '/' || s.ch == '*' { - // comment - if s.insertSemi && s.findLineEnd() { - // reset position to the beginning of the comment - s.ch = '/' - s.offset = s.file.Offset(pos) - s.readOffset = s.offset + 1 - s.insertSemi = false // newline consumed - return token.Semicolon, "\n", pos - } - comment := s.scanComment() - if s.mode&ScanComments == 0 { - // skip comment - s.insertSemi = false // newline consumed - return s.Scan() - } - tok = token.Comment - literal = comment - } else { - tok = s.switch2(token.Quo, token.QuoAssign) - } - case '%': - tok = s.switch2(token.Rem, token.RemAssign) - case '^': - tok = s.switch2(token.Xor, token.XorAssign) - case '<': - tok = s.switch4(token.Less, token.LessEq, '<', token.Shl, token.ShlAssign) - case '>': - tok = s.switch4(token.Greater, token.GreaterEq, '>', token.Shr, token.ShrAssign) - case '=': - tok = s.switch2(token.Assign, token.Equal) - case '!': - tok = s.switch2(token.Not, token.NotEqual) - case '&': - if s.ch == '^' { - s.next() - tok = s.switch2(token.AndNot, token.AndNotAssign) - } else { - tok = s.switch3(token.And, token.AndAssign, '&', token.LAnd) - } - case '|': - tok = s.switch3(token.Or, token.OrAssign, '|', token.LOr) - default: - // next reports unexpected BOMs - don't repeat - if ch != bom { - s.error(s.file.Offset(pos), fmt.Sprintf("illegal character %#U", ch)) - } - insertSemi = s.insertSemi // preserve insertSemi info - tok = token.Illegal - literal = string(ch) - } - } - - if s.mode&DontInsertSemis == 0 { - s.insertSemi = insertSemi - } - - return -} - -func (s *Scanner) next() { - if s.readOffset < len(s.src) { - s.offset = s.readOffset - if s.ch == '\n' { - s.lineOffset = s.offset - s.file.AddLine(s.offset) - } - r, w := rune(s.src[s.readOffset]), 1 - switch { - case r == 0: - s.error(s.offset, "illegal character NUL") - case r >= utf8.RuneSelf: - // not ASCII - r, w = utf8.DecodeRune(s.src[s.readOffset:]) - if r == utf8.RuneError && w == 1 { - s.error(s.offset, "illegal UTF-8 encoding") - } else if r == bom && s.offset > 0 { - s.error(s.offset, "illegal byte order mark") - } - } - s.readOffset += w - s.ch = r - } else { - s.offset = len(s.src) - if s.ch == '\n' { - s.lineOffset = s.offset - s.file.AddLine(s.offset) - } - s.ch = -1 // eof - } -} - -func (s *Scanner) peek() byte { - if s.readOffset < len(s.src) { - return s.src[s.readOffset] - } - - return 0 -} - -func (s *Scanner) error(offset int, msg string) { - if s.errorHandler != nil { - s.errorHandler(s.file.Position(s.file.FileSetPos(offset)), msg) - } - - s.errorCount++ -} - -func (s *Scanner) scanComment() string { - // initial '/' already consumed; s.ch == '/' || s.ch == '*' - offs := s.offset - 1 // position of initial '/' - var numCR int - - if s.ch == '/' { - //-style comment - // (the final '\n' is not considered part of the comment) - s.next() - for s.ch != '\n' && s.ch >= 0 { - if s.ch == '\r' { - numCR++ - } - s.next() - } - goto exit - } - - /*-style comment */ - s.next() - for s.ch >= 0 { - ch := s.ch - if ch == '\r' { - numCR++ - } - s.next() - if ch == '*' && s.ch == '/' { - s.next() - goto exit - } - } - - s.error(offs, "comment not terminated") - -exit: - lit := s.src[offs:s.offset] - - // On Windows, a (//-comment) line may end in "\r\n". - // Remove the final '\r' before analyzing the text for line directives (matching the compiler). - // Remove any other '\r' afterwards (matching the pre-existing behavior of the scanner). - if numCR > 0 && len(lit) >= 2 && lit[1] == '/' && lit[len(lit)-1] == '\r' { - lit = lit[:len(lit)-1] - numCR-- - } - - if numCR > 0 { - lit = StripCR(lit, lit[1] == '*') - } - - return string(lit) -} - -func (s *Scanner) findLineEnd() bool { - // initial '/' already consumed - - defer func(offs int) { - // reset scanner state to where it was upon calling findLineEnd - s.ch = '/' - s.offset = offs - s.readOffset = offs + 1 - s.next() // consume initial '/' again - }(s.offset - 1) - - // read ahead until a newline, EOF, or non-comment tok is found - for s.ch == '/' || s.ch == '*' { - if s.ch == '/' { - //-style comment always contains a newline - return true - } - /*-style comment: look for newline */ - s.next() - for s.ch >= 0 { - ch := s.ch - if ch == '\n' { - return true - } - s.next() - if ch == '*' && s.ch == '/' { - s.next() - break - } - } - s.skipWhitespace() // s.insertSemi is set - if s.ch < 0 || s.ch == '\n' { - return true - } - if s.ch != '/' { - // non-comment tok - return false - } - s.next() // consume '/' - } - - return false -} - -func (s *Scanner) scanIdentifier() string { - offs := s.offset - for isLetter(s.ch) || isDigit(s.ch) { - s.next() - } - - return string(s.src[offs:s.offset]) -} - -func (s *Scanner) scanMantissa(base int) { - for digitVal(s.ch) < base { - s.next() - } -} - -func (s *Scanner) scanNumber(seenDecimalPoint bool) (tok token.Token, lit string) { - // digitVal(s.ch) < 10 - 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 - } - - if s.ch == '0' { - // int or float - offs := s.offset - 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) - -fraction: - if s.ch == '.' { - tok = token.Float - s.next() - s.scanMantissa(10) - } - -exponent: - if s.ch == 'e' || s.ch == 'E' { - 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") - } - } - - return -} - -func (s *Scanner) scanEscape(quote rune) bool { - offs := s.offset - - var n int - var base, max uint32 - switch s.ch { - case 'a', 'b', 'f', 'n', 'r', 't', 'v', '\\', quote: - s.next() - return true - case '0', '1', '2', '3', '4', '5', '6', '7': - n, base, max = 3, 8, 255 - case 'x': - s.next() - n, base, max = 2, 16, 255 - case 'u': - s.next() - n, base, max = 4, 16, unicode.MaxRune - case 'U': - s.next() - n, base, max = 8, 16, unicode.MaxRune - default: - msg := "unknown escape sequence" - if s.ch < 0 { - msg = "escape sequence not terminated" - } - s.error(offs, msg) - return false - } - - var x uint32 - for n > 0 { - d := uint32(digitVal(s.ch)) - if d >= base { - msg := fmt.Sprintf("illegal character %#U in escape sequence", s.ch) - if s.ch < 0 { - msg = "escape sequence not terminated" - } - s.error(s.offset, msg) - return false - } - x = x*base + d - s.next() - n-- - } - - if x > max || 0xD800 <= x && x < 0xE000 { - s.error(offs, "escape sequence is invalid Unicode code point") - return false - } - - return true -} - -func (s *Scanner) scanRune() string { - offs := s.offset - 1 // '\'' opening already consumed - - valid := true - n := 0 - for { - ch := s.ch - if ch == '\n' || ch < 0 { - // only report error if we don't have one already - if valid { - s.error(offs, "rune literal not terminated") - valid = false - } - break - } - s.next() - if ch == '\'' { - break - } - n++ - if ch == '\\' { - if !s.scanEscape('\'') { - valid = false - } - // continue to read to closing quote - } - } - - if valid && n != 1 { - s.error(offs, "illegal rune literal") - } - - return string(s.src[offs:s.offset]) -} - -func (s *Scanner) scanString() string { - offs := s.offset - 1 // '"' opening already consumed - - for { - ch := s.ch - if ch == '\n' || ch < 0 { - s.error(offs, "string literal not terminated") - break - } - s.next() - if ch == '"' { - break - } - if ch == '\\' { - s.scanEscape('"') - } - } - - return string(s.src[offs:s.offset]) -} - -func (s *Scanner) scanRawString() string { - offs := s.offset - 1 // '`' opening already consumed - - hasCR := false - for { - ch := s.ch - if ch < 0 { - s.error(offs, "raw string literal not terminated") - break - } - - s.next() - - if ch == '`' { - break - } - - if ch == '\r' { - hasCR = true - } - } - - lit := s.src[offs:s.offset] - if hasCR { - lit = StripCR(lit, false) - } - - return string(lit) -} - -// StripCR removes carriage return characters. -func StripCR(b []byte, comment bool) []byte { - c := make([]byte, len(b)) - - i := 0 - for j, ch := range b { - // In a /*-style comment, don't strip \r from *\r/ (incl. sequences of \r from *\r\r...\r/) - // since the resulting */ would terminate the comment too early unless the \r is immediately - // following the opening /* in which case it's ok because /*/ is not closed yet. - if ch != '\r' || comment && i > len("/*") && c[i-1] == '*' && j+1 < len(b) && b[j+1] == '/' { - c[i] = ch - i++ - } - } - - return c[:i] -} - -func (s *Scanner) skipWhitespace() { - for s.ch == ' ' || s.ch == '\t' || s.ch == '\n' && !s.insertSemi || s.ch == '\r' { - s.next() - } -} - -func (s *Scanner) switch2(tok0, tok1 token.Token) token.Token { - if s.ch == '=' { - s.next() - return tok1 - } - - return tok0 -} - -func (s *Scanner) switch3(tok0, tok1 token.Token, ch2 rune, tok2 token.Token) token.Token { - if s.ch == '=' { - s.next() - return tok1 - } - - if s.ch == ch2 { - s.next() - return tok2 - } - - return tok0 -} - -func (s *Scanner) switch4(tok0, tok1 token.Token, ch2 rune, tok2, tok3 token.Token) token.Token { - if s.ch == '=' { - s.next() - return tok1 - } - - if s.ch == ch2 { - s.next() - if s.ch == '=' { - s.next() - return tok3 - } - - return tok2 - } - - return tok0 -} - -func isLetter(ch rune) bool { - return 'a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z' || ch == '_' || ch >= utf8.RuneSelf && unicode.IsLetter(ch) -} - -func isDigit(ch rune) bool { - return '0' <= ch && ch <= '9' || ch >= utf8.RuneSelf && unicode.IsDigit(ch) -} - -func digitVal(ch rune) int { - switch { - case '0' <= ch && ch <= '9': - return int(ch - '0') - case 'a' <= ch && ch <= 'f': - return int(ch - 'a' + 10) - case 'A' <= ch && ch <= 'F': - return int(ch - 'A' + 10) - } - - return 16 // larger than any legal digit val -} diff --git a/vendor/github.com/d5/tengo/compiler/source/file.go b/vendor/github.com/d5/tengo/compiler/source/file.go deleted file mode 100644 index 9e51c9a4..00000000 --- a/vendor/github.com/d5/tengo/compiler/source/file.go +++ /dev/null @@ -1,110 +0,0 @@ -package source - -// File represents a source file. -type File struct { - // File set for the file - set *FileSet - // File name as provided to AddFile - Name string - // Pos value range for this file is [base...base+size] - Base int - // File size as provided to AddFile - Size int - // Lines contains the offset of the first character for each line (the first entry is always 0) - Lines []int -} - -// Set returns FileSet. -func (f *File) Set() *FileSet { - return f.set -} - -// LineCount returns the current number of lines. -func (f *File) LineCount() int { - return len(f.Lines) -} - -// AddLine adds a new line. -func (f *File) AddLine(offset int) { - if i := len(f.Lines); (i == 0 || f.Lines[i-1] < offset) && offset < f.Size { - f.Lines = append(f.Lines, offset) - } -} - -// LineStart returns the position of the first character in the line. -func (f *File) LineStart(line int) Pos { - if line < 1 { - panic("illegal line number (line numbering starts at 1)") - } - - if line > len(f.Lines) { - panic("illegal line number") - } - - return Pos(f.Base + f.Lines[line-1]) -} - -// FileSetPos returns the position in the file set. -func (f *File) FileSetPos(offset int) Pos { - if offset > f.Size { - panic("illegal file offset") - } - - return Pos(f.Base + offset) -} - -// Offset translates the file set position into the file offset. -func (f *File) Offset(p Pos) int { - if int(p) < f.Base || int(p) > f.Base+f.Size { - panic("illegal Pos value") - } - - return int(p) - f.Base -} - -// Position translates the file set position into the file position. -func (f *File) Position(p Pos) (pos FilePos) { - if p != NoPos { - if int(p) < f.Base || int(p) > f.Base+f.Size { - panic("illegal Pos value") - } - - pos = f.position(p) - } - - return -} - -func (f *File) position(p Pos) (pos FilePos) { - offset := int(p) - f.Base - pos.Offset = offset - pos.Filename, pos.Line, pos.Column = f.unpack(offset) - - return -} - -func (f *File) unpack(offset int) (filename string, line, column int) { - filename = f.Name - if i := searchInts(f.Lines, offset); i >= 0 { - line, column = i+1, offset-f.Lines[i]+1 - } - - return -} - -func searchInts(a []int, x int) int { - // This function body is a manually inlined version of: - // return sort.Search(len(a), func(i int) bool { return a[i] > x }) - 1 - i, j := 0, len(a) - for i < j { - h := i + (j-i)/2 // avoid overflow when computing h - // i ≤ h < j - if a[h] <= x { - i = h + 1 - } else { - j = h - } - } - - return i - 1 -} diff --git a/vendor/github.com/d5/tengo/compiler/source/file_pos.go b/vendor/github.com/d5/tengo/compiler/source/file_pos.go deleted file mode 100644 index 4055fe6d..00000000 --- a/vendor/github.com/d5/tengo/compiler/source/file_pos.go +++ /dev/null @@ -1,47 +0,0 @@ -package source - -import "fmt" - -// FilePos represents a position information in the file. -type FilePos struct { - Filename string // filename, if any - Offset int // offset, starting at 0 - Line int // line number, starting at 1 - Column int // column number, starting at 1 (byte count) -} - -// IsValid returns true if the position is valid. -func (p FilePos) IsValid() bool { - return p.Line > 0 -} - -// String returns a string in one of several forms: -// -// file:line:column valid position with file name -// file:line valid position with file name but no column (column == 0) -// line:column valid position without file name -// line valid position without file name and no column (column == 0) -// file invalid position with file name -// - invalid position without file name -// -func (p FilePos) String() string { - s := p.Filename - - if p.IsValid() { - if s != "" { - s += ":" - } - - s += fmt.Sprintf("%d", p.Line) - - if p.Column != 0 { - s += fmt.Sprintf(":%d", p.Column) - } - } - - if s == "" { - s = "-" - } - - return s -} diff --git a/vendor/github.com/d5/tengo/compiler/source/file_set.go b/vendor/github.com/d5/tengo/compiler/source/file_set.go deleted file mode 100644 index da342364..00000000 --- a/vendor/github.com/d5/tengo/compiler/source/file_set.go +++ /dev/null @@ -1,96 +0,0 @@ -package source - -import ( - "sort" -) - -// FileSet represents a set of source files. -type FileSet struct { - Base int // base offset for the next file - Files []*File // list of files in the order added to the set - LastFile *File // cache of last file looked up -} - -// NewFileSet creates a new file set. -func NewFileSet() *FileSet { - return &FileSet{ - Base: 1, // 0 == NoPos - } -} - -// AddFile adds a new file in the file set. -func (s *FileSet) AddFile(filename string, base, size int) *File { - if base < 0 { - base = s.Base - } - if base < s.Base || size < 0 { - panic("illegal base or size") - } - - f := &File{ - set: s, - Name: filename, - Base: base, - Size: size, - Lines: []int{0}, - } - - base += size + 1 // +1 because EOF also has a position - if base < 0 { - panic("offset overflow (> 2G of source code in file set)") - } - - // add the file to the file set - s.Base = base - s.Files = append(s.Files, f) - s.LastFile = f - - return f -} - -// File returns the file that contains the position p. -// If no such file is found (for instance for p == NoPos), -// the result is nil. -// -func (s *FileSet) File(p Pos) (f *File) { - if p != NoPos { - f = s.file(p) - } - - return -} - -// Position converts a Pos p in the fileset into a FilePos value. -func (s *FileSet) Position(p Pos) (pos FilePos) { - if p != NoPos { - if f := s.file(p); f != nil { - return f.position(p) - } - } - - return -} - -func (s *FileSet) file(p Pos) *File { - // common case: p is in last file - if f := s.LastFile; f != nil && f.Base <= int(p) && int(p) <= f.Base+f.Size { - return f - } - - // p is not in last file - search all files - if i := searchFiles(s.Files, int(p)); i >= 0 { - f := s.Files[i] - - // f.base <= int(p) by definition of searchFiles - if int(p) <= f.Base+f.Size { - s.LastFile = f // race is ok - s.last is only a cache - return f - } - } - - return nil -} - -func searchFiles(a []*File, x int) int { - return sort.Search(len(a), func(i int) bool { return a[i].Base > x }) - 1 -} diff --git a/vendor/github.com/d5/tengo/compiler/source/pos.go b/vendor/github.com/d5/tengo/compiler/source/pos.go deleted file mode 100644 index 72128b13..00000000 --- a/vendor/github.com/d5/tengo/compiler/source/pos.go +++ /dev/null @@ -1,12 +0,0 @@ -package source - -// Pos represents a position in the file set. -type Pos int - -// NoPos represents an invalid position. -const NoPos Pos = 0 - -// IsValid returns true if the position is valid. -func (p Pos) IsValid() bool { - return p != NoPos -} diff --git a/vendor/github.com/d5/tengo/compiler/symbol.go b/vendor/github.com/d5/tengo/compiler/symbol.go deleted file mode 100644 index bcd53234..00000000 --- a/vendor/github.com/d5/tengo/compiler/symbol.go +++ /dev/null @@ -1,9 +0,0 @@ -package compiler - -// Symbol represents a symbol in the symbol table. -type Symbol struct { - Name string - Scope SymbolScope - Index int - LocalAssigned bool // if the local symbol is assigned at least once -} diff --git a/vendor/github.com/d5/tengo/compiler/symbol_scopes.go b/vendor/github.com/d5/tengo/compiler/symbol_scopes.go deleted file mode 100644 index e0c0d94b..00000000 --- a/vendor/github.com/d5/tengo/compiler/symbol_scopes.go +++ /dev/null @@ -1,12 +0,0 @@ -package compiler - -// SymbolScope represents a symbol scope. -type SymbolScope string - -// List of symbol scopes -const ( - ScopeGlobal SymbolScope = "GLOBAL" - ScopeLocal SymbolScope = "LOCAL" - ScopeBuiltin SymbolScope = "BUILTIN" - ScopeFree SymbolScope = "FREE" -) diff --git a/vendor/github.com/d5/tengo/compiler/symbol_table.go b/vendor/github.com/d5/tengo/compiler/symbol_table.go deleted file mode 100644 index 94c868de..00000000 --- a/vendor/github.com/d5/tengo/compiler/symbol_table.go +++ /dev/null @@ -1,159 +0,0 @@ -package compiler - -// SymbolTable represents a symbol table. -type SymbolTable struct { - parent *SymbolTable - block bool - store map[string]*Symbol - numDefinition int - maxDefinition int - freeSymbols []*Symbol - builtinSymbols []*Symbol -} - -// NewSymbolTable creates a SymbolTable. -func NewSymbolTable() *SymbolTable { - return &SymbolTable{ - store: make(map[string]*Symbol), - } -} - -// Define adds a new symbol in the current scope. -func (t *SymbolTable) Define(name string) *Symbol { - symbol := &Symbol{Name: name, Index: t.nextIndex()} - t.numDefinition++ - - if t.Parent(true) == nil { - symbol.Scope = ScopeGlobal - } else { - symbol.Scope = ScopeLocal - } - - t.store[name] = symbol - - t.updateMaxDefs(symbol.Index + 1) - - return symbol -} - -// DefineBuiltin adds a symbol for builtin function. -func (t *SymbolTable) DefineBuiltin(index int, name string) *Symbol { - if t.parent != nil { - return t.parent.DefineBuiltin(index, name) - } - - symbol := &Symbol{ - Name: name, - Index: index, - Scope: ScopeBuiltin, - } - - t.store[name] = symbol - - t.builtinSymbols = append(t.builtinSymbols, symbol) - - return symbol -} - -// Resolve resolves a symbol with a given name. -func (t *SymbolTable) Resolve(name string) (symbol *Symbol, depth int, ok bool) { - symbol, ok = t.store[name] - if !ok && t.parent != nil { - symbol, depth, ok = t.parent.Resolve(name) - if !ok { - return - } - - depth++ - - // if symbol is defined in parent table and if it's not global/builtin - // then it's free variable. - if !t.block && depth > 0 && symbol.Scope != ScopeGlobal && symbol.Scope != ScopeBuiltin { - return t.defineFree(symbol), depth, true - } - - return - } - - return -} - -// Fork creates a new symbol table for a new scope. -func (t *SymbolTable) Fork(block bool) *SymbolTable { - return &SymbolTable{ - store: make(map[string]*Symbol), - parent: t, - block: block, - } -} - -// Parent returns the outer scope of the current symbol table. -func (t *SymbolTable) Parent(skipBlock bool) *SymbolTable { - if skipBlock && t.block { - return t.parent.Parent(skipBlock) - } - - return t.parent -} - -// MaxSymbols returns the total number of symbols defined in the scope. -func (t *SymbolTable) MaxSymbols() int { - return t.maxDefinition -} - -// FreeSymbols returns free symbols for the scope. -func (t *SymbolTable) FreeSymbols() []*Symbol { - return t.freeSymbols -} - -// BuiltinSymbols returns builtin symbols for the scope. -func (t *SymbolTable) BuiltinSymbols() []*Symbol { - if t.parent != nil { - return t.parent.BuiltinSymbols() - } - - return t.builtinSymbols -} - -// Names returns the name of all the symbols. -func (t *SymbolTable) Names() []string { - var names []string - for name := range t.store { - names = append(names, name) - } - return names -} - -func (t *SymbolTable) nextIndex() int { - if t.block { - return t.parent.nextIndex() + t.numDefinition - } - - return t.numDefinition -} - -func (t *SymbolTable) updateMaxDefs(numDefs int) { - if numDefs > t.maxDefinition { - t.maxDefinition = numDefs - } - - if t.block { - t.parent.updateMaxDefs(numDefs) - } -} - -func (t *SymbolTable) defineFree(original *Symbol) *Symbol { - // TODO: should we check duplicates? - - t.freeSymbols = append(t.freeSymbols, original) - - symbol := &Symbol{ - Name: original.Name, - Index: len(t.freeSymbols) - 1, - Scope: ScopeFree, - } - - t.store[original.Name] = symbol - - return symbol -} diff --git a/vendor/github.com/d5/tengo/compiler/token/keywords.go b/vendor/github.com/d5/tengo/compiler/token/keywords.go deleted file mode 100644 index fd6e9d0b..00000000 --- a/vendor/github.com/d5/tengo/compiler/token/keywords.go +++ /dev/null @@ -1,19 +0,0 @@ -package token - -var keywords map[string]Token - -func init() { - keywords = make(map[string]Token) - for i := _keywordBeg + 1; i < _keywordEnd; i++ { - keywords[tokens[i]] = i - } -} - -// Lookup returns corresponding keyword if ident is a keyword. -func Lookup(ident string) Token { - if tok, isKeyword := keywords[ident]; isKeyword { - return tok - } - - return Ident -} diff --git a/vendor/github.com/d5/tengo/compiler/token/tokens.go b/vendor/github.com/d5/tengo/compiler/token/tokens.go deleted file mode 100644 index b32d36ee..00000000 --- a/vendor/github.com/d5/tengo/compiler/token/tokens.go +++ /dev/null @@ -1,208 +0,0 @@ -package token - -import "strconv" - -// Token represents a token. -type Token int - -// List of tokens -const ( - Illegal Token = iota - EOF - Comment - _literalBeg - Ident - Int - Float - Char - String - _literalEnd - _operatorBeg - Add // + - Sub // - - Mul // * - Quo // / - Rem // % - And // & - Or // | - Xor // ^ - Shl // << - Shr // >> - AndNot // &^ - AddAssign // += - SubAssign // -= - MulAssign // *= - QuoAssign // /= - RemAssign // %= - AndAssign // &= - OrAssign // |= - XorAssign // ^= - ShlAssign // <<= - ShrAssign // >>= - AndNotAssign // &^= - LAnd // && - LOr // || - Inc // ++ - Dec // -- - Equal // == - Less // < - Greater // > - Assign // = - Not // ! - NotEqual // != - LessEq // <= - GreaterEq // >= - Define // := - Ellipsis // ... - LParen // ( - LBrack // [ - LBrace // { - Comma // , - Period // . - RParen // ) - RBrack // ] - RBrace // } - Semicolon // ; - Colon // : - Question // ? - _operatorEnd - _keywordBeg - Break - Continue - Else - For - Func - Error - Immutable - If - Return - Export - True - False - In - Undefined - Import - _keywordEnd -) - -var tokens = [...]string{ - Illegal: "ILLEGAL", - EOF: "EOF", - Comment: "COMMENT", - Ident: "IDENT", - Int: "INT", - Float: "FLOAT", - Char: "CHAR", - String: "STRING", - Add: "+", - Sub: "-", - Mul: "*", - Quo: "/", - Rem: "%", - And: "&", - Or: "|", - Xor: "^", - Shl: "<<", - Shr: ">>", - AndNot: "&^", - AddAssign: "+=", - SubAssign: "-=", - MulAssign: "*=", - QuoAssign: "/=", - RemAssign: "%=", - AndAssign: "&=", - OrAssign: "|=", - XorAssign: "^=", - ShlAssign: "<<=", - ShrAssign: ">>=", - AndNotAssign: "&^=", - LAnd: "&&", - LOr: "||", - Inc: "++", - Dec: "--", - Equal: "==", - Less: "<", - Greater: ">", - Assign: "=", - Not: "!", - NotEqual: "!=", - LessEq: "<=", - GreaterEq: ">=", - Define: ":=", - Ellipsis: "...", - LParen: "(", - LBrack: "[", - LBrace: "{", - Comma: ",", - Period: ".", - RParen: ")", - RBrack: "]", - RBrace: "}", - Semicolon: ";", - Colon: ":", - Question: "?", - Break: "break", - Continue: "continue", - Else: "else", - For: "for", - Func: "func", - Error: "error", - Immutable: "immutable", - If: "if", - Return: "return", - Export: "export", - True: "true", - False: "false", - In: "in", - Undefined: "undefined", - Import: "import", -} - -func (tok Token) String() string { - s := "" - - if 0 <= tok && tok < Token(len(tokens)) { - s = tokens[tok] - } - - if s == "" { - s = "token(" + strconv.Itoa(int(tok)) + ")" - } - - return s -} - -// LowestPrec represents lowest operator precedence. -const LowestPrec = 0 - -// Precedence returns the precedence for the operator token. -func (tok Token) Precedence() int { - switch tok { - case LOr: - return 1 - case LAnd: - return 2 - case Equal, NotEqual, Less, LessEq, Greater, GreaterEq: - return 3 - case Add, Sub, Or, Xor: - return 4 - case Mul, Quo, Rem, Shl, Shr, And, AndNot: - return 5 - } - return LowestPrec -} - -// IsLiteral returns true if the token is a literal. -func (tok Token) IsLiteral() bool { - return _literalBeg < tok && tok < _literalEnd -} - -// IsOperator returns true if the token is an operator. -func (tok Token) IsOperator() bool { - return _operatorBeg < tok && tok < _operatorEnd -} - -// IsKeyword returns true if the token is a keyword. -func (tok Token) IsKeyword() bool { - return _keywordBeg < tok && tok < _keywordEnd -} |