12.4 Methods on Classes
This commit is contained in:
parent
580a5acb58
commit
591caeb216
4 changed files with 31 additions and 3 deletions
|
@ -177,7 +177,14 @@ class Interpreter implements Expr.Visitor<Object>, Stmt.Visitor<Void> {
|
||||||
@Override
|
@Override
|
||||||
public Void visitClassStmt(Stmt.Class stmt) {
|
public Void visitClassStmt(Stmt.Class stmt) {
|
||||||
environment.define(stmt.name.lexeme, null);
|
environment.define(stmt.name.lexeme, null);
|
||||||
LoxClass klass = new LoxClass(stmt.name.lexeme);
|
|
||||||
|
Map<String, LoxFunction> methods = new HashMap<>();
|
||||||
|
for (Stmt.Function method : stmt.methods) {
|
||||||
|
LoxFunction function = new LoxFunction(method, environment);
|
||||||
|
methods.put(method.name.lexeme, function);
|
||||||
|
}
|
||||||
|
|
||||||
|
LoxClass klass = new LoxClass(stmt.name.lexeme, methods);
|
||||||
environment.assign(stmt.name, klass);
|
environment.assign(stmt.name, klass);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,23 @@
|
||||||
package com.craftinginterpreters.lox;
|
package com.craftinginterpreters.lox;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
class LoxClass implements LoxCallable {
|
class LoxClass implements LoxCallable {
|
||||||
final String name;
|
final String name;
|
||||||
|
private final Map<String, LoxFunction> methods;
|
||||||
|
|
||||||
LoxClass(String name) {
|
LoxClass(String name, Map<String, LoxFunction> methods) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
this.methods = methods;
|
||||||
|
}
|
||||||
|
|
||||||
|
LoxFunction findMethod(String name) {
|
||||||
|
if (methods.containsKey(name)) {
|
||||||
|
return methods.get(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -16,6 +16,10 @@ class LoxInstance {
|
||||||
return fields.get(name.lexeme);
|
return fields.get(name.lexeme);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LoxFunction method = klass.findMethod(name.lexeme);
|
||||||
|
if (method != null)
|
||||||
|
return method;
|
||||||
|
|
||||||
throw new RuntimeError(name, "Undefined proprety '" + name.lexeme + "'.");
|
throw new RuntimeError(name, "Undefined proprety '" + name.lexeme + "'.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ class Resolver implements Expr.Visitor<Void>, Stmt.Visitor<Void> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private enum FunctionType {
|
private enum FunctionType {
|
||||||
NONE, FUNCTION
|
NONE, FUNCTION, METHOD
|
||||||
}
|
}
|
||||||
|
|
||||||
public void resolve(List<Stmt> statements) {
|
public void resolve(List<Stmt> statements) {
|
||||||
|
@ -36,6 +36,12 @@ class Resolver implements Expr.Visitor<Void>, Stmt.Visitor<Void> {
|
||||||
public Void visitClassStmt(Stmt.Class stmt) {
|
public Void visitClassStmt(Stmt.Class stmt) {
|
||||||
declare(stmt.name);
|
declare(stmt.name);
|
||||||
define(stmt.name);
|
define(stmt.name);
|
||||||
|
|
||||||
|
for (Stmt.Function method : stmt.methods) {
|
||||||
|
FunctionType declaration = FunctionType.METHOD;
|
||||||
|
resolveFunction(method, declaration);
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue