[jlox] Add get/set for instance fields
This commit is contained in:
@@ -213,11 +213,11 @@ public class Interpreter implements Expr.Visitor<Object>, Stmt.Visitor<Void> {
|
|||||||
var msg = "Expected %d arguments but got %d.".formatted(function.arity(), arguments.size());
|
var msg = "Expected %d arguments but got %d.".formatted(function.arity(), arguments.size());
|
||||||
throw new RuntimeError(expr.paren(), msg);
|
throw new RuntimeError(expr.paren(), msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return function.call(this, arguments);
|
||||||
} else {
|
} else {
|
||||||
throw new RuntimeError(expr.paren(), "Can only call functions and classes.");
|
throw new RuntimeError(expr.paren(), "Can only call functions and classes.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return function.call(this, arguments);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -354,6 +354,7 @@ public class Parser {
|
|||||||
} else if (match(DOT)) {
|
} else if (match(DOT)) {
|
||||||
Token name = consume(IDENTIFIER, "Expect property name after '.'.");
|
Token name = consume(IDENTIFIER, "Expect property name after '.'.");
|
||||||
expr = new Expr.Get(expr, name);
|
expr = new Expr.Get(expr, name);
|
||||||
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,12 +9,11 @@ import java.util.Stack;
|
|||||||
public class Resolver implements Expr.Visitor<Void>, Stmt.Visitor<Void> {
|
public class Resolver implements Expr.Visitor<Void>, Stmt.Visitor<Void> {
|
||||||
private final Interpreter interpreter;
|
private final Interpreter interpreter;
|
||||||
private final Stack<Map<String, Boolean>> scopes = new Stack<>();
|
private final Stack<Map<String, Boolean>> scopes = new Stack<>();
|
||||||
private FunctionType currentFuntion = FunctionType.NONE;
|
private FunctionType currentFunction = FunctionType.NONE;
|
||||||
|
|
||||||
private enum ClassType { NONE, CLASS }
|
|
||||||
|
|
||||||
private ClassType currentClass = ClassType.NONE;
|
private ClassType currentClass = ClassType.NONE;
|
||||||
|
|
||||||
|
private enum ClassType { NONE, CLASS }
|
||||||
|
|
||||||
Resolver(Interpreter interpreter) {
|
Resolver(Interpreter interpreter) {
|
||||||
this.interpreter = interpreter;
|
this.interpreter = interpreter;
|
||||||
@@ -56,8 +55,8 @@ public class Resolver implements Expr.Visitor<Void>, Stmt.Visitor<Void> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void resolveFunction(Stmt.Function function, FunctionType functionType) {
|
private void resolveFunction(Stmt.Function function, FunctionType functionType) {
|
||||||
var enclosingFunction = currentFuntion;
|
var enclosingFunction = currentFunction;
|
||||||
currentFuntion = functionType;
|
currentFunction = functionType;
|
||||||
beginScope();
|
beginScope();
|
||||||
for (var param : function.params()) {
|
for (var param : function.params()) {
|
||||||
declare(param);
|
declare(param);
|
||||||
@@ -65,7 +64,7 @@ public class Resolver implements Expr.Visitor<Void>, Stmt.Visitor<Void> {
|
|||||||
}
|
}
|
||||||
resolve(function.body());
|
resolve(function.body());
|
||||||
endScope();
|
endScope();
|
||||||
currentFuntion = enclosingFunction;
|
currentFunction = enclosingFunction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -142,12 +141,12 @@ public class Resolver implements Expr.Visitor<Void>, Stmt.Visitor<Void> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Void visitReturnStmt(Stmt.Return stmt) {
|
public Void visitReturnStmt(Stmt.Return stmt) {
|
||||||
if (currentFuntion == FunctionType.NONE) {
|
if (currentFunction == FunctionType.NONE) {
|
||||||
Lox.error(stmt.keyword(), "Can't return fom top-level code.");
|
Lox.error(stmt.keyword(), "Can't return fom top-level code.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stmt.value() != null) {
|
if (stmt.value() != null) {
|
||||||
if (currentFuntion == FunctionType.INITIALIZER) {
|
if (currentFunction == FunctionType.INITIALIZER) {
|
||||||
Lox.error(stmt.keyword(), "Can't return a value from an initializer.");
|
Lox.error(stmt.keyword(), "Can't return a value from an initializer.");
|
||||||
}
|
}
|
||||||
resolve(stmt.value());
|
resolve(stmt.value());
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
package xyz.ctsk.lox;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
public class ResolverTest {
|
|
||||||
@Test
|
|
||||||
void forLoopBug() throws IOException {
|
|
||||||
var canary = this.getClass().getResource("ResolverBug.lox").getPath();
|
|
||||||
Lox.runFile(canary);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
for (var i = 0; i < 2; i = i + 1) print i;
|
|
||||||
Reference in New Issue
Block a user