Skip to content

Commit

Permalink
Optimize memory management, fix initialization logic in constructors,…
Browse files Browse the repository at this point in the history
… and add null pointer checks to prevent memory allocation failures.
  • Loading branch information
ax-6 committed Jan 11, 2025
1 parent c9dbaae commit 84c8fbd
Showing 1 changed file with 153 additions and 46 deletions.
199 changes: 153 additions & 46 deletions prototype/compiler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <cstdarg>
#include <cstddef>
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iostream>
Expand Down Expand Up @@ -38,6 +39,15 @@
#define _AQVM_OPERATOR_THROW 0x17
#define _AQVM_OPERATOR_WIDE 0xFF

inline void EXIT_COMPILER(const char* func_name, const char* message) {
std::cerr << func_name << ": " << message << std::endl;
exit(-1);
}

inline void DEBUG_OUTPUT(const char* func_name, const char* message) {
std::cerr << func_name << ": " << message << std::endl;
}

namespace Aq {
namespace Compiler {
// A hash table for the lexer. Used to find special definitions such as compiler
Expand Down Expand Up @@ -1500,6 +1510,8 @@ class Type {

private:
BaseType base_data_ = BaseType::NONE;

Type* CreateBaseType(Token* token, std::size_t length, std::size_t& index);
};

class StmtNode {
Expand Down Expand Up @@ -1799,11 +1811,14 @@ class ArrayNode : public UnaryNode {
op_ = Operator::ARRAY;
index_ = nullptr;
}
virtual ~ArrayNode() = default;

void SetArrayNode(ExprNode* expr, ExprNode* index) {
expr_ = expr;
index_ = index;
}
virtual ~ArrayNode() = default;

ExprNode* GetIndex() { return index_; }

ArrayNode(const ArrayNode&) = default;
ArrayNode& operator=(const ArrayNode&) = default;
Expand Down Expand Up @@ -2163,6 +2178,7 @@ class CastNode : public ExprNode {
};

ExprNode::operator std::string() {
// TODO
if (type_ == StmtType::kIdentifier)
return *dynamic_cast<IdentifierNode*>(this);
return std::string();
Expand Down Expand Up @@ -2271,155 +2287,246 @@ class ReferenceType : public Type {
};

Type* Type::CreateType(Token* token, std::size_t length, std::size_t& index) {
std::cout << "CreateType" << " \n" << token[index] << std::endl << std::endl;
Type* type = new Type();
DEBUG_OUTPUT("Type::CreateType(Token*,std::size_t,std::size_t&)",
"Enter the func.");

if (token == nullptr)
EXIT_COMPILER("Type::CreateType(Token*,std::size_t,std::size_t&)",
"token is nullptr.");
if (index >= length)
EXIT_COMPILER("Type::CreateType(Token*,std::size_t,std::size_t&)",
"index is out of range.");

Type* type = nullptr;
while (index < length) {
DEBUG_OUTPUT("Type::CreateType(Token*,std::size_t,std::size_t&)",
"Enter while loop.");

if (token[index].type == Token::Type::KEYWORD) {
DEBUG_OUTPUT("Type::CreateType(Token*,std::size_t,std::size_t&)",
"Enter if(token[index].type == Token::Type::KEYWORD).");

switch (token[index].value.keyword) {
case Token::KeywordType::Const: {
ConstType* const_type = new ConstType();
if (type->GetType() != Type::TypeType::NONE) {
const_type->SetSubType(type);
type = const_type;
break;
}
index++;
if (index < length && token[index].type == Token::Type::KEYWORD) {
if (const_type == nullptr)
EXIT_COMPILER("Type::CreateType(Token*,std::size_t,std::size_t&)",
"const_type is nullptr.");

if (index + 1 < length &&
token[index + 1].type == Token::Type::KEYWORD) {
DEBUG_OUTPUT("Type::CreateType(Token*,std::size_t,std::size_t&)",
"Enter if (index + 1 < length && token[index + "
"1].type == Token::Type::KEYWORD).");
index++;
switch (token[index].value.keyword) {
case Token::KeywordType::Void:
DEBUG_OUTPUT(
"Type::CreateType(Token*,std::size_t,std::size_t&)",
"Enter case Token::KeywordType::Void.");
type->SetType(Type::BaseType::kVoid);
break;
case Token::KeywordType::Bool:
DEBUG_OUTPUT(
"Type::CreateType(Token*,std::size_t,std::size_t&)",
"Enter case Token::KeywordType::Bool.");
type->SetType(Type::BaseType::kBool);
break;
case Token::KeywordType::Char:
DEBUG_OUTPUT(
"Type::CreateType(Token*,std::size_t,std::size_t&)",
"Enter case Token::KeywordType::Char.");
type->SetType(Type::BaseType::kChar);
break;
case Token::KeywordType::Short:
DEBUG_OUTPUT(
"Type::CreateType(Token*,std::size_t,std::size_t&)",
"Enter case Token::KeywordType::Short.");
type->SetType(Type::BaseType::kShort);
break;
case Token::KeywordType::Int:
DEBUG_OUTPUT(
"Type::CreateType(Token*,std::size_t,std::size_t&)",
"Enter case Token::KeywordType::Int.");
type->SetType(Type::BaseType::kInt);
break;
case Token::KeywordType::Long:
DEBUG_OUTPUT(
"Type::CreateType(Token*,std::size_t,std::size_t&)",
"Enter case Token::KeywordType::Long.");
type->SetType(Type::BaseType::kLong);
break;
case Token::KeywordType::Float:
DEBUG_OUTPUT(
"Type::CreateType(Token*,std::size_t,std::size_t&)",
"Enter case Token::KeywordType::Float.");
type->SetType(Type::BaseType::kFloat);
break;
case Token::KeywordType::Double:
DEBUG_OUTPUT(
"Type::CreateType(Token*,std::size_t,std::size_t&)",
"Enter case Token::KeywordType::Double.");
type->SetType(Type::BaseType::kDouble);
break;
case Token::KeywordType::Auto:
DEBUG_OUTPUT(
"Type::CreateType(Token*,std::size_t,std::size_t&)",
"Enter case Token::KeywordType::Auto.");
type->SetType(Type::BaseType::kAuto);
break;
default:
std::cout << "ReturnType" << " \n"
<< token[index] << std::endl
<< std::endl;
return type;
DEBUG_OUTPUT(
"Type::CreateType(Token*,std::size_t,std::size_t&)",
"Enter case default.");
break;
}
const_type->SetSubType(type);
type = const_type;
} else {
type->SetType(Type::BaseType::NONE);
std::cout << "ReturnType" << " \n"
<< token[index] << std::endl
<< std::endl;
return type;
}

if (type == nullptr)
EXIT_COMPILER("Type::CreateType(Token*,std::size_t,std::size_t&)",
"type is nullptr.");

const_type->SetSubType(type);
type = const_type;
break;
}
case Token::KeywordType::Void:
DEBUG_OUTPUT("Type::CreateType(Token*,std::size_t,std::size_t&)",
"Enter case Token::KeywordType::Void.");
type = new Type();
type->SetType(Type::BaseType::kVoid);
break;
case Token::KeywordType::Bool:
DEBUG_OUTPUT("Type::CreateType(Token*,std::size_t,std::size_t&)",
"Enter case Token::KeywordType::Bool.");
type = new Type();
type->SetType(Type::BaseType::kBool);
break;
case Token::KeywordType::Char:
DEBUG_OUTPUT("Type::CreateType(Token*,std::size_t,std::size_t&)",
"Enter case Token::KeywordType::Char.");
type = new Type();
type->SetType(Type::BaseType::kChar);
break;
case Token::KeywordType::Short:
DEBUG_OUTPUT("Type::CreateType(Token*,std::size_t,std::size_t&)",
"Enter case Token::KeywordType::Short.");
type = new Type();
type->SetType(Type::BaseType::kShort);
break;
case Token::KeywordType::Int:
DEBUG_OUTPUT("Type::CreateType(Token*,std::size_t,std::size_t&)",
"Enter case Token::KeywordType::Int.");
type = new Type();
type->SetType(Type::BaseType::kInt);
break;
case Token::KeywordType::Long:
DEBUG_OUTPUT("Type::CreateType(Token*,std::size_t,std::size_t&)",
"Enter case Token::KeywordType::Long.");
type = new Type();
type->SetType(Type::BaseType::kLong);
break;
case Token::KeywordType::Float:
DEBUG_OUTPUT("Type::CreateType(Token*,std::size_t,std::size_t&)",
"Enter case Token::KeywordType::Float.");
type = new Type();
type->SetType(Type::BaseType::kFloat);
break;
case Token::KeywordType::Double:
DEBUG_OUTPUT("Type::CreateType(Token*,std::size_t,std::size_t&)",
"Enter case Token::KeywordType::Double.");
type = new Type();
type->SetType(Type::BaseType::kDouble);
break;
case Token::KeywordType::Struct:
DEBUG_OUTPUT("Type::CreateType(Token*,std::size_t,std::size_t&)",
"Enter case Token::KeywordType::Struct.");
type = new Type();
type->SetType(Type::BaseType::kStruct);
std::cout << "ReturnType" << " \n"
<< token[index] << std::endl
<< std::endl;
return type;
case Token::KeywordType::Union:
DEBUG_OUTPUT("Type::CreateType(Token*,std::size_t,std::size_t&)",
"Enter case Token::KeywordType::Union.");
type = new Type();
type->SetType(Type::BaseType::kUnion);
std::cout << "ReturnType" << " \n"
<< token[index] << std::endl
<< std::endl;
return type;
case Token::KeywordType::Enum:
DEBUG_OUTPUT("Type::CreateType(Token*,std::size_t,std::size_t&)",
"Enter case Token::KeywordType::Enum.");
type = new Type();
type->SetType(Type::BaseType::kEnum);
std::cout << "ReturnType" << " \n"
<< token[index] << std::endl
<< std::endl;
return type;
case Token::KeywordType::Auto:
DEBUG_OUTPUT("Type::CreateType(Token*,std::size_t,std::size_t&)",
"Enter case Token::KeywordType::Auto.");
type = new Type();
type->SetType(Type::BaseType::kAuto);
break;
default:
std::cout << "ReturnType" << " \n"
<< token[index] << std::endl
<< std::endl;
return type;
}
} else if (token[index].type == Token::Type::OPERATOR) {
DEBUG_OUTPUT("Type::CreateType(Token*,std::size_t,std::size_t&)",
"Enter if(token[index].type == Token::Type::OPERATOR).");

if (type == nullptr)
EXIT_COMPILER("Type::CreateType(Token*,std::size_t,std::size_t&)",
"type is nullptr.");

switch (token[index].value._operator) {
case Token::OperatorType::star: {
DEBUG_OUTPUT("Type::CreateType(Token*,std::size_t,std::size_t&)",
"Enter case Token::OperatorType::star.");
PointerType* pointer_type = new PointerType();
pointer_type->SetSubType(type);
type = pointer_type;
break;
}

case Token::OperatorType::amp: {
DEBUG_OUTPUT("Type::CreateType(Token*,std::size_t,std::size_t&)",
"Enter case Token::OperatorType::amp.");
ReferenceType* reference_type = new ReferenceType();
reference_type->SetSubType(type);
type = reference_type;
break;
}

default:
std::cout << "ReturnType" << " \n"
<< token[index] << std::endl
<< std::endl;
DEBUG_OUTPUT("Type::CreateType(Token*,std::size_t,std::size_t&)",
"Enter case Token::OperatorType::default.");
return type;
}
} else if (token[index].type == Token::Type::IDENTIFIER) {
DEBUG_OUTPUT("Type::CreateType(Token*,std::size_t,std::size_t&)",
"Enter if(token[index].type == Token::Type::IDENTIFIER).");

std::size_t index_temp = index;
Parser::ParsePrimaryExpr(token, length, index_temp);
if (token[index_temp].type == Token::Type::OPERATOR &&
token[index_temp].value._operator == Token::OperatorType::l_square) {
ExprNode* temp_expr = Parser::ParsePrimaryExpr(token, length, index_temp);
if (temp_expr == nullptr)
EXIT_COMPILER("Type::CreateType(Token*,std::size_t,std::size_t&)",
"ParsePrimaryExpr return nullptr.");

if (temp_expr->GetType() == StmtNode::StmtType::kArray) {
DEBUG_OUTPUT(
"Type::CreateType(Token*,std::size_t,std::size_t&)",
"Enter if (temp_expr->GetType() == StmtNode::StmtType::kArray).");
ArrayType* array_type = new ArrayType();
array_type->SetSubType(type,
Parser::ParseExpr(token, length, index_temp));
dynamic_cast<ArrayNode*>(temp_expr)->GetIndex());
type = array_type;
}
std::cout << "ReturnType" << " \n"
<< token[index] << std::endl
<< std::endl;

// TODO: Add support of custom types.

return type;
}
index++;
}
std::cout << "ReturnType" << " \n" << token[index] << std::endl << std::endl;
return type;

EXIT_COMPILER("Type::CreateType(Token*,std::size_t,std::size_t&)",
"index is out of range.");
return nullptr;
}

Parser::Parser() = default;
Expand Down

0 comments on commit 84c8fbd

Please sign in to comment.