Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
CXX := g++
CXXFLAGS := -std=c++17 -Wall -Wextra -O2

all: mycompiler

parser.cpp parser.hpp: parser.y
bison -d -o parser.cpp parser.y

lexer.cpp: lexer.l parser.hpp
flex -o lexer.cpp lexer.l

mycompiler: parser.cpp lexer.cpp main.cpp
$(CXX) $(CXXFLAGS) -o $@ parser.cpp lexer.cpp main.cpp -lfl

clean:
rm -f parser.cpp parser.hpp lexer.cpp mycompiler
1 change: 0 additions & 1 deletion README.md

This file was deleted.

84 changes: 0 additions & 84 deletions ast.h

This file was deleted.

178 changes: 178 additions & 0 deletions ast.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
#pragma once
#include <string>
#include <vector>
#include <iostream>
#include <cstdint>

namespace AST {

struct Node {
virtual ~Node() = default;
virtual void print(std::ostream& os, int indent = 0) const = 0;
};

inline void doIndent(std::ostream& os, int n) {
for (int i = 0; i < n; ++i) os << " ";
}

struct Expr : Node { };

struct IntLiteral : Expr {
std::int64_t value;
explicit IntLiteral(std::int64_t v) : value(v) {}
void print(std::ostream& os, int indent) const override {
doIndent(os, indent); os << "Int(" << value << ")\n";
}
};

struct BoolLiteral : Expr {
bool value;
explicit BoolLiteral(bool v) : value(v) {}
void print(std::ostream& os, int indent) const override {
doIndent(os, indent); os << "Bool(" << (value ? "true" : "false") << ")\n";
}
};

struct Identifier : Expr {
std::string name;
explicit Identifier(std::string n) : name(std::move(n)) {}
void print(std::ostream& os, int indent) const override {
doIndent(os, indent); os << "Id(" << name << ")\n";
}
};

enum class BinOp { Add, Sub, Mul, Div, Assign };

struct Binary : Expr {
BinOp op;
Expr* lhs;
Expr* rhs;
Binary(BinOp o, Expr* l, Expr* r) : op(o), lhs(l), rhs(r) {}
~Binary() { delete lhs; delete rhs; }
static const char* opToStr(BinOp o) {
switch (o) {
case BinOp::Add: return "+";
case BinOp::Sub: return "-";
case BinOp::Mul: return "*";
case BinOp::Div: return "/";
case BinOp::Assign: return "=";
}
return "?";
}
void print(std::ostream& os, int indent) const override {
doIndent(os, indent);
os << "BinOp(" << opToStr(op) << ")\n";
lhs->print(os, indent + 1);
rhs->print(os, indent + 1);
}
};

struct Unary : Expr {
enum class Op { Neg };
Op op;
Expr* rhs;
Unary(Op o, Expr* e) : op(o), rhs(e) {}
~Unary() { delete rhs; }
void print(std::ostream& os, int indent) const override {
doIndent(os, indent);
os << "Unary(-)\n";
rhs->print(os, indent + 1);
}
};

struct Stmt : Node { };

struct ReturnStmt : Stmt {
Expr* value;
explicit ReturnStmt(Expr* v) : value(v) {}
~ReturnStmt() { delete value; }
void print(std::ostream& os, int indent) const override {
doIndent(os, indent); os << "return\n";
value->print(os, indent + 1);
}
};

struct IfStmt : Stmt {
Expr* cond;
Stmt* thenS;
Stmt* elseS;
IfStmt(Expr* c, Stmt* t, Stmt* e) : cond(c), thenS(t), elseS(e) {}
~IfStmt() { delete cond; delete thenS; delete elseS; }
void print(std::ostream& os, int indent) const override {
doIndent(os, indent); os << "if\n";
cond->print(os, indent + 1);
doIndent(os, indent); os << "then\n";
thenS->print(os, indent + 1);
doIndent(os, indent); os << "else\n";
elseS->print(os, indent + 1);
}
};

struct VarDecl : Node {
std::string name;
std::string typeName;
Expr* init;
VarDecl(std::string n, std::string t, Expr* i)
: name(std::move(n)), typeName(std::move(t)), init(i) {}
~VarDecl() { delete init; }
void print(std::ostream& os, int indent) const override {
doIndent(os, indent);
os << "var " << name << " : " << typeName;
if (init) {
os << " =\n";
init->print(os, indent + 1);
} else {
os << "\n";
}
}
};

struct Param {
std::string name;
std::string typeName;
Param(std::string n, std::string t) : name(std::move(n)), typeName(std::move(t)) {}
};

struct MethodDecl : Node {
std::string name;
std::vector<Param*> params;
std::string returnType;
Stmt* body;
MethodDecl(std::string n, std::string rt, Stmt* b)
: name(std::move(n)), returnType(std::move(rt)), body(b) {}
~MethodDecl() { for (auto* p : params) delete p; delete body; }
void print(std::ostream& os, int indent) const override {
doIndent(os, indent);
os << "method " << name << "(";
for (size_t i = 0; i < params.size(); ++i) {
os << params[i]->name << " : " << params[i]->typeName;
if (i + 1 < params.size()) os << ", ";
}
os << ") : " << returnType << "\n";
if (body) body->print(os, indent + 1);
}
};

struct ClassDecl : Node {
std::string name;
std::vector<VarDecl*> fields;
std::vector<MethodDecl*> methods;
explicit ClassDecl(std::string n) : name(std::move(n)) {}
~ClassDecl() { for (auto* v : fields) delete v; for (auto* m : methods) delete m; }
void print(std::ostream& os, int indent) const override {
doIndent(os, indent);
os << "Class: " << name << "\n";
for (auto* v : fields) v->print(os, indent + 1);
for (auto* m : methods) m->print(os, indent + 1);
}
};

struct Program : Node {
std::vector<ClassDecl*> classes;
~Program() { for (auto* c : classes) delete c; }
void print(std::ostream& os, int indent = 0) const override {
for (auto* c : classes) c->print(os, indent);
}
};

}
Loading
Loading