12.4 Methods on Classes

This commit is contained in:
Tom Willemse 2021-04-11 19:55:24 -07:00
parent 580a5acb58
commit 591caeb216
4 changed files with 31 additions and 3 deletions

View file

@ -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;
} }

View file

@ -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

View file

@ -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 + "'.");
} }

View file

@ -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;
} }