Marsyas
0.6.0-alpha
|
00001 /* 00002 ** Copyright (C) 1998-2007 George Tzanetakis <gtzan@cs.uvic.ca> 00003 ** 00004 ** This program is free software; you can redistribute it and/or modify 00005 ** it under the terms of the GNU General Public License as published by 00006 ** the Free Software Foundation; either version 2 of the License, or 00007 ** (at your option) any later version. 00008 ** 00009 ** This program is distributed in the hope that it will be useful, 00010 ** but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 ** GNU General Public License for more details. 00013 ** 00014 ** You should have received a copy of the GNU General Public License 00015 ** along with this program; if not, write to the Free Software 00016 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00017 */ 00018 00019 #include <marsyas/expr/Expr.h> 00020 #include <marsyas/expr/ExParser.h> 00021 #include <marsyas/expr/ExScanner.h> 00022 #include <marsyas/expr/ExSymTbl.h> 00023 #include <marsyas/expr/ExNode.h> 00024 #include <marsyas/system/MarSystem.h> 00025 #include <marsyas/sched/Scheduler.h> 00026 #include <marsyas/sched/TmTimer.h> 00027 00028 #include <fstream> 00029 00030 using std::ostringstream; 00031 using namespace Marsyas; 00032 00033 void 00034 Ex::parse(Expr* e, ExNode*& init, ExNode*& expr) 00035 { 00036 ExScanner s; 00037 ExParser p(&(e->timer_),&s); 00038 00039 // parse init expression 00040 if (init_!="") { 00041 s.setString(init_.c_str()); 00042 p.Parse(e->sched_,e->marsym_,e->symbol_table_); 00043 init=p.getTree(); 00044 } 00045 else init=NULL; 00046 00047 if (expr_!="") { 00048 s.setString(expr_.c_str()); 00049 p.Parse(e->sched_,e->marsym_,e->symbol_table_); 00050 expr=p.getTree(); 00051 } 00052 else expr=NULL; 00053 } 00054 00055 Expr::Expr() 00056 { 00057 symbol_table_=NULL; 00058 init_expr_=NULL; expr_=NULL; 00059 rept_=NULL; rate_=NULL; 00060 marsym_=NULL; 00061 sched_=NULL; 00062 timer_=NULL; 00063 initialized_=false; 00064 } 00065 Expr::Expr(MarSystem* msym, Ex e) 00066 { 00067 marsym_=msym; 00068 timer_=NULL; 00069 sched_=NULL; 00070 symbol_table_=new ExRecord(); 00071 symbol_table_->inc_ref(); 00072 e.parse(this,init_expr_,expr_); 00073 rept_=NULL; 00074 rate_=NULL; 00075 initialized_=false; 00076 } 00077 Expr::Expr(MarSystem* msym, Ex e, Rp r) 00078 { 00079 set(msym,e,r); 00080 } 00081 Expr::Expr(MarSystem* msym, ExFile ef) 00082 { 00083 Ex e=ef.getEx(); 00084 Rp r=ef.getRp(); 00085 set(msym,e,r); 00086 } 00087 void 00088 Expr::set(MarSystem* m, Ex& e, Rp& r) 00089 { 00090 marsym_=m; 00091 timer_=NULL; 00092 sched_=NULL; 00093 symbol_table_=new ExRecord(); 00094 symbol_table_->inc_ref(); 00095 e.parse(this,init_expr_,expr_); 00096 r.parse(this,rept_,rate_); 00097 if (rept_&&rept_->getEvalType()!="mrs_bool") { 00098 MRSWARN("Expr:: Repetition expression must evaluate to bool: "+rept_->getEvalType()); 00099 rept_->deref(); rept_=NULL; 00100 if (rate_) rate_->deref(); rate_=NULL; 00101 } 00102 else if (rate_&&rate_->getEvalType()!="mrs_string") { 00103 MRSWARN("Expr:: Repetition rate expression must evaluate to string: "+rate_->getEvalType()); 00104 if (rept_) rept_->deref(); rept_=NULL; 00105 if (rate_) rate_->deref(); rate_=NULL; 00106 } 00107 initialized_=false; 00108 } 00109 00110 Expr::~Expr() 00111 { 00112 symbol_table_->deref(); 00113 delete expr_; 00114 delete init_expr_; 00115 delete rept_; 00116 delete rate_; 00117 } 00118 00119 void 00120 Expr::eval() 00121 { 00122 if (expr_!=NULL) 00123 expr_->eval(); 00124 } 00125 00126 bool 00127 Expr::repeat() 00128 { 00129 return (rept_)&&(rept_->eval()).toBool(); 00130 } 00131 00132 std::string 00133 Expr::repeat_interval() 00134 { 00135 if (rate_) return (rate_->eval()).toString(); 00136 return "__NULL"; 00137 } 00138 00139 void 00140 Expr::setScheduler(Scheduler* v) 00141 { 00142 sched_=v; 00143 } 00144 00145 void 00146 Expr::setTimer(TmTimer* t) 00147 { 00148 timer_=t; 00149 } 00150 00151 void 00152 Expr::post() 00153 { 00154 if (init_expr_&&!initialized_) 00155 init_expr_->eval(); 00156 initialized_=true; 00157 } 00158 00159 void 00160 ExFile::read(std::string fname) 00161 { 00162 std::ifstream from(fname.c_str()); 00163 if (!from) { MRSWARN("ExFile::read Cannot open file: "+fname); return; } 00164 std::string data; 00165 char buffer[256]; 00166 // flags correspond to the 5 possible blocks, no block can be declared more than once 00167 bool flags[6] = { false }; 00168 int pos=-1; 00169 std::string line; 00170 while (from.getline(buffer,256)) { 00171 if (buffer[0]=='#') { 00172 if (buffer[1]=='E'&&buffer[2]=='x') { // #ExInit: | #ExExpr: 00173 if (buffer[3]=='I'&&buffer[4]=='n'&&buffer[5]=='i'&&buffer[6]=='t'&&buffer[7]==':') { 00174 store(pos,data); data=""; pos=1; 00175 if (flags[pos]) { MRSWARN("ExFile::read Double declaration of #ExInit: block"); } 00176 } 00177 else if (buffer[3]=='E'&&buffer[4]=='x'&&buffer[5]=='p'&&buffer[6]=='r'&&buffer[7]==':') { 00178 store(pos,data); data=""; pos=2; 00179 if (flags[pos]) { MRSWARN("ExFile::read Double declaration of #ExExpr: block"); } 00180 } 00181 } 00182 else if (buffer[1]=='R'&&buffer[2]=='p') { 00183 if (buffer[3]=='E'&&buffer[4]=='x'&&buffer[5]=='p'&&buffer[6]=='r'&&buffer[7]==':') { 00184 // #RpExpr: 00185 store(pos,data); data=""; pos=3; 00186 if (flags[pos]) { MRSWARN("ExFile::read Double declaration of #RpExpr: block"); } 00187 } 00188 else if (buffer[3]=='R'&&buffer[4]=='a'&&buffer[5]=='t'&&buffer[6]=='e'&&buffer[7]==':') { 00189 // #RpRate: 00190 store(pos,data); data=""; pos=4; 00191 if (flags[pos]) { MRSWARN("ExFile::read Double declaration of #RpRate: block"); } 00192 } 00193 } 00194 else { 00195 MRSWARN("ExFile::read Unknown macro # in ExFile"); 00196 } 00197 flags[pos]=true; 00198 } 00199 else { data=data+buffer; } 00200 } 00201 if (!data.empty()) { store(pos,data); } 00202 from.close(); 00203 file_read_=true; 00204 } 00205 00206 void 00207 ExFile::store(int pos, std::string data) 00208 { 00209 switch(pos) { 00210 case 1: iex_=data; break; 00211 case 2: ex_=data; break; 00212 case 3: rp_=data; break; 00213 case 4: rr_=data; break; 00214 } 00215 }