Marsyas  0.5.0-beta1
/Users/jleben/code/marsyas/src/marsyas/expr/ExNode.h
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 
00019 /***
00020 ExNode represents an expression tree node. Additional nodes may be added later,
00021 but may also need to be added to the parser.
00022 
00023 There should only ever exist a single parent of any node, that is, a node may
00024 only be referenced by one object.
00025 
00026 To add library functions add a line like this to ExParser.h::preload() :-
00027 library->addRecord("Real|R.cos(mrs_real)|cos(mrs_natural)",new ExRecord(T_FUN,new ExNode_RealCos("mrs_real","Real.cos(mrs_real)"),true));
00028 then define the function as an ExNode class, you must support the calc and copy
00029 functions. In the constructor make sure you set is_pure to true if the function
00030 can be reduced to a const value given const parameters, or false otherwise.
00031 
00032 class ExNode_NatDbl : public ExNode_Fun {
00033     ExNode* child; public:
00034     ExNode_NatDbl(std::string typ, std::string sig, ExNode* x) : ExNode_Fun(typ,sig,true) { child=x; }
00035     virtual ExVal calc() { return false; }
00036     ExNode* copy() { return new ExNode_NatDbl(type,signature); }
00037 };
00038 
00039 
00040 ***/
00041 #ifndef MARSYAS_EX_NODE_H
00042 #define MARSYAS_EX_NODE_H
00043 
00044 #include <marsyas/expr/ExVal.h>
00045 #include <marsyas/expr/ExSymTbl.h>
00046 #include <marsyas/expr/ExCommon.h>
00047 #include <marsyas/sched/TmTimer.h>
00048 #include <marsyas/system/MarControl.h>
00049 #include <marsyas/system/MarSystem.h>
00050 #include <marsyas/common_header.h>
00051 
00052 #include <string>
00053 #include <iostream>
00054 #include <cstdlib>
00055 
00056 
00057 namespace Marsyas
00058 {
00089 void loadlib_Real(ExRecord* st);
00090 void loadlib_String(ExRecord* st);
00091 void loadlib_Natural(ExRecord* st);
00092 void loadlib_Stream(ExRecord* st);
00093 void loadlib_List(ExRecord* st);
00094 void load_symbols(ExRecord*);
00095 void loadlib_timer(ExRecord* st, TmTimer** tmr);
00096 
00097 class ExNode : public ExRefCount {
00098   std::string type; int kind;
00099 public:
00100   std::string val_str;
00101   ExVal value;
00102 
00103   ExNode* next; // expression(s)
00104 
00105   ExNode();
00106   ExNode(int k, std::string t);
00107   ExNode(int k, std::string t, ExVal v);
00108   ExNode(ExVal v);
00109   ExNode(const ExNode& v);
00110   virtual ~ExNode();
00111 
00112   void init();
00113 
00114   virtual bool is_const();
00115   bool is_list() const;
00116   bool is_seq() const;
00117 
00118   std::string getType() const;
00119   std::string getEvalType() const;
00120   void setType(const std::string t);
00121   int getKind() const { return kind; }
00122   void setKind(const int k);
00123 
00124   virtual ExNode* copy();
00125 
00126   ExVal getValue() { return value; }
00127   mrs_natural valToNatural() {return value.toNatural();}
00128 
00129   void setValue(mrs_natural x) {value.set(x); setKind(T_CONST); setType("mrs_natural");}
00130   void setValue(std::string x) {value.set(x); setKind(T_CONST); setType("mrs_string");}
00131   void setValue(mrs_real x) {value.set(x); setKind(T_CONST); setType("mrs_real");}
00132   void setValue(mrs_bool x) {value.set(x); setKind(T_CONST); setType("mrs_bool");}
00133 
00134   virtual std::string toString();
00135   virtual std::string oot();
00136   virtual ExVal eval();
00137   virtual ExVal calc() { return value;  }
00138 
00139   ExVal getSeqRange(int lidx, int ridx);
00140   ExVal getSeqElem(int idx);
00141   void setSeqElem(int idx, ExVal v);
00142   std::string getElemType() const;
00143 };
00144 /*** Unary Operators *********************************************************/
00145 // Unary Operators {{{
00146 #define UNARYOP(_NM,_KIND,_TYPE,_TO,_OP) \
00147 class ExNode_##_NM : public ExNode { \
00148     ExNode* child; public: \
00149     ExNode_##_NM(ExNode* v) : ExNode(_KIND,_TYPE) { child=v; } \
00150     virtual ~ExNode_##_NM() { child->deref(); } \
00151     virtual ExVal calc() { return _OP((child->eval())._TO); } \
00152 };
00153 UNARYOP(MathNeg_Real   ,OP_MNEG,"mrs_real"   ,toReal()   ,-);
00154 UNARYOP(MathNeg_Natural,OP_MNEG,"mrs_natural",toNatural(),-);
00155 UNARYOP(BoolNeg        ,OP_BNEG,"mrs_bool"   ,toBool()   ,!);
00156 //}}}
00157 /*** Conversions *************************************************************/
00158 // Conversions {{{
00159 UNARYOP(NaturalToReal  ,OP_CONV,"mrs_real"   ,toNatural(),(mrs_real)   );
00160 UNARYOP(RealToNatural  ,OP_CONV,"mrs_natural",toReal()   ,(mrs_natural));
00161 UNARYOP(RealToString   ,OP_CONV,"mrs_string" ,toReal()   ,dtos         );
00162 UNARYOP(NaturalToString,OP_CONV,"mrs_string" ,toNatural(),ltos         );
00163 UNARYOP(BoolToString   ,OP_CONV,"mrs_string" ,toBool()   ,btos         );
00164 //}}}
00165 /*** Binary Operators ********************************************************/
00166 // Binary Operators {{{
00167 #define BINOP(_NM,_KIND,_OP) \
00168 class ExNode_##_NM : public ExNode { \
00169     ExNode* lchild; ExNode* rchild; std::string d; public: \
00170     ExNode_##_NM(std::string t, ExNode* u, ExNode* v) : ExNode(_KIND,t) { \
00171         lchild=u; rchild=v; \
00172         if (getType()=="mrs_real") { d="d"; } else d=""; \
00173     } \
00174     virtual ~ExNode_##_NM() { lchild->deref(); rchild->deref(); } \
00175     virtual ExVal calc() { return (lchild->eval()) _OP (rchild->eval()); } \
00176 };
00177 BINOP(ADD,OP_ADD,+);
00178 BINOP(SUB,OP_SUB,-);
00179 BINOP(MUL,OP_MUL,*);
00180 BINOP(DIV,OP_DIV,/);
00181 BINOP(MOD,OP_MOD,%);
00182 BINOP(EQ,OP_EQ,==);
00183 BINOP(NE,OP_NE,!=);
00184 BINOP(GT,OP_GT,> );
00185 BINOP(GE,OP_GE,>=);
00186 BINOP(LT,OP_LT,< );
00187 BINOP(LE,OP_LE,<=);
00188 BINOP(OR,OP_OR,||);
00189 BINOP(AND,OP_AND,&&);
00190 //}}}
00191 /*** Conditional *************************************************************/
00192 class ExNode_Conditional : public ExNode//{{{
00193 {
00194 ExNode* cond; ExNode* then_; ExNode* else_; public:
00195   ExNode_Conditional(std::string t, ExNode* c, ExNode* ts, ExNode* es) : ExNode(T_COND,t) {
00196     cond=c; then_=ts; else_=es;
00197   }
00198   ~ExNode_Conditional() { cond->deref(); then_->deref(); else_->deref(); }
00199   virtual ExVal calc() {
00200     ExVal v = cond->eval();
00201     return (v.toBool()) ? then_->eval() : else_->eval();
00202   }
00203 };//}}}
00204 /*****************************************************************************/
00206 class ExNode_IterMap : public ExNode//{{{
00207 {
00208 ExNode* xs; ExRecord* var; ExNode* exprs; public:
00209   ExNode_IterMap(ExNode* s, ExRecord* r, ExNode* e, std::string t) : ExNode(T_VAR,t) {
00210     xs=s; var=r; var->inc_ref(); exprs=e;
00211   }
00212   virtual ~ExNode_IterMap() { xs->deref(); var->deref(); exprs->deref(); }
00213   virtual ExVal calc() {
00214     ExVal liszt=xs->eval();
00215     mrs_natural len=liszt.toNatural();
00216     ExNode** new_xs=NULL;
00217     if (len>0) {
00218       new_xs=new ExNode*[len];
00219       for (int i=0; i<len; ++i) {
00220         ExVal e=liszt.getSeqElem(i);
00221         var->setValue(e);
00222         ExVal v=exprs->eval();
00223         new_xs[i]=new ExNode(v);
00224       }
00225     }
00226     return ExVal(len,new_xs);
00227   }
00228 };//}}}
00230 class ExNode_IterIter : public ExNode//{{{
00231 {
00232 ExRecord* xs; ExRecord* var; ExNode* exprs; public:
00233   ExNode_IterIter(ExRecord* s, ExRecord* r, ExNode* e) : ExNode(T_VAR,"mrs_unit") {
00234     xs=s; xs->inc_ref(); var=r; var->inc_ref(); exprs=e;
00235   }
00236   virtual ~ExNode_IterIter() { xs->deref(); var->deref(); exprs->deref(); }
00237   virtual ExVal calc() {
00238     ExVal liszt=xs->getValue();
00239     mrs_natural len=liszt.toNatural();
00240     if (len>0) {
00241       for (int i=0; i<len; ++i) {
00242         ExVal e=liszt.getSeqElem(i);
00243         var->setValue(e);
00244         ExVal v=exprs->eval();
00245         xs->setValue(v,"",i);
00246       }
00247     }
00248     return ExVal();
00249   }
00250 };//}}}
00252 class ExNode_IterFor : public ExNode//{{{
00253 {
00254 ExNode* xs; ExRecord* var; ExNode* exprs; public:
00255   ExNode_IterFor(ExNode* s, ExRecord* r, ExNode* e) : ExNode(T_VAR,"mrs_unit") {
00256     xs=s; var=r; var->inc_ref(); exprs=e;
00257   }
00258   virtual ~ExNode_IterFor() { xs->deref(); var->deref(); exprs->deref(); }
00259   virtual ExVal calc() {
00260     ExVal liszt=xs->eval();
00261     mrs_natural len=liszt.toNatural();
00262     if (len>0) {
00263       for (int i=0; i<len; ++i) {
00264         ExVal e=liszt.getSeqElem(i);
00265         var->setValue(e);
00266         exprs->eval();
00267       }
00268     }
00269     return ExVal();
00270   }
00271 };//}}}
00272 class ExNode_IterRFor : public ExNode//{{{
00273 {
00274 ExNode* xs; ExRecord* var; ExNode* exprs; public:
00275   ExNode_IterRFor(ExNode* s, ExRecord* r, ExNode* e) : ExNode(T_VAR,"mrs_unit") {
00276     xs=s; var=r; var->inc_ref(); exprs=e;
00277   }
00278   virtual ~ExNode_IterRFor() { xs->deref(); var->deref(); exprs->deref(); }
00279   virtual ExVal calc() {
00280     ExVal liszt=xs->eval();
00281     mrs_natural len=liszt.toNatural();
00282     if (len>0) {
00283       for (int i=len-1; i>=0; i--) {
00284         ExVal e=liszt.getSeqElem(i);
00285         var->setValue(e);
00286         exprs->eval();
00287       }
00288     }
00289     return ExVal();
00290   }
00291 };//}}}
00292 
00295 class ExNode_StringMap : public ExNode//{{{
00296 {
00297 ExNode* xs; ExRecord* var; ExNode* exprs; public:
00298   ExNode_StringMap(ExNode* s, ExRecord* r, ExNode* e, std::string t) : ExNode(T_VAR,t) {
00299     xs=s; var=r; var->inc_ref(); exprs=e;
00300   }
00301   virtual ~ExNode_StringMap() { xs->deref(); var->deref(); exprs->deref(); }
00302   virtual ExVal calc() {
00303     std::string str=(xs->eval()).toString();
00304     std::string result="";
00305     mrs_natural len=(mrs_natural)str.length();
00306     if (len>0) {
00307       for (int i=0; i<len; ++i) {
00308         ExVal v=ExVal(((std::string)"")+str[i]);
00309         var->setValue(v);
00310         std::string r=(exprs->eval()).toString();
00311         result+=(exprs->eval()).toString();
00312       }
00313     }
00314     return ExVal(result);
00315   }
00316 };//}}}
00318 class ExNode_StringIter : public ExNode//{{{
00319 {
00320 ExRecord* xs; ExRecord* var; ExNode* exprs; public:
00321   ExNode_StringIter(ExRecord* s, ExRecord* r, ExNode* e) : ExNode(T_VAR,"mrs_unit") {
00322     xs=s; xs->inc_ref(); var=r; var->inc_ref(); exprs=e;
00323   }
00324   virtual ~ExNode_StringIter() { xs->deref(); var->deref(); exprs->deref(); }
00325   virtual ExVal calc() {
00326     std::cout << "ITER:"<<std::endl;
00327     std::string str=(xs->getValue()).toString();
00328     std::string result="";
00329     mrs_natural len=(mrs_natural)str.length();
00330     if (len>0) {
00331       for (int i=0; i<len; ++i) {
00332         ExVal v=ExVal(((std::string)"")+str[i]);
00333         var->setValue(v);
00334         result+=(exprs->eval()).toString();
00335       }
00336     }
00337     ExVal v=ExVal(result);
00338     xs->setValue(v);
00339     return ExVal();
00340   }
00341 };//}}}
00343 class ExNode_StringFor : public ExNode//{{{
00344 {
00345 ExNode* xs; ExRecord* var; ExNode* exprs; public:
00346   ExNode_StringFor(ExNode* s, ExRecord* r, ExNode* e) : ExNode(T_VAR,"mrs_unit") {
00347     xs=s; var=r; var->inc_ref(); exprs=e;
00348   }
00349   virtual ~ExNode_StringFor() { xs->deref(); var->deref(); exprs->deref(); }
00350   virtual ExVal calc() {
00351     std::string str=(xs->eval()).toString();
00352     std::string result="";
00353     mrs_natural len=(mrs_natural)str.length();
00354     if (len>0) {
00355       for (int i=0; i<len; ++i) {
00356         ExVal v=ExVal(((std::string)"")+str[i]);
00357         var->setValue(v);
00358         exprs->eval();
00359       }
00360     }
00361     return ExVal();
00362   }
00363 };//}}}
00364 class ExNode_StringRFor : public ExNode//{{{
00365 {
00366 ExNode* xs; ExRecord* var; ExNode* exprs; public:
00367   ExNode_StringRFor(ExNode* s, ExRecord* r, ExNode* e) : ExNode(T_VAR,"mrs_unit") {
00368     xs=s; var=r; var->inc_ref(); exprs=e;
00369   }
00370   virtual ~ExNode_StringRFor() { xs->deref(); var->deref(); exprs->deref(); }
00371   virtual ExVal calc() {
00372     std::string str=(xs->eval()).toString();
00373     std::string result="";
00374     mrs_natural len=(mrs_natural)str.length();
00375     if (len>0) {
00376       for (int i=len-1; i>=0; i--) {
00377         ExVal v=ExVal(((std::string)"")+str[i]);
00378         var->setValue(v);
00379         exprs->eval();
00380       }
00381     }
00382     return ExVal();
00383   }
00384 };//}}}
00385 
00386 /*** Lists *******************************************************************/
00387 class ExNode_SetElem : public ExNode//{{{
00388 {
00389 ExRecord* list; ExNode* var; ExNode* idx; public:
00390   ExNode_SetElem(ExRecord* xs, ExNode* i, ExNode* v) : ExNode(T_VAR,xs->getType()) {
00391     list=xs; list->inc_ref(); idx=i; var=v; var->inc_ref();
00392   }
00393   ~ExNode_SetElem() { list->deref(); var->deref(); idx->deref(); }
00394   virtual ExVal calc() {
00395     ExVal v=var->eval();
00396     mrs_natural i=(idx->eval()).toNatural();
00397     v.setSeqElem(i,v);
00398     return v;
00399   }
00400 };//}}}
00401 class ExNode_Range : public ExNode//{{{
00402 {
00403 ExNode* xs; ExNode* lidx; ExNode* ridx; public:
00404   ExNode_Range(ExNode* s, ExNode* l, ExNode* r) : ExNode(s->getKind(),s->getType()) { xs=s; lidx=l; ridx=r; }
00405   ~ExNode_Range() { xs->deref(); lidx->deref(); ridx->deref(); }
00406   virtual ExVal calc() {
00407     ExVal v=xs->eval();
00408     mrs_natural l=(lidx->eval()).toNatural();
00409     mrs_natural r=(ridx->eval()).toNatural();
00410     if (l<0) l=0; if (r<l) r=l;
00411     return v.getSeqRange(l,r);
00412   }
00413 };//}}}
00414 class ExNode_GetElem : public ExNode//{{{
00415 {
00416 ExNode* xs; ExNode* idx; public:
00417   ExNode_GetElem(ExNode* s, ExNode* i) : ExNode(s->getKind(),s->getElemType()) { xs=s; idx=i; }
00418   ~ExNode_GetElem() { xs->deref(); idx->deref(); }
00419   virtual ExVal calc() {
00420     ExVal v=xs->eval();
00421     mrs_natural i=(idx->eval()).toNatural();
00422     return v.getSeqElem(i);
00423   }
00424 };//}}}
00425 /*** Controls ****************************************************************/
00426 // GetCtrl //{{{
00427 #define GETCTRL(_T,_METHOD,_TP) \
00428 class ExNode_GetCtrl##_T : public ExNode { public: \
00429     std::string nm; MarControlPtr ptr; \
00430     ExNode_GetCtrl##_T(std::string n, MarControlPtr p) : ExNode(OP_GETCTRL,_TP) { nm=n; ptr=p; } \
00431     virtual ExVal calc() { return ptr->_METHOD; } \
00432 };
00433 GETCTRL(Real,to<mrs_real>(),"mrs_real");
00434 GETCTRL(String,to<mrs_string>(),"mrs_string");
00435 GETCTRL(Natural,to<mrs_natural>(),"mrs_natural");
00436 GETCTRL(Bool,to<mrs_bool>(),"mrs_bool");
00437 //}}}
00438 // SetCtrl //{{{
00439 #define SETCTRL(_N,_METHOD,_TP) \
00440 class ExNode_SetCtrl##_N : public ExNode { \
00441     std::string nm; MarControlPtr ptr; ExNode* ex; public: \
00442     ExNode_SetCtrl##_N(std::string n, MarControlPtr p, ExNode* u) : ExNode(OP_SETCTRL,_TP) { nm=n; ptr=p; ex=u; } \
00443     ~ExNode_SetCtrl##_N() { ex->deref(); } \
00444     virtual ExVal calc() { ExVal v=ex->eval(); ptr->setValue(v._METHOD); return v; } \
00445 };
00446 SETCTRL(Real,toReal(),"mrs_real");
00447 SETCTRL(String,toString(),"mrs_string");
00448 SETCTRL(Natural,toNatural(),"mrs_natural");
00449 SETCTRL(Bool,toBool(),"mrs_bool");
00450 //}}}
00451 class ExNode_Link : public ExNode//{{{
00452 {
00453 public:
00454   MarControlPtr ptr_a; MarControlPtr ptr_b;
00455   ExNode_Link(MarControlPtr pf, MarControlPtr pt, std::string t) : ExNode(OP_LINK,t) { ptr_a=pf; ptr_b=pt; }
00456   virtual ExVal calc() { return ptr_a->linkTo(ptr_b); }
00457 };//}}}
00458 /***********/
00459 class ExCNameAlias//{{{
00460 {
00461 public:
00462   std::string tp; std::string nm; MarControlPtr ptr;
00463   ExCNameAlias() { };
00464   ExCNameAlias(std::string t, std::string n, MarControlPtr p) { tp=t; nm=n; ptr=p; };
00465   virtual ~ExCNameAlias() {};
00466   virtual ExNode* getctrl() {
00467     if (tp=="mrs_real"   ) { return new ExNode_GetCtrlReal(nm,ptr); }
00468     if (tp=="mrs_natural") { return new ExNode_GetCtrlNatural(nm,ptr); }
00469     if (tp=="mrs_string" ) { return new ExNode_GetCtrlString(nm,ptr); }
00470     if (tp=="mrs_bool"   ) { return new ExNode_GetCtrlBool(nm,ptr); }
00471     return NULL;
00472   };
00473   virtual ExNode* setctrl(ExNode* u) {
00474     if (tp=="mrs_real"   ) { return new ExNode_SetCtrlReal(nm,ptr,u); }
00475     if (tp=="mrs_natural") { return new ExNode_SetCtrlNatural(nm,ptr,u); }
00476     if (tp=="mrs_string" ) { return new ExNode_SetCtrlString(nm,ptr,u); }
00477     if (tp=="mrs_bool"   ) { return new ExNode_SetCtrlBool(nm,ptr,u); }
00478     return NULL;
00479   };
00480 };//}}}
00481 /*** Variables****************************************************************/
00482 class ExNode_AsgnVar : public ExNode//{{{
00483 {
00484 ExRecord* var; ExNode* ex; std::string d; public:
00485   ExNode_AsgnVar(ExNode* f, ExRecord* r) : ExNode(OP_ASGN,f->getType()) {
00486     ex=f; var=r; var->inc_ref();
00487     if (f->getType()=="mrs_real") d="d"; else d="n";
00488   }
00489   virtual ~ExNode_AsgnVar() { var->deref(); ex->deref(); }
00490   virtual ExVal calc() { ExVal v=(ex->eval()); var->setValue(v); return v; }
00491 };//}}}
00492 class ExNode_ReadVar : public ExNode//{{{
00493 {
00494 ExRecord* var; std::string d; public:
00495   ExNode_ReadVar(ExRecord* es, std::string nm) : ExNode(T_NAME,es->getType()) {
00496     var=es; var->inc_ref(); val_str=nm;
00497     std::string t = es->getType();
00498     if (t=="mrs_real") d="d"; else d="n";
00499   }
00500   virtual ~ExNode_ReadVar() { var->deref(); }
00501   virtual ExVal calc() { return var->getValue(); }
00502 };//}}}
00503 /*** Functions and Libraries *************************************************/
00504 class ExFun : public ExNode//{{{
00505 {
00506 protected:
00507   ExNode** params;
00508   int num_params;
00509   std::vector<std::string> param_types;
00510   bool is_pure; bool const_params;
00511   std::string signature;
00512 public:
00513   ExFun(std::string t, std::string r) : ExNode(T_FUN,t) { setSignature(r); params=NULL; num_params=0; is_pure=false; }
00514   ExFun(std::string t, std::string r, bool pure) : ExNode(T_FUN,t) { setSignature(r); is_pure=pure; params=NULL; num_params=0; is_pure=false; }
00515   virtual ~ExFun();
00516   void setSignature(const std::string);
00517   std::string getSignature() const { return signature; }
00518   void setParams(ExNode* ps);
00519   void setParamTypes(std::string t);
00520   virtual bool is_const();
00521   ExFun* copy()=0;
00522 };//}}}
00523 // LibExNode {{{
00524 #define LibExNode0(_NM,_FUN) \
00525 class ExFun_##_NM : public ExFun { public: \
00526     ExFun_##_NM() : ExFun(type_,sig_,true) { } \
00527     virtual ExVal calc() { return _FUN(); } \
00528     ExFun* copy() { return new ExFun_##_NM (); } \
00529 };
00530 
00531 #define LibExFun1(_NM,_FUN,_T1,type_,sig_) \
00532 class ExFun_##_NM : public ExFun { public: \
00533     ExFun_##_NM() : ExFun(type_,sig_,true) { } \
00534     virtual ExVal calc() { return _FUN((params[0]->eval())._T1); } \
00535     ExFun* copy() { return new ExFun_##_NM (); } \
00536 };
00537 #define LibExFun2(_NM,_FUN,_T1,_T2) \
00538 class ExFun_##_NM : public ExFun { public: \
00539     ExFun_##_NM() : ExFun(type_,sig_,true) { } \
00540     virtual ExVal calc() { return _FUN((params[0]->eval())._T1,(params[1]->eval())._T2); } \
00541     ExFun* copy() { return new ExFun_##_NM (); } \
00542 };//}}}
00543 /*** Natural Library *********************************************************/
00544 class ExFun_NaturalMin : public ExFun//{{{
00545 {
00546 public:
00547   ExFun_NaturalMin() : ExFun("mrs_natural","Natural.min(mrs_natural,mrs_natural)",true) { }
00548   virtual ExVal calc() {
00549     mrs_natural n1=(params[0]->eval()).toNatural();
00550     mrs_natural n2=(params[1]->eval()).toNatural();
00551     return (n2<n1) ? n2 : n1;
00552   }
00553   ExFun* copy() { return new ExFun_NaturalMin(); }
00554 };//}}}
00555 class ExFun_NaturalMax : public ExFun//{{{
00556 {
00557 public:
00558   ExFun_NaturalMax() : ExFun("mrs_natural","Natural.max(mrs_natural,mrs_natural)",true) { }
00559   virtual ExVal calc() {
00560     mrs_natural n1=(params[0]->eval()).toNatural();
00561     mrs_natural n2=(params[1]->eval()).toNatural();
00562     return (n2>n1) ? n2 : n1;
00563   }
00564   ExFun* copy() { return new ExFun_NaturalMax(); }
00565 };//}}}
00566 class ExFun_NaturalRand : public ExFun//{{{
00567 {
00568 public:
00569   ExFun_NaturalRand() : ExFun("mrs_natural","Natural.rand()",true) { }
00570   virtual ExVal calc() { return (mrs_natural)rand(); }
00571   ExFun* copy() { return new ExFun_NaturalRand(); }
00572 };//}}}
00573 class ExFun_NaturalRandRange1 : public ExFun//{{{
00574 {
00575 public:
00576   ExFun_NaturalRandRange1() : ExFun("mrs_natural","Natural.rand(mrs_natural)",true) { }
00577   virtual ExVal calc() {
00578     mrs_natural n1=(params[0]->eval()).toNatural();
00579     mrs_natural on=((int)((double)rand()/(double)RAND_MAX*n1));
00580     return (mrs_natural)on;
00581   }
00582   ExFun* copy() { return new ExFun_NaturalRandRange1(); }
00583 };//}}}
00584 class ExFun_NaturalRandRange2 : public ExFun//{{{
00585 {
00586 public:
00587   ExFun_NaturalRandRange2() : ExFun("mrs_natural","Natural.rand(mrs_natural,mrs_natural)",true) { }
00588   virtual ExVal calc() {
00589     mrs_natural n1=(params[0]->eval()).toNatural();
00590     mrs_natural n2=(params[1]->eval()).toNatural();
00591     mrs_natural on=((int)((double)rand()/(double)RAND_MAX*(n2-n1)))+n1;
00592     return (mrs_natural)on;
00593   }
00594   ExFun* copy() { return new ExFun_NaturalRandRange2(); }
00595 };//}}}
00596 class ExFun_NaturalSRand : public ExFun//{{{
00597 {
00598 public:
00599   ExFun_NaturalSRand() : ExFun("mrs_natural","Natural.srand(mrs_natural)",true) { }
00600   virtual ExVal calc() { return (mrs_natural)0; }
00601   ExFun* copy() { return new ExFun_NaturalSRand(); }
00602 };//}}}
00603 class ExFun_NaturalAbs : public ExFun//{{{
00604 {
00605 public:
00606   ExFun_NaturalAbs() : ExFun("mrs_real","Natural.abs(mrs_real)",true) { }
00607   virtual ExVal calc() { mrs_natural d = (params[0]->eval()).toNatural(); return (d<0) ? -d : d; }
00608   ExFun* copy() { return new ExFun_NaturalAbs(); }
00609 };//}}}
00610 /*** Real Library ************************************************************/
00611 LibExFun1(RealCos,cos,toReal(),"mrs_real","Real.cos(mrs_real)");
00612 LibExFun1(RealSqrt,sqrt,toReal(),"mrs_real","Real.sqrt(mrs_real)");
00613 LibExFun1(RealSin,sin,toReal(),"mrs_real","Real.sin(mrs_real)");
00614 LibExFun1(RealACos,acos,toReal(),"mrs_real","Real.acos(mrs_real)");
00615 LibExFun1(RealASin,asin,toReal(),"mrs_real","Real.asin(mrs_real)");
00616 LibExFun1(RealATan,atan,toReal(),"mrs_real","Real.atan(mrs_real)");
00617 LibExFun1(RealCosH,cosh,toReal(),"mrs_real","Real.cosh(mrs_real)");
00618 LibExFun1(RealSinH,sinh,toReal(),"mrs_real","Real.sinh(mrs_real)");
00619 LibExFun1(RealTan,tan,toReal(),"mrs_real","Real.tan(mrs_real)");
00620 LibExFun1(RealLog,log,toReal(),"mrs_real","Real.log(mrs_real)");
00621 LibExFun1(RealLog10,log10,toReal(),"mrs_real","Real.log10(mrs_real)");
00622 
00623 class ExFun_RealAbs : public ExFun//{{{
00624 {
00625 public:
00626   ExFun_RealAbs() : ExFun("mrs_real","Real.abs(mrs_real)",true) { }
00627   virtual ExVal calc() { mrs_real d = (params[0]->eval()).toReal(); return (d<0.0) ? -d : d; }
00628   ExFun* copy() { return new ExFun_RealAbs(); }
00629 };//}}}
00630 class ExFun_RealLog2 : public ExFun//{{{
00631 {
00632 public:
00633   ExFun_RealLog2() : ExFun("mrs_real","Real.log2(mrs_real)",true) { }
00634   virtual ExVal calc() { return log10((params[0]->eval()).toReal())/log10(2.0); }
00635   ExFun* copy() { return new ExFun_RealLog2(); }
00636 };//}}}
00637 class ExFun_RealRand : public ExFun//{{{
00638 {
00639 public:
00640   ExFun_RealRand() : ExFun("mrs_real","Real.rand()",false) { }
00641   virtual ExVal calc() { return ((mrs_real)rand())/((mrs_real)RAND_MAX); }
00642   ExFun* copy() { return new ExFun_RealRand(); }
00643 };//}}}
00644 /*** String Library **********************************************************/
00645 class ExFun_StrLen : public ExFun//{{{
00646 {
00647 public:
00648   ExFun_StrLen() : ExFun("mrs_natural","String.len(mrs_string)",true) { }
00649   virtual ExVal calc() { return (mrs_natural)((params[0]->eval()).toString()).length(); }
00650   ExFun* copy() { return new ExFun_StrLen(); }
00651 };//}}}
00652 class ExFun_StrSub : public ExFun//{{{
00653 {
00654 public:
00655   ExFun_StrSub() : ExFun("mrs_string","String.sub(mrs_string,mrs_natural,mrs_natural)",true) { }
00656   virtual ExVal calc() {
00657     std::string str = params[0]->eval().toString();
00658     int s = params[1]->eval().toNatural();
00659     int e = params[2]->eval().toNatural();
00660     if (s<0) { s=0; }
00661     if (e>(int)(str.length()-s)) { e=((mrs_natural)str.length())-s; }
00662     return str.substr(s,e);
00663   }
00664   ExFun* copy() { return new ExFun_StrSub(); }
00665 };//}}}
00666 /*** Stream Library **********************************************************/
00667 // StreamOut {{{
00668 #define ExFun_StreamOutType(_TYPE,_CONVERSION,_METHOD,_type,_sig) \
00669 class ExFun_StreamOut##_TYPE : public ExFun { public: \
00670     ExFun_StreamOut##_TYPE() : ExFun(_type,_sig,false) { } \
00671     virtual ExVal calc() { ExVal x = params[0]->eval(); std::cout << _CONVERSION(x._METHOD()); return x; } \
00672     ExFun* copy() { return new ExFun_StreamOut##_TYPE(); } \
00673 };
00674 ExFun_StreamOutType(String,     ,toString, "mrs_string","Stream.op(mrs_string)");
00675 ExFun_StreamOutType(Real,   dtos,toReal,   "mrs_real","Stream.op(mrs_real)");
00676 ExFun_StreamOutType(Natural,ltos,toNatural,"mrs_natural","Stream.op(mrs_natural)");
00677 ExFun_StreamOutType(Bool,   btos,toBool,   "mrs_bool","Stream.op(mrs_bool)");
00678 //}}}
00679 // StreamOutNewline {{{
00680 #define ExFun_StreamOutNType(_TYPE,_CONVERSION,_METHOD,_type,_sig) \
00681 class ExFun_StreamOutN##_TYPE : public ExFun { public: \
00682     ExFun_StreamOutN##_TYPE() : ExFun(_type,_sig,false) { } \
00683     virtual ExVal calc() { ExVal x = params[0]->eval(); std::cout << _CONVERSION(x._METHOD()) << std::endl; return x; } \
00684     ExFun* copy() { return new ExFun_StreamOutN##_TYPE(); } \
00685 };
00686 ExFun_StreamOutNType(String, ,toString,"mrs_string","Stream.opn(mrs_string)");
00687 ExFun_StreamOutNType(Real,dtos,toReal,"mrs_real","Stream.opn(mrs_real)");
00688 ExFun_StreamOutNType(Natural,ltos,toNatural,"mrs_natural","Stream.opn(mrs_natural)");
00689 ExFun_StreamOutNType(Bool,btos,toBool,"mrs_bool","Stream.opn(mrs_bool)");
00690 class ExFun_StreamOutNVal : public ExFun {
00691 ExNode* rec; public:
00692   ExFun_StreamOutNVal(ExNode* r) : ExFun("mrs_unit","Stream.opn(mrs_val)",false) { rec=r; }
00693   virtual ExVal calc() { ExVal x=rec->eval(); std::cout << x << std::endl; return x; }
00694   virtual ~ExFun_StreamOutNVal() { rec->deref(); }
00695   ExFun* copy() { return new ExFun_StreamOutNVal(rec); }
00696 };
00697 //}}}
00698 /*** Timer Library ***********************************************************/
00699 // TimerGetStuff {{{
00700 #define TIMER_GET(_NM,_ZERO,_METHOD,_type,_sig) \
00701 class ExFun_TimerGet##_NM : public ExFun { \
00702     ExFun* child; public: \
00703     ExFun_TimerGet##_NM() : ExFun(_type,_sig,false) {} \
00704     virtual ExVal calc() { TmTimer** t=params[0]->eval().toTimer(); return (t==NULL||*t==NULL) ? _ZERO : (*t)->_METHOD; } \
00705     ExFun* copy() { return new ExFun_TimerGet##_NM(); } \
00706 };
00707 TIMER_GET(Prefix,"",getPrefix(),"mrs_string","Timer.prefix(mrs_timer)");
00708 TIMER_GET(Name,"",getName(),"mrs_string","Timer.name(mrs_timer)");
00709 TIMER_GET(Type,"",getType(),"mrs_string","Timer.type(mrs_timer)");
00710 TIMER_GET(Time,0,getTime(),"mrs_natural","Timer.time(mrs_timer)");
00711 //}}}
00712 /*
00713 class ExFun_TimerGetTimer : public ExFun {
00714     TmTimer** tmr; public:
00715     ExFun_TimerGetTimer(TmTimer** tm) : ExFun(_type,_sig,false) { tmr=tm; }
00716     virtual ExVal calc() { return tmr; }
00717     ExFun* copy() { return new ExFun_TimerGetTimer(tmr); }
00718 };
00719 */
00720 class ExFun_TimerIntrvlSize : public ExFun//{{{
00721 {
00722 public:
00723   ExFun_TimerIntrvlSize() : ExFun("mrs_natural","Timer.ival(mrs_timer,mrs_string)",false) {}
00724   virtual ExVal calc() {
00725     TmTimer** t=params[0]->eval().toTimer();
00726     std::string ts=params[1]->eval().toString();
00727     return (t==NULL||*t==NULL) ? 0 : (*t)->intervalsize(ts);
00728   }
00729   ExFun* copy() { return new ExFun_TimerIntrvlSize(); }
00730 };//}}}
00731 // TimerUpd {{{
00732 #define TIMER_UPD(_NM,_ZERO,_METHOD,_type,_sig) \
00733 class ExFun_TimerUpd##_NM : public ExFun { public: \
00734     ExFun_TimerUpd##_NM() : ExFun(_type,_sig,false) {} \
00735     virtual ExVal calc() { \
00736         TmTimer** t=params[0]->eval().toTimer(); \
00737         ExVal s=params[1]->eval(); \
00738         ExVal v=params[2]->eval(); \
00739         if (t==NULL||*t==NULL) { (*t)->updtimer(s.toString(),v._METHOD); return true; } return false; \
00740     } \
00741     ExFun* copy() { return new ExFun_TimerUpd##_NM(); } \
00742 };
00743 TIMER_UPD(Real,0.0,toReal(),"mrs_bool","Timer.upd(mrs_timer,mrs_string,mrs_real)");
00744 TIMER_UPD(Natural,0,toNatural(),"mrs_bool","Timer.upd(mrs_timer,mrs_string,mrs_natural)");
00745 TIMER_UPD(String,"",toString(),"mrs_bool","Timer.upd(mrs_timer,mrs_string,mrs_string)");
00746 TIMER_UPD(Bool,false,toBool(),"mrs_bool","Timer.upd(mrs_timer,mrs_string,mrs_bool)");
00747 //}}}
00748 /*****************************************************************************/
00749 class ExFun_ListLen : public ExFun//{{{
00750 {
00751 public:
00752   ExFun_ListLen() : ExFun("mrs_natural","List.len(mrs_list)",true) { }
00753   virtual ExVal calc() { return (mrs_natural)(params[0]->eval()).toNatural(); }//((params[0]->eval()).toNatural()); }
00754   ExFun* copy() { return new ExFun_ListLen(); }
00755 };//}}}
00756 /*** Done ********************************************************************/
00757 
00758 }//namespace Marsyas
00759 
00760 #endif
00761