60101ff5ad34195b65b2ede1381202f98e4fe2d9 — Martin Angers 5 months ago ccaaf5e master
internal/ast: work on ast types
1 files changed, 102 insertions(+), 16 deletions(-)

M internal/ast/ast.go
M internal/ast/ast.go => internal/ast/ast.go +102 -16
@@ 4,21 4,35 @@ "git.sr.ht/~mna/fastpeg/internal/bootstrap/token"
  )
  
- type Expression interface{}
+ // Node represents a node in the abstract syntax tree.
+ type Node interface {
+ 	Start() token.Pos
+ 	End() token.Pos
+ }
+ 
+ // Expression is any expression in the grammar.
+ type Expression interface {
+ 	Node
+ 	expr()
+ }
  
  // Grammar represents a parsed fastpeg grammar.
  type Grammar struct {
  	Definitions []*Definition
  }
  
+ func (g *Grammar) Start() token.Pos { return g.Definitions[0].Start() }
+ func (g *Grammar) End() token.Pos   { return g.Definitions[len(g.Definitions)-1].End() }
+ 
+ // Definition represents a single rule definition in a grammar.
  type Definition struct {
  	// Ident is the required identifier in a definition, i.e.:
  	// identifier <- expression
- 	Ident *Identifier
+ 	Ident *Word
  
  	// Arrow indicates the location and type of arrow in the
  	// definition.
- 	Arrow *Punctuation
+ 	Arrow *Word
  
  	// Expr is the expression associated with this definition's
  	// identifier.


@@ 26,65 40,134 @@   	// EOS is the end-of-statement if present for this
  	// definition, nil otherwise.
- 	EOS *Punctuation
+ 	EOS *Word
  }
  
+ func (d *Definition) Start() token.Pos { return d.Ident.Start() }
+ func (d *Definition) End() token.Pos {
+ 	if d.EOS != nil {
+ 		return d.EOS.End()
+ 	}
+ 	return d.Expr.End()
+ }
+ 
+ // Choice is a choice expression.
  type Choice struct {
  	// Exprs is the list of options, one expression for each
  	// choice.
  	Exprs []Expression
  
  	// Seps is the list of choice separators between each option.
- 	Seps []*Punctuation
+ 	Seps []*Word
  }
  
+ func (c *Choice) Start() token.Pos { return c.Exprs[0].Start() }
+ func (c *Choice) End() token.Pos   { return c.Exprs[len(c.Exprs)-1].End() }
+ 
+ func (c *Choice) expr() {}
+ 
+ // Sequence is a sequence expression.
  type Sequence struct {
  	// Exprs is the list of expressions in this sequence.
  	Exprs []Expression
  }
  
+ func (s *Sequence) Start() token.Pos { return s.Exprs[0].Start() }
+ func (s *Sequence) End() token.Pos   { return s.Exprs[len(s.Exprs)-1].End() }
+ 
+ func (s *Sequence) expr() {}
+ 
+ // Coderef is a code reference expression.
  type Coderef struct {
  	Pos   token.Pos
  	Type  token.Token
  	Ident string
  }
  
+ func (c *Coderef) Start() token.Pos { return c.Pos }
+ 
+ // TODO: should the token.Coderef be scanned from start to ending }?
+ func (c *Coderef) End() token.Pos { return c.Pos + token.Pos(len(c.Ident)) }
+ 
+ func (c *Coderef) expr() {}
+ 
+ // Label is a labeled expression.
  type Label struct {
- 	Ident *Identifier
- 	Colon *Punctuation
+ 	Ident *Word
+ 	Colon *Word
  	Expr  Expression
  }
  
+ func (l *Label) Start() token.Pos { return l.Ident.Start() }
+ func (l *Label) End() token.Pos   { return l.Expr.End() }
+ 
+ func (l *Label) expr() {}
+ 
+ // Prefix is a prefixed expression.
  type Prefix struct {
- 	Prefix *Punctuation
+ 	Prefix *Word
  	Expr   Expression
  }
  
+ func (p *Prefix) Start() token.Pos { return p.Prefix.Start() }
+ func (p *Prefix) End() token.Pos   { return p.Expr.End() }
+ 
+ func (p *Prefix) expr() {}
+ 
+ // Suffix is a suffixed expression.
  type Suffix struct {
- 	Suffix *Punctuation
  	Expr   Expression
+ 	Suffix *Word
  }
  
+ func (s *Suffix) Start() token.Pos { return s.Expr.Start() }
+ func (s *Suffix) End() token.Pos   { return s.Suffix.End() }
+ 
+ func (s *Suffix) expr() {}
+ 
+ // Ruleref is a rule reference expression.
  type Ruleref struct {
- 	Ident *Identifier
+ 	Ident *Word
  }
  
+ func (r *Ruleref) Start() token.Pos { return r.Ident.Start() }
+ func (r *Ruleref) End() token.Pos   { return r.Ident.End() }
+ 
+ func (r *Ruleref) expr() {}
+ 
+ // Literal is a literal string expression.
  type Literal struct {
+ 	Value *Word
  }
  
+ func (l *Literal) Start() token.Pos { return l.Value.Start() }
+ func (l *Literal) End() token.Pos   { return l.Value.End() }
+ 
+ func (l *Literal) expr() {}
+ 
+ // CharClass is a character class expression.
  type CharClass struct {
+ 	Value *Word
  }
  
+ func (c *CharClass) Start() token.Pos { return c.Value.Start() }
+ func (c *CharClass) End() token.Pos   { return c.Value.End() }
+ 
+ func (c *CharClass) expr() {}
+ 
+ // Any is a dot expression.
  type Any struct {
- 	Dot *Punctuation
+ 	Dot *Word
  }
  
- type Identifier struct {
- 	Pos   token.Pos
- 	Value string
- }
+ func (a *Any) Start() token.Pos { return a.Dot.Start() }
+ func (a *Any) End() token.Pos   { return a.Dot.End() }
+ 
+ func (a *Any) expr() {}
  
- type Punctuation struct {
+ // Word represents the representation of a literal (including identifiers)
+ // or punctuation in the grammar.
+ type Word struct {
  	// Pos is the FileSet-dependent position of the start of
  	// this punctuation.
  	Pos token.Pos


@@ 92,3 175,6 @@ // Value is the representation of this punctuation.
  	Value string
  }
+ 
+ func (w *Word) Start() token.Pos { return w.Pos }
+ func (w *Word) End() token.Pos   { return w.Pos + token.Pos(len(w.Value)) }