Commit ee14989e authored by Rob Pike's avatar Rob Pike

exp/template: lex variables

Variables start with'$' and are declared with ':='.

R=golang-dev, dsymonds
CC=golang-dev
https://golang.org/cl/4662084
parent 02039b63
...@@ -35,9 +35,10 @@ func (i item) String() string { ...@@ -35,9 +35,10 @@ func (i item) String() string {
type itemType int type itemType int
const ( const (
itemError itemType = iota // error occurred; value is text of error itemError itemType = iota // error occurred; value is text of error
itemBool // boolean constant itemBool // boolean constant
itemComplex // complex constant (1+2i); imaginary is just a number itemComplex // complex constant (1+2i); imaginary is just a number
itemColonEquals // colon-equals (':=') introducing a declaration
itemEOF itemEOF
itemField // alphanumeric identifier, starting with '.', possibly chained ('.x.y') itemField // alphanumeric identifier, starting with '.', possibly chained ('.x.y')
itemIdentifier // alphanumeric identifier itemIdentifier // alphanumeric identifier
...@@ -48,6 +49,7 @@ const ( ...@@ -48,6 +49,7 @@ const (
itemRightDelim // right action delimiter itemRightDelim // right action delimiter
itemString // quoted string (includes quotes) itemString // quoted string (includes quotes)
itemText // plain text itemText // plain text
itemVariable // variable starting with '$', such as '$' or '$1' or '$hello'.
// Keywords appear after all the rest. // Keywords appear after all the rest.
itemKeyword // used only to delimit the keywords itemKeyword // used only to delimit the keywords
itemDot // the cursor, spelled '.'. itemDot // the cursor, spelled '.'.
...@@ -62,18 +64,20 @@ const ( ...@@ -62,18 +64,20 @@ const (
// Make the types prettyprint. // Make the types prettyprint.
var itemName = map[itemType]string{ var itemName = map[itemType]string{
itemError: "error", itemError: "error",
itemBool: "bool", itemBool: "bool",
itemComplex: "complex", itemComplex: "complex",
itemEOF: "EOF", itemColonEquals: ":=",
itemField: "field", itemEOF: "EOF",
itemIdentifier: "identifier", itemField: "field",
itemLeftDelim: "left delim", itemIdentifier: "identifier",
itemNumber: "number", itemLeftDelim: "left delim",
itemPipe: "pipe", itemNumber: "number",
itemRawString: "raw string", itemPipe: "pipe",
itemRightDelim: "right delim", itemRawString: "raw string",
itemString: "string", itemRightDelim: "right delim",
itemString: "string",
itemVariable: "variable",
// keywords // keywords
itemDot: ".", itemDot: ".",
itemDefine: "define", itemDefine: "define",
...@@ -279,12 +283,19 @@ func lexInsideAction(l *lexer) stateFn { ...@@ -279,12 +283,19 @@ func lexInsideAction(l *lexer) stateFn {
return l.errorf("unclosed action") return l.errorf("unclosed action")
case isSpace(r): case isSpace(r):
l.ignore() l.ignore()
case r == ':':
if l.next() != '=' {
return l.errorf("expected :=")
}
l.emit(itemColonEquals)
case r == '|': case r == '|':
l.emit(itemPipe) l.emit(itemPipe)
case r == '"': case r == '"':
return lexQuote return lexQuote
case r == '`': case r == '`':
return lexRawQuote return lexRawQuote
case r == '$':
return lexIdentifier
case r == '.': case r == '.':
// special look-ahead for ".field" so we don't break l.backup(). // special look-ahead for ".field" so we don't break l.backup().
if l.pos < len(l.input) { if l.pos < len(l.input) {
...@@ -324,6 +335,8 @@ Loop: ...@@ -324,6 +335,8 @@ Loop:
l.emit(key[word]) l.emit(key[word])
case word[0] == '.': case word[0] == '.':
l.emit(itemField) l.emit(itemField)
case word[0] == '$':
l.emit(itemVariable)
case word == "true", word == "false": case word == "true", word == "false":
l.emit(itemBool) l.emit(itemBool)
default: default:
......
...@@ -85,6 +85,19 @@ var lexTests = []lexTest{ ...@@ -85,6 +85,19 @@ var lexTests = []lexTest{
tRight, tRight,
tEOF, 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{ {"pipeline", `intro {{echo hi 1.2 |noargs|args 1 "hi"}} outro`, []item{
{itemText, "intro "}, {itemText, "intro "},
tLeft, tLeft,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment