diff --git a/compiler/compiler.cc b/compiler/compiler.cc index 4aca13f..6a487fd 100644 --- a/compiler/compiler.cc +++ b/compiler/compiler.cc @@ -1 +1,61 @@ -#include "compiler/compiler.h" \ No newline at end of file +// Copyright 2024 AQ authors, All Rights Reserved. +// This program is licensed under the AQ License. You can find the AQ license in +// the root directory. + +#include "compiler/compiler.h" + +#include +#include +#include +#include +#include +#include + +#include "debugger/debugger.h" +#include "compiler/lexer/lexer.h" +#include "compiler/lexer/token.h" + +namespace Aq { +Compiler::Compiler() = default; +Compiler::~Compiler() = default; + +int Compiler::CompileFile(const char* filename) { + // TODO: Waiting for improvements. + auto start = std::chrono::high_resolution_clock::now(); + std::ifstream file; + file.open(filename); + if (!file.is_open()) { + Aq::Debugger error_info(Aq::Debugger::Level::ERROR, "Aq::Main", + "Main_ReadFileError", "Can't open file.", nullptr); + return -1; + } + + std::vector code; + char ch; + while (file.get(ch)) { + code.push_back(ch); + } + code.push_back('\0'); + file.close(); + Lexer lexer(code.data(), code.size() - 1); + Token token; + while (true) { + int return_value = lexer.LexToken(token); + if (token.length == 0) { + std::cout << "END OF THE CODE."; + } else { + std::cout << std::string(token.location, token.length) << std::endl; + } + if (lexer.IsReadEnd()) { + break; + } + } + auto end = std::chrono::high_resolution_clock::now(); + auto duration_in_milliseconds = + std::chrono::duration_cast(end - start); + double duration_in_seconds = + static_cast(duration_in_milliseconds.count()) / 1000.0; + std::cout << "Execution time: " << duration_in_seconds << " seconds.\n"; + return 0; +} +} // namespace Aq \ No newline at end of file diff --git a/compiler/compiler.h b/compiler/compiler.h index ffba818..cc8ac1b 100644 --- a/compiler/compiler.h +++ b/compiler/compiler.h @@ -1,10 +1,26 @@ +// Copyright 2024 AQ authors, All Rights Reserved. +// This program is licensed under the AQ License. You can find the AQ license in +// the root directory. + #ifndef AQ_COMPILE_COMPILE_H_ #define AQ_COMPILE_COMPILE_H_ namespace Aq { -namespace Compiler { -extern int CompileFile(const char* filename); -} +class Compiler { + public: + Compiler(); + ~Compiler(); + + int CompileFile(const char* filename); + + private: + class Lexer; + struct Token; + template + class LexMap; + class TokenMap; + class Parser; +}; } // namespace Aq #endif // AQ_COMPILE_H_ \ No newline at end of file diff --git a/compiler/lexer/lex_map.h b/compiler/lexer/lex_map.h index 93c642c..887b425 100644 --- a/compiler/lexer/lex_map.h +++ b/compiler/lexer/lex_map.h @@ -9,14 +9,14 @@ #include #include +#include "compiler/compiler.h" #include "debugger/debugger.h" namespace Aq { -namespace Compiler { // A hash table for the lexer. Used to find special definitions such as compiler // keywords. template -class LexMap { +class Compiler::LexMap { public: // Construct a LexMap class, and the default hash table memory size is 1024. // Do not modify it unless necessary. @@ -196,7 +196,5 @@ class LexMap { return 0; }; }; -} // namespace Compiler } // namespace Aq - #endif \ No newline at end of file diff --git a/compiler/lexer/lexer.cc b/compiler/lexer/lexer.cc index 391873c..1e60174 100644 --- a/compiler/lexer/lexer.cc +++ b/compiler/lexer/lexer.cc @@ -6,12 +6,12 @@ #include +#include "compiler/compiler.h" #include "compiler/lexer/token.h" #include "debugger/debugger.h" namespace Aq { -namespace Compiler { -bool Lexer::IsReadEnd() const { +bool Compiler::Lexer::IsReadEnd() const { if (buffer_ptr_ >= buffer_end_) { return true; } else { @@ -19,7 +19,7 @@ bool Lexer::IsReadEnd() const { } } -int Lexer::LexToken(Token& return_token) { +int Compiler::Lexer::LexToken(Token& return_token) { // Set the return token type to start. return_token.type = Token::Type::START; @@ -415,5 +415,4 @@ int Lexer::LexToken(Token& return_token) { return 0; } } -} // namespace Compiler } // namespace Aq \ No newline at end of file diff --git a/compiler/lexer/lexer.h b/compiler/lexer/lexer.h index 8fbb22e..21347e8 100644 --- a/compiler/lexer/lexer.h +++ b/compiler/lexer/lexer.h @@ -7,11 +7,11 @@ #include +#include "compiler/compiler.h" #include "compiler/lexer/token.h" namespace Aq { -namespace Compiler { -class Lexer { +class Compiler::Lexer { public: // Initialize the Lexer class and store |source_code| to |buffer_ptr_|. Lexer(char* source_code, size_t length) @@ -35,7 +35,6 @@ class Lexer { char* buffer_end_; TokenMap token_map_; }; -} // namespace Compiler } // namespace Aq #endif \ No newline at end of file diff --git a/compiler/lexer/test.cc b/compiler/lexer/test.cc index ca11cc7..c41d858 100644 --- a/compiler/lexer/test.cc +++ b/compiler/lexer/test.cc @@ -2,63 +2,10 @@ // This program is licensed under the AQ License. You can find the AQ license in // the root directory. -#include -#include -#include -#include -#include -#include - -#include "aq/aq.h" -#include "compiler/lexer/lex_map.h" -#include "compiler/lexer/lexer.h" -#include "compiler/lexer/token.h" -#include "debugger/debugger.h" - -int LexerTest(int argc, char* argv[]) { - auto start = std::chrono::high_resolution_clock::now(); - std::ifstream file; - const char* filename = argv[1]; - file.open(filename); - if (!file.is_open()) { - Aq::Debugger error_info(Aq::Debugger::Level::ERROR, "Aq::Main", - "Main_ReadFileError", "Can't open file.", nullptr); - return -1; - } - - std::vector code; - char ch; - while (file.get(ch)) { - code.push_back(ch); - } - code.push_back('\0'); - file.close(); - Aq::Compiler::Lexer lexer(code.data(), code.size() - 1); - Aq::Compiler::Token token; - while (true) { - int return_value = lexer.LexToken(token); - if (token.length == 0) { - std::cout << "END OF THE CODE."; - } else { - std::cout << std::string(token.location, token.length) << std::endl; - } - if (lexer.IsReadEnd()) { - break; - } - } - auto end = std::chrono::high_resolution_clock::now(); - auto duration_in_milliseconds = - std::chrono::duration_cast(end - start); - double duration_in_seconds = - static_cast(duration_in_milliseconds.count()) / 1000.0; - std::cout << "Execution time: " << duration_in_seconds << " seconds.\n"; - return 0; -} - -int LexMapTest(int argc, char* argv[]) { return 0; } +#include "compiler/compiler.h" int main(int argc, char* argv[]) { - LexerTest(argc, argv); - LexMapTest(argc, argv); + Aq::Compiler compiler; + compiler.CompileFile(argv[1]); return 0; } diff --git a/compiler/lexer/token.cc b/compiler/lexer/token.cc index cca4cf4..fbe7b6f 100644 --- a/compiler/lexer/token.cc +++ b/compiler/lexer/token.cc @@ -4,13 +4,13 @@ #include "compiler/lexer/token.h" +#include "compiler/compiler.h" #include "compiler/lexer/lex_map.h" #include "debugger/debugger.h" namespace Aq { -namespace Compiler { -Token::Token() = default; -Token::~Token() { +Compiler::Token::Token() = default; +Compiler::Token::~Token() { if (type == Type::NUMBER) { delete[] value.Number; } else if (type == Type::IDENTIFIER) { @@ -22,7 +22,7 @@ Token::~Token() { } } -TokenMap::TokenMap() { +Compiler::TokenMap::TokenMap() { keyword_map.Insert("auto", Token::KeywordType::Auto); keyword_map.Insert("and", Token::KeywordType::And); keyword_map.Insert("bitand", Token::KeywordType::Bitand); @@ -143,13 +143,12 @@ TokenMap::TokenMap() { operator_map.Insert(">>>", Token::OperatorType::greatergreatergreater); operator_map.Insert("^^", Token::OperatorType::caretcaret); } -TokenMap::~TokenMap() = default; +Compiler::TokenMap::~TokenMap() = default; -Token::KeywordType TokenMap::GetKeywordValue(const char* keyword) { +Compiler::Token::KeywordType Compiler::TokenMap::GetKeywordValue(const char* keyword) { return keyword_map.Find(keyword); } -Token::OperatorType TokenMap::GetOperatorValue(const char* _operator) { +Compiler::Token::OperatorType Compiler::TokenMap::GetOperatorValue(const char* _operator) { return operator_map.Find(_operator); } -} // namespace Compiler } // namespace Aq \ No newline at end of file diff --git a/compiler/lexer/token.h b/compiler/lexer/token.h index 00a44a1..b19c657 100644 --- a/compiler/lexer/token.h +++ b/compiler/lexer/token.h @@ -5,11 +5,11 @@ #ifndef AQ_COMPILER_LEXER_TOKEN_H_ #define AQ_COMPILER_LEXER_TOKEN_H_ +#include "compiler/compiler.h" #include "compiler/lexer/lex_map.h" namespace Aq { -namespace Compiler { -struct Token { +struct Compiler::Token { enum class Type { START, KEYWORD, @@ -168,7 +168,7 @@ struct Token { Token& operator=(Token&&) noexcept = default; }; -class TokenMap { +class Compiler::TokenMap { public: TokenMap(); ~TokenMap(); @@ -185,7 +185,5 @@ class TokenMap { LexMap keyword_map; LexMap operator_map; }; - -} // namespace Compiler } // namespace Aq #endif \ No newline at end of file