Skip to content

Commit 5c4c7da

Browse files
committed
passing all test cases
1 parent a645c39 commit 5c4c7da

13 files changed

Lines changed: 247 additions & 27 deletions

include/ast.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,6 @@
2727
#include "ast_string.hpp"
2828
#include "ast_type_node.hpp"
2929
#include "ast_struct.hpp"
30+
#include "ast_enum.hpp"
31+
#include "ast_typedef.hpp"
3032
ast::NodePtr ParseAST(std::string file_name);

include/ast_context.hpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "ast_function_table.hpp"
1111
#include "ast_literals.hpp"
1212
#include "ast_struct_table.hpp"
13+
#include "ast_type_table.hpp"
1314

1415
namespace ast {
1516

@@ -26,11 +27,14 @@ class Context : public std::enable_shared_from_this<Context>
2627
StructTable struct_table_;
2728

2829

30+
2931
// Private constructor to enforce shared_ptr management
3032
explicit Context(std::shared_ptr<Context> parent_context = nullptr, int offset = -20, StructTable struct_table = StructTable())
3133
: parent_context_(std::move(parent_context)), symbol_table_(SymbolTable(offset)), struct_table_(struct_table) {}
3234

3335
public:
36+
static TypeTable type_table_;
37+
3438
// Factory function to ensure Context is always created as a shared_ptr
3539
static std::shared_ptr<Context> Create(std::shared_ptr<Context> parent_context = nullptr, int offset = -20, StructTable struct_table = StructTable())
3640
{
@@ -159,9 +163,24 @@ class Context : public std::enable_shared_from_this<Context>
159163
{
160164
return parent_context_->GetMember(struct_identifier, member_identifier);
161165
}
166+
}
162167

168+
TypeStruct GetType(const std::string& name) const
169+
{
170+
return type_table_.GetType(name);
171+
}
172+
173+
void AddType(const std::string& name, TypeSpecifier type, int size, int is_pointer)
174+
{
175+
type_table_.AddType(name, type, size, is_pointer);
176+
}
177+
178+
bool HasType(const std::string& name) const
179+
{
180+
return type_table_.HasType(name);
163181
}
164182

165183
~Context() = default;
166184
};
167-
}
185+
186+
} // namespace ast

include/ast_enum.hpp

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,33 @@
22

33
namespace ast {
44

5-
class EnumDeclare : public Node
6-
{
5+
class EnumMember : public Node {
6+
77
private:
8-
NodePtr identifier_;
9-
NodePtr enumerator_list_;
8+
std::string identifier_;
9+
NodePtr value_;
1010

1111
public:
12-
EnumDeclare(NodePtr identifier, NodePtr enumerator_list) : identifier_(std::move(identifier)), enumerator_list_(std::move(enumerator_list)){};
12+
EnumMember(const std::string &identifier, NodePtr value) : identifier_(identifier), value_(std::move(value)) {}
13+
void EmitRISC(std::ostream& stream, std::shared_ptr<Context> context, std::string destReg, TypeSpecifier type) const override;
14+
void Print(std::ostream& stream) const override;
15+
std::string GetIdentifier() const { return identifier_; }
16+
TypeSpecifier GetType(std::shared_ptr<Context> ) const override { return TypeSpecifier::INT; }
17+
int IsPointer(std::shared_ptr<Context> ) const override { return value_ ? 1 : 0; }
18+
std::variant<int, float, double> GetConst() const override { return value_ ? value_->GetConst() : 0; }
19+
};
1320

21+
class EnumSpecifier : public Node {
22+
private:
23+
std::string identifier_;
24+
NodePtr members_;
25+
public:
26+
EnumSpecifier(const std::string &identifier, NodePtr members) : identifier_(identifier), members_(std::move(members)) {}
1427
void EmitRISC(std::ostream& stream, std::shared_ptr<Context> context, std::string destReg, TypeSpecifier type) const override;
1528
void Print(std::ostream& stream) const override;
16-
std::string GetIdentifier() const { return identifier_->GetIdentifier(); }
17-
TypeSpecifier GetType(std::shared_ptr<Context> context) const { return TypeSpecifier::INT; }
29+
std::string GetIdentifier() const { return identifier_; }
30+
TypeSpecifier GetType(std::shared_ptr<Context> ) const override { return TypeSpecifier::INT; }
31+
int IsPointer(std::shared_ptr<Context> ) const override { return 0; }
1832
};
1933

2034
}// namespace ast

include/ast_type_specifier.hpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ enum class TypeSpecifier
1515
SIGNED,
1616
UNSIGNED,
1717
STRUCT,
18-
ENUM
18+
ENUM,
19+
TYPEDEF
1920
};
2021

2122
template<typename LogStream>
@@ -42,9 +43,13 @@ LogStream& operator<<(LogStream& ls, const TypeSpecifier& type)
4243
return "struct";
4344
case TypeSpecifier::ENUM:
4445
return "enum";
46+
case TypeSpecifier::TYPEDEF:
47+
return "typedef";
4548
}
4649
throw std::runtime_error("Unexpected type specifier");
4750
};
4851
return ls << TypeToString();
4952
}
53+
54+
5055
} // namespace ast

include/ast_type_table.hpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#pragma once
2+
3+
#include <string>
4+
#include <unordered_map>
5+
6+
namespace ast {
7+
8+
struct TypeStruct {
9+
std::string name;
10+
TypeSpecifier type;
11+
int size;
12+
int is_pointer;
13+
};
14+
15+
class TypeTable {
16+
private:
17+
std::unordered_map<std::string, TypeStruct> table;
18+
19+
public:
20+
TypeTable() {
21+
table["int"] = {"int", TypeSpecifier::INT, 4, 0};
22+
table["float"] = {"float", TypeSpecifier::FLOAT, 4, 0};
23+
table["double"] = {"double", TypeSpecifier::DOUBLE, 8, 0};
24+
table["char"] = {"char", TypeSpecifier::CHAR, 1, 0};
25+
table["void"] = {"void", TypeSpecifier::VOID, 0, 0};
26+
}
27+
28+
void AddType(std::string name, TypeSpecifier type, int size, int is_pointer) {
29+
table[name] = {name, type, size, is_pointer};
30+
}
31+
32+
TypeStruct GetType(std::string name) {
33+
if (table.find(name) == table.end()) {
34+
throw std::runtime_error("Type not found");
35+
}
36+
return table[name];
37+
}
38+
39+
bool HasType(std::string name) {
40+
return table.find(name) != table.end();
41+
}
42+
};
43+
}

include/ast_typedef.hpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#include "ast_node.hpp"
2+
3+
namespace ast {
4+
5+
class TypedefDeclare : public Node
6+
{
7+
private:
8+
NodePtr declaration_specifiers_;
9+
NodePtr declarator_;
10+
11+
public:
12+
TypedefDeclare(NodePtr declaration_specifiers, NodePtr declarator): declaration_specifiers_(std::move(declaration_specifiers)), declarator_(std::move(declarator)) {}
13+
void EmitRISC(std::ostream& stream, std::shared_ptr<Context> context, std::string destReg, TypeSpecifier type) const override;
14+
void Print(std::ostream& stream) const override;
15+
TypeSpecifier GetType(std::shared_ptr<Context> context) const override { return declaration_specifiers_->GetType(context); }
16+
std::string GetIdentifier() const { return declarator_->GetIdentifier(); }
17+
int IsPointer(std::shared_ptr<Context> context) const { return declarator_->IsPointer(context); }
18+
};
19+
20+
class TypeName : public Node
21+
{
22+
private:
23+
std::string identifier_;
24+
25+
public:
26+
TypeName(std::string identifier): identifier_(std::move(identifier)) {}
27+
void EmitRISC(std::ostream& , std::shared_ptr<Context> , std::string , TypeSpecifier ) const override {}
28+
void Print(std::ostream& stream) const override { stream << identifier_; }
29+
TypeSpecifier GetType(std::shared_ptr<Context> context) const override {
30+
return context->GetType(identifier_).type;
31+
}
32+
std::string GetIdentifier() const { return identifier_; }
33+
int IsPointer(std::shared_ptr<Context> context) const {
34+
return context->GetType(identifier_).is_pointer;
35+
}
36+
};
37+
38+
} // namespace ast

src/ast_context.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ namespace ast {
66
FunctionTable Context::function_table_ = FunctionTable();
77
LiteralTable Context::literal_table_ = LiteralTable();
88
std::string Context::exit_label_ = "exit";
9+
TypeTable Context::type_table_ = TypeTable();
910

1011
int Context::AddSymbol(const std::string& name, const TypeSpecifier& type, int isPointer, int size, std::string structIdentifier)
1112
{

src/ast_enum.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#include "ast_enum.hpp"
2+
3+
namespace ast {
4+
5+
void EnumMember::EmitRISC(std::ostream& stream, std::shared_ptr<Context> context, std::string destReg, TypeSpecifier type) const {
6+
(void)stream;
7+
(void)context;
8+
(void)destReg;
9+
(void)type;
10+
}
11+
12+
void EnumMember::Print(std::ostream& stream) const {
13+
stream << identifier_;
14+
if (value_) {
15+
stream << " = ";
16+
value_->Print(stream);
17+
}
18+
}
19+
20+
void EnumSpecifier::EmitRISC(std::ostream& , std::shared_ptr<Context> context, std::string , TypeSpecifier ) const {
21+
std::vector<Symbol> symbols = members_->GetSymbols(context);
22+
std::vector<std::variant<int, float, double>> consts = members_->GetConstList();
23+
int value = 0;
24+
for (size_t i = 0; i < symbols.size(); i++) {
25+
if (symbols[i].isPointer) {
26+
value = std::get<int>(consts[i]);
27+
}
28+
context->AddSymbol(symbols[i].name, TypeSpecifier::ENUM, value);
29+
value++;
30+
}
31+
}
32+
33+
void EnumSpecifier::Print(std::ostream& stream) const {
34+
stream << "enum " << identifier_ << " {";
35+
members_->Print(stream);
36+
stream << "}";
37+
}
38+
39+
}// namespace ast

src/ast_symbol_table.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@ namespace ast {
3737
table_[name] = {structIdentifier, type, offset_, -1, isPointer};
3838
return offset_;
3939
}
40+
else if (type == TypeSpecifier::ENUM)
41+
{
42+
// Lazy implementation, change it later
43+
table_[name] = {name, type, isPointer, -1, isPointer};
44+
return isPointer;
45+
}
4046
else
4147
{
4248
throw std::runtime_error("SymbolTable: TypeSpecifier not supported");

src/ast_typedef.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#include "ast_typedef.hpp"
2+
3+
namespace ast {
4+
5+
void TypedefDeclare::EmitRISC(std::ostream& , std::shared_ptr<Context> context, std::string , TypeSpecifier ) const
6+
{
7+
context->AddType(declarator_->GetIdentifier(), declaration_specifiers_->GetType(context), 0, declarator_->IsPointer(context));
8+
}
9+
10+
void TypedefDeclare::Print(std::ostream& stream) const
11+
{
12+
declaration_specifiers_->Print(stream);
13+
stream << " ";
14+
declarator_->Print(stream);
15+
stream << ";\n";
16+
}
17+
18+
} // namespace ast

0 commit comments

Comments
 (0)