Skip to content

Commit

Permalink
add Base Class feature
Browse files Browse the repository at this point in the history
  • Loading branch information
flyingalex committed Feb 23, 2020
1 parent 7775c18 commit bef5cd4
Show file tree
Hide file tree
Showing 21 changed files with 208 additions and 604 deletions.
Binary file modified .DS_Store
Binary file not shown.
22 changes: 15 additions & 7 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,21 @@ project(cpp_lox LANGUAGES CXX)

set(CMAKE_INCLUDE_CURRENT_DIR ON)

set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

add_executable(cpp_lox
main.cpp
)
set(SOURCE_FILES
LoxInstance.cpp LoxInstance.hpp
LoxClass.cpp LoxClass.hpp
Resolver.cpp Resolver.hpp
Token.cpp Token.hpp
LoxFunction.cpp LoxFunction.hpp
Environment.cpp Environment.hpp
Interpreter.cpp Interpreter.hpp
lox.cpp lox.hpp
Parser.cpp Parser.hpp
Scanner.cpp Scanner.hpp
Stmt.hpp Expr.hpp
main.cpp
)
add_executable(cpp_lox ${SOURCE_FILES})
356 changes: 0 additions & 356 deletions CMakeLists.txt.user

This file was deleted.

23 changes: 18 additions & 5 deletions Interpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "./LoxCallable.hpp"
#include "./LoxFunction.hpp"
#include "./ReturnError.hpp"
#include "./LoxClass.hpp"
#include "./lox.hpp"

using std::stod;
Expand Down Expand Up @@ -184,18 +185,24 @@ Object Interpreter::visitCallExpr(shared_ptr<Call<Object>> expr) {
arguments.push_back(evaluate(argument));
}

if (callee.type != Object::Object_fun) {
if (callee.type != Object::Object_fun && callee.type != Object::Object_class) {
throw RuntimeError(expr->paren,
"Can only call functions and classes.");
}

shared_ptr<LoxCallable> function = callee.function;
if (arguments.size() != function->arity()) {
shared_ptr<LoxCallable> callable;
if (callee.type == Object::Object_fun) {
callable = callee.function;
}
if (callee.type == Object::Object_class) {
callable = callee.lox_class;
}
if (arguments.size() != callable->arity()) {
throw RuntimeError(expr->paren, "Expected " +
to_string(function->arity()) + " arguments but got " +
to_string(callable->arity()) + " arguments but got " +
to_string(arguments.size()) + ".");
}
return function->call(shared_from_this(), arguments);
return callable->call(shared_from_this(), arguments);
}

void Interpreter::visitExpressionStmt(const Expression& stmt) {
Expand Down Expand Up @@ -226,6 +233,12 @@ void Interpreter::visitBlockStmt(const Block& stmt) {
executeBlock(stmt.statements, env);
}

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));
environment->assign(stmt.name, Object::make_class_obj(klass));
}

void Interpreter::visitWhileStmt(const While& stmt) {
while (isTruthy(evaluate(stmt.condition))) {
Object obj = evaluate(stmt.condition);
Expand Down
1 change: 1 addition & 0 deletions Interpreter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class Interpreter:
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);
Expand Down
31 changes: 31 additions & 0 deletions LoxClass.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright 2020.2.23 <Copyright hulin>

#include <string>
#include <memory>
#include <vector>

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

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


LoxClass::LoxClass(string name_): name(name_) {}

Object LoxClass::call(
shared_ptr<Interpreter> interpreter,
vector<Object> arguments) {
auto instance = shared_ptr<LoxInstance>(new LoxInstance(*this));
return Object::make_instance_obj(instance);
}

int LoxClass::arity() {
return 0;
}
string LoxClass::toString() {
return name;
}
28 changes: 28 additions & 0 deletions LoxClass.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright 2020.2.23 <Copyright hulin>

#ifndef LOXCLASS_HPP_
#define LOXCLASS_HPP_

#include <string>
#include <memory>
#include <vector>
#include "./LoxCallable.hpp"
#include "./Interpreter.hpp"
#include "./Token.hpp"

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

class LoxClass: public LoxCallable {
public:
string name;
explicit LoxClass(string name_);
Object call(
shared_ptr<Interpreter> interpreter,
vector<Object> arguments);
int arity();
string toString();
};

#endif // LOXCLASS_HPP_
14 changes: 14 additions & 0 deletions LoxInstance.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright 2020.2.23 <Copyright hulin>

#include <string>

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

using std::string;

LoxInstance::LoxInstance(LoxClass klass_): klass(klass_) {}

string LoxInstance::toString() {
return klass.name + " instance";
}
18 changes: 18 additions & 0 deletions LoxInstance.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright 2020.2.23 <Copyright hulin>

#ifndef LOXINSTANCE_HPP_
#define LOXINSTANCE_HPP_

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

using std::string;

class LoxInstance {
public:
LoxClass klass;
explicit LoxInstance(LoxClass klass_);
string toString();
};

#endif // LOXINSTANCE_HPP_
13 changes: 6 additions & 7 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
CXXFLAGS=-g -std=c++11 -Wall -pedantic
CXX = g++

all: main test demo
all: main

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 Environment.o LoxFunction.o
lox.o: lox.cpp lox.hpp Interpreter.o Resolver.o
Interpreter.o: Interpreter.cpp Interpreter.hpp
lox.o: lox.cpp lox.hpp
Parser.o: Parser.cpp Parser.hpp
Scanner.o: Scanner.cpp Scanner.hpp
AstPrinter.o: AstPrinter.hpp AstPrinter.cpp

main: main.cpp lox.o LoxFunction.o Token.o Scanner.o Parser.o Interpreter.o Environment.o Resolver.o
test: test.cpp AstPrinter.o Token.o
demo: demo.cpp
main: main.cpp lox.o LoxFunction.o Token.o Scanner.o Parser.o Interpreter.o Environment.o Resolver.o LoxClass.o LoxInstance.o

clean:
rm -f *.o main
14 changes: 14 additions & 0 deletions Parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,7 @@ shared_ptr<Stmt> Parser::varDeclaration() {

shared_ptr<Stmt> Parser::declaration() {
try {
if (match({ CLASS })) return classDeclaration();
if (match({ FUN })) return function("function");
if (match({ VAR })) return varDeclaration();
return statement();
Expand All @@ -432,6 +433,19 @@ shared_ptr<Stmt> Parser::declaration() {
}
}

shared_ptr<Stmt> Parser::classDeclaration() {
Token name = consume(IDENTIFIER, "Expect class name.");
consume(LEFT_BRACE, "Expect '{' before class body.");

vector<shared_ptr<Stmt>> methods;
while (!check(RIGHT_BRACE) && !isAtEnd()) {
methods.push_back(function("method"));
}
consume(RIGHT_BRACE, "Expect '}' after class body.");

return shared_ptr<Stmt>(new Class(name, methods));
}

vector<shared_ptr<Stmt>> Parser::parse() {
vector<shared_ptr<Stmt>> statements;
while (!isAtEnd()) {
Expand Down
1 change: 1 addition & 0 deletions Parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ class Parser {
shared_ptr<Stmt> expressionStatement();
shared_ptr<Stmt> function(string kind);
shared_ptr<Stmt> declaration();
shared_ptr<Stmt> classDeclaration();
shared_ptr<Stmt> varDeclaration();
vector<shared_ptr<Stmt>> block();
};
Expand Down
5 changes: 5 additions & 0 deletions Resolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,11 @@ void Resolver::visitBlockStmt(const Block& stmt) {
endScope();
}

void Resolver::visitClassStmt(const Class& stmt) {
declare(stmt.name);
define(stmt.name);
}

void Resolver::visitIfStmt(const If& stmt) {
resolve(stmt.condition);
resolve(stmt.thenBranch);
Expand Down
1 change: 1 addition & 0 deletions Resolver.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class Resolver:
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);
Expand Down
18 changes: 17 additions & 1 deletion Stmt.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@
/*
program → declaration* EOF ;
declaration → funDecl
declaration → classDecl
|funDecl
| varDecl
| statement ;
classDecl → "class" IDENTIFIER "{" function* "}" ;
funDecl → "fun" function ;
function → IDENTIFIER "(" parameters? ")" block ;
parameters → IDENTIFIER ( "," IDENTIFIER )* ;
Expand Down Expand Up @@ -59,6 +62,7 @@ class If;
class While;
class Function;
class Return;
class Class;

class Visitor_Stmt {
public:
Expand All @@ -71,6 +75,7 @@ class Visitor_Stmt {
virtual void visitWhileStmt(const While& stmt) = 0;
virtual void visitFunctionStmt(const Function& stmt) = 0;
virtual void visitReturnStmt(const Return& stmt) = 0;
virtual void visitClassStmt(const Class& stmt) = 0;
};

class Stmt {
Expand Down Expand Up @@ -181,4 +186,15 @@ class Return: public Stmt {
shared_ptr<Expr<Object>> value;
};

class Class: public Stmt {
public:
Class(Token name_, vector<shared_ptr<Stmt>> function_):
name(name_), function(function_) { }
void accept(shared_ptr<Visitor_Stmt> visitor) override {
visitor->visitClassStmt(*this);
}
Token name;
vector<shared_ptr<Stmt>> function;
};

#endif // STMT_HPP_
8 changes: 8 additions & 0 deletions Token.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ using std::string;
using std::shared_ptr;

class LoxCallable;
class LoxInstance;
class LoxClass;

typedef enum {
LEFT_PAREN, RIGHT_PAREN, LEFT_BRACE, RIGHT_BRACE,
Expand Down Expand Up @@ -39,6 +41,8 @@ class Object {
Object_bool,
Object_nil,
Object_fun,
Object_instance,
Object_class,
} Object_type;
string str;
double num;
Expand All @@ -47,11 +51,15 @@ class Object {
Object_type type;
string toString();
shared_ptr<LoxCallable> function;
shared_ptr<LoxInstance> instance;
shared_ptr<LoxClass> lox_class;
static Object make_num_obj(double num);
static Object make_str_obj(string str);
static Object make_bool_obj(bool boolean);
static Object make_nil_obj();
static Object make_fun_obj(shared_ptr<LoxCallable> function_);
static Object make_instance_obj(shared_ptr<LoxInstance> instance_);
static Object make_class_obj(shared_ptr<LoxClass> lox_class_);
};

class Token {
Expand Down
Loading

0 comments on commit bef5cd4

Please sign in to comment.