From fe26a7c2e0b2f0acead5c105468a376ebf9dcc65 Mon Sep 17 00:00:00 2001 From: Bobby Lucero Date: Wed, 31 May 2023 02:44:39 -0400 Subject: [PATCH] Added scopes --- headers/Environment.h | 12 ++++++++++++ headers/Interpreter.h | 11 ++++++++++- headers/Lexer.h | 1 - headers/Parser.h | 2 ++ headers/Statement.h | 14 ++++++++++++++ headers/TypeWrapper.h | 3 +-- source.bob | 6 +++++- source/Environment.cpp | 11 +++++++++++ source/Interpreter.cpp | 33 +++++++++++++++++++++++++++++---- source/Parser.cpp | 14 ++++++++++++++ source/main.cpp | 4 ++-- 11 files changed, 100 insertions(+), 11 deletions(-) diff --git a/headers/Environment.h b/headers/Environment.h index 1a98106..65d34b2 100644 --- a/headers/Environment.h +++ b/headers/Environment.h @@ -15,7 +15,19 @@ public: std::shared_ptr get(Token name); + sptr(Environment) enclosing; + + Environment(){ + enclosing = nullptr; + } + + Environment(sptr(Environment) environment) : enclosing(environment) + { + + } private: std::unordered_map variables; + + }; \ No newline at end of file diff --git a/headers/Interpreter.h b/headers/Interpreter.h index 8e26dde..5e7def7 100644 --- a/headers/Interpreter.h +++ b/headers/Interpreter.h @@ -16,15 +16,22 @@ public: sptr(Object) visitVariableExpr(sptr(VarExpr) expression) override; sptr(Object) visitAssignExpr(sptr(AssignExpr) expression) override; + void visitBlockStmt(sptr(BlockStmt) statement) override; void visitExpressionStmt(sptr(ExpressionStmt) statement) override; void visitPrintStmt(sptr(PrintStmt) statement) override; void visitVarStmt(sptr(VarStmt) statement) override; void interpret(std::vector statements); + Interpreter(){ + environment = msptr(Environment)(); + } + private: - Environment environment; + sptr(Environment) environment; + + sptr(Object) evaluate(sptr(Expr) expr); bool isTruthy(sptr(Object) object); @@ -35,4 +42,6 @@ private: bool isWholeNumer(double num); void execute(std::shared_ptr statement); + + void executeBlock(std::vector> statements, std::shared_ptr env); }; diff --git a/headers/Lexer.h b/headers/Lexer.h index 83b08be..134125f 100644 --- a/headers/Lexer.h +++ b/headers/Lexer.h @@ -63,7 +63,6 @@ struct Token { TokenType type; std::string lexeme; - //TODO Object literal; int line; }; diff --git a/headers/Parser.h b/headers/Parser.h index d230919..92ad4cc 100644 --- a/headers/Parser.h +++ b/headers/Parser.h @@ -47,4 +47,6 @@ private: std::shared_ptr varDeclaration(); std::shared_ptr assignment(); + + std::vector> block(); }; \ No newline at end of file diff --git a/headers/Statement.h b/headers/Statement.h index e2ea73c..c4b8a2e 100644 --- a/headers/Statement.h +++ b/headers/Statement.h @@ -8,9 +8,11 @@ struct ExpressionStmt; struct PrintStmt; struct VarStmt; +struct BlockStmt; struct StmtVisitor { + virtual void visitBlockStmt(sptr(BlockStmt) stmt) = 0; virtual void visitExpressionStmt(sptr(ExpressionStmt) stmt) = 0; virtual void visitPrintStmt(sptr(PrintStmt) stmt) = 0; virtual void visitVarStmt(sptr(VarStmt) stmt) = 0; @@ -23,6 +25,18 @@ struct Stmt virtual ~Stmt(){}; }; +struct BlockStmt : Stmt, public std::enable_shared_from_this +{ + const std::vector statements; + explicit BlockStmt(std::vector statements) : statements(statements) + { + } + void accept(StmtVisitor* visitor) override + { + visitor->visitBlockStmt(shared_from_this()); + } +}; + struct ExpressionStmt : Stmt, public std::enable_shared_from_this { const sptr(Expr) expression; diff --git a/headers/TypeWrapper.h b/headers/TypeWrapper.h index 00dae47..1a95f54 100644 --- a/headers/TypeWrapper.h +++ b/headers/TypeWrapper.h @@ -17,8 +17,7 @@ struct String : Object std::string value; explicit String(std::string str) : value(str) {} ~String(){ - std::cout << value.size() << std::endl; - std::cout << "String being destroyed..." << std::endl; + } }; diff --git a/source.bob b/source.bob index 07e3668..2d27c7d 100644 --- a/source.bob +++ b/source.bob @@ -1 +1,5 @@ -10 10; \ No newline at end of file +var a = 1; +{ + var a = a + 2; + print a; +} \ No newline at end of file diff --git a/source/Environment.cpp b/source/Environment.cpp index 5bed3ed..44c75c6 100644 --- a/source/Environment.cpp +++ b/source/Environment.cpp @@ -13,6 +13,11 @@ sptr(Object) Environment::get(Token name) return variables[name.lexeme]; } + if(enclosing != nullptr) + { + return enclosing->get(name); + } + throw std::runtime_error("Undefined variable '" + name.lexeme + "'."); } @@ -30,5 +35,11 @@ void Environment::assign(Token name, std::shared_ptr value) { return; } + if(enclosing != nullptr) + { + enclosing->assign(name, value); + return; + } + throw std::runtime_error("Undefined variable '" + name.lexeme + "'."); } diff --git a/source/Interpreter.cpp b/source/Interpreter.cpp index 287a55c..ec5aef8 100644 --- a/source/Interpreter.cpp +++ b/source/Interpreter.cpp @@ -148,15 +148,19 @@ sptr(Object) Interpreter::visitBinaryExpr(sptr(BinaryExpr) 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) value = evaluate(expression->value); - environment.assign(expression->name, value); + environment->assign(expression->name, value); return value; } +void Interpreter::visitBlockStmt(std::shared_ptr statement) { + executeBlock(statement->statements, msptr(Environment)(environment)); +} + void Interpreter::visitExpressionStmt(sptr(ExpressionStmt) statement) { 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; - environment.define(statement->name.lexeme, value); + environment->define(statement->name.lexeme, value); } void Interpreter::interpret(std::vector statements) { @@ -193,7 +197,28 @@ void Interpreter::interpret(std::vector statements) { void Interpreter::execute(sptr(Stmt) statement) { - statement->accept(this); + try { + statement->accept(this); + } + catch(std::exception &e) + { + std::cout << "ERROR OCCURRED: " << e.what() << std::endl; + return; + } +} + +void Interpreter::executeBlock(std::vector 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) { diff --git a/source/Parser.cpp b/source/Parser.cpp index 0b36482..7b68d49 100644 --- a/source/Parser.cpp +++ b/source/Parser.cpp @@ -147,6 +147,7 @@ std::vector Parser::parse() { sptr(Stmt) Parser::statement() { if(match({PRINT})) return printStatement(); + if(match({OPEN_BRACE})) return msptr(BlockStmt)(block()); return expressionStatement(); } @@ -164,6 +165,19 @@ sptr(Stmt) Parser::expressionStatement() return msptr(ExpressionStmt)(expr); } +std::vector Parser::block() +{ + std::vector statements; + + while(!check(CLOSE_BRACE) && !isAtEnd()) + { + statements.push_back(declaration()); + } + + consume(CLOSE_BRACE, "Expected '}' after block."); + return statements; +} + sptr(Stmt) Parser::declaration() { try{ diff --git a/source/main.cpp b/source/main.cpp index 0778e7f..3c74612 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -8,8 +8,8 @@ int main(){ Bob bobLang; - //bobLang.runFile("source.bob"); - bobLang.runPrompt(); + bobLang.runFile("source.bob"); + //bobLang.runPrompt(); return 0; }