tahoma2d/toonz/sources/common/expressions/texpression.cpp

195 lines
5.8 KiB
C++
Raw Normal View History

2016-03-19 06:57:51 +13:00
// TnzBase includes
#include "tgrammar.h"
#include "tparser.h"
#include "tunit.h"
#include "texpression.h"
using namespace TSyntax;
//**********************************************************************************
// TExpression::Imp definition
//**********************************************************************************
2016-06-15 18:43:10 +12:00
class TExpression::Imp {
2016-03-19 06:57:51 +13:00
public:
2016-06-15 18:43:10 +12:00
const Grammar *m_grammar; //!< (not owned) The expression's grammar
TDoubleParam *m_param; //!< (not owned) The expression's owner
Calculator *m_calculator; //!< (owned) Expression calculator object
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
std::string m_text; //!< Text content
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
std::string m_error; //!< Description of an error in the expression's text
std::pair<int, int>
m_errorPos; //!< Position of the error in the expression's text
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
bool m_isValid, //!< Whether the expression is valid
2020-04-17 19:02:53 +12:00
m_hasBeenParsed, //!< Whether the expression has already been parsed
m_hasReference;
2016-03-19 06:57:51 +13:00
public:
2016-06-15 18:43:10 +12:00
Imp()
: m_grammar(0)
, m_param(0)
, m_calculator(0)
, m_errorPos(0, -1)
, m_isValid(false)
2020-04-17 19:02:53 +12:00
, m_hasBeenParsed(true)
, m_hasReference(false) {}
2016-06-15 18:43:10 +12:00
~Imp() { delete m_calculator; }
2016-03-19 06:57:51 +13:00
};
//**********************************************************************************
// TExpression implementation
//**********************************************************************************
2016-06-15 18:43:10 +12:00
TExpression::TExpression() : m_imp(new Imp()) {}
2016-03-19 06:57:51 +13:00
//--------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
TExpression::~TExpression() {}
2016-03-19 06:57:51 +13:00
//--------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
TExpression::TExpression(const TExpression &src) : m_imp(new Imp()) {
m_imp->m_grammar = src.m_imp->m_grammar;
m_imp->m_param = src.m_imp->m_param;
m_imp->m_text = src.m_imp->m_text;
m_imp->m_calculator = 0;
m_imp->m_isValid = src.m_imp->m_isValid;
m_imp->m_error = src.m_imp->m_error;
m_imp->m_errorPos = src.m_imp->m_errorPos;
m_imp->m_hasBeenParsed = false;
2020-04-17 19:02:53 +12:00
m_imp->m_hasReference = src.m_imp->m_hasReference;
2016-03-19 06:57:51 +13:00
}
//--------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
TExpression &TExpression::operator=(TExpression copy) {
std::swap(copy.m_imp, m_imp);
return *this;
2016-03-19 06:57:51 +13:00
}
//--------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void TExpression::setGrammar(const TSyntax::Grammar *grammar) {
m_imp->m_grammar = grammar;
m_imp->m_hasBeenParsed = false;
2016-03-19 06:57:51 +13:00
}
//--------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
const TSyntax::Grammar *TExpression::getGrammar() const {
return m_imp->m_grammar;
2016-03-19 06:57:51 +13:00
}
//--------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void TExpression::setText(std::string text) {
2020-04-17 19:02:53 +12:00
if (m_imp->m_text != text || m_imp->m_hasReference) {
2016-06-15 18:43:10 +12:00
m_imp->m_text = text;
delete m_imp->m_calculator;
m_imp->m_calculator = 0;
m_imp->m_isValid = false;
2020-04-17 19:02:53 +12:00
m_imp->m_hasReference = false;
2016-06-15 18:43:10 +12:00
m_imp->m_hasBeenParsed = false;
m_imp->m_error = "";
m_imp->m_errorPos = std::make_pair(0, -1);
}
2016-03-19 06:57:51 +13:00
}
//--------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
std::string TExpression::getText() const { return m_imp->m_text; }
2016-03-19 06:57:51 +13:00
//--------------------------------------------------------------------------
// note: unit is used by the CycleNode node only
2016-06-15 18:43:10 +12:00
TSyntax::Calculator *TExpression::getCalculator() {
if (!m_imp->m_hasBeenParsed) parse();
if (m_imp->m_isValid && m_imp->m_calculator)
return m_imp->m_calculator;
else
return 0;
2016-03-19 06:57:51 +13:00
}
//--------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
bool TExpression::isValid() {
if (!m_imp->m_hasBeenParsed) parse();
return m_imp->m_isValid;
2016-03-19 06:57:51 +13:00
}
//--------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
std::string TExpression::getError() const { return m_imp->m_error; }
2016-03-19 06:57:51 +13:00
//--------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
std::pair<int, int> TExpression::getErrorPos() const {
return m_imp->m_errorPos;
2016-03-19 06:57:51 +13:00
}
//--------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void TExpression::accept(TSyntax::CalculatorNodeVisitor &visitor) {
if (!m_imp->m_hasBeenParsed) parse();
if (m_imp->m_isValid && m_imp->m_calculator)
m_imp->m_calculator->accept(visitor);
2016-03-19 06:57:51 +13:00
}
//--------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void TExpression::parse() {
delete m_imp->m_calculator;
m_imp->m_calculator = 0;
2016-03-19 06:57:51 +13:00
2020-04-17 19:02:53 +12:00
m_imp->m_errorPos = std::make_pair(0, -1);
m_imp->m_error = std::string();
m_imp->m_hasReference = false;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
if (!m_imp->m_grammar) {
m_imp->m_error = "No grammar defined";
m_imp->m_isValid = false;
} else {
Parser parser(m_imp->m_grammar);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
m_imp->m_calculator = parser.parse(m_imp->m_text);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
if (m_imp->m_calculator)
m_imp->m_calculator->setOwnerParameter(m_imp->m_param);
2016-03-19 06:57:51 +13:00
2020-04-17 19:02:53 +12:00
m_imp->m_isValid = parser.isValid();
m_imp->m_hasReference = parser.hasReference();
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
if (!m_imp->m_isValid) {
m_imp->m_error = parser.getError();
m_imp->m_errorPos = parser.getErrorPos();
}
}
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
m_imp->m_hasBeenParsed = true;
2016-03-19 06:57:51 +13:00
}
//--------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void TExpression::setOwnerParameter(TDoubleParam *param) {
m_imp->m_param = param;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
if (m_imp->m_calculator) m_imp->m_calculator->setOwnerParameter(param);
2016-03-19 06:57:51 +13:00
}
//--------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
TDoubleParam *TExpression::getOwnerParameter() const { return m_imp->m_param; }
2016-03-19 06:57:51 +13:00
//--------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
bool TExpression::isCycling() const {
// TODO: this is a quick&dirty implementation to be replaced with a more
// "semantic" one
return getText().find("cycle") != std::string::npos;
2016-03-19 06:57:51 +13:00
}