DSM: implement for ($x in range(2, 5))

Development sponsored by TelTech Systems Inc.
sayer/1.4-spce2.6
Stefan Sayer 16 years ago
parent d90e76a7d3
commit 26db3fae33

@ -167,19 +167,43 @@ bool DSMChartReader::forFromToken(DSMArrayFor& af, const string& token) {
return false;
}
af.array_struct = forh_v[1];
vector<string> kv = explode(forh_v[0], ",");
if (kv.size() == 2) {
af.for_type = DSMArrayFor::Struct;
af.k = kv[0];
af.v = kv[1];
af.array_struct = forh_v[1];
DBG("for (%s,%s in %s) {\n", af.k.c_str(), af.v.c_str(), af.array_struct.c_str());
} else if (forh_v[1].length() > 7 &&
forh_v[1].substr(0,6)=="range(" &&
forh_v[1][forh_v[1].length()-1] == ')') {
af.for_type = DSMArrayFor::Range;
string range_s = forh_v[1].substr(6, forh_v[1].length()-7);
vector<string> range_v = explode(range_s, ",");
if (range_v.size() == 2) {
if (!str2int(range_v[0], af.range[0]) ||
!str2int(range_v[1], af.range[1])) {
ERROR("range(%s,%s) not understood in for\n",
range_v[0].c_str(), range_v[1].c_str());
return false;
}
} else {
af.range[0] = 0;
if (!str2int(range_s, af.range[1])) {
ERROR("range(%s) not understood in for\n", range_s.c_str());
return false;
}
}
af.k = forh_v[0];
DBG("for (%s in range(%d, %d) {\n",
af.k.c_str(), af.range[0], af.range[1]);
} else {
af.for_type = DSMArrayFor::Array;
af.array_struct = forh_v[1];
af.k = forh_v[0];
DBG("for (%s in %s) {\n", af.k.c_str(), af.array_struct.c_str());
}
return true;
}

@ -291,29 +291,39 @@ bool DSMStateEngine::runactions(vector<DSMElement*>::iterator from,
DSMArrayFor* array_for = dynamic_cast<DSMArrayFor*>(*it);
if (array_for) {
DBG("running for (%s%s in %s) {\n",
array_for->k.c_str(), array_for->v.empty() ? "" : (","+array_for->v).c_str(),
array_for->array_struct.c_str());
if (array_for->for_type == DSMArrayFor::Range) {
DBG("running for (%s in range(%d, %d) {\n",
array_for->k.c_str(), array_for->range[0], array_for->range[1]);
} else {
DBG("running for (%s%s in %s) {\n",
array_for->k.c_str(), array_for->v.empty() ? "" : (","+array_for->v).c_str(),
array_for->array_struct.c_str());
}
string array_name = array_for->array_struct;
string k_name = array_for->k;
string v_name = array_for->v;
if (!array_name.length() || !k_name.length()) {
WARN("empty array or counter name in for\n");
if (!k_name.length()) {
ERROR("empty counter name in for\n");
continue;
}
if (array_for->for_type != DSMArrayFor::Range && !array_name.length()) {
ERROR("empty array name in for\n");
continue;
}
if (array_name[0] == '$') array_name.erase(0, 1);
if (k_name[0] == '$') k_name.erase(0, 1);
bool is_kv = !v_name.empty();
if (is_kv && v_name[0] == '$') v_name.erase(0, 1);
if (array_for->for_type == DSMArrayFor::Struct && v_name[0] == '$')
v_name.erase(0, 1);
vector<pair<string, string> > cnt_values;
// get the counter values
if (is_kv) {
if (array_for->for_type == DSMArrayFor::Struct) {
VarMapT::iterator lb = sc_sess->var.lower_bound(array_name);
while (lb != sc_sess->var.end()) {
if ((lb->first.length() < array_name.length()) ||
@ -326,7 +336,7 @@ bool DSMStateEngine::runactions(vector<DSMElement*>::iterator from,
DBG(" '%s,%s'\n", varname.c_str(), valname.c_str());
lb++;
}
} else {
} else if (array_for->for_type == DSMArrayFor::Array) {
unsigned int a_index = 0;
while (true) {
VarMapT::iterator v = sc_sess->var.find(array_name+"["+int2str(a_index)+"]");
@ -338,13 +348,14 @@ bool DSMStateEngine::runactions(vector<DSMElement*>::iterator from,
}
}
// save counter
// save counter k
VarMapT::iterator c_it = sc_sess->var.find(k_name);
bool k_exists = c_it != sc_sess->var.end();
string k_save = k_exists ? c_it->second : string("");
// save counter v for Struct
bool v_exists = false; string v_save;
if (is_kv) {
if (array_for->for_type == DSMArrayFor::Struct) {
c_it = sc_sess->var.find(v_name);
v_exists = c_it != sc_sess->var.end();
if (v_exists)
@ -352,28 +363,46 @@ bool DSMStateEngine::runactions(vector<DSMElement*>::iterator from,
}
// run the loop
DBG("running for loop with %zd items\n", cnt_values.size());
for (vector<pair<string, string> >::iterator f_it=
cnt_values.begin(); f_it != cnt_values.end(); f_it++) {
if (is_kv) {
DBG("setting $%s=%s, $%s=%s\n", k_name.c_str(), f_it->first.c_str(),
v_name.c_str(), f_it->second.c_str());
sc_sess->var[k_name] = f_it->first;
sc_sess->var[v_name] = f_it->second;
} else {
DBG("setting $%s=%s\n", k_name.c_str(), f_it->first.c_str());
sc_sess->var[k_name] = f_it->first;
if (array_for->for_type == DSMArrayFor::Range) {
int cnt = array_for->range[0];
while (cnt != array_for->range[1]) {
sc_sess->var[k_name] = int2str(cnt);
DBG("setting $%s=%s\n", k_name.c_str(), sc_sess->var[k_name].c_str());
runactions(array_for->actions.begin(), array_for->actions.end(),
sess, sc_sess, event, event_params, is_consumed);
if (array_for->range[1] > array_for->range[0])
cnt++;
else
cnt--;
}
} else {
DBG("running for loop with %zd items\n", cnt_values.size());
for (vector<pair<string, string> > ::iterator f_it=
cnt_values.begin(); f_it != cnt_values.end(); f_it++) {
if (array_for->for_type == DSMArrayFor::Struct) {
DBG("setting $%s=%s, $%s=%s\n", k_name.c_str(), f_it->first.c_str(),
v_name.c_str(), f_it->second.c_str());
sc_sess->var[k_name] = f_it->first;
sc_sess->var[v_name] = f_it->second;
} else {
DBG("setting $%s=%s\n", k_name.c_str(), f_it->first.c_str());
sc_sess->var[k_name] = f_it->first;
}
runactions(array_for->actions.begin(), array_for->actions.end(),
sess, sc_sess, event, event_params, is_consumed);
}
runactions(array_for->actions.begin(), array_for->actions.end(),
sess, sc_sess, event, event_params, is_consumed);
}
// restore the counter[s]
if (k_exists)
sc_sess->var[k_name] = k_save;
else
sc_sess->var.erase(k_name);
if (is_kv) {
if (array_for->for_type == DSMArrayFor::Struct) {
if (v_exists)
sc_sess->var[v_name] = v_save;
else

@ -180,8 +180,18 @@ class DSMFunction
class DSMArrayFor
: public DSMElement {
public:
DSMArrayFor() { }
~DSMArrayFor() { }
enum DSMForType {
Range,
Array,
Struct
} for_type;
string k; // for(k in array)
string v; // if set, for(k,v in struct)
string v; // for(k,v in struct)
int range[2];
string array_struct; // array or struct name
vector<DSMElement*> actions;
};

Loading…
Cancel
Save