Skip to content

Commit 7fded12

Browse files
committed
updated lexer to hold keyword name
1 parent 3e81c83 commit 7fded12

File tree

9 files changed

+81
-32
lines changed

9 files changed

+81
-32
lines changed

src/main/java/com/example/ast/Expr.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,14 +136,14 @@ public String toString() {
136136
@Getter
137137
@AllArgsConstructor
138138
public static class This extends Expr {
139-
private final Token keyword;
139+
private final Token name;
140140

141141
public Object accept(ExprVisitor v) {
142142
return v.visitThisExpr(this);
143143
}
144144

145145
public String toString() {
146-
return String.format("this.%s", keyword.getLiteral());
146+
return String.format("this");
147147
}
148148
}
149149

src/main/java/com/example/environment/Resolver.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -225,8 +225,8 @@ else if (currentClass != ClassType.SUBCLASS)
225225
@Override
226226
public Object visitThisExpr(This expr) {
227227
if (currentClass == ClassType.NONE)
228-
throw new RuntimeError("Cannot use 'this' outside of a class.", expr.getKeyword());
229-
resolveLocal(expr, expr.getKeyword());
228+
throw new RuntimeError("Cannot use 'this' outside of a class.", expr.getName());
229+
resolveLocal(expr, expr.getName());
230230
return null;
231231
}
232232

src/main/java/com/example/interpreter/CustomFunction.java

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,19 @@
77

88
public class CustomFunction implements CustomCallable {
99
Environment closure;
10-
Boolean isInitializer = false;
10+
Boolean isConstructor = false;
1111
Stmt.Function declaration;
1212

13-
CustomFunction(Stmt.Function declaration, Environment closure, Boolean isInitializer) {
13+
CustomFunction(Stmt.Function declaration, Environment closure, Boolean isConstructor) {
1414
this.closure = closure;
15-
this.isInitializer = isInitializer;
15+
this.isConstructor = isConstructor;
1616
this.declaration = declaration;
1717
}
1818

1919
CustomFunction bind(CustomInstance instance) {
2020
Environment environment = new Environment(closure);
2121
environment.define("this", instance);
22-
return new CustomFunction(declaration, environment, isInitializer);
22+
return new CustomFunction(declaration, environment, isConstructor);
2323
}
2424

2525
@Override
@@ -40,20 +40,17 @@ public Object call(Interpreter interpreter, List<Object> arguments) {
4040
declaration.getBody().getStmts(),
4141
environment);
4242
} catch (CustomError.Return returnValue) {
43-
if (isInitializer) {
44-
return closure.getAt(0, "this");
45-
}
4643
return returnValue.getValue();
4744
}
48-
if (isInitializer) {
45+
if (isConstructor) {
4946
return closure.getAt(0, "this");
5047
}
5148
return null;
5249
}
5350

5451
@Override
5552
public String toString() {
56-
return "<fn:\"" + declaration.getName().getLiteral() + "\">";
53+
return String.format("<fn:\"%s\">", declaration.getName());
5754
}
5855

5956
}

src/main/java/com/example/interpreter/CustomInstance.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,9 @@ Object get(Token name) {
2929
void set(Token name, Object value) {
3030
fields.put((String) name.getLiteral(), value);
3131
}
32+
33+
@Override
34+
public String toString() {
35+
return String.format("<instance:\"%s>", customClass);
36+
}
3237
}

src/main/java/com/example/interpreter/Interpreter.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -260,12 +260,13 @@ public void visitClassStmt(Class stmt) {
260260
}
261261
Map<String, CustomFunction> methods = new HashMap<>();
262262
for (Stmt.Function method : stmt.getMethods()) {
263+
String className = (String) method.getName().getLiteral();
263264
methods.put(
264-
(String) method.getName().getLiteral(),
265+
className,
265266
new CustomFunction(
266267
method,
267268
environment,
268-
method.getName().getLiteral().equals("init")));
269+
className.equals(CustomClass.constructor)));
269270
}
270271
CustomClass klass = new CustomClass(
271272
(String) stmt.getName().getLiteral(),
@@ -299,7 +300,8 @@ public Object visitCallExpr(Call expr) {
299300
if (function.arity() == -1 || function.arity() == arguments.size()) {
300301
return function.call(this, arguments);
301302
}
302-
throw new RuntimeError("Expected " + function.arity() + " arguments but got " + arguments.size(),
303+
throw new RuntimeError(
304+
String.format("Expected %s arguments, but got %s", function.arity(), arguments.size()),
303305
expr.getParen());
304306
}
305307

@@ -339,7 +341,7 @@ public Object visitSuperExpr(Super expr) {
339341

340342
@Override
341343
public Object visitThisExpr(This expr) {
342-
return lookUpVariable(expr.getKeyword(), expr);
344+
return lookUpVariable(expr.getName(), expr);
343345
}
344346

345347
private Object lookUpVariable(Token name, Expr expr) {

src/main/java/com/example/lexer/Lexer.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -233,8 +233,8 @@ private Token identifier() {
233233
String text = new String(input, start, pos - start);
234234
TokenType type = keywords.get(text);
235235
if (type == null)
236-
return new Token(TokenType.Identifier, line, col, text);
237-
return new Token(type, line, col);
236+
type = TokenType.Identifier;
237+
return new Token(type, line, col, text);
238238
}
239239

240240
private void removeComment() {
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package com.example.lexer;
2+
3+
import static org.junit.Assert.assertEquals;
4+
import static org.junit.Assert.fail;
5+
6+
import java.util.Arrays;
7+
import java.util.Collection;
8+
9+
import org.junit.Test;
10+
import org.junit.runner.RunWith;
11+
import org.junit.runners.Parameterized;
12+
13+
import com.example.token.Token;
14+
import com.example.token.TokenType;
15+
16+
@RunWith(Parameterized.class)
17+
public class LexerKeywordTest {
18+
private String input;
19+
private TokenType expectedType;
20+
21+
@Parameterized.Parameters
22+
public static Collection<Object[]> data() {
23+
return Arrays.asList(new Object[][] {
24+
{ "true", TokenType.True },
25+
{ "false", TokenType.False },
26+
{ "null", TokenType.Null },
27+
{ "for", TokenType.For },
28+
{ "while", TokenType.While },
29+
{ "this", TokenType.This },
30+
{ "super", TokenType.Super },
31+
{ "return", TokenType.Return },
32+
{ "fn", TokenType.Function },
33+
34+
});
35+
}
36+
37+
public LexerKeywordTest(String input, TokenType expectedType) {
38+
this.input = input;
39+
this.expectedType = expectedType;
40+
}
41+
42+
@Test
43+
public void testSingleToken() {
44+
Token expected = new Token(expectedType, 1, 1, input);
45+
Lexer l = new Lexer(input);
46+
try {
47+
Token tok = l.next();
48+
assertEquals(tok, expected);
49+
50+
tok = new Token(TokenType.Eof, 1, input.length() + 1);
51+
} catch (LexerError e) {
52+
fail(e.getMessage());
53+
}
54+
}
55+
}

src/test/java/com/example/lexer/LexerObject.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ public static List<Object[]> data() {
2222
return Arrays.asList(new Object[][] {
2323
{ "1", new Token(TokenType.Number, 1, 1, 1.0) },
2424
{ "1.0", new Token(TokenType.Number, 1, 1, 1.0) },
25-
{ "true", new Token(TokenType.True, 1, 1, null) },
26-
{ "false", new Token(TokenType.False, 1, 1, null) },
27-
{ "null", new Token(TokenType.Null, 1, 1, null) },
25+
{ "true", new Token(TokenType.True, 1, 1, "true") },
26+
{ "false", new Token(TokenType.False, 1, 1, "false") },
27+
{ "null", new Token(TokenType.Null, 1, 1, "null") },
2828
});
2929
}
3030

src/test/java/com/example/lexer/LexerTest.java

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -51,16 +51,6 @@ public static Collection<Object[]> data() {
5151
{ "*=", TokenType.MultiplyAssign },
5252
{ "^=", TokenType.ExponentAssign },
5353
{ "!=", TokenType.NotEqual },
54-
{ "for", TokenType.For },
55-
{ "while", TokenType.While },
56-
{ "fn", TokenType.Function },
57-
{ "let", TokenType.Let },
58-
{ "if", TokenType.If },
59-
{ "else", TokenType.Else },
60-
{ "return", TokenType.Return },
61-
{ "class", TokenType.Class },
62-
{ "break", TokenType.Break },
63-
{ "continue", TokenType.Continue }
6454
});
6555
}
6656

0 commit comments

Comments
 (0)