Added scopes
This commit is contained in:
parent
7e0cead697
commit
fe26a7c2e0
@ -15,7 +15,19 @@ public:
|
|||||||
|
|
||||||
std::shared_ptr<Object> get(Token name);
|
std::shared_ptr<Object> get(Token name);
|
||||||
|
|
||||||
|
sptr(Environment) enclosing;
|
||||||
|
|
||||||
|
Environment(){
|
||||||
|
enclosing = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
Environment(sptr(Environment) environment) : enclosing(environment)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
std::unordered_map<std::string, sptr(Object)> variables;
|
std::unordered_map<std::string, sptr(Object)> variables;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -16,15 +16,22 @@ public:
|
|||||||
sptr(Object) visitVariableExpr(sptr(VarExpr) expression) override;
|
sptr(Object) visitVariableExpr(sptr(VarExpr) expression) override;
|
||||||
sptr(Object) visitAssignExpr(sptr(AssignExpr) expression) override;
|
sptr(Object) visitAssignExpr(sptr(AssignExpr) expression) override;
|
||||||
|
|
||||||
|
void visitBlockStmt(sptr(BlockStmt) statement) override;
|
||||||
void visitExpressionStmt(sptr(ExpressionStmt) statement) override;
|
void visitExpressionStmt(sptr(ExpressionStmt) statement) override;
|
||||||
void visitPrintStmt(sptr(PrintStmt) statement) override;
|
void visitPrintStmt(sptr(PrintStmt) statement) override;
|
||||||
void visitVarStmt(sptr(VarStmt) statement) override;
|
void visitVarStmt(sptr(VarStmt) statement) override;
|
||||||
|
|
||||||
void interpret(std::vector<sptr(Stmt)> statements);
|
void interpret(std::vector<sptr(Stmt)> statements);
|
||||||
|
|
||||||
|
Interpreter(){
|
||||||
|
environment = msptr(Environment)();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Environment environment;
|
sptr(Environment) environment;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
sptr(Object) evaluate(sptr(Expr) expr);
|
sptr(Object) evaluate(sptr(Expr) expr);
|
||||||
bool isTruthy(sptr(Object) object);
|
bool isTruthy(sptr(Object) object);
|
||||||
@ -35,4 +42,6 @@ private:
|
|||||||
bool isWholeNumer(double num);
|
bool isWholeNumer(double num);
|
||||||
|
|
||||||
void execute(std::shared_ptr<Stmt> statement);
|
void execute(std::shared_ptr<Stmt> statement);
|
||||||
|
|
||||||
|
void executeBlock(std::vector<std::shared_ptr<Stmt>> statements, std::shared_ptr<Environment> env);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -63,7 +63,6 @@ struct Token
|
|||||||
{
|
{
|
||||||
TokenType type;
|
TokenType type;
|
||||||
std::string lexeme;
|
std::string lexeme;
|
||||||
//TODO Object literal;
|
|
||||||
int line;
|
int line;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -47,4 +47,6 @@ private:
|
|||||||
std::shared_ptr<Stmt> varDeclaration();
|
std::shared_ptr<Stmt> varDeclaration();
|
||||||
|
|
||||||
std::shared_ptr<Expr> assignment();
|
std::shared_ptr<Expr> assignment();
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<Stmt>> block();
|
||||||
};
|
};
|
||||||
@ -8,9 +8,11 @@
|
|||||||
struct ExpressionStmt;
|
struct ExpressionStmt;
|
||||||
struct PrintStmt;
|
struct PrintStmt;
|
||||||
struct VarStmt;
|
struct VarStmt;
|
||||||
|
struct BlockStmt;
|
||||||
|
|
||||||
struct StmtVisitor
|
struct StmtVisitor
|
||||||
{
|
{
|
||||||
|
virtual void visitBlockStmt(sptr(BlockStmt) stmt) = 0;
|
||||||
virtual void visitExpressionStmt(sptr(ExpressionStmt) stmt) = 0;
|
virtual void visitExpressionStmt(sptr(ExpressionStmt) stmt) = 0;
|
||||||
virtual void visitPrintStmt(sptr(PrintStmt) stmt) = 0;
|
virtual void visitPrintStmt(sptr(PrintStmt) stmt) = 0;
|
||||||
virtual void visitVarStmt(sptr(VarStmt) stmt) = 0;
|
virtual void visitVarStmt(sptr(VarStmt) stmt) = 0;
|
||||||
@ -23,6 +25,18 @@ struct Stmt
|
|||||||
virtual ~Stmt(){};
|
virtual ~Stmt(){};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct BlockStmt : Stmt, public std::enable_shared_from_this<BlockStmt>
|
||||||
|
{
|
||||||
|
const std::vector<sptr(Stmt)> statements;
|
||||||
|
explicit BlockStmt(std::vector<sptr(Stmt)> statements) : statements(statements)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
void accept(StmtVisitor* visitor) override
|
||||||
|
{
|
||||||
|
visitor->visitBlockStmt(shared_from_this());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct ExpressionStmt : Stmt, public std::enable_shared_from_this<ExpressionStmt>
|
struct ExpressionStmt : Stmt, public std::enable_shared_from_this<ExpressionStmt>
|
||||||
{
|
{
|
||||||
const sptr(Expr) expression;
|
const sptr(Expr) expression;
|
||||||
|
|||||||
@ -17,8 +17,7 @@ struct String : Object
|
|||||||
std::string value;
|
std::string value;
|
||||||
explicit String(std::string str) : value(str) {}
|
explicit String(std::string str) : value(str) {}
|
||||||
~String(){
|
~String(){
|
||||||
std::cout << value.size() << std::endl;
|
|
||||||
std::cout << "String being destroyed..." << std::endl;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1 +1,5 @@
|
|||||||
10 10;
|
var a = 1;
|
||||||
|
{
|
||||||
|
var a = a + 2;
|
||||||
|
print a;
|
||||||
|
}
|
||||||
@ -13,6 +13,11 @@ sptr(Object) Environment::get(Token name)
|
|||||||
return variables[name.lexeme];
|
return variables[name.lexeme];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(enclosing != nullptr)
|
||||||
|
{
|
||||||
|
return enclosing->get(name);
|
||||||
|
}
|
||||||
|
|
||||||
throw std::runtime_error("Undefined variable '" + name.lexeme + "'.");
|
throw std::runtime_error("Undefined variable '" + name.lexeme + "'.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,5 +35,11 @@ void Environment::assign(Token name, std::shared_ptr<Object> value) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(enclosing != nullptr)
|
||||||
|
{
|
||||||
|
enclosing->assign(name, value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
throw std::runtime_error("Undefined variable '" + name.lexeme + "'.");
|
throw std::runtime_error("Undefined variable '" + name.lexeme + "'.");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -148,15 +148,19 @@ sptr(Object) Interpreter::visitBinaryExpr(sptr(BinaryExpr) expression)
|
|||||||
|
|
||||||
sptr(Object) Interpreter::visitVariableExpr(sptr(VarExpr) expression)
|
sptr(Object) Interpreter::visitVariableExpr(sptr(VarExpr) expression)
|
||||||
{
|
{
|
||||||
return environment.get(expression->name);
|
return environment->get(expression->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
sptr(Object) Interpreter::visitAssignExpr(sptr(AssignExpr) expression) {
|
sptr(Object) Interpreter::visitAssignExpr(sptr(AssignExpr) expression) {
|
||||||
sptr(Object) value = evaluate(expression->value);
|
sptr(Object) value = evaluate(expression->value);
|
||||||
environment.assign(expression->name, value);
|
environment->assign(expression->name, value);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Interpreter::visitBlockStmt(std::shared_ptr<BlockStmt> statement) {
|
||||||
|
executeBlock(statement->statements, msptr(Environment)(environment));
|
||||||
|
}
|
||||||
|
|
||||||
void Interpreter::visitExpressionStmt(sptr(ExpressionStmt) statement) {
|
void Interpreter::visitExpressionStmt(sptr(ExpressionStmt) statement) {
|
||||||
evaluate(statement->expression);
|
evaluate(statement->expression);
|
||||||
}
|
}
|
||||||
@ -176,7 +180,7 @@ void Interpreter::visitVarStmt(sptr(VarStmt) statement)
|
|||||||
|
|
||||||
//std::cout << "Visit var stmt: " << statement->name.lexeme << " set to: " << stringify(value) << std::endl;
|
//std::cout << "Visit var stmt: " << statement->name.lexeme << " set to: " << stringify(value) << std::endl;
|
||||||
|
|
||||||
environment.define(statement->name.lexeme, value);
|
environment->define(statement->name.lexeme, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::interpret(std::vector<sptr(Stmt)> statements) {
|
void Interpreter::interpret(std::vector<sptr(Stmt)> statements) {
|
||||||
@ -193,8 +197,29 @@ void Interpreter::interpret(std::vector<sptr(Stmt)> statements) {
|
|||||||
|
|
||||||
void Interpreter::execute(sptr(Stmt) statement)
|
void Interpreter::execute(sptr(Stmt) statement)
|
||||||
{
|
{
|
||||||
|
try {
|
||||||
statement->accept(this);
|
statement->accept(this);
|
||||||
}
|
}
|
||||||
|
catch(std::exception &e)
|
||||||
|
{
|
||||||
|
std::cout << "ERROR OCCURRED: " << e.what() << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Interpreter::executeBlock(std::vector<sptr(Stmt)> statements, sptr(Environment) env)
|
||||||
|
{
|
||||||
|
sptr(Environment) previous = this->environment;
|
||||||
|
this->environment = env;
|
||||||
|
|
||||||
|
for(sptr(Stmt) s : statements)
|
||||||
|
{
|
||||||
|
execute(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
this->environment = previous;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
sptr(Object) Interpreter::evaluate(sptr(Expr) expr) {
|
sptr(Object) Interpreter::evaluate(sptr(Expr) expr) {
|
||||||
return expr->accept(this);
|
return expr->accept(this);
|
||||||
|
|||||||
@ -147,6 +147,7 @@ std::vector<sptr(Stmt)> Parser::parse() {
|
|||||||
sptr(Stmt) Parser::statement()
|
sptr(Stmt) Parser::statement()
|
||||||
{
|
{
|
||||||
if(match({PRINT})) return printStatement();
|
if(match({PRINT})) return printStatement();
|
||||||
|
if(match({OPEN_BRACE})) return msptr(BlockStmt)(block());
|
||||||
return expressionStatement();
|
return expressionStatement();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,6 +165,19 @@ sptr(Stmt) Parser::expressionStatement()
|
|||||||
return msptr(ExpressionStmt)(expr);
|
return msptr(ExpressionStmt)(expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<sptr(Stmt)> Parser::block()
|
||||||
|
{
|
||||||
|
std::vector<sptr(Stmt)> statements;
|
||||||
|
|
||||||
|
while(!check(CLOSE_BRACE) && !isAtEnd())
|
||||||
|
{
|
||||||
|
statements.push_back(declaration());
|
||||||
|
}
|
||||||
|
|
||||||
|
consume(CLOSE_BRACE, "Expected '}' after block.");
|
||||||
|
return statements;
|
||||||
|
}
|
||||||
|
|
||||||
sptr(Stmt) Parser::declaration()
|
sptr(Stmt) Parser::declaration()
|
||||||
{
|
{
|
||||||
try{
|
try{
|
||||||
|
|||||||
@ -8,8 +8,8 @@
|
|||||||
int main(){
|
int main(){
|
||||||
Bob bobLang;
|
Bob bobLang;
|
||||||
|
|
||||||
//bobLang.runFile("source.bob");
|
bobLang.runFile("source.bob");
|
||||||
bobLang.runPrompt();
|
//bobLang.runPrompt();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user