diff options
Diffstat (limited to 'src/uscxml/plugins/datamodel')
6 files changed, 112 insertions, 38 deletions
diff --git a/src/uscxml/plugins/datamodel/promela/PromelaDataModel.cpp b/src/uscxml/plugins/datamodel/promela/PromelaDataModel.cpp index 593aadc..a7d7755 100644 --- a/src/uscxml/plugins/datamodel/promela/PromelaDataModel.cpp +++ b/src/uscxml/plugins/datamodel/promela/PromelaDataModel.cpp @@ -128,6 +128,9 @@ bool PromelaDataModel::evalAsBool(const Arabica::DOM::Node<std::string>& node, c } std::string PromelaDataModel::evalAsString(const std::string& expr) { + if (isDeclared(expr)) { + return Data::toJSON(_variables[expr]); + } return expr; } @@ -135,12 +138,12 @@ void PromelaDataModel::assign(const Element<std::string>& assignElem, const Node<std::string>& node, const std::string& content) { PromelaParser parser(content, PromelaParser::PROMELA_DECL); - declare(parser.ast); + evaluateDecl(parser.ast); // parser.dump(); // std::cout << Data::toJSON(_variables) << std::endl; } -void PromelaDataModel::declare(void* ast) { +void PromelaDataModel::evaluateDecl(void* ast) { PromelaParserNode* node = (PromelaParserNode*)ast; if (false) { } else if (node->type == DECL) { @@ -194,7 +197,7 @@ void PromelaDataModel::declare(void* ast) { _variables.compound[name->value] = variable; } else { - assert(false); + throwErrorExecution("Declaring variables via " + PromelaParserNode::typeToDesc((*nameIter)->type) + " not implemented"); } } assert(opIter == node->operands.end()); @@ -202,8 +205,10 @@ void PromelaDataModel::declare(void* ast) { for (std::list<PromelaParserNode*>::iterator declIter = node->operands.begin(); declIter != node->operands.end(); declIter++) { - declare(*declIter); + evaluateDecl(*declIter); } + } else { + throwErrorExecution("Declaring variables via " + PromelaParserNode::typeToDesc(node->type) + " not implemented"); } } @@ -214,6 +219,7 @@ int PromelaDataModel::evaluateExpr(void* ast) { case CONST: return strTo<int>(node->value); case NAME: + case VAR_ARRAY: return getVariable(node); case PLUS: return evaluateExpr(*opIter++) + evaluateExpr(*opIter++); @@ -239,9 +245,14 @@ int PromelaDataModel::evaluateExpr(void* ast) { 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: - assert(false); + throwErrorExecution("Support for " + PromelaParserNode::typeToDesc(node->type) + " expressions not implemented"); } + return 0; } void PromelaDataModel::evaluateStmnt(void* ast) { @@ -261,26 +272,79 @@ void PromelaDataModel::evaluateStmnt(void* ast) { break; } default: - assert(false); + throwErrorExecution("No support for " + PromelaParserNode::typeToDesc(node->type) + " statement implemented"); } } void PromelaDataModel::setVariable(void* ast, int value) { PromelaParserNode* node = (PromelaParserNode*)ast; - _variables.compound[node->value].compound["value"] = Data(value, Data::VERBATIM); + + 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"); + } + + 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(); - if (_variables.compound.find(node->value) == _variables.compound.end()) { - uscxml::Event exc; - exc.data.compound["exception"] = uscxml::Data("No variable " + node->value + " was declared", uscxml::Data::VERBATIM); - exc.name = "error.execution"; - exc.eventType = uscxml::Event::PLATFORM; - throw exc; + 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]; + } + default: + throwErrorExecution("Retrieving value of " + PromelaParserNode::typeToDesc(node->type) + " variable not implemented"); } - return strTo<int>(_variables[node->value]["value"]); + return 0; } void PromelaDataModel::assign(const std::string& location, const Data& data) { diff --git a/src/uscxml/plugins/datamodel/promela/PromelaDataModel.h b/src/uscxml/plugins/datamodel/promela/PromelaDataModel.h index aaafa9b..e6a7894 100644 --- a/src/uscxml/plugins/datamodel/promela/PromelaDataModel.h +++ b/src/uscxml/plugins/datamodel/promela/PromelaDataModel.h @@ -82,7 +82,7 @@ public: protected: - void declare(void* ast); + void evaluateDecl(void* ast); int evaluateExpr(void* ast); void evaluateStmnt(void* ast); diff --git a/src/uscxml/plugins/datamodel/promela/PromelaParser.cpp b/src/uscxml/plugins/datamodel/promela/PromelaParser.cpp index ba89e14..a27d2df 100644 --- a/src/uscxml/plugins/datamodel/promela/PromelaParser.cpp +++ b/src/uscxml/plugins/datamodel/promela/PromelaParser.cpp @@ -9,37 +9,44 @@ int promela_lex_init (void**); \ int promela_lex_destroy (void*); \ void promela_error (uscxml::PromelaParser* ctx, void* yyscanner, const char* err) { - uscxml::Event exceptionEvent; - exceptionEvent.data.compound["exception"] = uscxml::Data(err, uscxml::Data::VERBATIM); - exceptionEvent.name = "error.execution"; - exceptionEvent.eventType = uscxml::Event::PLATFORM; - throw exceptionEvent; + uscxml::Event excEvent; + excEvent.data.compound["exception"] = uscxml::Data(err, uscxml::Data::VERBATIM); + excEvent.name = "error.execution"; + excEvent.eventType = uscxml::Event::PLATFORM; + throw excEvent; } namespace uscxml { +PromelaParser::PromelaParser(const std::string& expr) { + init(expr); +} + PromelaParser::PromelaParser(const std::string& expr, Type expectedType) { + init(expr); + if (type != expectedType) { + std::stringstream ss; + ss << "Promela syntax type mismatch: Expected " << typeToDesc(expectedType) << " but got " << typeToDesc(type); + + uscxml::Event excEvent; + excEvent.data.compound["exception"] = uscxml::Data(ss.str(), uscxml::Data::VERBATIM); + excEvent.name = "error.execution"; + excEvent.eventType = uscxml::Event::PLATFORM; + throw excEvent; + } +} + +void PromelaParser::init(const std::string& expr) { input_length = expr.length() + 5; // plus some zero terminators input = (char*) calloc(1, input_length); memcpy(input, expr.c_str(), expr.length()); - + promela_lex_init(&scanner); // promela_assign_set_extra(ast, &scanner); promela__scan_buffer(input, input_length, scanner); promela_parse(this, scanner); - - if (type != expectedType) { - std::stringstream ss; - ss << "Promela syntax type mismatch: Expected " << typeToDesc(expectedType) << " but got " << typeToDesc(type); - - uscxml::Event exceptionEvent; - exceptionEvent.data.compound["exception"] = uscxml::Data(ss.str(), uscxml::Data::VERBATIM); - exceptionEvent.name = "error.execution"; - exceptionEvent.eventType = uscxml::Event::PLATFORM; - throw exceptionEvent; - } } - + PromelaParser::~PromelaParser() { free(input); promela_lex_destroy(scanner); diff --git a/src/uscxml/plugins/datamodel/promela/PromelaParser.h b/src/uscxml/plugins/datamodel/promela/PromelaParser.h index 6daa154..0cca365 100644 --- a/src/uscxml/plugins/datamodel/promela/PromelaParser.h +++ b/src/uscxml/plugins/datamodel/promela/PromelaParser.h @@ -64,6 +64,7 @@ public: static std::string typeToDesc(int type); + PromelaParser(const std::string& expr); PromelaParser(const std::string& expr, Type expectedType); virtual ~PromelaParser(); @@ -104,7 +105,9 @@ public: Type type; protected: - + + void init(const std::string& expr); + void* scanner; char* input; size_t input_length; diff --git a/src/uscxml/plugins/datamodel/promela/parser/promela.tab.cpp b/src/uscxml/plugins/datamodel/promela/parser/promela.tab.cpp index 10bef82..5cdcec1 100644 --- a/src/uscxml/plugins/datamodel/promela/parser/promela.tab.cpp +++ b/src/uscxml/plugins/datamodel/promela/parser/promela.tab.cpp @@ -1671,13 +1671,13 @@ yyreduce: case 6: /* Line 1787 of yacc.c */ #line 101 "promela.ypp" - { (yyval.node) = ctx->value(NAME, yylval.value); } + { (yyval.node) = ctx->value(NAME, (yyvsp[(1) - (1)].value)); } break; case 7: /* Line 1787 of yacc.c */ #line 102 "promela.ypp" - {} + { (yyval.node) = ctx->node(VAR_ARRAY, 2, ctx->value(NAME, (yyvsp[(1) - (4)].value)), (yyvsp[(3) - (4)].node)); } break; case 8: diff --git a/src/uscxml/plugins/datamodel/promela/parser/promela.ypp b/src/uscxml/plugins/datamodel/promela/parser/promela.ypp index 6147d40..b33ebd1 100644 --- a/src/uscxml/plugins/datamodel/promela/parser/promela.ypp +++ b/src/uscxml/plugins/datamodel/promela/parser/promela.ypp @@ -98,8 +98,8 @@ program : varref : cmpnd {} ; -pfld : NAME { $$ = ctx->value(NAME, yylval.value); } - | NAME '[' expr ']' {} +pfld : NAME { $$ = ctx->value(NAME, $1); } + | NAME '[' expr ']' { $$ = ctx->node(VAR_ARRAY, 2, ctx->value(NAME, $1), $3); } ; cmpnd : pfld {} |