Skip to content

Commit

Permalink
yo
Browse files Browse the repository at this point in the history
  • Loading branch information
songmeric committed Mar 19, 2024
1 parent 06a6f6e commit 2466b72
Show file tree
Hide file tree
Showing 26 changed files with 1,073 additions and 529 deletions.
34 changes: 34 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,40 @@
"ignoreFailures": true
}
]
},
{
"name": "Testcase",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/bin/c_compiler",
"args": [
"-S",
"compiler_tests/local_var/constant_initialiser",
"-o",
"bin/debug.s",
],
"cwd": "${workspaceFolder}",
"environment": [
{
"name": "ASAN_OPTIONS",
"value": "exitcode=0,detect_leaks=0"
}
],
"externalConsole": false,
"MIMode": "gdb",
"preLaunchTask": "Run make",
"setupCommands": [
{
"description": "Enable GDB pretty-printing",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "Show Intel style disassembly in GDB",
"text": "-gdb-set disassembly-flavor intel",
"ignoreFailures": true
}
]
}
]
}
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

CXXFLAGS += -std=c++20 -W -Wall -g -Wno-unused-parameter -Wno-unused-variable -Wno-unused-function -fsanitize=address -static-libasan -O0 -rdynamic --coverage -I include

CXXFLAGS += -DYYDEBUG=1

SOURCES := $(wildcard src/*.cpp)
DEPENDENCIES := $(patsubst src/%.cpp,build/%.d,$(SOURCES))

Expand Down
3 changes: 3 additions & 0 deletions constant_initialiser.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.text
.globl f
f:
2 changes: 2 additions & 0 deletions constant_initialiser..printed
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
int f() {
}
10 changes: 10 additions & 0 deletions constant_initialiser.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
.text
.globl f
f:
# Allocate space to save s0
addi sp,sp,-4
# Save caller's s0
sw s0,0(sp)
# Copy stack pointer into frame pointer
mv s0,sp
li a0, 12345
4 changes: 4 additions & 0 deletions constant_initialiser.s.printed
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
int f() {
int x = 12345;
return ;
}
4 changes: 4 additions & 0 deletions include/ast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
#include "ast_type_specifier.hpp"
#include "ast_constant.hpp"
#include "ast_context.hpp"
#include "ast_init_declarator.hpp"
#include "ast_declaration_list.hpp"
#include "ast_compound_stmt.hpp"
#include "ast_variable_ref.hpp"

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

Expand Down
25 changes: 25 additions & 0 deletions include/ast_compound_stmt.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#ifndef AST_COMPOUND_STMT_HPP
#define AST_COMPOUND_STMT_HPP

#include "ast_node.hpp"

class CompoundStatement : public Node
{
private:
Node *decls_;
Node *stmts_;

public:
CompoundStatement(Node *decls, Node *stmts)
: decls_(decls)
, stmts_(stmts) {}
~CompoundStatement()
{
delete decls_;
delete stmts_;
};
void EmitRISC(std::ostream &stream, Context &context) const override;
void Print(std::ostream &stream) const override;
};

#endif
51 changes: 51 additions & 0 deletions include/ast_context.hpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,63 @@
#ifndef AST_CONTEXT_HPP
#define AST_CONTEXT_HPP

#include <string>
#include <vector>
#include <map>

class Variable
{
public:
std::string type;
std::string name;
size_t offset = 0;
bool inMemory = true;
};

class Scope
{
public:
std::vector<Variable> locals;
size_t localsSize;
};

class Function {
public:
std::string type;
std::string name;
std::vector<Variable> parameters;
size_t locals_size = 0;
};

// 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 */
public:
std::vector<Scope> scopes;

void EnterScope();
void ExitScope();

Function* DeclareFunction(
std::string const &type,
std::string const &name);

size_t SizeOfType(std::string const &) const;

std::vector<Function> functions;

int currentFunction = -1;

Variable *DeclareVariable(
std::string const &type,
std::string const &name);

std::string declarationListType;

Variable *FindVariable(std::string const& name);
};

#endif
24 changes: 24 additions & 0 deletions include/ast_declaration_list.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#ifndef AST_DECLARATION_LIST_HPP
#define AST_DECLARATION_LIST_HPP

#include "ast_node.hpp"

class DeclarationList : public Node
{
private:
Node *type_;
Node *list_;

public:
DeclarationList(Node *type, Node *list)
: type_(type), list_(list){}
~DeclarationList()
{
delete type_;
delete list_;
};
void EmitRISC(std::ostream &stream, Context &context) const override;
void Print(std::ostream &stream) const override;
};

#endif
25 changes: 25 additions & 0 deletions include/ast_init_declarator.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#ifndef AST_INIT_DECLARATOR_HPP
#define AST_INIT_DECLARATOR_HPP

#include "ast_node.hpp"

class InitDeclarator : public Node
{
private:
Node *identifier_;
Node *value_;

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

#endif
25 changes: 25 additions & 0 deletions include/ast_variable_ref.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#ifndef AST_VARIABLE_REF_HPP
#define AST_VARIABLE_REF_HPP

#include "ast_node.hpp"
#include "ast_identifier.hpp"

class VariableReference : public Node
{
private:
Identifier *variable_identifier_;

public:
VariableReference(Identifier *variable_identifier)
: variable_identifier_(variable_identifier)
{
}
~VariableReference()
{
delete variable_identifier_;
};
void EmitRISC(std::ostream &stream, Context &context) const override;
void Print(std::ostream &stream) const override;
};

#endif
19 changes: 19 additions & 0 deletions src/ast_compound_stmt.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#include <sstream>
#include "ast_compound_stmt.hpp"

void CompoundStatement::EmitRISC(std::ostream &stream, Context &context) const
{
// Emit assembler directives.
if (decls_)
decls_->EmitRISC(stream, context);
if (stmts_)
stmts_->EmitRISC(stream, context);
}

void CompoundStatement::Print(std::ostream &stream) const
{
if (decls_)
decls_->Print(stream);
if (stmts_)
stmts_->Print(stream);
}
1 change: 1 addition & 0 deletions src/ast_constant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

void IntConstant::EmitRISC(std::ostream &stream, Context &context) const
{
stream << "# Load int constant\n";
stream << "li a0, " << value_ << std::endl;
}

Expand Down
70 changes: 70 additions & 0 deletions src/ast_context.cpp
Original file line number Diff line number Diff line change
@@ -1 +1,71 @@
#include <cassert>
#include "ast_context.hpp"
#include "ast_node.hpp"

void Context::EnterScope()
{
scopes.emplace_back();
}

void Context::ExitScope()
{
scopes.pop_back();
}

Function *Context::DeclareFunction(
std::string const &type,
std::string const &name)
{
currentFunction = functions.size();
Function &fn = functions.emplace_back();
fn.type = type;
fn.name = name;
return &fn;
}

size_t Context::SizeOfType(std::string const& /*type*/) const
{
// Hardcoded to int only for now
return 4;
}

Variable *Context::DeclareVariable(
std::string const& type, std::string const& name)
{
// Get a reference to the innermost scope
// and create a new variable in it
auto &inner = scopes.back();
Variable &variable = inner.locals.emplace_back();
variable.type = type;
variable.name = name;
assert(currentFunction != -1);

size_t variableSize = SizeOfType(type);

// Get a reference to the current function
// so we can use it to find where to place the
// new variable in the function's stack frame
Function &fn = functions[currentFunction];

// Make sure the offset is rounded to an
// aligned boundary later when it handles different types
fn.locals_size += variableSize;
variable.offset = -fn.locals_size & -variableSize;

return &variable;
}

Variable *Context::FindVariable(std::string const &name)
{
for (size_t i = scopes.size(); i > 0; --i)
{
auto &scope = scopes[i-1];
for (Variable& var : scope.locals)
{
if (var.name == name)
return &var;
}
}

return nullptr;
}
27 changes: 27 additions & 0 deletions src/ast_declaration_list.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#include <sstream>
#include "ast_declaration_list.hpp"
#include <unistd.h>

void DeclarationList::EmitRISC(std::ostream &stream, Context &context) const
{
std::ostringstream ss;
type_->EmitRISC(ss, context);
std::string type = ss.str();
size_t sz = context.SizeOfType(type);

context.declarationListType = type;

// Variable allocation codegen expects sizeof(T) in a1
//stream << "li a1," << sz << '\n';

// Allocate (and possibly initialize) each variable
list_->EmitRISC(stream, context);
}

void DeclarationList::Print(std::ostream &stream) const
{
type_->Print(stream);
stream << ' ';
list_->Print(stream);
stream << ";\n";
}
Loading

0 comments on commit 2466b72

Please sign in to comment.