@@ -18,7 +18,6 @@ var Keywords = map[string]TokenType{
18
18
"cdr" : CDR ,
19
19
"nil" : NIL ,
20
20
"true" : TRUE ,
21
- //"false": FALSE,
22
21
"and?" : ANDQ ,
23
22
"or?" : ORQ ,
24
23
"not?" : NOTQ ,
@@ -37,7 +36,6 @@ var KeywordsReverse = map[TokenType]string{
37
36
CDR : "cdr" ,
38
37
NIL : "nil" ,
39
38
TRUE : "true" ,
40
- //FALSE: "false",
41
39
ANDQ : "and?" ,
42
40
ORQ : "or?" ,
43
41
NOTQ : "not?" ,
@@ -47,7 +45,6 @@ var KeywordsReverse = map[TokenType]string{
47
45
NILQ : "nil?" ,
48
46
}
49
47
50
-
51
48
type Scanner struct {
52
49
Source string
53
50
Tokens []Token
@@ -97,7 +94,6 @@ func (s *Scanner) addTokenWithTypeAndLiteral(thisType TokenType, literal interfa
97
94
98
95
func (s * Scanner ) ScanTokens () []Token {
99
96
// Driving loop
100
- // Note that s.curr is not incremented in Number, String, or Identifier readers since they handle their own iteration
101
97
for ! s .isAtEnd () {
102
98
s .Start = s .Curr
103
99
s .ScanToken ()
@@ -111,15 +107,24 @@ func (s *Scanner) ScanTokens() []Token {
111
107
func (s * Scanner ) ScanToken () {
112
108
ch := s .advance ()
113
109
switch ch {
114
- case '(' : s .addToken (LEFT_PAREN )
115
- case ')' : s .addToken (RIGHT_PAREN )
116
- case '.' : s .addToken (DOT )
117
- case '-' : s .addToken (MINUS )
118
- case '+' : s .addToken (PLUS )
119
- case '*' : s .addToken (STAR )
120
- case '=' : s .addToken (EQUAL )
121
- case '<' : s .addToken (LESS )
122
- case '>' : s .addToken (GREATER )
110
+ case '(' :
111
+ s .addToken (LEFT_PAREN )
112
+ case ')' :
113
+ s .addToken (RIGHT_PAREN )
114
+ case '.' :
115
+ s .addToken (DOT )
116
+ case '-' :
117
+ s .addToken (MINUS )
118
+ case '+' :
119
+ s .addToken (PLUS )
120
+ case '*' :
121
+ s .addToken (STAR )
122
+ case '=' :
123
+ s .addToken (EQUAL )
124
+ case '<' :
125
+ s .addToken (LESS )
126
+ case '>' :
127
+ s .addToken (GREATER )
123
128
case '/' :
124
129
if s .match ('/' ) {
125
130
for ! s .isAtEnd () && s .peek () != '\n' {
@@ -129,19 +134,14 @@ func (s *Scanner) ScanToken() {
129
134
} else {
130
135
s .addToken (SLASH )
131
136
}
132
- // Hanle comments
133
- // case ';':
134
- // for !s.isAtEnd() && s.peek() != '\n' {
135
- // s.advance()
136
- // }
137
- // Handle whitespace
138
- case ' ' :
139
- case '\r' :
140
- case '\t' :
137
+ case ' ' :
138
+ case '\r' :
139
+ case '\t' :
141
140
case '\n' :
142
141
s .Line ++
143
142
// Handle strings
144
- case '"' : s .tokenizeString ()
143
+ case '"' :
144
+ s .tokenizeString ()
145
145
default :
146
146
if unicode .IsDigit (rune (ch )) {
147
147
s .tokenizeNumber ()
@@ -152,7 +152,7 @@ func (s *Scanner) ScanToken() {
152
152
LoxError (s .Line , errorStr )
153
153
}
154
154
}
155
-
155
+
156
156
}
157
157
158
158
func (s * Scanner ) match (expected rune ) bool {
@@ -163,7 +163,7 @@ func (s *Scanner) match(expected rune) bool {
163
163
return false
164
164
}
165
165
s .Curr ++
166
- return true ;
166
+ return true
167
167
}
168
168
169
169
func (s * Scanner ) tokenizeString () {
@@ -198,18 +198,19 @@ func (s *Scanner) tokenizeString() {
198
198
LoxError (s .Line , errorStr )
199
199
} else {
200
200
// Return token using substring created from initial and current positions
201
- s .addTokenWithTypeAndLiteral (STRING , s .Source [s .Start + 1 : s .Curr - 1 ])
201
+ s .addTokenWithTypeAndLiteral (STRING , s .Source [s .Start + 1 : s .Curr - 1 ])
202
202
}
203
203
204
204
// Return token using substring created from initial and current positions
205
205
}
206
206
207
207
// Number reader for Scanner
208
208
func (s * Scanner ) tokenizeNumber () {
209
- // Track initial position and whether or not a dot has been found
209
+ // Track initial position and whether a dot has been found
210
210
foundDot := false
211
211
212
212
// Iterate until end of number or end of file
213
+ // If s.Curr has not overflowed, and the current character is a digit or a dot
213
214
for s .Curr < len (s .Source ) && (unicode .IsDigit (rune (s .Source [s .Curr ])) || s .Source [s .Curr ] == '.' ) {
214
215
215
216
// Check for dot
@@ -229,9 +230,9 @@ func (s *Scanner) tokenizeNumber() {
229
230
floatVal , err := strconv .ParseFloat (s .Source [s .Start :s .Curr ], 64 )
230
231
231
232
if err != nil {
232
- errorStr := fmt .Sprintf ("Invalid number at line %d" , s .Line )
233
+ errorStr := fmt .Sprintf ("Invalid number at line %d" , s .Line )
233
234
LoxError (s .Line , errorStr )
234
- }
235
+ }
235
236
// Return token using substring created from initial and current positions
236
237
s .addTokenWithTypeAndLiteral (NUMBER , floatVal )
237
238
}
@@ -247,9 +248,9 @@ func (s *Scanner) tokenizeSymbol() {
247
248
// Check for existing keyword
248
249
symbol := s .Source [s .Start :s .Curr ]
249
250
if tokentype , exists := Keywords [symbol ]; exists {
250
- s .addToken (tokentype )
251
- } else {
252
- // Set to default value if the key is not found
253
- s .addToken (SYMBOL )
254
- }
251
+ s .addToken (tokentype )
252
+ } else {
253
+ // Set to default value if the key is not found
254
+ s .addToken (SYMBOL )
255
+ }
255
256
}
0 commit comments