Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor compiler skeleton #22

Merged
merged 13 commits into from
Mar 11, 2024
3 changes: 2 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ RUN apt-get update && apt-get install -y --fix-missing \
curl \
device-tree-compiler \
lcov \
nano
nano \
valgrind

# Install RISC-V Toolchain
WORKDIR /tmp
Expand Down
4 changes: 2 additions & 2 deletions debugging/example-backtrace-3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
#include <iostream>
#include <vector>

const char *ARRAY_OF_NUMBERS[] = { "1", "2" , "99" };
const char* ARRAY_OF_NUMBERS[] = { "1", "2" , "99" };

static int process_arguments(int argc, const char *argv[])
static int process_arguments(int argc, const char* argv[])
{
std::vector<int> numbers(argc - 1);
for (int i = 1 ; i < argc ; i++) {
Expand Down
7 changes: 2 additions & 5 deletions include/ast.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#ifndef AST_HPP
#define AST_HPP
#pragma once

#include <iostream>
#include <string>
Expand All @@ -14,6 +13,4 @@
#include "ast_constant.hpp"
#include "ast_context.hpp"

extern Node *ParseAST(std::string file_name);

#endif
ast::NodePtr ParseAST(std::string file_name);
11 changes: 6 additions & 5 deletions include/ast_constant.hpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
#ifndef AST_CONSTANT_HPP
#define AST_CONSTANT_HPP
#pragma once

#include "ast_node.hpp"

namespace ast {

class IntConstant : public Node
{
private:
Expand All @@ -11,8 +12,8 @@ class IntConstant : public Node
public:
IntConstant(int value) : value_(value) {}

void EmitRISC(std::ostream &stream, Context &context) const override;
void Print(std::ostream &stream) const override;
void EmitRISC(std::ostream& stream, Context& context) const override;
void Print(std::ostream& stream) const override;
};

#endif
} // namespace ast
8 changes: 4 additions & 4 deletions include/ast_context.hpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
#ifndef AST_CONTEXT_HPP
#define AST_CONTEXT_HPP
#pragma once

// An object of class Context is passed between AST nodes during compilation.
namespace ast {
// An object of class Context is passed between ast nodes during compilation.
// This can be used to pass around information about what's currently being
// compiled (e.g. function scope and variable names).
class Context
{
/* TODO decide what goes inside here */
};

#endif
} // namespace ast
20 changes: 9 additions & 11 deletions include/ast_direct_declarator.hpp
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
#ifndef AST_DIRECT_DECLARATOR_HPP
#define AST_DIRECT_DECLARATOR_HPP
#pragma once

#include "ast_node.hpp"

namespace ast {

class DirectDeclarator : public Node
{
private:
Node *identifier_;
NodePtr identifier_;

public:
DirectDeclarator(Node *identifier) : identifier_(identifier){};
~DirectDeclarator()
{
delete identifier_;
};
void EmitRISC(std::ostream &stream, Context &context) const override;
void Print(std::ostream &stream) const override;
DirectDeclarator(NodePtr identifier) : identifier_(std::move(identifier)){};

void EmitRISC(std::ostream& stream, Context& context) const override;
void Print(std::ostream& stream) const override;
};

#endif
} // namespace ast
27 changes: 12 additions & 15 deletions include/ast_function_definition.hpp
Original file line number Diff line number Diff line change
@@ -1,25 +1,22 @@
#ifndef AST_FUNCTION_DEFINITION_HPP
#define AST_FUNCTION_DEFINITION_HPP
#pragma once

#include "ast_node.hpp"
#include "ast_type_specifier.hpp"

namespace ast {

class FunctionDefinition : public Node
{
private:
Node *declaration_specifiers_;
Node *declarator_;
Node *compound_statement_;
const TypeSpecifier declaration_specifiers_;
NodePtr declarator_;
NodePtr compound_statement_;

public:
FunctionDefinition(Node *declaration_specifiers, Node *declarator, Node *compound_statement) : declaration_specifiers_(declaration_specifiers), declarator_(declarator), compound_statement_(compound_statement){};
~FunctionDefinition()
{
delete declaration_specifiers_;
delete declarator_;
delete compound_statement_;
};
void EmitRISC(std::ostream &stream, Context &context) const override;
void Print(std::ostream &stream) const override;
FunctionDefinition(TypeSpecifier declaration_specifiers, NodePtr declarator, NodePtr compound_statement) : declaration_specifiers_(declaration_specifiers), declarator_(std::move(declarator)), compound_statement_(std::move(compound_statement)){};

void EmitRISC(std::ostream& stream, Context& context) const override;
void Print(std::ostream& stream) const override;
};

#endif
} // namespace ast
15 changes: 8 additions & 7 deletions include/ast_identifier.hpp
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
#ifndef AST_IDENTIFIER_HPP
#define AST_IDENTIFIER_HPP
#pragma once

#include "ast_node.hpp"

namespace ast {

class Identifier : public Node
{
private:
std::string identifier_;

public:
Identifier(std::string identifier) : identifier_(identifier){};
~Identifier(){};
void EmitRISC(std::ostream &stream, Context &context) const override;
void Print(std::ostream &stream) const override;
Identifier(std::string identifier) : identifier_(std::move(identifier)){};

void EmitRISC(std::ostream& stream, Context& context) const override;
void Print(std::ostream& stream) const override;
};

#endif
} // namespace ast
19 changes: 8 additions & 11 deletions include/ast_jump_statement.hpp
Original file line number Diff line number Diff line change
@@ -1,22 +1,19 @@
#ifndef AST_JUMP_STATEMENT_HPP
#define AST_JUMP_STATEMENT_HPP
#pragma once

#include "ast_node.hpp"

namespace ast {

class ReturnStatement : public Node
{
private:
Node *expression_;
NodePtr expression_;

public:
ReturnStatement(Node *expression) : expression_(expression) {}
~ReturnStatement()
{
delete expression_;
};
ReturnStatement(NodePtr expression) : expression_(std::move(expression)) {}

void EmitRISC(std::ostream &stream, Context &context) const override;
void Print(std::ostream &stream) const override;
void EmitRISC(std::ostream& stream, Context& context) const override;
void Print(std::ostream& stream) const override;
};

#endif
} // namespace ast
45 changes: 20 additions & 25 deletions include/ast_node.hpp
Original file line number Diff line number Diff line change
@@ -1,43 +1,38 @@
#ifndef AST_NODE_HPP
#define AST_NODE_HPP
#pragma once

#include <iostream>
#include <memory>
#include <vector>

#include "ast_context.hpp"

namespace ast {

class Node
{
protected:
std::vector<Node *> branches_;

public:
Node(){};
virtual ~Node();
virtual void EmitRISC(std::ostream &stream, Context &context) const = 0;
virtual void Print(std::ostream &stream) const = 0;
virtual ~Node() {}
virtual void EmitRISC(std::ostream& stream, Context& context) const = 0;
virtual void Print(std::ostream& stream) const = 0;
};

// Represents a list of nodes.
// If you don't feel comfortable using std::unique_ptr, you can switch NodePtr to be defined
// as a raw pointer instead here and your project should still compile, although you'll need
// to add destructors to avoid leaking memory
// (and get rid of the now unnecessary std::move-s)
using NodePtr = std::unique_ptr<const Node>;

class NodeList : public Node
{
private:
std::vector<Node *> nodes_;
std::vector<NodePtr> nodes_;

public:
NodeList(Node *first_node) : nodes_({first_node}) {}

~NodeList()
{
for (auto node : nodes_)
{
delete node;
}
}

void PushBack(Node *item);
virtual void EmitRISC(std::ostream &stream, Context &context) const override;
virtual void Print(std::ostream &stream) const override;
NodeList(NodePtr first_node) { nodes_.push_back(std::move(first_node)); }

void PushBack(NodePtr item);
virtual void EmitRISC(std::ostream& stream, Context& context) const override;
virtual void Print(std::ostream& stream) const override;
};

#endif
} // namespace ast
31 changes: 18 additions & 13 deletions include/ast_type_specifier.hpp
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
#ifndef AST_TYPE_SPECIFIER
#define AST_TYPE_SPECIFIER
#pragma once

#include "ast_node.hpp"
#include <string_view>
#include <stdexcept>

class TypeSpecifier : public Node
{
private:
std::string type_;
namespace ast {

public:
TypeSpecifier(std::string type) : type_(type){};
~TypeSpecifier(){};
void EmitRISC(std::ostream &stream, Context &context) const override;
void Print(std::ostream &stream) const override;
enum class TypeSpecifier
{
INT
};

#endif
constexpr std::string_view ToString(TypeSpecifier type)
{
switch (type)
{
case TypeSpecifier::INT:
return "int";
}
throw std::runtime_error("Unexpected type specifier");
}

}
5 changes: 1 addition & 4 deletions include/cli.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#ifndef LANGPROC_COMPILER_CLI_H
#define LANGPROC_COMPILER_CLI_H
#pragma once

#include <iostream>
#include <unistd.h>
Expand All @@ -11,5 +10,3 @@ struct CommandLineArguments
};

CommandLineArguments ParseCommandLineArgs(int argc, char **argv);

#endif
8 changes: 6 additions & 2 deletions src/ast_constant.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
#include "ast_constant.hpp"

void IntConstant::EmitRISC(std::ostream &stream, Context &context) const
namespace ast {

void IntConstant::EmitRISC(std::ostream& stream, Context& context) const
{
stream << "li a0, " << value_ << std::endl;
}

void IntConstant::Print(std::ostream &stream) const
void IntConstant::Print(std::ostream& stream) const
{
stream << value_;
}

} // namespace ast
8 changes: 6 additions & 2 deletions src/ast_direct_declarator.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
#include "ast_direct_declarator.hpp"

void DirectDeclarator::EmitRISC(std::ostream &stream, Context &context) const
namespace ast {

void DirectDeclarator::EmitRISC(std::ostream& stream, Context& context) const
{
identifier_->EmitRISC(stream, context);
stream << ":" << std::endl;
}

void DirectDeclarator::Print(std::ostream &stream) const
void DirectDeclarator::Print(std::ostream& stream) const
{
identifier_->Print(stream);
}

} // namespace ast
11 changes: 7 additions & 4 deletions src/ast_function_definition.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#include "ast_function_definition.hpp"

void FunctionDefinition::EmitRISC(std::ostream &stream, Context &context) const
namespace ast {

void FunctionDefinition::EmitRISC(std::ostream& stream, Context& context) const
{
// Emit assembler directives.
// TODO: these are just examples ones, make sure you understand
Expand All @@ -16,10 +18,9 @@ void FunctionDefinition::EmitRISC(std::ostream &stream, Context &context) const
}
}

void FunctionDefinition::Print(std::ostream &stream) const
void FunctionDefinition::Print(std::ostream& stream) const
{
declaration_specifiers_->Print(stream);
stream << " ";
stream << ToString(declaration_specifiers_) << " ";

declarator_->Print(stream);
stream << "() {" << std::endl;
Expand All @@ -30,3 +31,5 @@ void FunctionDefinition::Print(std::ostream &stream) const
}
stream << "}" << std::endl;
}

}
Loading
Loading