Logo Search packages:      
Sourcecode: maria version File versions

Type.h

Go to the documentation of this file.
// Data type base class -*- c++ -*-

#ifndef TYPE_H_
# define TYPE_H_
# ifdef __GNUC__
#  pragma interface
# endif // __GNUC__

# include "util.h"
# include <string.h>
# include <assert.h>

/** @file Type.h
 * Abstract base class for data types
 */

/* Copyright © 1998-2003 Marko Mäkelä (msmakela@tcs.hut.fi).

   This file is part of MARIA, a reachability analyzer and model checker
   for high-level Petri nets.

   MARIA 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, or (at your option)
   any later version.

   MARIA 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.

   The GNU General Public License is often shipped with GNU software, and
   is generally kept in a file called COPYING or LICENSE.  If you do not
   have a copy of the license, write to the Free Software Foundation,
   59 Temple Place, Suite 330, Boston, MA 02111 USA. */

/** Data type base class */
00038 class Type
{
public:
  /** Type kinds (@see getKind) */
00042   enum Kind {
    tInt, tCard, tBool, tChar, tEnum, tId, tStruct, tVector, tUnion, tBuffer
  };

  /** Constructor */
  Type ();
protected:
  /** Copy constructor */
  Type (const class Type& old);
private:
  /** Assignment operator */
  class Type& operator= (const class Type& old);
public:
  /** Destructor */
  virtual ~Type ();
  /** Copy Type */
  virtual class Type* copy () const = 0;

  /** Determine the kind of the type */
  virtual enum Kind getKind () const = 0;

  /** Set the name of the type */
00064   void setName (char* name) { assert (!myName); myName = name; }
  /** Determine the name of the type */
00066   const char* getName () const { return myName; }

  /** Determine the syntactic name of the type */
  const char* getSyntacticName () const;

  /** Determine whether the type is ordered */
00072   bool isOrdered () const { return myIsOrdered; }
protected:
  /** Flag the type unordered */
00075   void flagUnordered () { myIsOrdered = false; }
public:
  /** Get the first value of this type (only for ordered types) */
  virtual class Value& getFirstValue () const = 0;
  /** Get the last value of this type (only for ordered types) */
  virtual class Value& getLastValue () const = 0;

  /** See if the type is assignable to another type
   * @param type  the type this type should be assignable to
   * @return            true if this type is assignable to the type
   */
  virtual bool isAssignable (const class Type& type) const;

  /** See if the type is always assignable to another type
   * @param type  the type this type should always be assignable to
   * @return            true if this type always is assignable to the type
   */
  virtual bool isAlwaysAssignable (const class Type& type) const;

  /** See if two types are assignable to each other
   * @param type1 first type to be checked
   * @param type2 second type to be checked
   * @return            true if the types are compatible with each other
   */
00099   static bool isCompatible (const class Type& type1, const class Type& type2) {
    return type1.isAssignable (type2) && type2.isAssignable (type1);
  }

  /** See if two types always are assignable to each other
   * @param type1 first type to be checked
   * @param type2 second type to be checked
   * @return            true if the types always are compatible with each other
   */
00108   static bool isAlwaysCompatible (const class Type& type1,
                          const class Type& type2) {
    return
      type1.isAlwaysAssignable (type2) && type2.isAlwaysAssignable (type1);
  }

  /** Determine whether a value is compatible with the constraints of this type
   * @param value value to check
   * @return            true if the value passes the constraint check
   */
  virtual bool isConstrained (const class Value& value) const;

  /**
   * Determine the number of possible values for this type or CARD_T_MAX,
   * if there are >= CARD_T_MAX possible values
   * @return            number of possible values
   */
00125   card_t getNumValues () const {
    if (myNumValues);
    else if (myConstraint)
      myNumValues = getNumConstrainedValues ();
    else
      myNumValues = do_getNumValues ();
    assert (myNumValues);
    return myNumValues;
  }

private:
  /**
   * Determine the number of possible values for this constrained type
   * @return            number of possible values
   */
  card_t getNumConstrainedValues () const;

  /** Determine the number of possible values for this type or CARD_T_MAX,
   * if there are >= CARD_T_MAX possible values
   * @return            number of possible values
   */
  virtual card_t do_getNumValues () const = 0;
public:

  /** Set the constraint */
  void setConstraint (class Constraint& constraint);

  /** Get the constraint */
00153   const class Constraint* getConstraint () const { return myConstraint; }
  /** Get the constraint */
00155   class Constraint* getConstraint () { return myConstraint; }

  /** Convert a value of this type to a number
   * @param value value to be converted
   * @return            number between 0 and getNumValues () - 1
   */
  virtual card_t convert (const class Value& value) const;

  /** Convert a number to a value of this type
   * @param number      number between 0 and getNumValues () - 1
   * @return            the corresponding value
   */
  virtual class Value* convert (card_t number) const;

  /** Determine whether this is a leaf type */
00170   bool isLeaf () const {
    switch (getKind ()) {
    case tInt: case tCard: case tBool: case tChar: case tEnum: case tId:
      return true;
    case tStruct: case tVector: case tUnion: case tBuffer:
      return false;
    }
    assert (false);
    return false;
  }

# ifdef EXPR_COMPILE
  /** Get the type this is derived from, or NULL */
  const class Type* getFather () const { return myFather; }
  /** Cancel the compilation */
  void uncompile ();
  /** Determine if the comparison code for the type has been generated */
  bool isGenerated ();
  /** Reset the counter of compiled types */
  static void uncompileAll ();

  /** Generate a C type declaration and auxiliary functions
   * @param out         output stream for the declarations
   */
  virtual void compile (class StringBuffer& out);

  /** Generate a C type declaration
   * @param out         output stream for the declarations
   * @param indent      indentation level
   */
  virtual void compileDefinition (class StringBuffer& out,
                          unsigned indent) const = 0;

  /** Generate auxiliary definitions
   * @param out         output stream for the declarations
   * @param indent      indentation level
   * @param interface   flag: generate interface declarations
   */
  virtual void compileExtraDefinitions (class StringBuffer& out,
                              unsigned indent,
                              bool interface) const;

  /** Generate equality or inequality comparison expression
   * @param out         output stream
   * @param indent      indentation level
   * @param left  left-hand-side C expression to be compared
   * @param right right-hand-side C expression to be compared
   * @param equal type of comparison: true=equality, false=inequality
   * @param first flag: first component (no indentation)
   * @param last  flag: last component (no expression chaining)
   * @param backslash   flag: prepend all newlines with backslashes
   * @return            true if any code was generated
   */
  virtual bool compileEqual (class StringBuffer& out,
                       unsigned indent,
                       const char* left,
                       const char* right,
                       bool equal,
                       bool first,
                       bool last,
                       bool backslash) const;

  /** Generate three-way comparison statements
   * @param out         output stream
   */
  void compileCompare3 (class StringBuffer& out) const {
    compileCompare3 (out, 0, "");
  }

  /** Generate three-way comparison statements
   * @param out         output stream
   * @param condition   additional condition for the comparison (NULL=none)
   * @param component   component to be compared
   */
  virtual void compileCompare3 (class StringBuffer& out,
                        const char* condition,
                        const char* component) const;
  /** Generate three-way comparison statements for leaf components
   * @param out         output stream
   * @param condition   additional condition for the comparison (NULL=none)
   * @param component   component to be compared
   */
  static void compileLeafCompare3 (class StringBuffer& out,
                           const char* condition,
                           const char* component);

  /** Generate statements for incrementing a value
   * @param out         output stream
   * @param indent      indentation level
   * @param lvalue      variable to receive the result
   * @param rvalue      variable whose successor is to be computed
   * @param wrap  overflow flag variable (NULL=omit overwrap code)
   */
  void compileSuccessor (class StringBuffer& out,
                   unsigned indent,
                   const char* lvalue,
                   const char* rvalue,
                   const char* wrap) const;

  /** Generate statements for decrementing a value
   * @param out         output stream
   * @param indent      indentation level
   * @param lvalue      variable to receive the result
   * @param rvalue      variable whose predecessor is to be computed
   * @param wrap  overflow flag variable (NULL=omit overwrap code)
   */
  void compilePredecessor (class StringBuffer& out,
                     unsigned indent,
                     const char* lvalue,
                     const char* rvalue,
                     const char* wrap) const;

  /** Generate statements for incrementing an unconstrained value
   * @param out         output stream
   * @param indent      indentation level
   * @param lvalue      variable to receive the result
   * @param rvalue      variable whose successor is to be computed
   * @param wrap  overflow flag variable (NULL=omit overwrap code)
   */
  virtual void do_compileSuccessor (class StringBuffer& out,
                            unsigned indent,
                            const char* lvalue,
                            const char* rvalue,
                            const char* wrap) const;

  /** Generate statements for decrementing an unconstrained value
   * @param out         output stream
   * @param indent      indentation level
   * @param lvalue      variable to receive the result
   * @param rvalue      variable whose predecessor is to be computed
   * @param wrap  overflow flag variable (NULL=omit overwrap code)
   */
  virtual void do_compilePredecessor (class StringBuffer& out,
                              unsigned indent,
                              const char* lvalue,
                              const char* rvalue,
                              const char* wrap) const;

  /** Emit an assignment to the first value of the compiled type
   * @param out         output stream
   * @param indent      indentation level (0=generate a compound expression)
   * @param value value to be assigned to
   */
  void compileBottom (class StringBuffer& out,
                  unsigned indent,
                  const char* value) const;

  /** Emit an assignment to the last value of the compiled type
   * @param out         output stream
   * @param indent      indentation level (0=generate a compound expression)
   * @param value value to be assigned to
   */
  void compileTop (class StringBuffer& out,
               unsigned indent,
               const char* value) const;

  /** Emit code for converting a value of this type to another
   * @param cexpr the compilation
   * @param indent      indentation level
   * @param target      target type
   * @param lvalue      left-hand-side value of the assignment
   * @param rvalue      C expression for the value to be converted
   */
  virtual void compileCast (class CExpression& cexpr,
                      unsigned indent,
                      const class Type& target,
                      const char* lvalue,
                      const char* rvalue) const;

  /** Emit code for converting a value to a number
   * @param out         output stream
   * @param indent      indentation level
   * @param value value to be converted
   * @param number      number to be computed
   * @param add         flag: add to number instead of assigning
   */
  void compileConversion (class StringBuffer& out,
                    unsigned indent,
                    const char* value,
                    const char* number,
                    bool add) const;

  /** Emit code for converting an unconstrained value to a number
   * @param out         output stream
   * @param indent      indentation level
   * @param value value to be converted
   * @param number      number to be computed
   * @param add         flag: add to number instead of assigning
   */
  virtual void do_compileConversion (class StringBuffer& out,
                             unsigned indent,
                             const char* value,
                             const char* number,
                             bool add) const = 0;

  /** Emit code for converting a number to a value
   * @param out         output stream
   * @param indent      indentation level
   * @param number      number to be converted
   * @param value value to be computed
   */
  virtual void compileReverseConversion (class StringBuffer& out,
                               unsigned indent,
                               const char* number,
                               const char* value) const;

  /** Emit code for encoding a value
   * @param cexpr the compilation
   * @param indent      indentation level
   * @param func  name of the encoding function
   * @param value value to be encoded
   */
  virtual void compileEncoder (class CExpression& cexpr,
                         unsigned indent,
                         const char* func,
                         const char* value) const;

  /** Emit code for decoding a value
   * @param cexpr the compilation
   * @param indent      indentation level
   * @param func  name of the decoding function
   * @param value value to be decoded
   */
  virtual void compileDecoder (class CExpression& cexpr,
                         unsigned indent,
                         const char* func,
                         const char* value) const;

  /** Emit the index of the compiled type
   * @param out         output stream
   */
  void appendIndex (class StringBuffer& out) const;

  /** Emit the name of the compiled type
   * @param out         output stream
   */
  void appendName (class StringBuffer& out) const;

  /** Emit the name of the compiled multi-set type
   * @param out         output stream
   */
  void appendMSetName (class StringBuffer& out) const;
# endif // EXPR_COMPILE

  /** Display the type definition
   * @param printer     the printer object
   */
  virtual void display (const class Printer& printer) const;

private:
  /** Number of possible values in the type */
00421   mutable card_t myNumValues;
  /** Name of the type (may be NULL) */
00423   char* myName;
  /** Flag: is the type ordered? */
00425   bool myIsOrdered;
protected:
  /** Constraint associated with the type */
00428   class Constraint* myConstraint;
# ifdef EXPR_COMPILE
  /** Index number of the compiled type */
  unsigned myIndex;
  /** Flag: have the comparison functions been generated? */
  bool myGenerated;
  /** Original type */
  const class Type* myFather;
# endif // EXPR_COMPILE
};

#endif // TYPE_H_

Generated by  Doxygen 1.6.0   Back to index