mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-19 07:42:54 +00:00
Do not use generic expressions for statemap rules but masks and values
This commit is contained in:
parent
63f636d401
commit
e009c2ee08
@ -22,7 +22,7 @@ separateAlphaBlendFunc
|
||||
mtlBlendOp == Disable: // Unused
|
||||
Disable, One, Zero;
|
||||
|
||||
mtlAlphaTest == Disable: // Used
|
||||
mtlAlphaTest == Always: // Used
|
||||
Add, Zero, One;
|
||||
|
||||
default:
|
||||
|
@ -23,6 +23,9 @@ namespace state_map
|
||||
|
||||
// Zero mask values must be last
|
||||
assert(value.m_state_bits_mask != 0 || i == var.m_values.size() - 1);
|
||||
|
||||
// Must not have a value outside the var mask
|
||||
assert((value.m_state_bits_mask & ~var.m_values_mask) == 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -68,9 +71,10 @@ StateMapLayoutVarValue::StateMapLayoutVarValue(std::string name, const size_t st
|
||||
{
|
||||
}
|
||||
|
||||
StateMapLayoutVar::StateMapLayoutVar(std::string name, const size_t stateBitsIndex, std::vector<StateMapLayoutVarValue> values)
|
||||
StateMapLayoutVar::StateMapLayoutVar(std::string name, const size_t stateBitsIndex, const size_t valuesMask, std::vector<StateMapLayoutVarValue> values)
|
||||
: m_name(std::move(name)),
|
||||
m_state_bits_index(stateBitsIndex),
|
||||
m_values_mask(valuesMask),
|
||||
m_values(std::move(values))
|
||||
{
|
||||
}
|
||||
|
@ -36,10 +36,11 @@ namespace state_map
|
||||
class StateMapLayoutVar
|
||||
{
|
||||
public:
|
||||
StateMapLayoutVar(std::string name, size_t stateBitsIndex, std::vector<StateMapLayoutVarValue> values);
|
||||
StateMapLayoutVar(std::string name, size_t stateBitsIndex, size_t valuesMask, std::vector<StateMapLayoutVarValue> values);
|
||||
|
||||
std::string m_name;
|
||||
size_t m_state_bits_index;
|
||||
size_t m_values_mask;
|
||||
std::vector<StateMapLayoutVarValue> m_values;
|
||||
};
|
||||
|
||||
|
@ -651,7 +651,7 @@ namespace IW4
|
||||
|
||||
inline state_map::StateMapLayoutVars stateMapVarLayout({
|
||||
{
|
||||
"mtlAlphaTest", 0, {
|
||||
"mtlAlphaTest", 0, GFXS0_ATEST_DISABLE | GFXS0_ATEST_MASK, {
|
||||
{"Always", GFXS0_ATEST_DISABLE},
|
||||
{"GE128", GFXS0_ATEST_GE_128},
|
||||
{"GT0", GFXS0_ATEST_GT_0},
|
||||
@ -659,7 +659,7 @@ namespace IW4
|
||||
}
|
||||
},
|
||||
{
|
||||
"mtlBlendOp", 0, {
|
||||
"mtlBlendOp", 0, GFXS0_BLENDOP_RGB_MASK, {
|
||||
{"Add", GFXS_BLENDOP_ADD << GFXS0_BLENDOP_RGB_SHIFT},
|
||||
{"Subtract", GFXS_BLENDOP_SUBTRACT << GFXS0_BLENDOP_RGB_SHIFT},
|
||||
{"RevSubtract", GFXS_BLENDOP_REVSUBTRACT << GFXS0_BLENDOP_RGB_SHIFT},
|
||||
@ -669,7 +669,7 @@ namespace IW4
|
||||
}
|
||||
},
|
||||
{
|
||||
"mtlSrcBlend", 0, {
|
||||
"mtlSrcBlend", 0, GFXS0_SRCBLEND_RGB_MASK, {
|
||||
{"Zero", GFXS_BLEND_ZERO << GFXS0_SRCBLEND_RGB_SHIFT},
|
||||
{"One", GFXS_BLEND_ONE << GFXS0_SRCBLEND_RGB_SHIFT},
|
||||
{"SrcColor", GFXS_BLEND_SRCCOLOR << GFXS0_SRCBLEND_RGB_SHIFT},
|
||||
@ -683,7 +683,7 @@ namespace IW4
|
||||
}
|
||||
},
|
||||
{
|
||||
"mtlDestBlend", 0, {
|
||||
"mtlDestBlend", 0, GFXS0_DSTBLEND_RGB_MASK, {
|
||||
{"Zero", GFXS_BLEND_ZERO << GFXS0_DSTBLEND_RGB_SHIFT},
|
||||
{"One", GFXS_BLEND_ONE << GFXS0_DSTBLEND_RGB_SHIFT},
|
||||
{"SrcColor", GFXS_BLEND_SRCCOLOR << GFXS0_DSTBLEND_RGB_SHIFT},
|
||||
@ -697,7 +697,7 @@ namespace IW4
|
||||
}
|
||||
},
|
||||
{
|
||||
"mtlBlendOpAlpha", 0, {
|
||||
"mtlBlendOpAlpha", 0, GFXS0_BLENDOP_ALPHA_MASK, {
|
||||
{"Add", GFXS_BLENDOP_ADD << GFXS0_BLENDOP_ALPHA_SHIFT},
|
||||
{"Subtract", GFXS_BLENDOP_SUBTRACT << GFXS0_BLENDOP_ALPHA_SHIFT},
|
||||
{"RevSubtract", GFXS_BLENDOP_REVSUBTRACT << GFXS0_BLENDOP_ALPHA_SHIFT},
|
||||
@ -707,7 +707,7 @@ namespace IW4
|
||||
}
|
||||
},
|
||||
{
|
||||
"mtlSrcBlendAlpha", 0, {
|
||||
"mtlSrcBlendAlpha", 0, GFXS0_SRCBLEND_ALPHA_MASK, {
|
||||
{"Zero", GFXS_BLEND_ZERO << GFXS0_SRCBLEND_ALPHA_SHIFT},
|
||||
{"One", GFXS_BLEND_ONE << GFXS0_SRCBLEND_ALPHA_SHIFT},
|
||||
{"SrcColor", GFXS_BLEND_SRCCOLOR << GFXS0_SRCBLEND_ALPHA_SHIFT},
|
||||
@ -721,7 +721,7 @@ namespace IW4
|
||||
}
|
||||
},
|
||||
{
|
||||
"mtlDestBlendAlpha", 0, {
|
||||
"mtlDestBlendAlpha", 0, GFXS0_DSTBLEND_ALPHA_MASK, {
|
||||
{"Zero", GFXS_BLEND_ZERO << GFXS0_DSTBLEND_ALPHA_SHIFT},
|
||||
{"One", GFXS_BLEND_ONE << GFXS0_DSTBLEND_ALPHA_SHIFT},
|
||||
{"SrcColor", GFXS_BLEND_SRCCOLOR << GFXS0_DSTBLEND_ALPHA_SHIFT},
|
||||
@ -735,38 +735,38 @@ namespace IW4
|
||||
}
|
||||
},
|
||||
{
|
||||
"mtlCullFace", 0, {
|
||||
"mtlCullFace", 0, GFXS0_CULL_MASK, {
|
||||
{"None", GFXS0_CULL_NONE},
|
||||
{"Back", GFXS0_CULL_BACK},
|
||||
{"Front", GFXS0_CULL_FRONT},
|
||||
}
|
||||
},
|
||||
{
|
||||
"mtlColorWriteRgb", 0, {
|
||||
"mtlColorWriteRgb", 0, GFXS0_COLORWRITE_RGB, {
|
||||
{"Enable", GFXS0_COLORWRITE_RGB},
|
||||
{"Disable", 0},
|
||||
}
|
||||
},
|
||||
{
|
||||
"mtlColorWriteAlpha", 0, {
|
||||
"mtlColorWriteAlpha", 0, GFXS0_COLORWRITE_ALPHA, {
|
||||
{"Enable", GFXS0_COLORWRITE_ALPHA},
|
||||
{"Disable", 0},
|
||||
}
|
||||
},
|
||||
{
|
||||
"mtlGammaWrite", 0, {
|
||||
"mtlGammaWrite", 0, GFXS0_GAMMAWRITE, {
|
||||
{"Enable", GFXS0_GAMMAWRITE},
|
||||
{"Disable", 0},
|
||||
}
|
||||
},
|
||||
{
|
||||
"mtlWireframe", 0, {
|
||||
"mtlWireframe", 0, GFXS0_POLYMODE_LINE, {
|
||||
{"Enable", GFXS0_POLYMODE_LINE},
|
||||
{"Disable", 0},
|
||||
}
|
||||
},
|
||||
{
|
||||
"mtlDepthTest", 1, {
|
||||
"mtlDepthTest", 1, GFXS1_DEPTHTEST_DISABLE | GFXS1_DEPTHTEST_MASK, {
|
||||
{"Disable", GFXS1_DEPTHTEST_DISABLE},
|
||||
{"Less", GFXS1_DEPTHTEST_LESS},
|
||||
{"LessEqual", GFXS1_DEPTHTEST_LESSEQUAL},
|
||||
@ -775,13 +775,13 @@ namespace IW4
|
||||
}
|
||||
},
|
||||
{
|
||||
"mtlDepthWrite", 1, {
|
||||
"mtlDepthWrite", 1, GFXS1_DEPTHWRITE, {
|
||||
{"Enable", GFXS1_DEPTHWRITE},
|
||||
{"Disable", 0},
|
||||
}
|
||||
},
|
||||
{
|
||||
"mtlPolygonOffset", 1, {
|
||||
"mtlPolygonOffset", 1, GFXS1_POLYGON_OFFSET_MASK, {
|
||||
{"1", GFXS1_POLYGON_OFFSET_1},
|
||||
{"2", GFXS1_POLYGON_OFFSET_2},
|
||||
{"shadowmap", GFXS1_POLYGON_OFFSET_SHADOWMAP},
|
||||
@ -789,14 +789,14 @@ namespace IW4
|
||||
}
|
||||
},
|
||||
{
|
||||
"mtlStencil", 1, {
|
||||
"mtlStencil", 1, GFXS1_STENCIL_FRONT_ENABLE | GFXS1_STENCIL_BACK_ENABLE, {
|
||||
{"OneSided", GFXS1_STENCIL_FRONT_ENABLE},
|
||||
{"TwoSided", GFXS1_STENCIL_FRONT_ENABLE | GFXS1_STENCIL_BACK_ENABLE},
|
||||
{"Disable", 0},
|
||||
}
|
||||
},
|
||||
{
|
||||
"mtlStencilFuncFront", 1, {
|
||||
"mtlStencilFuncFront", 1, GFXS1_STENCIL_FRONT_FUNC_MASK, {
|
||||
{"Less", GFXS_STENCILFUNC_LESS << GFXS1_STENCIL_FRONT_FUNC_SHIFT},
|
||||
{"Equal", GFXS_STENCILFUNC_EQUAL << GFXS1_STENCIL_FRONT_FUNC_SHIFT},
|
||||
{"LessEqual", GFXS_STENCILFUNC_LESSEQUAL << GFXS1_STENCIL_FRONT_FUNC_SHIFT},
|
||||
@ -808,7 +808,7 @@ namespace IW4
|
||||
}
|
||||
},
|
||||
{
|
||||
"mtlStencilOpFrontPass", 1, {
|
||||
"mtlStencilOpFrontPass", 1, GFXS1_STENCIL_FRONT_PASS_MASK, {
|
||||
{"Zero", GFXS_STENCILOP_ZERO << GFXS1_STENCIL_FRONT_PASS_SHIFT},
|
||||
{"Replace", GFXS_STENCILOP_REPLACE << GFXS1_STENCIL_FRONT_PASS_SHIFT},
|
||||
{"IncrSat", GFXS_STENCILOP_INCRSAT << GFXS1_STENCIL_FRONT_PASS_SHIFT},
|
||||
@ -820,7 +820,7 @@ namespace IW4
|
||||
}
|
||||
},
|
||||
{
|
||||
"mtlStencilOpFrontFail", 1, {
|
||||
"mtlStencilOpFrontFail", 1, GFXS1_STENCIL_FRONT_FAIL_MASK, {
|
||||
{"Zero", GFXS_STENCILOP_ZERO << GFXS1_STENCIL_FRONT_FAIL_SHIFT},
|
||||
{"Replace", GFXS_STENCILOP_REPLACE << GFXS1_STENCIL_FRONT_FAIL_SHIFT},
|
||||
{"IncrSat", GFXS_STENCILOP_INCRSAT << GFXS1_STENCIL_FRONT_FAIL_SHIFT},
|
||||
@ -832,7 +832,7 @@ namespace IW4
|
||||
}
|
||||
},
|
||||
{
|
||||
"mtlStencilOpFrontZFail", 1, {
|
||||
"mtlStencilOpFrontZFail", 1, GFXS1_STENCIL_FRONT_ZFAIL_MASK, {
|
||||
{"Zero", GFXS_STENCILOP_ZERO << GFXS1_STENCIL_FRONT_ZFAIL_SHIFT},
|
||||
{"Replace", GFXS_STENCILOP_REPLACE << GFXS1_STENCIL_FRONT_ZFAIL_SHIFT},
|
||||
{"IncrSat", GFXS_STENCILOP_INCRSAT << GFXS1_STENCIL_FRONT_ZFAIL_SHIFT},
|
||||
@ -844,7 +844,7 @@ namespace IW4
|
||||
}
|
||||
},
|
||||
{
|
||||
"mtlStencilFuncBack", 1, {
|
||||
"mtlStencilFuncBack", 1, GFXS1_STENCIL_BACK_FUNC_MASK, {
|
||||
{"Less", GFXS_STENCILFUNC_LESS << GFXS1_STENCIL_BACK_FUNC_SHIFT},
|
||||
{"Equal", GFXS_STENCILFUNC_EQUAL << GFXS1_STENCIL_BACK_FUNC_SHIFT},
|
||||
{"LessEqual", GFXS_STENCILFUNC_LESSEQUAL << GFXS1_STENCIL_BACK_FUNC_SHIFT},
|
||||
@ -856,7 +856,7 @@ namespace IW4
|
||||
}
|
||||
},
|
||||
{
|
||||
"mtlStencilOpBackPass", 1, {
|
||||
"mtlStencilOpBackPass", 1, GFXS1_STENCIL_BACK_PASS_MASK, {
|
||||
{"Zero", GFXS_STENCILOP_ZERO << GFXS1_STENCIL_BACK_PASS_SHIFT},
|
||||
{"Replace", GFXS_STENCILOP_REPLACE << GFXS1_STENCIL_BACK_PASS_SHIFT},
|
||||
{"IncrSat", GFXS_STENCILOP_INCRSAT << GFXS1_STENCIL_BACK_PASS_SHIFT},
|
||||
@ -868,7 +868,7 @@ namespace IW4
|
||||
}
|
||||
},
|
||||
{
|
||||
"mtlStencilOpBackFail", 1, {
|
||||
"mtlStencilOpBackFail", 1, GFXS1_STENCIL_BACK_FAIL_MASK, {
|
||||
{"Zero", GFXS_STENCILOP_ZERO << GFXS1_STENCIL_BACK_FAIL_SHIFT},
|
||||
{"Replace", GFXS_STENCILOP_REPLACE << GFXS1_STENCIL_BACK_FAIL_SHIFT},
|
||||
{"IncrSat", GFXS_STENCILOP_INCRSAT << GFXS1_STENCIL_BACK_FAIL_SHIFT},
|
||||
@ -880,7 +880,7 @@ namespace IW4
|
||||
}
|
||||
},
|
||||
{
|
||||
"mtlStencilOpBackZFail", 1, {
|
||||
"mtlStencilOpBackZFail", 1, GFXS1_STENCIL_BACK_ZFAIL_MASK, {
|
||||
{"Zero", GFXS_STENCILOP_ZERO << GFXS1_STENCIL_BACK_ZFAIL_SHIFT},
|
||||
{"Replace", GFXS_STENCILOP_REPLACE << GFXS1_STENCIL_BACK_ZFAIL_SHIFT},
|
||||
{"IncrSat", GFXS_STENCILOP_INCRSAT << GFXS1_STENCIL_BACK_ZFAIL_SHIFT},
|
||||
|
@ -1,50 +0,0 @@
|
||||
#include "StateMapExpressionMatchers.h"
|
||||
|
||||
#include "Parsing/Simple/Expression/SimpleExpressionScopeValue.h"
|
||||
#include "Parsing/Simple/Matcher/SimpleMatcherFactory.h"
|
||||
|
||||
using namespace state_map;
|
||||
|
||||
static constexpr int CAPTURE_VALUE = SimpleExpressionMatchers::CAPTURE_OFFSET_EXPRESSION_EXT + 1;
|
||||
|
||||
StateMapExpressionMatchers::StateMapExpressionMatchers()
|
||||
: StateMapExpressionMatchers(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
StateMapExpressionMatchers::StateMapExpressionMatchers(StateMapParserState* state)
|
||||
: SimpleExpressionMatchers(false, false, false, false, true),
|
||||
m_state(state)
|
||||
{
|
||||
}
|
||||
|
||||
std::unique_ptr<SimpleExpressionMatchers::matcher_t> StateMapExpressionMatchers::ParseOperandExtension(const supplier_t* labelSupplier) const
|
||||
{
|
||||
const SimpleMatcherFactory create(labelSupplier);
|
||||
|
||||
return create.Or({
|
||||
create.Identifier().Capture(CAPTURE_VALUE),
|
||||
create.Integer().Capture(CAPTURE_VALUE),
|
||||
});
|
||||
}
|
||||
|
||||
std::unique_ptr<ISimpleExpression> StateMapExpressionMatchers::ProcessOperandExtension(SequenceResult<SimpleParserValue>& result) const
|
||||
{
|
||||
assert(m_state);
|
||||
|
||||
const auto& valueToken = result.NextCapture(CAPTURE_VALUE);
|
||||
auto value = valueToken.m_type == SimpleParserValueType::IDENTIFIER ? valueToken.IdentifierValue() : std::to_string(valueToken.IntegerValue());
|
||||
|
||||
if (value.rfind("mtl", 0) == 0)
|
||||
{
|
||||
if (m_state->m_valid_vars.find(value) == m_state->m_valid_vars.end())
|
||||
throw ParsingException(valueToken.GetPos(), "Unknown variable");
|
||||
|
||||
return std::make_unique<SimpleExpressionScopeValue>(value);
|
||||
}
|
||||
|
||||
if (m_state->m_valid_values.find(value) == m_state->m_valid_values.end())
|
||||
throw ParsingException(valueToken.GetPos(), "Unknown value");
|
||||
|
||||
return std::make_unique<SimpleExpressionValue>(value);
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "Parsing/Simple/Expression/SimpleExpressionMatchers.h"
|
||||
#include "StateMap/Parsing/StateMapParserState.h"
|
||||
|
||||
namespace state_map
|
||||
{
|
||||
class StateMapExpressionMatchers final : public SimpleExpressionMatchers
|
||||
{
|
||||
public:
|
||||
StateMapExpressionMatchers();
|
||||
explicit StateMapExpressionMatchers(StateMapParserState* state);
|
||||
|
||||
protected:
|
||||
std::unique_ptr<matcher_t> ParseOperandExtension(const supplier_t* labelSupplier) const override;
|
||||
std::unique_ptr<ISimpleExpression> ProcessOperandExtension(SequenceResult<SimpleParserValue>& result) const override;
|
||||
|
||||
private:
|
||||
StateMapParserState* m_state;
|
||||
};
|
||||
}
|
@ -1,6 +1,8 @@
|
||||
#include "StateMapParser.h"
|
||||
|
||||
#include "Matcher/StateMapExpressionMatchers.h"
|
||||
#include <array>
|
||||
#include <sstream>
|
||||
|
||||
#include "Parsing/Simple/Matcher/SimpleMatcherFactory.h"
|
||||
|
||||
using namespace state_map;
|
||||
@ -64,18 +66,45 @@ namespace state_map
|
||||
class SequenceCondition final : public StateMapParser::sequence_t
|
||||
{
|
||||
static constexpr auto TAG_DEFAULT = 1;
|
||||
static constexpr auto TAG_EXPRESSION = 2;
|
||||
static constexpr auto TAG_CONDITION = 2;
|
||||
static constexpr auto TAG_EQUALS_OPERATION = 3;
|
||||
|
||||
static constexpr auto CAPTURE_OPERATOR = 1;
|
||||
|
||||
static constexpr auto LABEL_CONDITION = 1;
|
||||
static constexpr auto LABEL_EQUALS_OPERATION = 2;
|
||||
static constexpr auto LABEL_CONDITION_OPERATOR = 3;
|
||||
|
||||
public:
|
||||
SequenceCondition()
|
||||
{
|
||||
AddLabeledMatchers(StateMapExpressionMatchers().Expression(this), StateMapExpressionMatchers::LABEL_EXPRESSION);
|
||||
const SimpleMatcherFactory create(this);
|
||||
|
||||
AddLabeledMatchers(create.Or({
|
||||
create.Identifier(),
|
||||
create.Integer()
|
||||
}).Capture(CAPTURE_OPERATOR), LABEL_CONDITION_OPERATOR);
|
||||
|
||||
AddLabeledMatchers(create.And({
|
||||
create.True().Tag(TAG_EQUALS_OPERATION),
|
||||
create.Label(LABEL_CONDITION_OPERATOR),
|
||||
create.MultiChar(StateMapParser::MULTI_TOKEN_EQUALS),
|
||||
create.Label(LABEL_CONDITION_OPERATOR)
|
||||
}), LABEL_EQUALS_OPERATION);
|
||||
|
||||
AddLabeledMatchers(create.And({
|
||||
create.True().Tag(TAG_CONDITION),
|
||||
create.Label(LABEL_EQUALS_OPERATION),
|
||||
create.OptionalLoop(create.And({
|
||||
create.MultiChar(StateMapParser::MULTI_TOKEN_AND),
|
||||
create.Label(LABEL_EQUALS_OPERATION)
|
||||
}))
|
||||
}), LABEL_CONDITION);
|
||||
|
||||
AddMatchers({
|
||||
create.Or({
|
||||
create.Keyword("default").Tag(TAG_DEFAULT),
|
||||
create.Label(StateMapExpressionMatchers::LABEL_EXPRESSION).Tag(TAG_EXPRESSION)
|
||||
create.Label(LABEL_CONDITION)
|
||||
}),
|
||||
create.Char(':')
|
||||
});
|
||||
@ -94,11 +123,10 @@ namespace state_map
|
||||
state->m_definition->m_state_map_entries[state->m_current_entry_index].m_rules.emplace_back(std::move(newRule));
|
||||
}
|
||||
|
||||
if (result.PeekAndRemoveIfTag(TAG_EXPRESSION) == TAG_EXPRESSION)
|
||||
if (result.PeekAndRemoveIfTag(TAG_CONDITION) == TAG_CONDITION)
|
||||
{
|
||||
auto expression = StateMapExpressionMatchers(state).ProcessExpression(result);
|
||||
|
||||
state->m_current_rule->m_conditions.emplace_back(std::move(expression));
|
||||
auto condition = ProcessCondition(state, result);
|
||||
state->m_current_rule->m_conditions.emplace_back(std::move(condition));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -108,6 +136,73 @@ namespace state_map
|
||||
entry.m_default_index = entry.m_rules.size() - 1;
|
||||
}
|
||||
}
|
||||
|
||||
static StateMapCondition ProcessCondition(const StateMapParserState* state, SequenceResult<SimpleParserValue>& result)
|
||||
{
|
||||
StateMapCondition condition(state->m_layout.m_state_bits_count);
|
||||
|
||||
while (result.PeekAndRemoveIfTag(TAG_EQUALS_OPERATION) == TAG_EQUALS_OPERATION)
|
||||
{
|
||||
std::array<std::reference_wrapper<const SimpleParserValue>, 2> operatorToken
|
||||
{
|
||||
result.NextCapture(CAPTURE_OPERATOR),
|
||||
result.NextCapture(CAPTURE_OPERATOR)
|
||||
};
|
||||
|
||||
std::array<std::string, 2> operatorValue
|
||||
{
|
||||
ProcessOperator(operatorToken[0]),
|
||||
ProcessOperator(operatorToken[1])
|
||||
};
|
||||
|
||||
const auto variableIndex = IsVariable(operatorValue[1]) ? 1 : 0;
|
||||
const auto valueIndex = variableIndex == 0 ? 1 : 0;
|
||||
|
||||
const auto& variable = GetVariable(state, operatorToken[variableIndex], operatorValue[variableIndex]);
|
||||
const auto& value = GetValue(variable, operatorToken[valueIndex], operatorValue[valueIndex]);
|
||||
|
||||
condition.m_masks_per_index[variable.m_state_bits_index] |= variable.m_values_mask;
|
||||
condition.m_values_per_index[variable.m_state_bits_index] |= value.m_state_bits_mask;
|
||||
}
|
||||
|
||||
return condition;
|
||||
}
|
||||
|
||||
static std::string ProcessOperator(const SimpleParserValue& token)
|
||||
{
|
||||
return token.m_type == SimpleParserValueType::IDENTIFIER ? token.IdentifierValue() : std::to_string(token.IntegerValue());
|
||||
}
|
||||
|
||||
static bool IsVariable(const std::string& _operator)
|
||||
{
|
||||
return _operator.rfind("mtl", 0) == 0;
|
||||
}
|
||||
|
||||
static const StateMapLayoutVar& GetVariable(const StateMapParserState* state, const SimpleParserValue& operatorToken, const std::string& operatorValue)
|
||||
{
|
||||
const auto& foundVariable = state->m_valid_vars.find(operatorValue);
|
||||
if (foundVariable == state->m_valid_vars.end())
|
||||
throw ParsingException(operatorToken.GetPos(), "Unknown variable");
|
||||
|
||||
return state->m_layout.m_var_layout.m_vars[foundVariable->second];
|
||||
}
|
||||
|
||||
static const StateMapLayoutVarValue& GetValue(const StateMapLayoutVar& variable, const SimpleParserValue& operatorToken, const std::string& operatorValue)
|
||||
{
|
||||
const auto matchingValue = std::find_if(variable.m_values.begin(), variable.m_values.end(), [&operatorValue](const StateMapLayoutVarValue& value)
|
||||
{
|
||||
return value.m_name == operatorValue;
|
||||
});
|
||||
|
||||
if (matchingValue == variable.m_values.end())
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss << "Unknown value for variable \"" << variable.m_name << "\"";
|
||||
throw ParsingException(operatorToken.GetPos(), ss.str());
|
||||
}
|
||||
|
||||
return *matchingValue;
|
||||
}
|
||||
};
|
||||
|
||||
class SequenceValue final : public StateMapParser::sequence_t
|
||||
|
@ -11,6 +11,10 @@ namespace state_map
|
||||
{
|
||||
class StateMapParser final : public AbstractParser<SimpleParserValue, StateMapParserState>
|
||||
{
|
||||
public:
|
||||
static constexpr auto MULTI_TOKEN_AND = 600;
|
||||
static constexpr auto MULTI_TOKEN_EQUALS = 601;
|
||||
|
||||
protected:
|
||||
const std::vector<sequence_t*>& GetTestsForState() override;
|
||||
|
||||
|
@ -2,6 +2,12 @@
|
||||
|
||||
using namespace state_map;
|
||||
|
||||
StateMapCondition::StateMapCondition(const size_t entryCount)
|
||||
: m_masks_per_index(entryCount),
|
||||
m_values_per_index(entryCount)
|
||||
{
|
||||
}
|
||||
|
||||
StateMapRule::StateMapRule()
|
||||
: m_value(0u),
|
||||
m_passthrough(false)
|
||||
|
@ -4,14 +4,21 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "Parsing/Simple/Expression/ISimpleExpression.h"
|
||||
|
||||
namespace state_map
|
||||
{
|
||||
class StateMapCondition
|
||||
{
|
||||
public:
|
||||
std::vector<size_t> m_masks_per_index;
|
||||
std::vector<size_t> m_values_per_index;
|
||||
|
||||
explicit StateMapCondition(size_t entryCount);
|
||||
};
|
||||
|
||||
class StateMapRule
|
||||
{
|
||||
public:
|
||||
std::vector<std::unique_ptr<ISimpleExpression>> m_conditions;
|
||||
std::vector<StateMapCondition> m_conditions;
|
||||
size_t m_value;
|
||||
bool m_passthrough;
|
||||
|
||||
|
@ -6,21 +6,6 @@
|
||||
|
||||
using namespace state_map;
|
||||
|
||||
void StateMapVars::AddValue(std::string key, std::string value)
|
||||
{
|
||||
m_vars.emplace(std::make_pair(std::move(key), std::move(value)));
|
||||
}
|
||||
|
||||
SimpleExpressionValue StateMapVars::ValueByName(const std::string& name) const
|
||||
{
|
||||
const auto foundValue = m_vars.find(name);
|
||||
|
||||
if (foundValue != m_vars.end())
|
||||
return SimpleExpressionValue(foundValue->second);
|
||||
|
||||
return SimpleExpressionValue(0);
|
||||
}
|
||||
|
||||
StateMapHandler::StateMapHandler(const StateMapLayout& stateMapLayout, const StateMapDefinition& stateMap)
|
||||
: m_state_map_layout(stateMapLayout),
|
||||
m_state_map(stateMap)
|
||||
@ -32,19 +17,17 @@ void StateMapHandler::ApplyStateMap(const uint32_t* baseStateBits, uint32_t* out
|
||||
assert(baseStateBits != nullptr);
|
||||
assert(outStateBits != nullptr);
|
||||
|
||||
const auto vars = BuildVars(baseStateBits);
|
||||
|
||||
for (auto i = 0u; i < m_state_map_layout.m_state_bits_count; i++)
|
||||
outStateBits[i] = baseStateBits[i];
|
||||
|
||||
for (auto entryIndex = 0u; entryIndex < m_state_map.m_state_map_entries.size(); entryIndex++)
|
||||
{
|
||||
const auto& entry = m_state_map.m_state_map_entries[entryIndex];
|
||||
const auto matchingRule = std::find_if(entry.m_rules.begin(), entry.m_rules.end(), [&vars](const std::unique_ptr<StateMapRule>& rule)
|
||||
const auto matchingRule = std::find_if(entry.m_rules.begin(), entry.m_rules.end(), [&baseStateBits](const std::unique_ptr<StateMapRule>& rule)
|
||||
{
|
||||
const auto matchingCondition = std::find_if(rule->m_conditions.begin(), rule->m_conditions.end(), [&vars](std::unique_ptr<ISimpleExpression>& condition)
|
||||
const auto matchingCondition = std::find_if(rule->m_conditions.begin(), rule->m_conditions.end(), [&baseStateBits](const StateMapCondition& condition)
|
||||
{
|
||||
return condition->EvaluateNonStatic(&vars).IsTruthy();
|
||||
return ConditionIsTrue(condition, baseStateBits);
|
||||
});
|
||||
|
||||
return matchingCondition != rule->m_conditions.end();
|
||||
@ -57,27 +40,6 @@ void StateMapHandler::ApplyStateMap(const uint32_t* baseStateBits, uint32_t* out
|
||||
}
|
||||
}
|
||||
|
||||
StateMapVars StateMapHandler::BuildVars(const uint32_t* baseStateBits) const
|
||||
{
|
||||
StateMapVars result;
|
||||
|
||||
for (const auto& var : m_state_map_layout.m_var_layout.m_vars)
|
||||
{
|
||||
const auto baseStateBitField = baseStateBits[var.m_state_bits_index];
|
||||
const auto matchingValue = std::find_if(var.m_values.begin(), var.m_values.end(), [&baseStateBitField](const StateMapLayoutVarValue& value)
|
||||
{
|
||||
return (baseStateBitField & value.m_state_bits_mask) == value.m_state_bits_mask;
|
||||
});
|
||||
|
||||
if (matchingValue != var.m_values.end())
|
||||
result.AddValue(var.m_name, matchingValue->m_name);
|
||||
else
|
||||
std::cerr << "Could not find base value for state map var \"" << var.m_name << "\"\n";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void StateMapHandler::ApplyRule(const StateMapLayoutEntry& entry, const StateMapRule& rule, uint32_t* outStateBits)
|
||||
{
|
||||
if (rule.m_passthrough)
|
||||
@ -86,3 +48,15 @@ void StateMapHandler::ApplyRule(const StateMapLayoutEntry& entry, const StateMap
|
||||
outStateBits[entry.m_state_bits_index] &= ~entry.m_state_bits_mask;
|
||||
outStateBits[entry.m_state_bits_index] |= rule.m_value;
|
||||
}
|
||||
|
||||
bool StateMapHandler::ConditionIsTrue(const StateMapCondition& condition, const uint32_t* stateBits)
|
||||
{
|
||||
const auto stateBitCount = std::min(condition.m_masks_per_index.size(), condition.m_values_per_index.size());
|
||||
for (auto stateBitIndex = 0u; stateBitIndex < stateBitCount; stateBitIndex++)
|
||||
{
|
||||
if ((stateBits[stateBitIndex] & condition.m_masks_per_index[stateBitIndex]) != condition.m_values_per_index[stateBitIndex])
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1,24 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "Utils/ClassUtils.h"
|
||||
#include "StateMap/StateMapDefinition.h"
|
||||
#include "StateMap/StateMapLayout.h"
|
||||
|
||||
namespace state_map
|
||||
{
|
||||
class StateMapVars final : public ISimpleExpressionScopeValues
|
||||
{
|
||||
public:
|
||||
void AddValue(std::string key, std::string value);
|
||||
_NODISCARD SimpleExpressionValue ValueByName(const std::string& name) const override;
|
||||
|
||||
private:
|
||||
std::unordered_map<std::string, std::string> m_vars;
|
||||
};
|
||||
|
||||
class StateMapHandler
|
||||
{
|
||||
public:
|
||||
@ -27,8 +15,8 @@ namespace state_map
|
||||
void ApplyStateMap(const uint32_t* baseStateBits, uint32_t* outStateBits) const;
|
||||
|
||||
private:
|
||||
StateMapVars BuildVars(const uint32_t* baseStateBits) const;
|
||||
static void ApplyRule(const StateMapLayoutEntry& entry, const StateMapRule& rule, uint32_t* outStateBits);
|
||||
static bool ConditionIsTrue(const StateMapCondition& condition, const uint32_t* stateBits);
|
||||
|
||||
const StateMapLayout& m_state_map_layout;
|
||||
const StateMapDefinition& m_state_map;
|
||||
|
@ -5,7 +5,6 @@
|
||||
#include "Parsing/StateMapParser.h"
|
||||
#include "Parsing/Impl/CommentRemovingStreamProxy.h"
|
||||
#include "Parsing/Impl/ParserSingleInputStream.h"
|
||||
#include "Parsing/Matcher/StateMapExpressionMatchers.h"
|
||||
|
||||
using namespace state_map;
|
||||
|
||||
@ -51,7 +50,8 @@ std::unique_ptr<StateMapDefinition> StateMapReader::ReadStateMapDefinition() con
|
||||
lexerConfig.m_read_strings = false;
|
||||
lexerConfig.m_read_integer_numbers = true;
|
||||
lexerConfig.m_read_floating_point_numbers = false;
|
||||
StateMapExpressionMatchers().ApplyTokensToLexerConfig(lexerConfig);
|
||||
lexerConfig.m_multi_character_tokens.emplace_back(StateMapParser::MULTI_TOKEN_AND, "&&");
|
||||
lexerConfig.m_multi_character_tokens.emplace_back(StateMapParser::MULTI_TOKEN_EQUALS, "==");
|
||||
const auto lexer = std::make_unique<SimpleLexer>(m_comment_proxy.get(), std::move(lexerConfig));
|
||||
|
||||
const auto parser = std::make_unique<StateMapParser>(lexer.get(), m_state_map_name, m_state_map_layout);
|
||||
|
Loading…
x
Reference in New Issue
Block a user