Skip to content

Commit

Permalink
add methods on class featurec
Browse files Browse the repository at this point in the history
  • Loading branch information
flyingalex committed Feb 23, 2020
1 parent bef5cd4 commit 793e0f8
Show file tree
Hide file tree
Showing 18 changed files with 198 additions and 67 deletions.
58 changes: 36 additions & 22 deletions Expr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ class Logical;

template<class R>
class Call;
template<class R>
class Get;

template<class R>
class Set;

template <class R>
class Visitor {
Expand All @@ -51,7 +56,8 @@ class Visitor {
virtual R visitVariableExpr(shared_ptr<Variable<R>> expr) = 0;
virtual R visitLogicalExpr(shared_ptr<Logical<R>> expr) = 0;
virtual R visitCallExpr(shared_ptr<Call<R>> expr) = 0;
// virtual string visitSetExpr(Set& expr) = 0;
virtual R visitGetExpr(shared_ptr<Get<R>> expr) = 0;
virtual R visitSetExpr(shared_ptr<Set<R>> expr) = 0;
// virtual string visitSuperExpr(Super& expr) = 0;
// virtual string visitThisExpr(This& expr) = 0;
};
Expand Down Expand Up @@ -194,28 +200,36 @@ class Call:
vector<shared_ptr<Expr<R>>> arguments;
};

// template <class R>
// class Get: public Expr<R> {
// public:
// Get(shared_ptr<Expr<R>> object, Token name);
// R accept(shared_ptr<Visitor<R>> visitor) override {
// return visitor->visitGetExpr(*this);
// }
// Token name;
// shared_ptr<Expr<R>> object;
// };
template <class R>
class Get:
public Expr<R>,
public std::enable_shared_from_this<Get<R>>
{
public:
Get(shared_ptr<Expr<R>> object_, Token name_):
object(object_), name(name_) { }
R accept(shared_ptr<Visitor<R>> visitor) override {
return visitor->visitGetExpr(this->shared_from_this());
}
shared_ptr<Expr<R>> object;
Token name;
};

// template <class R>
// class Set: public Expr<R> {
// public:
// Set(shared_ptr<Expr<R>> object, Token name, shared_ptr<Expr<R>> value);
// R accept(shared_ptr<Visitor<R>> visitor) override {
// return visitor->visitSetExpr(*this);
// };
// shared_ptr<Expr<R>> object;
// Token name;
// shared_ptr<Expr<R>> value;
// };
template <class R>
class Set:
public Expr<R>,
public std::enable_shared_from_this<Set<R>>
{
public:
Set(shared_ptr<Expr<R>> object_, Token name_, shared_ptr<Expr<R>> value_):
object(object_), name(name_), value(value_) { }
R accept(shared_ptr<Visitor<R>> visitor) override {
return visitor->visitSetExpr(this->shared_from_this());
};
shared_ptr<Expr<R>> object;
Token name;
shared_ptr<Expr<R>> value;
};

// template <class R>
// class Super: public Expr<R> {
Expand Down
45 changes: 39 additions & 6 deletions Interpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@
#include "./RuntimeError.hpp"
#include "./Environment.hpp"
#include "./LoxCallable.hpp"
#include "./LoxInstance.hpp"
#include "./LoxClass.hpp"
#include "./LoxFunction.hpp"
#include "./ReturnError.hpp"
#include "./LoxClass.hpp"
#include "./lox.hpp"

using std::stod;
Expand Down Expand Up @@ -168,7 +169,8 @@ Object Interpreter::visitVariableExpr(shared_ptr<Variable<Object>> expr) {
return lookUpVariable(expr->name, expr);
}

Object Interpreter::lookUpVariable(Token name, shared_ptr<Variable<Object>> expr) {
Object Interpreter::lookUpVariable(
Token name, shared_ptr<Variable<Object>> expr) {
auto distance = locals.find(expr);
if (distance != locals.end()) {
return environment->getAt(distance->second, name.lexeme);
Expand All @@ -185,7 +187,8 @@ Object Interpreter::visitCallExpr(shared_ptr<Call<Object>> expr) {
arguments.push_back(evaluate(argument));
}

if (callee.type != Object::Object_fun && callee.type != Object::Object_class) {
if (callee.type != Object::Object_fun &&
callee.type != Object::Object_class) {
throw RuntimeError(expr->paren,
"Can only call functions and classes.");
}
Expand All @@ -205,6 +208,29 @@ Object Interpreter::visitCallExpr(shared_ptr<Call<Object>> expr) {
return callable->call(shared_from_this(), arguments);
}

Object Interpreter::visitGetExpr(shared_ptr<Get<Object>> expr) {
Object object = evaluate(expr->object);
if (object.type == Object::Object_instance) {
return (object.instance)->get(expr->name);
}

throw RuntimeError(expr->name,
"Only instances have properties.");
}

Object Interpreter::visitSetExpr(shared_ptr<Set<Object>> expr) {
Object object = evaluate(expr->object);

if (object.type != Object::Object_instance) {
throw RuntimeError(expr->name, "Only instances have fields.");
}

Object value = evaluate(expr->value);
value.instance->set(expr->name, value);
return value;
}


void Interpreter::visitExpressionStmt(const Expression& stmt) {
evaluate(stmt.expression);
}
Expand Down Expand Up @@ -235,7 +261,14 @@ void Interpreter::visitBlockStmt(const Block& stmt) {

void Interpreter::visitClassStmt(const Class& stmt) {
environment->define(stmt.name.lexeme, Object::make_nil_obj());
auto klass = shared_ptr<LoxClass>(new LoxClass(stmt.name.lexeme));

map<string, shared_ptr<LoxFunction>> methods;
for (auto method : stmt.methods) {
shared_ptr<LoxFunction> function(new LoxFunction(method, environment));
methods[method->name.lexeme] = function;
}

auto klass = shared_ptr<LoxClass>(new LoxClass(stmt.name.lexeme, methods));
environment->assign(stmt.name, Object::make_class_obj(klass));
}

Expand All @@ -254,10 +287,10 @@ void Interpreter::visitIfStmt(const If& stmt) {
}
}

void Interpreter::visitFunctionStmt(const Function& stmt) {
void Interpreter::visitFunctionStmt(shared_ptr<Function> stmt) {
shared_ptr<LoxFunction> function(new LoxFunction(stmt, environment));
Object obj = Object::make_fun_obj(function);
environment->define(stmt.name.lexeme, obj);
environment->define(stmt->name.lexeme, obj);
}

Object Interpreter::evaluate(shared_ptr<Expr<Object>> expr) {
Expand Down
4 changes: 3 additions & 1 deletion Interpreter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,16 @@ class Interpreter:
Object visitVariableExpr(shared_ptr<Variable<Object>> expr);
Object visitLogicalExpr(shared_ptr<Logical<Object>> expr);
Object visitCallExpr(shared_ptr<Call<Object>> expr);
Object visitGetExpr(shared_ptr<Get<Object>> expr);
Object visitSetExpr(shared_ptr<Set<Object>> expr);
void visitExpressionStmt(const Expression& stmt);
void visitPrintStmt(const Print& stmt);
void visitVarStmt(const Var& stmt);
void visitBlockStmt(const Block& stmt);
void visitClassStmt(const Class& stmt);
void visitIfStmt(const If& stmt);
void visitWhileStmt(const While& stmt);
void visitFunctionStmt(const Function& stmt);
void visitFunctionStmt(shared_ptr<Function> stmt);
void visitReturnStmt(const Return& stmt);
void executeBlock(
vector<shared_ptr<Stmt>> statements,
Expand Down
12 changes: 11 additions & 1 deletion LoxClass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,16 @@
#include "./LoxClass.hpp"
#include "./LoxInstance.hpp"
#include "./Interpreter.hpp"
#include "./LoxFunction.hpp"
#include "./Token.hpp"

using std::string;
using std::shared_ptr;
using std::vector;


LoxClass::LoxClass(string name_): name(name_) {}
LoxClass::LoxClass(string name_, map<string, shared_ptr<LoxFunction>> methods_):
name(name_), methods(methods_) {}

Object LoxClass::call(
shared_ptr<Interpreter> interpreter,
Expand All @@ -29,3 +31,11 @@ int LoxClass::arity() {
string LoxClass::toString() {
return name;
}

shared_ptr<LoxFunction> LoxClass::findMethod(string name) {
auto searched = methods.find(name);
if (searched != methods.end()) {
return searched->second;
}
return nullptr;
}
10 changes: 9 additions & 1 deletion LoxClass.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,26 @@
#include <string>
#include <memory>
#include <vector>
#include <map>
#include "./LoxCallable.hpp"
#include "./Interpreter.hpp"
#include "./LoxFunction.hpp"
#include "./Token.hpp"

using std::string;
using std::shared_ptr;
using std::vector;
using std::map;

class LoxClass: public LoxCallable {
public:
string name;
explicit LoxClass(string name_);
map<string, shared_ptr<LoxFunction>> methods;
shared_ptr<LoxFunction> findMethod(string name);
explicit LoxClass(
string name_,
map<string, shared_ptr<LoxFunction>> methods_);

Object call(
shared_ptr<Interpreter> interpreter,
vector<Object> arguments);
Expand Down
12 changes: 6 additions & 6 deletions LoxFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ using std::vector;
using std::string;

LoxFunction::LoxFunction(
Function declaration_,
shared_ptr<Function> declaration_,
shared_ptr<Environment> closure_
): declaration(declaration_), closure(closure_) {}

int LoxFunction::arity() {
return declaration.params.size();
return declaration->params.size();
}

Object LoxFunction::call(
Expand All @@ -30,20 +30,20 @@ Object LoxFunction::call(
) {
shared_ptr<Environment> environment(new Environment(closure));

for (int i = 0; i < declaration.params.size(); i++) {
for (int i = 0; i < declaration->params.size(); i++) {
environment->define(
declaration.params[i].lexeme,
declaration->params[i].lexeme,
arguments[i]);
}

try {
interpreter->executeBlock(declaration.body, environment);
interpreter->executeBlock(declaration->body, environment);
} catch (ReturnError returnValue) {
return returnValue.value;
}
return Object::make_nil_obj();
}

string LoxFunction::toString() {
return "<fn " + declaration.name.lexeme + ">";
return "<fn " + declaration->name.lexeme + ">";
}
7 changes: 5 additions & 2 deletions LoxFunction.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,12 @@ using std::string;

class LoxFunction: public LoxCallable {
public:
Function declaration;
shared_ptr<Function> declaration;
shared_ptr<Environment> closure;
explicit LoxFunction(Function declaration_, shared_ptr<Environment> closure_);
explicit LoxFunction(
shared_ptr<Function> declaration_,
shared_ptr<Environment> closure_
);

int arity();

Expand Down
21 changes: 21 additions & 0 deletions LoxInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

#include "./LoxInstance.hpp"
#include "./LoxClass.hpp"
#include "./RuntimeError.hpp"
#include "./Token.hpp"

using std::string;

Expand All @@ -12,3 +14,22 @@ LoxInstance::LoxInstance(LoxClass klass_): klass(klass_) {}
string LoxInstance::toString() {
return klass.name + " instance";
}

Object LoxInstance::get(Token name) {
auto searched = fields.find(name.lexeme);
if (searched != fields.end()) {
return searched->second;
}

shared_ptr<LoxFunction> method = klass.findMethod(name.lexeme);
if (method != nullptr) {
return Object::make_fun_obj(method);
}

throw RuntimeError(name,
"Undefined property '" + name.lexeme + "'.");
}

void LoxInstance::set(Token name, Object value) {
fields[name.lexeme] = value;
}
6 changes: 6 additions & 0 deletions LoxInstance.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,19 @@
#define LOXINSTANCE_HPP_

#include <string>
#include <map>
#include "./LoxClass.hpp"
#include "./Token.hpp"

using std::string;
using std::map;

class LoxInstance {
public:
LoxClass klass;
map<string, Object> fields;
Object get(Token name);
void set(Token name, Object value);
explicit LoxInstance(LoxClass klass_);
string toString();
};
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ CXX = g++

all: main

Token.o: Token.cpp Token.hpp
LoxInstance.o: LoxInstance.cpp LoxInstance.hpp
LoxClass.o: LoxClass.cpp LoxClass.hpp
Resolver.o: Resolver.cpp Resolver.hpp
Token.o: Token.cpp Token.hpp
LoxFunction.o: LoxFunction.cpp LoxFunction.hpp
Environment.o: Environment.cpp Environment.hpp
Interpreter.o: Interpreter.cpp Interpreter.hpp
Expand Down
Loading

0 comments on commit 793e0f8

Please sign in to comment.