Skip to content

Commit

Permalink
feat(dto-compiler): Implement the handling of simple size_t literals
Browse files Browse the repository at this point in the history
  • Loading branch information
whisperity committed Oct 23, 2023
1 parent 1ce5e90 commit de95ceb
Show file tree
Hide file tree
Showing 19 changed files with 906 additions and 136 deletions.
2 changes: 1 addition & 1 deletion .clang-tidy
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Last checked against Clang-Tidy 17.0.0
# Last checked against Clang-Tidy 16.0.2

# There **MUST** be an explicit newline between comments in the Checks: string
# and the actual contents that should be part of the string!
Expand Down
8 changes: 5 additions & 3 deletions src/implementation/Monomux.dto
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ namespace monomux::message
literal ui64 APIMajor = 1;
literal ui64 APIMinor = 0;

namespace inner
{
literal ui64 APIMajor = 3;
}

function ClientID() -> {ui64 ID;
ui64 Nonce;
}
Expand All @@ -42,6 +47,3 @@ record ProcessSpawnOptions {
};

} //! namespace monomux::message

namespace a::b::c {}
namespace a::b::c {}
3 changes: 3 additions & 0 deletions tools/dto_compiler/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@ add_executable(dto_compiler
DTOCompiler.cpp

dto_unit.cpp
generator.cpp
lexer.cpp
parser.cpp

ast/decl.cpp
ast/dump.cpp
ast/type.cpp
)
if (NOT MONOMUX_LIBRARY_TYPE STREQUAL "UNITY")
target_link_libraries(dto_compiler PUBLIC
Expand Down
27 changes: 22 additions & 5 deletions tools/dto_compiler/DTOCompiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <string_view>

#include "dto_unit.hpp"
#include "generator.hpp"
#include "lexer.hpp"
#include "parser.hpp"

Expand Down Expand Up @@ -56,14 +57,18 @@ int main(int ArgC, char* ArgV[])
InputBuffer = Buf.str();
}

std::cout << "Input string:\n" << InputBuffer << std::endl;
// std::cout << "Input string:\n" << InputBuffer << std::endl;

using namespace monomux::tools::dto_compiler;

lexer L{InputBuffer};
parser P{L};
bool Success = P.parse();
std::cout << P.get_unit().dump().str() << std::endl;
std::cout << [&P] {
std::ostringstream OS;
P.get_unit().dump(OS);
return OS.str();
}() << std::endl;

if (!Success)
{
Expand All @@ -83,8 +88,20 @@ int main(int ArgC, char* ArgV[])
Line.remove_prefix(LinePos);
return Line.substr(0, Line.find('\n'));
}();
std::cerr << " " << ErrorLine << std::endl;
std::cerr << " " << std::string(P.get_error().Location.Column - 1, ' ')
<< '^' << std::endl;
std::string LineNumber = std::to_string(P.get_error().Location.Line);
std::cerr << " " << LineNumber << " | " << ErrorLine << std::endl;
std::cerr << " " << std::string(LineNumber.size(), ' ') << " | "
<< std::string(P.get_error().Location.Column - 1, ' ') << '^'
<< std::endl;
std::cerr << std::endl;
}

std::ostringstream Header, Source; // NOLINT(readability-isolate-declaration)
generator G{std::move(P).take_unit(), Header, Source};
G.generate();

std::cout << "GENERATED CODE:\n\n";
std::cout << Header.str() << '\n';
// std::cout << "/* * * * * -----<8 ----- 8>----- * * * * */\n\n";
// std::cout << Source.str() << '\n';
}
27 changes: 26 additions & 1 deletion tools/dto_compiler/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ Format of the DTO DSL
The communication protocol's specification must be made available as a **single** text file, commonly with the `.dto` extension.
As a rule of thumb, the usual semantics and guidelines of C++ translation apply: things should be defined top to bottom, i.e., before using an entity, its definition **_MUST_** already have been made available.

### Identifiers

Any character sequence that is not matching to an explicitly defined meaning in this document is an _identifier_.
Identifiers carry no meaning during compilation, and are translated verbatim into the generated output code.

### Comments

```
Expand Down Expand Up @@ -66,7 +71,7 @@ namespace MyProgram::Communication
}
```

Entities in the DTO DSL and the resulting C++ source code may be enclosed into `namespace`s.
Entities in the DTO DSL and the resulting C++ source code may be enclosed into **`namespace`**s.
The semantics adhere to how the language feature works in C++.

A namespace's name **_MUST_** be a pure identifier, or a sequence of identifiers concatenated by the "scope operator" `::`.
Expand All @@ -84,6 +89,26 @@ It is **_NOT RECOMMENDED_** to reuse the same identifier for multiple declaratio

### Types

The following types are available.

- Integer types of fixed bit width: `ui64`.

#### Record types

### Literals

Integer literals are expressed as a sequence of decimal characters `0`, `1`, `2`, …, `9`.
Integer literals can be negative, in case they are prefixed with a `-`.

These expressions appear as the initialising values of constants.

### Constants

```
literal ui64 Version = 1;
```

Constants are introduced with the **`literal`** keyword, followed by the [type](#types) of the constant, followed by its [identifier (name)](#identifiers) and an [initialising value](#literals).
Constants are translated to the generated code as compile-time constant objects.

### Functions
2 changes: 1 addition & 1 deletion tools/dto_compiler/Tokens.inc.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
#endif /* SYMBOL_TOKEN */

#ifndef STR_SPELLING_TOKEN
#define STR_SPELLING_TOKEN(NAME, ...) SIMPLE_TOKEN(NAME)
#define STR_SPELLING_TOKEN(NAME, SPELLING) SIMPLE_TOKEN(NAME)
#endif /* STR_SPELLING_TOKEN */

#ifndef COMPLEX_TOKEN
Expand Down
102 changes: 27 additions & 75 deletions tools/dto_compiler/ast/decl.cpp
Original file line number Diff line number Diff line change
@@ -1,44 +1,33 @@
/* SPDX-License-Identifier: LGPL-3.0-only */
#include <algorithm>
#include <sstream>

#include "decl.hpp"

namespace monomux::tools::dto_compiler::ast
{

namespace
{

void print_ident(std::ostringstream& OS, std::size_t Indent)
const named_decl*
decl_context::lookup_in_current(std::string_view Identifier) const noexcept
{
if (Indent == 0)
OS << '.';

while (Indent > 1)
{
OS << "| ";
--Indent;
}
if (Indent == 1)
{
OS << "|- ";
}
auto It = std::find_if(
Children.begin(), Children.end(), [Identifier](const auto& NodeUniquePtr) {
if (const auto* ND = dynamic_cast<const named_decl*>(NodeUniquePtr.get()))
return ND->get_identifier() == Identifier;
return false;
});
return It != Children.end() ? dynamic_cast<const named_decl*>(It->get())
: nullptr;
}

} // namespace

[[nodiscard]] const decl*
const named_decl*
decl_context::lookup(std::string_view Identifier) const noexcept
{
auto LookupInChain = [](const decl_context* C,
std::string_view I) -> const named_decl* {
for (C = &C->first_in_chain(); C != nullptr; C = C->next())
{
if (const auto* FoundChild =
dynamic_cast<const named_decl*>(C->lookup_in_current(I)))
for (C = &C->first_in_chain(); C; C = C->next())
if (const auto* FoundChild = C->lookup_in_current(I))
return FoundChild;
}

return nullptr;
};

Expand All @@ -63,61 +52,24 @@ decl_context::lookup(std::string_view Identifier) const noexcept
return nullptr;
}

[[nodiscard]] const decl*
decl_context::lookup_in_current(std::string_view Identifier) const noexcept
const named_decl*
decl_context::lookup_with_parents(std::string_view Identifier) const noexcept
{
for (const auto& NodeUPtr : Children)
{
if (const auto* ND = dynamic_cast<const named_decl*>(NodeUPtr.get());
ND && ND->get_identifier() == Identifier)
return ND;
}
const auto* D = lookup(Identifier);
if (D)
return D;
if (parent())
return parent()->lookup_with_parents(Identifier);
return nullptr;
}

void decl_context::dump_children(std::ostringstream& OS,
std::size_t Depth) const
const namespace_decl* namespace_decl::get_outermost_namespace() const noexcept
{
// This should only print the *local* children as the dump is expected to be
// in-order transitive.
for (const auto& Child : Children)
{
print_ident(OS, Depth);
Child->dump(OS, Depth + 1);
}
if (!parent())
return this;
if (const auto* ParentNSD = dynamic_cast<const namespace_decl*>(parent()))
return ParentNSD->get_outermost_namespace();
return this;
}

#define MONOMUX_DECL_DUMP(TYPE) \
void TYPE::dump(std::ostringstream& OS, std::size_t Depth) const

MONOMUX_DECL_DUMP(decl) {}

MONOMUX_DECL_DUMP(comment_decl)
{
static constexpr std::size_t CommentPrintLength = 64;
OS << "CommentDecl " << this << ' ';
OS << (Comment.is_block_comment() ? "block " : "line ");
OS << Comment.get_comment().substr(0, CommentPrintLength);
OS << '\n';
}

MONOMUX_DECL_DUMP(named_decl) {}

MONOMUX_DECL_DUMP(namespace_decl)
{
OS << "NamespaceDecl " << this << ' ' << get_identifier() << ' ';
if (prev())
OS << "prev " << dynamic_cast<const namespace_decl*>(prev()) << ' ';
if (next())
OS << "next " << dynamic_cast<const namespace_decl*>(next()) << ' ';
OS << '\n';
dump_children(OS, Depth);
}

MONOMUX_DECL_DUMP(value_decl) {}

MONOMUX_DECL_DUMP(literal_decl) {}

#undef MONOMUX_DECL_DUMP

} // namespace monomux::tools::dto_compiler::ast
Loading

0 comments on commit de95ceb

Please sign in to comment.