Logo Search packages:      
Sourcecode: fauhdlc version File versions

NodeFactory.hpp

/* $Id: NodeFactory.hpp 4323 2009-01-27 13:48:12Z potyra $ 
 *
 * NodeFactory: helper scripts for the Parser to create AST nodes, mainly
 *              useful to not keep lots of c++ code out of the parser.
 *
 * Copyright (C) 2007-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 __NODE_FACTORY_HPP_INCLUDED
#define __NODE_FACTORY_HPP_INCLUDED

#include <list>
#include <string>
#include "frontend/ast/Expression.hpp"
#include "frontend/ast/IfStat.hpp"
#include "frontend/ast/LoopStat.hpp"
#include "frontend/ast/ValDeclaration.hpp"
#include "frontend/ast/CondalSigAssign.hpp"
#include "frontend/ast/Location.hpp"
#include "frontend/ast/RecordType.hpp"
#include "frontend/reporting/SyntaxError.hpp"
#include "frontend/visitor/TopDownVisitor.hpp"
#include "frontend/ast/SignalDeclaration.hpp"
#include "frontend/ast/ConstantDeclaration.hpp"
#include "frontend/ast/Aggregate.hpp"
#include "frontend/ast/SubtypeIndication.hpp"

namespace ast {

class Symbol;
class SymbolTable;
class NameLookup;

/** The NodeFactory creates various AST nodes. It serves as a bridge between
 *  the parser and the Syntax Tree.
 */
00040 class NodeFactory {
public:
      /** entity class of an attribute specification */
00043       enum entityClassE {
            EC_ENTITY,
            EC_ARCHITECTURE,
            EC_CONFIGURATION,
            EC_PROCEDURE,
            EC_FUNCTION,
            EC_PACKAGE,
            EC_TYPE,
            EC_SUBTYPE,
            EC_CONSTANT,
            EC_SIGNAL,
            EC_VARIABLE,
            EC_COMPONENT,
            EC_LABEL,
            EC_LITERAL,
            EC_UNITS,
            EC_GROUP,
            EC_FILE
      };

      /** storage helper class to unify range and index constraints. */
00064       class Constraint {
      public:
            /** range constraint (if any) */
00067             DiscreteRange *rangeConstraint;
            /** index constraint(s) (if any) */
00069             std::list<DiscreteRange*> *indexConstraint;
      };
      /** glue class to forward information about one identifier */
00072       class Identifier {
      public:
            //! c'tor
            /** @param id string of the identifier
             *  @param sym corresponding symbol (if any)
             */
00078             Identifier(
                  std::string *id, 
                  std::list<Symbol*> cands
                  ) :   identifier(id), candidates(cands) {}
            
            /** string of the identifier */
00084             std::string *identifier;
            /** list of candidate symbols */
00086             std::list<Symbol*> candidates;
      };

      /** helper class for generating if_stats and condal signal
       *  assignments. 
       *  */
00092       struct IfHelperS {
            /** dummy c'tor: initialize members with NULL */
00094             IfHelperS() : topstat(NULL), bottomElse(NULL) {}
            /** topmost if-statement of elsif part */
00096             IfStat *topstat;
            /** reference to bottom most else part of elsif */
00098             std::list<SeqStat*> **bottomElse;
      };

      /** helper struct to flatten context items during parsing. */
00102       struct ContextItemS {
            /** dummy c'tor: initialize members with NULL */
00104             ContextItemS() : libClauses(NULL), useClauses(NULL) {}
            /** library clauses */
00106             std::list<SimpleName*> *libClauses;
            /** use clauses */
00108             std::list<Name*> *useClauses;
      };

      /** helper struct for type definitions. */
00112       struct TypeDeclHelper {
      public:
            /** c'tor for enumeration types
             *  @param et declared EnumerationType */
00116             TypeDeclHelper(
                  EnumerationType *et
                  ) :   enumType(et), 
                        typeDecl(NULL),
                        conArrayBase(NULL),
                        wasRecordType(false) {}
            /** c'tor for record types.
             *  @param rt declared RecordType
             */
00125             TypeDeclHelper(
                  RecordType *rt
                  ) :   enumType(NULL),
                        typeDecl(rt),
                        conArrayBase(NULL),
                        wasRecordType(true) {}

            /** c'tor for constraint array types.
             *  The constraint array types declare an anonymous 
             *  unconstraint array and a subtype with an index constraint.
             *  @param indexConstraint index constraint of the array.
             *  @param elementType SubtypeIndication of the elements.
             *  @param loc location of the array definition.
             *  @param s SymbolTable instance.
             */
            TypeDeclHelper(
                  std::list<DiscreteRange*> *indexConstraint,
                  SubtypeIndication *elementType,
                  Location loc,
                  SymbolTable &s);

            /** c'tor for other types.
             *  @param other any other type declaration.
             */
00149             TypeDeclHelper(
                  TypeDeclaration *other
                  ) :   enumType(NULL),
                        typeDecl(other),
                        conArrayBase(NULL),
                        wasRecordType(false) {}

            /** register type declaration to SymbolTable
             *  @param symTab SymbolTable instance.
             *  @param id identifier of the type declaration.
             */
            void 
            registerType(
                  SymbolTable &symTab,
                  NodeFactory::Identifier *id
            ) const;

            /** flatten to a list of SymbolDeclarations. */
            std::list<SymbolDeclaration*>*
            flatten(void) const;

            /** enumeration type, in case one was declared. */
00171             EnumerationType *enumType;
            /** any other type declaration. */
00173             TypeDeclaration *typeDecl;
            /** corresponding anonymous base type of a constraint array */
00175             TypeDeclaration *conArrayBase;
            /** was this type declaration a record type? */
00177             bool wasRecordType;
      };

      /** Helper function for parsing elsif statement lists
          * Attach a new ifStat from condition, thenStats to remainder.
          * If remainder doesn't exist, create a new IfHelperS.
          *
          * @param remainder the parent elsif remainder.
          * @param condition condition of the current elsif part.
          * @param thenStats then-statements of the current elsif part.
        * @param loc location of the elseif token.
          *
          * @return adjusted remainder or a new one if remainder doesn't exist
          *         yet.
          */
      static struct IfHelperS& 
      createNestedElseIfs(
            struct IfHelperS *remainder,
            Expression* condition,
            std::list<SeqStat*> *thenStats,
            Location loc
      );

      /** Helper function for parsing if_stats.
          * In case of elseIfs present, attach elseStats to bottom most
          * if-statement, and set elsIf part of current if statement to
          * else-part.
          * Otherwise build a "regular" if-then-else statement.
          * 
          * @param condition condition of the current if-stat.
          * @param thenStats then-statement of the current if-stat.
          * @param elsIfs the elseIfs, which should already be nested. Struct
          *        will get deleted from this function.
          * @param elseStats else statements of current if-stat.
        * @param loc location of the if token.
          * 
          * @return parsed IfStat.
          */
      static struct IfStat& 
      createIfStat(
            Expression *condition,
            std::list<SeqStat*> *thenStats,
            struct IfHelperS* elsIfs,
            std::list<SeqStat*> *elseStats,
            Location loc
      );

      
      /** Create a list of Signal declarations.
          * The contents of the parameters are reused in the result, so
          * the caller mustn't free them.
          *
          * @param ids list of Identifiers for each Signal. The list itself 
          *            isn't reused anywhere, so caller can free it.
          * @param mode access mode of signal (in, out, inout).
          * @param isBus is the signal tagged as bus?
          * @param varInit optional initializer of signal.
          * @param subtypeIndic subtype indication of signal.
        * @param loc location of the signal declaration.
          * @return list of ValDecls, caller must free it.
          */
      static std::list<SignalDeclaration*>& 
      makeSignalDecls(
            std::list<std::string*> &ids,
            enum ValDeclaration::Mode mode, 
            bool isBus, 
            Expression *varInit,
            SubtypeIndication *subtypeIndic,
            Location loc
      );


      /** Create a list of constant declarations.
          * The contents of the parameters are reused in the result, so
          * the caller mustn't free them.
          *
          * @param ids list of Identifiers for each Signal. The list itself 
          *            isn't reused anywhere, so caller can free it.
          * @param varInit optional initializer of constant.
          * @param subtypeIndic subtype indication of the constant.
        * @param loc Location of the constant declaration.
          * @return list of ValDecls, caller must free it.
          */
      static std::list<ConstantDeclaration*>& 
      makeConstantDecls(
            std::list<std::string*> &ids,
            Expression* varInit,
            SubtypeIndication *subtypeIndic,
            Location loc
      );

      /** Create a list of Variable declarations.
          * The contents of the parameters are reused in the result, so
          * the caller mustn't free them.
          *
          * @param ids list of Identifiers for each Variable. The list itself
          *            isn't reused anywhere, so caller can free it.
          * @param varInit optional initializer of variable.
          * @param subtypeIndic subtype indication of the variable.
        * @param loc Location of the variable declaration.
          * @return list of ValDecls, caller must free it.
          */
      static std::list<SymbolDeclaration*>& 
      makeVarDecls(
            std::list<std::string*> &ids,
            Expression *varInit,
            SubtypeIndication *subtypeIndic,
            Location loc
      );


      /** Create a list of ValDeclaration declarations.
          * The contents of the parameters are reused in the result, so
          * the caller mustn't free them.
          *
          * This version is for function declarations.
          *
          * @param ids list of Identifiers for each Variable. The list itself
          *            isn't reused anywhere, so caller can free it.
          * @param varInit optional initializer of variable.
          * @param cls object class that will determine if it's a 
          *          Signal, Variable or Constant.
          * @param subtypeIndic subtype indication of the element.
        * @param mode access mode of the ValDeclaration.
        * @param loc location in the source file.
          * @return list of ValDecls, caller must free it.
          */
      static std::list<ValDeclaration*>&
      makeFuncInterfaceDecls(
            std::list<std::string*> &ids,
            Expression *varInit,
            enum ValDeclaration::Mode mode,
            enum ValDeclaration::ObjClass cls,
            SubtypeIndication *subtypeIndic,
            Location loc
      );

      /** Create a list of ValDeclaration declarations.
          * The contents of the parameters are reused in the result, so
          * the caller mustn't free them.
          *
          * This version is for procedure declarations.
          *
          * @param ids list of Identifiers for each Variable. The list itself
          *            isn't reused anywhere, so caller can free it.
          * @param varInit optional initializer of variable.
          * @param mode access mode (in/out/inout)
          * @param cls object class that will determine if it's a 
          *          Signal, Variable or Constant.
          * @param subtypeIndic subtype indication of the element.
        * @param loc location in the source file.
          * @return list of ValDecls, caller must free it.
          */
      static std::list<ValDeclaration*>&
      makeProcInterfaceDecls(
            std::list<std::string*> &ids,
            Expression *varInit,
            enum ValDeclaration::Mode mode,
            enum ValDeclaration::ObjClass cls,
            SubtypeIndication *subtypeIndic,
            Location loc
      );

      /** merge two context items.
          * The order will be all items from first context item first, then
          * items from second context item.
          *
          * @param first first context item. Parameter will be reused for
          *        result, caller must free it.
          * @param second second context item. Parameter will get freed
          *        during call.
          * @result merged context item.
          */
      static struct ContextItemS&
      mergeContextItems(
            struct ContextItemS &first, 
            struct ContextItemS &second
      );

      /** correctly create a CondalSigAssign during parsing.
       *  @param trg target value. Reused in result.
       *  @param conds top IfStat or SigAssignStat. Reused in result.
       *  @param loc location of assignment token.
       *  @return created CondalSigAssign. Allocated node, caller should
       *          free it once done with it.
       */
      static CondalSigAssign&
      makeCondalSigAssign(Name &trg, SeqStat &conds, Location loc);

      /** create a list of record type elements.
          * @param idlist list of identifiers.
          * @param subtype subtype indication of element.
          * @param loc location of the first elements (FIXME)
          * @return list of elements.
          */
      static std::list<RecordTypeElement*>&
      makeRecordTypeElements(
            std::list<std::string*> &idlist, 
            SubtypeIndication &subtype,
            Location loc);

      /** create the corresponding Aggregate from the give String Literal.
       *  @param stringLit string literal.
       *  @param loc Location of the string literal.
       *  @param nl NameLookup instance.
       *  @return the corresponding Aggregate or NULL if the string is a
       *          null-string.
       */
      static Aggregate* 
      makeAggregateFromString(
            const std::string &stringLit, 
            Location loc,
            const NameLookup &nl
      );

      //! register all enumeration elements from an enumeration type
      /** @param etype EnumerationType for which all EnumerationElements
       *         should get registered in the SymbolTable
       *  @param symbolTable SymbolTable instance.
       *  @param typeSym Symbol of the EnumerationType.
       */
      static void
      registerEnumElems(
            const EnumerationType *etype,
            SymbolTable &symbolTable,
            Symbol *typeSym
      );

      /** create an AttributeSpecification for the attribute denoted by
       *  designator with initializer init and attribute the named 
       *  entities in entityList that fit the entity class classFilter 
       *  with it.
       *  @param designator referred to attribute
       *  @param entityList list of named entities to attribute
       *  @param classFilter entity class
       *  @param init initializer for the specification.
       *  @param symTab SymbolTable instance.
       */
      static AttributeSpecification *
      handleAttributeSpecs(
            SimpleName *designator,
            std::list<SimpleName*> entityList,
            enum entityClassE classFilter,
            Expression *init,
            const SymbolTable &symTab);

      /** safe upward cast a list of derived class U to a list of parent
          * class T.
          * @param l pointer to list of derived class pointers. Memory will
          *        be reused as base class list.
          * @return list of base class pointers, type T
          *
          * Hint: if this function won't compile anywhere, just copy the
          * elements from the list, as this will always work (but is 
          * slower).
          */
      template <typename T, typename U>
      static std::list<T>*
      listCast(std::list<U> *l);

      /** combine two lists of same type.
          * @param dest list where elements are getting push_back'ed.
          * @param source list which contains elements to add.
          */
      template <typename T>
      static void
      listCombine(std::list<T> *dest, std::list<T> *source);

private:
      
      /** is the symbol sym of entityClass ec?
       *  @param sym Symbol to check.
       *  @param ec entity class
       *  @return true if sym is of class ec.
       */
      static bool
      isOfEntityClass(const Symbol &sym, enum entityClassE ec);
      
      //! very small visitor for attributing CondalSigAssign stats.
      /** This visitor will set the target for each SigAssignStat
       *  that's part of a CondalSigAssign.
       */
00459       class CondalSigAssignSetter : public TopDownVisitor {
      public:
            //! c'tor
            /** @param trg target that will get passed downwards.
             */
00464             CondalSigAssignSetter(Name &trg) : target(trg) {}
            
            /** set target to SigAssignStat nodes.
             *  @param node SigAssignStat that gets visited.
             */
            virtual void visit(SigAssignStat &node);
            
      private:
            /** target that will be passed downwards. */
00473             Name &target;
      };

};

}; /* namespace ast */

/* template definitions */
#include "frontend/ast/NodeFactory.tpp"

#endif /* __NODE_FACTORY_HPP_INCLUDED */

Generated by  Doxygen 1.6.0   Back to index