Skip to content
This repository was archived by the owner on Oct 12, 2026. It is now read-only.

Commit 88bdded

Browse files
committed
REFACTOR: Improve source module robustness.
Ref #1
1 parent c87a95c commit 88bdded

14 files changed

Lines changed: 128 additions & 54 deletions

File tree

‎CMakeLists.txt‎

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ target_include_directories(lbdSource PUBLIC
6464
${PROJECT_SOURCE_DIR}/include
6565
)
6666

67+
target_link_libraries(lbdSource PUBLIC
68+
fmt::fmt
69+
)
70+
6771
###### DIAGNOSTICS ######
6872

6973
file(GLOB_RECURSE DIAGNOSTICS_SOURCE_FILES CONFIGURE_DEPENDS
@@ -83,7 +87,6 @@ target_link_libraries(lbdDiagnostics PUBLIC
8387
fmt::fmt
8488
)
8589

86-
8790
###### TYPE ######
8891

8992
file(GLOB_RECURSE TYPE_SOURCE_FILES CONFIGURE_DEPENDS
@@ -178,7 +181,3 @@ enable_warnings(lbd)
178181
###### TESTS ######
179182

180183
enable_testing()
181-
182-
# add_executable(lexer_test tests/lexer_test.cc)
183-
# target_link_libraries(lexer_test PRIVATE lbdFrontend)
184-
# add_test(NAME lexer_test COMMAND lexer_test)

‎include/lbd/Error.hpp‎

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#pragma once
22

33
#include <cassert>
4+
#include <stdexcept>
45

56
template<typename>
67
inline constexpr bool alwaysFalseValue = false;
@@ -25,4 +26,25 @@ inline constexpr bool alwaysFalseValue = false;
2526
#define UNREACHABLE_OP ((void)0)
2627
#endif
2728

28-
#define UNREACHABLE(MSG) (assert(false && (MSG)), UNREACHABLE_OP)
29+
#define UNREACHABLE(MSG) (assert(false && (MSG)), UNREACHABLE_OP)
30+
31+
namespace lbd
32+
{
33+
class RuntimeError : public std::runtime_error
34+
{
35+
public:
36+
using std::runtime_error::runtime_error;
37+
};
38+
39+
class FileSystemError final : public RuntimeError
40+
{
41+
public:
42+
using RuntimeError::RuntimeError;
43+
};
44+
45+
class IOError final : public RuntimeError
46+
{
47+
public:
48+
using RuntimeError::RuntimeError;
49+
};
50+
}

‎include/lbd/Logger.hpp‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
#pragma once
22

3+
#include <iostream>
34
#include <lbd/Exceptions.hpp>
4-
#include <lbd/source/Range.hpp>
55
#include <lbd/utils/terminal/Colors.hpp>
66
#include <lbd/utils/terminal/Terminal.hpp>
77

8+
// TODO: Remove logger.
9+
810
namespace lbd
911
{
1012
struct Logger

‎include/lbd/diagnostics/DiagnosticEmitter.hpp‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ namespace lbd::diagnostics
2121

2222
void popContext();
2323

24+
/// NOTE: Use this only to report errors caused by external systems (e.g. filesystem or I/O), not by language diagnostics.
25+
[[noreturn]] void error(const source::Range &range, const std::string &message) const noexcept;
26+
2427
template<typename... Args>
2528
[[noreturn]] void error(const source::Range &range, const DiagnosticId id, Args &&... args)
2629
{
@@ -41,8 +44,10 @@ namespace lbd::diagnostics
4144
void emit(Severity severity, DiagnosticId id, const source::Range &range,
4245
const fmt::dynamic_format_arg_store<fmt::format_context> &arguments) const;
4346

47+
void emit(Severity severity, const source::Range &range, const std::string &message) const noexcept;
48+
4449
private:
4550
DiagnosticRenderer &diagnosticRenderer;
4651
std::vector<ContextFrame> contextStack;
4752
};
48-
}
53+
}

‎include/lbd/source/BufferManager.hpp‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ namespace lbd::source
1111
{
1212
public:
1313
// Create Buffers.
14-
[[nodiscard]] BufferId loadFile(const std::string &path) noexcept;
14+
[[nodiscard]] BufferId loadFile(const std::string &path);
1515

1616
[[nodiscard]] BufferId createBuffer(std::string name, std::string contents) noexcept;
1717

@@ -37,7 +37,7 @@ namespace lbd::source
3737
[[nodiscard]] std::string_view getLine(BufferId id, Offset offset) const noexcept;
3838

3939
// Optional utilities.
40-
[[nodiscard]] bool isBufferLoaded(const std::string &name) const noexcept;
40+
[[nodiscard]] bool isBufferLoaded(const std::string &name) const;
4141

4242
private:
4343
[[nodiscard]] BufferId addBuffer(std::string name, std::string contents) noexcept;
@@ -46,5 +46,5 @@ namespace lbd::source
4646
std::unordered_map<std::string, BufferId> m_bufferToIdMap;
4747
};
4848

49-
[[nodiscard]] std::string getAbsolutePath(const std::string &path) noexcept;
49+
[[nodiscard]] std::string getAbsolutePath(const std::string &path);
5050
}

‎include/lbd/source/Location.hpp‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@ namespace lbd::source
1313
BufferId bufferId;
1414
Offset offset;
1515
};
16-
}
16+
}

‎include/lbd/source/Range.hpp‎

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,27 @@
11
#pragma once
22

3-
#include <iostream>
3+
#include <ostream>
44
#include <lbd/source/Location.hpp>
55

66
namespace lbd::source
77
{
8-
struct Range
8+
class Range
99
{
10-
Location begin;
11-
Location end;
12-
10+
public:
1311
[[nodiscard]] Range(Location begin, Location end) noexcept;
1412

15-
// For debugging.
16-
[[nodiscard]] explicit Range(Location location) noexcept;
17-
13+
// TODO: Refactor diagnostics to support an optional source range, allowing this constructor to be removed.
14+
[[deprecated("Temporary constructor. Diagnostics will be refactored to support an optional source range.")]]
1815
[[nodiscard]] Range() noexcept;
1916

17+
[[nodiscard]] Location getBegin() const noexcept { return m_begin; }
18+
19+
[[nodiscard]] Location getEnd() const noexcept { return m_end; }
20+
2021
friend std::ostream &operator<<(std::ostream &outputStream, const Range &range);
22+
23+
private:
24+
Location m_begin;
25+
Location m_end;
2126
};
22-
}
27+
}

‎src/Context.cpp‎

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include <filesystem>
22
#include <lbd/Context.hpp>
3+
#include <lbd/Error.hpp>
34

45
namespace lbd
56
{
@@ -17,13 +18,20 @@ namespace lbd
1718

1819
source::BufferId Context::loadFile(const std::string &path, const source::Range &range)
1920
{
20-
if (!std::filesystem::exists(source::getAbsolutePath(path)))
21+
if (!std::filesystem::exists(path))
2122
{
2223
diagnosticEmitter.error(
2324
range,
2425
diagnostics::DiagnosticId::IO_PATH_DOES_NOT_EXISTS, path
2526
);
2627
}
27-
return bufferManager.loadFile(path);
28+
29+
try
30+
{
31+
return bufferManager.loadFile(path);
32+
} catch (const RuntimeError &e)
33+
{
34+
diagnosticEmitter.error(range, e.what());
35+
}
2836
}
29-
}
37+
}

‎src/REPL.cpp‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ namespace lbd::repl
2424
const std::string &path = argument;
2525

2626
// TODO: Should an already loaded file be loaded again. Current logic does not permit that.
27-
const source::BufferId bufferId = context.loadFile(path, {});
27+
const source::BufferId bufferId = context.loadFile(path, source::Range());
2828
const source::Buffer buffer = context.getBufferManager().getBuffer(bufferId);
2929
frontend::lexer::Lexer lexer(context, buffer);
3030

@@ -284,4 +284,4 @@ namespace lbd::repl
284284

285285
rx.history_save(LBD_HISTORY);
286286
}
287-
}
287+
}

‎src/diagnostics/DiagnosticEmitter.cpp‎

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,23 @@ namespace lbd::diagnostics
1313

1414
void DiagnosticEmitter::popContext() { contextStack.pop_back(); }
1515

16+
void DiagnosticEmitter::error(const source::Range &range, const std::string &message) const noexcept
17+
{
18+
emit(Severity::ERR, range, message);
19+
}
20+
1621
void DiagnosticEmitter::emit(const Severity severity, const DiagnosticId id, const source::Range &range,
1722
const fmt::dynamic_format_arg_store<fmt::format_context> &arguments) const
1823
{
1924
const std::string message = fmt::vformat(getDiagnosticInfo(id).message, arguments);
25+
emit(severity, range, message);
26+
}
27+
28+
void DiagnosticEmitter::emit(const Severity severity, const source::Range &range,
29+
const std::string &message) const noexcept
30+
{
2031
const Diagnostic diagnostic(severity, range, message, contextStack);
2132
diagnosticRenderer.render(diagnostic);
2233
if (severity == Severity::ERR) std::exit(EXIT_FAILURE);
2334
}
24-
}
35+
}

0 commit comments

Comments
 (0)