@@ -55,11 +55,31 @@ public final class Lexer {
55
55
OPERATORS .put (">>" , TokenType .GTGT );
56
56
OPERATORS .put (">>>" , TokenType .GTGTGT );
57
57
}
58
+
59
+ private static final Map <String , TokenType > KEYWORDS ;
60
+ static {
61
+ KEYWORDS = new HashMap <String , TokenType >();
62
+ KEYWORDS .put ("print" , TokenType .PRINT );
63
+ KEYWORDS .put ("println" , TokenType .PRINTLN );
64
+ KEYWORDS .put ("if" , TokenType .IF );
65
+ KEYWORDS .put ("else" , TokenType .ELSE );
66
+ KEYWORDS .put ("while" , TokenType .WHILE );
67
+ KEYWORDS .put ("for" , TokenType .FOR );
68
+ KEYWORDS .put ("do" , TokenType .DO );
69
+ KEYWORDS .put ("break" , TokenType .BREAK );
70
+ KEYWORDS .put ("continue" , TokenType .CONTINUE );
71
+ KEYWORDS .put ("def" , TokenType .DEF );
72
+ KEYWORDS .put ("return" , TokenType .RETURN );
73
+ KEYWORDS .put ("use" , TokenType .USE );
74
+ KEYWORDS .put ("match" , TokenType .MATCH );
75
+ KEYWORDS .put ("case" , TokenType .CASE );
76
+ }
58
77
59
78
private final String input ;
60
79
private final int length ;
61
80
62
81
private final List <Token > tokens ;
82
+ private final StringBuilder buffer ;
63
83
64
84
private int pos ;
65
85
private int row , col ;
@@ -69,6 +89,7 @@ public Lexer(String input) {
69
89
length = input .length ();
70
90
71
91
tokens = new ArrayList <>();
92
+ buffer = new StringBuilder ();
72
93
row = col = 1 ;
73
94
}
74
95
@@ -93,7 +114,7 @@ else if (OPERATOR_CHARS.indexOf(current) != -1) {
93
114
}
94
115
95
116
private void tokenizeNumber () {
96
- final StringBuilder buffer = new StringBuilder ();
117
+ clearBuffer ();
97
118
char current = peek (0 );
98
119
while (true ) {
99
120
if (current == '.' ) {
@@ -108,7 +129,7 @@ private void tokenizeNumber() {
108
129
}
109
130
110
131
private void tokenizeHexNumber () {
111
- final StringBuilder buffer = new StringBuilder ();
132
+ clearBuffer ();
112
133
char current = peek (0 );
113
134
while (Character .isDigit (current ) || isHexNumber (current )) {
114
135
buffer .append (current );
@@ -136,7 +157,7 @@ private void tokenizeOperator() {
136
157
return ;
137
158
}
138
159
}
139
- final StringBuilder buffer = new StringBuilder ();
160
+ clearBuffer ();
140
161
while (true ) {
141
162
final String text = buffer .toString ();
142
163
if (!OPERATORS .containsKey (text + current ) && !text .isEmpty ()) {
@@ -149,7 +170,7 @@ private void tokenizeOperator() {
149
170
}
150
171
151
172
private void tokenizeWord () {
152
- final StringBuilder buffer = new StringBuilder ();
173
+ clearBuffer ();
153
174
char current = peek (0 );
154
175
while (true ) {
155
176
if (!Character .isLetterOrDigit (current ) && (current != '_' ) && (current != '$' )) {
@@ -160,37 +181,25 @@ private void tokenizeWord() {
160
181
}
161
182
162
183
final String word = buffer .toString ();
163
- switch (word ) {
164
- case "print" : addToken (TokenType .PRINT ); break ;
165
- case "println" : addToken (TokenType .PRINTLN ); break ;
166
- case "if" : addToken (TokenType .IF ); break ;
167
- case "else" : addToken (TokenType .ELSE ); break ;
168
- case "while" : addToken (TokenType .WHILE ); break ;
169
- case "for" : addToken (TokenType .FOR ); break ;
170
- case "do" : addToken (TokenType .DO ); break ;
171
- case "break" : addToken (TokenType .BREAK ); break ;
172
- case "continue" : addToken (TokenType .CONTINUE ); break ;
173
- case "def" : addToken (TokenType .DEF ); break ;
174
- case "return" : addToken (TokenType .RETURN ); break ;
175
- case "use" : addToken (TokenType .USE ); break ;
176
- case "match" : addToken (TokenType .MATCH ); break ;
177
- case "case" : addToken (TokenType .CASE ); break ;
178
- default :
179
- addToken (TokenType .WORD , word );
180
- break ;
184
+ if (KEYWORDS .containsKey (word )) {
185
+ addToken (KEYWORDS .get (word ));
186
+ } else {
187
+ addToken (TokenType .WORD , word );
181
188
}
182
189
}
183
190
184
191
private void tokenizeText () {
185
192
next ();// skip "
186
- final StringBuilder buffer = new StringBuilder ();
193
+ clearBuffer ();
187
194
char current = peek (0 );
188
195
while (true ) {
189
196
if (current == '\0' ) throw error ("Reached end of file while parsing text string." );
190
197
if (current == '\\' ) {
191
198
current = next ();
192
199
switch (current ) {
193
200
case '"' : current = next (); buffer .append ('"' ); continue ;
201
+ case 'b' : current = next (); buffer .append ('\b' ); continue ;
202
+ case 'f' : current = next (); buffer .append ('\f' ); continue ;
194
203
case 'n' : current = next (); buffer .append ('\n' ); continue ;
195
204
case 't' : current = next (); buffer .append ('\t' ); continue ;
196
205
}
@@ -224,6 +233,10 @@ private void tokenizeMultilineComment() {
224
233
next (); // /
225
234
}
226
235
236
+ private void clearBuffer () {
237
+ buffer .setLength (0 );
238
+ }
239
+
227
240
private char next () {
228
241
pos ++;
229
242
final char result = peek (0 );
0 commit comments