Skip to content

Commit

Permalink
Fix ArrType IsEqual and rename variable, function
Browse files Browse the repository at this point in the history
  • Loading branch information
leewei05 authored and Lai-YT committed Apr 28, 2024
1 parent 83e309a commit 5a0850d
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 55 deletions.
13 changes: 6 additions & 7 deletions include/ast.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#ifndef AST_HPP_
#define AST_HPP_

#include <cstddef>
#include <memory>
#include <string>
#include <utility>
Expand Down Expand Up @@ -375,18 +374,18 @@ struct ArgExprNode : public ExprNode {
std::unique_ptr<ExprNode> arg;
};

// @brief An array subscripting expression.
/// @brief An array subscripting expression.
struct ArrSubExprNode : public ExprNode {
ArrSubExprNode(Location loc, std::unique_ptr<ExprNode> postfix_expr,
/// @param arr An expression that evaluates to the target array.
/// @param index An expression that evaluates to the subscription index.
ArrSubExprNode(Location loc, std::unique_ptr<ExprNode> arr,
std::unique_ptr<ExprNode> index)
: ExprNode{loc},
postfix_expr{std::move(postfix_expr)},
index{std::move(index)} {}
: ExprNode{loc}, arr{std::move(arr)}, index{std::move(index)} {}

void Accept(NonModifyingVisitor&) const override;
void Accept(ModifyingVisitor&) override;

std::unique_ptr<ExprNode> postfix_expr;
std::unique_ptr<ExprNode> arr;
std::unique_ptr<ExprNode> index;
};

Expand Down
23 changes: 12 additions & 11 deletions include/type.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ class Type {
/// @brief A convenience function to compare with a primitive type.
bool IsEqual(PrimitiveType that) const noexcept;

virtual std::size_t ToSize() const = 0;
// NOLINTNEXTLINE(readability-identifier-naming)
virtual std::size_t size() const = 0;
virtual std::string ToString() const = 0;
virtual std::unique_ptr<Type> Clone() const = 0;

Expand All @@ -57,7 +58,7 @@ class PrimType : public Type {
}

bool IsEqual(const Type& that) const noexcept override;
std::size_t ToSize() const override;
std::size_t size() const override;
std::string ToString() const override;
std::unique_ptr<Type> Clone() const override;

Expand All @@ -80,38 +81,38 @@ class PtrType : public Type {
}

bool IsEqual(const Type& that) const noexcept override;
std::size_t ToSize() const override;
std::size_t size() const override;
std::string ToString() const override;
std::unique_ptr<Type> Clone() const override;

private:
std::unique_ptr<Type> base_type_;
const std::size_t size_ = 8;
};

class ArrType : public Type {
public:
explicit ArrType(std::unique_ptr<Type> base_type, std::size_t len)
: base_type_{std::move(base_type)}, len_{len} {}
/// @param element_type The type of a single element in the array.
explicit ArrType(std::unique_ptr<Type> element_type, std::size_t len)
: element_type_{std::move(element_type)}, len_{len} {}

const Type& base_type() // NOLINT(readability-identifier-naming)
const Type& element_type() // NOLINT(readability-identifier-naming)
const noexcept {
return *base_type_;
return *element_type_;
}

bool IsArr() const noexcept override {
return true;
}

bool IsEqual(const Type& that) const noexcept override;
std::size_t ToSize() const override;
std::size_t size() const override;
std::string ToString() const override;
std::unique_ptr<Type> Clone() const override;

std::size_t GetLen() const;
std::size_t len() const; // NOLINT(readability-identifier-naming)

private:
std::unique_ptr<Type> base_type_;
std::unique_ptr<Type> element_type_;
std::size_t len_;
};

Expand Down
13 changes: 6 additions & 7 deletions src/ast_dumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,7 @@ void AstDumper::Visit(const DeclVarNode& decl) {

void AstDumper::Visit(const DeclArrNode& array_decl) {
std::cout << indenter_.Indent() << "DeclArrNode <" << array_decl.loc << "> "
<< array_decl.id << ": " << array_decl.type->ToString() << "["
<< array_decl.type->GetLen() << "]" << '\n';
<< array_decl.id << ": " << array_decl.type->ToString() << '\n';
}

void AstDumper::Visit(const ParamNode& parameter) {
Expand Down Expand Up @@ -256,12 +255,12 @@ void AstDumper::Visit(const ArgExprNode& arg_expr) {
indenter_.DecreaseLevel();
}

void AstDumper::Visit(const ArrSubExprNode& array_expr) {
std::cout << indenter_.Indent() << "ArrSubExprNode<" << array_expr.loc << "> "
<< array_expr.type->ToString() << '\n';
void AstDumper::Visit(const ArrSubExprNode& arr_sub_expr) {
std::cout << indenter_.Indent() << "ArrSubExprNode <" << arr_sub_expr.loc
<< "> " << arr_sub_expr.type->ToString() << '\n';
indenter_.IncreaseLevel();
array_expr.postfix_expr->Accept(*this);
array_expr.index->Accept(*this);
arr_sub_expr.arr->Accept(*this);
arr_sub_expr.index->Accept(*this);
indenter_.DecreaseLevel();
}

Expand Down
19 changes: 10 additions & 9 deletions src/qbe_ir_generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,8 @@ auto

void QbeIrGenerator::Visit(const DeclVarNode& decl) {
int id_num = NextLocalNum();
WriteInstr_("{} =l alloc{} {}", FuncScopeTemp{id_num}, decl.type->ToSize(),
decl.type->ToSize());
WriteInstr_("{} =l alloc{} {}", FuncScopeTemp{id_num}, decl.type->size(),
decl.type->size());
if (decl.init) {
decl.init->Accept(*this);
int init_num = num_recorder.NumOfPrevExpr();
Expand Down Expand Up @@ -153,9 +153,8 @@ void QbeIrGenerator::Visit(const DeclVarNode& decl) {

void QbeIrGenerator::Visit(const DeclArrNode& array_decl) {
int id_num = NextLocalNum();
std::size_t elem_size = array_decl.type->ToSize();
WriteInstr_("{} =l alloc{} {}", FuncScopeTemp{id_num}, elem_size,
elem_size * array_decl.type->GetLen());
WriteInstr_("{} =l alloc{} {}", FuncScopeTemp{id_num},
array_decl.type->element_type().size(), array_decl.type->size());
id_to_num[array_decl.id] = id_num;
}

Expand All @@ -176,7 +175,7 @@ void QbeIrGenerator::AllocMemForParams_(
int id_num = id_to_num.at(parameter->id);
int reg_num = NextLocalNum();
WriteInstr_("{} =l alloc{} {}", FuncScopeTemp{reg_num},
parameter->type->ToSize(), parameter->type->ToSize());
parameter->type->size(), parameter->type->size());
if (parameter->type->IsPtr()) {
WriteInstr_("storel {}, {}", FuncScopeTemp{id_num},
FuncScopeTemp{reg_num});
Expand Down Expand Up @@ -566,7 +565,7 @@ void QbeIrGenerator::Visit(const ArgExprNode& arg_expr) {
}

void QbeIrGenerator::Visit(const ArrSubExprNode& arr_sub_expr) {
arr_sub_expr.postfix_expr->Accept(*this);
arr_sub_expr.arr->Accept(*this);
const int reg_num = num_recorder.NumOfPrevExpr();
// address of the first element
const int base_addr = reg_num_to_id_num.at(reg_num);
Expand All @@ -578,10 +577,12 @@ void QbeIrGenerator::Visit(const ArrSubExprNode& arr_sub_expr) {
WriteInstr_("{} =l extsw {}", FuncScopeTemp{extended_num},
FuncScopeTemp{index_num});

// TODO: figure out what mul 4 means, I think it is related to word addressing
// offset = index number * element size
// e.g. int a[3]
// a[1]'s offset = 1 * 4 (int size)
const int offset = NextLocalNum();
WriteInstr_("{} =l mul {}, {}", FuncScopeTemp{offset},
FuncScopeTemp{extended_num}, 4);
FuncScopeTemp{extended_num}, arr_sub_expr.arr->type->size());

// res_addr = base_addr + offset
const int res_addr_num = NextLocalNum();
Expand Down
26 changes: 15 additions & 11 deletions src/type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ bool PrimType::IsEqual(const Type& that) const noexcept {
return false;
}

std::size_t PrimType::ToSize() const {
std::size_t PrimType::size() const {
switch (prim_type_) {
case PrimitiveType::kInt:
default:
Expand Down Expand Up @@ -43,8 +43,8 @@ bool PtrType::IsEqual(const Type& that) const noexcept {
return false;
}

std::size_t PtrType::ToSize() const {
return size_;
std::size_t PtrType::size() const {
return 8; // NOLINT(cppcoreguidelines-avoid-magic-numbers)
}

std::string PtrType::ToString() const {
Expand All @@ -57,25 +57,29 @@ std::unique_ptr<Type> PtrType::Clone() const {

bool ArrType::IsEqual(const Type& that) const noexcept {
if (const auto* that_arr = dynamic_cast<const ArrType*>(&that)) {
return that_arr->base_type_->IsEqual(*base_type_);
} else if (const auto* that_prim = dynamic_cast<const PrimType*>(&that)) {
return that_prim->IsEqual(*base_type_);
// For two array types to be compatible, both shall have compatible element
// types, and if both size specifiers are present, and are integer constant
// expressions, then both size specifiers shall have the same constant
// value.
return that_arr->element_type_->IsEqual(*element_type_) &&
that_arr->len_ == len_;
}
return false;
}

std::size_t ArrType::ToSize() const {
return base_type_->ToSize();
/// @note The size of an array is (size of base type) * (number of elements).
std::size_t ArrType::size() const {
return element_type_->size() * len_;
}

std::string ArrType::ToString() const {
return base_type_->ToString();
return element_type_->ToString() + "[" + std::to_string(len_) + "]";
}

std::unique_ptr<Type> ArrType::Clone() const {
return std::make_unique<ArrType>(base_type_->Clone(), len_);
return std::make_unique<ArrType>(element_type_->Clone(), len_);
}

std::size_t ArrType::GetLen() const {
std::size_t ArrType::len() const {
return len_;
}
7 changes: 5 additions & 2 deletions src/type_checker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -303,9 +303,12 @@ void TypeChecker::Visit(ArgExprNode& arg_expr) {
}

void TypeChecker::Visit(ArrSubExprNode& arr_sub_expr) {
arr_sub_expr.postfix_expr->Accept(*this);
arr_sub_expr.arr->Accept(*this);
arr_sub_expr.index->Accept(*this);
arr_sub_expr.type = arr_sub_expr.postfix_expr->type->Clone();
const auto* arr_type = dynamic_cast<ArrType*>((arr_sub_expr.arr->type).get());
assert(arr_type);
// arr_sub_expr should have the element type of the array.
arr_sub_expr.type = arr_type->element_type().Clone();
}

void TypeChecker::Visit(FuncCallExprNode& call_expr) {
Expand Down
16 changes: 8 additions & 8 deletions test/typecheck/array.exp
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,24 @@ ProgramNode <1:1>
DeclArrNode <2:7> a: int[3]
ExprStmtNode <4:3>
SimpleAssignmentExprNode <4:8> int
ArrSubExprNode<4:3> int
IdExprNode <4:3> a: int
ArrSubExprNode <4:3> int
IdExprNode <4:3> a: int[3]
IntConstExprNode <4:5> 0: int
IntConstExprNode <4:10> 1: int
ExprStmtNode <5:3>
SimpleAssignmentExprNode <5:8> int
ArrSubExprNode<5:3> int
IdExprNode <5:3> a: int
ArrSubExprNode <5:3> int
IdExprNode <5:3> a: int[3]
IntConstExprNode <5:5> 1: int
IntConstExprNode <5:10> 2: int
ExprStmtNode <6:3>
SimpleAssignmentExprNode <6:8> int
ArrSubExprNode<6:3> int
IdExprNode <6:3> a: int
ArrSubExprNode <6:3> int
IdExprNode <6:3> a: int[3]
IntConstExprNode <6:5> 2: int
BinaryExprNode <6:15> int +
ArrSubExprNode<6:10> int
IdExprNode <6:10> a: int
ArrSubExprNode <6:10> int
IdExprNode <6:10> a: int[3]
IntConstExprNode <6:12> 1: int
IntConstExprNode <6:17> 1: int
ReturnStmtNode <8:3>
Expand Down

0 comments on commit 5a0850d

Please sign in to comment.