type itemType int
const (
- itemError itemType = iota // error occurred; value is text of error
- itemBool // boolean constant
- itemComplex // complex constant (1+2i); imaginary is just a number
+ itemError itemType = iota // error occurred; value is text of error
+ itemBool // boolean constant
+ itemComplex // complex constant (1+2i); imaginary is just a number
+ itemColonEquals // colon-equals (':=') introducing a declaration
itemEOF
itemField // alphanumeric identifier, starting with '.', possibly chained ('.x.y')
itemIdentifier // alphanumeric identifier
itemRightDelim // right action delimiter
itemString // quoted string (includes quotes)
itemText // plain text
+ itemVariable // variable starting with '$', such as '$' or '$1' or '$hello'.
// Keywords appear after all the rest.
itemKeyword // used only to delimit the keywords
itemDot // the cursor, spelled '.'.
// Make the types prettyprint.
var itemName = map[itemType]string{
- itemError: "error",
- itemBool: "bool",
- itemComplex: "complex",
- itemEOF: "EOF",
- itemField: "field",
- itemIdentifier: "identifier",
- itemLeftDelim: "left delim",
- itemNumber: "number",
- itemPipe: "pipe",
- itemRawString: "raw string",
- itemRightDelim: "right delim",
- itemString: "string",
+ itemError: "error",
+ itemBool: "bool",
+ itemComplex: "complex",
+ itemColonEquals: ":=",
+ itemEOF: "EOF",
+ itemField: "field",
+ itemIdentifier: "identifier",
+ itemLeftDelim: "left delim",
+ itemNumber: "number",
+ itemPipe: "pipe",
+ itemRawString: "raw string",
+ itemRightDelim: "right delim",
+ itemString: "string",
+ itemVariable: "variable",
// keywords
itemDot: ".",
itemDefine: "define",
return l.errorf("unclosed action")
case isSpace(r):
l.ignore()
+ case r == ':':
+ if l.next() != '=' {
+ return l.errorf("expected :=")
+ }
+ l.emit(itemColonEquals)
case r == '|':
l.emit(itemPipe)
case r == '"':
return lexQuote
case r == '`':
return lexRawQuote
+ case r == '$':
+ return lexIdentifier
case r == '.':
// special look-ahead for ".field" so we don't break l.backup().
if l.pos < len(l.input) {
l.emit(key[word])
case word[0] == '.':
l.emit(itemField)
+ case word[0] == '$':
+ l.emit(itemVariable)
case word == "true", word == "false":
l.emit(itemBool)
default:
tRight,
tEOF,
}},
+ {"variables", "{{$c := printf $ $hello $23 $.Method}}", []item{
+ tLeft,
+ {itemVariable, "$c"},
+ {itemColonEquals, ":="},
+ {itemIdentifier, "printf"},
+ {itemVariable, "$"},
+ {itemVariable, "$hello"},
+ {itemVariable, "$23"},
+ {itemVariable, "$"},
+ {itemField, ".Method"},
+ tRight,
+ tEOF,
+ }},
{"pipeline", `intro {{echo hi 1.2 |noargs|args 1 "hi"}} outro`, []item{
{itemText, "intro "},
tLeft,