Skip to content

Commit

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

Allow static expressions on all menu item properties
Laupetin authored Dec 26, 2023

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
2 parents 3e18f74 + 0bcadc1 commit 44e501e
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
@@ -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({
@@ -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();
16 changes: 11 additions & 5 deletions src/ObjLoading/Parsing/Menu/Matcher/MenuMatcherFactory.h
Original file line number Diff line number Diff line change
@@ -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);
@@ -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);
};
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>
@@ -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
@@ -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;

23 changes: 10 additions & 13 deletions src/ObjLoading/Parsing/Menu/Sequence/ItemScopeSequences.cpp
Original file line number Diff line number Diff line change
@@ -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()
@@ -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)),
});
}

@@ -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;
@@ -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()
{
Loading

0 comments on commit 44e501e

Please sign in to comment.