Skip to content

Commit

Permalink
Merge pull request Laupetin#72 from Laupetin/fix/static-expressions-f…
Browse files Browse the repository at this point in the history
…or-menu-properties

Allow static expressions on all menu item properties
  • Loading branch information
Laupetin authored Dec 26, 2023
2 parents 3e18f74 + 0bcadc1 commit 44e501e
Show file tree
Hide file tree
Showing 6 changed files with 366 additions and 21 deletions.
50 changes: 50 additions & 0 deletions src/ObjLoading/Parsing/Menu/Matcher/MenuMatcherFactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,20 @@ MatcherFactoryWrapper<SimpleParserValue> MenuMatcherFactory::Numeric() const
}));
}

MatcherFactoryWrapper<SimpleParserValue> MenuMatcherFactory::TextExpression() const
{
return MatcherFactoryWrapper(Or({
StringChain().Tag(TAG_STRING_CHAIN).Capture(CAPTURE_STRING_CHAIN),
Identifier().Tag(TAG_IDENTIFIER).Capture(CAPTURE_IDENTIFIER),
And({
Char('(').Capture(CAPTURE_FIRST_TOKEN),
Label(MenuExpressionMatchers::LABEL_EXPRESSION),
Char(')'),
})
.Tag(TAG_EXPRESSION),
}));
}

MatcherFactoryWrapper<SimpleParserValue> MenuMatcherFactory::IntExpression() const
{
return MatcherFactoryWrapper(Or({
Expand Down Expand Up @@ -144,6 +158,42 @@ int MenuMatcherFactory::TokenIntExpressionValue(MenuFileParserState* state, Sequ
throw ParsingException(TokenPos(), "TokenIntExpressionValue must be expression or int");
}

std::string MenuMatcherFactory::TokenTextExpressionValue(MenuFileParserState* state, SequenceResult<SimpleParserValue>& result)
{
const auto nextTag = result.PeekTag();

assert(nextTag == TAG_STRING_CHAIN || nextTag == TAG_IDENTIFIER || nextTag == TAG_EXPRESSION);
if (nextTag == TAG_STRING_CHAIN)
{
result.NextTag();
return result.NextCapture(CAPTURE_STRING_CHAIN).StringValue();
}

if (nextTag == TAG_IDENTIFIER)
{
result.NextTag();
return result.NextCapture(CAPTURE_IDENTIFIER).IdentifierValue();
}

if (nextTag == TAG_EXPRESSION)
{
result.NextTag();
const auto expression = MenuExpressionMatchers(state).ProcessExpression(result);

if (!expression || !expression->IsStatic())
throw ParsingException(result.NextCapture(CAPTURE_FIRST_TOKEN).GetPos(), "Not a valid static expression");

const auto value = expression->EvaluateStatic();

if (value.m_type != SimpleExpressionValue::Type::STRING)
throw ParsingException(result.NextCapture(CAPTURE_FIRST_TOKEN).GetPos(), "Expression MUST be string type");

return std::move(*value.m_string_value);
}

throw ParsingException(TokenPos(), "TokenIntExpressionValue must be expression or int");
}

double MenuMatcherFactory::TokenNumericExpressionValue(MenuFileParserState* state, SequenceResult<SimpleParserValue>& result)
{
const auto nextTag = result.PeekTag();
Expand Down
16 changes: 11 additions & 5 deletions src/ObjLoading/Parsing/Menu/Matcher/MenuMatcherFactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,17 @@ namespace menu
{
class MenuMatcherFactory : public SimpleMatcherFactory
{
static constexpr auto TAG_INT = 1420;
static constexpr auto TAG_NUMERIC = 1421;
static constexpr auto TAG_EXPRESSION = 1422;
static constexpr auto TAG_STRING_CHAIN = 1420;
static constexpr auto TAG_IDENTIFIER = 1421;
static constexpr auto TAG_INT = 1422;
static constexpr auto TAG_NUMERIC = 1423;
static constexpr auto TAG_EXPRESSION = 1424;

static constexpr auto CAPTURE_FIRST_TOKEN = 1420;
static constexpr auto CAPTURE_INT = 1421;
static constexpr auto CAPTURE_NUMERIC = 1422;
static constexpr auto CAPTURE_STRING_CHAIN = 1421;
static constexpr auto CAPTURE_IDENTIFIER = 1422;
static constexpr auto CAPTURE_INT = 1423;
static constexpr auto CAPTURE_NUMERIC = 1424;

public:
explicit MenuMatcherFactory(const IMatcherForLabelSupplier<SimpleParserValue>* labelSupplier);
Expand All @@ -24,13 +28,15 @@ namespace menu
_NODISCARD MatcherFactoryWrapper<SimpleParserValue> TextNoChain() const;
_NODISCARD MatcherFactoryWrapper<SimpleParserValue> Numeric() const;

_NODISCARD MatcherFactoryWrapper<SimpleParserValue> TextExpression() const;
_NODISCARD MatcherFactoryWrapper<SimpleParserValue> IntExpression() const;
_NODISCARD MatcherFactoryWrapper<SimpleParserValue> NumericExpression() const;

_NODISCARD static int TokenNumericIntValue(const SimpleParserValue& value);
_NODISCARD static double TokenNumericFloatingPointValue(const SimpleParserValue& value);
_NODISCARD static std::string& TokenTextValue(const SimpleParserValue& value);

_NODISCARD static std::string TokenTextExpressionValue(MenuFileParserState* state, SequenceResult<SimpleParserValue>& result);
_NODISCARD static int TokenIntExpressionValue(MenuFileParserState* state, SequenceResult<SimpleParserValue>& result);
_NODISCARD static double TokenNumericExpressionValue(MenuFileParserState* state, SequenceResult<SimpleParserValue>& result);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "GenericStringPropertySequence.h"

#include "Parsing/Menu/Matcher/MenuExpressionMatchers.h"
#include "Parsing/Menu/Matcher/MenuMatcherFactory.h"

#include <utility>
Expand All @@ -10,18 +11,19 @@ GenericStringPropertySequence::GenericStringPropertySequence(std::string keyword
: m_set_callback(std::move(setCallback))
{
const MenuMatcherFactory create(this);
AddLabeledMatchers(MenuExpressionMatchers().Expression(this), MenuExpressionMatchers::LABEL_EXPRESSION);

AddMatchers({
create.KeywordIgnoreCase(std::move(keywordName)).Capture(CAPTURE_FIRST_TOKEN),
create.Text().Capture(CAPTURE_VALUE),
create.TextExpression(),
});
}

void GenericStringPropertySequence::ProcessMatch(MenuFileParserState* state, SequenceResult<SimpleParserValue>& result) const
{
if (m_set_callback)
{
const auto& value = MenuMatcherFactory::TokenTextValue(result.NextCapture(CAPTURE_VALUE));
const auto value = MenuMatcherFactory::TokenTextExpressionValue(state, result);
m_set_callback(state, result.NextCapture(CAPTURE_FIRST_TOKEN).GetPos(), value);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ namespace menu

private:
static constexpr auto CAPTURE_FIRST_TOKEN = 1;
static constexpr auto CAPTURE_VALUE = 2;

const callback_t m_set_callback;

Expand Down
23 changes: 10 additions & 13 deletions src/ObjLoading/Parsing/Menu/Sequence/ItemScopeSequences.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,8 +189,7 @@ namespace menu::item_scope_sequences

class SequenceRect final : public MenuFileParser::sequence_t
{
static constexpr auto CAPTURE_ALIGN_HORIZONTAL = 1;
static constexpr auto CAPTURE_ALIGN_VERTICAL = 2;
static constexpr auto TAG_ALIGN = 1;

public:
SequenceRect()
Expand All @@ -204,10 +203,12 @@ namespace menu::item_scope_sequences
create.NumericExpression(), // y
create.NumericExpression(), // w
create.NumericExpression(), // h
create.Optional(create.And({
create.Integer().Capture(CAPTURE_ALIGN_HORIZONTAL),
create.Integer().Capture(CAPTURE_ALIGN_VERTICAL),
})),
create.Optional(create
.And({
create.IntExpression(), // Align horizontal
create.IntExpression(), // Align vertical
})
.Tag(TAG_ALIGN)),
});
}

Expand All @@ -222,10 +223,10 @@ namespace menu::item_scope_sequences
const auto h = MenuMatcherFactory::TokenNumericExpressionValue(state, result);
CommonRect rect{x, y, w, h, 0, 0};

if (result.HasNextCapture(CAPTURE_ALIGN_HORIZONTAL) && result.HasNextCapture(CAPTURE_ALIGN_VERTICAL))
if (result.PeekAndRemoveIfTag(TAG_ALIGN) == TAG_ALIGN)
{
rect.horizontalAlign = result.NextCapture(CAPTURE_ALIGN_HORIZONTAL).IntegerValue();
rect.verticalAlign = result.NextCapture(CAPTURE_ALIGN_VERTICAL).IntegerValue();
rect.horizontalAlign = MenuMatcherFactory::TokenIntExpressionValue(state, result);
rect.verticalAlign = MenuMatcherFactory::TokenIntExpressionValue(state, result);
}

state->m_current_item->m_rect = rect;
Expand Down Expand Up @@ -259,10 +260,6 @@ namespace menu::item_scope_sequences

class SequenceDecodeEffect final : public MenuFileParser::sequence_t
{
static constexpr auto CAPTURE_LETTER_TIME = 1;
static constexpr auto CAPTURE_DECAY_START_TIME = 2;
static constexpr auto CAPTURE_DECAY_DURATION = 3;

public:
SequenceDecodeEffect()
{
Expand Down
Loading

0 comments on commit 44e501e

Please sign in to comment.