hcl/zclwrite/tokens.go
Martin Atkins 476e2c127e zclwrite: convert zclsyntax tokens into zclwrite tokens
In zclwrite we throw away the absolute source position information and
instead just retain the number of spaces before each token. This different
model allows us to rewrite parts of the token sequence without needing
to re-adjust all of the positions, and it also allows us to do simple
indentation and spacing adjustments just by walking through the token
list and adjusting these numbers.
2017-05-29 16:59:20 -07:00

67 lines
2.0 KiB
Go

package zclwrite
import (
"github.com/zclconf/go-zcl/zcl/zclsyntax"
)
// TokenGen is an abstract type that can append tokens to a list. It is the
// low-level foundation underlying the zclwrite AST; the AST provides a
// convenient abstraction over raw token sequences to facilitate common tasks,
// but it's also possible to directly manipulate the tree of token generators
// to make changes that the AST API doesn't directly allow.
type TokenGen interface {
AppendToTokens(Tokens) Tokens
}
// Token is a single sequence of bytes annotated with a type. It is similar
// in purpose to zclsyntax.Token, but discards the source position information
// since that is not useful in code generation.
type Token struct {
Type zclsyntax.TokenType
Bytes []byte
// We record the number of spaces before each token so that we can
// reproduce the exact layout of the original file when we're making
// surgical changes in-place. When _new_ code is created it will always
// be in the canonical style, but we preserve layout of existing code.
SpacesBefore int
}
// Tokens is a flat list of tokens.
type Tokens []*Token
// TokenSeq combines zero or more TokenGens together to produce a flat sequence
// of tokens from a tree of TokenGens.
type TokenSeq []TokenGen
func (t *Token) AppendToTokens(src Tokens) Tokens {
return append(src, t)
}
func (ts *Tokens) AppendToTokens(src Tokens) Tokens {
return append(src, (*ts)...)
}
func (ts *TokenSeq) AppendToTokens(src Tokens) Tokens {
toks := src
for _, gen := range *ts {
toks = gen.AppendToTokens(toks)
}
return toks
}
// Tokens returns the flat list of tokens represented by the receiving
// token sequence.
func (ts *TokenSeq) Tokens() Tokens {
return ts.AppendToTokens(nil)
}
func (ts *TokenSeq) Append(other *TokenSeq) {
*ts = append(*ts, other)
}
// TokenSeqEmpty is a TokenSeq that contains no tokens. It can be used anywhere,
// but its primary purpose is to be assigned as a replacement for a non-empty
// TokenSeq when eliminating a section of an input file.
var TokenSeqEmpty = TokenSeq([]TokenGen(nil))