Marsyas  0.5.0-beta1
/Users/jleben/code/marsyas/src/marsyas/expr/ExNode.cpp
Go to the documentation of this file.
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 }