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
39 changes: 39 additions & 0 deletions src/ast/AstVisitor.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#include "ast/AstVisitor.hpp"

#include "ast/ClassNode.hpp"
#include "ast/MainClassNode.hpp"
#include "ast/MethodNode.hpp"
#include "ast/MethodParameterNode.hpp"
#include "ast/MethodWithoutParametersNode.hpp"
#include "ast/Node.h"
#include "ast/VariableNode.hpp"

void AstVisitor::visit(const Node &node) {
for (const auto &child : node.children) {
child->accept(*this);
}
}

void AstVisitor::visit(const ClassNode &node) {
visit(static_cast<const Node &>(node));
}

void AstVisitor::visit(const MainClassNode &node) {
visit(static_cast<const Node &>(node));
}

void AstVisitor::visit(const MethodNode &node) {
visit(static_cast<const Node &>(node));
}

void AstVisitor::visit(const MethodWithoutParametersNode &node) {
visit(static_cast<const Node &>(node));
}

void AstVisitor::visit(const MethodParameterNode &node) {
visit(static_cast<const Node &>(node));
}

void AstVisitor::visit(const VariableNode &node) {
visit(static_cast<const Node &>(node));
}
25 changes: 25 additions & 0 deletions src/ast/AstVisitor.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#ifndef AST_VISITOR_HPP
#define AST_VISITOR_HPP

class Node;
class ClassNode;
class MainClassNode;
class MethodNode;
class MethodWithoutParametersNode;
class MethodParameterNode;
class VariableNode;

class AstVisitor {
public:
virtual ~AstVisitor() = default;

virtual void visit(const Node &node);
virtual void visit(const ClassNode &node);
virtual void visit(const MainClassNode &node);
virtual void visit(const MethodNode &node);
virtual void visit(const MethodWithoutParametersNode &node);
virtual void visit(const MethodParameterNode &node);
virtual void visit(const VariableNode &node);
};

#endif
19 changes: 2 additions & 17 deletions src/ast/ClassNode.cpp
Original file line number Diff line number Diff line change
@@ -1,23 +1,8 @@
#include "ast/ClassNode.hpp"

bool ClassNode::buildTable(SymbolTable &st) const {
bool valid = true;
if (st.lookupClass(className)) {
std::cerr << "Error: ";
std::cerr << "(line " << lineno << ") ";
std::cerr << "Class " << className << " already declared.\n";
valid = false;
}

st.addClass(className);
auto *currentClass = st.lookupClass(className);
st.enterClassScope(currentClass);
st.addVariable(className, "this");
bool validBody = body->buildTable(st);
st.exitScope();
#include "ast/AstVisitor.hpp"

return valid && validBody;
}
void ClassNode::accept(AstVisitor &visitor) const { visitor.visit(*this); }

std::string ClassNode::checkTypes(SymbolTable &st) const {
st.enterClassScope(className);
Expand Down
6 changes: 5 additions & 1 deletion src/ast/ClassNode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@ class ClassNode : public Node {
body = append_child(std::move(body_));
className = id->value;
}
bool buildTable(SymbolTable &st) const override;
void accept(AstVisitor &visitor) const override;

[[nodiscard]] const std::string &getClassName() const { return className; }
[[nodiscard]] const Node &getBodyNode() const { return *body; }

std::string checkTypes(SymbolTable &st) const override;
Operand generateIR(CFG &graph, SymbolTable &st) override;
};
Expand Down
25 changes: 2 additions & 23 deletions src/ast/MainClassNode.cpp
Original file line number Diff line number Diff line change
@@ -1,29 +1,8 @@
#include "ast/MainClassNode.hpp"

bool MainClassNode::buildTable(SymbolTable &st) const {
if (st.lookupClass(mainClassName)) {
std::cerr << "Error: (line " << lineno << ") Class '" << mainClassName
<< "' already declared.\n";
return false;
}
st.addClass(mainClassName);
auto *mainClass = st.lookupClass(mainClassName);
st.enterClassScope(mainClass);
#include "ast/AstVisitor.hpp"

st.addVariable(mainClassName, "this");
Variable *mainClassThis = st.lookupVariableInScope("this");
mainClass->addVariable(mainClassThis);

st.addMethod("void", "main");
Method *mainClassMethod = st.lookupMethod("main");
mainClass->addMethod(mainClassMethod);

st.enterMethodScope(mainClassMethod);
st.addVariable("String[]", mainMethodArgumentName);
st.exitScope();
st.exitScope();
return true;
}
void MainClassNode::accept(AstVisitor &visitor) const { visitor.visit(*this); }

std::string MainClassNode::checkTypes(SymbolTable &st) const {
st.enterClassScope(mainClassName);
Expand Down
11 changes: 10 additions & 1 deletion src/ast/MainClassNode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,16 @@ class MainClassNode : public Node {
mainMethodArgumentName = arg->value;
}

bool buildTable(SymbolTable &st) const override;
void accept(AstVisitor &visitor) const override;

[[nodiscard]] const std::string &getMainClassName() const {
return mainClassName;
}
[[nodiscard]] const std::string &getMainMethodArgumentName() const {
return mainMethodArgumentName;
}
[[nodiscard]] const Node &getBodyNode() const { return *body; }

std::string checkTypes(SymbolTable &st) const override;
Operand generateIR(CFG &graph, SymbolTable &st) override;
};
Expand Down
21 changes: 2 additions & 19 deletions src/ast/MethodNode.cpp
Original file line number Diff line number Diff line change
@@ -1,25 +1,8 @@
#include "ast/MethodNode.hpp"

bool MethodNode::buildTable(SymbolTable &st) const {
bool valid = true;
if (st.lookupMethod(methodName)) {
std::cerr << "Error: (line " << lineno << ") Method '" << methodName
<< "' already declared.\n";
valid = false;
}

st.addMethod(methodType, methodName);
auto *currentMethod = st.lookupMethod(methodName);
auto *currentClass = dynamic_cast<Class *>(st.getCurrentRecord());
currentClass->addMethod(currentMethod);
#include "ast/AstVisitor.hpp"

st.enterMethodScope(currentMethod);
bool validParams = params->buildTable(st);
bool validBody = body->buildTable(st);
st.exitScope();

return valid && validParams && validBody;
}
void MethodNode::accept(AstVisitor &visitor) const { visitor.visit(*this); }

std::string MethodNode::checkTypes(SymbolTable &st) const {
st.enterMethodScope(methodName);
Expand Down
9 changes: 8 additions & 1 deletion src/ast/MethodNode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,14 @@ class MethodNode : public Node {
methodName = id->value;
methodType = type->value;
}
bool buildTable(SymbolTable &st) const override;

void accept(AstVisitor &visitor) const override;

[[nodiscard]] const std::string &getMethodName() const { return methodName; }
[[nodiscard]] const std::string &getMethodType() const { return methodType; }
[[nodiscard]] const Node &getParametersNode() const { return *params; }
[[nodiscard]] const Node &getBodyNode() const { return *body; }

std::string checkTypes(SymbolTable &st) const override;
Operand generateIR(CFG &graph, SymbolTable &st) override;
};
Expand Down
16 changes: 4 additions & 12 deletions src/ast/MethodParameterNode.cpp
Original file line number Diff line number Diff line change
@@ -1,15 +1,7 @@
#include "ast/MethodParameterNode.hpp"

bool MethodParameterNode::buildTable(SymbolTable &st) const {
if (st.lookupVariableInScope(id->value)) {
std::cerr << "Error: (line " << lineno << ") Parameter '" << id->value
<< "' already declared.\n";
return false;
}
st.addVariable(type->value, id->value);
auto *parameter = st.lookupVariable(id->value);
auto *currentScope = st.getCurrentScope();
auto *currentMethod = dynamic_cast<Method *>(currentScope->getRecord());
currentMethod->addParameter(parameter);
return true;
#include "ast/AstVisitor.hpp"

void MethodParameterNode::accept(AstVisitor &visitor) const {
visitor.visit(*this);
}
11 changes: 10 additions & 1 deletion src/ast/MethodParameterNode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,16 @@ class MethodParameterNode : public Node {
type = append_child(std::move(type_));
id = append_child(std::move(id_));
}
bool buildTable(SymbolTable &st) const override;

void accept(AstVisitor &visitor) const override;

[[nodiscard]] const std::string &getParameterType() const {
return type->value;
}
[[nodiscard]] const std::string &getParameterName() const {
return id->value;
}

};

#endif
18 changes: 3 additions & 15 deletions src/ast/MethodWithoutParametersNode.cpp
Original file line number Diff line number Diff line change
@@ -1,21 +1,9 @@
#include "ast/MethodWithoutParametersNode.hpp"

bool MethodWithoutParametersNode::buildTable(SymbolTable &st) const {
if (st.lookupMethod(id->value)) {
std::cerr << "Error: (line " << lineno << ") Method '" << id->value
<< "' already declared.\n";
return false;
}
st.addMethod(type->value, id->value);
auto *currentMethod = st.lookupMethod(id->value);
auto *currentClass = dynamic_cast<Class *>(st.getCurrentRecord());
currentClass->addMethod(currentMethod);

st.enterMethodScope(currentMethod);
bool validBody = body->buildTable(st);
st.exitScope();
#include "ast/AstVisitor.hpp"

return validBody;
void MethodWithoutParametersNode::accept(AstVisitor &visitor) const {
visitor.visit(*this);
}

std::string MethodWithoutParametersNode::checkTypes(SymbolTable &st) const {
Expand Down
7 changes: 6 additions & 1 deletion src/ast/MethodWithoutParametersNode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,12 @@ class MethodWithoutParametersNode : public Node {
body = append_child(std::move(body_));
}

bool buildTable(SymbolTable &st) const override;
void accept(AstVisitor &visitor) const override;

[[nodiscard]] const std::string &getMethodName() const { return id->value; }
[[nodiscard]] const std::string &getMethodType() const { return type->value; }
[[nodiscard]] const Node &getBodyNode() const { return *body; }

std::string checkTypes(SymbolTable &st) const override;
Operand generateIR(CFG &graph, SymbolTable &st) override;
};
Expand Down
13 changes: 6 additions & 7 deletions src/ast/Node.cpp
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
#include "ast/Node.h"

#include "ast/AstVisitor.hpp"
#include "semantic/SymbolTable.hpp"
#include "semantic/SymbolTableVisitor.hpp"

bool Node::buildTable(SymbolTable &st) const {
bool valid = true;
for (const auto &child : children) {
if (!child->buildTable(st)) {
valid = false;
}
}
return valid;
return build_symbol_table(*this, st).ok();
}

std::string Node::checkTypes(SymbolTable &st) const {
Expand All @@ -32,6 +29,8 @@ Operand Node::generateIR(CFG &graph, SymbolTable &st) {
return "foobar";
}

void Node::accept(AstVisitor &visitor) const { visitor.visit(*this); }

void Node::print(int depth = 0) const {
for (int i = 0; i < depth; i++) {
std::cout << " ";
Expand Down
4 changes: 4 additions & 0 deletions src/ast/Node.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

#include "ir/CFG.hpp"

class AstVisitor;

class Node {
public:
std::string type{}, value{};
Expand All @@ -31,6 +33,8 @@ class Node {

virtual Operand generateIR(CFG &graph, SymbolTable &st);

virtual void accept(AstVisitor &visitor) const;

void print(int depth) const;
void printGraphviz(int &count, std::ostream &outStream);

Expand Down
26 changes: 2 additions & 24 deletions src/ast/VariableNode.cpp
Original file line number Diff line number Diff line change
@@ -1,30 +1,8 @@
#include "ast/VariableNode.hpp"

bool VariableNode::buildTable(SymbolTable &st) const {
#include "ast/AstVisitor.hpp"

Variable *lookup = st.lookupVariableInScope(name->value);
if (lookup) {
std::cerr << "Error: (line " << lineno << ") "
<< "Variable '" << name->value << "' "
<< "already declared.\n";
return false;
}
st.addVariable(type->value, name->value);
Variable *currentVariable = st.lookupVariable(name->value);

Record *curRecord = st.getCurrentRecord();
if (curRecord->getType() == curRecord->getID()) {
// Record is a class
auto *curClass = dynamic_cast<Class *>(curRecord);
curClass->addVariable(currentVariable);
} else {
// Record is a method
auto *curMethod = dynamic_cast<Method *>(curRecord);
curMethod->addVariable(currentVariable);
}

return true;
};
void VariableNode::accept(AstVisitor &visitor) const { visitor.visit(*this); }

std::string VariableNode::checkTypes(SymbolTable &st) const {
const auto &variableType = type->value;
Expand Down
10 changes: 9 additions & 1 deletion src/ast/VariableNode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,15 @@ class VariableNode : public Node {
name = append_child(std::move(name_));
}

bool buildTable(SymbolTable &st) const override;
void accept(AstVisitor &visitor) const override;

[[nodiscard]] const std::string &getVariableType() const {
return type->value;
}
[[nodiscard]] const std::string &getVariableName() const {
return name->value;
}

std::string checkTypes(SymbolTable &st) const override;
};

Expand Down
Loading