blob: c0848c4860f99b27675b0dc787bb5ae270b4de79 (
plain) (
tree)
|
|
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"
}
|