00001
00002
00003
00004 #include "runner.h"
00005
00006 #include <boost/scoped_ptr.hpp>
00007
00008 #include "cparser.h"
00009 #include "eparser.h"
00010 #include "logic.h"
00011 #include "tplate.h"
00012 #include "func.h"
00013 #include "data.h"
00014 #include "fityk.h"
00015 #include "info.h"
00016 #include "fit.h"
00017 #include "model.h"
00018 #include "guess.h"
00019 #include "transform.h"
00020
00021 using namespace std;
00022
00023 RealRange args2range(const Token& t1, const Token& t2)
00024 {
00025 RealRange range;
00026 if (t1.type == kTokenExpr)
00027 range.from = t1.value.d;
00028 if (t2.type == kTokenExpr)
00029 range.to = t2.value.d;
00030 return range;
00031 }
00032
00033 VMData* Runner::get_vm_from_token(const Token& t) const
00034 {
00035 assert (t.type == kTokenEVar);
00036 return &(*vdlist_)[t.value.i];
00037 }
00038
00039 void Runner::command_set(const vector<Token>& args)
00040 {
00041 SettingsMgr *sm = F_->settings_mgr();
00042 for (size_t i = 1; i < args.size(); i += 2) {
00043 string key = args[i-1].as_string();
00044 if (args[i].type == kTokenExpr)
00045 sm->set_as_number(key, args[i].value.d);
00046 else
00047 sm->set_as_string(key, Lexer::get_string(args[i]));
00048 }
00049 }
00050
00051 void Runner::command_undefine(const vector<Token>& args)
00052 {
00053 v_foreach (Token, i, args)
00054 F_->get_tpm()->undefine(i->as_string());
00055 }
00056
00057 void Runner::command_delete(const vector<Token>& args)
00058 {
00059 vector<int> dd;
00060 vector<string> vars, funcs, files;
00061 v_foreach (Token, i, args) {
00062 if (i->type == kTokenDataset)
00063 dd.push_back(i->value.i);
00064 else if (i->type == kTokenFuncname)
00065 funcs.push_back(Lexer::get_string(*i));
00066 else if (i->type == kTokenVarname)
00067 vars.push_back(Lexer::get_string(*i));
00068 else if (i->type == kTokenFilename || i->type == kTokenString)
00069 files.push_back(Lexer::get_string(*i));
00070 else
00071 assert(0);
00072 }
00073 if (!dd.empty()) {
00074 sort(dd.rbegin(), dd.rend());
00075 v_foreach (int, j, dd)
00076 F_->remove_dm(*j);
00077 }
00078 F_->delete_funcs(funcs);
00079 F_->delete_variables(vars);
00080 v_foreach (string, f, files) {
00081
00082 int r = remove(f->c_str());
00083 if (r != 0)
00084 F_->vmsg("Cannot remove file: " + *f);
00085 }
00086 if (!dd.empty() || !funcs.empty())
00087 F_->outdated_plot();
00088 }
00089
00090 void Runner::command_delete_points(const vector<Token>& args, int ds)
00091 {
00092 assert(args.size() == 1);
00093 Lexer lex(args[0].str);
00094 ep_.clear_vm();
00095 ep_.parse_expr(lex, ds);
00096
00097 Data *data = F_->get_data(ds);
00098 const vector<Point>& p = data->points();
00099 int len = data->points().size();
00100 vector<Point> new_p;
00101 new_p.reserve(len);
00102 for (int n = 0; n != len; ++n) {
00103 double val = ep_.calculate(n, p);
00104 if (fabs(val) < 0.5)
00105 new_p.push_back(p[n]);
00106 }
00107 data->set_points(new_p);
00108 F_->outdated_plot();
00109 }
00110
00111 void Runner::command_exec(TokenType tt, const string& str)
00112 {
00113
00114 if (tt == kTokenRest) {
00115 #ifdef HAVE_POPEN
00116 FILE* f = NULL;
00117 f = popen(str.c_str(), "r");
00118 if (!f)
00119 return;
00120 F_->get_ui()->exec_stream(f);
00121 pclose(f);
00122 #else
00123 F_->warn ("popen() was disabled during compilation.");
00124 #endif
00125 }
00126
00127
00128 else {
00129 F_->get_ui()->exec_script(str);
00130 }
00131 }
00132
00133 void Runner::read_dms(vector<Token>::const_iterator first,
00134 vector<Token>::const_iterator last,
00135 vector<DataAndModel*>& dms)
00136 {
00137 while (first != last) {
00138 assert(first->type == kTokenDataset);
00139 int d = first->value.i;
00140 if (d == Lexer::kAll) {
00141 dms = F_->get_dms();
00142 return;
00143 }
00144 else
00145 dms.push_back(F_->get_dm(d));
00146 ++first;
00147 }
00148 }
00149
00150 void Runner::command_fit(const vector<Token>& args, int ds)
00151 {
00152 if (args.empty()) {
00153 F_->get_fit()->fit(-1, vector1(F_->get_dm(ds)));
00154 F_->outdated_plot();
00155 }
00156 else if (args[0].type == kTokenDataset) {
00157 vector<DataAndModel*> dms;
00158 read_dms(args.begin(), args.end(), dms);
00159 F_->get_fit()->fit(-1, dms);
00160 F_->outdated_plot();
00161 }
00162 else if (args[0].type == kTokenNumber) {
00163 int n_steps = iround(args[0].value.d);
00164 vector<DataAndModel*> dms;
00165 if (args.size() > 1)
00166 read_dms(args.begin() + 1, args.end(), dms);
00167 else
00168 dms.push_back(F_->get_dm(ds));
00169 F_->get_fit()->fit(n_steps, dms);
00170 F_->outdated_plot();
00171 }
00172 else if (args[0].type == kTokenPlus) {
00173 int n_steps = iround(args[1].value.d);
00174 F_->get_fit()->continue_fit(n_steps);
00175 F_->outdated_plot();
00176 }
00177 else if (args[0].as_string() == "undo") {
00178 F_->get_fit_container()->load_param_history(-1, true);
00179 F_->outdated_plot();
00180 }
00181 else if (args[0].as_string() == "redo") {
00182 F_->get_fit_container()->load_param_history(+1, true);
00183 F_->outdated_plot();
00184 }
00185 else if (args[0].as_string() == "clear_history") {
00186 F_->get_fit_container()->clear_param_history();
00187 }
00188 else if (args[0].as_string() == "history") {
00189 int n = iround(args[1].value.d);
00190 F_->get_fit_container()->load_param_history(n, false);
00191 F_->outdated_plot();
00192 }
00193 }
00194
00195
00196 void Runner::command_guess(const vector<Token>& args, int ds)
00197 {
00198 DataAndModel* dm = F_->get_dm(ds);
00199 Data const* data = dm->data();
00200
00201 string name;
00202 int ignore_idx = -1;
00203 if (args[0].type == kTokenFuncname) {
00204 name = Lexer::get_string(args[0]);
00205 ignore_idx = F_->find_function_nr(name);
00206 }
00207 else
00208 name = F_->next_func_name();
00209
00210
00211 assert (args[1].type == kTokenCname);
00212 string ftype = args[1].as_string();
00213 Tplate::Ptr tp = F_->get_tpm()->get_shared_tp(ftype);
00214 if (!tp)
00215 throw ExecuteError("undefined function type: " + ftype);
00216
00217
00218 vector<string> par_names;
00219 vector<VMData*> par_values;
00220 for (size_t n = 2; n < args.size() - 3; n += 2) {
00221 assert (args[n].type == kTokenLname);
00222 par_names.push_back(args[n].as_string());
00223 par_values.push_back(get_vm_from_token(args[n+1]));
00224 }
00225 vector<VMData*> func_args = reorder_args(tp, par_names, par_values);
00226
00227
00228 RealRange range = args2range(*(args.end()-2), *(args.end()-1));
00229 if (range.from >= range.to)
00230 throw ExecuteError("invalid range");
00231
00232
00233 int lb = data->get_lower_bound_ac(range.from);
00234 int rb = data->get_upper_bound_ac(range.to);
00235 Guess g(F_->get_settings());
00236 g.initialize(dm, lb, rb, ignore_idx);
00237
00238
00239 vector<string> gkeys;
00240 vector<realt> gvals;
00241 if (tp->peak_d) {
00242 boost::array<double,4> peak_v = g.estimate_peak_parameters();
00243 gkeys.insert(gkeys.end(), Guess::peak_traits.begin(),
00244 Guess::peak_traits.end());
00245 gvals.insert(gvals.end(), peak_v.begin(), peak_v.end());
00246 }
00247 if (tp->linear_d) {
00248 boost::array<double,3> lin_v = g.estimate_linear_parameters();
00249 gkeys.insert(gkeys.end(), Guess::linear_traits.begin(),
00250 Guess::linear_traits.end());
00251 gvals.insert(gvals.end(), lin_v.begin(), lin_v.end());
00252 }
00253
00254
00255 vector<VMData> vd_storage(tp->fargs.size());
00256 for (size_t i = 0; i < tp->fargs.size(); ++i) {
00257 if (func_args[i] != NULL)
00258 continue;
00259 string dv = tp->defvals[i].empty() ? tp->fargs[i] : tp->defvals[i];
00260 ep_.clear_vm();
00261 Lexer lex(dv.c_str());
00262 bool r = ep_.parse_full(lex, 0, &gkeys);
00263 if (!r)
00264 throw ExecuteError("Cannot guess `" + dv + "' in " + tp->name);
00265 double value = ep_.calculate_custom(gvals);
00266 vd_storage[i].append_code(OP_TILDE);
00267 vd_storage[i].append_number(value);
00268 func_args[i] = &vd_storage[i];
00269 }
00270
00271
00272 int idx = F_->assign_func(name, tp, func_args);
00273
00274 FunctionSum& ff = dm->model()->get_ff();
00275 if (!contains_element(ff.names, name)) {
00276 ff.names.push_back(name);
00277 ff.idx.push_back(idx);
00278 }
00279 F_->use_parameters();
00280 F_->outdated_plot();
00281 }
00282
00283 void Runner::command_plot(const vector<Token>& args, int ds)
00284 {
00285 RealRange hor = args2range(args[0], args[1]);
00286 RealRange ver = args2range(args[2], args[3]);
00287 vector<int> dd;
00288 if (args.size() > 4) {
00289 for (size_t i = 4; i < args.size(); ++i) {
00290 int n = args[i].value.i;
00291 if (n == Lexer::kAll)
00292 for (int j = 0; j != F_->get_dm_count(); ++j)
00293 dd.push_back(j);
00294 else
00295 dd.push_back(n);
00296 }
00297 }
00298 else
00299 dd.push_back(ds);
00300 F_->view.change_view(hor, ver, dd);
00301 F_->get_ui()->draw_plot(UserInterface::kRepaintImmediately);
00302 }
00303
00304 void Runner::command_dataset_tr(const vector<Token>& args)
00305 {
00306 assert(args.size() == 2);
00307 assert(args[0].type == kTokenDataset);
00308 assert(args[1].type == kTokenExpr);
00309 int n = args[0].value.i;
00310 Lexer lex(args[1].str);
00311 ep_.clear_vm();
00312 ep_.parse_expr(lex, F_->default_dm(), NULL, NULL,
00313 ExpressionParser::kDatasetTrMode);
00314 DatasetTransformer dt(F_);
00315 dt.run_dt(ep_.vm(), n);
00316 F_->outdated_plot();
00317 }
00318
00319
00320 int Runner::make_func_from_template(const string& name,
00321 const vector<Token>& args, int pos)
00322 {
00323 string ftype = args[pos].as_string();
00324 vector<string> par_names;
00325 vector<VMData*> par_values;
00326 for (size_t n = pos+1; n < args.size(); n += 2) {
00327 if (args[n].type != kTokenLname && args[n].type != kTokenNop)
00328 break;
00329 if (args[n].type == kTokenLname)
00330 par_names.push_back(args[n].as_string());
00331 par_values.push_back(get_vm_from_token(args[n+1]));
00332 }
00333 if (!par_names.empty() && par_names.size() != par_values.size())
00334 throw ExecuteError("mixed keyword and non-keyword args");
00335 Tplate::Ptr tp = F_->get_tpm()->get_shared_tp(ftype);
00336 if (!tp)
00337 throw ExecuteError("undefined type of function: " + ftype);
00338 vector<VMData*> func_args;
00339 vector<VMData> vd_storage(tp->fargs.size());
00340 if (par_names.empty())
00341 func_args = par_values;
00342 else {
00343 func_args = reorder_args(tp, par_names, par_values);
00344
00345
00346
00347 vector<realt> cvals(par_values.size());
00348 vector<realt> dummy;
00349 for (size_t i = 0; i != par_values.size(); ++i)
00350 cvals[i] = run_code_for_variable(*par_values[i], F_->variables(),
00351 dummy);
00352
00353 for (size_t i = 0; i != tp->fargs.size(); ++i) {
00354 if (func_args[i] != NULL)
00355 continue;
00356
00357
00358 if (!tp->defvals.empty() && !tp->defvals[i].empty()) {
00359 string dv = tp->defvals[i];
00360 ep_.clear_vm();
00361 Lexer lex(dv.c_str());
00362 bool r = ep_.parse_full(lex, 0, &par_names);
00363 if (!r)
00364 throw ExecuteError("Cannot calculate `" + dv + "' in "
00365 + tp->name);
00366 double value = ep_.calculate_custom(cvals);
00367 vd_storage[i].append_code(OP_TILDE);
00368 vd_storage[i].append_number(value);
00369 func_args[i] = &vd_storage[i];
00370 }
00371 else
00372 throw ExecuteError("missing parameter " + tp->fargs[i]);
00373 }
00374 }
00375 F_->assign_func(name, tp, func_args);
00376 return par_values.size();
00377 }
00378
00379 static
00380 string get_func(const Ftk *F, int ds, vector<Token>::const_iterator a)
00381 {
00382 if (a->type == kTokenFuncname)
00383 return Lexer::get_string(*a);
00384 else {
00385 assert (a->type == kTokenDataset || a->type == kTokenNop);
00386 assert((a+1)->type == kTokenUletter);
00387 assert((a+2)->type == kTokenExpr);
00388 assert((a+1)->type == kTokenUletter);
00389 if (a->type == kTokenDataset)
00390 ds = a->value.i;
00391 char c = *(a+1)->str;
00392 int idx = iround((a+2)->value.d);
00393 return F->get_model(ds)->get_func_name(c, idx);
00394 }
00395 }
00396
00397
00398 void Runner::command_name_func(const vector<Token>& args, int ds)
00399 {
00400 string name = Lexer::get_string(args[0]);
00401 if (args[1].as_string() == "copy") {
00402 string orig_name = get_func(F_, ds, args.begin()+2);
00403 F_->assign_func_copy(name, orig_name);
00404 }
00405 else
00406 make_func_from_template(name, args, 1);
00407 F_->use_parameters();
00408 F_->outdated_plot();
00409 }
00410
00411 void Runner::command_assign_param(const vector<Token>& args, int ds)
00412 {
00413
00414
00415 string name = get_func(F_, ds, args.begin());
00416 string param = (args.end()-2)->as_string();
00417 const Token& var = *(args.end()-1);
00418 F_->substitute_func_param(name, param, get_vm_from_token(var));
00419 F_->use_parameters();
00420 F_->outdated_plot();
00421 }
00422
00423 void Runner::command_assign_all(const vector<Token>& args, int ds)
00424 {
00425
00426 assert(args[0].type == kTokenDataset || args[0].type == kTokenNop);
00427 assert(args[1].type == kTokenUletter);
00428 assert(args[2].type == kTokenMult);
00429 assert(args[3].type == kTokenLname);
00430 assert(args[4].type == kTokenEVar);
00431 if (args[0].type == kTokenDataset)
00432 ds = args[0].value.i;
00433 char c = *args[1].str;
00434 string param = args[3].as_string();
00435 VMData* vd = get_vm_from_token(args[4]);
00436 const FunctionSum& fz = F_->get_model(ds)->get_fz(c);
00437 v_foreach (string, i, fz.names) {
00438 if (contains_element(F_->find_function(*i)->tp()->fargs, param))
00439 F_->substitute_func_param(*i, param, vd);
00440 }
00441 F_->use_parameters();
00442 F_->outdated_plot();
00443 }
00444
00445 void Runner::command_name_var(const vector<Token>& args)
00446 {
00447 assert(args.size() == 4);
00448 assert(args[0].type == kTokenVarname);
00449 string name = Lexer::get_string(args[0]);
00450 VMData* vd = get_vm_from_token(args[1]);
00451 RealRange domain = args2range(args[2], args[3]);
00452 int pos = F_->make_variable(name, vd);
00453 F_->get_variable(pos)->domain = domain;
00454 F_->use_parameters();
00455 F_->outdated_plot();
00456 }
00457
00458 static
00459 int get_fz_or_func(const Ftk *F, int ds, vector<Token>::const_iterator a,
00460 vector<string>& added)
00461 {
00462
00463
00464 if (a->type == kTokenFuncname) {
00465 added.push_back(Lexer::get_string(*a));
00466 return 1;
00467 }
00468 else if (a->type == kTokenDataset || a->type == kTokenNop) {
00469 int r_ds = a->type == kTokenDataset ? a->value.i : ds;
00470 const Model* model = F->get_model(r_ds);
00471 assert((a+1)->type == kTokenUletter);
00472 char c = *(a+1)->str;
00473 if ((a+2)->type == kTokenNop) {
00474 const FunctionSum& s = model->get_fz(c);
00475 added.insert(added.end(), s.names.begin(), s.names.end());
00476 }
00477 else {
00478 int idx = iround((a+2)->value.d);
00479 added.push_back(model->get_func_name(c, idx));
00480 }
00481 return 3;
00482 }
00483 else
00484 return 0;
00485 }
00486
00487 static
00488 void add_functions_to(const Ftk* F, vector<string> const &names,
00489 FunctionSum& sum)
00490 {
00491 v_foreach (string, i, names) {
00492 int n = F->find_function_nr(*i);
00493 if (n == -1)
00494 throw ExecuteError("undefined function: %" + *i);
00495 if (contains_element(sum.names, *i))
00496 throw ExecuteError("%" + *i + " added twice");
00497 sum.names.push_back(*i);
00498 sum.idx.push_back(n);
00499 }
00500 }
00501
00502
00503 void Runner::command_change_model(const vector<Token>& args, int ds)
00504 {
00505
00506
00507
00508
00509 int lhs_ds = (args[0].type == kTokenDataset ? args[0].value.i : ds);
00510 FunctionSum& sum = F_->get_model(lhs_ds)->get_fz(*args[1].str);
00511 bool removed_functions = false;
00512 if (args[2].type == kTokenAssign && !sum.names.empty()) {
00513 sum.names.clear();
00514 sum.idx.clear();
00515 removed_functions = true;
00516 }
00517 vector<string> new_names;
00518 for (size_t i = 3; i < args.size(); i += 2) {
00519
00520 int n_tokens = get_fz_or_func(F_, ds, args.begin()+i, new_names);
00521 if (n_tokens > 0) {
00522 i += n_tokens - 1;
00523 }
00524
00525 else if (args[i].type == kTokenNumber) {
00526
00527 }
00528
00529 else if (args[i].type == kTokenLname && args[i].as_string() == "copy") {
00530 vector<string> v;
00531 int n_tokens = get_fz_or_func(F_, ds, args.begin()+i+1, v);
00532 v_foreach (string, j, v) {
00533 string name = F_->next_func_name();
00534 F_->assign_func_copy(name, *j);
00535 new_names.push_back(name);
00536 }
00537 i += n_tokens;
00538 }
00539 else if (args[i].type == kTokenCname) {
00540 string name = F_->next_func_name();
00541 int n_args = make_func_from_template(name, args, i);
00542 new_names.push_back(name);
00543 i += 2 * n_args;
00544 }
00545 else
00546 assert(0);
00547 assert(i+1 == args.size() || args[i+1].type == kTokenPlus);
00548 }
00549
00550 add_functions_to(F_, new_names, sum);
00551
00552 if (removed_functions)
00553 F_->auto_remove_functions();
00554 F_->use_parameters();
00555 F_->update_indices_in_models();
00556 F_->outdated_plot();
00557 }
00558
00559 void Runner::command_load(const vector<Token>& args)
00560 {
00561 int dataset = args[0].value.i;
00562 string filename = Lexer::get_string(args[1]);
00563 if (filename == ".") {
00564 if (dataset == Lexer::kNew)
00565 throw ExecuteError("New dataset (@+) cannot be reverted");
00566 if (args.size() > 2)
00567 throw ExecuteError("Options can't be given when reverting data");
00568 F_->get_data(dataset)->revert();
00569 }
00570 else {
00571 string format, options;
00572 if (args.size() > 2) {
00573 format = args[2].as_string();
00574 for (size_t i = 3; i < args.size(); ++i)
00575 options += (i == 3 ? "" : " ") + args[i].as_string();
00576 }
00577 F_->import_dataset(dataset, filename, format, options);
00578 }
00579 F_->outdated_plot();
00580 }
00581
00582 void Runner::command_all_points_tr(const vector<Token>& args, int ds)
00583 {
00584
00585 ep_.clear_vm();
00586 for (size_t i = 0; i < args.size(); i += 2) {
00587 Lexer lex(args[i+1].str);
00588 ep_.parse_expr(lex, ds);
00589 ep_.push_assign_lhs(args[i]);
00590 }
00591 Data *data = F_->get_data(ds);
00592 ep_.transform_data(data->get_mutable_points());
00593 data->after_transform();
00594 F_->outdated_plot();
00595 }
00596
00597
00598 void Runner::command_point_tr(const vector<Token>& args, int ds)
00599 {
00600
00601
00602
00603
00604
00605 Data *data = F_->get_data(ds);
00606 vector<Point>& points = data->get_mutable_points();
00607
00608 bool sorted = true;
00609 for (size_t n = 0; n < args.size(); n += 3) {
00610 char c = *args[n].str;
00611 int idx = iround(args[n+1].value.d);
00612 double val = args[n+2].value.d;
00613 if (idx < 0)
00614 idx += points.size();
00615 if (idx < 0 || idx >= (int) points.size())
00616 throw ExecuteError("wrong point index: " + S(idx));
00617 Point& p = points[idx];
00618 if (c == 'x' || c == 'X') {
00619 p.x = val;
00620 if ((idx != 0 && points[idx-1].x > val) ||
00621 (idx+1 < (int) points.size() && val > points[idx+1].x))
00622 sorted = false;
00623 data->find_step();
00624 }
00625 else if (c == 'y' || c == 'Y') {
00626 p.y = val;
00627 }
00628 else if (c == 's' || c == 'S')
00629 p.sigma = val;
00630 else if (c == 'a' || c == 'A') {
00631 bool old_a = p.is_active;
00632 p.is_active = (fabs(val) >= 0.5);
00633 if (old_a != p.is_active)
00634 data->update_active_for_one_point(idx);
00635 }
00636 }
00637
00638 if (!sorted) {
00639 data->sort_points();
00640 data->find_step();
00641 }
00642 F_->outdated_plot();
00643 }
00644
00645
00646 void Runner::command_resize_p(const vector<Token>& args, int ds)
00647 {
00648
00649 int val = iround(args[0].value.d);
00650 if (val < 0 || val > 1e6)
00651 throw ExecuteError("wrong length: " + S(val));
00652 Data *data = F_->get_data(ds);
00653 data->get_mutable_points().resize(val);
00654 data->after_transform();
00655 F_->outdated_plot();
00656 }
00657
00658 void Runner::execute_command(Command& c, int ds)
00659 {
00660 switch (c.type) {
00661 case kCmdDebug:
00662 command_debug(F_, ds, c.args[0], c.args[1]);
00663 break;
00664 case kCmdDefine:
00665 F_->get_tpm()->define(c.defined_tp);
00666 break;
00667 case kCmdDelete:
00668 command_delete(c.args);
00669 break;
00670 case kCmdDeleteP:
00671 command_delete_points(c.args, ds);
00672 break;
00673 case kCmdExec:
00674 assert(0);
00675
00676 break;
00677 case kCmdFit:
00678 command_fit(c.args, ds);
00679 break;
00680 case kCmdGuess:
00681 command_guess(c.args, ds);
00682 break;
00683 case kCmdInfo:
00684 command_redirectable(F_, ds, kCmdInfo, c.args);
00685 break;
00686 case kCmdPlot:
00687 command_plot(c.args, ds);
00688 break;
00689 case kCmdPrint:
00690 command_redirectable(F_, ds, kCmdPrint, c.args);
00691 break;
00692 case kCmdReset:
00693 F_->reset();
00694 F_->outdated_plot();
00695 break;
00696 case kCmdSet:
00697 command_set(c.args);
00698 break;
00699 case kCmdSleep:
00700 F_->get_ui()->wait(c.args[0].value.d);
00701 break;
00702 case kCmdUndef:
00703 command_undefine(c.args);
00704 break;
00705 case kCmdUse:
00706 F_->set_default_dm(c.args[0].value.i);
00707 F_->outdated_plot();
00708 break;
00709 case kCmdQuit:
00710 throw ExitRequestedException();
00711 break;
00712 case kCmdShell:
00713 system(c.args[0].str);
00714 break;
00715 case kCmdLoad:
00716 command_load(c.args);
00717 break;
00718 case kCmdNameFunc:
00719 command_name_func(c.args, ds);
00720 break;
00721 case kCmdDatasetTr:
00722 command_dataset_tr(c.args);
00723 break;
00724 case kCmdAllPointsTr:
00725 command_all_points_tr(c.args, ds);
00726 break;
00727 case kCmdPointTr:
00728 command_point_tr(c.args, ds);
00729 break;
00730 case kCmdResizeP:
00731 command_resize_p(c.args, ds);
00732 break;
00733 case kCmdTitle:
00734 F_->get_data(ds)->set_title(Lexer::get_string(c.args[0]));
00735 break;
00736 case kCmdAssignParam:
00737 if (c.args[2].type == kTokenMult)
00738 command_assign_all(c.args, ds);
00739 else
00740 command_assign_param(c.args, ds);
00741 break;
00742
00743
00744
00745 case kCmdNameVar:
00746 command_name_var(c.args);
00747 break;
00748 case kCmdChangeModel:
00749 command_change_model(c.args, ds);
00750 break;
00751 case kCmdNull:
00752
00753 break;
00754 }
00755 }
00756
00757 void Runner::recalculate_command(Command& c, int ds, Statement& st)
00758 {
00759
00760 if (c.type == kCmdAllPointsTr || c.type == kCmdDeleteP ||
00761 c.type == kCmdDatasetTr)
00762 return;
00763
00764 const vector<Point>& points = F_->get_data(ds)->points();
00765 vm_foreach (Token, t, c.args)
00766 if (t->type == kTokenExpr) {
00767 Lexer lex(t->str);
00768 ep_.clear_vm();
00769 ep_.parse_expr(lex, ds);
00770 t->value.d = ep_.calculate(0, points);
00771 }
00772 else if (t->type == kTokenEVar) {
00773 Lexer lex(t->str);
00774 ep_.clear_vm();
00775 ep_.parse_expr(lex, ds, NULL, NULL, ExpressionParser::kAstMode);
00776 st.vdlist[t->value.i] = ep_.vm();
00777 }
00778 }
00779
00780
00781
00782 void Runner::execute_statement(Statement& st)
00783 {
00784 boost::scoped_ptr<Settings> s_orig;
00785 vdlist_ = &st.vdlist;
00786 try {
00787 if (!st.with_args.empty()) {
00788 s_orig.reset(new Settings(*F_->get_settings()));
00789 command_set(st.with_args);
00790 }
00791 v_foreach (int, i, st.datasets) {
00792 vm_foreach (Command, c, st.commands) {
00793
00794
00795
00796
00797
00798 if (i != st.datasets.begin() || c != st.commands.begin() ||
00799 !st.with_args.empty())
00800 recalculate_command(*c, *i, st);
00801
00802 if (c->type == kCmdExec) {
00803
00804
00805 assert(c->args.size() == 1);
00806 const Token& t = c->args[0];
00807 TokenType tt = t.type;
00808 string str = Lexer::get_string(t);
00809 Statement backup;
00810
00811
00812 st.datasets.swap(backup.datasets);
00813 st.with_args.swap(backup.with_args);
00814 st.commands.swap(backup.commands);
00815 command_exec(tt, str);
00816 st.datasets.swap(backup.datasets);
00817 st.with_args.swap(backup.with_args);
00818 st.commands.swap(backup.commands);
00819 }
00820 else
00821 execute_command(*c, *i);
00822 }
00823 }
00824 }
00825 catch (...) {
00826 if (!st.with_args.empty())
00827 F_->settings_mgr()->set_all(*s_orig);
00828 throw;
00829 }
00830 if (!st.with_args.empty())
00831 F_->settings_mgr()->set_all(*s_orig);
00832 }
00833