* Example script
#+begin_src
fn fib(n) {
- if (n < 2) {
- return n;
- }
- return fib(n-1)+fib(n-2);
+ return fibIter(n, 0, 1);
+}
+
+fn fibIter(n, curr, next) {
+ if (n == 0) {
+ return curr;
+ } else if (n == 1) {
+ return next;
+ } else {
+ return fibIter(n - 1, next, curr + next);
+ }
}
class Prova {
init(n) {
this.n = n;
this.start = clock();
- fib(n);
+ this.fib_n = fib(n);
this.end = clock();
}
runtime() {
- println("fib("+ this.n +") runtime: " + (this.end - this.start));
+ println("fib("+ this.n +") = "+ this.fib_n + " runtime: " +
+ (this.end - this.start));
}
}
class LBPLCallable {
public:
virtual int arity() = 0;
- virtual LBPLType call(Interpreter*, std::vector<LBPLType>&) = 0;
+ virtual Value call(Interpreter*, std::vector<Value>&) = 0;
};
#endif
LBPLFunc *findMethod(const std::string &);
int arity() override;
- LBPLType call(Interpreter *, std::vector<LBPLType> &) override;
+ Value call(Interpreter *, std::vector<Value> &) override;
};
#endif
void bind(std::shared_ptr<LBPLInstance> &instance);
int arity() override;
- LBPLType call(Interpreter *, std::vector<LBPLType> &) override;
+ Value call(Interpreter *, std::vector<Value> &) override;
};
#endif
class LBPLInstance {
private:
LBPLClass *lbplClass;
- std::map<std::string, LBPLType> fields;
+ std::map<std::string, Value> fields;
public:
LBPLInstance(LBPLClass *lbplClass) : lbplClass(lbplClass), fields() {}
LBPLInstance(LBPLInstance *other)
: lbplClass(other->lbplClass), fields(other->fields) {}
- LBPLType get(const Token *name);
- void set(const Token *name, LBPLType &value);
+ Value get(const Token *name);
+ void set(const Token *name, Value &value);
};
#endif
class LBPLCallable;
class LBPLClass;
-using LBPLType =
+using Value =
std::variant<std::string, int, double, bool, char, std::nullptr_t,
std::shared_ptr<LBPLClass>, std::shared_ptr<LBPLInstance>,
std::shared_ptr<LBPLCallable>>;
void visitExprStmt(ExprStmt *) override;
void visitReturnStmt(ReturnStmt *) override;
- LBPLType visitBinaryExpr(BinaryExpr *) override;
- LBPLType visitBreakExpr(BreakExpr *) override;
- LBPLType visitContinueExpr(ContinueExpr *) override;
- LBPLType visitUnaryExpr(UnaryExpr *) override;
- LBPLType visitLiteralExpr(LiteralExpr *) override;
- LBPLType visitGroupExpr(GroupingExpr *) override;
- LBPLType visitSuperExpr(SuperExpr *) override;
- LBPLType visitThisExpr(ThisExpr *) override;
- LBPLType visitCallExpr(FnCallExpr *) override;
- LBPLType visitGetFieldExpr(GetFieldExpr *) override;
- LBPLType visitSetFieldExpr(SetFieldExpr *) override;
- LBPLType visitTernaryExpr(TernaryExpr *) override;
- LBPLType visitVarExpr(VariableExpr *) override;
- LBPLType visitAssignExpr(AssignExpr *) override;
+ Value visitBinaryExpr(BinaryExpr *) override;
+ Value visitBreakExpr(BreakExpr *) override;
+ Value visitContinueExpr(ContinueExpr *) override;
+ Value visitUnaryExpr(UnaryExpr *) override;
+ Value visitLiteralExpr(LiteralExpr *) override;
+ Value visitGroupExpr(GroupingExpr *) override;
+ Value visitSuperExpr(SuperExpr *) override;
+ Value visitThisExpr(ThisExpr *) override;
+ Value visitCallExpr(FnCallExpr *) override;
+ Value visitGetFieldExpr(GetFieldExpr *) override;
+ Value visitSetFieldExpr(SetFieldExpr *) override;
+ Value visitTernaryExpr(TernaryExpr *) override;
+ Value visitVarExpr(VariableExpr *) override;
+ Value visitAssignExpr(AssignExpr *) override;
};
#endif
int arity() override { return 1; };
- LBPLType call(Interpreter *, std::vector<LBPLType> &args) override {
+ Value call(Interpreter *, std::vector<Value> &args) override {
if (std::holds_alternative<std::string>(args[0])) {
std::cout << std::get<std::string>(args[0]) << std::endl;
} else if (std::holds_alternative<int>(args[0])) {
int arity() override { return 0; };
- LBPLType call(Interpreter *, std::vector<LBPLType> &args) override {
+ Value call(Interpreter *, std::vector<Value> &args) override {
return std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch())
.count() /
class Environment {
public:
- std::map<std::string, LBPLType> env;
+ std::map<std::string, Value> env;
std::shared_ptr<Environment> enclosing;
public:
return std::make_shared<Environment>(*this);
}
- void define(const std::string &, LBPLType &);
- void define(const std::string &, LBPLType &&);
+ void define(const std::string &, Value &);
+ void define(const std::string &, Value &&);
void printEnv(const std::string &&);
- LBPLType get(std::shared_ptr<const Token> &);
- LBPLType getAt(int, std::shared_ptr<const Token> &);
- LBPLType getAt(int, const std::string &);
- void assign(std::shared_ptr<const Token> &, LBPLType &);
- void assign(std::shared_ptr<const Token> &, LBPLType &&);
- void assignAt(int, std::shared_ptr<const Token> &, LBPLType &);
+ Value get(std::shared_ptr<const Token> &);
+ Value getAt(int, std::shared_ptr<const Token> &);
+ Value getAt(int, const std::string &);
+ void assign(std::shared_ptr<const Token> &, Value &);
+ void assign(std::shared_ptr<const Token> &, Value &&);
+ void assignAt(int, std::shared_ptr<const Token> &, Value &);
};
#endif
: line(line), column(column), file(filename) {}
virtual ~Expr(){};
- virtual LBPLType accept(Expression::Visitor *) { return nullptr; }
+ virtual Value accept(Expression::Visitor *) { return nullptr; }
};
struct BinaryExpr : public Expr {
: left(std::move(left)), right(std::move(right)), op(op),
Expr(line, column, file) {}
- LBPLType accept(Expression::Visitor *visitor) {
+ Value accept(Expression::Visitor *visitor) {
return visitor->visitBinaryExpr(this);
}
};
BreakExpr(int line, int column, const std::string &file)
: Expr(line, column, file) {}
- LBPLType accept(Expression::Visitor *visitor) {
+ Value accept(Expression::Visitor *visitor) {
return visitor->visitBreakExpr(this);
}
};
struct ContinueExpr : public Expr {
ContinueExpr(int line, int column, const std::string &file)
: Expr(line, column, file) {}
- LBPLType accept(Expression::Visitor *visitor) {
+ Value accept(Expression::Visitor *visitor) {
return visitor->visitContinueExpr(this);
}
};
UnaryExpr(int line, int column, const std::string &file,
std::unique_ptr<Expr> right, std::shared_ptr<const Token> &op)
: right(std::move(right)), op(op), Expr(line, column, file) {}
- LBPLType accept(Expression::Visitor *visitor) {
+ Value accept(Expression::Visitor *visitor) {
return visitor->visitUnaryExpr(this);
}
};
LiteralExpr(int line, int column, const std::string &file,
std::shared_ptr<const Token> &&literal)
: token(literal), Expr(line, column, file) {}
- LBPLType accept(Expression::Visitor *visitor) {
+ Value accept(Expression::Visitor *visitor) {
return visitor->visitLiteralExpr(this);
}
};
SuperExpr(int line, int column, const std::string &file,
std::shared_ptr<const Token> &field)
: field(field), Expr(line, column, file) {}
- LBPLType accept(Expression::Visitor *visitor) {
+ Value accept(Expression::Visitor *visitor) {
return visitor->visitSuperExpr(this);
}
};
ThisExpr(int line, int column, const std::string &file, std::shared_ptr<const Token>& keyword)
: keyword(keyword), Expr(line, column, file) {}
- LBPLType accept(Expression::Visitor *visitor) {
+ Value accept(Expression::Visitor *visitor) {
return visitor->visitThisExpr(this);
}
};
GroupingExpr(int line, int column, const std::string &file,
std::unique_ptr<Expr> &expr)
: expr(std::move(expr)), Expr(line, column, file) {}
- LBPLType accept(Expression::Visitor *visitor) {
+ Value accept(Expression::Visitor *visitor) {
return visitor->visitGroupExpr(this);
}
};
VariableExpr(int line, int column, const std::string &file,
std::shared_ptr<const Token> &variable)
: variable(variable), Expr(line, column, file) {}
- LBPLType accept(Expression::Visitor *visitor) {
+ Value accept(Expression::Visitor *visitor) {
return visitor->visitVarExpr(this);
}
};
std::unique_ptr<Expr> &value)
: variable(variable), value(std::move(value)), Expr(line, column, file) {}
- LBPLType accept(Expression::Visitor *visitor) {
+ Value accept(Expression::Visitor *visitor) {
return visitor->visitAssignExpr(this);
}
};
: callee(std::move(callee)), args(std::move(args)),
Expr(line, column, file) {}
- LBPLType accept(Expression::Visitor *visitor) {
+ Value accept(Expression::Visitor *visitor) {
return visitor->visitCallExpr(this);
}
};
: condition(std::move(condition)), trueBranch(std::move(trueBranch)),
falseBranch(std::move(falseBranch)), Expr(line, column, file) {}
- LBPLType accept(Expression::Visitor *visitor) {
+ Value accept(Expression::Visitor *visitor) {
return visitor->visitTernaryExpr(this);
}
};
std::shared_ptr<const Token> &field)
: instance(std::move(instance)), field(field), Expr(line, column, file) {}
- LBPLType accept(Expression::Visitor *visitor) {
+ Value accept(Expression::Visitor *visitor) {
return visitor->visitGetFieldExpr(this);
}
};
: instance(std::move(instance)), field(field), value(std::move(value)),
Expr(line, column, file) {}
- LBPLType accept(Expression::Visitor *visitor) {
+ Value accept(Expression::Visitor *visitor) {
return visitor->visitSetFieldExpr(this);
}
};
class ContinueException {};
class ReturnException {
public:
- LBPLType value;
+ Value value;
public:
- ReturnException(LBPLType &&value) : value(value) {}
+ ReturnException(Value &&value) : value(value) {}
};
class Interpreter : Statement::Visitor, Expression::Visitor {
private:
void execute(std::unique_ptr<Stmt> &);
- LBPLType evaluate(std::unique_ptr<Expr> &);
- LBPLType lookupVariable(std::shared_ptr<const Token> &, Expr *);
- bool isTruthy(const LBPLType &);
- bool isTruthy(LBPLType &&);
+ Value evaluate(std::unique_ptr<Expr> &);
+ Value lookupVariable(std::shared_ptr<const Token> &, Expr *);
+ bool isTruthy(const Value &);
+ bool isTruthy(Value &&);
- LBPLType performBinaryOperation(std::shared_ptr<const Token> &,
- const LBPLType &, const LBPLType &);
+ Value performBinaryOperation(std::shared_ptr<const Token> &,
+ const Value &, const Value &);
void visitFnStmt(FnStmt *) override;
void visitVarStmt(VarStmt *) override;
void visitExprStmt(ExprStmt *) override;
void visitReturnStmt(ReturnStmt *) override;
- LBPLType visitBinaryExpr(BinaryExpr *) override;
- LBPLType visitBreakExpr(BreakExpr *) override;
- LBPLType visitContinueExpr(ContinueExpr *) override;
- LBPLType visitUnaryExpr(UnaryExpr *) override;
- LBPLType visitLiteralExpr(LiteralExpr *) override;
- LBPLType visitGroupExpr(GroupingExpr *) override;
- LBPLType visitSuperExpr(SuperExpr *) override;
- LBPLType visitThisExpr(ThisExpr *) override;
- LBPLType visitCallExpr(FnCallExpr *) override;
- LBPLType visitGetFieldExpr(GetFieldExpr *) override;
- LBPLType visitSetFieldExpr(SetFieldExpr *) override;
- LBPLType visitTernaryExpr(TernaryExpr *) override;
- LBPLType visitVarExpr(VariableExpr *) override;
- LBPLType visitAssignExpr(AssignExpr *) override;
+ Value visitBinaryExpr(BinaryExpr *) override;
+ Value visitBreakExpr(BreakExpr *) override;
+ Value visitContinueExpr(ContinueExpr *) override;
+ Value visitUnaryExpr(UnaryExpr *) override;
+ Value visitLiteralExpr(LiteralExpr *) override;
+ Value visitGroupExpr(GroupingExpr *) override;
+ Value visitSuperExpr(SuperExpr *) override;
+ Value visitThisExpr(ThisExpr *) override;
+ Value visitCallExpr(FnCallExpr *) override;
+ Value visitGetFieldExpr(GetFieldExpr *) override;
+ Value visitSetFieldExpr(SetFieldExpr *) override;
+ Value visitTernaryExpr(TernaryExpr *) override;
+ Value visitVarExpr(VariableExpr *) override;
+ Value visitAssignExpr(AssignExpr *) override;
public:
void executeBlock(std::vector<std::unique_ptr<Stmt>> &,
void visitExprStmt(ExprStmt *) override;
void visitReturnStmt(ReturnStmt *) override;
- LBPLType visitBinaryExpr(BinaryExpr *) override;
- LBPLType visitBreakExpr(BreakExpr *) override;
- LBPLType visitContinueExpr(ContinueExpr *) override;
- LBPLType visitUnaryExpr(UnaryExpr *) override;
- LBPLType visitLiteralExpr(LiteralExpr *) override;
- LBPLType visitGroupExpr(GroupingExpr *) override;
- LBPLType visitSuperExpr(SuperExpr *) override;
- LBPLType visitThisExpr(ThisExpr *) override;
- LBPLType visitCallExpr(FnCallExpr *) override;
- LBPLType visitGetFieldExpr(GetFieldExpr *) override;
- LBPLType visitSetFieldExpr(SetFieldExpr *) override;
- LBPLType visitTernaryExpr(TernaryExpr *) override;
- LBPLType visitVarExpr(VariableExpr *) override;
- LBPLType visitAssignExpr(AssignExpr *) override;
+ Value visitBinaryExpr(BinaryExpr *) override;
+ Value visitBreakExpr(BreakExpr *) override;
+ Value visitContinueExpr(ContinueExpr *) override;
+ Value visitUnaryExpr(UnaryExpr *) override;
+ Value visitLiteralExpr(LiteralExpr *) override;
+ Value visitGroupExpr(GroupingExpr *) override;
+ Value visitSuperExpr(SuperExpr *) override;
+ Value visitThisExpr(ThisExpr *) override;
+ Value visitCallExpr(FnCallExpr *) override;
+ Value visitGetFieldExpr(GetFieldExpr *) override;
+ Value visitSetFieldExpr(SetFieldExpr *) override;
+ Value visitTernaryExpr(TernaryExpr *) override;
+ Value visitVarExpr(VariableExpr *) override;
+ Value visitAssignExpr(AssignExpr *) override;
public:
Resolver(Interpreter *interpreter)
namespace Expression {
struct Visitor {
- virtual LBPLType visitBinaryExpr(BinaryExpr *) = 0;
- virtual LBPLType visitBreakExpr(BreakExpr *) = 0;
- virtual LBPLType visitContinueExpr(ContinueExpr *) = 0;
- virtual LBPLType visitUnaryExpr(UnaryExpr *) = 0;
- virtual LBPLType visitLiteralExpr(LiteralExpr *) = 0;
- virtual LBPLType visitGroupExpr(GroupingExpr *) = 0;
- virtual LBPLType visitSuperExpr(SuperExpr *) = 0;
- virtual LBPLType visitThisExpr(ThisExpr *) = 0;
- virtual LBPLType visitCallExpr(FnCallExpr *) = 0;
- virtual LBPLType visitGetFieldExpr(GetFieldExpr *) = 0;
- virtual LBPLType visitSetFieldExpr(SetFieldExpr *) = 0;
- virtual LBPLType visitTernaryExpr(TernaryExpr *) = 0;
- virtual LBPLType visitVarExpr(VariableExpr *) = 0;
- virtual LBPLType visitAssignExpr(AssignExpr *) = 0;
+ virtual Value visitBinaryExpr(BinaryExpr *) = 0;
+ virtual Value visitBreakExpr(BreakExpr *) = 0;
+ virtual Value visitContinueExpr(ContinueExpr *) = 0;
+ virtual Value visitUnaryExpr(UnaryExpr *) = 0;
+ virtual Value visitLiteralExpr(LiteralExpr *) = 0;
+ virtual Value visitGroupExpr(GroupingExpr *) = 0;
+ virtual Value visitSuperExpr(SuperExpr *) = 0;
+ virtual Value visitThisExpr(ThisExpr *) = 0;
+ virtual Value visitCallExpr(FnCallExpr *) = 0;
+ virtual Value visitGetFieldExpr(GetFieldExpr *) = 0;
+ virtual Value visitSetFieldExpr(SetFieldExpr *) = 0;
+ virtual Value visitTernaryExpr(TernaryExpr *) = 0;
+ virtual Value visitVarExpr(VariableExpr *) = 0;
+ virtual Value visitAssignExpr(AssignExpr *) = 0;
};
} // namespace Expression
#include "LBPLInstance.h"
#include "interpreter.h"
-LBPLType LBPLClass::call(Interpreter *interpreter, std::vector<LBPLType> &args) {
+Value LBPLClass::call(Interpreter *interpreter, std::vector<Value> &args) {
auto instance = std::make_shared<LBPLInstance>(this);
LBPLFunc *init = findMethod("init");
int LBPLFunc::arity() { return stmt->args.size(); }
-LBPLType LBPLFunc::call(Interpreter *interpreter, std::vector<LBPLType> &args) {
+Value LBPLFunc::call(Interpreter *interpreter, std::vector<Value> &args) {
auto env = std::make_shared<Environment>(closureEnv);
for (int i = 0; i < stmt->args.size(); i++) {
#include "LBPLInstance.h"
-LBPLType LBPLInstance::get(const Token *name) {
+Value LBPLInstance::get(const Token *name) {
if (fields.contains(name->lexeme)) {
return fields.find(name->lexeme)->second;
}
throw RuntimeError(name, "Undefined field '" + name->lexeme + "'.");
}
-void LBPLInstance::set(const Token *name, LBPLType &value) {
+void LBPLInstance::set(const Token *name, Value &value) {
fields.insert_or_assign(name->lexeme, value);
}
std::cout << ")\n";
}
-LBPLType AST_Printer::visitBinaryExpr(BinaryExpr *expr) {
+Value AST_Printer::visitBinaryExpr(BinaryExpr *expr) {
std::cout << "(" << expr->op->lexeme << " ";
expr->left->accept(this);
std::cout << " ";
return nullptr;
}
-LBPLType AST_Printer::visitBreakExpr(BreakExpr *expr) {
+Value AST_Printer::visitBreakExpr(BreakExpr *expr) {
std::cout << "(breaking)";
return nullptr;
}
-LBPLType AST_Printer::visitContinueExpr(ContinueExpr *expr) {
+Value AST_Printer::visitContinueExpr(ContinueExpr *expr) {
std::cout << "(continuing)\n";
return nullptr;
}
-LBPLType AST_Printer::visitUnaryExpr(UnaryExpr *expr) {
+Value AST_Printer::visitUnaryExpr(UnaryExpr *expr) {
std::cout << "(" << expr->op->lexeme << " ";
expr->right->accept(this);
std::cout << ")";
return nullptr;
}
-LBPLType AST_Printer::visitLiteralExpr(LiteralExpr *expr) {
+Value AST_Printer::visitLiteralExpr(LiteralExpr *expr) {
std::cout << expr->token->lexeme;
return nullptr;
}
-LBPLType AST_Printer::visitSuperExpr(SuperExpr *expr) {
+Value AST_Printer::visitSuperExpr(SuperExpr *expr) {
std::cout << "(super)";
return nullptr;
}
-LBPLType AST_Printer::visitThisExpr(ThisExpr *expr) {
+Value AST_Printer::visitThisExpr(ThisExpr *expr) {
std::cout << "(this)";
return nullptr;
}
-LBPLType AST_Printer::visitAssignExpr(AssignExpr *expr) {
+Value AST_Printer::visitAssignExpr(AssignExpr *expr) {
std::cout << "(assign ";
expr->value->accept(this);
std::cout << " to " << expr->variable->lexeme << ")";
return nullptr;
}
-LBPLType AST_Printer::visitGroupExpr(GroupingExpr *expr) {
+Value AST_Printer::visitGroupExpr(GroupingExpr *expr) {
expr->expr->accept(this);
return nullptr;
}
-LBPLType AST_Printer::visitCallExpr(FnCallExpr *expr) {
+Value AST_Printer::visitCallExpr(FnCallExpr *expr) {
std::cout << "(calling `";
expr->callee->accept(this);
std::cout << "` with parameters [";
return nullptr;
}
-LBPLType AST_Printer::visitGetFieldExpr(GetFieldExpr *expr) {
+Value AST_Printer::visitGetFieldExpr(GetFieldExpr *expr) {
std::cout << "get field `" << expr->field->lexeme << "` from ";
expr->instance->accept(this);
return nullptr;
}
-LBPLType AST_Printer::visitSetFieldExpr(SetFieldExpr *expr) {
+Value AST_Printer::visitSetFieldExpr(SetFieldExpr *expr) {
std::cout << "setting field `" << expr->field->lexeme << "` from ";
expr->instance->accept(this);
std::cout << " to ";
return nullptr;
}
-LBPLType AST_Printer::visitTernaryExpr(TernaryExpr *expr) {
+Value AST_Printer::visitTernaryExpr(TernaryExpr *expr) {
std::cout << "condition `";
expr->condition->accept(this);
std::cout << "` if true ";
return nullptr;
}
-LBPLType AST_Printer::visitVarExpr(VariableExpr *expr) {
+Value AST_Printer::visitVarExpr(VariableExpr *expr) {
std::cout << expr->variable->lexeme;
return nullptr;
}
#include <utility>
#include <variant>
-void Environment::define(const std::string &name, LBPLType &value) {
+void Environment::define(const std::string &name, Value &value) {
env.insert(std::make_pair(name, value));
}
-void Environment::define(const std::string &name, LBPLType &&value) {
+void Environment::define(const std::string &name, Value &&value) {
env.insert(std::make_pair(name, value));
}
-LBPLType Environment::get(std::shared_ptr<const Token> &name) {
+Value Environment::get(std::shared_ptr<const Token> &name) {
auto it = env.find(name->lexeme);
if (it != env.end()) {
throw RuntimeError(name.get(), "Undefined name '"+name->lexeme+"'.");
}
-LBPLType Environment::getAt(int depth, std::shared_ptr<const Token> &name) {
+Value Environment::getAt(int depth, std::shared_ptr<const Token> &name) {
return getAt(depth, name->lexeme);
}
-LBPLType Environment::getAt(int depth, const std::string &name) {
+Value Environment::getAt(int depth, const std::string &name) {
if (depth > 0) {
return enclosing->getAt(depth-1, name);
}
return it != env.end() ? it->second : nullptr;
}
-void Environment::assign(std::shared_ptr<const Token> &name, LBPLType &value) {
+void Environment::assign(std::shared_ptr<const Token> &name, Value &value) {
if (env.contains(name->lexeme)) {
env.insert_or_assign(name->lexeme, value);
} else if (enclosing) {
}
}
-void Environment::assign(std::shared_ptr<const Token> &name, LBPLType &&value) {
+void Environment::assign(std::shared_ptr<const Token> &name, Value &&value) {
assign(name, value);
}
-void Environment::assignAt(int depth, std::shared_ptr<const Token> &name, LBPLType &value) {
+void Environment::assignAt(int depth, std::shared_ptr<const Token> &name, Value &value) {
if (depth > 0) {
enclosing->assignAt(depth-1, name, value);
}
}
void Interpreter::visitVarStmt(VarStmt *stmt) {
- LBPLType value;
+ Value value;
if (stmt->value) {
value = stmt->value->accept(this);
}
}
void Interpreter::visitClassStmt(ClassStmt *stmt) {
- LBPLType superclass;
+ Value superclass;
currentEnv->define(stmt->name->lexeme, nullptr);
if (stmt->superclass) {
throw ReturnException(stmt->value->accept(this));
}
-LBPLType Interpreter::visitBinaryExpr(BinaryExpr *expr) {
- LBPLType left = expr->left->accept(this);
- LBPLType right = expr->right->accept(this);
+Value Interpreter::visitBinaryExpr(BinaryExpr *expr) {
+ Value left = expr->left->accept(this);
+ Value right = expr->right->accept(this);
return performBinaryOperation(expr->op, left, right);
}
-LBPLType Interpreter::visitBreakExpr(BreakExpr *) { throw BreakException(); }
-LBPLType Interpreter::visitContinueExpr(ContinueExpr *) {
+Value Interpreter::visitBreakExpr(BreakExpr *) { throw BreakException(); }
+Value Interpreter::visitContinueExpr(ContinueExpr *) {
throw ContinueException();
}
-LBPLType Interpreter::visitUnaryExpr(UnaryExpr *expr) {
- LBPLType right = expr->right->accept(this);
+Value Interpreter::visitUnaryExpr(UnaryExpr *expr) {
+ Value right = expr->right->accept(this);
if (expr->op->type == TokenType::Minus) {
if (std::holds_alternative<int>(right)) {
return nullptr;
}
-LBPLType Interpreter::visitLiteralExpr(LiteralExpr *expr) {
+Value Interpreter::visitLiteralExpr(LiteralExpr *expr) {
if (expr->token->type == TokenType::True) {
return true;
} else if (expr->token->type == TokenType::False) {
return nullptr;
}
-LBPLType Interpreter::visitGroupExpr(GroupingExpr *expr) {
+Value Interpreter::visitGroupExpr(GroupingExpr *expr) {
return expr->expr->accept(this);
}
-LBPLType Interpreter::visitSuperExpr(SuperExpr *) { return nullptr; }
-LBPLType Interpreter::visitThisExpr(ThisExpr *expr) { return lookupVariable(expr->keyword, expr); }
+Value Interpreter::visitSuperExpr(SuperExpr *) { return nullptr; }
+Value Interpreter::visitThisExpr(ThisExpr *expr) { return lookupVariable(expr->keyword, expr); }
-LBPLType Interpreter::visitCallExpr(FnCallExpr *expr) {
- LBPLType callee = expr->callee->accept(this);
+Value Interpreter::visitCallExpr(FnCallExpr *expr) {
+ Value callee = expr->callee->accept(this);
- std::vector<LBPLType> args;
+ std::vector<Value> args;
args.reserve(expr->args.size());
for (auto &&arg : expr->args) {
"Can only call a function or class initializer.");
}
-LBPLType Interpreter::visitGetFieldExpr(GetFieldExpr *expr) {
- LBPLType instance = expr->instance->accept(this);
+Value Interpreter::visitGetFieldExpr(GetFieldExpr *expr) {
+ Value instance = expr->instance->accept(this);
if (std::holds_alternative<std::shared_ptr<LBPLInstance>>(instance)) {
return std::get<std::shared_ptr<LBPLInstance>>(instance)->get(
expr->field.get());
"Only instances of classes can have properties");
}
-LBPLType Interpreter::visitSetFieldExpr(SetFieldExpr *expr) {
- LBPLType instance = expr->instance->accept(this);
+Value Interpreter::visitSetFieldExpr(SetFieldExpr *expr) {
+ Value instance = expr->instance->accept(this);
if (std::holds_alternative<std::shared_ptr<LBPLInstance>>(instance)) {
- LBPLType value = expr->value->accept(this);
+ Value value = expr->value->accept(this);
std::get<std::shared_ptr<LBPLInstance>>(instance)->set(expr->field.get(),
value);
} else {
return nullptr;
}
-LBPLType Interpreter::visitTernaryExpr(TernaryExpr *expr) {
+Value Interpreter::visitTernaryExpr(TernaryExpr *expr) {
if (isTruthy(expr->condition->accept(this))) {
return expr->trueBranch->accept(this);
}
return expr->falseBranch->accept(this);
}
-LBPLType Interpreter::visitVarExpr(VariableExpr *expr) {
+Value Interpreter::visitVarExpr(VariableExpr *expr) {
return lookupVariable(expr->variable, expr);
}
-LBPLType Interpreter::visitAssignExpr(AssignExpr *expr) {
- LBPLType value = expr->value->accept(this);
+Value Interpreter::visitAssignExpr(AssignExpr *expr) {
+ Value value = expr->value->accept(this);
auto it = locals.find(expr);
if (it == locals.end()) {
void Interpreter::execute(std::unique_ptr<Stmt> &stmt) { stmt->accept(this); }
-LBPLType Interpreter::evaluate(std::unique_ptr<Expr> &expr) {
+Value Interpreter::evaluate(std::unique_ptr<Expr> &expr) {
return expr->accept(this);
}
-LBPLType Interpreter::performBinaryOperation(std::shared_ptr<const Token> &op,
- const LBPLType &left,
- const LBPLType &right) {
+Value Interpreter::performBinaryOperation(std::shared_ptr<const Token> &op,
+ const Value &left,
+ const Value &right) {
auto performIntOp = [](int l, int r,
- std::shared_ptr<const Token> &op) -> LBPLType {
+ std::shared_ptr<const Token> &op) -> Value {
switch (op->type) {
case TokenType::Plus:
return l + r;
};
auto performDoubleOp = [](double l, double r,
- std::shared_ptr<const Token> &op) -> LBPLType {
+ std::shared_ptr<const Token> &op) -> Value {
switch (op->type) {
case TokenType::Plus:
return l + r;
};
auto performStringOp = [](const std::string &l, const std::string &r,
- std::shared_ptr<const Token> &op) -> LBPLType {
+ std::shared_ptr<const Token> &op) -> Value {
if (op->type == TokenType::Plus) {
return l + r;
} else {
};
return std::visit(
- [&](const auto &l, const auto &r) -> LBPLType {
+ [&](const auto &l, const auto &r) -> Value {
using L = std::decay_t<decltype(l)>;
using R = std::decay_t<decltype(r)>;
currentEnv = prev;
}
-bool Interpreter::isTruthy(const LBPLType &value) {
+bool Interpreter::isTruthy(const Value &value) {
if (std::holds_alternative<std::nullptr_t>(value)) {
return std::get<std::nullptr_t>(value) != nullptr;
} else if (std::holds_alternative<bool>(value)) {
return false;
}
-bool Interpreter::isTruthy(LBPLType &&value) { return isTruthy(value); }
+bool Interpreter::isTruthy(Value &&value) { return isTruthy(value); }
-LBPLType Interpreter::lookupVariable(std::shared_ptr<const Token> &name,
+Value Interpreter::lookupVariable(std::shared_ptr<const Token> &name,
Expr *expr) {
auto it = locals.find(expr);
}
}
-LBPLType Resolver::visitBinaryExpr(BinaryExpr *expr) {
+Value Resolver::visitBinaryExpr(BinaryExpr *expr) {
expr->left->accept(this);
expr->right->accept(this);
return nullptr;
}
-LBPLType Resolver::visitBreakExpr(BreakExpr *expr) {
+Value Resolver::visitBreakExpr(BreakExpr *expr) {
if (loops <= 0) {
throw SyntaxError(expr, "Can't break from outside of a loop.");
}
return nullptr;
}
-LBPLType Resolver::visitContinueExpr(ContinueExpr *expr) {
+Value Resolver::visitContinueExpr(ContinueExpr *expr) {
if (loops <= 0) {
throw SyntaxError(expr, "Can't break from outside of a loop.");
}
return nullptr;
}
-LBPLType Resolver::visitUnaryExpr(UnaryExpr *expr) {
+Value Resolver::visitUnaryExpr(UnaryExpr *expr) {
expr->right->accept(this);
return nullptr;
}
-LBPLType Resolver::visitLiteralExpr(LiteralExpr *) { return nullptr; }
+Value Resolver::visitLiteralExpr(LiteralExpr *) { return nullptr; }
-LBPLType Resolver::visitGroupExpr(GroupingExpr *expr) {
+Value Resolver::visitGroupExpr(GroupingExpr *expr) {
expr->expr->accept(this);
return nullptr;
}
-LBPLType Resolver::visitSuperExpr(SuperExpr *expr) {
+Value Resolver::visitSuperExpr(SuperExpr *expr) {
if (currentClass == ClassType::None) {
throw SyntaxError(expr, "Can't access 'super' from outside of class body.");
} else if (currentClass != ClassType::Subclass) {
return nullptr;
}
-LBPLType Resolver::visitThisExpr(ThisExpr *expr) {
+Value Resolver::visitThisExpr(ThisExpr *expr) {
resolveLocal(expr, "this");
return nullptr;
}
-LBPLType Resolver::visitCallExpr(FnCallExpr *expr) {
+Value Resolver::visitCallExpr(FnCallExpr *expr) {
expr->callee->accept(this);
for (auto &&arg : expr->args) {
return nullptr;
}
-LBPLType Resolver::visitGetFieldExpr(GetFieldExpr *expr) {
+Value Resolver::visitGetFieldExpr(GetFieldExpr *expr) {
expr->instance->accept(this);
return nullptr;
}
-LBPLType Resolver::visitSetFieldExpr(SetFieldExpr *expr) {
+Value Resolver::visitSetFieldExpr(SetFieldExpr *expr) {
expr->value->accept(this);
expr->instance->accept(this);
return nullptr;
}
-LBPLType Resolver::visitTernaryExpr(TernaryExpr *expr) {
+Value Resolver::visitTernaryExpr(TernaryExpr *expr) {
expr->condition->accept(this);
expr->trueBranch->accept(this);
expr->falseBranch->accept(this);
return nullptr;
}
-LBPLType Resolver::visitVarExpr(VariableExpr *expr) {
+Value Resolver::visitVarExpr(VariableExpr *expr) {
if (!scopes.empty() && scopes.back().contains(expr->variable->lexeme) &&
scopes.back().find(expr->variable->lexeme)->second != VarState::Ready) {
throw SyntaxError(expr, "You are trying to read the value of a variable "
return nullptr;
}
-LBPLType Resolver::visitAssignExpr(AssignExpr *expr) {
+Value Resolver::visitAssignExpr(AssignExpr *expr) {
expr->value->accept(this);
resolveLocal(expr, expr->variable.get());
return nullptr;