initial support for if blocks (no else)

sayer/1.4-spce2.6
Matthew Williams 16 years ago committed by Mathew Williams
parent dab65232ec
commit f4b8287436

@ -43,7 +43,7 @@ bool DSMChartReader::is_wsp(const char c) {
}
bool DSMChartReader::is_snt(const char c) {
return c== ';' || c == '{' || c == '}';
return c== ';' || c == '{' || c == '}' || c == '[' || c == ']';
}
string DSMChartReader::getToken(string str, size_t& pos) {
@ -219,16 +219,44 @@ bool DSMChartReader::decode(DSMStateDiagram* e, const string& chart,
stack.push_back(new DSMTransition());
continue;
}
if (stack.empty()) {
if (token == ";")
continue;
continue;
ERROR("Without context I do not understand '%s'\n", token.c_str());
return false;
}
DSMElement* stack_top = &(*stack.back());
DSMConditionTree* ct = dynamic_cast<DSMConditionTree*>(stack_top);
if (ct) {
if (token == "[") {
stack.push_back(new DSMConditionList());
continue;
}
if (token == "{") {
stack.push_back(new ActionList(ActionList::AL_if));
continue;
}
if (token == ";") {
stack.pop_back();
ActionList* al = dynamic_cast<ActionList*>(&(*stack.back()));
if (al) {
owner->transferElem(ct);
al->actions.push_back(ct);
DBG("Added DSMConditionTree to ActionList\n");
} else {
ERROR("no ActionList for DSMConditionTree\n");
delete al;
return false;
}
continue;
}
}
State* state = dynamic_cast<State*>(stack_top);
if (state) {
if (!state->name.length()) {
@ -237,6 +265,7 @@ bool DSMChartReader::decode(DSMStateDiagram* e, const string& chart,
continue;
}
if (token == "enter") {
DBG("adding 'enter' actions for state '%s'\n", state->name.c_str());
stack.push_back(new ActionList(ActionList::AL_enter));
continue;
}
@ -261,116 +290,150 @@ bool DSMChartReader::decode(DSMStateDiagram* e, const string& chart,
continue;
}
ActionList* al = dynamic_cast<ActionList*>(stack_top);
if (al) {
if (token == ";") {
continue;
ActionList* al = dynamic_cast<ActionList*>(stack_top);
if (al) {
if (token == ";") {
continue;
}
if (token == "{") {
continue;
}
if ((token == "}") || (token == "->")) {
stack.pop_back();
if (stack.empty()) {
ERROR("no item for action list\n");
delete al;
return false;
}
if (al->al_type == ActionList::AL_if ||
al->al_type == ActionList::AL_else) {
DSMConditionTree* ct = dynamic_cast<DSMConditionTree*>(&(*stack.back()));
if (!ct) {
ERROR("no DSMConditionTree for action list\n");
delete al;
return false;
}
if (al->al_type == ActionList::AL_if) {
ct->run_if_true = al->actions;
} else if (al->al_type == ActionList::AL_else) {
ct->run_if_false = al->actions;
}
} else if (al->al_type == ActionList::AL_enter ||
al->al_type == ActionList::AL_exit) {
State* s = dynamic_cast<State*>(&(*stack.back()));
if (!s) {
ERROR("no State for action list\n");
delete al;
return false;
}
if (al->al_type == ActionList::AL_enter) {
s->pre_actions = al->actions;
} else if (al->al_type == ActionList::AL_exit) {
s->post_actions = al->actions;
}
} else if (al->al_type == ActionList::AL_trans) {
DSMTransition* t = dynamic_cast<DSMTransition*>(&(*stack.back()));
if (!t) {
ERROR("no DSMTransition for action list\n");
delete al;
return false;
}
t->actions = al->actions;
} else {
ERROR("internal: unknown transition list type\n");
}
delete al;
continue;
}
if (token == "{") {
continue;
}
if ((token == "}") || (token == "->")) {
stack.pop_back();
if (stack.empty()) {
ERROR("no item for action list\n");
delete al;
return false;
}
if (al->al_type == ActionList::AL_enter ||
al->al_type == ActionList::AL_exit) {
State* s = dynamic_cast<State*>(&(*stack.back()));
if (!s) {
ERROR("no State for action list\n");
delete al;
return false;
}
if (al->al_type == ActionList::AL_enter)
s->pre_actions = al->actions;
else if (al->al_type == ActionList::AL_exit)
s->post_actions = al->actions;
} else if (al->al_type == ActionList::AL_trans) {
DSMTransition* t = dynamic_cast<DSMTransition*>(&(*stack.back()));
if (!t) {
ERROR("no DSMTransition for action list\n");
delete al;
return false;
}
t->actions = al->actions;
} else {
ERROR("internal: unknown transition list type\n");
}
delete al;
continue;
}
// token is action
// DBG("adding action '%s'\n", token.c_str());
DSMAction* a = actionFromToken(token);
if (!a)
return false;
owner->transferElem(a);
al->actions.push_back(a);
continue;
}
if (token == "if") {
//token is condition tree
stack.push_back(new DSMConditionTree());
continue;
} else {
// token is action
DBG("adding action '%s'\n", token.c_str());
DSMAction* a = actionFromToken(token);
if (!a)
return false;
owner->transferElem(a);
al->actions.push_back(a);
continue;
}
}
DSMConditionList* cl = dynamic_cast<DSMConditionList*>(stack_top);
if (cl) {
if (token == ";")
continue;
continue;
if ((token == "{") || (token == "}")) {
// readability
continue;
// readability
continue;
}
if ((token == "/") || (token == "->")) {
// end of condition list
stack.pop_back();
if (stack.empty()) {
ERROR("no transition to apply conditions to\n");
delete cl;
return false;
}
DSMTransition* tr = dynamic_cast<DSMTransition*>(&(*stack.back()));
if (!tr) {
ERROR("no transition to apply conditions to\n");
delete cl;
return false;
}
tr->precond = cl->conditions;
tr->is_exception = cl->is_exception;
delete cl;
// start AL_trans action list
if (token == "/") {
stack.push_back(new ActionList(ActionList::AL_trans));
}
continue;
if ((token == "/") || (token == "->") || (token == "]")) {
// end of condition list
stack.pop_back();
if (stack.empty()) {
ERROR("nothing to apply conditions to\n");
delete cl;
return false;
}
DSMElement* el = &(*stack.back());
DSMTransition* tr = dynamic_cast<DSMTransition*>(el);
DSMConditionTree* ct = dynamic_cast<DSMConditionTree*>(el);
if (tr) {
tr->precond = cl->conditions;
tr->is_exception = cl->is_exception;
} else if (ct) {
ct->conditions = cl->conditions;
ct->is_exception = cl->is_exception;
} else {
ERROR("no transition or condition list to apply conditions to\n");
delete cl;
return false;
}
delete cl;
// start AL_trans action list
if (token == "/") {
stack.push_back(new ActionList(ActionList::AL_trans));
}
continue;
}
if (token == "not") {
cl->invert_next = !cl->invert_next;
continue;
cl->invert_next = !cl->invert_next;
continue;
}
if (token == "exception") {
cl->is_exception = true;
continue;
cl->is_exception = true;
continue;
}
// DBG("new condition: '%s'\n", token.c_str());
DBG("new condition: '%s'\n", token.c_str());
DSMCondition* c = conditionFromToken(token, cl->invert_next);
cl->invert_next = false;
if (!c)
return false;
return false;
owner->transferElem(c);
cl->conditions.push_back(c);
continue;
}
DSMTransition* tr = dynamic_cast<DSMTransition*>(stack_top);
if (tr) {
if (!tr->name.length()) {

@ -57,7 +57,9 @@ class ActionList : public DSMElement {
enum AL_type {
AL_enter,
AL_exit,
AL_trans
AL_trans,
AL_if,
AL_else
};
AL_type al_type;
@ -65,7 +67,7 @@ class ActionList : public DSMElement {
ActionList(AL_type al_type)
: al_type(al_type) { }
vector<DSMAction*> actions;
vector<DSMElement*> actions;
};
struct DSMConditionList : public DSMElement {

@ -46,11 +46,11 @@ DSMStateDiagram::~DSMStateDiagram() {
void DSMStateDiagram::addState(const State& state, bool is_initial) {
DBG("adding state '%s'\n", state.name.c_str());
for (vector<DSMAction*>::const_iterator it=
for (vector<DSMElement*>::const_iterator it=
state.pre_actions.begin(); it != state.pre_actions.end(); it++) {
DBG(" pre-action '%s'\n", (*it)->name.c_str());
}
for (vector<DSMAction*>::const_iterator it=
for (vector<DSMElement*>::const_iterator it=
state.post_actions.begin(); it != state.post_actions.end(); it++) {
DBG(" post-action '%s'\n", (*it)->name.c_str());
}
@ -75,7 +75,7 @@ bool DSMStateDiagram::addTransition(const DSMTransition& trans) {
DBG(" DSMCondition %s'%s'\n",
(*it)->invert?"not ":"", (*it)->name.c_str());
}
for (vector<DSMAction*>::const_iterator it=
for (vector<DSMElement*>::const_iterator it=
trans.actions.begin(); it != trans.actions.end(); it++) {
DBG(" Action '%s'\n", (*it)->name.c_str());
}
@ -224,42 +224,70 @@ void DSMStateEngine::onBeforeDestroy(DSMSession* sc_sess, AmSession* sess) {
(*it)->onBeforeDestroy(sc_sess, sess);
}
bool DSMStateEngine::runactions(vector<DSMAction*>::iterator from,
vector<DSMAction*>::iterator to,
bool DSMStateEngine::runactions(vector<DSMElement*>::iterator from,
vector<DSMElement*>::iterator to,
AmSession* sess, DSMSession* sc_sess, DSMCondition::EventType event,
map<string,string>* event_params, bool& is_consumed) {
// DBG("running %zd actions\n", to - from);
for (vector<DSMAction*>::iterator it=from; it != to; it++) {
DBG("executing '%s'\n", (*it)->name.c_str());
if ((*it)->execute(sess, sc_sess, event, event_params)) {
string se_modifier;
switch ((*it)->getSEAction(se_modifier,
sess, sc_sess, event, event_params)) {
case DSMAction::Repost:
is_consumed = false;
break;
case DSMAction::Jump:
DBG("jumping to %s\n", se_modifier.c_str());
if (jumpDiag(se_modifier, sess, sc_sess, event, event_params)) {
// is_consumed = false;
return true;
} break;
case DSMAction::Call:
DBG("calling %s\n", se_modifier.c_str());
if (callDiag(se_modifier, sess, sc_sess, event, event_params)) {
// is_consumed = false;
return true;
} break;
case DSMAction::Return:
if (returnDiag(sess, sc_sess)) {
//is_consumed = false;
return true;
} break;
default: break;
for (vector<DSMElement*>::iterator it=from; it != to; it++) {
DSMConditionTree* cond_tree = dynamic_cast<DSMConditionTree*>(*it);
if (cond_tree) {
DBG("checking conditions\n");
vector<DSMCondition*>::iterator con=cond_tree->conditions.begin();
while (con!=cond_tree->conditions.end()) {
if (!(*con)->_match(sess, sc_sess, event, event_params))
break;
con++;
}
if (con == cond_tree->conditions.end()) {
DBG("condition tree matched.\n");
if (runactions(cond_tree->run_if_true.begin(), cond_tree->run_if_true.end(),
sess, sc_sess, event, event_params, is_consumed))
return true;
} else {
if(runactions(cond_tree->run_if_false.begin(), cond_tree->run_if_false.end(),
sess, sc_sess, event, event_params, is_consumed))
return true;
}
}
DSMAction* dsm_act = dynamic_cast<DSMAction*>(*it);
if (dsm_act) {
DBG("executing '%s'\n", (dsm_act)->name.c_str());
if ((dsm_act)->execute(sess, sc_sess, event, event_params)) {
string se_modifier;
switch ((dsm_act)->getSEAction(se_modifier,
sess, sc_sess, event, event_params)) {
case DSMAction::Repost:
is_consumed = false;
break;
case DSMAction::Jump:
DBG("jumping to %s\n", se_modifier.c_str());
if (jumpDiag(se_modifier, sess, sc_sess, event, event_params)) {
// is_consumed = false;
return true;
}
break;
case DSMAction::Call:
DBG("calling %s\n", se_modifier.c_str());
if (callDiag(se_modifier, sess, sc_sess, event, event_params)) {
// is_consumed = false;
return true;
}
break;
case DSMAction::Return:
if (returnDiag(sess, sc_sess)) {
//is_consumed = false;
return true;
}
break;
default: break;
}
}
}
}
return false;
}

@ -141,8 +141,8 @@ class State
public:
State();
~State();
vector<DSMAction*> pre_actions;
vector<DSMAction*> post_actions;
vector<DSMElement*> pre_actions;
vector<DSMElement*> post_actions;
vector<DSMTransition> transitions;
};
@ -154,13 +154,22 @@ class DSMTransition
~DSMTransition();
vector<DSMCondition*> precond;
vector<DSMAction*> actions;
vector<DSMElement*> actions;
string from_state;
string to_state;
bool is_exception;
};
class DSMConditionTree
: public DSMElement {
public:
vector<DSMCondition*> conditions;
vector<DSMElement*> run_if_true;
vector<DSMElement*> run_if_false;
bool is_exception;
};
class DSMModule;
class DSMStateDiagram {
@ -224,8 +233,8 @@ class DSMStateEngine {
DSMCondition::EventType event,
map<string,string>* event_params);
bool returnDiag(AmSession* sess, DSMSession* sc_sess);
bool runactions(vector<DSMAction*>::iterator from,
vector<DSMAction*>::iterator to,
bool runactions(vector<DSMElement*>::iterator from,
vector<DSMElement*>::iterator to,
AmSession* sess, DSMSession* sc_sess, DSMCondition::EventType event,
map<string,string>* event_params, bool& is_consumed);

Loading…
Cancel
Save