Removed templating as it turns out, wasn't needed. Added shorthands to make the code less ugly

This commit is contained in:
Bobby Lucero 2023-05-27 13:11:08 -04:00
parent a0ec4af169
commit 9500cf9773
10 changed files with 108 additions and 112 deletions

View File

@ -1,18 +1,20 @@
#pragma once #pragma once
#include "Expression.h" #include "Expression.h"
#include "TypeWrapper.h" #include "TypeWrapper.h"
#include "helperFunctions/ShortHands.h"
#include <string> #include <string>
#include <initializer_list> #include <initializer_list>
class ASTPrinter : public Visitor<std::shared_ptr<Object>>
class ASTPrinter : public Visitor
{ {
std::shared_ptr<Object> visitBinaryExpr(BinaryExpr<std::shared_ptr<Object>>* expression) override; sptr(Object) visitBinaryExpr(BinaryExpr* expression) override;
std::shared_ptr<Object> visitGroupingExpr(GroupingExpr<std::shared_ptr<Object>>* expression) override; sptr(Object) visitGroupingExpr(GroupingExpr* expression) override;
std::shared_ptr<Object> visitLiteralExpr(LiteralExpr<std::shared_ptr<Object>>* expression) override; sptr(Object) visitLiteralExpr(LiteralExpr* expression) override;
std::shared_ptr<Object> visitUnaryExpr(UnaryExpr<std::shared_ptr<Object>>* expression) override; sptr(Object) visitUnaryExpr(UnaryExpr* expression) override;
public: public:
std::shared_ptr<Object> print(Expr<std::shared_ptr<Object>>* expr); sptr(Object) print(Expr* expr);
private: private:
std::shared_ptr<Object> parenthesize(std::string name, std::vector<std::shared_ptr<Expr<std::shared_ptr<Object>>>> exprs); sptr(Object) parenthesize(std::string name, std::vector<sptr(Expr)> exprs);
}; };

View File

@ -3,76 +3,81 @@
// //
#pragma once #pragma once
#include "Lexer.h"
#include <iostream> #include <iostream>
#include "Lexer.h"
#include "helperFunctions/ShortHands.h"
#include "TypeWrapper.h"
struct BinaryExpr;
struct GroupingExpr;
struct LiteralExpr;
struct UnaryExpr;
struct Visitor
{
virtual sptr(Object) visitBinaryExpr(BinaryExpr* expression) = 0;
virtual sptr(Object) visitGroupingExpr(GroupingExpr* expression) = 0;
virtual sptr(Object) visitLiteralExpr(LiteralExpr* expression) = 0;
virtual sptr(Object) visitUnaryExpr(UnaryExpr* expression) = 0;
};
template <typename T>
struct Visitor;
template <typename T>
struct Expr{ struct Expr{
virtual T accept(Visitor<T>* visitor) = 0; virtual sptr(Object) accept(Visitor* visitor) = 0;
virtual ~Expr(){} virtual ~Expr(){}
}; };
template <typename T>
struct BinaryExpr : Expr<T>
{
const std::shared_ptr<Expr<T>> left;
const Token oper;
const std::shared_ptr<Expr<T>> right;
BinaryExpr(std::shared_ptr<Expr<T>> left, Token oper, std::shared_ptr<Expr<T>> right) : left(left), oper(oper), right(right) struct BinaryExpr : Expr
{
const std::shared_ptr<Expr> left;
const Token oper;
const std::shared_ptr<Expr> right;
BinaryExpr(sptr(Expr) left, Token oper, sptr(Expr) right) : left(left), oper(oper), right(right)
{ {
} }
T accept(Visitor<T>* visitor) override{ sptr(Object) accept(Visitor* visitor) override{
return visitor->visitBinaryExpr(this); return visitor->visitBinaryExpr(this);
} }
}; };
template <typename T>
struct GroupingExpr : Expr<T>
{
const std::shared_ptr<Expr<T>> expression;
GroupingExpr(std::shared_ptr<Expr<T>> expression) : expression(expression) struct GroupingExpr : Expr
{
const std::shared_ptr<Expr> expression;
GroupingExpr(sptr(Expr) expression) : expression(expression)
{ {
} }
T accept(Visitor<T>* visitor) override{ sptr(Object) accept(Visitor* visitor) override{
return visitor->visitGroupingExpr(this); return visitor->visitGroupingExpr(this);
} }
}; };
template <typename T>
struct LiteralExpr : Expr<T> struct LiteralExpr : Expr
{ {
const std::string value; const std::string value;
const bool isNumber; const bool isNumber;
LiteralExpr(std::string value, bool isNumber) : value(value), isNumber(isNumber) LiteralExpr(std::string value, bool isNumber) : value(value), isNumber(isNumber)
{ {
} }
T accept(Visitor<T>* visitor) override{ sptr(Object) accept(Visitor* visitor) override{
return visitor->visitLiteralExpr(this); return visitor->visitLiteralExpr(this);
} }
}; };
template <typename T>
struct UnaryExpr : Expr<T> struct UnaryExpr : Expr
{ {
const Token oper; const Token oper;
const std::shared_ptr<Expr<T>> right; const std::shared_ptr<Expr> right;
UnaryExpr(Token oper, std::shared_ptr<Expr<T>> right) : oper(oper), right(right) UnaryExpr(Token oper, sptr(Expr) right) : oper(oper), right(right)
{ {
} }
T accept(Visitor<T>* visitor) override{ sptr(Object) accept(Visitor* visitor) override{
return visitor->visitUnaryExpr(this); return visitor->visitUnaryExpr(this);
} }
}; };
//// ////
template <typename T>
struct Visitor
{
virtual T visitBinaryExpr(BinaryExpr<T>* expression) = 0;
virtual T visitGroupingExpr(GroupingExpr<T>* expression) = 0;
virtual T visitLiteralExpr(LiteralExpr<T>* expression) = 0;
virtual T visitUnaryExpr(UnaryExpr<T>* expression) = 0;
};

View File

@ -4,6 +4,7 @@
#include "Lexer.h" #include "Lexer.h"
#include "Expression.h" #include "Expression.h"
#include "TypeWrapper.h" #include "TypeWrapper.h"
#include "helperFunctions/ShortHands.h"
class Parser class Parser
{ {
@ -13,16 +14,16 @@ private:
public: public:
explicit Parser(std::vector<Token> tokens) : tokens(std::move(tokens)){}; explicit Parser(std::vector<Token> tokens) : tokens(std::move(tokens)){};
std::shared_ptr<Expr<std::shared_ptr<Object>>> parse(); sptr(Expr) parse();
private: private:
std::shared_ptr<Expr<std::shared_ptr<Object>>> expression(); sptr(Expr) expression();
std::shared_ptr<Expr<std::shared_ptr<Object>>> equality(); sptr(Expr) equality();
std::shared_ptr<Expr<std::shared_ptr<Object>>> comparison(); sptr(Expr) comparison();
std::shared_ptr<Expr<std::shared_ptr<Object>>> term(); sptr(Expr) term();
std::shared_ptr<Expr<std::shared_ptr<Object>>> factor(); sptr(Expr) factor();
std::shared_ptr<Expr<std::shared_ptr<Object>>> unary(); sptr(Expr) unary();
std::shared_ptr<Expr<std::shared_ptr<Object>>> primary(); sptr(Expr) primary();
bool match(std::vector<TokenType> types); bool match(std::vector<TokenType> types);

View File

@ -2,9 +2,7 @@
#include <string> #include <string>
struct Object struct Object
{ {
static int count; virtual ~Object(){};
Object();
virtual ~Object();
}; };
struct Number : public Object struct Number : public Object

View File

@ -0,0 +1,5 @@
#pragma once
#include <memory>
#define sptr(T) std::shared_ptr<T>
#define msptr(T) std::make_shared<T>

View File

@ -4,40 +4,38 @@
#include "../headers/ASTPrinter.h" #include "../headers/ASTPrinter.h"
std::shared_ptr<Object> ASTPrinter::visitBinaryExpr(BinaryExpr<std::shared_ptr<Object>>* expression){ sptr(Object) ASTPrinter::visitBinaryExpr(BinaryExpr* expression){
std::cout << expression->left << std::endl; std::cout << expression->left << std::endl;
return parenthesize(expression->oper.lexeme, std::vector<std::shared_ptr<Expr<std::shared_ptr<Object>>>>{expression->left, expression->right}); return parenthesize(expression->oper.lexeme, std::vector<sptr(Expr)>{expression->left, expression->right});
} }
std::shared_ptr<Object> ASTPrinter::visitGroupingExpr(GroupingExpr<std::shared_ptr<Object>>* expression){ sptr(Object) ASTPrinter::visitGroupingExpr(GroupingExpr* expression){
return parenthesize("group", std::vector<std::shared_ptr<Expr<std::shared_ptr<Object>>>>{expression->expression}); return parenthesize("group", std::vector<sptr(Expr)>{expression->expression});
} }
std::shared_ptr<Object> ASTPrinter::visitLiteralExpr(LiteralExpr<std::shared_ptr<Object>>* expression){ sptr(Object) ASTPrinter::visitLiteralExpr(LiteralExpr* expression){
return std::make_shared<String>(expression->value); return msptr(String)(expression->value);
} }
std::shared_ptr<Object> ASTPrinter::visitUnaryExpr(UnaryExpr<std::shared_ptr<Object>>* expression){ sptr(Object) ASTPrinter::visitUnaryExpr(UnaryExpr* expression){
return parenthesize(expression->oper.lexeme, std::vector<std::shared_ptr<Expr<std::shared_ptr<Object>>>>{expression->right}); return parenthesize(expression->oper.lexeme, std::vector<sptr(Expr)>{expression->right});
} }
std::shared_ptr<Object> ASTPrinter::print(Expr<std::shared_ptr<Object>> *expr) { sptr(Object) ASTPrinter::print(Expr *expr) {
return expr->accept(this); return expr->accept(this);
} }
std::shared_ptr<Object> ASTPrinter::parenthesize(std::string name, std::vector<std::shared_ptr<Expr<std::shared_ptr<Object>>>> exprs) { sptr(Object) ASTPrinter::parenthesize(std::string name, std::vector<sptr(Expr)> exprs) {
std::string builder; std::string builder;
builder += "(" + name; builder += "(" + name;
for(const std::shared_ptr<Expr<std::shared_ptr<Object>>>& expr : exprs) for(const sptr(Expr)& expr : exprs)
{ {
builder += " "; builder += " ";
builder += std::dynamic_pointer_cast<String>(expr->accept(this))->value; builder += std::dynamic_pointer_cast<String>(expr->accept(this))->value;
} }
builder += ")"; builder += ")";
return std::make_shared<String>(builder); return msptr(String)(builder);
} }

View File

@ -8,94 +8,94 @@
// to all the morons on facebook who don't know what pemdas is, fuck you // to all the morons on facebook who don't know what pemdas is, fuck you
/////////////////////////////////////////// ///////////////////////////////////////////
std::shared_ptr<Expr<std::shared_ptr<Object>>> Parser::expression() sptr(Expr) Parser::expression()
{ {
return equality(); return equality();
} }
std::shared_ptr<Expr<std::shared_ptr<Object>>> Parser::equality() sptr(Expr) Parser::equality()
{ {
std::shared_ptr<Expr<std::shared_ptr<Object>>> expr = comparison(); sptr(Expr) expr = comparison();
while(match({BANG_EQUAL, DOUBLE_EQUAL})) while(match({BANG_EQUAL, DOUBLE_EQUAL}))
{ {
Token op = previous(); Token op = previous();
std::shared_ptr<Expr<std::shared_ptr<Object>>> right = comparison(); sptr(Expr) right = comparison();
expr = std::make_shared<BinaryExpr<std::shared_ptr<Object>>>(expr, op, right); expr = msptr(BinaryExpr)(expr, op, right);
} }
return expr; return expr;
} }
std::shared_ptr<Expr<std::shared_ptr<Object>>> Parser::comparison() sptr(Expr) Parser::comparison()
{ {
std::shared_ptr<Expr<std::shared_ptr<Object>>> expr = term(); sptr(Expr) expr = term();
while(match({GREATER, GREATER_EQUAL, LESS, LESS_EQUAL})) while(match({GREATER, GREATER_EQUAL, LESS, LESS_EQUAL}))
{ {
Token op = previous(); Token op = previous();
std::shared_ptr<Expr<std::shared_ptr<Object>>> right = term(); sptr(Expr) right = term();
expr = std::make_shared<BinaryExpr<std::shared_ptr<Object>>>(expr, op, right); expr = msptr(BinaryExpr)(expr, op, right);
} }
return expr; return expr;
} }
std::shared_ptr<Expr<std::shared_ptr<Object>>> Parser::term() sptr(Expr) Parser::term()
{ {
std::shared_ptr<Expr<std::shared_ptr<Object>>> expr = factor(); sptr(Expr) expr = factor();
while(match({MINUS, PLUS})) while(match({MINUS, PLUS}))
{ {
std::cout << "Found comparison" << std::endl; std::cout << "Found comparison" << std::endl;
Token op = previous(); Token op = previous();
std::shared_ptr<Expr<std::shared_ptr<Object>>> right = factor(); sptr(Expr) right = factor();
expr = std::make_shared<BinaryExpr<std::shared_ptr<Object>>>(expr, op, right); expr = msptr(BinaryExpr)(expr, op, right);
} }
return expr; return expr;
} }
std::shared_ptr<Expr<std::shared_ptr<Object>>> Parser::factor() sptr(Expr) Parser::factor()
{ {
std::shared_ptr<Expr<std::shared_ptr<Object>>> expr = unary(); sptr(Expr) expr = unary();
while(match({SLASH, STAR})) while(match({SLASH, STAR}))
{ {
Token op = previous(); Token op = previous();
std::shared_ptr<Expr<std::shared_ptr<Object>>> right = unary(); sptr(Expr) right = unary();
expr = std::make_shared<BinaryExpr<std::shared_ptr<Object>>>(expr, op, right); expr = msptr(BinaryExpr)(expr, op, right);
} }
return expr; return expr;
} }
std::shared_ptr<Expr<std::shared_ptr<Object>>> Parser::unary() sptr(Expr) Parser::unary()
{ {
if(match({BANG, MINUS})) if(match({BANG, MINUS}))
{ {
Token op = previous(); Token op = previous();
std::shared_ptr<Expr<std::shared_ptr<Object>>> right = unary(); sptr(Expr) right = unary();
return std::make_shared<UnaryExpr<std::shared_ptr<Object>>>(op, right); return msptr(UnaryExpr)(op, right);
} }
return primary(); return primary();
} }
std::shared_ptr<Expr<std::shared_ptr<Object>>> Parser::primary() sptr(Expr) Parser::primary()
{ {
if(match({FALSE})) return std::make_shared<LiteralExpr<std::shared_ptr<Object>>>("true", false); if(match({FALSE})) return msptr(LiteralExpr)("true", false);
if(match({TRUE})) return std::make_shared<LiteralExpr<std::shared_ptr<Object>>>("true", false); if(match({TRUE})) return msptr(LiteralExpr)("true", false);
if(match({NONE})) return std::make_shared<LiteralExpr<std::shared_ptr<Object>>>("none", false); if(match({NONE})) return msptr(LiteralExpr)("none", false);
if(match({NUMBER})) return std::make_shared<LiteralExpr<std::shared_ptr<Object>>>(previous().lexeme, true); if(match({NUMBER})) return msptr(LiteralExpr)(previous().lexeme, true);
if(match({STRING})) return std::make_shared<LiteralExpr<std::shared_ptr<Object>>>(previous().lexeme, false); if(match({STRING})) return msptr(LiteralExpr)(previous().lexeme, false);
if(match({OPEN_PAREN})) if(match({OPEN_PAREN}))
{ {
std::shared_ptr<Expr<std::shared_ptr<Object>>> expr = expression(); sptr(Expr) expr = expression();
consume(CLOSE_PAREN, "Expected ')' after expression on line " + std::to_string(peek().line)); consume(CLOSE_PAREN, "Expected ')' after expression on line " + std::to_string(peek().line));
return std::make_shared<GroupingExpr<std::shared_ptr<Object>>>(expr); return msptr(GroupingExpr)(expr);
} }
throw std::runtime_error("Expression expected at: " + std::to_string(peek().line)); throw std::runtime_error("Expression expected at: " + std::to_string(peek().line));
@ -104,7 +104,7 @@ std::shared_ptr<Expr<std::shared_ptr<Object>>> Parser::primary()
/////////////////////////////////////////// ///////////////////////////////////////////
std::shared_ptr<Expr<std::shared_ptr<Object>>> Parser::parse() { sptr(Expr) Parser::parse() {
return expression(); return expression();

View File

@ -4,15 +4,3 @@
#include "../headers/TypeWrapper.h" #include "../headers/TypeWrapper.h"
#include <iostream> #include <iostream>
int Object::count;
Object::Object() {
std::cout << "Inc"<<std::endl;
Object::count += 1;
}
Object::~Object() {
std::cout << "dec"<<std::endl;
Object::count -= 1;
}

View File

@ -50,7 +50,7 @@ void Bob::run(string source)
try { try {
vector<Token> tokens = lexer.Tokenize(source); vector<Token> tokens = lexer.Tokenize(source);
Parser p(tokens); Parser p(tokens);
shared_ptr<Expr<shared_ptr<Object>>> expr = p.parse(); shared_ptr<Expr> expr = p.parse();
ASTPrinter printer; ASTPrinter printer;
@ -59,7 +59,7 @@ void Bob::run(string source)
for(Token t : tokens){ for(Token t : tokens){
//cout << "{type: " << t.type << ", value: " << t.lexeme << "}" << endl; cout << "{type: " << t.type << ", value: " << t.lexeme << "}" << endl;
} }
@ -70,7 +70,7 @@ void Bob::run(string source)
return; return;
} }
cout << "Current object count: " << Object::count << endl;
} }

View File

@ -9,7 +9,6 @@
#include "../headers/ASTPrinter.h" #include "../headers/ASTPrinter.h"
#include "../headers/TypeWrapper.h" #include "../headers/TypeWrapper.h"
int main(){ int main(){
Object::count = 0;
Bob bobLang; Bob bobLang;
//bobLang.runFile("source.bob"); //bobLang.runFile("source.bob");