Logo Search packages:      
Sourcecode: faust version File versions  Download package

node.hh

Go to the documentation of this file.
/************************************************************************
 ************************************************************************
    FAUST compiler
      Copyright (C) 2003-2004 GRAME, Centre National de Creation Musicale
    ---------------------------------------------------------------------
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 ************************************************************************
 ************************************************************************/



/*****************************************************************************
******************************************************************************/

/** \file node.hh
 * A Node is a tagged unions of int, double, symbol and void* used in the implementation of CTrees.
 * Nodes are completly described by the node.h file, there is no node.cpp file.
 *
 * <b>API:</b>
 *
 *    Node(symbol("abcd"));   : node with symbol content
 *    Node(10);                     : node with int content
 *    Node(3.14159);                : node with double content
 *
 *    n->type();                    : kIntNode or kDoubleNode or kSymNode
 *
 *    n->getInt();                  : int content of n
 *    n->getDouble();               : double content of n
 *    n->getSym();                  : symbol content of n
 *
 *    if (isInt(n, &i)) ... : int i = int content of n
 *    if (isDouble(n, &f))    ... : double f = double content of n
 *    if (isSym(n, &s)) ... : Sym s = Sym content of n
 *
 */

/******************************************************************************
*****************************************************************************/


#ifndef     __NODE__
#define     __NODE__

#include <iostream>
#include "symbol.hh"

using namespace std;

/**
 * Tags used to define the type of a Node
 */
enum { kIntNode, kDoubleNode, kSymNode, kPointerNode };


/**
 * Class Node = (type x (int + double + Sym + void*))
 */
00070 class Node
{
      int         fType;
      union {
            int   i;
            double      f;
            Sym   s;
            void*       p;
      } fData;

 public:
      // constructeurs (assume size of field f is the biggest)
      Node (int x)                        : fType(kIntNode)             { fData.f = 0; fData.i = x; }
      Node (double x)               : fType(kDoubleNode)    { fData.f = x; }
      Node (const char* name)       : fType(kSymNode)             { fData.f = 0; fData.s = symbol(name); }
      Node (const string& name)     : fType(kSymNode)             { fData.f = 0; fData.s = symbol(name); }
      Node (Sym x)                        : fType(kSymNode)             { fData.f = 0; fData.s = x; }
      Node (void* x)                      : fType(kPointerNode)   { fData.f = 0; fData.p = x; }

    Node (const Node& n)        : fType(n.fType)        { fData = n.fData; }

      // predicats
      bool operator == (const Node& n) const { return fType == n.fType && fData.f == n.fData.f; }
      bool operator != (const Node& n) const { return fType != n.fType || fData.f != n.fData.f; }

      // accessors
      int         type()            const       { return fType; }

      int         getInt()          const       { return fData.i; }
      double      getDouble()       const       { return fData.f; }
      Sym   getSym()          const       { return fData.s; }
      void*       getPointer()      const       { return fData.p; }

      // conversions and promotion for numbers
      operator int()     const          { return (fType == kIntNode) ? fData.i : (fType == kDoubleNode) ? int(fData.f) : 0 ; }
    operator double() const     { return (fType == kIntNode) ? double(fData.i) : (fType == kDoubleNode) ? fData.f : 0.0 ; }

      ostream&    print (ostream& fout) const;                          ///< print a node on a stream
};

//printing
inline ostream& operator << (ostream& s, const Node& n) { return n.print(s); }



//-------------------------------------------------------------------------
// Perdicates and pattern matching
//-------------------------------------------------------------------------

// integers
inline bool isInt (const Node& n)
{
      return (n.type() == kIntNode);
}

inline bool isInt (const Node& n, int* x)
{
      if (n.type() == kIntNode) {
            *x = n.getInt();
            return true;
      } else {
            return false;
      }
}


// floats
inline bool isDouble (const Node& n)
{
      return (n.type() == kDoubleNode);
}

inline bool isDouble (const Node& n, double* x)
{
      if (n.type() == kDoubleNode) {
            *x = n.getDouble();
            return true;
      } else {
            return false;
      }
}



inline bool isZero (const Node& n)
{
      return (n.type() == kDoubleNode) && (n.getDouble() == 0.0)
            || (n.type() == kIntNode) && (n.getInt() == 0);
}

inline bool isGEZero (const Node& n)
{
      return (n.type() == kDoubleNode) && (n.getDouble() >= 0.0)
            || (n.type() == kIntNode) && (n.getInt() >= 0);
}

inline bool isGTZero (const Node& n)
{
      return (n.type() == kDoubleNode) && (n.getDouble() > 0.0)
            || (n.type() == kIntNode) && (n.getInt() > 0);
}

inline bool isOne (const Node& n)
{
      return (n.type() == kDoubleNode) && (n.getDouble() == 1.0)
            || (n.type() == kIntNode) && (n.getInt() == 1);
}

inline bool isMinusOne (const Node& n)
{
      return (n.type() == kDoubleNode) && (n.getDouble() == -1.0)
            || (n.type() == kIntNode) && (n.getInt() == -1);
}


// numbers in general
inline bool isNum (const Node& n)
{
      return isInt(n)||isDouble(n);
}


// symbols
inline bool isSym (const Node& n)
{
      return (n.type() == kSymNode);
}

inline bool isSym (const Node& n, Sym* x)
{
      if (n.type() == kSymNode) {
            *x = n.getSym();
            return true;
      } else {
            return false;
      }
}


// void pointer
inline bool isPointer (const Node& n)
{
      return (n.type() == kPointerNode);
}

inline bool isPointer (const Node& n, void** x)
{
      if (n.type() == kPointerNode) {
            *x = n.getPointer();
            return true;
      } else {
            return false;
      }
}




//-------------------------------------------------------------------------
// Mathematical operations on nodes
//-------------------------------------------------------------------------


// arithmetic operations

inline const Node addNode (const Node& x, const Node& y)
      { return (isDouble(x)||isDouble(y)) ? Node(double(x)+double(y)) : Node(int(x)+int(y)); }

inline const Node subNode (const Node& x, const Node& y)
      { return (isDouble(x)||isDouble(y)) ? Node(double(x)-double(y)) : Node(int(x)-int(y)); }

inline const Node mulNode (const Node& x, const Node& y)
      { return (isDouble(x)||isDouble(y)) ? Node(double(x)*double(y)) : Node(int(x)*int(y)); }

inline const Node divNode (const Node& x, const Node& y)
      { return (isDouble(x)||isDouble(y)) ? Node(double(x)/double(y)) : Node(int(x)/int(y)); }

inline const Node divExtendedNode (const Node& x, const Node& y)
      { return  (isDouble(x)||isDouble(y)) ? Node(double(x)/double(y))
                  : (double(int(x)/int(y))==double(x)/double(y)) ? Node(int(x)/int(y))
                  : Node(double(x)/double(y)); }

inline const Node remNode (const Node& x, const Node& y)
      { return Node(int(x)%int(y)); }

// inverse functions

inline const Node minusNode (const Node& x)
      { return subNode(0, x); }

inline const Node inverseNode (const Node& x)
      { return divNode(1.0f, x); }


// bit shifting operations

inline const Node lshNode (const Node& x, const Node& y)
      { return Node(int(x)<<int(y)); }

inline const Node rshNode (const Node& x, const Node& y)
      { return Node(int(x)>>int(y)); }


// boolean operations on bits

inline const Node andNode (const Node& x, const Node& y)
      { return Node(int(x)&int(y)); }

inline const Node orNode (const Node& x, const Node& y)
      { return Node(int(x)|int(y)); }

inline const Node xorNode (const Node& x, const Node& y)
      { return Node(int(x)^int(y)); }


// compare operations

inline const Node gtNode (const Node& x, const Node& y)
      { return (isDouble(x)||isDouble(y)) ? Node(double(x)>double(y)) : Node(int(x)>int(y)); }

inline const Node ltNode (const Node& x, const Node& y)
      { return (isDouble(x)||isDouble(y)) ? Node(double(x)<double(y)) : Node(int(x)<int(y)); }

inline const Node geNode (const Node& x, const Node& y)
      { return (isDouble(x)||isDouble(y)) ? Node(double(x)>=double(y)) : Node(int(x)>=int(y)); }

inline const Node leNode (const Node& x, const Node& y)
      { return (isDouble(x)||isDouble(y)) ? Node(double(x)<=double(y)) : Node(int(x)<=int(y)); }
#if 1
inline const Node eqNode (const Node& x, const Node& y)
      { return (isDouble(x)||isDouble(y)) ? Node(double(x)==double(y)) : Node(int(x)==int(y)); }

inline const Node neNode (const Node& x, const Node& y)
      { return (isDouble(x)||isDouble(y)) ? Node(double(x)!=double(y)) : Node(int(x)!=int(y)); }
#endif



#endif

Generated by  Doxygen 1.6.0   Back to index