ControlReference/ExpressionParser: separate parsing from binding
This commit is contained in:
parent
ba87a50338
commit
c332580b83
|
@ -31,7 +31,9 @@ void ControlReference::UpdateReference(const ciface::Core::DeviceContainer& devi
|
||||||
const ciface::Core::DeviceQualifier& default_device)
|
const ciface::Core::DeviceQualifier& default_device)
|
||||||
{
|
{
|
||||||
ControlFinder finder(devices, default_device, IsInput());
|
ControlFinder finder(devices, default_device, IsInput());
|
||||||
std::tie(m_parse_status, m_parsed_expression) = ParseExpression(expression, finder);
|
std::tie(m_parse_status, m_parsed_expression) = ParseExpression(expression);
|
||||||
|
if (m_parsed_expression)
|
||||||
|
m_parsed_expression->UpdateReferences(finder);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ControlReference::BoundCount() const
|
int ControlReference::BoundCount() const
|
||||||
|
|
|
@ -212,16 +212,11 @@ class ControlExpression : public Expression
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ControlQualifier qualifier;
|
ControlQualifier qualifier;
|
||||||
Device::Control* control;
|
Device::Control* control = nullptr;
|
||||||
// Keep a shared_ptr to the device so the control pointer doesn't become invalid
|
// Keep a shared_ptr to the device so the control pointer doesn't become invalid
|
||||||
std::shared_ptr<Device> m_device;
|
std::shared_ptr<Device> m_device;
|
||||||
|
|
||||||
ControlExpression(ControlQualifier qualifier_, std::shared_ptr<Device> device,
|
ControlExpression(ControlQualifier qualifier_) : qualifier(qualifier_) {}
|
||||||
Device::Control* control_)
|
|
||||||
: qualifier(qualifier_), control(control_), m_device(std::move(device))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ControlState GetValue() const override { return control ? control->ToInput()->GetState() : 0.0; }
|
ControlState GetValue() const override { return control ? control->ToInput()->GetState() : 0.0; }
|
||||||
void SetValue(ControlState value) override
|
void SetValue(ControlState value) override
|
||||||
{
|
{
|
||||||
|
@ -229,6 +224,11 @@ public:
|
||||||
control->ToOutput()->SetState(value);
|
control->ToOutput()->SetState(value);
|
||||||
}
|
}
|
||||||
int CountNumControls() const override { return control ? 1 : 0; }
|
int CountNumControls() const override { return control ? 1 : 0; }
|
||||||
|
void UpdateReferences(ControlFinder& finder) override
|
||||||
|
{
|
||||||
|
m_device = finder.FindDevice(qualifier);
|
||||||
|
control = finder.FindControl(qualifier);
|
||||||
|
}
|
||||||
operator std::string() const override { return "`" + static_cast<std::string>(qualifier) + "`"; }
|
operator std::string() const override { return "`" + static_cast<std::string>(qualifier) + "`"; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -276,6 +276,12 @@ public:
|
||||||
return lhs->CountNumControls() + rhs->CountNumControls();
|
return lhs->CountNumControls() + rhs->CountNumControls();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UpdateReferences(ControlFinder& finder) override
|
||||||
|
{
|
||||||
|
lhs->UpdateReferences(finder);
|
||||||
|
rhs->UpdateReferences(finder);
|
||||||
|
}
|
||||||
|
|
||||||
operator std::string() const override
|
operator std::string() const override
|
||||||
{
|
{
|
||||||
return OpName(op) + "(" + (std::string)(*lhs) + ", " + (std::string)(*rhs) + ")";
|
return OpName(op) + "(" + (std::string)(*lhs) + ", " + (std::string)(*rhs) + ")";
|
||||||
|
@ -319,6 +325,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
int CountNumControls() const override { return inner->CountNumControls(); }
|
int CountNumControls() const override { return inner->CountNumControls(); }
|
||||||
|
void UpdateReferences(ControlFinder& finder) override { inner->UpdateReferences(finder); }
|
||||||
operator std::string() const override { return OpName(op) + "(" + (std::string)(*inner) + ")"; }
|
operator std::string() const override { return OpName(op) + "(" + (std::string)(*inner) + ")"; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -346,6 +353,12 @@ public:
|
||||||
static_cast<std::string>(*m_rhs) + ')';
|
static_cast<std::string>(*m_rhs) + ')';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UpdateReferences(ControlFinder& finder) override
|
||||||
|
{
|
||||||
|
m_lhs->UpdateReferences(finder);
|
||||||
|
m_rhs->UpdateReferences(finder);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const std::unique_ptr<Expression>& GetActiveChild() const
|
const std::unique_ptr<Expression>& GetActiveChild() const
|
||||||
{
|
{
|
||||||
|
@ -390,16 +403,11 @@ struct ParseResult
|
||||||
class Parser
|
class Parser
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Parser(std::vector<Token> tokens_, ControlFinder& finder_) : tokens(tokens_), finder(finder_)
|
explicit Parser(std::vector<Token> tokens_) : tokens(tokens_) { m_it = tokens.begin(); }
|
||||||
{
|
|
||||||
m_it = tokens.begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
ParseResult Parse() { return Toplevel(); }
|
ParseResult Parse() { return Toplevel(); }
|
||||||
private:
|
private:
|
||||||
std::vector<Token> tokens;
|
std::vector<Token> tokens;
|
||||||
std::vector<Token>::iterator m_it;
|
std::vector<Token>::iterator m_it;
|
||||||
ControlFinder& finder;
|
|
||||||
|
|
||||||
Token Chew() { return *m_it++; }
|
Token Chew() { return *m_it++; }
|
||||||
Token Peek() { return *m_it; }
|
Token Peek() { return *m_it; }
|
||||||
|
@ -415,12 +423,7 @@ private:
|
||||||
switch (tok.type)
|
switch (tok.type)
|
||||||
{
|
{
|
||||||
case TOK_CONTROL:
|
case TOK_CONTROL:
|
||||||
{
|
return {ParseStatus::Successful, std::make_unique<ControlExpression>(tok.qualifier)};
|
||||||
std::shared_ptr<Device> device = finder.FindDevice(tok.qualifier);
|
|
||||||
Device::Control* control = finder.FindControl(tok.qualifier);
|
|
||||||
return {ParseStatus::Successful,
|
|
||||||
std::make_unique<ControlExpression>(tok.qualifier, std::move(device), control)};
|
|
||||||
}
|
|
||||||
case TOK_LPAREN:
|
case TOK_LPAREN:
|
||||||
return Paren();
|
return Paren();
|
||||||
default:
|
default:
|
||||||
|
@ -508,7 +511,7 @@ private:
|
||||||
ParseResult Toplevel() { return Binary(); }
|
ParseResult Toplevel() { return Binary(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
static ParseResult ParseComplexExpression(const std::string& str, ControlFinder& finder)
|
static ParseResult ParseComplexExpression(const std::string& str)
|
||||||
{
|
{
|
||||||
Lexer l(str);
|
Lexer l(str);
|
||||||
std::vector<Token> tokens;
|
std::vector<Token> tokens;
|
||||||
|
@ -516,29 +519,25 @@ static ParseResult ParseComplexExpression(const std::string& str, ControlFinder&
|
||||||
if (tokenize_status != ParseStatus::Successful)
|
if (tokenize_status != ParseStatus::Successful)
|
||||||
return {tokenize_status};
|
return {tokenize_status};
|
||||||
|
|
||||||
return Parser(tokens, finder).Parse();
|
return Parser(tokens).Parse();
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::unique_ptr<Expression> ParseBarewordExpression(const std::string& str,
|
static std::unique_ptr<Expression> ParseBarewordExpression(const std::string& str)
|
||||||
ControlFinder& finder)
|
|
||||||
{
|
{
|
||||||
ControlQualifier qualifier;
|
ControlQualifier qualifier;
|
||||||
qualifier.control_name = str;
|
qualifier.control_name = str;
|
||||||
qualifier.has_device = false;
|
qualifier.has_device = false;
|
||||||
|
|
||||||
std::shared_ptr<Device> device = finder.FindDevice(qualifier);
|
return std::make_unique<ControlExpression>(qualifier);
|
||||||
Device::Control* control = finder.FindControl(qualifier);
|
|
||||||
return std::make_unique<ControlExpression>(qualifier, std::move(device), control);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<ParseStatus, std::unique_ptr<Expression>> ParseExpression(const std::string& str,
|
std::pair<ParseStatus, std::unique_ptr<Expression>> ParseExpression(const std::string& str)
|
||||||
ControlFinder& finder)
|
|
||||||
{
|
{
|
||||||
if (StripSpaces(str).empty())
|
if (StripSpaces(str).empty())
|
||||||
return std::make_pair(ParseStatus::EmptyExpression, nullptr);
|
return std::make_pair(ParseStatus::EmptyExpression, nullptr);
|
||||||
|
|
||||||
auto bareword_expr = ParseBarewordExpression(str, finder);
|
auto bareword_expr = ParseBarewordExpression(str);
|
||||||
ParseResult complex_result = ParseComplexExpression(str, finder);
|
ParseResult complex_result = ParseComplexExpression(str);
|
||||||
|
|
||||||
if (complex_result.status != ParseStatus::Successful)
|
if (complex_result.status != ParseStatus::Successful)
|
||||||
{
|
{
|
||||||
|
|
|
@ -54,6 +54,7 @@ public:
|
||||||
virtual ControlState GetValue() const = 0;
|
virtual ControlState GetValue() const = 0;
|
||||||
virtual void SetValue(ControlState state) = 0;
|
virtual void SetValue(ControlState state) = 0;
|
||||||
virtual int CountNumControls() const = 0;
|
virtual int CountNumControls() const = 0;
|
||||||
|
virtual void UpdateReferences(ControlFinder& finder) = 0;
|
||||||
virtual operator std::string() const = 0;
|
virtual operator std::string() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -64,7 +65,6 @@ enum class ParseStatus
|
||||||
EmptyExpression,
|
EmptyExpression,
|
||||||
};
|
};
|
||||||
|
|
||||||
std::pair<ParseStatus, std::unique_ptr<Expression>> ParseExpression(const std::string& expr,
|
std::pair<ParseStatus, std::unique_ptr<Expression>> ParseExpression(const std::string& expr);
|
||||||
ControlFinder& finder);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue