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 #include <marsyas/expr/ExNode.h> 00019 00020 using std::ostringstream; 00021 using namespace Marsyas; 00022 00023 void 00024 Marsyas::loadlib_Real(ExRecord* st) 00025 { 00026 st->addReserved("Real|R.abs(mrs_real)",new ExFun_RealAbs()); 00027 st->addReserved("Real|R.cos(mrs_real)",new ExFun_RealCos()); 00028 st->addReserved("Real|R.acos(mrs_real)",new ExFun_RealACos()); 00029 st->addReserved("Real|R.cosh(mrs_real)",new ExFun_RealCosH()); 00030 00031 st->addReserved("Real|R.sin(mrs_real)",new ExFun_RealSin()); 00032 st->addReserved("Real|R.asin(mrs_real)",new ExFun_RealASin()); 00033 st->addReserved("Real|R.sinh(mrs_real)",new ExFun_RealSinH()); 00034 00035 st->addReserved("Real|R.tan(mrs_real)",new ExFun_RealTan()); 00036 st->addReserved("Real|R.atan(mrs_real)",new ExFun_RealATan()); 00037 00038 st->addReserved("Real|R.log|ln(mrs_real)",new ExFun_RealLog()); 00039 st->addReserved("Real|R.log2(mrs_real)",new ExFun_RealLog2()); 00040 st->addReserved("Real|R.log10(mrs_real)",new ExFun_RealLog10()); 00041 00042 st->addReserved("Real|R.rand()",new ExFun_RealRand()); 00043 00044 st->addReserved("Real|R.sqrt(mrs_real)",new ExFun_RealSqrt()); 00045 #define _PI_VAL_ 3.14159265358979323846264338327950288419716939937510 00046 #define _E_VAL_ 2.7182818284590452353602874713526624977572470936999595749669676277240766303535 00047 st->addReserved("Real|R.e",(mrs_real)_E_VAL_); 00048 st->addReserved("Real|R.pi",(mrs_real)_PI_VAL_); 00049 st->addReserved("Real|R.pi2",(mrs_real)(_PI_VAL_ / 2.0)); 00050 st->addReserved("Real|R.pi4",(mrs_real)(_PI_VAL_ / 4.0)); 00051 st->addReserved("Real|R.dpr",(mrs_real)(360.0 / (2.0 * _PI_VAL_))); 00052 st->addReserved("Real|R.rpd",(mrs_real)(( 2.0 * _PI_VAL_) / 360.0)); 00053 } 00054 00055 void 00056 Marsyas::loadlib_Natural(ExRecord* st) 00057 { 00058 st->addReserved("Natural|N.abs(mrs_natural)",new ExFun_NaturalAbs()); 00059 st->addReserved("Natural|N.rand()",new ExFun_NaturalRand()); 00060 st->addReserved("Natural|N.rand(mrs_natural)",new ExFun_NaturalRandRange1()); 00061 st->addReserved("Natural|N.rand(mrs_natural,mrs_natural)",new ExFun_NaturalRandRange2()); 00062 st->addReserved("Natural|N.min(mrs_natural,mrs_natural)",new ExFun_NaturalMin()); 00063 st->addReserved("Natural|N.max(mrs_natural,mrs_natural)",new ExFun_NaturalMax()); 00064 st->addReserved("Natural|N.srand(mrs_natural)",new ExFun_NaturalSRand()); 00065 st->addReserved("Natural|N.randmax",(mrs_natural)RAND_MAX); 00066 } 00067 00068 void 00069 Marsyas::loadlib_String(ExRecord* st) 00070 { 00071 st->addReserved("String|S.len(mrs_string)",new ExFun_StrLen()); 00072 st->addReserved("String|S.sub(mrs_string,mrs_natural,mrs_natural)",new ExFun_StrSub()); 00073 } 00074 00075 void 00076 Marsyas::loadlib_Stream(ExRecord* st) 00077 { 00078 // st->addReserved("Stream.op",new ExFun_StreamOutString("_fun","Stream.op")); // for lookup 00079 st->addReserved("Stream.op(mrs_string)",new ExFun_StreamOutString()); 00080 st->addReserved("Stream.op(mrs_real)",new ExFun_StreamOutReal()); 00081 st->addReserved("Stream.op(mrs_natural)",new ExFun_StreamOutNatural()); 00082 st->addReserved("Stream.op(mrs_bool)",new ExFun_StreamOutBool()); 00083 00084 st->addReserved("Stream.opn(mrs_string)",new ExFun_StreamOutNString()); 00085 st->addReserved("Stream.opn(mrs_real)",new ExFun_StreamOutNReal()); 00086 st->addReserved("Stream.opn(mrs_natural)",new ExFun_StreamOutNNatural()); 00087 st->addReserved("Stream.opn(mrs_bool)",new ExFun_StreamOutNBool()); 00088 } 00089 00090 void 00091 Marsyas::loadlib_List(ExRecord* st) 00092 { 00093 st->addReserved("List.len(mrs_list)",new ExFun_ListLen()); 00094 } 00095 00096 void 00097 Marsyas::load_symbols(ExRecord* st) 00098 { 00099 loadlib_Real(st); 00100 loadlib_Natural(st); 00101 loadlib_String(st); 00102 loadlib_Stream(st); 00103 loadlib_List(st); 00104 } 00105 00106 void 00107 Marsyas::loadlib_timer(ExRecord* st, TmTimer** tmr) 00108 { 00109 st->addReserved("Timer|Tmr.cur",(TmTimer**)tmr,"Timer.cur",T_VAR); 00110 st->addReserved("Timer|Tmr.prefix(mrs_timer)",new ExFun_TimerGetPrefix()); 00111 st->addReserved("Timer|Tmr.name(mrs_timer)",new ExFun_TimerGetName()); 00112 st->addReserved("Timer|Tmr.type(mrs_timer)",new ExFun_TimerGetType()); 00113 st->addReserved("Timer|Tmr.time(mrs_timer)",new ExFun_TimerGetTime()); 00114 st->addReserved("Timer|Tmr.upd(mrs_timer,mrs_string,mrs_real)",new ExFun_TimerUpdReal()); 00115 st->addReserved("Timer|Tmr.upd(mrs_timer,mrs_string,mrs_natural)",new ExFun_TimerUpdNatural()); 00116 st->addReserved("Timer|Tmr.upd(mrs_timer,mrs_string,mrs_string)",new ExFun_TimerUpdString()); 00117 st->addReserved("Timer|Tmr.upd(mrs_timer,mrs_string,mrs_bool)",new ExFun_TimerUpdBool()); 00118 st->addReserved("Timer|Tmr.ival(mrs_timer,mrs_string)",new ExFun_TimerIntrvlSize()); 00119 } 00120 /* 00121 void Marsyas::loadlib_timer(ExRecord* st, VScheduler** tmr) 00122 { 00123 st->addReserved("Scheduler|Sched.tmr(mrs_scheduler,mrs_string)",new ExFun_SchedulerFind("mrs_timer","Scheduler.tmr(mrs_scheduler,mrs_string)")); 00124 // st->addReserved("Scheduler|Sched.addtmr(mrs_scheduler,mrs_string,mrs_string)",new ExFun_SchedulerAddTimer("mrs_bool","Scheduler.addtmr(mrs_scheduler,mrs_string,mrs_string)")); 00125 // st->addReserved("Scheduler|Sched.post(mrs_scheduler,mrs_timer,mrs_event)",new ExFun_ 00126 } 00127 */ 00128 ExNode::ExNode() : ExRefCount() 00129 { 00130 init(); 00131 } 00132 00133 ExNode::ExNode(int k, std::string t) : ExRefCount() 00134 { 00135 init(); 00136 setKind(k); 00137 setType(t); 00138 } 00139 00140 ExNode::ExNode(int k, std::string t, ExVal v) : ExRefCount() 00141 { 00142 init(); 00143 setKind(k); 00144 setType(t); 00145 value=v; 00146 } 00147 00148 ExNode::ExNode(ExVal v) : ExRefCount() 00149 { 00150 init(); 00151 setKind(T_CONST); // what about list types 00152 setType(v.getType()); 00153 // std::cout<<"ExNode<"<<getType()<<">\n"; 00154 value=v; 00155 } 00156 00157 ExNode::ExNode(const ExNode& v) : ExRefCount() 00158 { 00159 init(); 00160 setType(v.getType()); 00161 setKind(v.getKind()); 00162 val_str=v.val_str; 00163 value=v.value; 00164 next=NULL; 00165 } 00166 00167 void 00168 ExNode::init() 00169 { 00170 next=NULL; 00171 inc_ref(); 00172 } 00173 00174 bool 00175 ExNode::is_const() 00176 { 00177 return (getKind()==T_CONST); 00178 } 00179 00180 bool 00181 ExNode::is_list() const 00182 { 00183 std::string humuhumunukunukuapuaa=getType(); 00184 // whoa! that's crazy man.. 00185 size_t len = humuhumunukunukuapuaa.length(); 00186 return (len>3) 00187 && (humuhumunukunukuapuaa[len-4]=='l') 00188 && (humuhumunukunukuapuaa[len-3]=='i') 00189 && (humuhumunukunukuapuaa[len-2]=='s') 00190 && (humuhumunukunukuapuaa[len-1]=='t'); 00191 } 00192 00193 bool 00194 ExNode::is_seq() const 00195 { 00196 return getType()=="mrs_string"||is_list(); 00197 } 00198 00199 ExNode::~ExNode() 00200 { 00201 if (next) next->deref(); 00202 } 00203 00204 ExNode* 00205 ExNode::copy() 00206 { 00207 return new ExNode(*this); 00208 } 00209 00210 std::string 00211 ExNode::getType() const 00212 { 00213 // return (getKind()==T_CONST) ? value.getType() : type; 00214 return type; 00215 } 00216 00217 std::string 00218 ExNode::getEvalType() const 00219 { 00220 if (next==NULL) return getType(); 00221 ExNode* e=next; while (e->next!=NULL) { e=e->next; } 00222 return e->getType(); 00223 } 00224 00225 void 00226 ExNode::setType(const std::string t) 00227 { 00228 type=t; 00229 } 00230 00231 std::string 00232 ExNode::getElemType() const 00233 { 00234 int r=(int)type.rfind(' '); 00235 return type.substr(0,r); 00236 } 00237 00238 void 00239 ExNode::setKind(const int k) 00240 { 00241 kind=k; 00242 } 00243 00244 std::string 00245 ExNode::toString() 00246 { 00247 std::string o = oot(); 00248 if (next!=NULL) o=o+", "+next->toString(); 00249 return o; 00250 } 00251 00252 std::string 00253 ExNode::oot() 00254 { 00255 return value.toString(); 00256 } 00257 00258 ExVal 00259 ExNode::eval() 00260 { 00261 ExVal v = calc(); // evaluate for side-effects 00262 if (next!=NULL) { return next->eval(); } 00263 return v; 00264 } 00265 00266 ExVal 00267 ExNode::getSeqRange(int lidx, int ridx) 00268 { 00269 return value.getSeqRange(lidx,ridx); 00270 } 00271 00272 ExVal 00273 ExNode::getSeqElem(int idx) 00274 { 00275 return value.getSeqElem(idx); 00276 } 00277 00278 void 00279 ExNode::setSeqElem(int idx, ExVal v) 00280 { 00281 value.setSeqElem(idx, v); 00282 } 00283 00284 /*** ExFun **************************************************************/ 00285 void 00286 ExFun::setParams(ExNode* ps) 00287 { 00288 bool evaluatable=true; 00289 num_params=0; 00290 if (ps!=NULL) { 00291 ExNode* p=ps; 00292 for (; p!=NULL; num_params++,p=p->next); 00293 params=new ExNode*[num_params]; 00294 int i=0; 00295 while(i<num_params) { 00296 ExNode* param=ps; ps=ps->next; param->next=NULL; // sever the linked list to avoid eval() list 00297 std::string pt_i=param_types[i]; 00298 std::string pst=param->getType(); 00299 if (pt_i!=pst) { 00300 if (pt_i=="mrs_real") { 00301 if (pst=="mrs_natural") { param=new ExNode_NaturalToReal(param); } 00302 } 00303 else if (pt_i=="mrs_natural") { 00304 if (pst=="mrs_real") { param=new ExNode_RealToNatural(param); } 00305 } 00306 } 00307 params[i]=param; 00308 if (param->getKind()!=T_CONST) { evaluatable=false; } 00309 ++i; 00310 } 00311 } 00312 const_params=evaluatable; 00313 } 00314 00315 void 00316 ExFun::setParamTypes(std::string t) 00317 { 00318 int s=(int)t.find('('); if (s<0) return; 00319 int e=(int)t.rfind(')'); 00320 t=t.substr(s+1,e-s-1); 00321 while (t!="") { 00322 int x=(int)t.find(','); 00323 if (x>=0) { 00324 std::string p=t.substr(0,x); 00325 param_types.push_back(p); 00326 t=t.substr(x+1); 00327 } 00328 else { 00329 param_types.push_back(t); 00330 t=""; 00331 } 00332 } 00333 } 00334 00335 ExFun::~ExFun() 00336 { 00337 for (int i=0; i<num_params; ++i) { params[i]->deref(); } 00338 delete [] params; 00339 } 00340 00341 bool 00342 ExFun::is_const() 00343 { 00344 return (getKind()==T_CONST||((getKind()==T_FUN)&&is_pure&&const_params)); 00345 } 00346 00347 void 00348 ExFun::setSignature(const std::string s) 00349 { 00350 signature=s; 00351 setParamTypes(s); 00352 }