Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: allow multiple 'with' fields #153

Merged
merged 2 commits into from
May 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
77 changes: 52 additions & 25 deletions ecsact/detail/grammar.hh
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ struct parameters {
static constexpr auto rule = [] {
return lexy::dsl::parenthesized.list(
lexy::dsl::p<parameter>,
lexy::dsl::sep(lexy::dsl::comma)
lexy::dsl::trailing_sep(lexy::dsl::comma)
);
}();

Expand Down Expand Up @@ -668,17 +668,25 @@ struct system_component_statement {
static constexpr auto value = lexy::noop;
};

struct with_fields : lexy::token_production {
static constexpr auto rule = lexy::dsl::list(
lexy::dsl::p<field_name>,
lexy::dsl::trailing_sep(lexy::dsl::comma)
);
static constexpr auto value = lexy::as_list<std::vector<std::string_view>>;
};

static constexpr auto capability = lexy::dsl::p<filter> |
lexy::dsl::p<access> | lexy::dsl::p<assignment>;

static constexpr auto rule = capability >> lexy::dsl::p<type_name> >>
lexy::dsl::opt(lexy::dsl::p<with_keyword> >> lexy::dsl::p<field_name>);
lexy::dsl::opt(lexy::dsl::p<with_keyword> >> lexy::dsl::p<with_fields>);

static constexpr auto value = lexy::callback<ecsact_statement>(
[](
ecsact_system_capability cap,
std::string_view component_name,
std::optional<std::string_view> with_entity_field_name
ecsact_system_capability cap,
std::string_view component_name,
std::optional<std::vector<std::string_view>> with_entity_field_names
) {
ecsact_statement statement{
.type = ECSACT_STATEMENT_SYSTEM_COMPONENT,
Expand All @@ -691,10 +699,15 @@ struct system_component_statement {
data.component_name.data = component_name.data();
data.component_name.length = static_cast<int>(component_name.size());

if(with_entity_field_name) {
data.with_entity_field_name.data = with_entity_field_name->data();
data.with_entity_field_name.length =
static_cast<int>(with_entity_field_name->size());
if(with_entity_field_names) {
data.with_field_name_list_count =
static_cast<int>(with_entity_field_names->size());
for(int i = 0; data.with_field_name_list_count > i; ++i) {
data.with_field_name_list[i] = ecsact_statement_sv{
.data = (*with_entity_field_names)[i].data(),
.length = static_cast<int>((*with_entity_field_names)[i].size()),
};
}
}

return statement;
Expand Down Expand Up @@ -758,21 +771,35 @@ struct with_statement {
static constexpr auto value = lexy::noop;
};

struct with_fields : lexy::token_production {
static constexpr auto rule = lexy::dsl::list(
lexy::dsl::p<field_name>,
lexy::dsl::trailing_sep(lexy::dsl::comma)
);
static constexpr auto value = lexy::as_list<std::vector<std::string_view>>;
};

static constexpr auto rule = lexy::dsl::p<with_keyword> >>
lexy::dsl::p<field_name>;
lexy::dsl::p<with_fields>;

static constexpr auto value = lexy::callback<ecsact_statement>(
[](std::vector<std::string_view> field_names) {
auto data = ecsact_system_with_statement{};
data.with_field_name_list_count = field_names.size();

for(int i = 0; data.with_field_name_list_count > i; ++i) {
data.with_field_name_list[i] = ecsact_statement_sv{
.data = field_names[i].data(),
.length = static_cast<int>(field_names[i].size()),
};
}

static constexpr auto value =
lexy::callback<ecsact_statement>([](std::string_view field_name) {
return ecsact_statement{
.type = ECSACT_STATEMENT_SYSTEM_WITH_ENTITY,
.data{.system_with_entity_statement{
.with_entity_field_name{
.data = field_name.data(),
.length = static_cast<int>(field_name.size()),
},
}},
.type = ECSACT_STATEMENT_SYSTEM_WITH,
.data{.system_with_statement{data}},
};
});
}
);
};

struct system_notify_statement {
Expand Down Expand Up @@ -1003,13 +1030,13 @@ using system_component_level_statement = statement<
system_component_statement,
with_statement>;

constexpr char system_with_entity_level_statement_name[] =
constexpr char system_with_level_statement_name[] =
"system with entity level statement";
constexpr char system_with_entity_level_statement_expected_message[] =
constexpr char system_with_level_statement_expected_message[] =
"expected system with entity level statement";
using system_with_entity_level_statement = statement<
system_with_entity_level_statement_name,
system_with_entity_level_statement_expected_message,
using system_with_level_statement = statement<
system_with_level_statement_name,
system_with_level_statement_expected_message,
system_component_statement,
with_statement>;

Expand Down
4 changes: 2 additions & 2 deletions ecsact/ecsact_parse_statement.cc
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ static auto context_grammar(ecsact_statement_type context_type, Fn&& fn) {
return fn(grammar::entity_field_level_statement{});
case ECSACT_STATEMENT_SYSTEM_COMPONENT:
return fn(grammar::system_component_level_statement{});
case ECSACT_STATEMENT_SYSTEM_WITH_ENTITY:
return fn(grammar::system_with_entity_level_statement{});
case ECSACT_STATEMENT_SYSTEM_WITH:
return fn(grammar::system_with_level_statement{});
case ECSACT_STATEMENT_PACKAGE:
return fn(grammar::package_level_statement{});
case ECSACT_STATEMENT_IMPORT:
Expand Down
15 changes: 10 additions & 5 deletions ecsact/parse/statements.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
#include "ecsact/runtime/common.h"
#include "ecsact/runtime/definitions.h"

/** Maximum number of 'with' fields that may be parsed */
#define ECSACT_MAX_WITH_FIELDS 32

typedef enum {
ECSACT_STATEMENT_NONE,
ECSACT_STATEMENT_UNKNOWN,
Expand All @@ -22,7 +25,7 @@ typedef enum {
ECSACT_STATEMENT_ENTITY_FIELD,
ECSACT_STATEMENT_SYSTEM_COMPONENT,
ECSACT_STATEMENT_SYSTEM_GENERATES,
ECSACT_STATEMENT_SYSTEM_WITH_ENTITY,
ECSACT_STATEMENT_SYSTEM_WITH,
ECSACT_STATEMENT_ENTITY_CONSTRAINT,
ECSACT_STATEMENT_SYSTEM_NOTIFY,
ECSACT_STATEMENT_SYSTEM_NOTIFY_COMPONENT,
Expand Down Expand Up @@ -83,12 +86,14 @@ typedef struct {
typedef struct {
ecsact_system_capability capability;
ecsact_statement_sv component_name;
ecsact_statement_sv with_entity_field_name;
int with_field_name_list_count;
ecsact_statement_sv with_field_name_list[ECSACT_MAX_WITH_FIELDS];
} ecsact_system_component_statement;

typedef struct {
ecsact_statement_sv with_entity_field_name;
} ecsact_system_with_entity_statement;
int with_field_name_list_count;
ecsact_statement_sv with_field_name_list[ECSACT_MAX_WITH_FIELDS];
} ecsact_system_with_statement;

typedef struct {
bool optional;
Expand Down Expand Up @@ -143,7 +148,7 @@ typedef union {
ecsact_field_statement field_statement;
ecsact_user_type_field_statement user_type_field_statement;
ecsact_system_component_statement system_component_statement;
ecsact_system_with_entity_statement system_with_entity_statement;
ecsact_system_with_statement system_with_statement;
ecsact_entity_constraint_statement entity_constraint_statement;
ecsact_system_notify_statement system_notify_statement;
ecsact_system_notify_component_statement system_notify_component_statement;
Expand Down
5 changes: 3 additions & 2 deletions test/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
load("@rules_cc//cc:defs.bzl", "cc_test")
load("@ecsact_parse//bazel:copts.bzl", "copts")
load("@rules_cc//cc:defs.bzl", "cc_test")

# keep sorted
_TESTS = [
Expand All @@ -16,7 +16,7 @@ _TESTS = [
"system_generates_statement",
"system_notify_statement",
"system_statement",
"system_with_entity_statement",
"system_with_statement",
"unknown_statement",
]

Expand All @@ -36,6 +36,7 @@ cc_library(
deps = [
":parse_test_util",
"@ecsact_parse",
"@magic_enum",
"@googletest//:gtest",
"@googletest//:gtest_main",
],
Expand Down
8 changes: 6 additions & 2 deletions test/MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@ module(name = "ecsact_parse_test")

bazel_dep(name = "rules_cc", version = "0.0.9")
bazel_dep(name = "googletest", version = "1.14.0")

bazel_dep(name = "magic_enum", version = "0.9.3")
bazel_dep(name = "ecsact_parse")
local_path_override(module_name = "ecsact_parse", path = "..")
local_path_override(
module_name = "ecsact_parse",
path = "..",
)

bazel_dep(name = "toolchains_llvm", version = "1.0.0", dev_dependency = True)
bazel_dep(name = "hedron_compile_commands", dev_dependency = True)

git_override(
module_name = "hedron_compile_commands",
commit = "204aa593e002cbd177d30f11f54cff3559110bb9",
Expand Down
Loading