Logo Search packages:      
Sourcecode: fauhdlc version File versions

BuiltinFunction.hpp

/* $Id: BuiltinFunction.hpp 4323 2009-01-27 13:48:12Z potyra $ 
 * BuiltinFunction: inline implementation of a number of builtin functions like
 *                  operators.
 *
 * Copyright (C) 2008-2009 FAUmachine Team <info@faumachine.org>.
 * This program is free software. You can redistribute it and/or modify it
 * under the terms of the GNU General Public License, either version 2 of
 * the License, or (at your option) any later version. See COPYING.
 */


#ifndef __BUILTIN_FUNCTION_HPP_INCLUDED
#define __BUILTIN_FUNCTION_HPP_INCLUDED

#include <cassert>
#include <list>
#include "frontend/misc/BuiltinSymbolTable.hpp"
#include "frontend/ast/ConstInteger.hpp"
#include "frontend/ast/TypeDeclaration.hpp"

namespace ast {

//! helper class for math of arbitrary universal types.
00024 class UniversalMath {
public:
      //! calculate absolute value
      /** @param numeric value, for which abs should get calculated.
       *  @return absolute value.
       */
      template <typename T>
      static T
00032       abs(T value) {
            if (value < 0) {
                  return -value;
            }

            return value;
      }
};

/** any builtin function should derive from this class. */
00042 class BuiltinFunction {
public:
      //! virtual dummy d'tor.
00045       virtual ~BuiltinFunction() {}

      /** execute the builtin returning the result.
       *  @param args arguments for the builtin function.
       *  @return result of the builtin */
      virtual Expression* execute(std::list<Expression*> args) const = 0;
};

//! any unary operand should implement this class
/** Template parameter C: type of const node.
 *  Template parameter V: value type of const node.
 */
template <typename C, typename V>
00058 class BuiltinUnop : public BuiltinFunction {
public:
      /** execute the builtin returning the result.
       *  @param args arguments for the builtin function.
       *  @return result of the builtin */
00063       virtual Expression* execute(std::list<Expression*> args) const {
            assert(args.size() == 1);

            Expression *f = args.front();
            C *constNode = dynamic_cast<C*>(f);
            assert(constNode != NULL);
            
            V result = this->executeUnop(constNode->value);
            C *rNode = new C(result, f->location);
            rNode->type = f->type;

            return rNode;
      }

protected:
      /** execute the unary operator.
       *  @param operand operand value.
       *  @return value of the builtin.
       */
      virtual V executeUnop(V operand) const = 0;
};

//! any binary operand with same parameter should dervive from this class
/** Template parameter C: type of const node.
 *  Template parameter V: value type of const node.
 */
template <typename C, typename V>
00090 class BuiltinBinOpSameType : public BuiltinFunction {
public:
      /** execute the builtin returning the result.
       *  @param args arguments for the builtin function.
       *  @return result of the builtin */
00095       virtual Expression* execute(std::list<Expression*> args) const {
            assert(args.size() == 2);

            Expression *l = args.front();
            C *left = dynamic_cast<C*>(l);
            Expression *r = args.back();
            C *right = dynamic_cast<C*>(r);
            assert(left != NULL);
            assert(right != NULL);
            
            V result = this->executeBinOp(left->value, right->value);
            C *resNode = new C(result, left->location);
            resNode->type = left->type;
            return resNode;
      }

protected:
      /** execute the binary operator
       *  @param left left operand
       *  @param right right operand
       *  @return value of the builtin.
       */
      virtual V executeBinOp(V left, V right) const = 0;
};

//! any binary operand with same parameter resulting in std.std.bool use this
/** Template parameter C: type of const node.
 *  Template parameter V: value type of const node.
 */
template <typename C, typename V>
00125 class BoolBinOpSameType : public BuiltinFunction {
public:
      /** c'tor
       *  @param symTab SymbolTable instance (to look up std.std.boolean).
       */
00130       BoolBinOpSameType(SymbolTable &symTab) : st(symTab) {}

      /** execute the builtin returning the result.
       *  @param args arguments for the builtin function.
       *  @return result of the builtin */
00135       virtual Expression* execute(std::list<Expression*> args) const {
            assert(args.size() == 2);

            Expression *l = args.front();
            C *left = dynamic_cast<C*>(l);
            Expression *r = args.back();
            C *right = dynamic_cast<C*>(r);
            assert(left != NULL);
            assert(right != NULL);
            
            bool result = this->executeBinOp(left->value, right->value);
            universal_integer resVal = VHDL_FALSE;
            if (result) {
                  resVal = VHDL_TRUE;
            }

            ConstInteger *resNode = 
                  new ConstInteger(resVal, left->location);
            TypeDeclaration *boolean = st.getStdStandardType("boolean");
            resNode->type = 
                  new SubtypeIndication(boolean, boolean->location);
            return resNode;
      }

protected:
      /** execute the binary operator
       *  @param left left operand
       *  @param right right operand
       *  @return value of the builtin.
       */
      virtual bool executeBinOp(V left, V right) const = 0;

private:
      SymbolTable &st;
};


//! unary minus
template <typename C, typename V>
00174 class UnaryMinus : public BuiltinUnop<C, V> {
private:
      /** execute the builtin returning the result.
       *  @return result of this builtin.
       */
00179       virtual V executeUnop(V operand) const {
            return - operand;
      }
};

//! unary plus (identity)
template <typename C, typename V>
00186 class UnaryPlus : public BuiltinUnop<C, V> {
private:
      /** execute the builtin returning the result.
       *  @return result of this builtin.
       */
00191       virtual V executeUnop(V operand) const {
            return operand;
      }
};

//! unary absolute value
template <typename C, typename V>
00198 class UnaryAbs : public BuiltinUnop<C, V> {
private:
      /** execute the builtin returning the result.
       *  @return result of this builtin.
       */
00203       virtual V executeUnop(V operand) const {
            if (operand < 0) {
                  return - operand;
            }

            return operand;
      }
};

//! binary plus
template <typename C, typename V>
00214 class BinaryPlus : public BuiltinBinOpSameType<C, V> {
private:
      /** execute the binary operator
       *  @param left left operand
       *  @param right right operand
       *  @return value of the builtin.
       */
00221       virtual V executeBinOp(V left, V right) const {
            // FIXME range check!
            return left + right;
      }
}; 

//! binary minus
template <typename C, typename V>
00229 class BinaryMinus : public BuiltinBinOpSameType<C, V> {
private:
      /** execute the binary operator
       *  @param left left operand
       *  @param right right operand
       *  @return value of the builtin.
       */
00236       virtual V executeBinOp(V left, V right) const {
            // FIXME range check!
            return left - right;
      }
};

//! binary multiplication
template <typename C, typename V>
00244 class BinaryMult : public BuiltinBinOpSameType<C, V> {
private:
      /** execute the binary operator
       *  @param left left operand
       *  @param right right operand
       *  @return value of the builtin.
       */
00251       virtual V executeBinOp(V left, V right) const {
            // FIXME range check!
            return left * right;
      }
};

//! binary division
template <typename C, typename V>
00259 class BinaryDiv : public BuiltinBinOpSameType<C, V> {
private:
      /** execute the binary operator
       *  @param left left operand
       *  @param right right operand
       *  @return value of the builtin.
       */
00266       virtual V executeBinOp(V left, V right) const {
            return left / right;
      }
};

//! binary modulo (only for integer types)
00272 class BinaryMod : 
      public BuiltinBinOpSameType<ConstInteger, universal_integer> {
private:
      /** execute the binary operator
       *  @param left left operand
       *  @param right right operand
       *  @return value of the builtin.
       */
      virtual universal_integer 
00281       executeBinOp(universal_integer left, universal_integer right) const {
            //lrm, p.105: A = B * N + (A mod B)
            //            sign of B, abs(A mod B) < abs(B)
            //
            //    5 % 4
            //    4 * N + (mod)
            //    4 * 1 + 1
            //
            //    5 % -4
            //    -4 * -2 + (-3)
            //
            //    -5 % 4 
            //      4 * -2 + 3
            //  
            //      -5 % -4
            //      -4 * 1 + (-1)
            // FIXME: right == 0 -> error
            assert(right != 0);

            if ((left > 0) && (right < 0)) {
                  universal_integer tmp = 
                        UniversalMath::abs(
                              left % UniversalMath::abs(right));
                  return right + tmp;
            }

            if ((left < 0) && (right > 0)) {
                  universal_integer tmp = 
                        UniversalMath::abs(
                              UniversalMath::abs(left) % right);
                  return right - tmp;
            }

            universal_integer tmp = 
                  UniversalMath::abs(
                        UniversalMath::abs(left) % 
                              UniversalMath::abs(right));
            if (right < 0) {
                  return -tmp;
            }

            return tmp;
      }
};

//! binary remainder (only for integer types)
00327 class BinaryRem : 
      public BuiltinBinOpSameType<ConstInteger, universal_integer> {
private:
      /** execute the binary operator
       *  @param left left operand
       *  @param right right operand
       *  @return value of the builtin.
       */
      virtual universal_integer 
00336       executeBinOp(universal_integer left, universal_integer right) const {
            //lrm, p. 104: A = (A/B) ∗ B +(A rem B)
            //             A rem B has the sign of A and 
            //             a abs. value less than abs (B)
            // FIXME right == 0 -> error
            assert(right != 0);
            
            return left - ((left / right) * right);
      }
};

//! universal equal operator
template <typename C, typename V>
00349 class BoolEqual : public BoolBinOpSameType<C, V> {
public:
      //! c'tor
      /** @param symTab SymbolTable instance 
       */
00354       BoolEqual(SymbolTable &symTab) : BoolBinOpSameType<C, V>(symTab) {}

private:
      /** execute the binary operator
       *  @param left left operand
       *  @param right right operand
       *  @return value of the builtin.
       */
      virtual bool
00363       executeBinOp(V left, V right) const {
            return left == right;
      }
};

//! universal not equal operator
template <typename C, typename V>
00370 class BoolNotEqual : public BoolBinOpSameType<C, V> {
public:
      //! c'tor
      /** @param symTab SymbolTable instance 
       */
00375       BoolNotEqual(SymbolTable &symTab) : BoolBinOpSameType<C, V>(symTab) {}

private:
      /** execute the binary operator
       *  @param left left operand
       *  @param right right operand
       *  @return value of the builtin.
       */
      virtual bool
00384       executeBinOp(V left, V right) const {
            return left != right;
      }
};

//! universal less than operator
template <typename C, typename V>
00391 class BoolLess : public BoolBinOpSameType<C, V> {
public:
      //! c'tor
      /** @param symTab SymbolTable instance 
       */
00396       BoolLess(SymbolTable &symTab) : BoolBinOpSameType<C, V>(symTab) {}

private:
      /** execute the binary operator
       *  @param left left operand
       *  @param right right operand
       *  @return value of the builtin.
       */
      virtual bool
00405       executeBinOp(V left, V right) const {
            return left < right;
      }
};

//! universal less or equal
template <typename C, typename V>
00412 class BoolLessOrEqual : public BoolBinOpSameType<C, V> {
public:
      //! c'tor
      /** @param symTab SymbolTable instance 
       */
00417       BoolLessOrEqual(
            SymbolTable &symTab
            ) :   BoolBinOpSameType<C, V>(symTab) {}

private:
      /** execute the binary operator
       *  @param left left operand
       *  @param right right operand
       *  @return value of the builtin.
       */
      virtual bool
00428       executeBinOp(V left, V right) const {
            return left <= right;
      }
};

//! universal greater than operator
template <typename C, typename V>
00435 class BoolGreater : public BoolBinOpSameType<C, V> {
public:
      //! c'tor
      /** @param symTab SymbolTable instance 
       */
00440       BoolGreater(SymbolTable &symTab) : BoolBinOpSameType<C, V>(symTab) {}

private:
      /** execute the binary operator
       *  @param left left operand
       *  @param right right operand
       *  @return value of the builtin.
       */
      virtual bool
00449       executeBinOp(V left, V right) const {
            return left > right;
      }
};

//! universal greater or equal
template <typename C, typename V>
00456 class BoolGreaterOrEqual : public BoolBinOpSameType<C, V> {
public:
      //! c'tor
      /** @param symTab SymbolTable instance 
       */
00461       BoolGreaterOrEqual(
            SymbolTable &symTab
            ) :   BoolBinOpSameType<C, V>(symTab) {}

private:
      /** execute the binary operator
       *  @param left left operand
       *  @param right right operand
       *  @return value of the builtin.
       */
      virtual bool
00472       executeBinOp(V left, V right) const {
            return left >= right;
      }
};

//! AND operator (bit, boolean)
00478 class EnumAND : public BuiltinBinOpSameType<ConstInteger, universal_integer> {
private:
      /** execute the binary operator
       *  @param left left operand
       *  @param right right operand
       *  @return value of the builtin.
       */
      virtual universal_integer
00486       executeBinOp(universal_integer left, universal_integer right) const {
            if ((left == VHDL_TRUE) && (right == VHDL_TRUE)) {
                  return VHDL_TRUE;
            }

            return VHDL_FALSE;
      }
};

//! OR operator (bit, boolean)
00496 class EnumOR : public BuiltinBinOpSameType<ConstInteger, universal_integer> {
private:
      /** execute the binary operator
       *  @param left left operand
       *  @param right right operand
       *  @return value of the builtin.
       */
      virtual universal_integer
00504       executeBinOp(universal_integer left, universal_integer right) const {
            if ((left == VHDL_TRUE) || (right == VHDL_TRUE)) {
                  return VHDL_TRUE;
            }

            return VHDL_FALSE;
      }
};

//! NAND operator (bit, boolean)
00514 class EnumNAND : public BuiltinBinOpSameType<ConstInteger, universal_integer> {
private:
      /** execute the binary operator
       *  @param left left operand
       *  @param right right operand
       *  @return value of the builtin.
       */
      virtual universal_integer
00522       executeBinOp(universal_integer left, universal_integer right) const {
            if ((left == VHDL_TRUE) && (right == VHDL_TRUE)) {
                  return VHDL_FALSE;
            }

            return VHDL_TRUE;
      }
};

//! NOR operator (bit, boolean)
00532 class EnumNOR : public BuiltinBinOpSameType<ConstInteger, universal_integer> {
private:
      /** execute the binary operator
       *  @param left left operand
       *  @param right right operand
       *  @return value of the builtin.
       */
      virtual universal_integer
00540       executeBinOp(universal_integer left, universal_integer right) const {
            if ((left == VHDL_TRUE) || (right == VHDL_TRUE)) {
                  return VHDL_FALSE;
            }

            return VHDL_TRUE;
      }
};

//! XOR operator (bit, boolean)
00550 class EnumXOR : public BuiltinBinOpSameType<ConstInteger, universal_integer> {
private:
      /** execute the binary operator
       *  @param left left operand
       *  @param right right operand
       *  @return value of the builtin.
       */
      virtual universal_integer
00558       executeBinOp(universal_integer left, universal_integer right) const {
            if (left != right) {
                  return VHDL_TRUE;
            }

            return VHDL_FALSE;
      }
};

//! XNOR operator (bit, boolean)
00568 class EnumXNOR : public BuiltinBinOpSameType<ConstInteger, universal_integer> {
private:
      /** execute the binary operator
       *  @param left left operand
       *  @param right right operand
       *  @return value of the builtin.
       */
      virtual universal_integer
00576       executeBinOp(universal_integer left, universal_integer right) const {
            if (left != right) {
                  return VHDL_FALSE;
            }

            return VHDL_TRUE;
      }
};

//! unary NOT (bit, boolean)
00586 class EnumNOT : public BuiltinUnop<ConstInteger, universal_integer> {
private:
      /** execute the builtin returning the result.
       *  @return result of this builtin.
       */
      virtual universal_integer 
00592       executeUnop(universal_integer operand) const {
            if (operand == VHDL_TRUE) {
                  return VHDL_FALSE;
            }

            return VHDL_TRUE;
      }
};

//! return a predefined value, to be used by enumeration types.
00602 class ReturnValue : public BuiltinFunction {
public:
      //! c'tor.
      /** @param value this value will be returned on execution. 
       *  @param t type of the return value.
       */
00608       ReturnValue(
            universal_integer value,
            const TypeDeclaration *t
            ) :   val(value),
                  type(t) {}

      /** execute the builtin returning the result.
       *  @param args arguments for the builtin function.
       *  @return the predefined value. */
00617       virtual Expression* execute(std::list<Expression*> args) const {
            assert(args.empty());

            ConstInteger *ret =  new ConstInteger(this->val, 
                              Location("Builtin result"));
            ret->type = new SubtypeIndication(this->type, 
                                    this->type->location);
            return ret;
      }

private:
      //! value to return on execution.
00629       universal_integer val;
      //! corresponding type declaration
00631       const TypeDeclaration *type;
};


};

#endif /* __BUILTIN_FUNCTION_HPP_INCLUDED */

Generated by  Doxygen 1.6.0   Back to index