Skip to content

Commit d35ed37

Browse files
committed
switch finished
1 parent 6269410 commit d35ed37

10 files changed

Lines changed: 243 additions & 92 deletions

include/ast_context.hpp

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -19,22 +19,22 @@ class Context : public std::enable_shared_from_this<Context>
1919
SymbolTable symbol_table_;
2020
static int label_counter_ ;
2121
std::string function_call_name_;
22-
std::string exit_label_;
22+
static std::string exit_label_;
2323
static FunctionTable function_table_;
24-
//reg stack not used
25-
RegStack reg_stack_;
24+
25+
2626
static LiteralTable literal_table_;
2727

2828

2929
// Private constructor to enforce shared_ptr management
30-
explicit Context(std::shared_ptr<Context> parent_context = nullptr, int offset = -20, RegStack reg_stack = RegStack())
31-
: parent_context_(std::move(parent_context)), symbol_table_(SymbolTable(offset)), reg_stack_(reg_stack) {}
30+
explicit Context(std::shared_ptr<Context> parent_context = nullptr, int offset = -20)
31+
: parent_context_(std::move(parent_context)), symbol_table_(SymbolTable(offset)) {}
3232

3333
public:
3434
// Factory function to ensure Context is always created as a shared_ptr
35-
static std::shared_ptr<Context> Create(std::shared_ptr<Context> parent_context = nullptr, int offset = -20, RegStack reg_stack = RegStack())
35+
static std::shared_ptr<Context> Create(std::shared_ptr<Context> parent_context = nullptr, int offset = -20)
3636
{
37-
return std::shared_ptr<Context>(new Context(std::move(parent_context), offset, reg_stack));
37+
return std::shared_ptr<Context>(new Context(std::move(parent_context), offset));
3838
}
3939

4040
// Adds a symbol to the current context.
@@ -50,8 +50,8 @@ class Context : public std::enable_shared_from_this<Context>
5050
std::shared_ptr<Context> CreateChildContext()
5151
{
5252
int offset = symbol_table_.GetOffset();
53-
RegStack reg_stack = reg_stack_;
54-
return Create(shared_from_this(), offset, reg_stack);
53+
return Create(shared_from_this(), offset);
54+
5555
}
5656

5757
// Searches for a symbol in the current context and then in parent contexts.
@@ -80,24 +80,24 @@ class Context : public std::enable_shared_from_this<Context>
8080
return exit_label_;
8181
}
8282

83-
void PushReg(std::ostream& stream, std::string reg, int offset) {
84-
reg_stack_.PushReg(reg, offset);
85-
stream << "addi sp, sp, -4" << std::endl;
86-
stream << "sw " << reg << ", 0(sp)" << std::endl;
83+
void PushReg(std::string reg, std::ostream& stream) {
84+
function_table_.PushReg(reg, stream);
85+
86+
8787
}
8888

89-
Reg PopReg(std::ostream& stream) {
90-
stream << "lw " << reg_stack_.TopReg().reg << ", 0(sp)" << std::endl;
91-
stream << "addi sp, sp, 4" << std::endl;
92-
return reg_stack_.PopReg();
89+
void PopReg(std::ostream& stream) {
90+
function_table_.PopReg(stream);
91+
92+
9393
}
9494

9595
void ExitRegStack(std::ostream& stream) {
96-
while (!reg_stack_.Empty()) {
97-
stream << "lw " << reg_stack_.TopReg().reg << ", 0(sp)" << std::endl;
98-
stream << "addi sp, sp, 4" << std::endl;
99-
reg_stack_.PopReg();
100-
}
96+
function_table_.ExitRegStack(stream);
97+
98+
99+
100+
101101
}
102102

103103
void AddFunction(const std::string& name, const TypeSpecifier& return_type, const std::vector<TypeSpecifier>& parameters, int is_pointer)

include/ast_function_table.hpp

Lines changed: 57 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,60 @@
11
#include "ast_type_specifier.hpp"
2+
#include "ast_reg_stack.hpp"
23

3-
namespace ast
4-
{
5-
6-
struct Function
7-
{
8-
std::string name;
9-
TypeSpecifier return_type;
10-
std::vector<TypeSpecifier> parameters;
11-
int is_pointer;
12-
};
13-
14-
class FunctionTable
15-
{
16-
private:
17-
std::unordered_map<std::string, Function> functions;
18-
std::string current_function;
19-
20-
public:
21-
void AddFunction(const std::string &name, const TypeSpecifier &return_type, const std::vector<TypeSpecifier> &parameters, int is_pointer)
22-
{
23-
functions[name] = Function{name, return_type, parameters, is_pointer};
24-
}
25-
26-
void SetCurrentFunction(const std::string &name)
27-
{
28-
current_function = name;
29-
}
30-
31-
const Function *GetCurrentFunction() const
32-
{
33-
return &functions.at(current_function);
34-
}
35-
36-
const Function *GetFunction(const std::string &name) const
37-
{
38-
return &functions.at(name);
39-
}
40-
41-
bool HasFunction(const std::string &name) const
42-
{
43-
return functions.find(name) != functions.end();
44-
}
45-
};
4+
namespace ast {
5+
6+
struct Function {
7+
std::string name;
8+
TypeSpecifier return_type;
9+
std::vector<TypeSpecifier> parameters;
10+
int is_pointer;
11+
RegStack reg_stack = RegStack();
12+
};
13+
14+
class FunctionTable {
15+
private:
16+
std::unordered_map<std::string, Function> functions;
17+
std::string current_function;
18+
19+
public:
20+
void AddFunction(const std::string& name, const TypeSpecifier& return_type, const std::vector<TypeSpecifier>& parameters, int is_pointer)
21+
{
22+
functions[name] = Function{name, return_type, parameters, is_pointer};
23+
}
24+
25+
void SetCurrentFunction(const std::string& name)
26+
{
27+
current_function = name;
28+
}
29+
30+
const Function* GetCurrentFunction() const
31+
{
32+
return &functions.at(current_function);
33+
}
34+
35+
const Function* GetFunction(const std::string& name) const
36+
{
37+
return &functions.at(name);
38+
}
39+
40+
bool HasFunction(const std::string& name) const
41+
{
42+
return functions.find(name) != functions.end();
43+
}
44+
45+
void PushReg(std::string reg, std::ostream& stream)
46+
{
47+
functions.at(current_function).reg_stack.PushReg(reg, stream);
48+
}
49+
50+
void PopReg(std::ostream& stream)
51+
{
52+
return functions.at(current_function).reg_stack.PopReg(stream);
53+
}
54+
55+
void ExitRegStack(std::ostream& stream)
56+
{
57+
functions.at(current_function).reg_stack.ExitRegStack(stream);
58+
}
59+
};
4660
} // namespace ast

include/ast_jump_statement.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,13 @@ class ReturnStatement : public Node
1616
void Print(std::ostream& stream) const override;
1717
};
1818

19+
class BreakStatement : public Node
20+
{
21+
public:
22+
BreakStatement() = default;
23+
24+
void EmitRISC(std::ostream& stream, std::shared_ptr<Context> context, std::string destReg, TypeSpecifier type) const override;
25+
void Print(std::ostream& stream) const override;
26+
};
27+
1928
} // namespace ast

include/ast_reg_stack.hpp

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
#pragma once
32

43
#include <stack>
@@ -14,17 +13,28 @@ struct Reg {
1413
class RegStack {
1514
private:
1615
std::stack<Reg> stack_;
16+
int offset_ = 0;
1717

1818
public:
19-
void PushReg(std::string reg, int offset) {
20-
Reg r = {reg, offset};
21-
stack_.push(r);
19+
20+
RegStack() : offset_(0) {}
21+
22+
void PushReg(std::string reg, std::ostream& stream) {
23+
Reg reg_struct = {reg, offset_};
24+
stack_.push(reg_struct);
25+
stream << "addi sp, sp, -4" << std::endl;
26+
stream << "sw " << reg << ", " << offset_ << "(sp)" << std::endl;
27+
offset_ -= 4;
2228
}
2329

24-
Reg PopReg() {
25-
Reg r = stack_.top();
30+
void PopReg(std::ostream& stream) {
31+
if (stack_.empty()) {
32+
return;
33+
}
34+
stream << "lw " << stack_.top().reg << ", " << stack_.top().offset << "(sp)" << std::endl;
35+
stream << "addi sp, sp, 4" << std::endl;
2636
stack_.pop();
27-
return r;
37+
offset_ += 4;
2838
}
2939

3040
bool Empty() {
@@ -34,6 +44,12 @@ class RegStack {
3444
Reg TopReg() {
3545
return stack_.top();
3646
}
47+
48+
void ExitRegStack(std::ostream& stream) {
49+
while (!stack_.empty()) {
50+
PopReg(stream);
51+
}
52+
}
3753
};
3854

3955
} // namespace ast

include/ast_selection_statement.hpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,36 @@ namespace ast {
1313
void EmitRISC(std::ostream& stream, std::shared_ptr<Context> context, std::string destReg, TypeSpecifier type) const override;
1414
void Print(std::ostream& stream) const override;
1515
};
16+
17+
class CaseStatement : public Node
18+
19+
{
20+
private:
21+
NodePtr condition_;
22+
NodePtr statement_;
23+
24+
public:
25+
CaseStatement(NodePtr condition, NodePtr statement) : condition_(std::move(condition)), statement_(std::move(statement)) {}
26+
27+
void EmitRISC(std::ostream& stream, std::shared_ptr<Context> context, std::string destReg, TypeSpecifier type) const override;
28+
void Print(std::ostream& stream) const override;
29+
};
30+
31+
class SwitchStatement : public Node
32+
33+
{
34+
private:
35+
NodePtr condition_;
36+
NodePtr case_statements_;
37+
38+
public:
39+
SwitchStatement(NodePtr condition, NodePtr case_statements) : condition_(std::move(condition)), case_statements_(std::move(case_statements)) {}
40+
41+
void EmitRISC(std::ostream& stream, std::shared_ptr<Context> context, std::string destReg, TypeSpecifier type) const override;
42+
void Print(std::ostream& stream) const override;
43+
44+
};
45+
46+
47+
1648
} // namespace ast

src/ast_context.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ namespace ast {
44
int Context::label_counter_ = 1;
55
FunctionTable Context::function_table_ = FunctionTable();
66
LiteralTable Context::literal_table_ = LiteralTable();
7+
std::string Context::exit_label_ = "exit";
78
int Context::AddSymbol(const std::string& name, const TypeSpecifier& type, int isPointer)
89
{
910
return symbol_table_.AddSymbol(name, type, isPointer);

src/ast_jump_statement.cpp

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ void ReturnStatement::EmitRISC(std::ostream& stream, std::shared_ptr<Context> co
1111
expression_->EmitRISC(stream, context, "a5", type);
1212
}
1313
stream << "mv a0,a5" << std::endl;
14-
//context->ExitRegStak(stream);
14+
context->ExitRegStack(stream);
1515
exit_scope(stream);
1616
stream << "ret" << std::endl;
1717
return;
@@ -23,7 +23,7 @@ void ReturnStatement::EmitRISC(std::ostream& stream, std::shared_ptr<Context> co
2323
expression_->EmitRISC(stream, context, "a5", type);
2424
}
2525
stream << "mv a0,a5" << std::endl;
26-
//context->ExitRegStack(stream);
26+
context->ExitRegStack(stream);
2727
exit_scope(stream);
2828
stream << "ret" << std::endl;
2929
}
@@ -34,7 +34,7 @@ void ReturnStatement::EmitRISC(std::ostream& stream, std::shared_ptr<Context> co
3434
expression_->EmitRISC(stream, context, "a5", type);
3535
}
3636
stream << "fmv.s fa0,fa5" << std::endl;
37-
//context->ExitRegStack(stream);
37+
context->ExitRegStack(stream);
3838
exit_scope(stream);
3939
stream << "ret" << std::endl;
4040
}
@@ -45,7 +45,7 @@ void ReturnStatement::EmitRISC(std::ostream& stream, std::shared_ptr<Context> co
4545
expression_->EmitRISC(stream, context, "a5", type);
4646
}
4747
stream << "fmv.d fa0,fa5" << std::endl;
48-
//context->ExitRegStack(stream);
48+
context->ExitRegStack(stream);
4949
exit_scope(stream);
5050
stream << "ret" << std::endl;
5151
}
@@ -56,13 +56,12 @@ void ReturnStatement::EmitRISC(std::ostream& stream, std::shared_ptr<Context> co
5656
expression_->EmitRISC(stream, context, "a5", type);
5757
}
5858
stream << "mv a0,a5" << std::endl;
59-
//context->ExitRegStack(stream);
59+
context->ExitRegStack(stream);
6060
exit_scope(stream);
6161
stream << "ret" << std::endl;
6262
}
6363
else if (type == TypeSpecifier::VOID)
6464
{
65-
6665
exit_scope(stream);
6766
stream << "ret" << std::endl;
6867
}
@@ -83,4 +82,16 @@ void ReturnStatement::Print(std::ostream& stream) const
8382
stream << ";" << std::endl;
8483
}
8584

85+
void BreakStatement::EmitRISC(std::ostream& stream, std::shared_ptr<Context> context, std::string, TypeSpecifier ) const
86+
{
87+
// Need to fix this will not work always
88+
context->ExitRegStack(stream);
89+
stream << "j " << context->GetExitLabel() << std::endl;
90+
}
91+
92+
void BreakStatement::Print(std::ostream& stream) const
93+
{
94+
stream << "break;" << std::endl;
95+
}
96+
8697
}

0 commit comments

Comments
 (0)