@@ -18,7 +18,6 @@ class Lexer(object):
1818 ',' : 'comma' ,
1919 ':' : 'colon' ,
2020 '@' : 'current' ,
21- '$' : 'root' ,
2221 '(' : 'lparen' ,
2322 ')' : 'rparen' ,
2423 '{' : 'lbrace' ,
@@ -115,22 +114,15 @@ def tokenize(self, expression, options=None):
115114 elif self ._current == '!' :
116115 yield self ._match_or_else ('=' , 'ne' , 'not' )
117116 elif self ._current == '=' :
118- if self ._next () == '=' :
119- yield { 'type' : 'eq' , 'value' : '==' ,
120- 'start' : self ._position - 1 , 'end' : self . _position }
121- self ._next ()
117+ yield self ._match_or_else ( '=' , 'eq' , 'assign' )
118+ elif self . _current == '$' :
119+ if self ._peek_may_be_valid_unquoted_identifier ():
120+ yield self ._consume_variable ()
122121 else :
123- if self ._current is None :
124- # If we're at the EOF, we never advanced
125- # the position so we don't need to rewind
126- # it back one location.
127- position = self ._position
128- else :
129- position = self ._position - 1
130- raise LexerError (
131- lexer_position = position ,
132- lexer_value = '=' ,
133- message = "Unknown token '='" )
122+ yield {'type' : 'root' ,
123+ 'value' : self ._current ,
124+ 'start' : self ._position , 'end' : self ._position + 1 }
125+ self ._next ()
134126 else :
135127 raise LexerError (lexer_position = self ._position ,
136128 lexer_value = self ._current ,
@@ -145,6 +137,28 @@ def _consume_number(self):
145137 buff += self ._current
146138 return buff
147139
140+ def _consume_variable (self ):
141+ start = self ._position
142+ buff = self ._current
143+ self ._next ()
144+ if self ._current not in self .START_IDENTIFIER :
145+ raise LexerError (
146+ lexer_position = start ,
147+ lexer_value = self ._current ,
148+ message = 'Invalid variable starting character %s' % self ._current )
149+ buff += self ._current
150+ while self ._next () in self .VALID_IDENTIFIER :
151+ buff += self ._current
152+ return {'type' : 'variable' , 'value' : buff ,
153+ 'start' : start , 'end' : start + len (buff )}
154+
155+ def _peek_may_be_valid_unquoted_identifier (self ):
156+ if (self ._position == self ._length - 1 ):
157+ return False
158+ else :
159+ next = self ._chars [self ._position + 1 ]
160+ return next in self .START_IDENTIFIER
161+
148162 def _peek_is_next_digit (self ):
149163 if (self ._position == self ._length - 1 ):
150164 return False
0 commit comments