diff options
Diffstat (limited to 'src/uscxml/plugins/datamodel/promela/PromelaDataModel.cpp')
-rw-r--r-- | src/uscxml/plugins/datamodel/promela/PromelaDataModel.cpp | 281 |
1 files changed, 162 insertions, 119 deletions
diff --git a/src/uscxml/plugins/datamodel/promela/PromelaDataModel.cpp b/src/uscxml/plugins/datamodel/promela/PromelaDataModel.cpp index a7d7755..aa32806 100644 --- a/src/uscxml/plugins/datamodel/promela/PromelaDataModel.cpp +++ b/src/uscxml/plugins/datamodel/promela/PromelaDataModel.cpp @@ -61,16 +61,13 @@ boost::shared_ptr<DataModelImpl> PromelaDataModel::create(InterpreterImpl* inter } void PromelaDataModel::registerIOProcessor(const std::string& name, const IOProcessor& ioprocessor) { -// std::cout << "PromelaDataModel::registerIOProcessor" << std::endl; } void PromelaDataModel::setSessionId(const std::string& sessionId) { -// std::cout << "PromelaDataModel::setSessionId" << std::endl; _sessionId = sessionId; } void PromelaDataModel::setName(const std::string& name) { -// std::cout << "PromelaDataModel::setName" << std::endl; _name = name; } @@ -102,13 +99,35 @@ bool PromelaDataModel::validate(const std::string& location, const std::string& } uint32_t PromelaDataModel::getLength(const std::string& expr) { - return 0; + if (!isDeclared(expr)) { + throwErrorExecution("Variable " + expr + " was not declared"); + } + + if (!_variables[expr].hasKey("size")) { + throwErrorExecution("Variable " + expr + " is no array"); + } + + return strTo<int>(_variables[expr]["size"].atom); } void PromelaDataModel::setForeach(const std::string& item, - const std::string& array, - const std::string& index, - uint32_t iteration) { + const std::string& array, + const std::string& index, + uint32_t iteration) { + // assign array element to item + std::stringstream ss; + ss << array << "[" << iteration << "]"; + + PromelaParser itemParser(item, PromelaParser::PROMELA_EXPR); + PromelaParser arrayParser(ss.str(), PromelaParser::PROMELA_EXPR); + + setVariable(itemParser.ast, getVariable(arrayParser.ast)); + + if (index.length() > 0) { + PromelaParser indexParser(index, PromelaParser::PROMELA_EXPR); + setVariable(indexParser.ast, iteration); + } + } void PromelaDataModel::eval(const Element<std::string>& scriptElem, const std::string& expr) { @@ -126,7 +145,7 @@ bool PromelaDataModel::evalAsBool(const Arabica::DOM::Node<std::string>& node, c // parser.dump(); return evaluateExpr(parser.ast) > 0; } - + std::string PromelaDataModel::evalAsString(const std::string& expr) { if (isDeclared(expr)) { return Data::toJSON(_variables[expr]); @@ -135,8 +154,8 @@ std::string PromelaDataModel::evalAsString(const std::string& expr) { } void PromelaDataModel::assign(const Element<std::string>& assignElem, - const Node<std::string>& node, - const std::string& content) { + const Node<std::string>& node, + const std::string& content) { PromelaParser parser(content, PromelaParser::PROMELA_DECL); evaluateDecl(parser.ast); // parser.dump(); @@ -151,10 +170,10 @@ void PromelaDataModel::evaluateDecl(void* ast) { PromelaParserNode* vis = *opIter++; PromelaParserNode* type = *opIter++; PromelaParserNode* varlist = *opIter++; - + for (std::list<PromelaParserNode*>::iterator nameIter = varlist->operands.begin(); - nameIter != varlist->operands.end(); - nameIter++) { + nameIter != varlist->operands.end(); + nameIter++) { Data variable; variable.compound["vis"] = Data(vis->value, Data::VERBATIM); variable.compound["type"] = Data(type->value, Data::VERBATIM); @@ -162,7 +181,7 @@ void PromelaDataModel::evaluateDecl(void* ast) { if (false) { } else if ((*nameIter)->type == NAME) { // plain variables without initial assignment - + if (type->value == "mtype") { variable.compound["value"] = Data(_lastMType++, Data::INTERPRETED); } else { @@ -172,7 +191,7 @@ void PromelaDataModel::evaluateDecl(void* ast) { } else if ((*nameIter)->type == ASGN) { // initially assigned variables - + std::list<PromelaParserNode*>::iterator opIterAsgn = (*nameIter)->operands.begin(); PromelaParserNode* name = *opIterAsgn++; PromelaParserNode* expr = *opIterAsgn++; @@ -183,16 +202,16 @@ void PromelaDataModel::evaluateDecl(void* ast) { _variables.compound[name->value] = variable; } else if ((*nameIter)->type == VAR_ARRAY) { // variable arrays - + std::list<PromelaParserNode*>::iterator opIterAsgn = (*nameIter)->operands.begin(); PromelaParserNode* name = *opIterAsgn++; int size = evaluateExpr(*opIterAsgn++); - + variable.compound["size"] = size; for (int i = 0; i < size; i++) { variable.compound["value"].array.push_back(Data(0, Data::INTERPRETED)); } - + assert(opIterAsgn == (*nameIter)->operands.end()); _variables.compound[name->value] = variable; @@ -203,8 +222,8 @@ void PromelaDataModel::evaluateDecl(void* ast) { assert(opIter == node->operands.end()); } else if (node->type == DECLLIST) { for (std::list<PromelaParserNode*>::iterator declIter = node->operands.begin(); - declIter != node->operands.end(); - declIter++) { + declIter != node->operands.end(); + declIter++) { evaluateDecl(*declIter); } } else { @@ -216,41 +235,41 @@ int PromelaDataModel::evaluateExpr(void* ast) { PromelaParserNode* node = (PromelaParserNode*)ast; std::list<PromelaParserNode*>::iterator opIter = node->operands.begin(); switch (node->type) { - case CONST: - return strTo<int>(node->value); - case NAME: - case VAR_ARRAY: - return getVariable(node); - case PLUS: - return evaluateExpr(*opIter++) + evaluateExpr(*opIter++); - case MINUS: - return evaluateExpr(*opIter++) - evaluateExpr(*opIter++); - case DIVIDE: - return evaluateExpr(*opIter++) / evaluateExpr(*opIter++); - case MODULO: - return evaluateExpr(*opIter++) % evaluateExpr(*opIter++); - case EQ: - return evaluateExpr(*opIter++) == evaluateExpr(*opIter++); - case LT: - return evaluateExpr(*opIter++) < evaluateExpr(*opIter++); - case LE: - return evaluateExpr(*opIter++) <= evaluateExpr(*opIter++); - case GT: - return evaluateExpr(*opIter++) > evaluateExpr(*opIter++); - case GE: - return evaluateExpr(*opIter++) >= evaluateExpr(*opIter++); - case TIMES: - return evaluateExpr(*opIter++) * evaluateExpr(*opIter++); - case LSHIFT: - return evaluateExpr(*opIter++) << evaluateExpr(*opIter++); - case RSHIFT: - return evaluateExpr(*opIter++) >> evaluateExpr(*opIter++); - case AND: - return evaluateExpr(*opIter++) != 0 && evaluateExpr(*opIter++) != 0; - case OR: - return evaluateExpr(*opIter++) != 0 || evaluateExpr(*opIter++) != 0; - default: - throwErrorExecution("Support for " + PromelaParserNode::typeToDesc(node->type) + " expressions not implemented"); + case CONST: + return strTo<int>(node->value); + case NAME: + case VAR_ARRAY: + return getVariable(node); + case PLUS: + return evaluateExpr(*opIter++) + evaluateExpr(*opIter++); + case MINUS: + return evaluateExpr(*opIter++) - evaluateExpr(*opIter++); + case DIVIDE: + return evaluateExpr(*opIter++) / evaluateExpr(*opIter++); + case MODULO: + return evaluateExpr(*opIter++) % evaluateExpr(*opIter++); + case EQ: + return evaluateExpr(*opIter++) == evaluateExpr(*opIter++); + case LT: + return evaluateExpr(*opIter++) < evaluateExpr(*opIter++); + case LE: + return evaluateExpr(*opIter++) <= evaluateExpr(*opIter++); + case GT: + return evaluateExpr(*opIter++) > evaluateExpr(*opIter++); + case GE: + return evaluateExpr(*opIter++) >= evaluateExpr(*opIter++); + case TIMES: + return evaluateExpr(*opIter++) * evaluateExpr(*opIter++); + case LSHIFT: + return evaluateExpr(*opIter++) << evaluateExpr(*opIter++); + case RSHIFT: + return evaluateExpr(*opIter++) >> evaluateExpr(*opIter++); + case AND: + return evaluateExpr(*opIter++) != 0 && evaluateExpr(*opIter++) != 0; + case OR: + return evaluateExpr(*opIter++) != 0 || evaluateExpr(*opIter++) != 0; + default: + throwErrorExecution("Support for " + PromelaParserNode::typeToDesc(node->type) + " expressions not implemented"); } return 0; } @@ -259,20 +278,20 @@ void PromelaDataModel::evaluateStmnt(void* ast) { PromelaParserNode* node = (PromelaParserNode*)ast; std::list<PromelaParserNode*>::iterator opIter = node->operands.begin(); switch (node->type) { - case ASGN: { - PromelaParserNode* name = *opIter++; - PromelaParserNode* expr = *opIter++; - setVariable(name, evaluateExpr(expr)); - break; - } - case STMNT: { - while(opIter != node->operands.end()) { - evaluateStmnt(*opIter++); - } - break; + case ASGN: { + PromelaParserNode* name = *opIter++; + PromelaParserNode* expr = *opIter++; + setVariable(name, evaluateExpr(expr)); + break; + } + case STMNT: { + while(opIter != node->operands.end()) { + evaluateStmnt(*opIter++); } - default: - throwErrorExecution("No support for " + PromelaParserNode::typeToDesc(node->type) + " statement implemented"); + break; + } + default: + throwErrorExecution("No support for " + PromelaParserNode::typeToDesc(node->type) + " statement implemented"); } } @@ -281,80 +300,104 @@ void PromelaDataModel::setVariable(void* ast, int value) { std::list<PromelaParserNode*>::iterator opIter = node->operands.begin(); switch (node->type) { - case VAR_ARRAY: { - PromelaParserNode* name = *opIter++; - PromelaParserNode* expr = *opIter++; - int index = evaluateExpr(expr); - - if (_variables.compound.find(name->value) == _variables.compound.end()) { - throwErrorExecution("No variable " + name->value + " was declared"); - } - - if (!_variables[name->value].hasKey("size")) { - throwErrorExecution("Variable " + name->value + " is no array"); - } + case VAR_ARRAY: { + PromelaParserNode* name = *opIter++; + PromelaParserNode* expr = *opIter++; + int index = evaluateExpr(expr); - if (strTo<int>(_variables[name->value]["size"].atom) <= index) { - throwErrorExecution("Index " + toStr(index) + " in array " + name->value + "[" + _variables[name->value]["size"].atom + "] is out of bounds"); - } + if (_variables.compound.find(name->value) == _variables.compound.end()) { + throwErrorExecution("No variable " + name->value + " was declared"); + } - _variables.compound[name->value].compound["value"][index] = Data(value, Data::VERBATIM); - - break; + if (!_variables[name->value].hasKey("size")) { + throwErrorExecution("Variable " + name->value + " is no array"); } - case NAME: - _variables.compound[node->value].compound["value"] = Data(value, Data::VERBATIM); - break; - default: - break; + + if (strTo<int>(_variables[name->value]["size"].atom) <= index) { + throwErrorExecution("Index " + toStr(index) + " in array " + name->value + "[" + _variables[name->value]["size"].atom + "] is out of bounds"); + } + + _variables.compound[name->value].compound["value"][index] = Data(value, Data::VERBATIM); + + break; } - + case NAME: + _variables.compound[node->value].compound["value"] = Data(value, Data::VERBATIM); + break; + default: + break; + } + // std::cout << Data::toJSON(_variables) << std::endl; } int PromelaDataModel::getVariable(void* ast) { PromelaParserNode* node = (PromelaParserNode*)ast; // node->dump(); - + std::list<PromelaParserNode*>::iterator opIter = node->operands.begin(); switch(node->type) { - case NAME: - if (_variables.compound.find(node->value) == _variables.compound.end()) { - throwErrorExecution("No variable " + node->value + " was declared"); - } - return strTo<int>(_variables[node->value]["value"]); - case VAR_ARRAY: { - PromelaParserNode* name = *opIter++; - PromelaParserNode* expr = *opIter++; - int index = evaluateExpr(expr); - - if (_variables.compound.find(name->value) == _variables.compound.end()) { - throwErrorExecution("No variable " + name->value + " was declared"); - } - - if (!_variables[name->value].hasKey("size")) { - throwErrorExecution("Variable " + name->value + " is no array"); - } - - if (strTo<int>(_variables[name->value]["size"].atom) <= index) { - throwErrorExecution("Index " + toStr(index) + " in array " + name->value + "[" + _variables[name->value]["size"].atom + "] is out of bounds"); - } - return _variables.compound[name->value].compound["value"][index]; + case NAME: + if (_variables.compound.find(node->value) == _variables.compound.end()) { + throwErrorExecution("No variable " + node->value + " was declared"); } - default: - throwErrorExecution("Retrieving value of " + PromelaParserNode::typeToDesc(node->type) + " variable not implemented"); + if (_variables[node->value].compound.find("size") != _variables[node->value].compound.end()) { + throwErrorExecution("Type error: Variable " + node->value + " is an array"); + } + return strTo<int>(_variables[node->value]["value"].atom); + case VAR_ARRAY: { + PromelaParserNode* name = *opIter++; + PromelaParserNode* expr = *opIter++; + int index = evaluateExpr(expr); + + if (_variables.compound.find(name->value) == _variables.compound.end()) { + throwErrorExecution("No variable " + name->value + " was declared"); + } + + if (!_variables[name->value].hasKey("size")) { + throwErrorExecution("Variable " + name->value + " is no array"); + } + + if (strTo<int>(_variables[name->value]["size"].atom) <= index) { + throwErrorExecution("Index " + toStr(index) + " in array " + name->value + "[" + _variables[name->value]["size"].atom + "] is out of bounds"); + } + return strTo<int>(_variables.compound[name->value].compound["value"][index].atom); + } + default: + throwErrorExecution("Retrieving value of " + PromelaParserNode::typeToDesc(node->type) + " variable not implemented"); } return 0; } +std::string PromelaDataModel::andExpressions(std::list<std::string> expressions) { + + if (expressions.size() == 0) + return ""; + + if (expressions.size() == 1) + return *(expressions.begin()); + + std::ostringstream exprSS; + exprSS << "("; + std::string conjunction = ""; + for (std::list<std::string>::const_iterator exprIter = expressions.begin(); + exprIter != expressions.end(); + exprIter++) { + exprSS << conjunction << "(" << *exprIter << ")"; + conjunction = " && "; + } + exprSS << ")"; + return exprSS.str(); +} + void PromelaDataModel::assign(const std::string& location, const Data& data) { // used for e.g. to assign command line parameters std::cout << "Ignoring " << location << " = " << Data::toJSON(data) << std::endl; } void PromelaDataModel::init(const Element<std::string>& dataElem, - const Node<std::string>& node, - const std::string& content) { + const Node<std::string>& node, + const std::string& content) { // from <datamodel> assign(dataElem, node, content); } |