aboutsummaryrefslogtreecommitdiff
path: root/users/fcuny/exp/monkey/pkg/lexer/lexer.go
diff options
context:
space:
mode:
authorfranck cuny <franck@fcuny.net>2020-01-11 14:40:32 +0100
committerfranck cuny <franck@fcuny.net>2020-01-11 14:40:32 +0100
commit4fb91ad4622e099f798e01873bac914b64ed48f4 (patch)
tree1953ed23ac4c7edb49801db4e70906e0e2545da2 /users/fcuny/exp/monkey/pkg/lexer/lexer.go
parenttoken: add tokens for equal and not equal. (diff)
downloadinfra-4fb91ad4622e099f798e01873bac914b64ed48f4.tar.gz
lexer: support tokens for equal and not equal.
The tokens for equal (`==`) and not equal (`!=`) are composed of two characters. We introduce a new helper (`peekChar`) that we use when we encounter the token `=` or `!` to see if this is a token composed of two characters. Add some tests to ensure they are parsed correctly.
Diffstat (limited to 'users/fcuny/exp/monkey/pkg/lexer/lexer.go')
-rw-r--r--users/fcuny/exp/monkey/pkg/lexer/lexer.go28
1 files changed, 26 insertions, 2 deletions
diff --git a/users/fcuny/exp/monkey/pkg/lexer/lexer.go b/users/fcuny/exp/monkey/pkg/lexer/lexer.go
index d538cf5..06d526e 100644
--- a/users/fcuny/exp/monkey/pkg/lexer/lexer.go
+++ b/users/fcuny/exp/monkey/pkg/lexer/lexer.go
@@ -56,6 +56,16 @@ func (l *Lexer) skipWhitespace() {
}
}
+// peekChar returns the character at position (which is the next charatecter),
+// but does not increment `readPosition` and `position`.
+// This is needed to read tokens that are composed of two characters (e.g. `==`).
+func (l *Lexer) peekChar() byte {
+ if l.readPosition >= len(l.input) {
+ return 0
+ }
+ return l.input[l.readPosition]
+}
+
// NextToken reads the next token from the lexer and returns the current token.
func (l *Lexer) NextToken() token.Token {
var tok token.Token
@@ -64,13 +74,27 @@ func (l *Lexer) NextToken() token.Token {
switch l.ch {
case '=':
- tok = newToken(token.ASSIGN, l.ch)
+ if l.peekChar() == '=' {
+ ch := l.ch
+ l.readChar()
+ literal := string(ch) + string(l.ch)
+ tok = token.Token{Type: token.EQ, Literal: literal}
+ } else {
+ tok = newToken(token.ASSIGN, l.ch)
+ }
case '+':
tok = newToken(token.PLUS, l.ch)
case '-':
tok = newToken(token.MINUS, l.ch)
case '!':
- tok = newToken(token.BANG, l.ch)
+ if l.peekChar() == '=' {
+ ch := l.ch
+ l.readChar()
+ literal := string(ch) + string(l.ch)
+ tok = token.Token{Type: token.NOT_EQ, Literal: literal}
+ } else {
+ tok = newToken(token.BANG, l.ch)
+ }
case '*':
tok = newToken(token.ASTERISK, l.ch)
case '/':