Skip to content

Commit

Permalink
update(statements): made statements compatible with tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Rohith-Raju committed Mar 25, 2024
1 parent d55bf78 commit 6d906ca
Show file tree
Hide file tree
Showing 10 changed files with 264 additions and 212 deletions.
5 changes: 5 additions & 0 deletions include/Expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,9 @@ class Literal : public Expr {
~Literal();
};

class Variable : public Expr {
public:
Token *name;
};

#endif
190 changes: 29 additions & 161 deletions include/Interpreter.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,175 +5,43 @@
#ifndef CRUX_INTERPRETER_H
#define CRUX_INTERPRETER_H

#include "Error.h"
#include "Expr.h"
#include "Statement.h"
#include "Token.h"
#include "utls/Object.h"
#include "utls/RuntimeError.h"
#include <iostream>
#include <string>
#include <vector>
class Interpreter {
private:
void excecute(Statement *stmnt) {
switch (stmnt->type) {
case StmntPrint_type:
return visitPrintStmnt((Print *)stmnt);
case StmntExpr_type:
return visitExprStmnt((Expression *)stmnt);
}
}

Object evaluate(Expr *expr) {
switch (expr->type) {
case ExprType_Binary:
return visitBinaryExp((Binary *)expr);
case ExprType_Unary:
return visitUnaryExp((Unary *)expr);
case ExprType_Literal:
return visitLiteral((Literal *)expr);
case ExprType_Grouping:
return visitGroupExp((Grouping *)expr);
case ExprType_Ternary:
return visitTernaryExp((Ternary *)expr);
}
return Object();
}

bool isTruthy(Object right) {
if (right.type == nullptr_type)
return false;
if (right.type == bool_type)
return right.bool_literal;
return true;
}

bool isEqual(Object left, Object right) {
if (left.type == nullptr_type && right.type == nullptr_type)
return true;
if (left.type == nullptr_type)
return false;

return left.num_literal == right.num_literal;
}

void checkNumberOperand(Token *op, Object right) {
if (right.type == num_type)
return;
RuntimeError(*op, "Operand must be a number");
}
bool checkIfSameTypes(Object left, Object right) {
if (left.type == num_type && right.type == num_type)
return true;
else
return false;
}

bool checkCompatibility(Token *op, Object left, Object right) {
if ((left.type == string_type && right.type == num_type) ||
left.type == num_type && right.type == string_type) {
return true;
} else {
return false;
}
}
Object excecute(Statement *stmnt);

Object evaluate(Expr *expr);

bool isTruthy(Object right);

bool isEqual(Object left, Object right);

void checkNumberOperand(Token *op, Object right);

bool checkIfSameTypes(Object left, Object right);

bool checkCompatibility(Token *op, Object left, Object right);

public:
void interpret(std::vector<Statement *> &statements) {
try {
for (Statement *stmt : statements) {
excecute(stmt);
}
} catch (RuntimeError error) {
crux::runtimeError(error);
}
}

void visitPrintStmnt(Print *expr) {
Object value = evaluate(expr->expression);
std::cout << value.str() << "\n";
return;
}

void visitExprStmnt(Expression *expr) { evaluate(expr->expression); }

Object visitLiteral(Literal *expr) { return *expr->literal; }

Object visitGroupExp(Grouping *expr) { return evaluate(expr->expression); }

Object visitUnaryExp(Unary *expr) {
Object right = evaluate(expr->right);
switch (expr->op->type) {
case BANG:
return !isTruthy(right);
case MINUS:
checkNumberOperand(expr->op, right);
return -right.num_literal;
default:
RuntimeError(*expr->op, "Invalid operator used");
}
return Object();
}

Object visitBinaryExp(Binary *expr) {
Object left = evaluate(expr->left);
Object right = evaluate(expr->right);
Token *op = expr->op;
switch (op->type) {
case MINUS:
checkIfSameTypes(left, right);
return left.num_literal - right.num_literal;
case SLASH:
checkIfSameTypes(left, right);
return left.num_literal / right.num_literal;
case STAR:
checkIfSameTypes(left, right);
return left.num_literal * right.num_literal;
case PLUS:
if (checkIfSameTypes(left, right)) {
if (left.type == num_type && right.type == num_type)
return left.num_literal + right.num_literal;
if (left.type == string_type && right.type == string_type)
return left.string_literal + right.string_literal;
} else if (checkCompatibility(op, left, right)) {
if (left.type == string_type && right.type == num_type)
return left.string_literal + std::to_string(right.num_literal);
else if (left.type == num_type && right.type == string_type)
return std::to_string(left.num_literal) + right.string_literal;
}
throw new RuntimeError(*op, "Error: Cannot evaluate expression");
case GREATER:
checkIfSameTypes(left, right);
return left.num_literal > right.num_literal;
case GREATER_EQUAL:
checkIfSameTypes(left, right);
return left.num_literal >= right.num_literal;
case LESS:
checkIfSameTypes(left, right);
return left.num_literal < right.num_literal;
case LESS_EQUAL:
checkIfSameTypes(left, right);
return left.num_literal <= right.num_literal;
case BANG_EQUAL:
return !isEqual(left, right);
case EQUAL_EQUAL:
return isEqual(left, right);
}
RuntimeError(*op, "Operator not found");
}

Object visitTernaryExp(Ternary *expr) {
Object condition = evaluate(expr->condition);
if (condition.type == bool_type) {
if (condition.bool_literal)
return evaluate(expr->expression1);
else
return evaluate(expr->expression2);
} else {
RuntimeError(*expr->op1, "Ternary Expression couldn't be evaluated");
}
return Object();
}
std::string interpret(std::vector<Statement *> &statements);

void visitPrintStmnt(Print *expr);

Object visitExprStmnt(Expression *expr);

Object visitLiteral(Literal *expr);

Object visitGroupExp(Grouping *expr);

Object visitUnaryExp(Unary *expr);

Object visitBinaryExp(Binary *expr);

Object visitTernaryExp(Ternary *expr);
};

#endif // CRUX_INTERPRETER_H
4 changes: 4 additions & 0 deletions include/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ class Parser {
Statement *printStatement();
Statement *expressionStatement();

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

// helper functions
Expr *equality();
bool check(TokenType type);
Expand Down
12 changes: 8 additions & 4 deletions include/Statement.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,7 @@

#include "Expr.h"

enum Statement_type {
StmntExpr_type,
StmntPrint_type,
};
enum Statement_type { StmntExpr_type, StmntPrint_type, StmntVar_type };

class Statement {
public:
Expand All @@ -30,4 +27,11 @@ class Expression : public Statement {
Expression(Expr *expression);
};

class Var : public Statement {
public:
Token *name;
Expr *expression;
Var(Token *name, Expr *expression);
};

#endif
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ set(Sources Error.cpp
utls/Object.cpp
Expr.cpp
AstPrinter.cpp
Interpreter.cpp
Statement.cpp
)

Expand Down
Loading

0 comments on commit 6d906ca

Please sign in to comment.