1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
|
/* $Id$
*
* Wait conditions: Checks sensitivity lists and wait statements, and
* transforms sensitivity lists into wait statements.
*
* Copyright (C) 2008-2009 FAUmachine Team <info@faumachine.org>.
* This program is free software. You can redistribute it and/or modify it
* under the terms of the GNU General Public License, either version 2 of
* the License, or (at your option) any later version. See COPYING.
*/
#include "frontend/visitor/WaitConditions.hpp"
#include "frontend/ast/Process.hpp"
#include "frontend/ast/WaitStat.hpp"
#include "frontend/ast/ProcCallStat.hpp"
#include "frontend/ast/ProcedureDeclaration.hpp"
#include "frontend/reporting/ErrorRegistry.hpp"
namespace ast {
WaitConditions::WaitConditions() : sensList(NULL), waitSeen(false)
{
}
void
WaitConditions::visit(Process &node)
{
// wait statement AND sensitivityList -> ERROR
// no wait statement AND sensitivityList empty -> WARNING
//
// semantics of a wait:
// time := now() + timeout
// loop
// trigger(self, time)
// trigger_sig(self, signal_list)
// suspend()
// time1 := now()
// exit if time1 >= time -- timeout
// exit if condition -- condition met
// end loop
this->sensList = node.sensitivityList;
this->waitSeen = false;
if (node.seqStats != NULL) {
this->listTraverse(*node.seqStats);
}
if ((this->sensList == NULL) && (! this->waitSeen)) {
std::string msg = "";
if (node.name != NULL) {
msg += *node.name;
msg += " ";
}
msg += "contains no wait statement, possible infinite loop";
CompileError *ce =
new CompileError(node, msg);
ErrorRegistry::addWarning(ce);
}
if ((this->sensList != NULL) && (! this->waitSeen)) {
assert(! this->sensList->empty());
WaitStat *ws = new WaitStat(this->sensList, NULL, NULL,
this->sensList->front()->location);
if (node.seqStats == NULL) {
node.seqStats = new std::list<SeqStat*>();
}
node.seqStats->push_back(ws);
}
this->sensList = NULL;
this->waitSeen = false;
node.sensitivityList = NULL;
}
void
WaitConditions::visit(WaitStat &node)
{
this->waitSeen = true;
if (this->sensList != NULL) {
CompileError *ce = new CompileError(node,
"Wait statement and sensitivity list present.");
ErrorRegistry::addError(ce);
}
// TODO construct sensitivity list if empty from condition. (LRM 8.1)
}
void
WaitConditions::visit(ProcCallStat &node)
{
assert(node.definition != NULL);
if (node.definition->containsWait) {
this->waitSeen = true;
if (this->sensList != NULL) {
CompileError *ce = new CompileError(node,
"Wait statement via procedure call, but "
"sensitivity list present.");
ErrorRegistry::addError(ce);
}
}
}
void
WaitConditions::visit(ProcedureDeclaration &node)
{
if (node.definition != NULL) {
this->sensList = NULL;
this->waitSeen = false;
node.definition->accept(*this);
node.containsWait = this->waitSeen;
this->waitSeen = false;
}
}
}; /* namespace ast */
|