Skip to content

Commit

Permalink
update(function): fix recursion and repl state
Browse files Browse the repository at this point in the history
  • Loading branch information
Rohith-Raju committed May 15, 2024
1 parent e3965db commit 353300d
Show file tree
Hide file tree
Showing 13 changed files with 148 additions and 38 deletions.
12 changes: 9 additions & 3 deletions include/Interpreter.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

class Interpreter {
private:
static Environment *environment;
Environment *environment;

void excecute(Statement *stmnt);

Expand All @@ -31,13 +31,17 @@ class Interpreter {
bool checkCompatibility(Token *op, Object left, Object right);

public:
static Environment *globals;
Environment *globals;

Interpreter();

bool isBreakUsed = false;

void excecuteBlock(std::vector<Statement *> stmnts, Environment *env);
bool isReturnUsed = false;

Object returnObj;

Object excecuteBlock(std::vector<Statement *> stmnts, Environment *env);

void interpret(std::vector<Statement *> &statements);

Expand All @@ -55,6 +59,8 @@ class Interpreter {

void visitFuncStmnt(Function *stmnt);

void visitReturnStmnt(Return *stmnt);

Object visitAssignment(Assignment *expr);

Object visitLogicalExp(Logical *expr);
Expand Down
3 changes: 2 additions & 1 deletion include/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,14 @@ class Parser {
Statement *breakStatement();
Statement *expressionStatement();
Statement *function(std::string str);
Statement *returnStatement();
std::vector<Statement *> blockStatement();

// Variable stuff
Statement *declaration();
Statement *varDeclaration();

// helper functions
// Helper functions
Expr *equality();
bool check(TokenType type);
Token advance();
Expand Down
6 changes: 6 additions & 0 deletions include/Return.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#include "utls/Object.h"

struct ReturnValue {
Object value;
ReturnValue(Object value) : value(value){};
};
10 changes: 9 additions & 1 deletion include/Statement.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ enum Statement_type {
StmntIf_type,
StmntWhile_type,
StmntBreak_type,
StmntFunc_type
StmntFunc_type,
StmntReturn_type
};

class Statement {
Expand Down Expand Up @@ -88,4 +89,11 @@ class Function : public Statement {
std::vector<Statement *> body);
};

class Return : public Statement {
public:
Token *keyword;
Expr *value;
Return(Token *keyword, Expr *value);
};

#endif
2 changes: 1 addition & 1 deletion include/env/Env.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class Environment {

public:
Environment();
~Environment();
//~Environment();
Environment(Environment *enclosing);
void define(Token *tkn, Object value);
void define(std::string name, Object value);
Expand Down
47 changes: 43 additions & 4 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,42 @@
#include "Interpreter.h"
#include "Scanner.h"
#include <Parser.h>
#include <cstdlib>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <memory>
#include <ostream>
#include <sstream>
#include <string>
#include <vector>

namespace fs = std::filesystem;

void runCode(std::string source);

std::string readFile(fs::path path) {
if (path.extension() != ".crux") {
std::cerr << "Filename " << path.filename()
<< " should end with the extension \".crux\" \n";
exit(64);
}

std::ostringstream data;
std::fstream file(path, std::ios_base::in);
if (!file.is_open()) {
std::cerr << "File could't be found or opened \n";
exit(64);
}
data << file.rdbuf();
return data.str();
}

void runFile(std::string path) {
fs::path fPath(path);
runCode(readFile(fPath));
}

void runPromt() {
for (;;) {
std::cout << "> ";
Expand All @@ -25,16 +55,25 @@ void runPromt() {
}
}

Interpreter interpreter{};

void runCode(std::string source) {
Scanner scanner(source);
std::vector<Token> tokens = scanner.scanTokens();
Parser parser(tokens);
std::vector<Statement *> expression = parser.parse();
std::unique_ptr<Interpreter> interpreter = std::make_unique<Interpreter>();
interpreter->interpret(expression);
interpreter.interpret(expression);
}

int main() {
runPromt();
int main(int argc, char *argv[]) {
if (argc > 2) {
std::cout << "usage: crux <script>\n";
std::cout << "using repl: ./crux\n";
exit(64);
} else if (argc == 2) {
runFile(argv[1]);
} else {
runPromt();
}
return 0;
}
4 changes: 2 additions & 2 deletions src/Function.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ Object CruxFunction::call(Interpreter *interpreter, std::vector<Object> args) {
for (int i = 0; i < declaration->params.size(); i++) {
env->define(declaration->params[i], args[i]);
}
interpreter->excecuteBlock(declaration->body, env);
return Object();
Object value = interpreter->excecuteBlock(declaration->body, env);
return value;
}

std::string CruxFunction::str() {
Expand Down
29 changes: 21 additions & 8 deletions src/Interpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@
#include <string>
#include <vector>

Environment *Interpreter::environment;
Environment *Interpreter::globals;

Interpreter::Interpreter() {
if (!environment) {
globals = new Environment();
Expand Down Expand Up @@ -51,8 +48,12 @@ void Interpreter::excecute(Statement *stmnt) {
case StmntFunc_type:
visitFuncStmnt((Function *)stmnt);
break;
case StmntReturn_type:
visitReturnStmnt((Return *)stmnt);
break;
case StmntBreak_type:
isBreakUsed = true;
break;
}
}

Expand Down Expand Up @@ -102,7 +103,7 @@ void Interpreter::checkNumberOperand(Token *op, Object right) {
}

bool Interpreter::checkIfSameTypes(Object left, Object right) {
if (left.type == num_type && right.type == num_type)
if (left.type == right.type)
return true;
else
return false;
Expand Down Expand Up @@ -168,22 +169,33 @@ void Interpreter::visitFuncStmnt(Function *stmnt) {
environment->define(stmnt->name, declaration);
}

void Interpreter::visitReturnStmnt(Return *stmnt) {
returnObj = evaluate(stmnt->value);
isReturnUsed = true;
}

void Interpreter::visitBlockStmnt(Block *stmnt) {
Environment *locals = new Environment(environment);
excecuteBlock(stmnt->stmnt, locals);
delete locals;
}

void Interpreter::excecuteBlock(std::vector<Statement *> stmnts,
Environment *env) {
Object Interpreter::excecuteBlock(std::vector<Statement *> stmnts,
Environment *env) {
Environment *previous = environment;
environment = env;
for (Statement *stmnt : stmnts) {
excecute(stmnt);
if (crux::hadRuntimeError)
if (isBreakUsed || isReturnUsed || crux::hadRuntimeError)
break;
}
environment = previous;

if (isReturnUsed) {
isReturnUsed = false;
return this->returnObj;
}

return Object();
}

Object Interpreter::visitVariableExp(Variable *expr) {
Expand All @@ -203,6 +215,7 @@ Object Interpreter::visitLogicalExp(Logical *expr) {

Object Interpreter::visitAssignment(Assignment *expr) {
Object value = evaluate(expr->value);

environment->assign(expr->name, value);
return value;
}
Expand Down
12 changes: 12 additions & 0 deletions src/Parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ Statement *Parser::statement() {
return forStatement();
if (match(BREAK))
return breakStatement();
if (match(RETURN))
return returnStatement();
if (match(LEFT_BRACE))
return new Block(blockStatement());
return expressionStatement();
Expand Down Expand Up @@ -322,6 +324,16 @@ Statement *Parser::function(std::string kind) {
return new Function(name, params, body);
}

Statement *Parser::returnStatement() {
Token *name = new Token(previous());
Expr *value = nullptr;
if (!check(SEMICOLON)) {
value = expression();
}
consume(SEMICOLON, "expected ; at the end of the statement");
return new Return(name, value);
}

Expr *Parser::primary() {
if (match(FALSE))
return new Literal(new Object(false));
Expand Down
3 changes: 3 additions & 0 deletions src/Statement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,6 @@ Break::Break(bool isBrkPre)
Function::Function(Token *name, std::vector<Token *> params,
std::vector<Statement *> body)
: Statement(StmntFunc_type), name(name), params(params), body(body) {}

Return::Return(Token *keyword, Expr *value)
: Statement(StmntReturn_type), keyword(keyword), value(value) {}
20 changes: 9 additions & 11 deletions src/env/Env.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,18 @@

Environment::Environment() : enclosing(nullptr) {}

Environment::~Environment() {
if (enclosing != nullptr) {
deepClean(enclosing);
}
values.clear();
enclosing = nullptr;
}
// Environment::~Environment() {
// if (enclosing != nullptr) {
// deepClean(enclosing);
// }
// enclosing = nullptr;
// }

void Environment::deepClean(Environment *enclosing) {
if (enclosing != nullptr)
deepClean(enclosing);

enclosing->values.clear();
delete enclosing;
enclosing = nullptr;
return;
}
Expand All @@ -34,7 +32,7 @@ void Environment::define(Token *tkn, Object value) {
}

void Environment::define(std::string name, Object value) {
values.emplace(name, value);
values.insert({name, value});
}

void Environment::assign(Token *name, Object value) {
Expand All @@ -55,8 +53,8 @@ Object Environment::get(Token *name) {
if (values.find(name->lexeme) != values.end()) {
Object obj = values[name->lexeme];
if (obj.type == nullptr_type)
throw RuntimeError(*name, "Uninitalized variable " + name->lexeme +
" can't be computed");
throw RuntimeError(*name, "Uninitalized variable :" + name->lexeme +
" nil values can't be computed");
return obj;
}

Expand Down
Loading

0 comments on commit 353300d

Please sign in to comment.