Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
9db091f
feat: implemented lexer
biqiboqi Oct 14, 2025
6acbc9b
build: add lexer subdirectory and link it to the ui library
bialger Oct 14, 2025
5b6738d
refactor: replace ui library with compiler_ui, update main function t…
bialger Oct 14, 2025
3054895
fix: clean up whitespace and formatting in StartCompilerConsoleUI fun…
bialger Oct 14, 2025
c883081
refactor: major code cleanup and restructuring
biqiboqi Oct 15, 2025
677d7de
Merge remote-tracking branch 'origin/lexer' into lexer
biqiboqi Oct 15, 2025
4c9cb55
fix: fixed compiler_ui_functions.cpp
biqiboqi Oct 15, 2025
b8c57ec
refactor: reorganize lexer handlers and include necessary headers for…
bialger Oct 15, 2025
52aac4d
refactor: optimize imports
biqiboqi Oct 15, 2025
d3b922a
refactor: add braces for constructions without them, return arguments…
biqiboqi Oct 15, 2025
85e4587
refactor: reformated to google codestyle
biqiboqi Oct 15, 2025
fc0ca1d
fix: fixed comments handling
biqiboqi Oct 16, 2025
615cd4c
refactor: apply consistent formatting and remove unnecessary line bre…
bialger Oct 16, 2025
25d9def
fix: add missing newline at end of main.cpp file
bialger Oct 16, 2025
1dbea0b
refactor: update StartCompilerConsoleUI to accept error output stream…
bialger Oct 16, 2025
3d61ecc
refactor: replace TokenType enum with string representation in lexer …
bialger Oct 16, 2025
d97ae41
refactor: update lexer token classes to use TokenPosition for line an…
bialger Oct 16, 2025
4547b24
refactor: add TokenPosition class for managing line and column tracki…
bialger Oct 16, 2025
c4e9acf
refactor: improve code formatting and consistency in lexer token classes
bialger Oct 16, 2025
84b093e
refactor: separate SourceCodeWrapper from Lexer and refactor other co…
bialger Oct 16, 2025
025bd76
fix: fixed NewlineHandler.cpp bug
biqiboqi Oct 16, 2025
ed744cf
fix: fixed :: operator
biqiboqi Oct 17, 2025
6a7f551
fix: fixed :: operator and : punct
biqiboqi Oct 17, 2025
7e0e974
refactor: fix codestyle
biqiboqi Oct 17, 2025
e5af702
feat: add nan and inf float handling, add in keyword
biqiboqi Oct 17, 2025
112b55c
fix: fixed # keywords
biqiboqi Oct 17, 2025
e2c11d8
fix: add continue and break keywords
biqiboqi Oct 17, 2025
182747a
fix: returned main and fixed codestyle
biqiboqi Oct 17, 2025
e444694
fix: changed long double to double, add xor keyword
biqiboqi Oct 19, 2025
e3f82b5
fix: changed long double to double, add xor keyword
biqiboqi Oct 19, 2025
7c6c9b8
feat: made keyword map static field
biqiboqi Oct 19, 2025
239b062
feat: made keyword map static field
biqiboqi Oct 19, 2025
893f9c1
fix: reversed condition in WhitespaceHandler.cpp
biqiboqi Oct 19, 2025
a3b223a
feat: add dor handler, fixed some char and string bugs, like handling…
biqiboqi Oct 19, 2025
6287d93
fix: add '\0' handling, removed xor keyword, fixed 1e3 and 1.3e3 hand…
biqiboqi Oct 20, 2025
9d0be54
test: tests for every lexem type and big program tests
cloalenka Oct 20, 2025
841ce2b
test: small fixes in small tests, added tests for comments, turned of…
cloalenka Oct 20, 2025
f3233fd
test: small clang-format fixes in small tests
cloalenka Oct 20, 2025
03dcc7a
Merge branch 'lexer' into lexer_tests
cloalenka Oct 20, 2025
ab8d208
fix: fix '\0' handling
biqiboqi Oct 20, 2025
9fd287b
Merge branch 'lexer' into lexer_tests
cloalenka Oct 20, 2025
1220ea0
fix: format for clang-tidy
cloalenka Oct 20, 2025
dd9add2
fix: changed one comment
cloalenka Oct 20, 2025
29739d6
Merge pull request #9 from Ovum-Programming-Language/lexer_tests
bialger Oct 20, 2025
d1d8506
feat: include additional standard headers in compiler UI and lexer files
bialger Oct 20, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bin/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
add_executable(${PROJECT_NAME} main.cpp)

target_link_libraries(${PROJECT_NAME} PUBLIC
ui
compiler_ui
)

target_include_directories(${PROJECT_NAME} PUBLIC ${PROJECT_SOURCE_DIR})
14 changes: 11 additions & 3 deletions bin/main.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
#include <iostream>

#include "lib/ui/ui_functions.hpp"
#include "lib/compiler_ui/compiler_ui_functions.hpp"

int main(int32_t argc, char** argv) {
std::vector<std::string> args = std::vector<std::string>(argv, argv + argc);
return StartConsoleUI(args, std::cout);
const std::string sample = R"ovum(
// demo
fun Main(args: StringArray): Int {
val count: Int = args.Length()
sys::Print("Args count: " + count.ToString())
return 0
}
)ovum";

return StartCompilerConsoleUI({"ovumc", sample}, std::cout, std::cerr);
}
2 changes: 1 addition & 1 deletion cmake/SetCompilerOptions.cmake
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

Expand Down
6 changes: 2 additions & 4 deletions lib/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
cmake_minimum_required(VERSION 3.12)

add_subdirectory(mylib)
add_subdirectory(ui)
add_subdirectory(lexer)
add_subdirectory(compiler_ui)
10 changes: 10 additions & 0 deletions lib/compiler_ui/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
add_library(compiler_ui STATIC
compiler_ui_functions.cpp
compiler_ui_functions.hpp
)

target_link_libraries(compiler_ui PUBLIC
lexer
)

target_include_directories(compiler_ui PUBLIC ${PROJECT_SOURCE_DIR})
28 changes: 28 additions & 0 deletions lib/compiler_ui/compiler_ui_functions.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#include "lib/lexer/Lexer.hpp"

#include <exception>

#include "compiler_ui_functions.hpp"

int32_t StartCompilerConsoleUI(const std::vector<std::string>& args, std::ostream& out, std::ostream& err) {
if (args.size() < 2) {
err << "Insufficient arguments\n";
return 1;
}

const std::string& sample = args[1];
Lexer lx(sample, true);

try {
auto toks = lx.Tokenize();

for (auto& t : toks) {
out << t->ToString() << "\n";
}
} catch (const std::exception& e) {
err << "Lexer error: " << e.what() << "\n";
return 1;
}

return 0;
}
11 changes: 11 additions & 0 deletions lib/compiler_ui/compiler_ui_functions.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#ifndef COMPILER_UI_FUNCTIONS_HPP_
#define COMPILER_UI_FUNCTIONS_HPP_

#include <cstdint>
#include <ostream>
#include <string>
#include <vector>

int32_t StartCompilerConsoleUI(const std::vector<std::string>& args, std::ostream& out, std::ostream& err);

#endif // COMPILER_UI_FUNCTIONS_HPP_
41 changes: 41 additions & 0 deletions lib/lexer/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
add_library(lexer STATIC
Lexer.cpp
SourceCodeWrapper.cpp
handlers/CharHandler.cpp
handlers/ColonHandler.cpp
handlers/DefaultHandler.cpp
handlers/DotCompositeHandler.cpp
handlers/IdentifierHandler.cpp
handlers/NewlineHandler.cpp
handlers/NumberHandler.cpp
handlers/OperatorHandler.cpp
handlers/PunctHandler.cpp
handlers/SlashHandler.cpp
handlers/StringHandler.cpp
handlers/WhitespaceHandler.cpp
tokens/CommentToken.cpp
tokens/EofToken.cpp
tokens/IdentToken.cpp
tokens/KeywordToken.cpp
tokens/LiteralToken.cpp
tokens/NewlineToken.cpp
tokens/OperatorToken.cpp
tokens/PunctToken.cpp
values/BoolValue.cpp
values/CharValue.cpp
values/FloatValue.cpp
values/IntValue.cpp
values/StringValue.cpp
tokens/TokenFactory.cpp
tokens/TokenPosition.cpp
)

target_include_directories(lexer
PUBLIC
${CMAKE_SOURCE_DIR}
)

target_include_directories(lexer
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
)
107 changes: 107 additions & 0 deletions lib/lexer/Lexer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
#include "Lexer.hpp"

#include <string>
#include <utility>

#include "handlers/CharHandler.hpp"
#include "handlers/ColonHandler.hpp"
#include "handlers/DefaultHandler.hpp"
#include "handlers/DotCompositeHandler.hpp"
#include "handlers/IdentifierHandler.hpp"
#include "handlers/NewlineHandler.hpp"
#include "handlers/NumberHandler.hpp"
#include "handlers/OperatorHandler.hpp"
#include "handlers/PunctHandler.hpp"
#include "handlers/SlashHandler.hpp"
#include "handlers/StringHandler.hpp"
#include "handlers/WhitespaceHandler.hpp"

#include "tokens/TokenFactory.hpp"

namespace {
constexpr const char* kOperatorChars = "+-*%<>=!&|^~?";
constexpr const char* kPunctChars = ",;(){}[]";
} // namespace

Lexer::Lexer(std::string_view src, bool keep_comments) :
wrapper_(src, keep_comments), handlers_(MakeDefaultHandlers()), default_handler_(MakeDefaultHandler()) {
}

std::vector<TokenPtr> Lexer::Tokenize() {
std::vector<TokenPtr> tokens;
tokens.reserve(kDefaultTokenReserve);

while (!wrapper_.IsAtEnd()) {
wrapper_.ResetTokenPosition();

char ch_read = wrapper_.Advance();
Handler* current_handler = handlers_.at(static_cast<unsigned char>(ch_read)).get();

if (!current_handler) {
current_handler = default_handler_.get();
}

OptToken maybe_token = current_handler->Scan(wrapper_);

if (maybe_token && *maybe_token) {
tokens.push_back(std::move(*maybe_token));
}
}

tokens.push_back(TokenFactory::MakeEof(wrapper_.GetLine(), wrapper_.GetCol()));
return tokens;
}

void Lexer::SetHandler(unsigned char ch, std::unique_ptr<Handler> handler) {
handlers_.at(ch) = std::move(handler);
}

void Lexer::SetDefaultHandler(std::unique_ptr<Handler> handler) {
default_handler_ = std::move(handler);
}

std::array<std::unique_ptr<Handler>, kDefaultTokenReserve> Lexer::MakeDefaultHandlers() {
std::array<std::unique_ptr<Handler>, kDefaultTokenReserve> table{};
table.at(static_cast<unsigned char>(' ')) = std::make_unique<WhitespaceHandler>();
table.at(static_cast<unsigned char>('\t')) = std::make_unique<WhitespaceHandler>();
table.at(static_cast<unsigned char>('\r')) = std::make_unique<WhitespaceHandler>();

table.at(static_cast<unsigned char>('\n')) = std::make_unique<NewlineHandler>();

for (unsigned char ch = 'a'; ch <= 'z'; ++ch) {
table.at(ch) = std::make_unique<IdentifierHandler>();
}

for (unsigned char ch = 'A'; ch <= 'Z'; ++ch) {
table.at(ch) = std::make_unique<IdentifierHandler>();
}

table.at(static_cast<unsigned char>('_')) = std::make_unique<IdentifierHandler>();
table.at(static_cast<unsigned char>('#')) = std::make_unique<IdentifierHandler>();

for (unsigned char digit = '0'; digit <= '9'; ++digit) {
table.at(digit) = std::make_unique<NumberHandler>();
}

table.at(static_cast<unsigned char>('.')) = std::make_unique<DotCompositeHandler>();

table.at(static_cast<unsigned char>('"')) = std::make_unique<StringHandler>();
table.at(static_cast<unsigned char>('\'')) = std::make_unique<CharHandler>();
table.at(static_cast<unsigned char>('/')) = std::make_unique<SlashHandler>();

table.at(static_cast<unsigned char>(':')) = std::make_unique<ColonHandler>();

for (const unsigned char ch : std::string(kOperatorChars)) {
table.at(ch) = std::make_unique<OperatorHandler>();
}

for (const unsigned char ch : std::string(kPunctChars)) {
table.at(ch) = std::make_unique<PunctHandler>();
}

return table;
}

std::unique_ptr<Handler> Lexer::MakeDefaultHandler() {
return std::make_unique<DefaultHandler>();
}
35 changes: 35 additions & 0 deletions lib/lexer/Lexer.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#ifndef LEXER_HPP_
#define LEXER_HPP_

#include <array>
#include <cstddef>
#include <memory>
#include <string_view>
#include <vector>

#include "SourceCodeWrapper.hpp"
#include "handlers/Handler.hpp"

constexpr std::size_t kDefaultTokenReserve = 256;

class Lexer {
public:
explicit Lexer(std::string_view src, bool keep_comments = false);

std::vector<TokenPtr> Tokenize();

void SetHandler(unsigned char ch, std::unique_ptr<Handler> handler);

void SetDefaultHandler(std::unique_ptr<Handler> handler);

private:
static std::array<std::unique_ptr<Handler>, kDefaultTokenReserve> MakeDefaultHandlers();

static std::unique_ptr<Handler> MakeDefaultHandler();

SourceCodeWrapper wrapper_;
std::array<std::unique_ptr<Handler>, kDefaultTokenReserve> handlers_{};
std::unique_ptr<Handler> default_handler_;
};

#endif // LEXER_HPP_
11 changes: 11 additions & 0 deletions lib/lexer/LexerError.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#ifndef LEXERERROR_HPP_
#define LEXERERROR_HPP_

#include <stdexcept>

class LexerError : public std::runtime_error {
public:
using std::runtime_error::runtime_error;
};

#endif // LEXERERROR_HPP_
Loading