diff --git a/lib/config/aexpression.cpp b/lib/config/aexpression.cpp index e7d977d23..982743584 100644 --- a/lib/config/aexpression.cpp +++ b/lib/config/aexpression.cpp @@ -102,8 +102,8 @@ void AExpression::FindDebugInfoPath(const std::vector& path, DebugInfo& void AExpression::MakeInline(void) { - ASSERT(m_Operator == &AExpression::OpDict); - m_Operand2 = true; + if (m_Operator == &AExpression::OpDict) + m_Operand2 = true; } Value AExpression::EvaluateOperand1(const Dictionary::Ptr& locals) const @@ -295,28 +295,62 @@ Value AExpression::OpSet(const Dictionary::Ptr& locals) const Value AExpression::OpSetPlus(const Dictionary::Ptr& locals) const { - Value result = locals->Get(m_Operand1) + EvaluateOperand2(locals); + Value left = locals->Get(m_Operand1); + AExpression::Ptr exp_right = m_Operand2; + Dictionary::Ptr xlocals = locals; + + if (exp_right->m_Operator == &AExpression::OpDict) + xlocals = left; + + Value result = left + EvaluateOperand2(xlocals); locals->Set(m_Operand1, result); return result; } Value AExpression::OpSetMinus(const Dictionary::Ptr& locals) const { - Value result = locals->Get(m_Operand1) - EvaluateOperand2(locals); + Value left = locals->Get(m_Operand1); + AExpression::Ptr exp_right = m_Operand2; + Dictionary::Ptr xlocals = locals; + + if (exp_right->m_Operator == &AExpression::OpDict) + xlocals = left; + + Value result = left - EvaluateOperand2(xlocals); locals->Set(m_Operand1, result); return result; } Value AExpression::OpSetMultiply(const Dictionary::Ptr& locals) const { - Value result = locals->Get(m_Operand1) * EvaluateOperand2(locals); + Value left = locals->Get(m_Operand1); + AExpression::Ptr exp_right = m_Operand2; + Dictionary::Ptr xlocals = locals; + + if (exp_right->m_Operator == &AExpression::OpDict) + xlocals = left; + + Value result = left * EvaluateOperand2(xlocals); locals->Set(m_Operand1, result); return result; } Value AExpression::OpSetDivide(const Dictionary::Ptr& locals) const { - Value result = locals->Get(m_Operand1) / EvaluateOperand2(locals); + Value left = locals->Get(m_Operand1); + AExpression::Ptr exp_right = m_Operand2; + Dictionary::Ptr xlocals = locals; + + if (exp_right->m_Operator == &AExpression::OpDict) + xlocals = left; + + Value result = left / EvaluateOperand2(xlocals); locals->Set(m_Operand1, result); return result; } + +Value AExpression::OpIndexer(const Dictionary::Ptr& locals) const +{ + Dictionary::Ptr dict = locals->Get(m_Operand1); + return dict->Get(m_Operand2); +} diff --git a/lib/config/aexpression.h b/lib/config/aexpression.h index 36c77a20e..4d388cb15 100644 --- a/lib/config/aexpression.h +++ b/lib/config/aexpression.h @@ -76,6 +76,7 @@ public: Value OpSetMinus(const Dictionary::Ptr& locals) const; Value OpSetMultiply(const Dictionary::Ptr& locals) const; Value OpSetDivide(const Dictionary::Ptr& locals) const; + Value OpIndexer(const Dictionary::Ptr& locals) const; private: OpCallback m_Operator; diff --git a/lib/config/config_parser.yy b/lib/config/config_parser.yy index 4381b8fb4..b297fc574 100644 --- a/lib/config/config_parser.yy +++ b/lib/config/config_parser.yy @@ -542,7 +542,11 @@ lterm_items_inner: /* empty */ lterm: T_IDENTIFIER lbinary_op rterm { - $$ = new Value(make_shared($2, $1, static_cast(*$3), DebugInfoRange(@1, @3))); + AExpression::Ptr aexpr = static_cast(*$3); + if ($2 == &AExpression::OpSetPlus || $2 == &AExpression::OpSetMinus || $2 == &AExpression::OpSetMultiply || $2 == &AExpression::OpSetDivide) + aexpr->MakeInline(); + + $$ = new Value(make_shared($2, $1, aexpr, DebugInfoRange(@1, @3))); delete $3; } | identifier '[' T_STRING ']' lbinary_op rterm @@ -555,7 +559,9 @@ lterm: T_IDENTIFIER lbinary_op rterm subexprl->Add(subexpr); AExpression::Ptr expr = make_shared(&AExpression::OpDict, subexprl, DebugInfoRange(@1, @6)); - + if ($5 == &AExpression::OpSetPlus || $5 == &AExpression::OpSetMinus || $5 == &AExpression::OpSetMultiply || $5 == &AExpression::OpSetDivide) + expr->MakeInline(); + $$ = new Value(make_shared(&AExpression::OpSetPlus, $1, expr, DebugInfoRange(@1, @6))); free($1); } @@ -660,6 +666,12 @@ rterm: T_STRING $$ = new Value(make_shared(&AExpression::OpNegate, static_cast(*$2), DebugInfoRange(@1, @2))); delete $2; } + | identifier '[' T_STRING ']' + { + $$ = new Value(make_shared(&AExpression::OpIndexer, $1, $3, DebugInfoRange(@1, @4))); + free($1); + free($3); + } | '[' rterm_items ']' { $$ = new Value(make_shared(&AExpression::OpArray, Array::Ptr($2), DebugInfoRange(@1, @3)));