Skip to content

Commit 9fdfb46

Browse files
chore: add clang-format config, add CI code format checks
1 parent b6056cf commit 9fdfb46

23 files changed

+1113
-752
lines changed

.clang-format

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
---
2+
Language: Cpp
3+
Standard: c++20
4+
BasedOnStyle: LLVM
5+
6+
IndentWidth: 4
7+
TabWidth: 4
8+
NamespaceIndentation: All
9+
AccessModifierOffset: -4
10+
11+
ColumnLimit: 120
12+
13+
PenaltyReturnTypeOnItsOwnLine: 1000
14+
15+
BinPackParameters: false
16+
BinPackArguments: false
17+
AlignAfterOpenBracket: BlockIndent
18+
19+
AllowShortFunctionsOnASingleLine: None
20+
InsertBraces: true
21+
AllowShortLambdasOnASingleLine: Empty
22+
23+
BreakConstructorInitializers: AfterColon
24+
PackConstructorInitializers: CurrentLine
25+
26+
PointerAlignment: Left
27+
ReferenceAlignment: Left
28+
29+
SpaceAfterTemplateKeyword: false
30+
AlwaysBreakTemplateDeclarations: No
31+
32+
SortIncludes: Never
33+
34+
AlignTrailingComments:
35+
Kind: Always
36+
OverEmptyLines: 2

.github/workflows/ci.yml

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,10 +107,21 @@ jobs:
107107
alert-threshold: '150%'
108108
fail-on-alert: true
109109

110+
clang-format:
111+
name: Clang Format
112+
runs-on: ubuntu-latest
113+
if: github.event_name == 'pull_request'
114+
steps:
115+
- uses: actions/checkout@v4
116+
- name: Check formatting
117+
run: |
118+
find include tests -name "*.h" -o -name "*.cpp" | \
119+
xargs clang-format --dry-run --Werror
120+
110121
all-checks:
111122
name: All Checks
112123
runs-on: ubuntu-latest
113124
if: github.event_name == 'pull_request'
114-
needs: unittests
125+
needs: [unittests, clang-format]
115126
steps:
116127
- run: echo "All checks passed"

include/pvm/bytecode/bytecode.h

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,18 @@ namespace ngu::pvm {
2727
// - integral type → 1 byte
2828
// - bytecode<N> → N bytes (via ::capacity())
2929
// - raw array T[N] → N bytes
30-
template <typename T> consteval std::size_t contribution() {
30+
template<typename T> consteval std::size_t contribution() {
3131
using U = std::remove_cvref_t<T>;
32-
if constexpr (std::is_integral_v<U>)
32+
if constexpr (std::is_integral_v<U>) {
3333
return 1;
34-
else if constexpr (requires { U::capacity(); })
34+
} else if constexpr (requires { U::capacity(); }) {
3535
return U::capacity();
36-
else if constexpr (std::is_array_v<U>)
36+
} else if constexpr (std::is_array_v<U>) {
3737
return std::extent_v<U>;
38+
}
3839
return 0;
3940
}
40-
}
41+
} // namespace detail
4142

4243
/**
4344
* @brief Fixed-capacity compile-time byte buffer holding @p N bytes of bytecode.
@@ -49,15 +50,15 @@ namespace ngu::pvm {
4950
* - @c std::uint8_t - single byte; @n
5051
* - @c bytecode<M> - another bytecode buffer (contributes M bytes); @n
5152
* - raw array @c T[M] - contributes M bytes. @n
52-
* The deduction guide computes @p N as the sum of all argument contributions at compile time. @n
53-
* Array constructor - copies the first @c len bytes from a @c uint8_t[N] array.
53+
* The deduction guide computes @p N as the sum of all argument contributions at compile time.
54+
* @n Array constructor - copies the first @c len bytes from a @c uint8_t[N] array.
5455
*
5556
* @par Fields
5657
* @c bytes - raw byte storage. @n
5758
* @c length - number of bytes written; never exceeds @p N.
5859
*/
5960
template<std::size_t N> struct bytecode {
60-
template <typename... Args> consteval explicit bytecode(Args&&... args) {
61+
template<typename... Args> consteval explicit bytecode(Args&&... args) {
6162
(append(std::forward<Args>(args)), ...);
6263
}
6364

@@ -87,7 +88,7 @@ namespace ngu::pvm {
8788
}
8889
}
8990

90-
template <std::size_t M> consteval void append(std::uint8_t const (&arr)[M]) {
91+
template<std::size_t M> consteval void append(std::uint8_t const (&arr)[M]) {
9192
for (std::size_t i = 0; i < M && length < N; ++i) {
9293
bytes[length++] = arr[i];
9394
}
@@ -100,7 +101,7 @@ namespace ngu::pvm {
100101
}
101102
};
102103

103-
template <typename... Args> bytecode(Args&&... args) -> bytecode<(detail::contribution<Args>() + ...)>;
104-
}
104+
template<typename... Args> bytecode(Args&&... args) -> bytecode<(detail::contribution<Args>() + ...)>;
105+
} // namespace ngu::pvm
105106

106-
#endif //NGU_PVM_BYTECODE_BYTECODE_H
107+
#endif // NGU_PVM_BYTECODE_BYTECODE_H

include/pvm/bytecode/bytecode_decoder.h

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@
2828
namespace ngu::pvm {
2929
/// @brief Bytecode decoding mode.
3030
/// @c RUNTIME - stores only instruction offsets; used by the interpreter at runtime. @n
31-
/// @c COMPILE_TIME - additionally stores opcodes, immediates and metadata; builds a label table.
31+
/// @c COMPILE_TIME - additionally stores opcodes, immediates and metadata; builds a label
32+
/// table.
3233
enum decode_time { RUNTIME, COMPILE_TIME };
3334

3435
/**
@@ -64,8 +65,7 @@ namespace ngu::pvm {
6465
std::conditional_t<DecodeTime == COMPILE_TIME, extension_data_ct, empty> data_ct{};
6566
};
6667

67-
template<decode_time DecodeTime>
68-
using insn_entry = instruction_entry<DecodeTime>;
68+
template<decode_time DecodeTime> using insn_entry = instruction_entry<DecodeTime>;
6969

7070
using insn_entry_rt = insn_entry<RUNTIME>;
7171
using insn_entry_ct = insn_entry<COMPILE_TIME>;
@@ -74,7 +74,8 @@ namespace ngu::pvm {
7474
* @brief A single entry in the label table.
7575
*
7676
* @c label_id - label identifier (immediate value from @c OP_LABEL). @n
77-
* @c target_index - index of the next real instruction after the label (meta-instructions are not counted). @n
77+
* @c target_index - index of the next real instruction after the label (meta-instructions are
78+
* not counted). @n
7879
* @c target - pointer to the next instruction entry in the stream.
7980
*/
8081
struct label_entry {
@@ -84,14 +85,12 @@ namespace ngu::pvm {
8485
};
8586

8687
/// @brief View over the decoder instruction stream. @tparam DecodeTime Decoding mode.
87-
template<decode_time DecodeTime> class instruction_stream :
88-
public indexed_view<instruction_stream<DecodeTime>> {
88+
template<decode_time DecodeTime> class instruction_stream : public indexed_view<instruction_stream<DecodeTime>> {
8989
public:
9090
using value_type = instruction_entry<DecodeTime>;
9191

92-
constexpr instruction_stream(const value_type* data,
93-
const std::size_t count)
94-
: data_(data), count_(count) {}
92+
constexpr instruction_stream(const value_type* data, const std::size_t count) : data_(data), count_(count) {
93+
}
9594

9695
constexpr const value_type& at_impl(std::size_t i) const {
9796
return data_[i];
@@ -106,8 +105,7 @@ namespace ngu::pvm {
106105
std::size_t count_;
107106
};
108107

109-
template<decode_time DecodeTime>
110-
using insn_stream = instruction_stream<DecodeTime>;
108+
template<decode_time DecodeTime> using insn_stream = instruction_stream<DecodeTime>;
111109

112110
using insn_stream_rt = insn_stream<RUNTIME>;
113111
using insn_stream_ct = insn_stream<COMPILE_TIME>;
@@ -116,9 +114,8 @@ namespace ngu::pvm {
116114
struct label_table : public indexed_view<label_table> {
117115
using value_type = label_entry;
118116

119-
constexpr label_table(const value_type* data,
120-
const std::size_t count)
121-
: data_(data), count_(count) {}
117+
constexpr label_table(const value_type* data, const std::size_t count) : data_(data), count_(count) {
118+
}
122119

123120
constexpr const value_type& at_impl(std::size_t i) const {
124121
return data_[i];
@@ -146,9 +143,10 @@ namespace ngu::pvm {
146143
template<decode_time DecodeTime, std::size_t N> class bytecode_decoder {
147144
static constexpr std::size_t MAX_INSN = (N + 3) / 4; //(N + divisor - 1) / divisor
148145
public:
149-
constexpr explicit bytecode_decoder(const bytecode<N> &code);
146+
constexpr explicit bytecode_decoder(const bytecode<N>& code);
150147

151-
/// @brief Returns the instruction stream. @return @ref insn_stream for the given @c DecodeTime.
148+
/// @brief Returns the instruction stream. @return @ref insn_stream for the given @c
149+
/// DecodeTime.
152150
constexpr insn_stream<DecodeTime> get_instruction_stream() const {
153151
return insn_stream{insns_, insn_count_};
154152
}
@@ -169,10 +167,11 @@ namespace ngu::pvm {
169167
}
170168

171169
private:
172-
// Iterates over bytecode bytes and fills insns_[]. In COMPILE_TIME mode also extracts opcodes, immediates and meta flags.
170+
// Iterates over bytecode bytes and fills insns_[]. In COMPILE_TIME mode also extracts
171+
// opcodes, immediates and meta flags.
173172
constexpr void build_instruction_stream() {
174-
const std::uint8_t *pc{ code_.bytes };
175-
const std::uint8_t *end{ code_.bytes + code_.size() };
173+
const std::uint8_t* pc{code_.bytes};
174+
const std::uint8_t* end{code_.bytes + code_.size()};
176175
std::size_t index{};
177176

178177
while (pc < end && index < MAX_INSN) {
@@ -198,7 +197,8 @@ namespace ngu::pvm {
198197
insn_count_ = index;
199198
}
200199

201-
// Scans insns_[] for OP_LABEL entries and fills labels_[]. new_idx counts only real (non-meta) instructions.
200+
// Scans insns_[] for OP_LABEL entries and fills labels_[]. new_idx counts only real
201+
// (non-meta) instructions.
202202
constexpr void build_label_table() {
203203
std::uint64_t new_idx{};
204204
for (std::size_t i{}; i < insn_count_; ++i) {
@@ -208,8 +208,7 @@ namespace ngu::pvm {
208208
labels_[label_count_].target = &insns_[i + 1];
209209
labels_[label_count_].target_index = new_idx;
210210
++label_count_;
211-
}
212-
else {
211+
} else {
213212
++new_idx;
214213
}
215214
}
@@ -229,12 +228,13 @@ namespace ngu::pvm {
229228
return bytecode_decoder<DecodeTime, N>(code);
230229
}
231230

232-
template<decode_time DecodeTime, std::size_t N> constexpr bytecode_decoder<DecodeTime, N>::bytecode_decoder(const bytecode<N> &code) : code_(code) {
231+
template<decode_time DecodeTime, std::size_t N>
232+
constexpr bytecode_decoder<DecodeTime, N>::bytecode_decoder(const bytecode<N>& code) : code_(code) {
233233
build_instruction_stream();
234234
if constexpr (DecodeTime == COMPILE_TIME) {
235235
build_label_table();
236236
}
237237
}
238-
}
238+
} // namespace ngu::pvm
239239

240-
#endif //NGU_PVM_BYTECODE_BYTECODE_DECODER_H
240+
#endif // NGU_PVM_BYTECODE_BYTECODE_DECODER_H

include/pvm/bytecode/instruction_decoder.h

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ namespace ngu::pvm {
2525
* @brief Static utility set for extracting fields from a 32-bit instruction header.
2626
*
2727
* All methods accept a raw @c header and return the corresponding field
28-
* according to the format: @c OPCODE(0) | INSN_SIZE(8) | MODE(11) | DESTINATION(12) | SOURCE(16).
28+
* according to the format: @c OPCODE(0) | INSN_SIZE(8) | MODE(11) | DESTINATION(12) |
29+
* SOURCE(16).
2930
*/
3031
struct instruction_decoder {
3132
using bits = arch::insn_bits;
@@ -62,12 +63,11 @@ namespace ngu::pvm {
6263

6364
/// @brief Returns the total instruction size in bytes (header + immediate).
6465
static constexpr std::size_t total_size(const std::uint32_t header) {
65-
return detail::get_total_size(
66-
static_cast<arch::insn_size>(insn_size(header))
67-
);
66+
return detail::get_total_size(static_cast<arch::insn_size>(insn_size(header)));
6867
}
6968

70-
/// @brief Reads the immediate value from @p data (little-endian) after the header. Returns 0 if no immediate is present.
69+
/// @brief Reads the immediate value from @p data (little-endian) after the header. Returns
70+
/// 0 if no immediate is present.
7171
static constexpr std::uint64_t immediate(const std::uint32_t header, const std::uint8_t* data) {
7272
if (!has_immediate(header)) {
7373
return 0;
@@ -82,12 +82,11 @@ namespace ngu::pvm {
8282
return result;
8383
}
8484

85-
/// @brief Reads 4 bytes from @p data and assembles them into a 32-bit header (little-endian).
85+
/// @brief Reads 4 bytes from @p data and assembles them into a 32-bit header
86+
/// (little-endian).
8687
static constexpr std::uint32_t read_header(const std::uint8_t* data) {
87-
return static_cast<std::uint32_t>(data[0]) |
88-
(static_cast<std::uint32_t>(data[1]) << 8) |
89-
(static_cast<std::uint32_t>(data[2]) << 16) |
90-
(static_cast<std::uint32_t>(data[3]) << 24);
88+
return static_cast<std::uint32_t>(data[0]) | (static_cast<std::uint32_t>(data[1]) << 8) |
89+
(static_cast<std::uint32_t>(data[2]) << 16) | (static_cast<std::uint32_t>(data[3]) << 24);
9190
}
9291
};
9392

@@ -102,10 +101,12 @@ namespace ngu::pvm {
102101
*/
103102
class instruction_view {
104103
public:
105-
explicit instruction_view(const std::uint32_t* ptr = nullptr) : ip_(ptr) {}
104+
explicit instruction_view(const std::uint32_t* ptr = nullptr) : ip_(ptr) {
105+
}
106106

107-
bool valid() const { return ip_ != nullptr; }
108-
std::uint32_t data() const { return valid() ? *ip_ : 0; }
107+
std::uint32_t data() const {
108+
return valid() ? *ip_ : 0;
109+
}
109110

110111
std::uint8_t opcode() const {
111112
return insn_decoder::opcode(data());
@@ -131,20 +132,23 @@ namespace ngu::pvm {
131132
return insn_decoder::has_immediate(data());
132133
}
133134

135+
std::uint64_t immediate() const {
136+
return valid() ? insn_decoder::immediate(data(), reinterpret_cast<const std::uint8_t*>(ip_ + 1)) : 0;
137+
}
138+
134139
std::size_t size() const {
135140
return insn_decoder::total_size(data());
136141
}
137142

138-
std::uint64_t immediate() const {
139-
return valid() ? insn_decoder::immediate(data(),
140-
reinterpret_cast<const std::uint8_t*>(ip_ + 1)) : 0;
143+
bool valid() const {
144+
return ip_ != nullptr;
141145
}
142146

143147
private:
144148
const std::uint32_t* ip_{};
145149
};
146150

147151
using insn_view = instruction_view;
148-
}
152+
} // namespace ngu::pvm
149153

150-
#endif //NGU_PVM_BYTECODE_INSTRUCTION_DECODER_H
154+
#endif // NGU_PVM_BYTECODE_INSTRUCTION_DECODER_H

0 commit comments

Comments
 (0)