ControlReference/ExpressionParser: separate parsing from binding

This commit is contained in:
Michael M 2017-06-07 18:48:17 -07:00
parent ba87a50338
commit c332580b83
3 changed files with 34 additions and 33 deletions

View File

@ -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

View File

@ -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)
{ {

View File

@ -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);
} }
} }