123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349 |
- package parser
- import (
- "strings"
- "github.com/d5/tengo/v2/token"
- )
- // Stmt represents a statement in the AST.
- type Stmt interface {
- Node
- stmtNode()
- }
- // AssignStmt represents an assignment statement.
- type AssignStmt struct {
- LHS []Expr
- RHS []Expr
- Token token.Token
- TokenPos Pos
- }
- func (s *AssignStmt) stmtNode() {}
- // Pos returns the position of first character belonging to the node.
- func (s *AssignStmt) Pos() Pos {
- return s.LHS[0].Pos()
- }
- // End returns the position of first character immediately after the node.
- func (s *AssignStmt) End() 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, ", ")
- }
- // BadStmt represents a bad statement.
- type BadStmt struct {
- From Pos
- To Pos
- }
- func (s *BadStmt) stmtNode() {}
- // Pos returns the position of first character belonging to the node.
- func (s *BadStmt) Pos() Pos {
- return s.From
- }
- // End returns the position of first character immediately after the node.
- func (s *BadStmt) End() Pos {
- return s.To
- }
- func (s *BadStmt) String() string {
- return "<bad statement>"
- }
- // BlockStmt represents a block statement.
- type BlockStmt struct {
- Stmts []Stmt
- LBrace Pos
- RBrace Pos
- }
- func (s *BlockStmt) stmtNode() {}
- // Pos returns the position of first character belonging to the node.
- func (s *BlockStmt) Pos() Pos {
- return s.LBrace
- }
- // End returns the position of first character immediately after the node.
- func (s *BlockStmt) End() 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, "; ") + "}"
- }
- // BranchStmt represents a branch statement.
- type BranchStmt struct {
- Token token.Token
- TokenPos Pos
- Label *Ident
- }
- func (s *BranchStmt) stmtNode() {}
- // Pos returns the position of first character belonging to the node.
- func (s *BranchStmt) Pos() Pos {
- return s.TokenPos
- }
- // End returns the position of first character immediately after the node.
- func (s *BranchStmt) End() Pos {
- if s.Label != nil {
- return s.Label.End()
- }
- return 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
- }
- // EmptyStmt represents an empty statement.
- type EmptyStmt struct {
- Semicolon Pos
- Implicit bool
- }
- func (s *EmptyStmt) stmtNode() {}
- // Pos returns the position of first character belonging to the node.
- func (s *EmptyStmt) Pos() Pos {
- return s.Semicolon
- }
- // End returns the position of first character immediately after the node.
- func (s *EmptyStmt) End() Pos {
- if s.Implicit {
- return s.Semicolon
- }
- return s.Semicolon + 1
- }
- func (s *EmptyStmt) String() string {
- return ";"
- }
- // ExportStmt represents an export statement.
- type ExportStmt struct {
- ExportPos Pos
- Result Expr
- }
- func (s *ExportStmt) stmtNode() {}
- // Pos returns the position of first character belonging to the node.
- func (s *ExportStmt) Pos() Pos {
- return s.ExportPos
- }
- // End returns the position of first character immediately after the node.
- func (s *ExportStmt) End() Pos {
- return s.Result.End()
- }
- func (s *ExportStmt) String() string {
- return "export " + s.Result.String()
- }
- // 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() Pos {
- return s.Expr.Pos()
- }
- // End returns the position of first character immediately after the node.
- func (s *ExprStmt) End() Pos {
- return s.Expr.End()
- }
- func (s *ExprStmt) String() string {
- return s.Expr.String()
- }
- // ForInStmt represents a for-in statement.
- type ForInStmt struct {
- ForPos 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() Pos {
- return s.ForPos
- }
- // End returns the position of first character immediately after the node.
- func (s *ForInStmt) End() 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()
- }
- // ForStmt represents a for statement.
- type ForStmt struct {
- ForPos 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() Pos {
- return s.ForPos
- }
- // End returns the position of first character immediately after the node.
- func (s *ForStmt) End() 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()
- }
- // IfStmt represents an if statement.
- type IfStmt struct {
- IfPos 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() Pos {
- return s.IfPos
- }
- // End returns the position of first character immediately after the node.
- func (s *IfStmt) End() 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
- }
- // IncDecStmt represents increment or decrement statement.
- type IncDecStmt struct {
- Expr Expr
- Token token.Token
- TokenPos Pos
- }
- func (s *IncDecStmt) stmtNode() {}
- // Pos returns the position of first character belonging to the node.
- func (s *IncDecStmt) Pos() Pos {
- return s.Expr.Pos()
- }
- // End returns the position of first character immediately after the node.
- func (s *IncDecStmt) End() Pos {
- return Pos(int(s.TokenPos) + 2)
- }
- func (s *IncDecStmt) String() string {
- return s.Expr.String() + s.Token.String()
- }
- // ReturnStmt represents a return statement.
- type ReturnStmt struct {
- ReturnPos Pos
- Result Expr
- }
- func (s *ReturnStmt) stmtNode() {}
- // Pos returns the position of first character belonging to the node.
- func (s *ReturnStmt) Pos() Pos {
- return s.ReturnPos
- }
- // End returns the position of first character immediately after the node.
- func (s *ReturnStmt) End() 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"
- }
|