Added scopes
This commit is contained in:
parent
7e0cead697
commit
fe26a7c2e0
@ -15,7 +15,19 @@ public:
|
||||
|
||||
std::shared_ptr<Object> get(Token name);
|
||||
|
||||
sptr(Environment) enclosing;
|
||||
|
||||
Environment(){
|
||||
enclosing = nullptr;
|
||||
}
|
||||
|
||||
Environment(sptr(Environment) environment) : enclosing(environment)
|
||||
{
|
||||
|
||||
}
|
||||
private:
|
||||
std::unordered_map<std::string, sptr(Object)> variables;
|
||||
|
||||
|
||||
|
||||
};
|
||||
@ -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<sptr(Stmt)> 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<Stmt> statement);
|
||||
|
||||
void executeBlock(std::vector<std::shared_ptr<Stmt>> statements, std::shared_ptr<Environment> env);
|
||||
};
|
||||
|
||||
@ -63,7 +63,6 @@ struct Token
|
||||
{
|
||||
TokenType type;
|
||||
std::string lexeme;
|
||||
//TODO Object literal;
|
||||
int line;
|
||||
};
|
||||
|
||||
|
||||
@ -47,4 +47,6 @@ private:
|
||||
std::shared_ptr<Stmt> varDeclaration();
|
||||
|
||||
std::shared_ptr<Expr> assignment();
|
||||
|
||||
std::vector<std::shared_ptr<Stmt>> block();
|
||||
};
|
||||
@ -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<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>
|
||||
{
|
||||
const sptr(Expr) expression;
|
||||
|
||||
@ -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;
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -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];
|
||||
}
|
||||
|
||||
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<Object> value) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(enclosing != nullptr)
|
||||
{
|
||||
enclosing->assign(name, value);
|
||||
return;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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<BlockStmt> 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<sptr(Stmt)> statements) {
|
||||
@ -193,8 +197,29 @@ void Interpreter::interpret(std::vector<sptr(Stmt)> statements) {
|
||||
|
||||
void Interpreter::execute(sptr(Stmt) statement)
|
||||
{
|
||||
try {
|
||||
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) {
|
||||
return expr->accept(this);
|
||||
|
||||
@ -147,6 +147,7 @@ std::vector<sptr(Stmt)> 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<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()
|
||||
{
|
||||
try{
|
||||
|
||||
@ -8,8 +8,8 @@
|
||||
int main(){
|
||||
Bob bobLang;
|
||||
|
||||
//bobLang.runFile("source.bob");
|
||||
bobLang.runPrompt();
|
||||
bobLang.runFile("source.bob");
|
||||
//bobLang.runPrompt();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user