--- /dev/null
+
+
+SUBDIRS(asn1)
--- /dev/null
+#include <iostream>
+#include "ADT/asn1/Asn1Boolean.h"
+
+//
+Asn1Boolean::Asn1Boolean()
+{
+}
+//
+Asn1Boolean::Asn1Boolean(const Asn1Boolean &o)
+{
+}
+
+//
+Asn1Boolean::~Asn1Boolean()
+{
+}
--- /dev/null
+#include <iostream>
+#include "ADT/asn1/Asn1Choice.h"
+
+// default Contructor
+Asn1Choice::Asn1Choice()
+{
+}
+
+//
+Asn1Choice::Asn1Choice(const Asn1Choice &o)
+{
+}
+
+// default Desctructor
+Asn1Choice::~Asn1Choice()
+{
+}
--- /dev/null
+#include <iostream>
+#include "ADT/asn1/Asn1Class.h"
+
+// default Contructor
+Asn1Class::Asn1Class()
+{
+}
+
+//
+Asn1Class::Asn1Class(const Asn1Class &o)
+{
+}
+
+// default Desctructor
+Asn1Class::~Asn1Class()
+{
+}
--- /dev/null
+#include <iostream>
+
+#include "ADT/asn1/Asn1Decl.h"
+#include "ADT/asn1/Asn1Constraint.h"
+
+// default Contructor
+Asn1Constraint::Asn1Constraint()
+{
+}
+
+//
+Asn1Constraint::Asn1Constraint(const Asn1Constraint &o)
+{
+}
+
+// default Desctructor
+Asn1Constraint::~Asn1Constraint()
+{
+}
--- /dev/null
+#include <iostream>
+#include "ADT/asn1/Asn1Decl.h"
+#include "ADT/asn1/Asn1Context.h"
+
+// default Contructor
+Asn1Context::Asn1Context()
+{
+}
+
+//
+Asn1Context::Asn1Context(const Asn1Context &o)
+{
+}
+
+// default Desctructor
+Asn1Context::~Asn1Context()
+{
+}
--- /dev/null
+#include <iostream>
+#include "ADT/asn1/Asn1Decl.h"
+
+// default Contructor
+Asn1Decl::Asn1Decl()
+{
+}
+
+//
+Asn1Decl::Asn1Decl(const Asn1Decl &o)
+{
+}
+
+// default Desctructor
+Asn1Decl::~Asn1Decl()
+{
+}
--- /dev/null
+#include <iostream>
+#include "ADT/asn1/Asn1Field.h"
+
+// default Contructor
+Asn1Field::Asn1Field()
+{
+}
+
+//
+Asn1Field::Asn1Field(const Asn1Field &o)
+{
+}
+
+// default Desctructor
+Asn1Field::~Asn1Field()
+{
+}
--- /dev/null
+#include <iostream>
+#include "ADT/asn1/Asn1Integer.h"
+
+// default Contructor
+Asn1Integer::Asn1Integer()
+{
+}
+
+//
+Asn1Integer::Asn1Integer(const Asn1Integer &o)
+{
+}
+
+// default Desctructor
+Asn1Integer::~Asn1Integer()
+{
+}
--- /dev/null
+#include <iostream>
+#include "ADT/asn1/Asn1Module.h"
+
+// default Contructor
+Asn1Module::Asn1Module()
+{
+}
+
+//
+Asn1Module::Asn1Module(const Asn1Module &o)
+{
+}
+
+// default Desctructor
+Asn1Module::~Asn1Module()
+{
+}
--- /dev/null
+#include <iostream>
+#include "ADT/asn1/Asn1Object.h"
+
+// default Contructor
+Asn1Object::Asn1Object()
+{
+}
+
+//
+Asn1Object::Asn1Object(const Asn1Object &o)
+{
+}
+
+// default Desctructor
+Asn1Object::~Asn1Object()
+{
+}
--- /dev/null
+#include <iostream>
+#include "ADT/asn1/Asn1Type.h"
+#include "ADT/asn1/Asn1Oid.h"
+
+// default Contructor
+Asn1ObjectIdentifier::Asn1ObjectIdentifier()
+{
+}
+
+//
+Asn1ObjectIdentifier::Asn1ObjectIdentifier(const Asn1ObjectIdentifier &o)
+{
+}
+
+// default Desctructor
+Asn1ObjectIdentifier::~Asn1ObjectIdentifier()
+{
+}
--- /dev/null
+#include <iostream>
+#include "ADT/asn1/Asn1Sequence.h"
+
+// default Contructor
+Asn1Sequence::Asn1Sequence()
+{
+}
+
+//
+Asn1Sequence::Asn1Sequence(const Asn1Sequence &o)
+{
+}
+
+// default Desctructor
+Asn1Sequence::~Asn1Sequence()
+{
+}
--- /dev/null
+#include <iostream>
+#include "ADT/asn1/Asn1Set.h"
+
+// default Contructor
+Asn1Set::Asn1Set()
+{
+}
+
+//
+Asn1Set::Asn1Set(const Asn1Set &o)
+{
+}
+
+// default Desctructor
+Asn1Set::~Asn1Set()
+{
+}
--- /dev/null
+#include <iostream>
+#include "ADT/asn1/Asn1Type.h"
+
+// default Contructor
+Asn1Type::Asn1Type()
+{
+}
+
+//
+Asn1Type::Asn1Type(const Asn1Type &o)
+{
+}
+
+// default Desctructor
+Asn1Type::~Asn1Type()
+{
+}
--- /dev/null
+PROJECT(AdtAsn1)
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../../include/)
+ADD_LIBRARY(commonAdtAsn1
+ Asn1Boolean.cpp
+ Asn1Choice.cpp
+ Asn1Class.cpp
+ Asn1Constraint.cpp
+ Asn1Context.cpp
+ Asn1Decl.cpp
+ Asn1Field.cpp
+ Asn1Integer.cpp
+ Asn1Module.cpp
+ Asn1Object.cpp
+ Asn1Oid.cpp
+ Asn1Sequence.cpp
+ Asn1Set.cpp
+ Asn1Type.cpp
+ )
--- /dev/null
+#include <iostream>
+#include <vector>
+#include <map>
+
+
+#include "AST/Stmt.h"
+#include "AST/Expr.h"
+#include "AST/Decl.h"
+
+#include "AST/DeclContext.h"
+
+#include <AST/Type.h>
+#include <AST/ASTContext.h>
+
+
+namespace AST {
+
+/**
+ * Default Constructor
+ */
+ASTContext::ASTContext()
+ : m_Types()
+ // BuiltinTypes ...
+#define BUILTIN_TYPE(Id,Cls) , Cls(BuiltinType::Id)
+#include "AST/BuiltinTypes.h.def"
+{
+ m_TranslationUnitDecl = AST::TranslationUnitDecl::Create(*this,NULL,"rootDecl");
+}
+
+/**
+ * Default Destructor
+ */
+ASTContext::~ASTContext()
+{
+}
+/**
+ *
+ */
+Type &
+ASTContext::getValueTypeType(const ValueTypeDecl *D)
+{
+ // Check If Decl already has TypeForDecl
+ if (D->getTypeForDecl())
+ return *D->getTypeForDecl();
+ // Check If Decl has Previous Decl and if Previous has TypeForDecl
+ TypelistConstIterator it = m_Types.find(D->getName()) ;
+ if ( it != m_Types.end() )
+ {
+ ValueType *nT = reinterpret_cast<AST::ValueType *>((*it).second);
+ const_cast<ValueTypeDecl *>( D )->setTypeForDecl(nT);
+ return *nT;
+ }
+ // Create new Type and push it in the map
+ ValueType *nT = new ValueType(D);
+ m_Types[D->getName()] = nT;
+ const_cast<ValueTypeDecl *>( D )->setTypeForDecl(nT);
+ return *nT;
+}
+
+/**
+ *
+ */
+Type &
+ASTContext::getTypedefType(const TypedefDecl *D)
+{
+ // Check If Decl already has TypeForDecl
+ if (D->getTypeForDecl())
+ return *D->getTypeForDecl();
+ // Check If Decl has Previous Decl and if Previous has TypeForDecl
+ // Create new Type and push it in the map
+ TypedefType *nT = new TypedefType(D);
+
+ m_Types[D->getName()] = nT;
+ const_cast<TypedefDecl *>( D )->setTypeForDecl(nT);
+ return *nT;
+}
+
+
+
+/**
+ *
+ */
+Type &
+ASTContext::getRecordType(const RecordDecl *D)
+{
+ // Check If Decl already has TypeForDecl
+ if (D->getTypeForDecl())
+ return *D->getTypeForDecl();
+ // Check If Decl has Previous Decl and if Previous has TypeForDecl
+ TypelistConstIterator it = m_Types.find(D->getName()) ;
+ if ( it != m_Types.end() )
+ {
+ RecordType *nT = reinterpret_cast<AST::RecordType *>((*it).second);
+ const_cast<RecordDecl *>( D )->setTypeForDecl(nT);
+ return *nT;
+ }
+ // Create new Type and push it in the map
+ std::cerr<<"ASTContext::getRecordType: TODO "<<D->getName()<<std::endl;
+ RecordType *nT = new RecordType(D);
+ m_Types[D->getName()] = nT;
+ const_cast<RecordDecl *>( D )->setTypeForDecl(nT);
+ return *nT;
+}
+
+Type &
+ASTContext::getConstantArrayType(Type *EltTy,long length)
+{
+ std::cerr<<"ASTContext::getConstantArrayType: TODO "<<length<<std::endl;
+ ConstantArrayType *cat = new ConstantArrayType(EltTy,length);
+ //Todo implement
+ return CharTy;
+}
+
+Type &
+ASTContext::getFunctionType(Type *RetTy,std::vector<Type *>Parma,const std::string &fn)
+{
+ return CharTy;
+}
+
+Type &ASTContext::getTypeDeclType(TypeDecl *Decl,TypeDecl *prevDecl )
+{
+ if (Decl->m_TypeForDecl)
+ return *Decl->m_TypeForDecl;
+ //
+ if (prevDecl && prevDecl->m_TypeForDecl)
+ {
+ Decl->m_TypeForDecl = prevDecl->m_TypeForDecl;
+ return *prevDecl->m_TypeForDecl;
+ }
+ std::cout<<"ASTContext::getTypeDeclType Todo"<<std::endl;
+ return CharTy;
+}
+
+/**
+ * Initialize all builtin types.
+ */
+void InitBuiltinTypes()
+{
+}
+
+
+}
--- /dev/null
+PROJECT(AST)
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../include/)
+ADD_LIBRARY(commonAST
+ DeclContext.cpp
+ DeclTypeDecl.cpp
+ Expr.cpp
+ ExprCallExpr.cpp
+ ExprDeclRefExpr.cpp
+ StmtIfStmt.cpp
+ StmtWhileStmt.cpp
+ StmtAsmStmt.cpp
+ StmtOutputStmt.cpp
+ ASTContext.cpp
+ Type.cpp
+ )
--- /dev/null
+#include <iostream>
+#include <vector>
+#include <map>
+
+
+#include "AST/Stmt.h"
+#include "AST/Expr.h"
+#include "AST/Decl.h"
+
+#include "AST/DeclContext.h"
+
+#include <AST/Type.h>
+#include <AST/ASTContext.h>
+
+namespace AST
+{
+
+/**
+ * Find the Translation unit for the given Declaration
+ */
+TranslationUnitDecl *
+Decl::getTranslationUnitDecl(TypeClass _tc)
+{
+ if (TranslationUnitDecl *TUD = dynamic_cast<TranslationUnitDecl *>(this))
+ {
+ return TUD;
+ }
+ /* If not, get The DeclContext and check parents*/
+ DeclContext *DC = getDeclContext();
+
+ const DeclContext *DC = getDeclContext() const;
+ return NULL;
+}
+
+/**
+ * ??
+ */
+DeclContext *Decl::getDeclContext()
+{
+}
+
+
+void EventDecl::Signature(SignatureNodeID &id)
+{
+ id+=getName();
+ // Add Parameters as well
+}
+
+void FunctionDecl::Signature(SignatureNodeID &id)
+{
+ id+=getName();
+ // Add Parameters as well
+}
+
+void RecordDecl::Signature(SignatureNodeID &id)
+{
+ id+=getName();
+ // Add Parameters as well
+}
+
+
+field_iterator RecordDecl::field_begin() const
+{
+ return field_iterator(decl_iterator(m_FirstDecl));
+}
+
+field_iterator RecordDecl::field_begin() const
+{
+ return field_iterator(decl_iterator(m_LastDecl));
+}
+
+}
--- /dev/null
+#include <iostream>
+#include <vector>
+#include <map>
+
+
+#include "AST/Stmt.h"
+#include "AST/Expr.h"
+#include "AST/Decl.h"
+
+#include "AST/DeclContext.h"
+
+namespace AST {
+
+ void DeclContext::addHiddenDecl(Decl *d)
+ {
+ // std::cout<<"DeclContext::addHiddenDecl Ctx="<<(long)this<<" decl kind "<<d->getKind()<<std::endl;
+ if (m_FirstDecl )
+ {
+ m_LastDecl->setNextDeclInContext(d);
+ m_LastDecl = d;
+ } else {
+ m_FirstDecl = m_LastDecl = d;
+ }
+
+ };
+
+ /**
+ *
+ *
+ */
+ DeclContext::lookup_result DeclContext::lookup(const std::string &_n)
+ {
+ lookup_result result;
+ Decl *l = m_FirstDecl;
+ DeclContext *current = this;
+ bool found = false;
+ while (! found && (l != NULL))
+ {
+ NamedDecl *c = dynamic_cast<NamedDecl *>(l);
+ if ( (c) && ! _n.compare(c->getName() ) ) {
+ found = true;
+ result.push_back(c);
+ }
+ // Check if it's a Transition
+ EventDecl *evt = dynamic_cast<EventDecl *>(l);
+ if (current->isTransition() && evt )
+ {
+ // Loop over Event and check arguments
+ //std::cout<<"lookup in event"<<std::endl;
+ if ( evt->param_size() > 0 )
+ {
+ // std::cout<<"Event "<<evt->getName()<<" Has parameters"<<std::endl;
+ for (AST::FunctionDecl::const_param_iterator pit = evt->param_begin()
+ ; pit != evt->param_end()
+ ; ++pit)
+ {
+ //std::cout<<"Event Check:"<<(*pit)->getName()<<" "<<std::endl;
+ if (! _n.compare((*pit)->getName()))
+ {
+ result.push_back(*pit);
+ found = true;
+ }
+ }
+ }
+ }
+
+ // Move up until Translation Unit
+ l = l->getNextDeclInContext() ;
+ if ( l == NULL ) {
+#if 0
+ std::cout<<"DeclContext::lookup go to parent Current T="<<current->isTransition();
+ std::cout<<" S="<<current->isState()<<std::endl;
+#endif
+ DeclContext *p = current->getParent();
+ while ( (l == NULL) && p &&!p->isTranslationUnit() )
+ {
+ current = p;
+ l = p->m_FirstDecl;
+#if 0
+ std::cout<<"DeclContext::lookup "<<l<<" T="<<p->isTransition();
+ std::cout<<" F="<<p->isFunction();
+ std::cout<<" TU="<<p->isTranslationUnit();
+ std::cout<<" AT="<<p->isAutomaton();
+ std::cout<<" S="<<p->isState()<<std::endl;
+#endif
+ p = p->getParent();
+ }
+ }
+ } ;
+ return result;
+ }
+ ///
+ DeclContext *DeclContext::getParent()
+ {
+ if (DeclContext *DC = dynamic_cast<DeclBase *>(this)->getDeclContext())
+ return DC;
+ return NULL;
+ }
+ ///
+ const DeclContext *DeclContext::getParent() const
+ {
+ return const_cast<DeclContext *>(this)->getParent();
+ }
+ ///
+ bool DeclContext::isTranslationUnit() const
+ {
+ DeclContext *_this = const_cast<DeclContext *>(this);
+ return dynamic_cast<AST::TranslationUnitDecl *>(_this) != NULL;
+ }
+ ///
+ bool DeclContext::isRecord() const
+ {
+ DeclContext *_this = const_cast<DeclContext *>(this);
+ return dynamic_cast<AST::RecordDecl *>(_this) != NULL;
+ }
+ ///
+ bool DeclContext::isFunction() const
+ {
+ DeclContext *_this = const_cast<DeclContext *>(this);
+ return dynamic_cast<AST::FunctionDecl *>(_this) != NULL;
+ }
+ ///
+ bool DeclContext::isState() const
+ {
+ DeclContext *_this = const_cast<DeclContext *>(this);
+ return dynamic_cast<AST::StateDecl *>(_this) != NULL;
+ }
+ ///
+ bool DeclContext::isTransition() const
+ {
+ DeclContext *_this = const_cast<DeclContext *>(this);
+ return dynamic_cast<AST::TransitionDecl *>(_this) != NULL;
+ }
+ ///
+ bool DeclContext::isAutomaton() const
+ {
+ DeclContext *_this = const_cast<DeclContext *>(this);
+ return dynamic_cast<AST::AutomatonDecl *>(_this) != NULL;
+ }
+ ///
+ bool DeclContext::isBlock() const
+ {
+ DeclContext *_this = const_cast<DeclContext *>(this);
+ return dynamic_cast<AST::BlockDecl *>(_this) != NULL;
+ }
+ ///
+ bool DeclContext::isPackage() const
+ {
+ DeclContext *_this = const_cast<DeclContext *>(this);
+ return dynamic_cast<AST::PackageDecl *>(_this) != NULL;
+ }
+}
--- /dev/null
+#include <iostream>
+#include <vector>
+#include <map>
+
+
+#include "AST/Stmt.h"
+#include "AST/Expr.h"
+#include "AST/Decl.h"
+#include "AST/DeclTypeDecl.h"
+
+#include "AST/DeclContext.h"
+
+namespace AST {
+
+/**
+ *
+ */
+bool
+ValueTypeDecl::isStruct() const
+{
+ if (RecordType *r = dynamic_cast<RecordType *>(m_Specialization))
+ {
+ return r->getDecl()->isStruct();
+ }
+ return false;
+}
+/**
+ *
+ */
+bool
+ValueTypeDecl::isUnion() const
+{
+ if (RecordType *r = dynamic_cast<RecordType *>(m_Specialization))
+ {
+ return r->getDecl()->isUnion();
+ }
+ return false;
+}
+
+/**
+ *
+ */
+bool
+ValueTypeDecl::isEnum() const
+{
+ if (EnumType *r = dynamic_cast<EnumType *>(m_Specialization))
+ {
+ return true;
+ }
+ return false;
+}
+
+/**
+ *
+ */
+bool
+ValueTypeDecl::isArray() const
+{
+ if (ArrayType *r = dynamic_cast<ArrayType *>(m_Specialization))
+ {
+ return true;
+ }
+ return false;
+}
+
+
+}
--- /dev/null
+#include <iostream>
+#include <vector>
+#include <map>
+
+#include <string.h>
+
+#include "AST/Stmt.h"
+#include "AST/Expr.h"
+#include "AST/Decl.h"
+
+#include "AST/DeclContext.h"
+
+namespace AST {
+
+Expr *ExprIterator::operator [](size_t i)
+{
+ return static_cast< Expr *>(I[i]);
+}
+
+Expr *ExprIterator::operator *() const
+{
+ return static_cast< Expr *>(*I);
+}
+
+Expr *ExprIterator::operator ->() const
+{
+ return static_cast< Expr *>(*I);
+}
+
+bool
+Expr::evalute(EvalResult &result)
+{
+ return true;
+}
+
+ParenListExpr::ParenListExpr() : Expr(ParenListExprClass) , m_NbExprs(0) {
+ memset(m_Stmts,0x00, ParenListExpr::MAX);
+}
+
+Stmt::range_iterator
+ParenListExpr::children() {
+ Stmt::range_iterator r(&m_Stmts[0],&m_Stmts[m_NbExprs]);
+ return r;
+}
+/**
+ * MemberExpr implementation methods
+ */
+MemberExpr::MemberExpr(Expr *base,ValueDecl *mem,Type *Ty)
+ : Expr(MemberExprClass,Ty) , m_Base(base), m_Member(mem)
+{
+}
+
+/* To be improved */
+MemberExpr *
+MemberExpr::Create(ASTContext &AC,Expr *base,ValueDecl *_member,Type *Ty)
+{
+ return new MemberExpr(base,_member,Ty);
+}
+
+
+#if 0
+Expr* getBase() const
+{
+ return reinterpret_cast<Expr *>(m_Base);
+}
+
+ValueDecl *getMember() const
+{
+ return reinterpret_cast<Expr *>(m_Member);
+}
+#endif
+
+ArraySubscriptExpr::ArraySubscriptExpr(Expr *base,Expr *idx,Type *Ty)
+ : m_Base(base),m_Index(idx) , Expr(ArraySubscriptExprClass,Ty)
+{
+}
+
+
+ArraySubscriptExpr *
+ArraySubscriptExpr::Create(ASTContext &AC,Expr *base,Expr *_idx,Type *Ty)
+{
+ return new ArraySubscriptExpr(base,_idx,Ty);
+}
+
+
+
+#if 0
+enum BinaryOperatorKind {
+ // Operators are listed in ORDER of precedence
+ BO_Mul, BO_Div, BO_Rem, // Multiplicative operators
+ BO_Add, BO_Sub, // Additive operators
+ BO_Shl, BO_Shr, // Bitwise shift operators
+ BO_LT, BO_GT, BO_LE, BO_GE, // Relation operators
+ BO_EQ, BO_NE, // Equal Operators
+ BO_And, // Bitwise And, Xor, Or
+ BO_Xor,
+ BO_Or,
+ BO_LAnd, // Logical And / Or
+ BO_LOr,
+ BO_Assign // Assignement Operators
+};
+
+enum UnaryOperatorKind {
+ UO_PostInc, UO_PostDec, // postfix increment and decrement
+ UO_PreInc, UO_PreDec, // prefix increment and decrement
+ UO_Plus, UO_Minus, // Unary arithmetic
+ UO_Not, UO_LNot, UO_Test //
+};
+
+#endif
+const char *
+BinaryOperator::getOpcodeStr( ) const
+{
+ switch (getOpcode())
+ {
+ case BO_Mul: return "*";
+ case BO_Div: return "/";
+ case BO_Rem: return "";
+ case BO_Add: return "+";
+ case BO_Sub: return "-";
+ case BO_Shl: return ">>";
+ case BO_Shr: return "<<";
+ case BO_LT: return "<";
+ case BO_GT: return ">";
+ case BO_LE: return "<=";
+ case BO_GE: return ">=";
+ case BO_EQ: return "=";
+ case BO_NE: return "/=";
+ case BO_And: return "and";
+ case BO_Xor: return "";
+ case BO_Or: return "";
+ case BO_LAnd: return "";
+ case BO_LOr: return "";
+ case BO_Assign: return ":="; // Assignement Operators
+ default: return "unknown";
+ }
+}
+
+}
--- /dev/null
+
+#include <iostream>
+#include <vector>
+#include <map>
+
+
+#include "AST/Stmt.h"
+#include "AST/Expr.h"
+#include "AST/Decl.h"
+
+#include "AST/DeclContext.h"
+
+namespace AST {
+
+ CallExpr::CallExpr(const DeclContext *ctx,Expr *fn,std::vector<AST::Expr*> args) : Expr(CallExprClass) {
+ m_NumArgs = args.size();
+ int i = 1;
+ for( std::vector<AST::Expr *>::iterator it = args.begin() ; it != args.end() ; ++it) {
+ m_Args[i++] = *it;
+ }
+ m_Args[FN] = fn;
+ }
+
+FunctionDecl *
+CallExpr::getCalleeDecl() const {
+ if ( DeclRefExpr *r = dynamic_cast<DeclRefExpr *>(m_Args[FN]) ) {
+ return dynamic_cast<AST::FunctionDecl *>(r->getDecl());
+ } else return NULL;
+}
+
+
+}
--- /dev/null
+#include <iostream>
+#include <vector>
+#include <map>
+
+
+#include "AST/Stmt.h"
+#include "AST/Expr.h"
+#include "AST/Decl.h"
+
+#include "AST/DeclContext.h"
+
+namespace AST {
+
+Decl *
+DeclRefExpr::getDecl() const {
+ return dynamic_cast<AST::Decl *>(m_value);
+}
+
+
+bool DeclRefExpr::isRefFunctionDecl() const
+{ return dynamic_cast<FunctionDecl *>(getDecl()) != NULL ; }
+
+bool DeclRefExpr::isRefVarDecl() const
+{ return dynamic_cast<VarDecl *>(getDecl()) != NULL ; }
+
+bool DeclRefExpr::isRefParmVarDecl() const
+{ return dynamic_cast<ParmVarDecl *>(getDecl()) != NULL ; }
+
+
+}
--- /dev/null
+#include <iostream>
+#include <string.h>
+#include <string>
+#include <vector>
+#include <map>
+
+
+#include "AST/Stmt.h"
+#include "AST/Expr.h"
+#include "AST/Decl.h"
+
+#include "AST/DeclContext.h"
+#include "AST/StmtIterator.h"
+
+
+namespace AST {
+
+
+ AST::StringLiteral *AsmStmt::getLiteral() const {
+ return dynamic_cast<StringLiteral *>(m_Stmts[LIT]);
+ };
+
+ void AsmStmt::setLiteral(AST::Expr *E) {
+ m_Stmts[LIT] = E;
+ }
+
+ void AsmStmt::setExpr(AST::Expr *E) {
+ m_Stmts[EXPR] = E;
+ }
+
+ AsmStmt::AsmStmt(DeclContext *DC,StmtClass KD,const std::string &op ) : Stmt(KD) {
+ memset(m_Stmts,0x00,END);
+ // m_Stmts[LIT] = cond;
+ }
+
+ VarDecl *AsmStmt::getVarDecl() const
+ {
+ AST::DeclRefExpr *ref = dynamic_cast<AST::DeclRefExpr *>(m_Stmts[LIT]);
+ if (ref)
+ {
+ return dynamic_cast<AST::VarDecl *>(ref->getDecl());
+ } else
+ return NULL;
+ }
+
+ TimerDecl *AsmStmt::getTimerDecl() const
+ {
+ AST::DeclRefExpr *ref = dynamic_cast<AST::DeclRefExpr *>(m_Stmts[LIT]);
+ if (ref)
+ {
+ return dynamic_cast<AST::TimerDecl *>(ref->getDecl());
+ } else
+ return NULL;
+ }
+
+ /// For SET and RESET Statements
+ bool AsmStmt::isArgVariable() const
+ {
+ AST::DeclRefExpr *ref = dynamic_cast<AST::DeclRefExpr *>(m_Stmts[LIT]);
+ if (ref)
+ {
+ return dynamic_cast<AST::VarDecl *>(ref->getDecl()) != NULL;
+ } else
+ return false;
+ }
+
+ bool AsmStmt::isArgTimer() const
+ {
+ AST::DeclRefExpr *ref = dynamic_cast<AST::DeclRefExpr *>(m_Stmts[LIT]);
+ if (ref)
+ {
+ return dynamic_cast<AST::TimerDecl *>(ref->getDecl()) != NULL;
+ } else
+ return false;
+ }
+
+
+ /**
+ * LDS ASM
+ */
+ LdsAsmStmt::LdsAsmStmt(DeclContext *DC,const std::string &op ) : AsmStmt(DC,Stmt::LdsAsmStmtClass,op) {
+
+#define SETOP(x) if (! op.compare( #x ) ) { m_Opcode = x ;}
+ if (! op.compare("AEL_RETURN") ) { m_Opcode = AEL_RETURN ;}
+ SETOP(AEL_SET)
+ SETOP(AEL_NOP)
+ SETOP(AEL_LOOP_MSG)
+ SETOP(AEL_SET)
+ SETOP(AEL_RESET)
+ SETOP(AEL_JSR_IND)
+ SETOP(AEL_RTS)
+ }
+
+};
+
--- /dev/null
+#include <iostream>
+#include <string.h>
+#include <string>
+#include <vector>
+#include <map>
+
+
+#include "AST/Stmt.h"
+#include "AST/Expr.h"
+#include "AST/Decl.h"
+
+#include "AST/DeclContext.h"
+#include "AST/StmtIterator.h"
+
+
+namespace AST {
+
+ IfStmt::IfStmt(DeclContext *DC,Expr *cond,Stmt *_then,Stmt *_else ) : Stmt(Stmt::IfStmtClass) {
+ memset(m_Stmts,0x00,END);
+ m_Stmts[COND] = cond;
+ m_Stmts[THEN] = _then;
+ m_Stmts[ELSE] = _else;
+ }
+
+ AST::Expr *IfStmt::getCond() const {
+ return dynamic_cast<Expr *>(m_Stmts[COND]);
+ };
+
+ Stmt::range_iterator IfStmt::children() {
+ return range_iterator(&m_Stmts[0],&m_Stmts[0]+3);
+ }
+}
--- /dev/null
+#include <iostream>
+#include <string.h>
+#include <string>
+#include <vector>
+#include <map>
+
+
+#include "AST/Stmt.h"
+#include "AST/Expr.h"
+#include "AST/Decl.h"
+
+#include "AST/DeclContext.h"
+#include "AST/StmtIterator.h"
+
+
+namespace AST {
+
+
+ OutputStmt::OutputStmt(DeclContext *DC,const std::string &op,DeclRefExpr *sig,Expr *dest)
+ : m_NumArgs(0) , Stmt(Stmt::OutputStmtClass)
+ {
+ memset(m_Stmts,0x00,END);
+ m_Stmts[SIG] = sig;
+ }
+
+ EventDecl *OutputStmt::getEventDecl() const
+ {
+
+ DeclRefExpr *dref = dynamic_cast<DeclRefExpr *>(m_Stmts[SIG]);
+ if (dref)
+ return dynamic_cast<EventDecl *>(dref->getDecl());
+ return NULL;
+ }
+
+ void OutputStmt::setDestination(Expr *dest)
+ {
+ m_Stmts[DEST] = dest;
+ }
+
+ void OutputStmt::setArgs(std::vector<AST::Expr *> &_args)
+ {
+ m_NumArgs = _args.size();
+ int i = 0;
+ for( std::vector<AST::Expr *>::iterator it = _args.begin() ; it != _args.end() ; ++it) {
+ m_Args[i++] = *it;
+ }
+ }
+ Expr *OutputStmt::getArg(unsigned i)
+ {
+ return static_cast<Expr *>(m_Args[i]);
+ }
+
+ const Expr *OutputStmt::getArg(unsigned i) const
+ {
+ return static_cast<Expr *>(m_Args[i]);
+ }
+
+};
+
+/*
+ * ex: set sw=2 et list:
+ */
--- /dev/null
+#include <iostream>
+#include <string.h>
+#include <string>
+#include <vector>
+#include <map>
+
+
+#include "AST/Stmt.h"
+#include "AST/Expr.h"
+#include "AST/Decl.h"
+
+#include "AST/DeclContext.h"
+#include "AST/StmtIterator.h"
+
+
+namespace AST {
+
+ WhileStmt::WhileStmt(DeclContext *DC,Expr *cond,Stmt *_body ) : Stmt(Stmt::WhileStmtClass) {
+ memset(m_Stmts,0x00,END);
+ m_Stmts[COND] = cond;
+ m_Stmts[BODY] = _body;
+ }
+
+ AST::Expr *WhileStmt::getCond() const {
+ return dynamic_cast<Expr *>(m_Stmts[COND]);
+ };
+
+
+/**
+ *
+ */
+ BreakStmt::BreakStmt(DeclContext *DC,Expr *cond) : m_Cond(NULL), Stmt(Stmt::BreakStmtClass)
+ {
+ m_Cond = cond;
+ };
+
+ Expr *BreakStmt::getCond()
+ { return dynamic_cast<AST::Expr *>(m_Cond); };
+
+
+
+
+}
--- /dev/null
+#include <iostream>
+#include <vector>
+#include <map>
+
+
+#include "AST/Stmt.h"
+#include "AST/Expr.h"
+#include "AST/Decl.h"
+
+#include "AST/DeclContext.h"
+
+#include <AST/Type.h>
+#include <AST/ASTContext.h>
+
+namespace AST
+{
+
+/**
+ *
+ */
+Type::Type(TypeClass _tc) : TC(_tc)
+{
+}
+
+const char *
+BuiltinType::getNameAsStr() const
+{
+ switch (m_Kind)
+ {
+#define BUILTIN_TYPE(Id,Cls) case Id: return #Id;
+#include "AST/BuiltinTypes.h.def"
+ default: return "Uknown";
+ };
+}
+
+
+}
--- /dev/null
+
+OPTION(CG_DEBUG_IF "Debug Code Gen If" OFF)
+OPTION(CG_DEBUG_EXPR "Debug Code Gen Expr" OFF)
+
+IF(CG_DEBUG_IF)
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DCG_DEBUG_IF")
+ENDIF(CG_DEBUG_IF)
+SUBDIRS(AST CodeGen IR UnitTests ADT LDSExecutionEngine LDSBytecode)
--- /dev/null
+#include <vector>
+#include <stack>
+#include <iostream>
+#include <sstream>
+#include <algorithm>
+#include <map>
+#include "AST/Stmt.h"
+#include "AST/Expr.h"
+#include "AST/Decl.h"
+
+#include "AST/DeclContext.h"
+
+#include "AST/StmtVisitor.h"
+
+#include <aeb/dlilist.h>
+#include <aeb/dlilist_node.h>
+#include <IR/LdsInstruction.h>
+#include <IR/BasicBlock.h>
+#include <IR/Behavior.h>
+#include <IR/Transition.h>
+#include <IR/Function.h>
+#include <IR/Argument.h>
+#include <IR/GlobalVariable.h>
+#include <IR/LdsBuilder.h>
+#include <CodeGen/CodeGenType.h>
+#include <CodeGen/CodeGenModule.h>
+#include <CodeGen/CodeGenFunction.h>
+#include <CodeGen/CGDebug.h>
+
+
+typedef aeb::lds::Value * RetValue;
+
+// Helper class to Emit Code for Scaler Expression
+//
+class ScalarExprEmitterHelper : public AST::StmtVisitor<ScalarExprEmitterHelper , RetValue> {
+ protected:
+ /**
+ * Try to keep track of temporarly Values used during evaluation or Visit
+ */
+ struct StackResult {
+ StackResult() : m_Index(0) , m_Value(NULL) {}
+ long m_Index;
+ aeb::lds::Value *m_Value;
+ };
+ protected:
+ aeb::lds::Builder &m_Builder;
+ aeb::lds::CodeGen::CodeGenFunction m_CGF;
+ aeb::lds::CodeGen::CodeGenModule &m_CGM;
+ std::stack<int> m_Stack;
+ long m_depth;
+ public:
+ ScalarExprEmitterHelper(aeb::lds::CodeGen::CodeGenFunction &cgf)
+ : m_CGF(cgf)
+ , m_Builder(cgf.getBuilder())
+ , m_depth(0)
+ , m_CGM(cgf.getModule())
+ {};
+
+ //delegate work to parent class !!!
+ // Emiters ....
+
+ // Start with Visitors,
+ //
+ RetValue Visit(AST::Expr *E) {
+ return AST::StmtVisitor<ScalarExprEmitterHelper ,RetValue>::Visit(E);
+ }
+ //
+ RetValue VisitBinaryOperator(AST::BinaryOperator *E) {
+ //CGDBG_EXPR("SEEH::VisitBinaryOperator TOBE Implemented")
+ std::cout<<"SEEH::VisitBinaryOperator "<<E->getOpcode()<<" TOBE Implemented"<<std::endl;
+ return NULL;
+ }
+ //
+ RetValue VisitUnaryOperator(AST::UnaryOperator *E) {
+ switch (E->getOpcode()) {
+ case AST::UO_LNot :
+ std::cout<<"SEEH::VisitUnaryOperator "<<E->getOpcode()<<" TOBE Implemented"<<std::endl;
+ break;
+ case AST::UO_Test :
+ std::cout<<"SEEH::VisitUnaryOperator "<<E->getOpcode()<<" TOBE Implemented"<<std::endl;
+ break;
+ break;
+ default:
+ std::cout<<"SEEH::VisitUnaryOperator "<<E->getOpcode()<<" TOBE Implemented"<<std::endl;
+ }
+ return NULL;
+ }
+
+ //
+ RetValue VisitCallExpr(AST::CallExpr *E) {
+ m_CGF.EmitCallExpr(E);
+ return NULL;
+ }
+ //
+ RetValue VisitCreateExpr(AST::CreateExpr *E) {
+ //m_CGF.EmitCallExpr(E);
+ AST::StringLiteral *s = dynamic_cast<AST::StringLiteral *>(E->getAgent());
+ if (s)
+ {
+ std::cout<<"SEEH::VisitCreateExpr "<<s->getString()<<" TOBE Implemented"<<std::endl;
+ }else
+ {
+ std::cout<<"SEEH::VisitCreateExpr "<<" TOBE Implemented"<<std::endl;
+ }
+ return NULL;
+ }
+ //
+ RetValue VisitMemberExpr(AST::MemberExpr *E) {
+ aeb::lds::Value *base = Visit(E->getBase());
+ std::cout<<"SEEH::VisitMemberExpr "<<base->getName()<<" TOBE Implemented"<<std::endl;
+ return m_Builder.CreateExtractValue(base,2,"TODO");
+ }
+ //
+ RetValue VisitArraySubscriptExpr(AST::ArraySubscriptExpr *E) {
+ aeb::lds::Value *base = Visit(E->getBase());
+ std::cout<<"SEEH::VisitArraySubscriptExpr "<<base->getName()<<" TOBE Implemented"<<std::endl;
+ return m_Builder.CreateExtractValue(base,2,"TODO");
+ }
+
+ //
+ RetValue VisitIntegerLiteral(AST::IntegerLiteral *E) {
+ CGDBG_EXPR_ARGS("SEEH::VisitIntegerLiteral %s ",E->get_value());
+ // Should be CreateLoadConstInt
+ return m_Builder.CreateTest(E->get_value());
+ }
+ //
+ RetValue VisitDeclRefExpr(AST::DeclRefExpr *E) {
+ if ( E->isRefFunctionDecl())
+ {
+ CGDBG_EXPR("SEEH::VisitDeclRefExpr Fct ");
+ return m_Builder.CreateTest("FLAG_TMP_1");
+ } else if (E->isRefParmVarDecl())
+ {
+ int Count = 0;
+ aeb::lds::Function *f = m_CGF.getCurrentFunction();
+ AST::ParmVarDecl* var = dynamic_cast<AST::ParmVarDecl *>(E->getDecl());
+ CGDBG_EXPR_ARGS("SEEH::VisitDeclRefExpr ParmVar %s",dynamic_cast<AST::NamedDecl *>(E->getDecl())->getName());
+ for (aeb::lds::Function::ArgumentIterator ait = f->arg_begin();
+ ait != f->arg_end()
+ ; ++ait)
+ {
+ Count++;
+ // std::cout<<"Compare <"<<ait->getName()<<">"<<std::endl;
+ if (! (ait)->getName().compare(var->getName()))
+ {
+ CGDBG_EXPR_ARGS("SEEH: Found Argument ",var->getName());
+ return m_Builder.CreateLoad(ait);
+ break;
+ }
+ }
+ return m_Builder.CreateTest("FLAG_TMP_1");
+ } else if (E->isRefVarDecl())
+ {
+ AST::VarDecl* var = dynamic_cast<AST::VarDecl *>(E->getDecl());
+ CGDBG_EXPR_ARGS("SEEH::VisitDeclRefExpr Var %s",dynamic_cast<AST::NamedDecl *>(E->getDecl())->getName());
+ aeb::lds::GlobalVariable *lv = m_CGF.getModule().GetGlobalVariable(var);
+ return m_Builder.CreateLoad(lv);
+ } else {
+ // Unknown ref for now should Stop
+ std::cout<<"SEEH::VisitDeclRefExpr Unknown "<<std::endl;
+ return m_Builder.CreateTest("FLAG_TMP_1");
+ }
+ // Should be CreateLoadVar();
+ //return m_Builder.CreateTest(dynamic_cast<AST::NamedDecl *>(E->getDecl())->getName());
+ }
+
+ //
+ RetValue VisitStringLiteral(AST::StringLiteral *E) {
+ std::cout<<"SEEH::VisitStringLiteral ERROR CreateCall Not NICE nor good but that's how it is "<<E->getString()<<std::endl;
+ return m_Builder.CreateCall(E->getString());
+ }
+
+ // Unary
+ RetValue VisitUnaryNot(AST::UnaryOperator *E) {
+ // std::cout<<"VisitNot TO BE COMPLETED"<<std::endl;
+ RetValue r = Visit(E->getSubExpr());
+ return m_Builder.CreateNot(NULL);
+ }
+ RetValue VisitUnaryLNot(AST::UnaryOperator *E) {
+ // std::cout<<"VisitLNot TO BE COMPLETED "<<std::endl;
+ Visit(E->getSubExpr());
+ return m_Builder.CreateNot(NULL);
+ }
+
+ RetValue VisitUnaryTest(AST::UnaryOperator *E) {
+ // std::cout<<"VisitTest TO BE COMPLETED "<<std::endl;
+ AST::StringLiteral *l = dynamic_cast<AST::StringLiteral *>(E->getSubExpr());
+ AST::IntegerLiteral *i = dynamic_cast<AST::IntegerLiteral *>(E->getSubExpr());
+ AST::DeclRefExpr *ref = dynamic_cast<AST::DeclRefExpr *>(E->getSubExpr());
+ if (l)
+ {
+ std::cerr<<"SEEH::VisitUnaryTest Error, SubExpr is StringLiteral"<<std::endl;
+ return m_Builder.CreateTest(l->getString());
+ } else if (i)
+ {
+ std::cerr<<"SEEH::VisitUnaryTest Error, SubExpr is IntegerLiteral"<<std::endl;
+ return m_Builder.CreateCmpInteger(i->get_value());
+ } else if (ref)
+ {
+ AST::NamedDecl *decl = dynamic_cast<AST::NamedDecl *>(ref->getDecl());
+ if (AST::ParmVarDecl *v = dynamic_cast<AST::ParmVarDecl *>(ref->getDecl()))
+ {
+ std::cerr<<"SEEH::VisitUnaryTest Error, SubExpr is DeclRef Param"<<decl->getName()<<std::endl;
+ return m_Builder.CreateTest(decl->getName());
+ } else if (AST::VarDecl *v = dynamic_cast<AST::VarDecl *>(ref->getDecl()))
+ {
+ aeb::lds::GlobalVariable *lv = m_CGF.getModule().GetGlobalVariable(v);
+ return m_Builder.CreateLoad(lv);
+ } else
+ return m_Builder.CreateTest(decl->getName());
+ } else {
+ std::cerr<<"SEEH::VisitUnaryTest Error, SubExpr is not a StringLiteral nor Integer nor DeclRef !! Aiee"<<std::endl;
+ return m_Builder.CreateCmp(NULL);
+ }
+ }
+
+ RetValue VisitParenExpr(AST::ParenExpr *E) {
+ return this->Visit(dynamic_cast<AST::Expr *>(E->getStmt()));
+ }
+
+ RetValue EmitBinaryOp(AST::BinaryOperator *E) {
+ std::ostringstream oss;
+ oss<<"FLAG_TMP_";
+#if 0
+ std::cout<<"Build EmitBinOp "<<E->getOpcode()<<" depth="<<m_depth<<"Load LHS "<<dynamic_cast<AST::BinaryOperator *>(E->getLHS());
+ std::cout<<" Load RHS "<<dynamic_cast<AST::BinaryOperator *>(E->getRHS());
+ std::cout<<std::endl;
+#endif
+ RetValue LHS = Visit(E->getLHS());
+ m_Stack.push(m_depth++);
+ // Store result
+ // std::cout<<"Build Load depth="<<m_depth++<<std::endl;
+ oss<<m_Stack.size();
+ m_Builder.CreateStore(oss.str());
+ if (LHS)
+ {
+ std::cerr<<"EmitBinaryOp: LHS != NULL "<<oss.str()<<std::endl;
+ LHS->setName(oss.str());
+ } else
+ std::cerr<<"EmitBinaryOp: LHS == NULL"<<std::endl;
+
+ RetValue RHS = Visit(E->getRHS());
+
+ switch (E->getOpcode() ) {
+ case AST::BO_And :
+ m_Builder.CreateAnd(oss.str());
+ break;
+ case AST::BO_Or :
+ m_Builder.CreateOr(NULL,NULL);
+ break;
+ case AST::BO_LOr :
+ m_Builder.CreateOr(oss.str());
+ break;
+ case AST::BO_Add :
+ m_Builder.CreatePlus(LHS,RHS);
+ break;
+ case AST::BO_Sub :
+ m_Builder.CreateMoin(LHS,RHS);
+ break;
+ default:
+ std::cout<<"SEEH::UNSUPPORTED OPERATION "<<E->getOpcode()<<std::endl;
+ };
+ // Store result
+ m_depth--;
+ m_Stack.pop();
+ if (m_Stack.size() > 0) {
+ m_Builder.CreateStore(oss.str());
+ m_Builder.CreateCmp(oss.str());
+ } else if (m_Stack.size() == 1) {
+ // :std::cout<<" Shoudl Store ? "<<oss.str()<<std::endl;
+ // m_Builder.CreateCmp(oss.str());
+ } else {
+ // std::cout<<" Stack Empty "<<oss.str()<<std::endl;
+ }
+ return NULL;
+ }
+#define HANDLE_BINOP(OP) \
+ RetValue Visit ## OP (AST::BinaryOperator *E) { \
+ return EmitBinaryOp(E); \
+ }
+
+ HANDLE_BINOP(BinMul);
+ HANDLE_BINOP(BinDiv);
+ HANDLE_BINOP(BinRem);
+ HANDLE_BINOP(BinAdd);
+ HANDLE_BINOP(BinSub);
+ HANDLE_BINOP(BinShl);
+ HANDLE_BINOP(BinShr);
+ HANDLE_BINOP(BinAnd);
+ HANDLE_BINOP(BinXor);
+ HANDLE_BINOP(BinOr);
+ HANDLE_BINOP(BinLAnd);
+ HANDLE_BINOP(BinLOr);
+ // HANDLE_BINOP(BinAssign);
+#undef HANDLE_BINOP
+ // Comparision stuff
+ // Should Return a Value or something Like that
+ aeb::lds::Value *EmitCompare(AST::BinaryOperator *E,const char *lop)
+ {
+ std::ostringstream oss;
+ oss<<"FLAG_TMP_";
+ RetValue LHS = Visit(E->getLHS());
+ m_Stack.push(m_depth++);
+ // Store result
+ oss<<m_Stack.size();
+ aeb::lds::Value *v = m_Builder.CreateStore(oss.str());
+ v->setName(oss.str());
+ RetValue RHS = Visit(E->getRHS());
+ //
+ m_depth--;
+ m_Stack.pop();
+ /** The code below is a bit wierd to me */
+ if (m_Stack.size() > 0)
+ {
+ m_Builder.CreateStore(oss.str());
+ return m_Builder.CreateCmp(oss.str());
+ } else if (m_Stack.size() == 1) {
+ // :std::cout<<" Shoudl Store ? "<<oss.str()<<std::endl;
+ // m_Builder.CreateCmp(oss.str());
+ return m_Builder.CreateCmp(oss.str()) ;
+ } else {
+ // std::cout<<" Stack Empty "<<oss.str()<<std::endl;
+ //return m_Builder.CreateCmp(oss.str()) ;
+ return m_Builder.CreateCmp(v,std::string(lop)) ;
+ }
+ }
+#define HANDLE_BINOP(OP,lop) \
+ RetValue Visit ## OP (AST::BinaryOperator *E) { \
+ CGDBG_EXPR("SEEH:: Handle Compare Visit" # OP ); \
+ aeb::lds::Value *v = EmitCompare(E,lop); \
+ return NULL; \
+ }
+ HANDLE_BINOP(BinLT,"LT");
+ HANDLE_BINOP(BinGT,"GT");
+ HANDLE_BINOP(BinLE,"LE");
+ HANDLE_BINOP(BinGE,"GE");
+ HANDLE_BINOP(BinEQ,"EQ");
+ HANDLE_BINOP(BinNE,"NE");
+
+ RetValue VisitBinAssign (AST::BinaryOperator *E) {
+ AST::StringLiteral *l = dynamic_cast<AST::StringLiteral *>(E->getLHS());
+ CGDBG_EXPR("SEEH::Handle VisitBinAssign");
+ // This is wrong
+ //RetValue LHS = Visit(E->getLHS());
+ RetValue RHS = Visit(E->getRHS());
+ if (l)
+ {
+ return m_Builder.CreateStore(l->getString());
+ } else if (AST::MemberExpr *member = dynamic_cast<AST::MemberExpr *>(E->getLHS()))
+ {
+ std::cerr<<"SEEH:VisitBinAssign LHS TODO MemberExpr "<<std::endl;
+ } else if (AST::ArraySubscriptExpr *member = dynamic_cast<AST::ArraySubscriptExpr *>(E->getLHS()))
+ {
+ std::cerr<<"SEEH:VisitBinAssign LHS TODO ArraySubcrtiptExpr "<<std::endl;
+ } else if (AST::DeclRefExpr *drexpr = dynamic_cast<AST::DeclRefExpr *>(E->getLHS()))
+ { // Handle Differnt Kind of Store
+ if (drexpr->isRefFunctionDecl())
+ { // This is an error. Cannot Store into a Function. Forbidden
+ std::cerr<<"SEEH:VisitBinAssign LHS ERROR DeclRefExpr is Function "<<std::endl;
+ } else if (drexpr->isRefVarDecl())
+ {
+ AST::VarDecl *var = dynamic_cast<AST::VarDecl *>(drexpr->getDecl());
+ aeb::lds::GlobalVariable *lv = m_CGF.getModule().GetGlobalVariable(var);
+ return m_Builder.CreateStore(lv);
+ }
+ } else {
+ std::cerr<<"SEEH:VisitBinAssign LHS cannot be other than StringLiteral"<<std::endl;
+ }
+ return NULL;
+ }
+
+};
+
+// Entry point to generate Scalar Expression
+// for CodeGenFunction class
+namespace aeb {
+namespace lds {
+namespace CodeGen {
+
+void
+CodeGenFunction::EmitScalarExpression(AST::Expr *E) {
+
+ ScalarExprEmitterHelper sm(*this);
+ sm.Visit(E);
+}
+
+}
+}
+}
--- /dev/null
+#include <iostream>
+#include <sstream>
+#include <vector>
+#include <algorithm>
+#include <map>
+#include <stdlib.h>
+
+#include "AST/Stmt.h"
+#include "AST/Expr.h"
+#include "AST/Decl.h"
+
+#include "AST/DeclContext.h"
+
+
+#include <aeb/dlilist.h>
+#include <aeb/dlilist_node.h>
+#include <IR/LdsInstruction.h>
+#include <IR/BasicBlock.h>
+#include <IR/Behavior.h>
+#include <IR/Function.h>
+#include <IR/Argument.h>
+#include <IR/Transition.h>
+#include <IR/LdsBuilder.h>
+#include <IR/Module.h>
+#include <CodeGen/CodeGenType.h>
+#include <CodeGen/CodeGenModule.h>
+#include <CodeGen/CodeGenFunction.h>
+#include <CodeGen/CGDebug.h>
+
+//#define CG_DEBUG
+//#define CG_DEBUG_IF
+
+namespace aeb {
+namespace lds {
+namespace CodeGen {
+
+// A Builder that provide Blocks and set
+CodeGenFunction::CodeGenFunction(CodeGenModule &CGM,const Builder &builder) : m_Builder(builder) , m_CurFn(NULL),m_CGM(CGM)
+ , m_SwitchInst(NULL)
+{
+// std::cout<<"CodeGenFunction::CodeGenFunction constructor"<<std::endl;
+}
+
+
+/**
+ * There is a lot to discuss regarging type conversion, const_cast, dynamic_cast ...
+ *
+ */
+
+/**
+ * Main entry point to generate code for a function.
+ */
+void
+CodeGenFunction::GenerateCode(const AST::FunctionDecl *FnDecl,Function *Fn)
+{
+ if ( !Fn ) {
+ std::cerr<<"CodeGenFunction::GeneratoreCode Error Fn == NULL"<<std::endl;
+ }
+ m_CurFn = Fn;
+ EnsureInsertPoint();
+ if (AST::Stmt * stmt = FnDecl->getBody() ) {
+ EmitStmt(stmt);
+ }
+ aeb::lds::BasicBlock *cb = m_Builder.GetInsertBlock();
+ m_Builder.ClearInsertPoint();
+ m_CurFn = NULL;
+}
+
+/**
+ *
+ */
+void
+CodeGenFunction::GenerateCode(const AST::TransitionDecl *FnDecl,Function *Fn)
+{
+ if ( !Fn ) {
+ std::cerr<<"CodeGenFunction::GenerateCode Error no function"<<std::endl;
+ }
+ Fn->setName(FnDecl->getName());
+ m_CurFn = Fn;
+ // Maybe I should transfer Events and TargetState here or at least create a link
+
+
+ EnsureInsertPoint();
+ if (AST::Stmt * stmt = FnDecl->getBody() ) {
+ EmitStmt(stmt);
+ }
+#if 0
+ std::cout<<"CodeGenFunction::GenerateCode After Emit Statements"<<std::endl;
+ std::cout<<"CodeGenFunction::GenerateCode Fct "<<Fn->getName()<<std::endl;
+ std::cout<<" size:"<<m_CurFn->getBlockList().size()<<std::endl;
+#endif
+ aeb::lds::BasicBlock *cb = m_Builder.GetInsertBlock();
+ if (cb)
+ cb->setName(FnDecl->getName());
+ m_Builder.ClearInsertPoint();
+ m_CurFn = NULL;
+}
+
+void CodeGenFunction::EmitBreakStmt(AST::BreakStmt *S)
+{
+ //std::cout<<"CodeGenFunction::EmitBreak Need to Branch Stack Size="<<m_BreakContinueStack.size()<<std::endl;
+ // Need to EmitBranch to end of While or Switch
+ if (m_BreakContinueStack.top().m_Break)
+ EmitBranch(m_BreakContinueStack.top().m_Break);
+}
+
+
+/**
+ *
+ *
+ */
+void CodeGenFunction::EmitGotoStmt(AST::GotoStmt *S)
+{
+ // std::cout<<"CodeGenFunction::EmitGoto"<<std::endl;
+ m_Builder.CreateGotoState(S->getLabel()->getName());
+}
+
+/**
+ *
+ *
+ */
+void CodeGenFunction::EmitWhileStmt(AST::WhileStmt *S)
+{
+ aeb::lds::BasicBlock *condBlock = createBasicBlock("WHILE.COND");
+ aeb::lds::BasicBlock *endBlock = createBasicBlock("WHILE.END");
+ aeb::lds::BasicBlock *bodyBlock = createBasicBlock("WHILE.BODY");
+ std::cout<<"CodeGenFunction::EmitWhile"<<std::endl;
+ EmitBlock(condBlock);
+
+ EmitScalarExpression( S->getCond());
+ m_Builder.CreateCondBr(bodyBlock,endBlock);
+
+ EmitBlock(bodyBlock);
+ EmitStmt(S->getBody());
+ EmitBranch(condBlock);
+ EmitBlock(endBlock);
+
+}
+
+/**
+ *
+ *
+ */
+void CodeGenFunction::EmitSwitchCaseStmt(AST::SwitchCaseStmt *S)
+{
+
+ aeb::lds::BasicBlock *CB = NULL;
+ aeb::lds::BasicBlock *Block = createBasicBlock("SW.DO");
+
+ if (m_SwitchHashBlock) {
+ aeb::lds::BasicBlock *curBB = m_Builder.GetInsertBlock();
+ if (curBB) {
+ m_Builder.SetInsertPoint(m_SwitchHashBlock);
+ m_Builder.CreateBr(Block);
+ } else {
+ m_Builder.SetInsertPoint(m_SwitchHashBlock);
+ m_Builder.CreateBr(Block);
+ }
+ } else {
+ std::cout<<"CodeGenFunction::EmitSwitchCase ??? No HashBlock"<<std::endl;
+ }
+
+ m_Builder.ClearInsertPoint();
+
+ EmitBlock(Block);
+ EmitStmt(S->getSubStmt());
+
+ m_Builder.ClearInsertPoint();
+}
+
+/**
+ *
+ *
+ */
+void CodeGenFunction::EmitSwitchStmt(AST::SwitchStmt *S)
+{
+ m_SwitchHashBlock = createBasicBlock("SW.HASH");
+
+ if (AST::StringLiteral *s = dynamic_cast<AST::StringLiteral *>(S->getCond()) )
+ {
+ /* Is it a global Variable ? */
+ aeb::lds::GlobalVariable *gv = m_CGM.getOrCreateGlobal(s->getString(),false);
+
+ m_SwitchInst = m_Builder.CreateSwitch(reinterpret_cast<aeb::lds::Value *>(gv),m_SwitchHashBlock);
+ }else if (AST::Expr *e = dynamic_cast<AST::Expr *>(S->getCond()) )
+ {
+ /* Evaluate or emit the expression first */
+ /* Put Result in a temporaly variable */
+ std::cerr<<"CodeGenFunction::EmitSwitchCase ??? Not Yet CODEDE"<<std::endl;
+ exit(0);
+ }else
+ {
+ /* Should not happen */
+ // m_SwitchInst = m_Builder.CreateSwitch("switch",m_SwitchHashBlock);
+ std::cerr<<"CodeGenFunction::EmitSwitchCase ??? No HashBlock"<<std::endl;
+ exit(0);
+ }
+ aeb::lds::BasicBlock *ExitBlock = createBasicBlock("SW.EPILOG");
+
+ m_Builder.ClearInsertPoint();
+ // Save Exit point
+ m_BreakContinueStack.push(BreakContinue(ExitBlock,NULL,m_SwitchHashBlock));
+ for (AST::SwitchStmt::const_case_iterator it = S->case_begin(); it != S->case_end() ; it++)
+ {
+ EmitStmt(*it);
+ }
+ if (m_SwitchHashBlock) {
+ EmitBlock(m_SwitchHashBlock);
+ } else {
+ std::cout<<"CodeGenFunction::EmitSwitch Hoops SwitchHashBlock lost .... "<<std::endl;
+ }
+ if (ExitBlock) {
+ EmitBlock(ExitBlock);
+ }
+
+ m_BreakContinueStack.pop();
+ m_SwitchInst = NULL;
+ if (m_BreakContinueStack.size() > 0) {
+ m_SwitchHashBlock = m_BreakContinueStack.top().m_Hash;
+ } else
+ m_SwitchHashBlock = NULL;
+}
+
+
+void CodeGenFunction::EmitIfStmt(AST::IfStmt *S)
+{
+ CGDBG_IF("CodeGenFunction::EmitIfStmt Begin");
+ // aeb::lds::BasicBlock *CondBlock = createBasicBlock("IF.COND");
+ aeb::lds::BasicBlock *ThenBlock = createBasicBlock("IF.THEN");
+ aeb::lds::BasicBlock *ContBlock = createBasicBlock("IF.END");
+ aeb::lds::BasicBlock *ElseBlock = ContBlock;
+
+ if ( S->getElse())
+ {
+ CGDBG_IF("CodeGenFunction::EmitIfStmt createBasicBlock IF.ELSE");
+ ElseBlock = createBasicBlock("IF.ELSE");
+ }
+ // EmitBlock( CondBlock);
+ EmitScalarExpression( S->getCond());
+ // Branch instruction goes here
+ // ??? ConV should be the result of the evaluation ?
+ m_Builder.CreateCondBr(ThenBlock,ElseBlock);
+ //
+ CGDBG_IF("CodeGenFunction::EmitIfStmt : Before EmitBlock ThenBlock (IF.THEN)");
+ EmitBlock(ThenBlock);
+
+ if (S->getThen()) {
+ EmitStmt( S->getThen());
+ }
+ // This Section replaces EmitBranch(ContBlock)
+ CGDBG_IF_ARGS("CodeGenFunction::EmitIfStmt : Before EmitBranch (%s)",ContBlock->getName());
+ EmitBranch(ContBlock);
+ //
+ if (const AST::Stmt *Else = S->getElse()) {
+ CGDBG_IF("CodeGenFunction::EmitIfStmt : Handle Else case ");
+ // std::cout<<"EMitIf : Before EmitBranch ContBlock (IF.END)"<<std::endl;
+ EmitBranch(ContBlock);
+ // std::cout<<"EMitIf : Before EmitBlock ElseBlock (IF.ELSE)"<<std::endl;
+ EmitBlock(ElseBlock);
+ // std::cout<<"EMitIf : Before EmitStmt Else"<<std::endl;
+ EmitStmt( S->getElse());
+ // std::cout<<"EMitIf : Before EmitBranch ContBlock"<<std::endl;
+ EmitBranch(ContBlock);
+ }
+
+ CGDBG_IF("CodeGenFunction::EmitIfStmt : Before EmitBlock ContBlock true");
+ EmitBlock(ContBlock,true);
+ CGDBG_IF("CodeGenFunction::EmitIfStmt : End\n");
+}
+// Main entry point
+void CodeGenFunction::EmitStmt(AST::Stmt *S)
+{
+ if (EmitSimpleStmt(S))
+ return;
+ if ( ! HaveInsertPoint())
+ {
+ EnsureInsertPoint();
+ }
+ switch (S->getStmtClass()) {
+ case AST::Stmt::CompoundStmtClass:
+ EmitCompoundStmt(dynamic_cast<AST::CompoundStmt *>(S));
+ break;
+ case AST::Stmt::GotoStmtClass:
+ EmitGotoStmt(static_cast<AST::GotoStmt *>(S));
+ break;
+ case AST::Stmt::IfStmtClass:
+ EmitIfStmt(static_cast<AST::IfStmt *>(S));
+ break;
+ case AST::Stmt::SwitchCaseStmtClass:
+ EmitSwitchCaseStmt(static_cast<AST::SwitchCaseStmt *>(S));
+ break;
+ case AST::Stmt::SwitchStmtClass:
+ EmitSwitchStmt(static_cast<AST::SwitchStmt *>(S));
+ break;
+ case AST::Stmt::WhileStmtClass:
+ EmitWhileStmt(static_cast<AST::WhileStmt *>(S));
+ break;
+ case AST::Stmt::BreakStmtClass:
+ EmitBreakStmt(static_cast<AST::BreakStmt *>(S));
+ break;
+ case AST::Stmt::ForStmtClass:
+ std::cout<<"TOBE CODED "<<std::endl;
+ break;
+ case AST::Stmt::CallExprClass:
+ EmitCallExpr(static_cast<AST::CallExpr *>(S));
+ break;
+ case AST::Stmt::ParenExprClass:
+ EmitStmt(dynamic_cast<AST::ParenExpr *>(S)->getStmt());
+ break;
+ case AST::Stmt::BinaryOperatorClass:
+ {
+ AST::BinaryOperator *u = dynamic_cast<AST::BinaryOperator *>(S);
+ CGDBG_ARGS("CodeGenFunction::EmitSmt BinaryOperator %d",u->getOpcode());
+ EmitScalarExpression(u);
+ }
+ break;
+ case AST::Stmt::UnaryOperatorClass:
+ {
+ AST::UnaryOperator *u = dynamic_cast<AST::UnaryOperator *>(S);
+ std::cout<<"UnaryOperator "<<u->getOpcode()<<std::endl;
+ }
+ break;
+ case AST::Stmt::IntegerLiteralClass:
+ std::cout<<"int "<<std::endl;
+ break;
+ case AST::Stmt::StringLiteralClass:
+ {
+ AST::StringLiteral *u = dynamic_cast<AST::StringLiteral *>(S);
+ std::cout<<"String var or Fct Call ? "<<u->getString()<<std::endl;
+ aeb::lds::CallInst *c = m_Builder.CreateCall(u->getString());
+ }
+ break;
+
+ case AST::Stmt::ReturnStmtClass:
+ {
+ if (AST::ReturnStmt *ret = dynamic_cast<AST::ReturnStmt *>(S)) {
+ if ( ret->getIndirect() ) {
+ aeb::lds::ReturnInst *c = m_Builder.CreateRetSub();
+ } else
+ aeb::lds::ReturnInst *c = m_Builder.CreateRetVoid();
+ }
+ }
+ break;
+ case AST::Stmt::LdsAsmStmtClass:
+ {
+ EmitLdsAsmStmt(dynamic_cast<AST::LdsAsmStmt *>(S));
+ }
+ break;
+ case AST::Stmt::OutputStmtClass:
+ {
+ EmitOutputStmt(dynamic_cast<AST::OutputStmt *>(S));
+ }
+ break;
+ default:
+ std::cout<<"EmitStmt unknown ... "<<S->getStmtClass()<<std::endl;
+ ;
+ }
+}
+
+
+bool CodeGenFunction::EmitSimpleStmt(AST::Stmt *S)
+{
+ switch (S->getStmtClass()) {
+ default: return false;
+ //case Stmt::NullStmtClass: break;
+ case AST::Stmt::CompoundStmtClass:
+ EmitCompoundStmt(dynamic_cast<AST::CompoundStmt *>(S));
+ break;
+#if 0
+ case AST::Stmt::DeclStmtClass:
+ EmitDeclStmt(dynamic_cast<AST::DeclStmt *>(S));
+ break;
+ case AST::Stmt::LabelStmtClass:
+ EmitLabelStmt(dynamic_cast<AST::LabelStmt>(S));
+ break;
+#endif
+ //case AST::Stmt::AttributedStmtClass:
+ // EmitAttributedStmt(dynamic_cast<AST::AttributedStmt>(S)); break;
+ case AST::Stmt::GotoStmtClass:
+ EmitGotoStmt(dynamic_cast<AST::GotoStmt *>(S));
+ break;
+ case AST::Stmt::BreakStmtClass:
+ EmitBreakStmt(dynamic_cast<AST::BreakStmt *>(S));
+ break;
+ case AST::Stmt::OutputStmtClass:
+ EmitOutputStmt(dynamic_cast<AST::OutputStmt *>(S));
+ break;
+ //case AST::Stmt::ContinueStmtClass: EmitContinueStmt(dynamic_cast<AST::ContinueStmt>(S)); break;
+ //case AST::Stmt::DefaultStmtClass: EmitDefaultStmt(dynamic_cast<AST::DefaultStmt>(S)); break;
+ case AST::Stmt::SwitchCaseStmtClass:
+ EmitSwitchCaseStmt(dynamic_cast<AST::SwitchCaseStmt *>(S));
+ break;
+ }
+#if 0
+STMT(ReturnStmt,Stmt)
+STMT(ForStmt,Stmt)
+STMT(OutputStmt,Stmt)
+STMT(AsmStmt,Stmt)
+STMT(LdsAsmStmt,AsmStmt)
+#endif
+ return true;
+}
+
+
+
+/**
+ *
+ */
+void CodeGenFunction::EmitOutputStmt(AST::OutputStmt *S)
+{
+ AST::EventDecl *sig = S->getEventDecl();
+ aeb::lds::Value *v = m_CGM.getModule().getOrInsertSignal(sig->getName());
+ aeb::lds::SendEventInst *c = m_Builder.CreateOutput(v);
+
+ CGDBG_ARGS("CodeGenFunction::EmitOutputStmt %s Args=%d",sig->getName(),S->getNumArgs());
+ /* Process Arguments */
+ int ParamIdx = 1;
+ AST::Stmt::range_iterator rit = S->children() ;
+ for ( AST::Stmt::child_iterator it = begin(rit)
+ ; it != end(rit)
+ ; ++it, ParamIdx++ )
+ {
+ aeb::lds::Value *value = NULL;
+
+ if ( AST::StringLiteral *u = dynamic_cast<AST::StringLiteral *>(*it) )
+ {
+ //
+ // This is wrong. I should check from which context is the parameter.
+ // Only if the parameter name is from global context
+ std::cerr<<"ERROR: CodeGenFunction::EmitOutputStmt Parameter is StringLiteral NOT GOOD missing declaration "<<u->getString()<<std::endl;
+ value = m_CGM.getOrCreateGlobal(u->getString(),false);
+ if (c)
+ {
+ // Call c function there is no definition or body
+ //TODO Missing the type here
+ std::cout<<"CodeGenFunction::EmitOutputStmt C call "<<sig->getName();
+ std::cout<<" p:"<<u->getString()<<std::endl;
+ c->addParam(reinterpret_cast<Value *>(value));
+ }
+ } else if ( AST::DeclRefExpr *u = dynamic_cast<AST::DeclRefExpr *>(*it) )
+ {
+ AST::ValueDecl *nv = dynamic_cast<AST::ValueDecl *>(u->getDecl());
+ AST::ParmVarDecl *pv = dynamic_cast<AST::ParmVarDecl *>(u->getDecl());
+ if (pv)
+ {
+ value = getCurrentFunction()->getArgument(pv->getName());
+ if (value)
+ {
+ std::cout<<"CodeGenFunction::EmitOutput "<<sig->getName();
+ std::cout<<" FOUND Param "<<pv->getName()<<" Idx="<<ParamIdx;
+ std::cout<<" PV Type NULL ? "<<(pv->getType() == NULL)<<std::endl;
+ } else
+ {
+ std::cout<<"CodeGenFunction::EmitOutput ERROR function call parameter not globalVariable !!!!!! "<<ParamIdx<<std::endl;
+ value = m_CGM.getOrCreateGlobal(nv);
+ }
+ } else
+ {
+ //TODO BAD AND WRONG IT's A PARAMETER FROM THE CURRENT CALL STACK
+ value = m_CGM.getOrCreateGlobal(nv);
+ }
+ std::cout<<"CodeGenFunction::EmitOutput call "<<sig->getName();
+ std::cout<<" Param NamedDecl: "<<nv->getName()<<" "<<std::endl;
+ if (c)
+ {
+ c->addParam(reinterpret_cast<Value *>(value));
+ }
+ } else if ( AST::Expr *u = dynamic_cast<AST::Expr *>(*it) )
+ {
+ std::cout<<"CodeGenFunction::EmitOutputStmt call "<<sig->getName();
+ std::cout<<" TODO parameter is expression"<<std::endl;
+ } else
+ {
+ std::cout<<"CodeGenFunction::EmitOutputStmt call "<<sig->getName();
+ std::cout<<" TODO parameter is may be a constant "<<std::endl;
+ }
+ } /*End for*/
+}
+
+void CodeGenFunction::EmitLdsAsmStmt(AST::LdsAsmStmt *S)
+{
+ switch (S->getOpcode()) {
+ case AST::LdsAsmStmt::AEL_RETURN:
+ {
+ aeb::lds::ReturnInst *c = m_Builder.CreateRetVoid();
+ }
+ break;
+ case AST::LdsAsmStmt::AEL_RESET:
+ {
+ if (S->isArgVariable())
+ {
+ //m_CGM.getOrCreateGlobal(S->getLiteral()->getString());
+ m_CGM.getOrCreateGlobal(S->getVarDecl());
+ aeb::lds::Instruction *c = m_Builder.CreateReset(S->getLiteral()->getString());
+ } else if (S->isArgTimer())
+ {
+ std::cout<<"CodeGenFunction::EmitLdsAsmStmt TODO RESET TIMER"<<std::endl;
+ } else
+ {
+ std::cout<<"CodeGenFunction::EmitLdsAsmStmt RESET ????"<<std::endl;
+ }
+
+ }
+ break;
+ case AST::LdsAsmStmt::AEL_SET:
+ {
+ if (S->isArgVariable())
+ {
+ //m_CGM.getOrCreateGlobal(S->getLiteral()->getString());
+ m_CGM.getOrCreateGlobal(S->getVarDecl());
+ aeb::lds::Instruction *c = m_Builder.CreateSet(S->getLiteral()->getString());
+ } else if (S->isArgTimer())
+ {
+ std::cout<<"CodeGenFunction::EmitLdsAsmStmt TODO SET TIMER"<<std::endl;
+ } else
+ {
+ std::cout<<"CodeGenFunction::EmitLdsAsmStmt SET ????"<<std::endl;
+ }
+ }
+ break;
+ case AST::LdsAsmStmt::AEL_JSR_IND:
+ {
+ m_CGM.getOrCreateGlobal(S->getLiteral()->getString(),false);
+ aeb::lds::Instruction *c = m_Builder.CreateJsrInd(S->getLiteral()->getString());
+ }
+ break;
+ case AST::LdsAsmStmt::AEL_RTS:
+ {
+ aeb::lds::ReturnInst *c = m_Builder.CreateRetSub();
+ }
+ break;
+ case AST::LdsAsmStmt::AEL_NOP:
+ {
+ aeb::lds::Instruction *c = m_Builder.CreateNop();
+ }
+ break;
+ case AST::LdsAsmStmt::AEL_LOOP_MSG:
+ {
+ // AST::EventDecl *sig = S->getEventDecl();
+ aeb::lds::Value *v = m_CGM.getModule().getOrInsertSignal(S->getLiteral()->getString());
+ aeb::lds::Instruction *c = m_Builder.CreateSendEvent(v);
+ }
+ break;
+ default:
+ std::cout<<"EmitLdsAsmStmt UNKNOWN Statement ... "<<S->getStmtClass()<<std::endl;
+ ;
+ };
+}
+
+void CodeGenFunction::EmitCompoundStmt(AST::CompoundStmt *S)
+{
+ aeb::lds::BasicBlock *incoming = m_Builder.GetInsertBlock();
+ //std::cout<<"CodeGenFunction::EmitCompoundStmt"<<std::endl;
+ for (AST::CompoundStmt::iterator it = S->begin() ; it != S->end() ; ++it)
+ EmitStmt(*it);
+
+ aeb::lds::BasicBlock *outgoing = m_Builder.GetInsertBlock();
+ if (incoming != outgoing)
+ {
+ //std::cout<<"CodeGenFunction::EmitCompoundStmt Clear Insert :"<<std::endl;
+ // m_Builder.ClearInsertPoint();
+ }
+}
+
+/**
+ * Function Call
+ * I need to
+ *
+ */
+void CodeGenFunction::EmitCallExpr(AST::CallExpr *S)
+{
+ AST::FunctionDecl *d = dynamic_cast<AST::FunctionDecl *>(S->getCalleeDecl()) ;
+ aeb::lds::BasicBlock *BB = m_Builder.GetInsertBlock();
+ int ParamIdx = 0;
+ if (! BB)
+ {
+ std::cout<<"CodeGenFunction::EmitCallExpr ERROR BB== NULL "<<d->getName()<<std::endl;
+ }
+ if (!d) {
+ AST::StringLiteral *s = dynamic_cast<AST::StringLiteral *>(S->getCalleeDecl()) ;
+ std::cout<<"CodeGenFunction::EmitCallExpr Problem, d is not of type FunctionDecl "<<S->getStmtClass()<<std::endl;
+ if (! S->getCalleeDecl()) {
+ std::cout<<"CodeGenFunction::EmitCallExpr no callee "<<std::endl;
+ }
+ if (s)
+ std::cout<<"CodeGenFunction::EmitCallExpr Problem, its: "<<s->getString()<<std::endl;
+ return;
+ }
+
+ if ( ! HaveInsertPoint() ) {
+ std::cout<<"CodeGenFunction::EmitCallExpr ERROR no insert point "<<d->getName()<<std::endl;
+ }
+ // std::cout<<"CodeGenFunction::EmitCallExpr( "<<d->getName()<<" )"<<std::endl;
+
+ aeb::lds::CallInst *c = NULL;
+ if (d->hasDefinition())
+ {
+ // Jump to Function ... CreateJsr Value not string
+ m_Builder.CreateJsr(d->getName());
+ } else
+ c= m_Builder.CreateCall(d->getName());
+ // Handle Parameter stuff to complete the Call.
+ // Also add function declaration in module
+ m_CGM.EmitGlobalFunctionDefinition(d,true);
+ // Parameters should be defined as globalVariables !!!!
+ // For now, we add the parameters in the CallInst ...
+ AST::Stmt::range_iterator rit = S->children() ;
+ for ( AST::Stmt::child_iterator it = begin(rit)
+ ; it != end(rit)
+ ; ++it, ParamIdx++ )
+ {
+ aeb::lds::Value *value = NULL;
+ if ( AST::StringLiteral *u = dynamic_cast<AST::StringLiteral *>(*it) )
+ {
+ //
+ // This is wrong. I should check from which context is the parameter.
+ // Only if the parameter name is from global context
+ std::cerr<<"ERROR: CodeGenFunction::EmitCallExpr Parameter is StringLiteral NOT GOOD missing declaration "<<u->getString()<<std::endl;
+ value = m_CGM.getOrCreateGlobal(u->getString(),false);
+ if (c)
+ {
+ // Call c function there is no definition or body
+ //TODO Missing the type here
+ std::cout<<"CodeGenFunction::EmittCallExpr C call "<<d->getName()<<" p:"<<u->getString()<<std::endl;
+ c->addParam(reinterpret_cast<Value *>(value));
+ } else {
+ // Internal defined Function do not have parameters yet
+ std::cout<<"CodeGenFunction::EmittCallExpr call "<<d->getName()<<" of defined function with parameters not supported"<<std::endl;
+ break;
+ }
+ } else if ( AST::DeclRefExpr *u = dynamic_cast<AST::DeclRefExpr *>(*it) )
+ {
+ AST::ValueDecl *nv = dynamic_cast<AST::ValueDecl *>(u->getDecl());
+ AST::ParmVarDecl *pv = dynamic_cast<AST::ParmVarDecl *>(u->getDecl());
+ if (pv)
+ {
+ value = getCurrentFunction()->getArgument(pv->getName());
+ if (value)
+ {
+ std::cout<<"CodeGenFunction::EmitCallExpr "<<d->getName()<<" FOUND Param "<<pv->getName()<<" Idx="<<ParamIdx<<" PV Type NULL ? "<<(pv->getType() == NULL)<<std::endl;
+ } else
+ {
+ std::cout<<"CodeGenFunction::EmitCallExpr ERROR function call parameter not globalVariable !!!!!! "<<ParamIdx<<std::endl;
+ value = m_CGM.getOrCreateGlobal(nv);
+ }
+ } else
+ {
+ //TODO BAD AND WRONG IT's A PARAMETER FROM THE CURRENT CALL STACK
+ value = m_CGM.getOrCreateGlobal(nv);
+ }
+#ifdef CG_DEBUG
+ std::cout<<"CodeGenFunction::EmittCallExpr call "<<d->getName()<<" Param NamedDecl: "<<nv->getName()<<" "<<std::endl;
+#endif
+ if (c)
+ {
+ c->addParam(reinterpret_cast<Value *>(value));
+ }
+ } else if ( AST::Expr *u = dynamic_cast<AST::Expr *>(*it) )
+ {
+ std::cout<<"CodeGenFunction::EmittCallExpr call "<<d->getName()<<" TODO parameter is expression"<<std::endl;
+ } else
+ {
+ std::cout<<"CodeGenFunction::EmittCallExpr call "<<d->getName()<<" TODO parameter is may be a constant "<<std::endl;
+ }
+ }
+}
+
+
+
+void CodeGenFunction::EmitBlock(aeb::lds::BasicBlock *target,bool isFinished)
+{
+ if (target == NULL) {
+ std::cout<<"CodeGenFunction::EmitBlock target="<<target<<std::endl;
+ exit(0);
+ }
+ aeb::lds::BasicBlock *cb = m_Builder.GetInsertBlock();
+
+ EmitBranch(target);
+ /* I have an Issue with if expr the execute call else do something else endif */
+ if (isFinished && ! target->isUsed())
+ {
+#ifdef GC_DEBUG
+ std::cout<<"CodeGenFunction::EmitBlock Fin: "<<isFinished<<std::endl;
+#endif
+ delete target;
+ return;
+ }
+
+ // Need to place the block at the End of function....
+ // Is there a necessity for parent in BasicBlock ?
+ if (cb && cb->getParent()) {
+ // Place the block after the current block
+ // std::cout<<"CodeGenFunction::EmitBlock insert in "<<m_CurFn->getName()<<" after ("<<cb->getName()<<") block (" << target->getName()<<")"<<std::endl;
+ m_CurFn->getBlockList().insertAfter(cb->getIterator(),target);
+ } else {
+ // Place The blck aat the end
+ // std::cout<<"CodeGenFunction::EmitBlock insert in "<<m_CurFn->getName()<<" end "<<target->getName()<<std::endl;
+ m_CurFn->getBlockList().push_back(target);
+ }
+ // std::cout<<"CodeGenFunction::EmitBlock insert in "<<m_CurFn->getName()<<" New Size "<<m_CurFn->getBlockList().size()<<std::endl;
+ m_Builder.SetInsertPoint(target);
+
+}
+
+void CodeGenFunction::EmitBranch(aeb::lds::BasicBlock *target)
+{
+ // std::cout<<"CodeGenFunction::EmitBranch"<<std::endl;
+ aeb::lds::BasicBlock *curBB = m_Builder.GetInsertBlock();
+ if ( !curBB || curBB->getTerminator())
+ {
+ // If there is no curBlock or if curBlock is terminated. Don't do
+ // anything
+ /* I have in Issue with if expr the execute call else do something else endif
+ * Because execute is a Terminator
+ */
+#if 0
+ std::cout<<"CodeGenFunction::EmitBranch... !curBB || curBB->getTerminator() ";
+ if (curBB)
+ {
+ std::cout<<" Clear Insert Point "<<curBB->getName()<<std::endl;
+ } else
+ std::cout<<" curBB == NULL"<<std::endl;
+#endif
+ } else {
+ //std::cout<<"CodeGenFunction::EmitBranch... Add Br "<<target->getName()<<std::endl;
+ m_Builder.CreateBr(target);
+ }
+ m_Builder.ClearInsertPoint();
+}
+
+
+
+aeb::lds::BasicBlock *
+CodeGenFunction::createBasicBlock(const std::string &n,aeb::lds::BasicBlock *parent,aeb::lds::BasicBlock *before)
+{
+ return BasicBlock::Create(n,parent);
+}
+
+
+
+bool
+CodeGenFunction::HaveInsertPoint()
+{
+ return m_Builder.GetInsertBlock() != NULL;
+}
+
+
+}
+}
+}
+
--- /dev/null
+#include <iostream>
+#include <vector>
+#include <algorithm>
+#include <map>
+#include <sstream>
+
+
+#include "AST/Stmt.h"
+#include "AST/Expr.h"
+#include "AST/Decl.h"
+
+#include "AST/DeclContext.h"
+
+
+#include <aeb/dlilist.h>
+#include <aeb/dlilist_node.h>
+#include <IR/LdsInstruction.h>
+#include <IR/BasicBlock.h>
+#include <IR/Transition.h>
+#include <IR/Module.h>
+#include <IR/Type.h>
+#include <IR/LdsBuilder.h>
+#include <CodeGen/CodeGenType.h>
+#include <CodeGen/CodeGenModule.h>
+#include <CodeGen/CodeGenFunction.h>
+#include <CodeGen/CGDebug.h>
+
+namespace aeb {
+namespace lds {
+namespace CodeGen {
+
+
+ CodeGenModule::CodeGenModule(AST::ASTContext &C, aeb::lds::Module *m)
+ : m_Context(C),m_Module(m) , m_CodeGenType(*this)
+ {
+ }
+
+ void CodeGenModule::EmitTopLevelDecl(AST::Decl *decl)
+ {
+ switch (decl->getKind() ) {
+ case AST::DeclBase::FunctionDecl :
+ EmitGlobalFunctionDefinition(dynamic_cast<AST::FunctionDecl *>(decl),false);
+ break;
+ case AST::DeclBase::StateDecl :
+ EmitGlobalStateDefinition(dynamic_cast<AST::StateDecl *>(decl));
+ break;
+ case AST::DeclBase::TransitionDecl :
+ std::cout<<"CodeGenModule::EmitTopLevelDecl Transition:"<<decl->getKind()<<std::endl;
+ break;
+ case AST::DeclBase::EventDecl :
+ {
+ EmitEvent(dynamic_cast<AST::EventDecl *>(decl));
+ }
+ break;
+ case AST::DeclBase::TimerDecl :
+ {
+ EmitTimerDefinition(dynamic_cast<AST::TimerDecl *>(decl));
+ }
+ break;
+ case AST::DeclBase::VarDecl :
+ {
+ AST::VarDecl *v = dynamic_cast<AST::VarDecl *>(decl);
+ if (v->isConstant())
+ {
+ EmitConstantValueInit(v);
+ } else
+ EmitGlobalVarDefinition(dynamic_cast<AST::VarDecl *>(decl));
+ }
+ break;
+ case AST::DeclBase::LabelDecl :
+ {
+ AST::LabelDecl *l = dynamic_cast<AST::LabelDecl *>(decl);
+ std::cout<<"CodeGenModele::EmitTopLevelDecl Label ";
+ std::cout<<l->getName()<<" "<<decl->getKind()<<std::endl;
+ }
+ break;
+ case AST::DeclBase::RecordDecl :
+ std::cout<<"CodeGenModele::EmitTopLevelDecl Record: "<<std::endl;
+ break;
+ case AST::DeclBase::EnumDecl :
+ std::cout<<"CodeGenModele::EmitTopLevelDecl Enum: "<<std::endl;
+ break;
+ case AST::DeclBase::TypedefDecl :
+ {
+ AST::TypedefDecl *l = dynamic_cast<AST::TypedefDecl *>(decl);
+ std::cout<<"CodeGenModele::EmitTopLevelDecl Typedef: TODO "<<l->getName()<<std::endl;
+ }
+ break;
+ case AST::DeclBase::ValueTypeDecl :
+ EmitValueTypeDefinition(dynamic_cast<AST::ValueTypeDecl *>(decl));
+ break;
+ case AST::DeclBase::AutomatonDecl:
+ case AST::DeclBase::PackageDecl:
+ case AST::DeclBase::SystemDecl:
+ case AST::DeclBase::BlockDecl:
+ std::cout<<"CodeGenModele::EmitTopLevelDecl Ingore: Auth decl,PckDecl,SysDecl,BlcDecl"<<std::endl;
+ break;
+ default:
+ std::cout<<"CodeGenModele::EmitTopLevelDecl Not Yet Handled Kind("<<decl->getKind()<<")"<<std::endl;
+ };
+ }
+
+
+ /**
+ * Loop over Transition ....
+ * Check if there is a core implementation
+ */
+ void CodeGenModule::EmitGlobalFunctionDefinition(AST::FunctionDecl *_d,bool onlydef) {
+ if (_d->hasDefinition() && ! onlydef) {
+ // std::cout<<"Emit Code For Function "<<_d->getName()<<std::endl;
+ // Alright, it's a task, we should use the CGFunction class to create Instruction blocks
+ aeb::lds::Function *Fct = m_Module->getOrInsertFunction(_d->getName(),NULL,aeb::lds::Function::Local);
+ CodeGenFunction m_CGF(*this,aeb::lds::Builder());
+ m_CGF.GenerateCode(_d,Fct);
+
+ } else {
+ // std::cout<<"Emit Code For Function "<<_d->getName()<<" Builder Not called Params:"<<_d->param_size()<<std::endl;
+ aeb::lds::Function *Fct = m_Module->getOrInsertFunction(_d->getName(),NULL,aeb::lds::Function::ExternalLink);
+ // I need the function signature in order to be able to call the right code
+ Fct->setNbParams(_d->param_size());
+ if ( _d->param_size() != Fct->args().size())
+ for (AST::FunctionDecl::const_param_iterator pit = _d->param_begin()
+ ; pit != _d->param_end()
+ ; ++pit)
+ {
+ if (AST::ParmVarDecl *pv = dynamic_cast<AST::ParmVarDecl *>(*pit))
+ {
+ aeb::lds::Type *iTy = NULL;
+ if (pv->getType() != NULL)
+ {
+#if 1
+ iTy = getType().ConvertType(pv->getType());
+#else
+ // std::cout<<"CodeGenModule::EmitGlobalFunctionDefinition "<<pv->getName()<<" Has type ";
+ switch (pv->getType()->getClass())
+ {
+ case AST::Type::Builtin :
+ case AST::Type::Typedef :
+ {
+ AST::BuiltinType *bTy = dynamic_cast<AST::BuiltinType *>(pv->getType());
+ // std::cout<<bTy->getNameAsStr();
+ iTy = getType().ConvertType(pv->getType());
+ }
+ break;
+ default:
+ //std::cout<<" Used Defined";
+ std::cerr<<"EmitGlobalFunctionDefinition "<<pv->getName()<<" Unhandled type"<<std::endl;
+ }
+ //std::cout<<" clsId="<<pv->getType()->getClass()<<std::endl;
+#endif
+ }
+ aeb::lds::Argument *arg = new Argument((*pit)->getName(),Fct);
+ arg->setType(iTy);
+ } else
+ aeb::lds::Argument *arg = new Argument((*pit)->getName(),Fct);
+ }
+ }
+ }
+
+ /**
+ * Loop over Transition ....
+ */
+ void CodeGenModule::EmitGlobalStateDefinition(AST::StateDecl *_d) {
+ // std::cout<<"CodeGenModele::EmitGlobalStateDefinition "<<_d->getKind()<<" "<<_d->getName()<<std::endl;
+ AST::DeclContext *DC = dynamic_cast<AST::DeclContext *>(_d);
+ // Simply loop through
+ if (DC) {
+ aeb::lds::State *state = new State(_d->getName());
+ m_Module->getOrInsertState(_d->getName(),state);
+
+ for (AST::DeclContext::decl_iterator it = DC->begin(); it != DC->end() ; ++it )
+ {
+ if ( AST::TransitionDecl *t = dynamic_cast<AST::TransitionDecl *>(*it))
+ {
+ //std::cout<<"Emit Code For State "<<state->getName()<<"Transition "<<t->getName()<<std::endl;
+ aeb::lds::Function *Fct = m_Module->getOrInsertFunction(t->getName());
+
+ CodeGenFunction m_CGF(*this,aeb::lds::Builder());
+ // Add Parameters to the function before generating the code
+ AST::EventDecl *e = *(t->events_begin());
+ if ( e->param_size() > 0 )
+ {
+ //std::cout<<"Function "<<t->getName()<<" Has parameters ";
+ for (AST::FunctionDecl::const_param_iterator pit = e->param_begin()
+ ; pit != e->param_end()
+ ; ++pit)
+ {
+ //std::cout<<" <"<<(*pit)->getName()<<">";
+ aeb::lds::Argument *arg = new Argument((*pit)->getName(),Fct);
+ }
+ //std::cout<<std::endl;
+ }
+
+ m_CGF.GenerateCode(t,Fct);
+ // Loop through the events in the transition and create a Transition per event.
+ for (AST::TransitionDecl::event_iterator evt = t->events_begin() ; evt != t->events_end() ; ++evt )
+ {
+ // std::cout<<"EmitGloblStateDef:: Create "<<state->getName()<<" Transition for Event "<<(*evt)->getName()<<std::endl;
+ aeb::lds::Transition *lTransition = new aeb::lds::Transition(t->getName());
+ aeb::lds::Signal *sig = GetSignal(*evt);
+ state->insertTransition(lTransition,sig,Fct,t->getTargetState());
+ }
+ // Generated code should be in lTransition. I should be able to do the Same with Global Functions.
+ // Add The Transition into Module
+ }
+ }
+ } else {
+ std::cerr<<"WRONG Decl"<<std::endl;
+ }
+ }
+ /**
+ *
+ */
+ void CodeGenModule::EmitValueTypeDefinition(AST::ValueTypeDecl *D)
+ {
+ GlobalVariable *GV;
+ std::cout<<"CodeGenModule::EmitValueType TODO ";
+ std::cout<<" "<<D->getName()<<std::endl;
+ aeb::lds::StructType *_struct =
+ m_CodeGenType.addStructTypeDecl(D);
+ }
+
+ /**
+ *
+ */
+ void CodeGenModule::EmitEvent(AST::EventDecl *e)
+ {
+ std::cout<<"CodeGenModele::EmitEvent:";
+ std::cout<<" "<<e->getName()<<std::endl;
+ aeb::lds::Signal *Sig = GetSignal(e);
+ }
+ /**
+ *
+ */
+ aeb::lds::Signal *CodeGenModule::GetSignal(AST::EventDecl *e)
+ {
+ aeb::lds::Signal *Sig =
+ m_Module->getOrInsertSignal(e->getName());
+ Sig->setNbParams(e->param_size());
+ if ( e->param_size() != Sig->args().size())
+ {
+ std::cout<<"CodeGenModele::GetSignal:";
+ std::cout<<" "<<e->getName()<<" Set Type for argument "<<std::endl;
+ for (AST::FunctionDecl::const_param_iterator pit = e->param_begin()
+ ; pit != e->param_end()
+ ; ++pit)
+ {
+ aeb::lds::Type *iTy = NULL;
+ if (AST::ParmVarDecl *pv = dynamic_cast<AST::ParmVarDecl *>(*pit))
+ {
+ iTy = getType().ConvertType(pv->getType());
+ }
+ aeb::lds::SigArgument *arg = new SigArgument((*pit)->getName(),Sig);
+ arg->setType(iTy);
+ }
+ }
+ return Sig;
+ }
+ /**
+ * Get Or create LDS Variable
+ */
+ aeb::lds::GlobalVariable *CodeGenModule::GetGlobalVariable(AST::VarDecl *D)
+ {
+ GlobalVariable *GV;
+ CGDBG_ARGS("CodeGenModule::GetGlobalVariable %s",
+ D->getName());
+ aeb::lds::Type *Ty = getType().ConvertType(D->getType());
+ GV =m_Module->insertGlobal(D->getName(),false,Ty);
+ return GV;
+ }
+
+
+ /**
+ *
+ */
+ void CodeGenModule::EmitConstantValueInit(AST::VarDecl *D)
+ {
+ GlobalVariable *GV;
+ std::cout<<"CodeGenModule::EmitConstantValueInit TODO Var:";
+ std::cout<<" "<<D->getName()<<std::endl;
+ aeb::lds::Type *Ty = getType().ConvertType(D->getType());
+ GV =m_Module->insertGlobal(D->getName(),true,Ty);
+ }
+ /**
+ *
+ */
+ void CodeGenModule::EmitGlobalVarDefinition(AST::VarDecl *D)
+ {
+ GlobalVariable *GV;
+ CGDBG_ARGS("CodeGenModule::EmitGlobalVarDefinition ",
+ ,D->getName());
+ aeb::lds::Type *Ty = getType().ConvertType(D->getType());
+ GV =m_Module->insertGlobal(D->getName(),false,Ty);
+ }
+ /**
+ *
+ */
+ void CodeGenModule::EmitTimerDefinition(AST::TimerDecl *D)
+ {
+ std::cout<<"CodeGenModule::EmitTimerDefinition ";
+ std::cout<<" "<<D->getName()<<std::endl;
+ aeb::lds::Signal *Sig =
+ m_Module->getOrInsertSignal(D->getName());
+ }
+#if 1
+ /*
+ *
+ *
+ */
+ GlobalVariable * CodeGenModule::getOrCreateGlobal(const std::string &_flag,bool constant,void *_Ty )
+ {
+ GlobalVariable *GV;
+ std::cout<<"CodeGenModule::getOrCreateGlobal deprecated: "<<_flag<<std::endl;
+ GV =m_Module->insertGlobal(_flag,constant);
+ return GV;
+ }
+#endif
+ GlobalVariable * CodeGenModule::getOrCreateGlobal(const AST::ValueDecl *D)
+ {
+ GlobalVariable *GV;
+ aeb::lds::Type *Ty = getType().ConvertType(D->getType());
+ //std::cout<<"CodeGenModule::getOrCreateGlobal "<<D->getName()<<std::endl;
+ GV =m_Module->insertGlobal(D->getName(),Ty);
+ return GV;
+ }
+}
+}
+}
+/**
+ * vim: sw=2 et ts=2 list:
+ */
--- /dev/null
+PROJECT(AST)
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../include/)
+INCLUDE_DIRECTORIES(${aebutils_SOURCE_DIR})
+
+
+ADD_LIBRARY(commonCodeGen
+ CGFunction.cpp
+ ModuleBuilder.cpp
+ CGModule.cpp
+ CGExprScalar.cpp
+ CodeGenType.cpp
+ )
--- /dev/null
+#include <iostream>
+#include <vector>
+#include <map>
+#include <algorithm>
+#include <sstream>
+
+
+#include "AST/Stmt.h"
+#include "AST/Expr.h"
+#include "AST/Decl.h"
+
+#include "AST/DeclContext.h"
+
+
+#include <aeb/dlilist.h>
+#include <aeb/dlilist_node.h>
+#include <IR/LdsInstruction.h>
+#include <IR/BasicBlock.h>
+#include <IR/Transition.h>
+#include <IR/Module.h>
+#include <IR/Type.h>
+#include <IR/LdsBuilder.h>
+#include <CodeGen/CodeGenType.h>
+#include <CodeGen/CodeGenModule.h>
+#include <CodeGen/CodeGenFunction.h>
+
+namespace aeb {
+namespace lds {
+namespace CodeGen {
+
+
+ CodeGenType::CodeGenType(CodeGenModule &CGM)
+ : m_Module(CGM), m_Context(CGM.getContext())
+ {
+ }
+
+ aeb::lds::Type *
+ CodeGenType::ConvertBuiltinType(AST::BuiltinType *BITy)
+ {
+ switch (BITy->getKind())
+ {
+ case AST::BuiltinType::Integer:
+ return aeb::lds::Type::getPrimitiveType(aeb::lds::Type::IntegerTyID);
+ case AST::BuiltinType::Boolean:
+ return aeb::lds::Type::getPrimitiveType(aeb::lds::Type::IntegerTyID);
+ case AST::BuiltinType::Char:
+ return aeb::lds::Type::getPrimitiveType(aeb::lds::Type::IntegerTyID);
+ case AST::BuiltinType::String:
+ return aeb::lds::Type::getPrimitiveType(aeb::lds::Type::ArrayTyID);
+ case AST::BuiltinType::Natural:
+ return aeb::lds::Type::getPrimitiveType(aeb::lds::Type::TimeTyID);
+ case AST::BuiltinType::Time:
+ return aeb::lds::Type::getPrimitiveType(aeb::lds::Type::TimeTyID);
+ case AST::BuiltinType::Duration:
+ return aeb::lds::Type::getPrimitiveType(aeb::lds::Type::DurationTyID);
+ case AST::BuiltinType::Pid:
+ return aeb::lds::Type::getPrimitiveType(aeb::lds::Type::PidTyID);
+ case AST::BuiltinType::Void:
+ return aeb::lds::Type::getPrimitiveType(aeb::lds::Type::VoidTyID);
+ default:
+ return aeb::lds::Type::getPrimitiveType(aeb::lds::Type::VoidTyID);
+ }
+ }
+
+ aeb::lds::Type *
+ CodeGenType::ConvertType(AST::Type *Ty)
+ {
+
+ if (Ty)
+ {
+ if (Ty->getClass() == AST::Type::Builtin)
+ {
+ AST::BuiltinType *BITy = dynamic_cast<AST::BuiltinType *>(Ty);
+ return ConvertBuiltinType(BITy);
+ }else if (Ty->getClass() == AST::Type::Typedef)
+ {
+ AST::TypedefType *TDTy = dynamic_cast<AST::TypedefType *>(Ty);
+ AST::TypedefDecl *td = static_cast<AST::TypedefDecl *>(TDTy->getDecl());
+ return ConvertType(td->getBaseType());
+ }else
+ {
+ std::cerr<<"CodeGenType::ConvertType Not builtin TODO return NULL not good"<<std::endl;
+ return NULL;
+ }
+ } else
+ {
+ std::cerr<<"CodeGenType::ConvertType Not Type return NULL not good"<<std::endl;
+ return NULL;
+ }
+ }
+
+ aeb::lds::StructType *
+ CodeGenType::addStructTypeDecl(AST::ValueTypeDecl *_decl)
+ {
+ return NULL;
+ }
+}
+}
+}
+/**
+ * ex: set et sw=4 ts=4 list:
+ */
--- /dev/null
+#include <iostream>
+#include <vector>
+#include <algorithm>
+#include <map>
+#include <string>
+#include <memory>
+#include <sstream>
+
+
+#include "AST/Stmt.h"
+#include "AST/Expr.h"
+#include "AST/Decl.h"
+
+#include "AST/DeclContext.h"
+
+
+#include <aeb/dlilist.h>
+#include <aeb/dlilist_node.h>
+#include <IR/LdsInstruction.h>
+
+
+#include <IR/BasicBlock.h>
+#include <IR/Transition.h>
+#include <IR/LdsBuilder.h>
+
+#include <IR/Module.h>
+#include <CodeGen/CodeGenType.h>
+#include "CodeGen/CodeGenModule.h"
+#include <CodeGen/CodeGenFunction.h>
+
+
+#include "CodeGen/ModuleBuilder.h"
+namespace aeb {
+ namespace lds {
+ namespace CodeGen {
+
+/**
+ *
+ *
+ */
+class CodeGeneratorImpl : public CodeGenerator {
+
+ protected:
+ CodeGenModule *m_Builder;
+ aeb::lds::Module *m_Module;
+ // unique_ptr only available in c++11
+ // std::unique_ptr<aeb::lds::Module> m_Module2;
+ public:
+ CodeGeneratorImpl(AST::ASTContext &C,const std::string &_mn) {
+ m_Module = new aeb::lds::Module(_mn);
+ m_Builder = new CodeGenModule(C,m_Module);
+ }
+
+ virtual ~CodeGeneratorImpl() {
+ delete m_Builder;
+ }
+
+ aeb::lds::Module *GetModule() {
+ return m_Module;
+ }
+ aeb::lds::CodeGen::CodeGenModule *GetBuilder() {
+ return m_Builder;
+ }
+
+ void HandleTopLevelEvents(AST::AutomatonDecl *aut) {
+ for (AST::AutomatonDecl::event_iterator it = aut->events_begin() ;
+ it != aut->events_end();
+ ++it ) {
+ // std::cout<<"Have Event: "<<(*it)->getName()<< " TODO add in module"<<std::endl;
+ // Store events in Module for Generation ....
+ m_Builder->EmitTopLevelDecl(*it);
+ }
+ }
+
+ void HandleTopLevelEvents(AST::AgentTypeDecl *aut) {
+ for (AST::AgentTypeDecl::event_iterator it = aut->events_begin() ;
+ it != aut->events_end();
+ ++it ) {
+ // std::cout<<"Have Event: "<<(*it)->getName()<< " TODO add in module"<<std::endl;
+ // Store events in Module for Generation ....
+ m_Builder->EmitTopLevelDecl(*it);
+ }
+ }
+ /**
+ *
+ */
+ void HandleTopLevelDecl(AST::Decl *_decl) {
+ AST::DeclContext *DC = dynamic_cast<AST::DeclContext *>(_decl);
+ // Get All events first
+ if (AST::AutomatonDecl *aut = dynamic_cast<AST::AutomatonDecl *>(_decl)) {
+ HandleTopLevelEvents(aut);
+ } else if (AST::AutomatonTypeDecl *autt = dynamic_cast<AST::AutomatonTypeDecl *>(_decl)) {
+ HandleTopLevelEvents(autt);
+ }
+ // Simply loop through
+ if (DC) {
+ for (AST::DeclContext::decl_iterator it = DC->begin(); it != DC->end() ; ++it ) {
+ if (! dynamic_cast<AST::EventDecl *>(*it))
+ m_Builder->EmitTopLevelDecl(*it);
+ }
+ } else {
+ std::cout<<"CodeGeneratorImpl::HandleTopLevelDecl:: WRONG Decl"<<std::endl;
+ }
+ };
+};
+
+///
+CodeGenerator *CreateLdsGenerator(AST::ASTContext &C,const std::string &_ModuleName) {
+ return new CodeGeneratorImpl(C,_ModuleName);
+}
+
+ }
+ }
+}
--- /dev/null
+#include <iostream>
+#include <algorithm>
+#include <cassert>
+#include <vector>
+#include "IR/Value.h"
+#include "IR/Type.h"
+#include "IR/Transition.h"
+#include "IR/Behavior.h"
+#include "IR/Function.h"
+#include "IR/Signal.h"
+#include "IR/Argument.h"
+#include "IR/BasicBlock.h"
+#define FUNCTION_SYMTAB
+// May be Create TraitsSigArgumentImpl.h
+#include "IR/SymbolTableTraitsImpl.h"
+#include "IR/LdsInstruction.h"
+namespace aeb {
+ // Template instantiation
+
+ typedef dlilist<lds::Argument> lst;
+
+template <>
+void SymbolTableListTraits<aeb::lds::SigArgument>::addNodeToList(aeb::lds::SigArgument *s)
+{
+ ItemParent *p = getListOwner();
+ if ( !p || s->getParent() != NULL)
+ {
+ std::cerr<<"SymbolTable::addNodeToList Big Problem Parent:";
+ }
+ else
+ {
+ s->setParent(p);
+ std::cout<<"SymbolTableListTraits Signal "<<p->getName()<<" before: "<<p->getNbParams();
+ std::cout<<" After:"<<p->getNbParams()<<std::endl;
+ }
+}
+namespace lds {
+
+ void Argument::setParent(Function *_p)
+ {
+ m_Parent = _p;
+ }
+
+ Argument::Argument(const std::string &Ty,Function *p)
+ : m_name(Ty) , m_Parent(NULL), Value(Type::getPrimitiveType(Type::VoidTyID),ArgumentVal)
+ {
+ setName(Ty);
+ if (p)
+ {
+ p->args().push_back(this);
+ }
+ }
+
+ SigArgument::SigArgument(const std::string &Ty,Signal *p)
+ : m_Parent(NULL), Value(Type::getPrimitiveType(Type::VoidTyID),ArgumentVal)
+ {
+ setName(Ty);
+ if (p)
+ {
+ p->args().push_back(this);
+ }
+ }
+
+
+}
+}
--- /dev/null
+#include <iostream>
+#include <sstream>
+#include <algorithm>
+#include <cassert>
+// #include "aeb/dlilist.h"
+// #include "aeb/dlilist_node.h"
+// #include "IR/SymbolTableTraits.h"
+#include "IR/BasicBlock.h"
+#include "IR/Transition.h"
+#include "IR/Function.h"
+#include "IR/Value.h"
+#include "IR/Argument.h"
+#include "IR/SymbolTableTraitsImpl.h"
+#include "IR/LdsInstruction.h"
+namespace aeb {
+
+template class SymbolTableListTraits<lds::Instruction>;
+namespace lds {
+
+
+
+BasicBlock::BasicBlock(const BasicBlock &p,const std::string &name , BasicBlock *parent )
+ : Value(NULL,BasicBlockVal) ,m_Name(name) ,m_Instructions() ,m_Parent(NULL)
+{
+ //m_Instructions.test();
+};
+
+BasicBlock::BasicBlock(const std::string &name,BasicBlock *parent )
+ : Value(NULL,BasicBlockVal), m_Name(name) , m_Instructions() ,m_Parent(NULL)
+{
+ //std::cout<<"Build::BB ctor"<<std::endl;
+};
+
+BasicBlock::~BasicBlock() {
+ // Should clean Instruction List
+}
+
+size_t BasicBlock::NbOpcode() const
+{
+ size_t s = 0;
+ for ( const_iterator i = begin() ; i != end() ; ++i)
+ s+= (&(*i))->NbOpcode();
+ return s;
+}
+
+size_t BasicBlock::NbOpcode(iterator ¤t) const
+{
+ size_t s = 0;
+ for ( const_iterator i = begin() ; i != current ; ++i)
+ s+= (&(*i))->NbOpcode();
+ return s;
+}
+
+
+}
+}
--- /dev/null
+PROJECT(AST)
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../include/)
+INCLUDE_DIRECTORIES(${aebutils_SOURCE_DIR})
+
+
+ADD_LIBRARY(commonIR
+ LdsInstruction.cpp
+ BasicBlock.cpp
+ Transition.cpp
+ Argument.cpp
+ GlobalVariable.cpp
+ Module.cpp
+ State.cpp
+ Value.cpp
+ Type.cpp
+ User.cpp
+ )
--- /dev/null
+#include <iostream>
+#include <algorithm>
+#include <cassert>
+#include <vector>
+#include "IR/Value.h"
+#include "IR/Type.h"
+#include "IR/Transition.h"
+#include "IR/Behavior.h"
+#include "IR/Function.h"
+#include "IR/Signal.h"
+#include "IR/Argument.h"
+#include "IR/BasicBlock.h"
+#define FUNCTION_SYMTAB
+// May be Create TraitsSigArgumentImpl.h
+#include "IR/GlobalVariable.h"
+namespace aeb {
+ // Template instantiation
+namespace lds {
+
+GlobalVariable::GlobalVariable(const std::string &flg , bool constant,Type *_Ty)
+ : m_IsConstant(constant)
+ , Constant(_Ty, GlobalVariableVal,OperandTraits<GlobalVariable>::op_begin(this),1)
+ , m_Parent(NULL)
+{
+ Value::setName(flg);
+}
+
+void
+GlobalVariable::setInitializer(Constant *InitVal)
+{
+}
+
+Constant *
+GlobalVariable::getInitializer()
+{
+ return NULL;
+}
+
+}
+}
--- /dev/null
+#include <iostream>
+#include <sstream>
+#include <algorithm>
+#include <cassert>
+#include "aeb/dlilist.h"
+#include "aeb/dlilist_node.h"
+#include "IR/LdsInstruction.h"
+#include "IR/SymbolTableTraits.h"
+#include "IR/BasicBlock.h"
+#include "IR/Type.h"
+#include "IR/Value.h"
+#include "IR/GlobalVariable.h"
+#include "IR/Function.h"
+#include "IR/Argument.h"
+#include <string.h>
+#include <CodeGen/CGDebug.h>
+//#define DEBUG_OPCODE
+//#define DEBUG_BRANCH
+namespace aeb {
+namespace lds {
+
+// Remove Instruction from BasicBlock. No delete
+void Instruction::removeFromParent()
+{
+ std::cout<<"TOBE CODED removeFromParent"<<std::endl ;
+}
+
+// Remove from Parent and erase;
+void Instruction::eraseFromParent()
+{
+ std::cout<<"TOBE CODED eraseFromParent"<<std::endl ;
+}
+
+// Insert an unlinked instruction Before I
+void Instruction::insertBefore(Instruction *I)
+{
+ std::cout<<"TOBE CODED insertBefore"<<std::endl ;
+}
+// Insert an unliked instruction After I
+void Instruction::insertAfter(Instruction *I)
+{
+ std::cout<<"TOBE CODED insertAfter"<<std::endl ;
+}
+
+/**============================================================================
+ * BranchInst Implementation ....
+ */
+BranchInst::BranchInst(unsigned int op,BasicBlock *IfTrue
+ ,BasicBlock *IfFalse )
+ : TerminatorInst(op, OperandTraits<BranchInst>::op_end(this) - 2 ,2)
+{
+#ifdef DEBUG_BRANCH
+ std::cout<<"BranchInst::BranchInst "<<getNumOperands()<<std::endl;
+#endif
+ m_Block[BTRUE] = IfTrue;
+ m_Block[BFALSE] = IfFalse;
+ Op<0>() = IfTrue;
+ if (IfFalse)
+ {
+#ifdef DEBUG_BRANCH
+ std::cout<<"\tBranchInst::BranchInst "<<&Op<-1>()<<std::endl;
+#endif
+ Op<-1>() = IfFalse;
+ }
+ setName("Br");
+}
+
+/**
+ * Too complicated think about something better
+ */
+int BranchInst::ThenLength()
+{
+ int length = 0;
+ aeb::lds::BasicBlock *b = NULL ,*pB=getParent();
+ if (getParent() && getTrue())
+ {
+ if ( ( (b = getParent()->getNextNode()) == getTrue()) && ! getFalse())
+ {
+#ifdef DEBUG_BRANCH
+ std::cout<<"BranchInst ThenLength parent == m_Block[BTRUE]"<<" "<<std::endl;
+#endif
+ length = b->size();
+ } else if ((pB->getParent() != getTrue()->getParent() )
+ || (getTrue()->getParent() == NULL)
+ )
+ {
+#ifdef DEBUG_BRANCH
+ std::cout<<"BranchInst::ThenLength Instruction ERROR and dest not in same function "<<" "<<pB->getParent()<<std::endl;
+#endif
+ b = pB->getNextNode();
+ while ( (b != getTrue()) && b!=NULL)
+ {
+ length += b->NbOpcode();
+ b = b->getNextNode();
+ }
+ length--;
+ } else {
+ int countb = 0;
+ b = pB->getNextNode();
+ while ( (b != getTrue()) && b!=NULL) {
+ length += b->NbOpcode();
+ b = b->getNextNode();
+ countb++;
+ }
+#ifdef DEBUG_BRANCH
+ std::cout<<"BranchInst::ThenLength parent->next != getTrue()"<<" b="<<b<<" length = "<<length;
+ std::cout<<" Countb = "<<countb<<std::endl;
+#endif
+ if ( (b == NULL) ) {
+ BasicBlock::iterator it(this);
+ length = pB->NbOpcode(it) + this->NbOpcode();
+ CGDBG_ARGS("BranchInst ERROR Find Destination node backwords length=%d",length);
+ b = pB->getPrevNode();
+ while ( (b != getTrue()) && b!=NULL) {
+ length += b->NbOpcode();
+ b = b->getPrevNode();
+ }
+ if (b)
+ {
+ length += b->NbOpcode();
+ setOpcode(AEL_JUMP_MOINSOpcode);
+ }
+ } else if ((b == NULL) && length) {
+ length--;
+ }
+ }
+ }
+#ifdef DEBUG_BRANCH
+ std::cout<<"BranchInst::ThenLength before exit "<<" length="<<length<<std::endl;
+#endif
+ return length;
+}
+
+/**
+ *
+ */
+const char *BranchInst::getOpcodeName()
+{
+ static std::string s;
+ std::ostringstream oss;
+ int l = ThenLength();
+ oss.str("");
+ std::string res = Instruction::getOpcodeName();
+ //std::cerr<<"BranchInst::getOpcodeName "<<res<<std::endl;
+ if (getTrue() ) {
+ oss<<res<<" , "<<l;
+#ifdef DEBUG_OPCODE
+ oss<<" /* ("<<getTrue()->getName();
+ oss<<" ) True Direct Branch ";
+ oss<<" */";
+#endif
+ } else {
+ oss<<res<<" /* BIG Problem */";
+ }
+ //std::cerr<<"BranchInst::getOpcodeName Result "<<oss.str().c_str()<<std::endl;
+ s = oss.str();
+ return s.c_str();
+}
+
+/**
+ *
+ */
+size_t BranchInst::NbOpcode() const
+{
+ if (isUnConditional( ) && (getParent()->getNextNode() == getTrue() ))
+ {
+ return 0;
+ } else {
+ return 2;
+ }
+}
+
+/**============================================================================
+ * BranchCondInst Implementation
+ */
+int BranchCondInst::ThenLength()
+{
+ int length = 0;
+ aeb::lds::BasicBlock *b = NULL ,*pB=getParent();
+ if (getParent() && getTrue())
+ {
+ if ( ( (b = getParent()->getNextNode()) == getTrue())
+ && ! getFalse())
+ {
+#ifdef DEBUG_BRANCH
+ std::cout<<"BranchCondInst ThenLength parent->next == m_Block[BTRUE]"<<" length="<<b->size()<<std::endl;
+#endif
+ length = b->size();
+ } else if ((pB->getParent() != getFalse()->getParent() )
+ || (getFalse()->getParent() == NULL)
+ )
+ {
+#ifdef DEBUG_BRANCH
+ std::cout<<"BranchCondInst::ThenLength Instruction ERROR and dest not in same function "<<" "<<pB->getParent()<<std::endl;
+#endif
+ b = getTrue();
+ while ( (b) && (b != getFalse()))
+ {
+ length += b->NbOpcode();
+ b = b->getNextNode();
+ }
+ length--;
+ }
+ else
+ {
+ b = getTrue();
+ while ( (b) && (b != getFalse()))
+ {
+ length += b->NbOpcode();
+ b = b->getNextNode();
+ }
+#ifdef DEBUG_BRANCH
+ std::cout<<"BranchCondInst ThenLength parent->next != m_Block[BTRUE]"<<" len="<<length<<std::endl;
+#endif
+ }
+ }
+ return length;
+}
+
+
+const char *BranchCondInst::getOpcodeName()
+{
+ static std::string s;
+ std::ostringstream oss;
+ std::string res = Instruction::getOpcodeName();
+ int l = ThenLength();
+ oss.str("");
+ if (getFalse() )
+ {
+ oss<<res<<" , "<<l;
+#ifdef DEBUG_OPCODE
+ oss<<" /* ("<<getFalse()->getName();
+ oss<<" ) false Cond Branch getTrue = ";
+ oss<<getTrue()->getName()<<" */";
+#endif
+ } else {
+ oss<<res<<" // BIG Problem";
+ }
+ // std::cout<<"BranchCondInst::getOpcodeName Result "<<oss.str().c_str()<<std::endl;
+ s = oss.str();
+ return s.c_str();
+}
+
+/**============================================================================
+ * BranchSubroutine Implemetation
+ */
+const char *BranchSubroutine::getOpcodeName()
+{
+ std::ostringstream oss;
+ static std::string s;
+ oss.str("");
+ std::string res = Instruction::getOpcodeName();
+ oss<<res<<","<<m_Fct;
+ s = oss.str();
+ return s.c_str();
+}
+
+/**============================================================================
+ * SwitchInst
+ */
+int SwitchInst::ThenLength()
+{
+ int length = 0;
+ aeb::lds::BasicBlock *b = NULL ,*p=getParent();
+ if (getParent() && getHash())
+ {
+ if ( (b = getParent()->getNextNode()) == getHash() ) {
+ length = b->size();
+ } else {
+ b = p->getNextNode();
+ while ( (b != getHash()) && b!=NULL) {
+ length += b->NbOpcode();
+ b = b->getNextNode();
+ }
+ if (b == NULL) {
+ BasicBlock::iterator it(this);
+ length = p->NbOpcode(it) + this->NbOpcode();
+#ifdef DEBUG_BRANCH
+ std::cout<<"SwitchInst::TheLength ERROR Find Destination node backwords length="<<length<<std::endl;
+#endif
+ b = p->getPrevNode();
+ while ( (b != getHash()) && b!=NULL) {
+ length += b->NbOpcode();
+ b = b->getPrevNode();
+ }
+ if (b)
+ length += b->NbOpcode();
+ if (b)
+ setOpcode(AEL_JUMP_MOINSOpcode);
+ }
+ }
+ }
+
+ return length;
+}
+
+const char *SwitchInst::getOpcodeName()
+{
+ std::ostringstream oss;
+ std::string res = Instruction::getOpcodeName();
+ static std::string s;
+ //std::cerr<<"SwitchInst::getOpcodeName "<<res<<std::endl;
+ int l = ThenLength();
+ oss.str("");
+ if ( m_HashBlock) {
+ oss<<res<<" , "<<l<<", "<<m_Cond->getName();//<<" /* ("<<m_HashBlock->getName()<<" ) */";
+ } else {
+ oss<<res<<" // BIG Problem";
+ }
+ //std::cout<<"SwitchInst::getOpcodeName Result "<<oss.str().c_str()<<std::endl;
+ s = oss.str();
+ return s.c_str();
+}
+
+/**============================================================================
+ * LoadInst
+ */
+LoadInst::LoadInst(unsigned int op,const std::string &Flg,bool _co)
+ : Instruction(op) , m_Constant(_co) , m_Value(NULL) ,m_Flag(Flg)
+{
+ //std::cout<<"CreateLoadInst "<<Flg<<std::endl;
+ setName(Flg);
+}
+
+LoadInst::LoadInst(unsigned int op,Value *v)
+ : Instruction(op), m_Value(v)
+{
+ m_Flag = v->getName();
+ //std::cout<<"CreateLoadInst From Value :"<<m_Flag<<std::endl;
+ setName(m_Flag);
+ if (v->isGlobalVariable())
+ {
+ const aeb::lds::GlobalVariable *gv = dynamic_cast<const aeb::lds::GlobalVariable *>(v);
+ if (gv)
+ m_Constant = gv->isConstant();
+ }
+}
+
+const char *LoadInst::getOpcodeName()
+{
+ static std::string s;
+ s = "";
+ if (m_Value)
+ {
+ // Most likely an Argument
+ if (m_Value->isGlobalVariable())
+ {
+ s+= "LOADV("+m_Flag+")";
+ } else
+ {
+ aeb::lds::Argument *arg = dynamic_cast<aeb::lds::Argument *>(m_Value);
+ aeb::lds::Function *fct= arg->getParent();
+ if (fct)
+ {
+ int d = std::distance(fct->arg_begin()
+ ,aeb::lds::Function::ArgumentIterator(arg));
+ std::ostringstream os;
+ os.str("");
+ os<<"LOADP("<<d+1<<","<<m_Flag<<")";
+ s+=os.str();
+ } else
+ {
+ s+= "LOADP(1,"+m_Flag+") /* Bug*/";
+ }
+ };
+ } else
+ {
+ if ( m_Constant)
+ {
+ s+= "LOADK("+m_Flag+")";
+ } else
+ {
+ s = Instruction::getOpcodeName(m_Opcode) ;
+ s+= " ," ; s+=m_Flag ;
+ }
+ }
+ return s.c_str();
+}
+
+/**============================================================================
+ * StoreInst
+ */
+
+StoreInst::StoreInst(unsigned int op,Value *v)
+ : Instruction(op),m_Value(v)
+{
+}
+
+const char *StoreInst::getOpcodeName()
+{
+ static std::string s;
+ if (m_Value)
+ {
+ s = "STORE_V("+m_Value->getName()+")";
+ } else
+ {
+ s = Instruction::getOpcodeName(m_Opcode) ;
+ s+= " ," ; s+=m_Flag ;
+ }
+ return s.c_str();
+}
+
+
+/**============================================================================
+ * CallInst
+ */
+const char *CallInst::getOpcodeName()
+{
+ int i = 1;
+ std::stringstream si;
+ std::string s("e"); // See gen_aac why. It's linked to External function defines
+ s += m_callee.c_str();
+ for ( std::vector<Value *>::iterator it = m_Params.begin()
+ ; it != m_Params.end(); ++it)
+ {
+ s+= " , ";
+ si.str("");
+ si<<i; i++;
+ if ((*it)->isArgument())
+ {
+ s+= "CALL_PARAM_PV("+si.str()+","+(*it)->getName()+")";
+ } else if ((*it)->isGlobalVariable())
+ {
+ s+= "CALL_PARAM_GV("+si.str()+","+(*it)->getName()+")";
+ } else {
+ s+= "CALL_PARAM_LV("+si.str()+","+(*it)->getName()+")";
+ }
+ }
+ m_ret = s;
+ return m_ret.c_str();
+}
+
+/**============================================================================
+ * SendEvenyInst implementation
+ **/
+const char *
+SendEventInst::getOpcodeName()
+{
+ static std::string s;
+ int i = 1;
+ std::stringstream si;
+ s = Instruction::getOpcodeName(m_Opcode) ;
+ s+= " ," ; s+=m_Event;
+
+ for ( std::vector<Value *>::iterator it = m_Params.begin()
+ ; it != m_Params.end()
+ ; ++it,i++)
+ {
+ s+= " , ";
+ si.str("");
+ si<<i;
+ if ((*it)->isArgument())
+ {
+ s+= "CALL_PARAM_PV("+si.str()+","+(*it)->getName()+")";
+ } else if ((*it)->isGlobalVariable())
+ {
+ s+= "CALL_PARAM_GV("+si.str()+","+(*it)->getName()+")";
+ } else {
+ s+= "CALL_PARAM_LV("+si.str()+","+(*it)->getName()+")";
+ }
+ }
+ return s.c_str();
+};
+
+/**============================================================================
+ * ExtractValueInst implementation
+ **/
+ExtractValueInst::ExtractValueInst(Value *v,int idx)
+ : Instruction(AEL_EXTRACTOpcode), m_Value(v),m_Index(idx)
+{
+ std::cout<<"ExtractValue:: got v="<<v->getName()<<std::endl;
+}
+
+const char *ExtractValueInst::getOpcodeName()
+{
+ std::stringstream si;
+ static std::string s;
+ si.str("");
+ // Should be Type in index
+ si<<m_Value->getName()<<","<<m_Index;
+ s= "EXTRACT("+si.str()+")";
+ return s.c_str();
+}
+
+/**============================================================================
+ * Compare Instruction Implementation
+ */
+CmpInst::CmpInst(unsigned int op,const std::string &s,bool lc) : m_Flag(s)
+ , m_LoadConstant(lc)
+ , Instruction(op)
+ , m_Value(NULL)
+{
+}
+
+CmpInst::CmpInst(unsigned int op,Value *v,const std::string &s,bool lc) : m_Flag(v->getName())
+ , m_CmpInst(s)
+ , m_LoadConstant(lc)
+ , Instruction(op)
+ , m_Value(v)
+{
+}
+
+const char *CmpInst::getOpcodeName()
+{
+ static std::string s;
+ if (m_Value)
+ {
+ s = "CMP_"+m_CmpInst+"("+m_Flag+")";
+ } else
+ {
+ s = Instruction::getOpcodeName(m_Opcode) ;
+ s+= " ," ; s+=m_Flag;
+ }
+ return s.c_str();
+}
+
+/**============================================================================
+ * Binary Operation Generation
+ */
+BinaryOperator::BinaryOperator(unsigned int op,Value *V1,Value *V2,BasicBlock *insertAf )
+ : Instruction(op),m_V1(V1),m_V2(V2)
+{
+ if (m_V1)
+ {
+ }
+ if (m_V2)
+ {
+ }
+}
+///
+const char *BinaryOperator::getOpcodeName()
+{
+ static std::string s;
+ s = Instruction::getOpcodeName(m_Opcode) ;
+ /// FLAG_GLOBAL Depends on Order. Might work well with and and or
+ if (! m_V1)
+ {
+ s+= " ,FLAG_GLOBAL ," ; s+=m_Flag ;
+ } else
+ {
+ s+= " , "+m_V1->getName()+",FLAG_GLOBAL " ;
+ }
+ if (m_V1)
+ m_V1->getName();
+ std::cout<<"BinaryOperator::getOpcodeName "<<Instruction::getOpcodeName(m_Opcode);
+ if (m_V1)
+ std::cout<<" LHS="<<m_V1->getName()<<" ";
+ if (m_V2)
+ std::cout<<" RHS="<<m_V2->getName()<<" ";
+ std::cout<<"\n";
+ return s.c_str();
+}
+
+}
+}
+/**
+ * ex: sw=2 et list:
+ */
+
--- /dev/null
+#include <iostream>
+#include <cassert>
+#include <algorithm>
+
+namespace aeb {
+ namespace lds {
+ class Instruction;
+ class Transition;
+ class Function;
+ }
+};
+#include "IR/BasicBlock.h"
+#include "IR/Transition.h"
+#include "IR/Argument.h"
+#include "IR/Function.h"
+#include "IR/SymbolTableTraitsImpl.h"
+#include "IR/Module.h"
+
+namespace aeb {
+// template class SymbolTableTraits<lds::GlobalVariable,lds::Module>;
+template class SymbolTableListTraits<lds::GlobalVariable>;
+template class SymbolTableListTraits<lds::Signal>;
+
+namespace lds {
+
+
+ Module::Module(const std::string &s) : m_Name(s)
+ {
+ }
+
+ Module::~Module()
+ {
+ // May be try to loop over all States and erase them
+ std::cout<<"Module::~Module"<<std::endl;
+ }
+
+ //
+ Function *
+ Module::getOrInsertFunction(const std::string &_name,Function *f,Function::FctType fct) {
+ Function *_f = f;
+ if ( !_f )
+ {
+ function_iterator it = std::find(function_begin(),function_end(),_name);
+ if (it == function_end() )
+ {
+ // std::cout<<"Module::getOrInsert function Create "<<_name<<std::endl;
+ _f = Function::Create(_name,fct);
+ } else {
+ // std::cout<<"Module::getOrInsert function found "<<_name<<std::endl;
+ return &*it;
+ }
+ }
+ if (_f) {
+ //std::cout<<"Module::getOrInsert add function into m_Functions : "<<_name<<std::endl;
+ //m_Functions.insert(m_Functions.end(),_f);
+ m_Functions.push_back(_f);
+ }
+ return _f;
+ }
+ //
+ State *
+ Module::getOrInsertState(const std::string &_name,State *s)
+ {
+ m_States.insert(m_States.end(),s);
+ return s;
+ }
+ //
+ Signal *
+ Module::getOrInsertSignal(const std::string &_name)
+ {
+ Signal *e = NULL;
+
+ //std::cout<<"Module::getOrInsert Signal : "<<_name<<std::endl;
+ signal_iterator it = std::find(signal_begin(),signal_end(),_name);
+ if (it == signal_end())
+ {
+ e = Signal::Create(_name);
+ m_Signals.push_back(e);
+ } else
+ { // Event already in list
+ e = &*it;
+ return e;
+ }
+ return e;
+ }
+ //
+ Function *
+ Module::getFunction(const std::string &_name)
+ {
+ function_iterator it = std::find(function_begin(),function_end(),_name);
+ if (it == function_end() )
+ {
+ // std::cout<<"Module::getOrInsert function Create "<<_name<<std::endl;
+ return NULL;
+ } else {
+ // std::cout<<"Module::getOrInsert function found "<<_name<<std::endl;
+ return &*it;
+ }
+ }
+
+ //
+ State *Module::getState(const std::string &_name)
+ {
+ return NULL;
+ }
+ const Module::GlobalListType &Module::getGlobalList() const
+ {
+ return m_Globals;
+ }
+ const Module::FunctionListType &Module::getFunctionList() const
+ {
+ return m_Functions;
+ }
+
+ //
+ GlobalVariable *Module::getGlobal(const std::string &_name)
+ {
+ global_iterator it = std::find(global_begin(),global_end(),_name);
+ if (it == global_end() ) {
+ return NULL;
+ }
+ return &(*it);
+ }
+
+ void Module::insertGlobal(GlobalVariable *g)
+ {
+ // Check If global name is already there
+ global_iterator it = std::find(global_begin(),global_end(),g->getName());
+ // if not, insert
+ }
+
+ // Simple Function when GlobalVariable is just a Flag
+ GlobalVariable *Module::insertGlobal(const std::string &_flag,bool constant,Type *_Ty)
+ {
+ global_iterator it = std::find(global_begin(),global_end(),_flag);
+ if (it == global_end() ) {
+ GlobalVariable *GV = new GlobalVariable(_flag,constant,_Ty);
+ m_Globals.insert(m_Globals.end(),GV);
+ return GV;
+ } else {
+ return &(*it);
+ }
+ }
+
+}
+}
--- /dev/null
+#include <iostream>
+#include <cassert>
+
+#include "IR/State.h"
+#include "IR/Signal.h"
+#include "IR/Transition.h"
+#include "IR/SymbolTableTraitsImpl.h"
+#include "IR/LdsInstruction.h"
+
+namespace aeb {
+
+ // Template instantiation
+
+template class SymbolTableListTraits<lds::Transition>;
+
+namespace lds {
+
+
+ Transition *State::getOrInsertTransition(const std::string &_name,Transition *t)
+ {
+ m_Transitions.insert(m_Transitions.end(),t);
+ return t;
+ }
+
+ void State::insertTransition(Transition *t,Signal *_evt,Function *fct,const std::string &_st)
+ {
+ t->setTargetState(_st);
+ t->setEvent(_evt);
+ t->setFunction(fct);
+ m_Transitions.insert(m_Transitions.end(),t);
+ }
+
+}
+}
--- /dev/null
+#include <iostream>
+#include <algorithm>
+#include <cassert>
+#include "IR/Transition.h"
+#include "IR/Behavior.h"
+#include "IR/Function.h"
+#include "IR/Argument.h"
+#include "IR/State.h"
+#include "IR/Signal.h"
+#include "IR/Type.h"
+#include "IR/Value.h"
+#include "IR/SymbolTableTraitsImpl.h"
+#include "IR/LdsInstruction.h"
+namespace aeb {
+ // Template instantiation
+
+ //template class SymbolTableTraits<lds::BasicBlock,lds::Transition>;
+
+ // template class SymbolTableTraits<lds::BasicBlock,lds::Behavior>;
+
+ typedef dlilist<lds::BasicBlock> lst;
+ lst tb;
+namespace lds {
+
+
+Behavior::Behavior(const Behavior &p )
+ : m_Name(p.m_Name) ,Value(p)
+{
+// std::cout<<"Behavior:: copy "<<m_Name<<std::endl;
+};
+
+Behavior::Behavior(const std::string &name ,Type *Ty,unsigned tid)
+ : Value(Ty,tid) ,m_Name(name) ,m_Blocks()
+{
+ setName(name);
+// std::cout<<"Behavior::Behavior "<<m_Name<<std::endl;
+};
+
+Behavior::~Behavior() {
+ // std::cout<<"Behavior::~Transtion "<<getName()<<std::endl;
+}
+
+
+/////
+
+Transition::Transition(const Transition &p ) : m_Parent(NULL) {
+};
+
+Transition::Transition(const std::string &name,State *parent )
+ :
+ //Behaviour (name,NULL,Value::TransitionVal)
+ m_Parent(NULL)
+{
+};
+
+Transition::~Transition() {
+ // std::cout<<"Transition::~Transtion "<<getName()<<std::endl;
+}
+
+std::string Transition::getTargetState() const
+{
+ if ( ! m_TargetState.compare("same") )
+ {
+ return m_Parent->getName();
+ } else
+ return m_TargetState ; };
+
+
+const std::string &Transition::getEvent() const
+{
+ return m_Event->getName();
+}
+
+
+Function::Function(const std::string &s,FctType fc)
+ : Behavior(s,NULL,Value::FunctionVal)
+ , m_Parent(NULL)
+ , m_FctType(fc)
+ , m_NbParam(0)
+{
+}
+
+
+Signal::Signal(const std::string &s,FctType fc)
+ : Behavior(s,NULL,Value::SignalVal)
+ , m_Parent(NULL)
+ , m_FctType(fc)
+ , m_NbParam(0)
+{
+}
+
+}
+}
--- /dev/null
+#include <iostream>
+#include <cassert>
+#include <vector>
+#include "IR/Type.h"
+
+namespace aeb
+{
+namespace lds
+{
+
+Type::Type(TypeID tid)
+ : m_TypeID(tid) , m_ContainedTypes(NULL), m_NbContainedTys(0)
+{
+}
+
+Type *
+Type::getPrimitiveType(TypeID tid)
+{
+ static Type VoidTy(VoidTyID);
+ static Type FloatTy(FloatTyID);
+ static Type LabelTy(LabelTyID);
+ static Type PidTy(PidTyID);
+ // Derived static Type (ID);'s
+ static Type IntegerTy(IntegerTyID);
+ static Type NaturalTy(NaturalTyID);
+ static Type TimeTy(TimeTyID);
+ static Type DurationTy(DurationTyID);
+ static Type FunctionTy(FunctionTyID);
+ static Type ArrayTy(ArrayTyID);
+ static Type PointerTy(PointerTyID);
+
+ switch (tid)
+ {
+ case FloatTyID: return &FloatTy;
+ case LabelTyID: return &LabelTy;
+ case PidTyID: return &PidTy;
+ // Derived case ID: return &;'s
+ case IntegerTyID: return &IntegerTy;
+ case NaturalTyID: return &NaturalTy;
+ case TimeTyID: return &TimeTy;
+ case DurationTyID: return &DurationTy;
+ case FunctionTyID: return &FunctionTy;
+ case ArrayTyID: return &ArrayTy;
+ case PointerTyID: return &PointerTy;
+ default:
+ return &VoidTy;
+ };
+}
+
+void Type::print(std::ostream &os) const
+{
+ switch (m_TypeID)
+ {
+ case FloatTyID: os<<"double "; break;
+ case LabelTyID: os<<"LabelTy "; break;
+ case PidTyID: os<<"Pid "; break;
+ // Derived case ID: os<<""; break;'s
+ case IntegerTyID: os<<"long "; break;
+ case NaturalTyID: os<<"double "; break;
+ case TimeTyID: os<<"Time "; break;
+ case DurationTyID: os<<"Duration"; break;
+ case FunctionTyID: os<<"Function"; break;
+ case ArrayTyID: os<<"char * "; break;
+ case PointerTyID: os<<"void * "; break;
+ default:
+ os<<"void ";
+ };
+}
+
+void Type::printNative(std::ostream &os) const
+{
+ switch (m_TypeID)
+ {
+ case FloatTyID: os<<"double "; break;
+ case LabelTyID: os<<"LabelTy "; break;
+ case PidTyID: os<<"Pid "; break;
+ // Derived case ID: os<<""; break;'s
+ case IntegerTyID: os<<"long "; break;
+ case NaturalTyID: os<<"double "; break;
+ case TimeTyID: os<<"Time "; break;
+ case DurationTyID: os<<"Duration"; break;
+ case FunctionTyID: os<<"Function"; break;
+ case ArrayTyID: os<<"char * "; break;
+ case PointerTyID: os<<"void * "; break;
+ default:
+ os<<"void ";
+ };
+}
+
+void Type::printLds(std::ostream &os) const
+{
+ switch (m_TypeID)
+ {
+ case FloatTyID: os<<"Float "; break;
+ case LabelTyID: os<<"LabelTy "; break;
+ case PidTyID: os<<"Integer "; break;
+ // Derived case ID: os<<""; break;'s
+ case IntegerTyID: os<<"Integer "; break;
+ case NaturalTyID: os<<"Integer "; break;
+ case TimeTyID: os<<"Time "; break;
+ case DurationTyID: os<<"Duration"; break;
+ case FunctionTyID: os<<"Function"; break;
+ case ArrayTyID: os<<"String "; break;
+ case PointerTyID: os<<"User "; break;
+ default:
+ os<<"Integer ";
+ };
+}
+
+
+const Type *
+CompositeType::getTypeAtIndex(unsigned i) const
+{
+ assert( i < m_NbContainedTys && "out of range !");
+ if (m_ContainedTypes && (i < m_NbContainedTys))
+ {
+ return &m_ContainedTypes[i];
+ }
+
+}
+
+}
+}
+/**
+ * ex: set et sw=4 ts=4 list:
+ */
--- /dev/null
+#include <iostream>
+#include <string.h>
+#include <IR/User.h>
+
+
+namespace aeb {
+namespace lds {
+
+
+/// new operator
+void *
+User::operator new(size_t s, unsigned Us)
+{
+ //std::cout<<"User::new s="<<s<<" Us="<<Us<<"sizeof(Use)="<<sizeof(Use)<<std::endl;
+ void *Storage = ::operator new(s+sizeof(Use)*Us);
+ Use *Start = static_cast<Use*>(Storage);
+ Use *End = Start+Us;
+ User *Obj = reinterpret_cast<User*>(End);
+ Obj->m_Operands =Start;
+ Obj->m_NumOperands=Us;
+ // Only initialize Use's
+ if(Us)
+ memset(Start,0x00,sizeof(Use)*Us);
+ //std::cout<<"\tUser::new return Storage="<<Storage<<" Obj="<<Obj<<std::endl;
+ return Obj;
+}
+
+void User::operator delete(void *Usr)
+{
+ User *Start = static_cast<User*>(Usr);
+ Use *Storage = static_cast<Use*>(Usr) - Start->m_NumOperands;
+ //std::cout<<"User::delete "<<Storage<<" NbOp="<<Start->m_NumOperands<<std::endl;
+ // If there were hung-off uses, they will have been freed already and
+ // NumOperands reset to 0, so here we just free the User itself.
+ ::operator delete(Storage);
+}
+ //
+
+/* End namespace */
+}
+}
--- /dev/null
+#include <iostream>
+#include <string>
+#include <cassert>
+#include <vector>
+
+#include "IR/Value.h"
+#include "IR/Type.h"
+
+
+namespace aeb {
+namespace lds {
+
+Value::Value(Type *_Ty,unsigned vid)
+ : m_UseList(NULL),m_Name(""), m_VTy(_Ty), m_SubClassID(vid)
+{
+}
+
+
+#if 0
+Type *
+Value::getType() { return m_VTy; };
+#endif
+
+void
+Value::setName(const std::string &_n)
+{
+// std::cout<<"Value::setName( "<<_n<<")"<<std::endl;
+ m_Name = _n;
+}
+
+const std::string &
+Value::getName() const
+{
+ return m_Name;
+}
+
+
+
+}
+}
--- /dev/null
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <ostream>
+#include <set>
+#include <vector>
+#include <map>
+#include <algorithm>
+
+
+#include "AST/Stmt.h"
+#include "AST/Expr.h"
+#include "AST/Decl.h"
+
+#include "AST/ASTRecursiveVisitor.h"
+#include "IR/Module.h"
+
+
+#include <aeb/dlilist.h>
+#include <aeb/dlilist_node.h>
+#include <IR/LdsInstruction.h>
+#include <IR/LdsInstrVisitor.h>
+#include <IR/Transition.h>
+#include <IR/BasicBlock.h>
+#include <IR/LdsBuilder.h>
+#include <CodeGen/CodeGenType.h>
+#include <CodeGen/CodeGenModule.h>
+#include <CodeGen/CodeGenFunction.h>
+#include <CodeGen/ModuleBuilder.h>
+
+
+#include "LDSBytecode/AutomatonBytecode.h"
+
+/**
+ * First Traversal to calculate sizes entry points and
+ * so on.
+ */
+struct BStatistics : public aeb::lds::InstrVisitor<BStatistics>
+{
+ unsigned int m_Transitions;
+ unsigned int m_States;
+ unsigned int m_NbI,m_NbIl;
+ unsigned int m_NbGlobals;
+ unsigned int m_NbCFunction;
+ unsigned int m_NbLdsFunction;
+ unsigned int m_NbSignals;
+ unsigned int m_ConstantCounter;
+
+ typedef std::map<std::string,int> ConstantMap;
+ typedef ConstantMap::iterator constant_iterator;
+ ConstantMap m_Constants;
+
+ BStatistics() : m_Transitions(0)
+ , m_States(0)
+ , m_NbI(0)
+ , m_NbIl(0)
+ , m_NbCFunction(0)
+ , m_NbLdsFunction(0)
+ , m_NbSignals(0)
+ , m_ConstantCounter(0)
+ , m_NbGlobals(0) {}
+
+ int getConstantIndex(const std::string &s)
+ {
+ constant_iterator it = m_Constants.find(s);
+ if (it != m_Constants.end())
+ {
+ return it->second;
+ } else
+ {
+ return 0;
+ }
+ }
+ void visitTransition(aeb::lds::Transition &T)
+ {
+ aeb::lds::Function *f = T.getFunction();
+ std::cout<<"TRAN "<<T.getEvent()<<" -> "<<T.getTargetState();
+ if ( f != NULL)
+ {
+ std::cout<<"0 AEL_CALL ("<<f->getName()<<")"<<std::endl;
+ } else
+ {
+ std::cout<<std::endl;
+ }
+ m_Transitions++;
+ };
+ void visitSignal(aeb::lds::Signal &T)
+ {
+ m_NbSignals++;
+ m_ConstantCounter++;
+ }
+ void visitState(aeb::lds::State &T)
+ {
+ std::cout<<"STATE "<<T.getName()<<std::endl;
+ m_Constants[T.getName()] = m_ConstantCounter;
+ m_States++;
+ m_ConstantCounter++;
+ };
+ void visitGlobalVariable(aeb::lds::GlobalVariable &T)
+ {
+ std::cout<<"GLOBAL "<<T.getName()<<" ("<<m_ConstantCounter<<")"<<std::endl;
+ m_Constants[T.getName()] = m_ConstantCounter;
+ m_NbGlobals++;
+ m_ConstantCounter++;
+
+ };
+
+ void visitFunction(aeb::lds::Function &F)
+ {
+ std::cout<<"FUNCTION "<<(F.isExternal()?" AEL ":" LDS ")<<F.getName();
+ std::cout<<" P="<<F.getNbParams()<<" ("<<m_ConstantCounter<<")"<<std::endl;
+ m_Constants[F.getName()] = m_ConstantCounter;
+
+ m_ConstantCounter++;
+
+ if(F.isExternal())
+ {
+ m_NbCFunction++;
+ }
+ else
+ m_NbLdsFunction++;
+
+ m_NbIl = 0;
+ };
+
+ void visitInstruction(aeb::lds::Instruction &I)
+ {
+ std::cout<<m_NbIl<<"\t"<<I.getOpcodeName();
+ std::cout<<std::endl;
+ m_NbI+=I.NbOpcode();
+ m_NbIl+=I.NbOpcode();
+ }
+
+ void visitAEL_JUMP_PLUS(aeb::lds::BranchInst &I)
+ {
+ if (I.NbOpcode())
+ {
+ std::cout<<m_NbIl<<"\t"<<I.getOpcodeName();
+ std::cout<<std::endl;
+ m_NbI+=I.NbOpcode();
+ m_NbIl+=I.NbOpcode();
+ }
+ }
+
+ void visitAEL_CALL(aeb::lds::CallInst &I)
+ {
+ int fi = getConstantIndex(I.getCallee());
+ std::cout<<m_NbIl<<"\t"<<I.getOpcodeString()<<"( ";
+ std::cout<<I.getCallee()<<"<"<<fi<<"> ";
+ for ( int i = 0 ; i < I.getNbParameters() ; ++i)
+ {
+ aeb::lds::Value *param = I.getParameter(i);
+ int ci = getConstantIndex(param->getName());
+ std::cout<<param<<" <"<<ci<<"> ";
+ }
+ std::cout<<")"<<std::endl;
+ m_NbI+=I.NbOpcode();
+ m_NbIl+=I.NbOpcode();
+ }
+
+ friend std::ostream &operator <<(std::ostream &os,BStatistics &s) {
+ os<<"\tNb States : "<<s.m_States<<std::endl;
+ os<<"\tNb Signals : "<<s.m_NbSignals<<std::endl;
+ os<<"\tNb Transition : "<<s.m_Transitions<<std::endl;
+ os<<"\tNb Globals : "<<s.m_NbGlobals<<std::endl;
+ os<<"\tNb CFunction : "<<s.m_NbCFunction<<std::endl;
+ os<<"\tNb LdsFunction : "<<s.m_NbLdsFunction<<std::endl;
+ os<<"\tNb Instructions : "<<s.m_NbI<<std::endl;
+ os<<"\tNb Constants : "<<s.m_ConstantCounter<<std::endl;
+ return os;
+ }
+};
+
+namespace lds
+{
+
+AutomatonBytecode::AutomatonBytecode(std::ostream &os)
+ : m_ostream(os)
+{
+}
+
+AutomatonBytecode::~AutomatonBytecode()
+{
+}
+
+/**
+ * Try to build an organized structure that represents the automaton
+ *
+ * -> General header
+ * -> Constants .... string, ints
+ * -> Signals that can be triggered
+ * -> States (Should be represented as an object )
+ * (contains an array of functions each event for a transition
+ * is a function entry point
+ * therefore, two or more function can point the same code.
+ * see how to implement this
+ * )
+ * -> LDS Task Is a Function as well
+ * -> External Function table / To be filled when loading ...
+ * -> What about global variables ?
+ *
+ */
+void
+AutomatonBytecode::Generate(aeb::lds::Module &m_Module)
+{
+ BStatistics stat;
+ stat.visit(&m_Module);
+
+ std::cout<<" BStatistics :"<<std::endl;
+ std::cout<<stat<<std::endl;
+}
+
+
+void
+AutomatonBytecode::Generate(AST::TranslationUnitDecl *DC)
+{
+
+ for (AST::DeclContext::decl_iterator it = DC->begin()
+ ; it !=DC->end(); ++it)
+ {
+ AST::AutomatonDecl *automat = dynamic_cast<AST::AutomatonDecl *>(*it);
+ if (automat)
+ {
+ BStatistics stat;
+ aeb::lds::CodeGen::CodeGenerator *CG =
+ aeb::lds::CodeGen::CreateLdsGenerator(DC->getASTContext(),automat->getName());
+
+ std::cout<<"gen_code: process: "<<automat->getName()<<std::endl;
+ CG->HandleTopLevelDecl(automat);
+ // Something Like, CG->GetModule, AACGenerator act( stream,Module)
+ //act.generate
+ // Or bc BCGenerator(stream,Module)
+ // bc.save
+ aeb::lds::Module *m = CG->GetModule();
+ stat.visit(m);
+ std::cout<<"Stats Module "<<automat->getName()<<std::endl;
+ std::cout<<stat<<std::endl;
+
+ delete m;
+ delete CG;
+ }
+ }
+}
+
+
+}
--- /dev/null
+PROJECT(pldsbc)
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../include/)
+INCLUDE_DIRECTORIES(${aebutils_SOURCE_DIR})
+
+
+ADD_LIBRARY(ldsbytecode
+ AutomatonBytecode.cpp
+ )
--- /dev/null
+PROJECT(pldsvm)
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../include/)
+INCLUDE_DIRECTORIES(${aebutils_SOURCE_DIR})
+
+
+ADD_LIBRARY(ldsvm
+ LdsExecutionContext.cpp
+ LdsExecutionEngine.cpp
+ )
--- /dev/null
+#include <iostream>
+#include <cassert>
+
+#include "LDSExecutionEngine/LdsObject.h"
+#include "LDSExecutionEngine/LdsExecutionContext.h"
+
+
+namespace lds
+{
+
+CallInformation::CallInformation()
+ : m_previous(NULL), m_next(NULL)
+ , m_func(NULL)
+ , m_pc(NULL)
+{
+}
+
+/**
+ * Execution Context
+ */
+ExecutionContext::ExecutionContext()
+ : m_stack(m_ec_stack) , m_top(m_stack) , m_base_ci()
+ , m_ci(&m_base_ci)
+{
+
+}
+
+/**
+ * Check the kind of function to execute.
+ * Is it an LDS TASK or a C function
+ *
+ */
+int
+ExecutionContext::precall(StackIdx func,int nresults)
+{
+ return 1;
+}
+
+void
+ExecutionContext::postcall(StackIdx func,int nresults)
+{
+}
+
+void
+ExecutionContext::Load(const std::string &file_name)
+{
+}
+
+}
--- /dev/null
+#include <iostream>
+#include <cassert>
+
+#include "LDSExecutionEngine/LdsObject.h"
+#include "LDSExecutionEngine/LdsExecutionContext.h"
+#include "LDSExecutionEngine/LdsExecutionEngine.h"
+
+#if 0
+#define LDSVM_LOG_DEBUG_FMT(x,args...) printf(x "\n", args)
+#define LDSVM_LOG_DEBUG(x,args...) printf(x)
+#else
+#define LDSVM_LOG_DEBUG_FMT(x,args...)
+#define LDSVM_LOG_DEBUG(x,args...)
+#endif
+
+
+namespace lds {
+
+
+
+void ExecutionEngine::AEL_NOP(ExecutionContext &_c)
+{
+ LDSVM_LOG_DEBUG("AEL_NOP");
+ _c.incIP();
+}
+
+void ExecutionEngine::AEL_RETURN(ExecutionContext &_c)
+{
+ LDSVM_LOG_DEBUG("AEL_RETURN");
+}
+
+/**
+ * Change State
+ */
+void ExecutionEngine::AEL_ETAT(ExecutionContext &_c)
+{
+ LDSVM_LOG_DEBUG_FMT("AEL_ETAT %d",_c.getOpcode(_c.getIP()+1));
+ _c.setState(_c.getOpcode(_c.getIP() + 1));
+ _c.incIP(2);
+}
+
+void ExecutionEngine::AEL_JUMP_PLUS(ExecutionContext &_c)
+{
+ LDSVM_LOG_DEBUG_FMT("AEL_JUMP_PLUS %d",_c.getOpcode(_c.getIP()+1));
+ _c.incIP(2 + _c.getOpcode(_c.getIP() + 1 ));
+}
+
+void ExecutionEngine::AEL_JUMP_PLUS_IF(ExecutionContext &_c)
+{
+ LDSVM_LOG_DEBUG_FMT("AEL_JUMP_PLUS_IF %d %d"
+ ,_c.getOpcode(_c.getIP())
+ ,_c.getOpcode(_c.getIP()+1));
+ if (_c.Accumulator())
+ {
+ _c.incIP(2+_c.getOpcode(_c.getIP()+1));
+ } else {
+ _c.incIP(2);
+ }
+}
+
+void ExecutionEngine::AEL_JUMP_PLUS_IF_NOT(ExecutionContext &_c)
+{
+ if (! _c.Accumulator()) {
+ LDSVM_LOG_DEBUG_FMT("AEL_JUMP_PLUS_IF_NOT %d %d"
+ ,_c.getOpcode(_c.getIP())
+ ,_c.getOpcode(_c.getIP()+1));
+ _c.incIP(2+_c.getOpcode(_c.getIP()+1));
+ } else {
+ LDSVM_LOG_DEBUG("AEL_JUMP_PLUS_IF 0");
+ _c.incIP(2);
+ }
+}
+
+void ExecutionEngine::AEL_JUMP_MOINS(ExecutionContext &_c)
+{
+ LDSVM_LOG_DEBUG_FMT("AEL_JMP_MOINS %d",_c.getOpcode(_c.getIP()+1));
+ _c.decIP(_c.getOpcode(_c.getIP()+1));
+}
+
+void ExecutionEngine::AEL_JUMP_IND(ExecutionContext &_c)
+{
+ LDSVM_LOG_DEBUG_FMT("AEL_JMP_IND %d",_c.getOpcode(_c.getIP()+1));
+}
+
+void ExecutionEngine::AEL_JSR(ExecutionContext &_c)
+{
+ LDSVM_LOG_DEBUG_FMT("AEL_JSR %d",_c.getOpcode(_c.getIP()+1));
+}
+
+/**
+ * Used to call TASK. That's where I need to create a
+ * new execution context and be able to come back
+ */
+void ExecutionEngine::AEL_JSR_IND(ExecutionContext &_c)
+{
+ LDSVM_LOG_DEBUG_FMT("AEL_JSR_IND %d TODO",_c.getOpcode(_c.getIP()+1));
+}
+
+/**
+ * This instruction is the last on before return from
+ * execution ....
+ */
+void ExecutionEngine::AEL_RTS(ExecutionContext &_c)
+{
+ LDSVM_LOG_DEBUG_FMT("AEL_RTS %d TODO",_c.getOpcode(_c.getIP()+1));
+}
+
+void ExecutionEngine::AEL_SET(ExecutionContext &_c)
+{
+ LDSVM_LOG_DEBUG_FMT("AEL_SET %d",_c.getOpcode(_c.getIP()+1));
+ _c.Register(_c.getOpcode(_c.getIP()+1)) = 1;
+ _c.incIP(2);
+}
+
+void ExecutionEngine::AEL_RESET(ExecutionContext &_c)
+{
+ LDSVM_LOG_DEBUG_FMT("AEL_RESET %d",_c.getOpcode(_c.getIP()+1));
+ _c.Register(_c.getOpcode(_c.getIP()+1)) = 0;
+ _c.incIP(2);
+}
+
+/**
+ * Save content of FLAG_GLOBAL into FLAG_XXX
+ */
+void ExecutionEngine::AEL_CHARGE(ExecutionContext &_c)
+{
+ LDSVM_LOG_DEBUG_FMT("AEL_CHARGE %d",_c.getOpcode(_c.getIP()+1));
+ _c.Register(_c.getOpcode(_c.getIP()+1)) = _c.Register(FLAG_GLOBAL);
+ _c.incIP(2);
+}
+
+void ExecutionEngine::AEL_TEST(ExecutionContext &_c)
+{
+ LDSVM_LOG_DEBUG_FMT("AEL_TEST %d",_c.getOpcode(_c.getIP()+1));
+ _c.Accumulator() = _c.Register(_c.getOpcode(_c.getIP()+1));
+ _c.incIP(2);
+}
+
+
+void ExecutionEngine::AEL_LOOP_MSG(ExecutionContext &_c)
+{
+ LDSVM_LOG_DEBUG_FMT("AEL_LOOP_MSG %d",_c.getOpcode(_c.getIP()+1));
+
+ //_c.m_EventQueue.push(_c.getOpcode(_c.getIP()+1));
+ _c.incIP(2);
+}
+
+/**
+ * This Instruction calls a C function
+ */
+void ExecutionEngine::AEL_CALL(ExecutionContext &_c)
+{
+ LDSVM_LOG_DEBUG_FMT("AEL_CALL %d",_c.getOpcode(_c.getIP()+1));
+ // Next opcode is the Function index May be just call
+ // _c.precall(); need to find the function entry
+}
+
+
+void ExecutionEngine::AEL_COMPL(ExecutionContext &_c)
+{
+ LDSVM_LOG_DEBUG_FMT("AEL_COMPL %d",_c.getOpcode(_c.getIP()+1));
+ _c.Register(_c.getOpcode(_c.getIP()+1)) =
+ ! _c.Register(_c.getOpcode(_c.getIP()+1)) ;
+ _c.incIP(2);
+}
+
+
+void ExecutionEngine::AEL_AND(ExecutionContext &_c)
+{
+ LDSVM_LOG_DEBUG_FMT("AEL_AND %d",_c.getOpcode(_c.getIP()+1));
+ _c.Register(FLAG_GLOBAL) =
+ _c.Register(_c.getOpcode(_c.getIP()+1))
+ && _c.Register(_c.getOpcode(_c.getIP()+2)) ;
+ _c.incIP(3);
+}
+
+void ExecutionEngine::AEL_OR(ExecutionContext &_c)
+{
+ LDSVM_LOG_DEBUG_FMT("AEL_OR %d",_c.getOpcode(_c.getIP()+1));
+ _c.Register(FLAG_GLOBAL) =
+ _c.Register(_c.getOpcode(_c.getIP()+1))
+ || _c.Register(_c.getOpcode(_c.getIP()+2)) ;
+ _c.incIP(3);
+}
+
+void ExecutionEngine::AEL_PLUS(ExecutionContext &_c)
+{
+ LDSVM_LOG_DEBUG_FMT("AEL_PLUS %d",_c.getOpcode(_c.getIP()+1));
+ _c.incIP(3);
+}
+
+void ExecutionEngine::AEL_MOIN(ExecutionContext &_c)
+{
+ LDSVM_LOG_DEBUG_FMT("AEL_MOIN %d",_c.getOpcode(_c.getIP()+1));
+ _c.incIP(3);
+}
+
+void ExecutionEngine::AEL_MUL(ExecutionContext &_c)
+{
+ LDSVM_LOG_DEBUG_FMT("AEL_MUL %d",_c.getOpcode(_c.getIP()+1));
+ _c.incIP(3);
+}
+
+void ExecutionEngine::AEL_EQU(ExecutionContext &_c)
+{
+ LDSVM_LOG_DEBUG_FMT("AEL_EQU %d",_c.getOpcode(_c.getIP()+1));
+ _c.incIP(3);
+}
+
+void ExecutionEngine::AEL_END(ExecutionContext &_c)
+{
+ LDSVM_LOG_DEBUG_FMT("AEL_END SHOULD NEVER BE CALLED%d",_c.getOpcode(_c.getIP()+1));
+}
+
+void
+ExecutionEngine::Load(const std::string &file_name,ExecutionContext &e)
+{
+}
+
+void
+ExecutionEngine::run(ExecutionContext &c)
+{
+ StackIdx base;
+ CallInformation *ci = c.get_ci();
+ ci->m_call_status |= CIST_FRESH;
+
+ newframe:
+ base = ci->m_base;
+
+ // Now loop over instructions
+ for (;;)
+ {
+ Instruction i = *(ci->m_pc++);
+ if ( i >=0 && i < lds::AEL_END)
+ {
+ //std::cout<<"Execute OP "<<opcode<<std::endl;
+ // Buildin Handle EXECUTE in a different way
+ // as we enter in a new execution context
+ switch(i)
+ {
+ case lds::AEL_CALL:
+ {
+ //
+ (*(m_BuiltinOp[(long)i]))(c);
+ goto newframe;
+ }
+ break;
+ case lds::AEL_RTS:
+ {
+ (*(m_BuiltinOp[(long)i]))(c);
+ goto newframe;
+ }
+ break;
+ case lds::AEL_RETURN:
+ break;
+ default:
+ (*(m_BuiltinOp[(long)i]))(c);
+ }
+ } else {
+ // Userdefined opcode
+ std::cout<<"Execute USER OP "<<i<<std::endl;
+ }
+
+ }
+}
+
+
+}
--- /dev/null
+PROJECT(test-adt)
+IF(WIN32)
+MESSAGE("CPP UNIT not yet supported for windows")
+ELSE(WIN32)
+SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}
+ "${rules_SOURCE_DIR}/")
+
+FIND_LIBRARY(DL_LIB ltdl "/lib:/usr/local/lib:/usr/lib")
+
+FIND_PACKAGE(CPPUNIT REQUIRED)
+INCLUDE_DIRECTORIES(${CPPUNIT_INCLUDE_DIRS})
+INCLUDE_DIRECTORIES(${aebutils_SOURCE_DIR})
+
+
+IF(CPPUNIT_FOUND)
+ MESSAGE("FOUND CCPUNIT for test-adt")
+ INCLUDE_DIRECTORIES(${CPPUNIT_INCLUDE_DIRS})
+ELSE(CPPUNIT_FOUND)
+ INCLUDE_DIRECTORIES("/USers/aeb/External/include")
+ENDIF(CPPUNIT_FOUND)
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../include)
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
+
+
+#
+# Start OPTIONAL has SHARED POINTER
+#
+
+FILE(GLOB UNITESTSRC ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
+MESSAGE("GLOBAL FILS: ${UNITESTSRC}")
+SET_DIRECTORY_PROPERTIES(PROPERTIES
+ ADDITIONAL_MAKE_CLEAN_FILES "${TESTSRC} ${TESTHDR}"
+ )
+
+
+#
+#
+#
+ADD_EXECUTABLE(tests-sdl
+ ${TESTSRC}
+ ${UNITESTSRC}
+ )
+
+
+
+TARGET_LINK_LIBRARIES(tests-sdl ${CPPUNIT_LIBRARY} )
+
+IF(NOT ${DL_LIB} STREQUAL DL_LIB-NOTFOUND)
+ MESSAGE("DL LIB contains: ${DL_LIB} and var ")
+ TARGET_LINK_LIBRARIES(tests-sdl ${DL_LIB} )
+ENDIF(NOT ${DL_LIB} STREQUAL DL_LIB-NOTFOUND)
+ENDIF(WIN32)
\ No newline at end of file
--- /dev/null
+#include <cppunit/config/SourcePrefix.h>
+
+#include <fstream>
+#include <iostream>
+#include <string.h>
+
+#include "ADT/Adt.h"
+#include "UNIT-TEST-adt-sdl.h"
+
+CPPUNIT_TEST_SUITE_REGISTRATION( TC_TEST_adt_sdl);
+
+
+void TC_TEST_adt_sdl::setUp()
+{
+
+}
+
+void TC_TEST_adt_sdl::TEST_Struct()
+{
+ ADT::StructType *t = ADT::StructType::Create("testStruct");
+ ADT::PrimitiveType *b1 = ADT::BooleanType::Create("B1");
+ ADT::PrimitiveType *b2 = ADT::IntegerType::Create("I2");
+ t->addField(ADT::Field::Create("namd1",b1));
+ t->addField(ADT::Field::Create("namd2",b2));
+ CPPUNIT_ASSERT( t->size() == 2);
+}
+
+void TC_TEST_adt_sdl::TEST_Choice()
+{
+ ADT::ChoiceType *t = ADT::ChoiceType::Create("testChoice");
+ ADT::PrimitiveType *b1 = ADT::BooleanType::Create("B1");
+ ADT::PrimitiveType *b2 = ADT::IntegerType::Create("I2");
+ t->addField(ADT::Field::Create("namd1",b1));
+ t->addField(ADT::Field::Create("namd2",b2));
+ CPPUNIT_ASSERT( t->size() == 2);
+}
+
+
+void TC_TEST_adt_sdl::TEST_Module()
+{
+ ADT::Module *m = ADT::Module::Create("m1");
+ ADT::PrimitiveType *b1 = ADT::BooleanType::Create("B1");
+ ADT::PrimitiveType *b2 = ADT::IntegerType::Create("B2");
+ m->insert(b1);
+ m->insert(b2);
+ CPPUNIT_ASSERT(m->size() == 2);
+}
+
+void TC_TEST_adt_sdl::TEST_Module_lookup_ok()
+{
+ ADT::Module *m = ADT::Module::Create("m1");
+ ADT::PrimitiveType *b1 = ADT::BooleanType::Create("B1");
+ m->insert(b1);
+ CPPUNIT_ASSERT(m->lookup("B1") != NULL);
+}
+
+void TC_TEST_adt_sdl::TEST_Module_lookup_failed()
+{
+ ADT::Module *m = ADT::Module::Create("m1");
+ ADT::PrimitiveType *b1 = ADT::BooleanType::Create("B1");
+ m->insert(b1);
+ CPPUNIT_ASSERT(m->lookup("dede") == NULL);
+}
--- /dev/null
+#ifndef TESTCASE_SIMPLETYPE_H
+#define TESTCASE_SIMPLETYPE_H
+
+#include <cppunit/extensions/HelperMacros.h>
+
+#include "ADT/Adt.h"
+
+class TC_TEST_adt_sdl : public CPPUNIT_NS::TestFixture
+{
+ CPPUNIT_TEST_SUITE( TC_TEST_adt_sdl );
+ CPPUNIT_TEST(TEST_Struct);
+ CPPUNIT_TEST(TEST_Choice);
+ CPPUNIT_TEST(TEST_Module);
+ CPPUNIT_TEST(TEST_Module_lookup_ok);
+ CPPUNIT_TEST(TEST_Module_lookup_failed);
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+ void setUp();
+ protected:
+
+ void TEST_Struct();
+ void TEST_Choice();
+ void TEST_Module();
+ void TEST_Module_lookup_ok();
+ void TEST_Module_lookup_failed();
+};
+
+#endif
--- /dev/null
+#include <iostream>
+
+#include <cppunit/BriefTestProgressListener.h>
+#include <cppunit/CompilerOutputter.h>
+#include <cppunit/XmlOutputter.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/TestResult.h>
+#include <cppunit/TestResultCollector.h>
+#include <cppunit/TestRunner.h>
+
+
+
+int main(int argc,char **argv)
+{
+ //asn1::types::debug_level = 9;
+
+ // if ( (argc > 1) && strcmp(argv[1],"-r") == 0)
+ // asn1::types::debug_level = 1;
+
+ // Create the event manager and test controller
+ CPPUNIT_NS::TestResult controller;
+
+ // Add a listener that colllects test result
+ CPPUNIT_NS::TestResultCollector result;
+ controller.addListener( &result );
+
+ // Add a listener that print dots as test run.
+ CPPUNIT_NS::BriefTestProgressListener progress;
+ controller.addListener( &progress );
+
+ // Add the top suite to the test runner
+ CPPUNIT_NS::TestRunner runner;
+ runner.addTest( CPPUNIT_NS::TestFactoryRegistry::getRegistry().makeTest() );
+ runner.run( controller );
+
+ // Print test in a compiler compatible format.
+ CPPUNIT_NS::CompilerOutputter outputter( &result, CPPUNIT_NS::stdCOut() );
+ outputter.write();
+
+ // Test xml output
+ std::ofstream xmlFile("Asn1TestResults.xml");
+ CPPUNIT_NS::XmlOutputter xmlOutput(&result,xmlFile);
+ xmlOutput.write();
+ return result.wasSuccessful() ? 0 : 1;
+
+}
--- /dev/null
+#ifndef ADT_H__
+#define ADT_H__
+/* vim: et sw=2 ts=2
+ */
+#include "aeb/dlilist.h"
+#include "aeb/dlilist_node.h"
+#include <algorithm>
+namespace ADT {
+
+/**
+ * \brief Abstract data type base class.
+ */
+class Adt : public ::aeb::dlilist_node<Adt> {
+ public:
+ enum AdtClass {
+ AdtNoClass = 0
+#define ADT(Cls,Parent) ,Cls##Class
+#ifdef WITH_ADT_ASN1
+# define ASN1TYPE(Cls,Parent) ,Cls##Class
+#endif
+#ifdef WITH_ADT_GDMO
+# define GDMO_DECL(Cls,Parent) ,Cls##Class
+#endif
+#include "ADT/Adt.h.inc"
+#ifdef WITH_ADT_GDMO
+#include "ADT/gdmo/Gdmo.h.inc"
+#endif
+#undef ADT
+ };
+ /// Constructors
+ Adt(AdtClass c = AdtNoClass) : m_Class(c) {};
+
+ Adt(const std::string &_s,AdtClass c) : m_Class(c),m_Name(_s) {};
+ virtual ~Adt() {};
+
+ ///Setter / Getter for Name
+ std::string getName() { return m_Name; }
+
+ ///Setter / Getter for Name
+ std::string getName() const { return m_Name; }
+
+
+ /// Getter for Class
+ AdtClass getClass() const {return m_Class; };
+
+ protected:
+ AdtClass m_Class;
+ /// All Abstract Data Types should have a name. If not, it's an anonymous type and
+ /// size of m_Name is 0
+ std::string m_Name;
+ private:
+};
+
+#include "ADT/AdtModule.h"
+#include "ADT/AdtPrimitiveType.h"
+#include "ADT/AdtTypeRefType.h"
+#include "ADT/AdtField.h"
+#include "ADT/AdtContainer.h"
+#include "ADT/AdtChoice.h"
+#include "ADT/AdtStruct.h"
+
+#ifdef WITH_ADT_ASN1
+#endif
+#ifdef WITH_ADT_GDMO
+#include "ADT/gdmo/Gdmo.h"
+#endif
+}
+
+
+#endif
--- /dev/null
+/**
+ * SDL Abstract Data Types
+ */
+#ifndef ADT
+# define ADT(Cls,Parent)
+#endif
+ADT(Container,Adt)
+ADT(ChoiceType,Container)
+ADT(StructType,Container)
+ADT(BagType,Container)
+ADT(PrimitiveType,Adt)
+ADT(BooleanType,PrimitiveType)
+ADT(IntegerType,PrimitiveType)
+ADT(StringType,PrimitiveType)
+ADT(TypeRefType,Adt)
+ADT(ValueType,Adt)
+ADT(Module,Adt)
+ADT(Field,Adt)
+
+
+/**
+ * ASN1 Abstract Data Types
+ */
+#ifndef ASN1TYPE
+# define ASN1TYPE(Cls,Parent)
+#endif
+
+
+ASN1TYPE(REFERENCE,Adt)
+ASN1TYPE(EXPORTVAR,Adt)
+ASN1TYPE(UNIVERSAL,Adt)
+ASN1TYPE(BITVECTOR,Adt)
+ASN1TYPE(EXTENSIBLE,Adt)
+ASN1TYPE(COMPONENTS_OF,Adt)
+ASN1TYPE(VALUESET,Adt)
+ASN1TYPE(CLASSDEF,Adt)
+ASN1TYPE(INSTANCE,Adt)
+
+/**
+ * Class Field type
+ */
+ASN1TYPE(ClassFieldTF,Adt) /* Type Field */
+ASN1TYPE(ClassFieldFTVF,Adt) /* Fixed Type Value Field */
+ASN1TYPE(ClassFieldVTVF,Adt) /* Variable Type Value Field */
+ASN1TYPE(ClassFieldFTVSF,Adt) /* Fixed Type Value Set Field */
+ASN1TYPE(ClassFieldVTVSF,Adt) /* Variable Type Value Set Field*/
+ASN1TYPE(ClassFieldOF,Adt) /* Object Field */
+ASN1TYPE(ClassFieldOSF,Adt) /* Object Set Field */
+/* Constructed Types
+ */
+ASN1TYPE(Sequence,StructType)
+ASN1TYPE(Choice,ChoiceType)
+ASN1TYPE(Set,Adt)
+
+ASN1TYPE(SequenceOf,Adt) /* Should be a vector or an array */
+ASN1TYPE(SetOf,Bag) /* Comes from SDL specification */
+ASN1TYPE(Selection,Adt) /* */
+
+/* Basic Types
+ */
+ASN1TYPE(Asn1Primitive,PrimitiveType)
+ASN1TYPE(Any,Asn1Primitive)
+ASN1TYPE(Boolean,Asn1Primitive)
+ASN1TYPE(Integer,Asn1Primitive)
+ASN1TYPE(BitString,Asn1Primitive)
+ASN1TYPE(OctetString,Asn1Primitive)
+ASN1TYPE(Null,Asn1Primitive)
+ASN1TYPE(ObjectIdentifier,Asn1Primitive)
+ASN1TYPE(ObjectDescriptor,Asn1Primitive)
+ASN1TYPE(Real,Asn1Primitive)
+ASN1TYPE(Enumerated,Asn1Primitive)
+ASN1TYPE(RelativeOid,Asn1Primitive)
+ASN1TYPE(External,Asn1Primitive)
+ASN1TYPE(EmbeddedPdv,Asn1Primitive)
+ASN1TYPE(CharString,Asn1Primitive)
+ASN1TYPE(UTCTime,Asn1Primitive)
+ASN1TYPE(GeneralizedTime,Asn1Primitive)
+
+ASN1TYPE(ObjectClass,Asn1Primitive)
+ASN1TYPE(Object,Asn1Primitive)
+
+/* String Types
+ */
+ASN1TYPE(String,Asn1Primitive)
+ASN1TYPE(IA5String,String)
+ASN1TYPE(PrintableString,String)
+ASN1TYPE(VisibleString,String)
+ASN1TYPE(ISO646String,String) /* aka VisibleString */
+ASN1TYPE(NumericString,String)
+ASN1TYPE(UniversalString,String)
+ASN1TYPE(BMPString,String)
+ASN1TYPE(UTF8String,String)
+ASN1TYPE(GeneralString,String)
+ASN1TYPE(GraphicString,String)
+ASN1TYPE(TeletexString,String)
+ASN1TYPE(T61String,String)
+ASN1TYPE(VideotexString,String)
+ASN1TYPE(ObjectDescriptor,String)
+
+/**
+ * XSD Abstract Data Types
+ */
+#ifndef XSDTYPE
+# define XSDTYPE(Cls,Parent)
+#endif
--- /dev/null
+#ifndef ADTCHOICE_H__
+#define ADTCHOICE_H__
+/* vim: et sw=2 ts=2
+ */
+
+
+class ChoiceType : public Container {
+ public:
+
+ virtual ~ChoiceType() {};
+
+ static ChoiceType *Create(const std::string &_s) {
+ return new ChoiceType(_s);
+ }
+ ///
+ bool addField(Field *d) {
+ if (d) {
+ if (lookup(d->getName())) {
+ // Already in structure don't add twice the same name
+ return false;
+ } else {
+ m_Fields.push_back(d);
+ return true;
+ }
+ } else
+ return false;
+ };
+
+ protected:
+ ChoiceType(const std::string &_s,AdtClass c=ChoiceTypeClass ) : Container(_s,c) {} ;
+
+ protected:
+
+ private:
+};
+
+#endif
--- /dev/null
+#ifndef ADTCONTAINER_H__
+#define ADTCONTAINER_H__
+/* vim: et sw=2 ts=2
+ */
+
+
+class Container: public Adt {
+ public:
+ // Constains a list of Instruction ....
+ typedef aeb::dlilist<Adt> FieldList;
+
+ // Instruction Iterator
+ typedef FieldList::iterator iterator;
+ typedef FieldList::const_iterator const_iterator;
+
+ protected:
+ explicit Container(const std::string &_s = "",AdtClass c=ContainerClass) : Adt(_s,c),m_Fields() {} ;
+
+ struct searchByName {
+ searchByName(const std::string &n) : m_Name(n) {};
+ int operator ()(Adt &l) {
+ return !m_Name.compare(l.getName());
+ };
+ std::string m_Name;
+ };
+ public:
+ static Container *Create(const std::string &_s) {
+ return new Container(_s);
+ }
+
+ virtual ~Container() {};
+
+ ///
+ bool addField(Field *d) {
+ if (d) {
+ if (lookup(d->getName())) {
+ // Already in structure don't add twice the same name
+ return false;
+ } else {
+ m_Fields.push_back(d);
+ return true;
+ }
+ } else
+ return false;
+ };
+
+ ///
+ bool add(Adt *d) {
+ if (d) {
+ if (lookup(d->getName())) {
+ // Already in structure don't add twice the same name
+ return false;
+ } else {
+ m_Fields.push_back(d);
+ return true;
+ }
+ } else
+ return false;
+ };
+
+
+ /// Iterators
+ iterator begin() { return m_Fields.begin(); }
+ iterator end() { return m_Fields.end(); }
+
+ size_t size() const { return m_Fields.size(); }
+ /// lookup field in current structure
+ Adt *lookup(const std::string &_s) {
+ iterator it = std::find_if(begin(),end(),searchByName(_s));
+ if (it != end())
+ return &*it;
+ return NULL;
+
+ };
+ protected:
+ FieldList m_Fields;
+ private:
+};
+
+#endif
--- /dev/null
+#ifndef ADTFIELD_H__
+#define ADTFIELD_H__
+/* vim: et sw=2 ts=2
+ */
+
+/**
+ * \brief A field is contained in a Structure or a Bag. It references a Primary or contructed type.
+ * -- When added to a structure or Bag, the function getParent shoud return the Parent that owns the
+ * field.
+ */
+class Field : public Adt {
+ public:
+ virtual ~Field() {};
+ protected:
+ Field(const std::string &_s ="", Adt *_typeref = NULL) : Adt(_s,FieldClass) , m_TypeRef(_typeref) {} ;
+
+ public:
+ static Field *Create(const std::string &_s,Adt *_typeref = NULL) {
+ return new Field(_s,_typeref);
+ }
+
+ Adt *getParent() { return NULL;};
+ // Getter
+ Adt *getTypeRef() const { return m_TypeRef; };
+ protected:
+ /// The field is contained in structs, Bags, Maybe I should use reference counting if to names point to the same type !!!!
+ Adt *m_TypeRef;
+ private:
+};
+
+#endif
--- /dev/null
+#ifndef ADTMODULE_H__
+#define ADTMODULE_H__
+
+// vim: et sw=2 ts=2
+/**
+ *
+ * \brief This class is a container. It keeps track of all Abstract datatypes defined
+ * in a module. Provides lockup functions , iterators and so one.
+ *
+ * As it contains a list of definition, this module shall inherit from something like a list
+ * container
+ */
+class Module : public Adt {
+ public:
+ // Constains a list of Instruction ....
+ typedef aeb::dlilist<Adt> AdtList;
+
+ // Instruction Iterator
+ typedef AdtList::iterator iterator;
+ typedef AdtList::const_iterator const_iterator;
+
+ protected:
+ // Constructors
+ Module(Adt::AdtClass c,const std::string &name) : Adt(name,c) {};
+
+ struct searchByName {
+ searchByName(const std::string &n) : m_Name(n) {};
+ int operator ()(Adt &l) {
+ return !m_Name.compare(l.getName());
+ };
+ std::string m_Name;
+ };
+ public:
+ ~Module() {};
+ static Module *Create(const std::string &_s) { return new Module(ModuleClass,_s); }
+ // Iterators
+ iterator begin() { return m_Types.begin(); }
+ iterator end() { return m_Types.end(); }
+
+ size_t size() const { return m_Types.size(); }
+ /// Search for given type name in module
+ Adt *lookup(const std::string &_s) {
+ iterator it = std::find_if(begin(),end(),searchByName(_s));
+ if (it != end())
+ return &*it;
+ return NULL;
+ };
+
+ /// Insert new Abstract Data Type in Module. If Data Type already exists, return false and don't insert in
+ /// the list
+ bool insert(Adt *m) { if (m) { m_Types.push_back(m); return true;} else {return false;}};
+ protected:
+ /// Types contained in module
+ AdtList m_Types;
+ private:
+
+};
+
+#endif
--- /dev/null
+#ifndef ADTPRIMITIVETYPE_H__
+#define ADTPRIMITIVETYPE_H__
+/* vim: et sw=2 ts=2
+ */
+
+/**
+ * \brief Root class to handle primitive types like string,boolean,integer.
+ * All other types are constructed struct, vector, array bag
+ */
+class PrimitiveType : public Adt {
+ public:
+ PrimitiveType(const std::string &_s,AdtClass c=PrimitiveTypeClass) : Adt(_s,c) {} ;
+ virtual ~PrimitiveType() {};
+ protected:
+
+ private:
+};
+
+
+/**
+ *
+ */
+#define PRIMITIVE(Cls) \
+class Cls : public PrimitiveType { \
+ protected: \
+ Cls (const std::string &_s,AdtClass c=Cls##Class) : PrimitiveType(_s,c) { } ; \
+ public: \
+ virtual ~Cls() {} ;\
+ static Cls *Create(const std::string &_s) { return new Cls(_s); } \
+ protected: \
+}
+
+PRIMITIVE(BooleanType);
+PRIMITIVE(StringType);
+PRIMITIVE(IntegerType);
+
+#endif
--- /dev/null
+#ifndef ADTSTRUCT_H__
+#define ADTSTRUCT_H__
+/* vim: et sw=2 ts=2
+ */
+
+
+class StructType : public Container {
+ public:
+
+ protected:
+ explicit StructType(const std::string &_s = "") : Container(_s,StructTypeClass) {} ;
+
+ public:
+ static StructType *Create(const std::string &_s) {
+ return new StructType(_s);
+ }
+
+ virtual ~StructType() {};
+
+ ///
+ bool addField(Field *d) {
+ if (d) {
+ if (lookup(d->getName())) {
+ // Already in structure don't add twice the same name
+ return false;
+ } else {
+ m_Fields.push_back(d);
+ return true;
+ }
+ } else
+ return false;
+ };
+ protected:
+ private:
+};
+
+#endif
--- /dev/null
+#ifndef ADTTYPEREF_H__
+#define ADTTYPEREF_H__
+/* vim: et sw=2 ts=2
+ */
+
+/**
+ * \brief A field is contained in a Structure or a Bag. It references a Primary or contructed type.
+ * -- When added to a structure or Bag, the function getParent shoud return the Parent that owns the
+ * field.
+ */
+class TypeRefType : public Adt {
+ public:
+ virtual ~TypeRefType() {};
+ protected:
+ TypeRefType(const std::string &_s ="", Adt *_typeref = NULL) : Adt(_s,TypeRefTypeClass) , m_TypeRef(_typeref) {} ;
+
+ public:
+ static TypeRefType *Create(const std::string &_s,Adt *_typeref = NULL) {
+ return new TypeRefType(_s,_typeref);
+ }
+
+ Adt *getParent() { return NULL;};
+ // Getter
+ Adt *getTypeRef() const { return m_TypeRef; };
+ protected:
+ /// The field is contained in structs, Bags, Maybe I should use reference counting if to names point to the same type !!!!
+ Adt *m_TypeRef;
+ private:
+};
+
+#endif
--- /dev/null
+#ifndef ASN1BOOLEAN_H
+#define ASN1BOOLEAN_H
+
+class Asn1Boolean {
+ public:
+ //
+ Asn1Boolean() ;
+ //
+ Asn1Boolean(const Asn1Boolean &o) ;
+ //
+ ~Asn1Boolean() ;
+ protected:
+};
+#endif /*ASN1BOOLEAN_H*/
--- /dev/null
+#ifndef ASN1CHOICE_H
+#define ASN1CHOICE_H
+
+
+class Asn1Choice {
+ public:
+ //
+ Asn1Choice() ;
+ //
+ Asn1Choice(const Asn1Choice &o) ;
+ //
+ ~Asn1Choice() ;
+ protected:
+};
+
+
+#endif /*ASN1CHOICE_H*/
--- /dev/null
+#ifndef ASN1CLASS_H
+#define ASN1CLASS_H
+
+/**
+ * class Asn1Class
+ *
+ * \brief
+ * \author
+ */
+class Asn1Class {
+ public:
+ //
+ Asn1Class() ;
+ //
+ Asn1Class(const Asn1Class &o) ;
+ //
+ ~Asn1Class() ;
+ protected:
+};
+
+
+#endif /*ASN1CLASS_H*/
--- /dev/null
+#ifndef ASN1CONSTRAINT_H
+#define ASN1CONSTRAINT_H
+
+/**
+ * class Asn1Constraint
+ *
+ * \brief
+ * \author
+ */
+class Asn1Constraint : public Asn1Decl {
+ public:
+ //
+ Asn1Constraint() ;
+ //
+ Asn1Constraint(const Asn1Constraint &o) ;
+ //
+ ~Asn1Constraint() ;
+ protected:
+};
+
+
+#endif /*ASN1CONSTRAINT_H*/
--- /dev/null
+#ifndef ASN1CONTEXT_H
+#define ASN1CONTEXT_H
+
+class Asn1Decl;
+/**
+ * class Asn1Context
+ *
+ * \brief
+ * \author
+ */
+class Asn1Context {
+ public:
+ //
+ Asn1Context() ;
+ //
+ Asn1Context(const Asn1Context &o) ;
+ //
+ ~Asn1Context() ;
+ protected:
+ Asn1Decl *m_First;
+ Asn1Decl *m_Last;
+};
+
+
+
+#endif /*ASN1CONTEXT_H*/
--- /dev/null
+#ifndef ASN1DECL_H
+#define ASN1DECL_H
+
+
+/**
+ * class Asn1Decl
+ *
+ * \brief
+ * \author
+ */
+class Asn1Decl {
+ public:
+ //
+ Asn1Decl() ;
+ //
+ Asn1Decl(const Asn1Decl &o) ;
+ //
+ ~Asn1Decl() ;
+ protected:
+ Asn1Decl *m_Next;
+};
+
+
+
+#endif /*ASN1DECL_H*/
--- /dev/null
+#ifndef ASN1FIELD_H
+#define ASN1FIELD_H
+
+/**
+ * class Asn1Field
+ *
+ * \brief
+ * \author
+ */
+class Asn1Field {
+ public:
+ //
+ Asn1Field() ;
+ //
+ Asn1Field(const Asn1Field &o) ;
+ //
+ ~Asn1Field() ;
+ protected:
+};
+
+
+#endif /*ASN1FIELD_H*/
--- /dev/null
+#ifndef ASN1INTEGER_H
+#define ASN1INTEGER_H
+
+
+/**
+ * class Asn1Intger
+ *
+ * \brief
+ * \author
+ */
+class Asn1Integer {
+ public:
+ //
+ Asn1Integer() ;
+ //
+ Asn1Integer(const Asn1Integer &o) ;
+ //
+ ~Asn1Integer() ;
+ protected:
+};
+
+
+#endif /*ASN1INTEGER_H*/
--- /dev/null
+#ifndef ASN1MODULE_H
+#define ASN1MODULE_H
+
+
+/**
+ * class Asn1Module
+ *
+ * \brief
+ * \author
+ */
+class Asn1Module {
+ public:
+ //
+ Asn1Module() ;
+ //
+ Asn1Module(const Asn1Module &o) ;
+ //
+ ~Asn1Module() ;
+ protected:
+};
+
+
+#endif /*ASN1MODULE_H*/
--- /dev/null
+#ifndef ASN1OBJECT_H
+#define ASN1OBJECT_H
+
+/**
+ * class Asn1Object
+ *
+ * \brief
+ * \author
+ */
+class Asn1Object {
+ public:
+ //
+ Asn1Object() ;
+ //
+ Asn1Object(const Asn1Object &o) ;
+ //
+ ~Asn1Object() ;
+ protected:
+};
+
+
+#endif /*ASN1OBJECT_H*/
--- /dev/null
+#ifndef ASN1OBJECTSET_H
+#define ASN1OBJECTSET_H
+
+
+/**
+ * class Asn1ObjectSet
+ *
+ * \brief
+ * \author
+ */
+class Asn1ObjectSet {
+ public:
+ //
+ Asn1ObjectSet() ;
+ //
+ Asn1ObjectSet(const Asn1ObjectSet &o) ;
+ //
+ ~Asn1ObjectSet() ;
+ protected:
+};
+
+
+
+#endif /*ASN1OBJECTSET_H*/
--- /dev/null
+#ifndef ASN1OID_H
+#define ASN1OID_H
+
+
+/**
+ * class Asn1ObjectIdentifier
+ *
+ * \brief
+ * \author
+ */
+class Asn1ObjectIdentifier : public Asn1Type {
+ public:
+ //
+ Asn1ObjectIdentifier() ;
+ //
+ Asn1ObjectIdentifier(const Asn1ObjectIdentifier &o) ;
+ //
+ ~Asn1ObjectIdentifier() ;
+ protected:
+};
+
+
+#endif /*ASN1OID_H*/
--- /dev/null
+#ifndef ASN1SEQUENCE_H
+#define ASN1SEQUENCE_H
+
+
+/**
+ * class Asn1Sequence
+ *
+ * \brief
+ * \author
+ */
+class Asn1Sequence {
+ public:
+ //
+ Asn1Sequence() ;
+ //
+ Asn1Sequence(const Asn1Sequence &o) ;
+ //
+ ~Asn1Sequence() ;
+ protected:
+};
+
+
+#endif /*ASN1SEQUENCE_H*/
--- /dev/null
+#ifndef ASN1SET_H
+#define ASN1SET_H
+
+/**
+ * class Asn1Set
+ *
+ * \brief
+ * \author
+ */
+class Asn1Set {
+ public:
+ //
+ Asn1Set() ;
+ //
+ Asn1Set(const Asn1Set &o) ;
+ //
+ ~Asn1Set() ;
+ protected:
+};
+
+
+
+#endif /*ASN1SET_H*/
--- /dev/null
+#ifndef ASN1TYPE_H
+#define ASN1TYPE_H
+
+
+/**
+ * class Asn1Type
+ *
+ * \brief
+ * \author
+ */
+class Asn1Type {
+ public:
+ //
+ Asn1Type() ;
+ //
+ Asn1Type(const Asn1Type &o) ;
+ //
+ ~Asn1Type() ;
+ protected:
+};
+
+
+
+#endif /*ASN1TYPE_H*/
--- /dev/null
+#ifndef TYPE
+# define TYPE(NAME,CLASS,MCLASS)
+#endif
+TYPE(REFERENCE,Asn1Typeref,Asn1Decl)
+TYPE(EXPORTVAR,Asn1Type,Asn1Decl)
+TYPE(UNIVERSAL)
+TYPE(BITVECTOR)
+TYPE(EXTENSIBLE)
+TYPE(COMPONENTS_OF)
+TYPE(VALUESET)
+TYPE(CLASSDEF,Asn1Class,Asn1Type)
+TYPE(INSTANCE)
+
+/**
+ * Class Field type
+ */
+#ifndef FIELD _TYPE
+# define FIELD_TYPE(ID,CLASS,MCLASS) TYPE(ID,CLASS,MCLASS)
+#endif
+FIELD_TYPE(CLASSFIELD_TF,Asn1Field,Asn1Field) /* Type Field */
+FIELD_TYPE(CLASSFIELD_FTVF,Asn1Field,Asn1Field) /* Fixed Type Value Field */
+FIELD_TYPE(CLASSFIELD_VTVF,Asn1Field,Asn1Field) /* Variable Type Value Field */
+FIELD_TYPE(CLASSFIELD_FTVSF,Asn1Field,Asn1Field) /* Fixed Type Value Set Field */
+FIELD_TYPE(CLASSFIELD_VTVSF,Asn1Field,Asn1Field) /* Variable Type Value Set Field*/
+FIELD_TYPE(CLASSFIELD_OF,Asn1Field,Asn1Field) /* Object Field */
+FIELD_TYPE(CLASSFIELD_OSF,Asn1Field,Asn1Field) /* Object Set Field */
+
+/*
+ * Constructed Types
+ */
+TYPE(SEQUENCE,Asn1Sequence,Asn1Decl) /* 17 */
+TYPE(CHOICE,Asn1Choice,Asn1Decl)
+TYPE(SET,Asn1Choice,Asn1Decl)
+TYPE(SEQUENCE_OF)
+TYPE(SET_OF)
+TYPE(SELECTION)
+
+/*
+ * Basic Types
+ */
+TYPE(ANY,Asn1Type,Asn1Type)
+TYPE(BOOLEAN,Asn1Boolean,Asn1Type)
+TYPE(INTEGER,Asn1Integer,Asn1Type)
+TYPE(BIT_STRING)
+TYPE(OCTET_STRING)
+TYPE(NULL)
+TYPE(OBJECT_IDENTIFIER,Asn1Oid,Asn1Decl)
+TYPE(OBJECT_DESCRIPTOR)
+TYPE(REAL,Asn1Type,Asn1Type)
+TYPE(ENUMERATED,Ans1Integer,Asn1Integer)
+TYPE(RELATIVE_OID,Asn1Oid,Asn1Decl)
+TYPE(EXTERNAL)
+TYPE(EMBEDDED_PDV)
+TYPE(CHARACTER_STRING,Asn1String,Asn1Decl)
+/*
+ * Time Types
+ */
+TYPE(Time,Asn1Time,Asn1Decl)
+TYPE(UTCTime,Asn1UTCTime,Asn1Time)
+TYPE(GeneralizedTime,Asn1GTime,Asn1Time)
+
+/*
+ * String Types
+ */
+#ifndef STRING_TYPE
+# define STRING_TYPE(ID,CLASS,MCLASS) TYPE(ID,CLASS,MCLASS)
+#endif
+STRING_TYPE(STRING,Asn1String,Asn1String)
+STRING_TYPE(STRING_IA5String,Asn1String,Asn1String)
+STRING_TYPE(STRING_PrintableString,Asn1String,Asn1String)
+STRING_TYPE(STRING_VisibleString,Asn1String,Asn1String)
+STRING_TYPE(STRING_ISO646String,Asn1String,Asn1String) /* aka VisibleString */
+STRING_TYPE(STRING_NumericString,Asn1String,Asn1String)
+STRING_TYPE(STRING_UniversalString,Asn1String,Asn1String)
+STRING_TYPE(STRING_BMPString,Asn1String,Asn1String)
+STRING_TYPE(STRING_UTF8String ,Asn1String,Asn1String)
+STRING_TYPE(STRING_GeneralString,Asn1String,Asn1String)
+STRING_TYPE(STRING_GraphicString,Asn1String,Asn1String)
+STRING_TYPE(STRING_TeletexString,Asn1String,Asn1String)
+STRING_TYPE(STRING_T61String,Asn1String,Asn1String)
+STRING_TYPE(STRING_VideotexString,Asn1String,Asn1String)
+STRING_TYPE(STRING_ObjectDescriptor,Asn1String,Asn1String)
+
+TYPE(TYPE_MAX)
+
+#undef TYPE
--- /dev/null
+#ifndef GDMO_H
+#define GDMO_H
+
+namespace GDMO
+{
+
+ /**
+ * Base class
+ */
+ class gdmo : public Adt
+ {
+ public:
+ gdmo(Adt::AdtClass c)
+ : Adt(c)
+ {
+ }
+ gdmo(Adt::AdtClass c,const std::string &n)
+ : Adt(n,c)
+ {
+ }
+ protected:
+ };
+
+ /**
+ *
+ */
+ class decl : public gdmo
+ {
+ protected:
+ decl(Adt::AdtClass c,const std::string &n="")
+ : gdmo(c,n)
+ {
+ }
+
+ public:
+
+ static decl *Create(const std::string &name)
+ {
+ return new decl(Adt::declClass,name);
+ }
+
+ const std::string get_name() const
+ {
+ std::string s = getName();
+ return s;
+ }
+ protected:
+ };
+
+
+ /**
+ * All labels in gdmo document
+ */
+ class oid_item : public decl
+ {
+ oid_item(Adt::AdtClass c ,const std::string &s,const long v = -1)
+ : decl(c,s) ,m_value(v)
+ { }
+ public:
+ static oid_item *Create(const std::string &name = "",const long v = -1)
+ {
+ return new oid_item(Adt::oid_itemClass,name,v);
+ }
+
+ /**
+ *
+ */
+ const std::string get_name()
+ {
+ std::string s = getName();
+ if ( s.size() < 1 )
+ {
+ std::ostringstream ss;
+ ss<<m_value;
+ s = ss.str();
+ } else if ( m_value > -1)
+ {
+ std::ostringstream ss;
+ ss<<s<<" ("<<m_value<<") ";
+ s = ss.str();
+ }
+ return s;
+ }
+ long get_value() const
+ {
+ return m_value;
+ }
+ protected:
+ long m_value;
+ };
+
+
+ /**
+ * All labels in gdmo document
+ */
+ class label : public decl
+ {
+ label(Adt::AdtClass c ,const std::string &s,const std::string &n)
+ : decl(c,n) ,m_scope(s)
+ { }
+ public:
+ static label *Create(const std::string &name)
+ {
+ return new label(Adt::labelClass,"",name);
+ }
+ static label *Create(const std::string &scope,const std::string &name)
+ {
+ return new label(Adt::labelClass,scope,name);
+ }
+
+ /**
+ *
+ */
+ void set_scope(const std::string &s)
+ {
+ m_scope = s;
+ }
+
+ std::string get_scope() const
+ {
+ return m_scope;
+ }
+ protected:
+ std::string m_scope;
+ };
+ /**
+ * attribute property
+ */
+ class typeref;
+ class property : public decl
+ {
+ protected:
+ property(Adt::AdtClass c,const std::string &n="")
+ : decl(c,n)
+ {
+ memset(&flags,0x00,sizeof(flags));
+ }
+
+ property(Adt::AdtClass c,decl *de)
+ : decl(c,"") , m_decl(de)
+ {
+ memset(&flags,0x00,sizeof(flags));
+ }
+
+ public:
+ struct
+ {
+ unsigned long get:1;
+ unsigned long replace:1;
+ unsigned long add:1;
+ unsigned long remove:1;
+ } flags;
+
+ static property *Create(const std::string &name)
+ {
+ return new property(Adt::propertyClass,name);
+ }
+
+ const std::string get_name() const
+ {
+ std::string s = getName();
+ return s;
+ }
+ decl *get_decl() const
+ {
+ return m_decl;
+ }
+ protected:
+ decl *m_decl;
+ };
+
+
+
+ /**
+ *
+ */
+ class typeref : public decl
+ {
+ typeref (Adt::AdtClass c ,const std::string &s,const std::string &n)
+ : decl(c,n) ,m_module(s)
+ { }
+ public:
+ static typeref *Create(const std::string &name)
+ {
+ return new typeref(Adt::typerefClass,"",name);
+ }
+ static typeref *Create(const std::string &scope,const std::string &name)
+ {
+ return new typeref(Adt::typerefClass,scope,name);
+ }
+ std::string get_asn1_module()
+ {
+ return m_module;
+ }
+ protected:
+ std::string m_module;
+ };
+
+
+ /**
+ * @brief The highest level of declaration. Each
+ * template contains a given number of constructs.
+ * That pleads for specializing each template
+ * or I find a way to declare the constructs for each
+ * template and generate the associated member functions
+ * and classes
+ */
+ class templates : public gdmo
+ {
+ public:
+ templates(Adt::AdtClass c,const label &l)
+ : gdmo(c,l.getName()) , m_label(l)
+ {
+ }
+ label get_label() const
+ {
+ return m_label;
+ }
+ protected:
+ label m_label;
+ };
+
+ /**
+ *
+ */
+ class construct : public gdmo
+ {
+ public:
+ typedef Container::iterator iterator;
+
+ construct(Adt::AdtClass c,Container *cont)
+ : gdmo(c,cont->getName()) , m_container(cont) ,m_decl(NULL)
+ {
+ }
+ construct(Adt::AdtClass c,decl *cont)
+ : gdmo(c) , m_container(NULL) ,m_decl(cont)
+ {
+ }
+
+ size_t size() const
+ {
+ if (m_container)
+ return m_container->size();
+ return 0;
+ };
+ iterator begin()
+ {
+ return m_container->begin();
+ }
+ iterator end()
+ {
+ return m_container->end();
+ }
+ decl *get_decl() const
+ {
+ return m_decl;
+ }
+ protected:
+ Container *m_container;
+ decl *m_decl;
+ };
+
+#define GDMO_DECL(cls,parent)
+#define GDMO_PROPLIST_DECL(cls,parent) \
+ class cls : public parent \
+ { \
+ protected: \
+ cls(Adt::AdtClass c,decl *_con) \
+ : parent(c,_con) \
+ { \
+ } \
+ public: \
+ static cls *Create(decl *l) \
+ { \
+ return new cls(Adt::cls##Class,l); \
+ } \
+ };
+
+#define GDMO_CONSTRUCT_DECL(cls,parent) \
+ class cls : public parent \
+ { \
+ protected: \
+ cls(Adt::AdtClass c,Container *_con) \
+ : parent(c,_con) \
+ { \
+ } \
+ cls(Adt::AdtClass c,decl *_con) \
+ : parent(c,_con) \
+ { \
+ } \
+ public: \
+ static cls *Create(Container *l) \
+ { \
+ return new cls(Adt::cls##Class,l); \
+ } \
+ static cls *Create(decl *l) \
+ { \
+ return new cls(Adt::cls##Class,l); \
+ } \
+ }; \
+
+#define GDMO_TPLT_DECL(x,y)
+
+#include "ADT/gdmo/Gdmo.h.inc"
+
+#include "ADT/gdmo/GdmoTemplates.h"
+
+ class module : public Module
+ {
+ protected:
+ module(const std::string &s)
+ : Module(Adt::moduleClass,s)
+ {
+ }
+ public:
+ static module *Create(const std::string &s)
+ {
+ return new module(s);
+ }
+ };
+
+
+
+ /**
+ * All labels in gdmo document
+ */
+ class pkg_attribute : public decl
+ {
+
+#define PKG_CONST(etype) \
+ etype(vf,PROPL_REPLACE_DEFAULT,replace_default) \
+ etype(vs,PROPL_DEFAULT,default) \
+ etype(vs,PROPL_INITIAL,initial) \
+ etype(vs,PROPL_PERMITTED,permitted) \
+ etype(vs,PROPL_REQUIRED,required) \
+ etype(vs,PROPL_GET_REPLACE,get_replace) \
+ etype(vs,PROPL_ADD_REMOVE,add_remove) \
+ etype(vs,PROPL_SET_BY_CREATED,set_by_created) \
+ etype(vs,PROPL_NO_MODIFY,no_modify) \
+
+#define vs ,
+#define vf
+#define etype(COMMA,e,T) COMMA e
+ public:
+ enum eConstruct {PKG_CONST(etype) ,PROPL_END};
+#undef etype
+#undef vs
+ protected:
+ property *m_properties[PROPL_END];
+/**
+ * Add setter and getters
+ */
+
+#define vs
+#define etype(v,e,T) \
+ property_## T * get_##T() const { return dynamic_cast< property_##T*>(m_properties[e]);} \
+ void set_##T(property_##T *c) { m_properties[ e ] = c;} \
+
+ public:
+ PKG_CONST(etype)
+#undef etype
+#undef vs
+#undef vf
+#undef PKG_CONST
+ protected:
+ pkg_attribute(Adt::AdtClass c ,const std::string &s,const std::string &n)
+ : decl(c,n) ,m_scope(s)
+ {
+ memset(m_properties,0x00,sizeof(property *)*PROPL_END);
+ }
+ public:
+ static pkg_attribute *Create(const std::string &name)
+ {
+ return new pkg_attribute(Adt::pkg_attributeClass,"",name);
+ }
+ static pkg_attribute *Create(const std::string &scope,const std::string &name)
+ {
+ return new pkg_attribute(Adt::pkg_attributeClass,scope,name);
+ }
+
+ /**
+ *
+ */
+ void set_scope(const std::string &s)
+ {
+ m_scope = s;
+ }
+
+ std::string get_scope() const
+ {
+ return m_scope;
+ }
+ protected:
+ std::string m_scope;
+ };
+
+
+
+}
+#endif /*GDMO_H*/
--- /dev/null
+#ifndef GDMO_DECL
+# define GDMO_DECL(cls,parent)
+#endif
+
+GDMO_DECL(module,Module)
+GDMO_DECL(decl,gdmo)
+//GDMO_DECL(container,gdmo)
+/**
+ * typereferences
+ */
+GDMO_DECL(label,decl)
+GDMO_DECL(pkg_attribute,decl)
+GDMO_DECL(property,decl)
+GDMO_DECL(oid_item,decl)
+GDMO_DECL(reference,decl)
+GDMO_DECL(typeref,reference)
+GDMO_DECL(valueref,reference)
+
+/**
+ * templates
+ */
+#ifndef GDMO_TPLT_DECL
+# define GDMO_TPLT_DECL(cls,parent) GDMO_DECL(cls,parent)
+#endif
+GDMO_DECL(templates,decl)
+
+GDMO_TPLT_DECL(mo_tplt,templates)
+GDMO_TPLT_DECL(package_tplt,templates)
+GDMO_TPLT_DECL(name_binding_tplt,templates)
+GDMO_TPLT_DECL(attribute_tplt,templates)
+GDMO_TPLT_DECL(attribute_group_tplt,templates)
+GDMO_TPLT_DECL(behaviour_tplt,templates)
+GDMO_TPLT_DECL(action_tplt,templates)
+GDMO_TPLT_DECL(parameter_tplt,templates)
+GDMO_TPLT_DECL(notification_tplt,templates)
+
+#ifndef GDMO_CONSTRUCT_DECL
+# define GDMO_CONSTRUCT_DECL(cls,parent) GDMO_DECL(cls,parent)
+#endif
+
+GDMO_CONSTRUCT_DECL(mo_derived_from,construct)
+GDMO_CONSTRUCT_DECL(mo_characterized_by,construct)
+GDMO_CONSTRUCT_DECL(mo_cond_packages,construct)
+GDMO_CONSTRUCT_DECL(mo_registered,construct)
+
+GDMO_CONSTRUCT_DECL(pkg_behaviour,construct)
+GDMO_CONSTRUCT_DECL(pkg_attributes,construct)
+GDMO_CONSTRUCT_DECL(pkg_attribute_group,construct)
+GDMO_CONSTRUCT_DECL(pkg_actions,construct)
+GDMO_CONSTRUCT_DECL(pkg_notifications,construct)
+GDMO_CONSTRUCT_DECL(pkg_registered,construct)
+
+
+GDMO_CONSTRUCT_DECL(attr_syntax,construct)
+GDMO_CONSTRUCT_DECL(attr_match_for,construct)
+GDMO_CONSTRUCT_DECL(attr_behaviour,construct)
+GDMO_CONSTRUCT_DECL(attr_parameters,construct)
+GDMO_CONSTRUCT_DECL(attr_registered,construct)
+
+GDMO_CONSTRUCT_DECL(parameter_context,construct)
+GDMO_CONSTRUCT_DECL(parameter_syntax,construct)
+GDMO_CONSTRUCT_DECL(parameter_attribute,construct)
+GDMO_CONSTRUCT_DECL(parameter_behaviour,construct)
+GDMO_CONSTRUCT_DECL(parameter_registered,construct)
+
+GDMO_CONSTRUCT_DECL(name_binding_subordinate,construct)
+GDMO_CONSTRUCT_DECL(name_binding_named_by_superior,construct)
+GDMO_CONSTRUCT_DECL(name_binding_with_attribute,construct)
+GDMO_CONSTRUCT_DECL(name_binding_behaviour,construct)
+GDMO_CONSTRUCT_DECL(name_binding_create,construct)
+GDMO_CONSTRUCT_DECL(name_binding_delete,construct)
+GDMO_CONSTRUCT_DECL(name_binding_registered,construct)
+
+GDMO_CONSTRUCT_DECL(action_behaviour,construct)
+GDMO_CONSTRUCT_DECL(action_mode,construct)
+GDMO_CONSTRUCT_DECL(action_parameters,construct)
+GDMO_CONSTRUCT_DECL(action_with_information,construct)
+GDMO_CONSTRUCT_DECL(action_with_reply,construct)
+GDMO_CONSTRUCT_DECL(action_registered,construct)
+
+GDMO_CONSTRUCT_DECL(notification_mode,construct)
+GDMO_CONSTRUCT_DECL(notification_behaviour,construct)
+GDMO_CONSTRUCT_DECL(notification_parameters,construct)
+GDMO_CONSTRUCT_DECL(notification_with_information,construct)
+GDMO_CONSTRUCT_DECL(notification_with_reply,construct)
+GDMO_CONSTRUCT_DECL(notification_registered,construct)
+
+GDMO_CONSTRUCT_DECL(attribute_group_group_elements,construct)
+
+GDMO_CONSTRUCT_DECL(behaviour_defined_as,construct)
+
+#ifndef GDMO_PROPLIST_DECL
+# define GDMO_PROPLIST_DECL(cls,parent) GDMO_DECL(cls,parent)
+#endif
+GDMO_PROPLIST_DECL(property_replace_default,property)
+GDMO_PROPLIST_DECL(property_default,property)
+GDMO_PROPLIST_DECL(property_initial,property)
+GDMO_PROPLIST_DECL(property_permitted,property)
+GDMO_PROPLIST_DECL(property_required,property)
+GDMO_PROPLIST_DECL(property_get_replace,property)
+GDMO_PROPLIST_DECL(property_add_remove,property)
+GDMO_PROPLIST_DECL(property_set_by_created,property)
+GDMO_PROPLIST_DECL(property_no_modify,property)
+
+#undef GDMO_DECL
+#undef GDMO_TPLT_DECL
+#undef GDMO_CONSTRUCT_DECL
+#undef GDMO_PROPLIST_DECL
--- /dev/null
+
+
+/**
+ * mo_tplt
+ */
+class mo_tplt : public templates
+{
+ protected:
+#define MO_CONST(etype) \
+ etype(vf,MO_DERIRVED_FROM,derived_from) \
+ etype(vs,MO_CHARACTERIZED_BY,characterized_by) \
+ etype(vs,MO_COND_PACKAGES,cond_packages) \
+ etype(vs,MO_REGISTERED,registered) \
+
+#define vs ,
+#define vf
+#define etype(COMMA,e,T) COMMA e
+ public:
+ enum eConstruct {MO_CONST(etype) ,MO_END};
+#undef etype
+#undef vs
+#undef vf
+ protected:
+ construct *m_constructs[MO_END];
+/**
+ * Add setter and getters
+ */
+
+#define vs
+#define vf
+#define etype(v,e,T) \
+ mo_## T * get_##T() const { return dynamic_cast< mo_##T*>(m_constructs[e]);} \
+ void set_##T(mo_##T *c) { m_constructs[ e ] = c;} \
+
+ public:
+ MO_CONST(etype)
+#undef etype
+#undef vs
+#undef vf
+ protected:
+ mo_tplt(Adt::AdtClass c,const label &l)
+ : templates(c,l)
+ {
+ memset(m_constructs,0x00,sizeof( construct *) * MO_END);
+ }
+ public:
+ static mo_tplt *Create(const label &l)
+ {
+ return new mo_tplt(Adt::mo_tpltClass,l);
+ }
+};
+
+/**
+ * package_tplt
+ */
+class package_tplt : public templates
+{
+#define PKG_CONST(etype) \
+ etype(vf,PKG_BEHAVIOUR,behaviour) \
+ etype(vs,PKG_ATTRIBUTES,attributes) \
+ etype(vs,PKG_ATTR_GROUP,attribute_group) \
+ etype(vs,PKG_ACTIONS,actions) \
+ etype(vs,PKG_NOTIFICATIONS,notifications) \
+ etype(vs,PKG_REGISTERED,registered)
+
+#define vs ,
+#define vf
+#define etype(COMMA,e,T) COMMA e
+ public:
+ enum eConstruct {PKG_CONST(etype) ,PKG_END};
+#undef etype
+#undef vs
+#undef vf
+ protected:
+ construct *m_constructs[PKG_END];
+/**
+ * Add setter and getters
+ */
+
+#define vs
+#define vf
+#define etype(v,e,T) \
+ pkg_## T * get_##T() const { return dynamic_cast< pkg_##T*>(m_constructs[e]);} \
+ void set_##T(pkg_##T *c) { m_constructs[ e ] = c;} \
+
+ public:
+ PKG_CONST(etype)
+#undef etype
+#undef vs
+#undef vf
+#undef PKG_CONST
+ protected:
+ package_tplt(Adt::AdtClass c,const label &l)
+ : templates(c,l)
+ {
+ memset(m_constructs,0x00,sizeof( construct *) * PKG_END);
+ }
+ public:
+ static package_tplt *Create(const label &l)
+ {
+ return new package_tplt(Adt::package_tpltClass,l);
+ }
+};
+
+/**
+ * name_binding_tplt
+ */
+class name_binding_tplt : public templates
+{
+#define NBIND_CONST(etype) \
+ etype(vf,NBIND_SUBORDINATE,subordinate) \
+ etype(vs,NBIND_NAMED_BY_SUPERIOR,named_by_superior) \
+ etype(vs,NBIND_WITH_ATTRIBUTE,with_attribute) \
+ etype(vs,NBIND_BEHAVIOUR,behaviour) \
+ etype(vs,NBIND_CREATE,create) \
+ etype(vs,NBIND_DELETE,delete) \
+ etype(vs,NBIND_REGISTERED,registered)
+
+#define vs ,
+#define vf
+#define etype(COMMA,e,T) COMMA e
+ public:
+ enum eConstruct {NBIND_CONST(etype) ,NBIND_END};
+#undef etype
+#undef vs
+#undef vf
+ protected:
+ construct *m_constructs[NBIND_END];
+/**
+ * Add setter and getters
+ */
+
+#define vs
+#define vf
+#define etype(v,e,T) \
+ name_binding_## T * get_##T() const { return dynamic_cast< name_binding_##T*>(m_constructs[e]);} \
+ void set_##T(name_binding_##T *c) { m_constructs[ e ] = c;} \
+
+ public:
+ NBIND_CONST(etype)
+#undef etype
+#undef vs
+#undef vf
+ protected:
+ name_binding_tplt(Adt::AdtClass c,const label &l)
+ : templates(c,l)
+ {
+ memset(m_constructs,0x00,sizeof( construct *) * NBIND_END);
+ }
+ public:
+ static name_binding_tplt *Create(const label &l)
+ {
+ return new name_binding_tplt(Adt::name_binding_tpltClass,l);
+ }
+};
+
+/**
+ * attributes_tplt
+ */
+class attribute_tplt : public templates
+{
+#define ATTR_CONST(etype) \
+ etype(vf,ATTR_SYNTAX,syntax) \
+ etype(vs,ATTR_MATCH_FOR,match_for) \
+ etype(vs,ATTR_BEHAVIOUR,behaviour) \
+ etype(vs,ATTR_PARAMETERS,parameters) \
+ etype(vs,ATTR_REGISTERED,registered)
+
+#define vs ,
+#define vf
+#define etype(COMMA,e,T) COMMA e
+ public:
+ enum eConstruct {ATTR_CONST(etype) ,ATTR_END};
+#undef etype
+#undef vs
+#undef vf
+ protected:
+ construct *m_constructs[ATTR_END];
+/**
+ * Add setter and getters
+ */
+
+#define vs
+#define vf
+#define etype(v,e,T) \
+ attr_## T * get_##T() const { return dynamic_cast< attr_##T*>(m_constructs[e]);} \
+ void set_##T(attr_##T *c) { m_constructs[ e ] = c;} \
+
+ public:
+ ATTR_CONST(etype)
+#undef etype
+#undef vs
+#undef vf
+ protected:
+ attribute_tplt(Adt::AdtClass c,const label &l)
+ : templates(c,l)
+ {
+ memset(m_constructs,0x00,sizeof( construct *) * ATTR_END);
+ }
+ public:
+ static attribute_tplt *Create(const label &l)
+ {
+ return new attribute_tplt(Adt::attribute_tpltClass,l);
+ }
+};
+
+/**
+ * attribute_group_tplt
+ */
+class attribute_group_tplt : public templates
+{
+#define ATTRG_CONST(etype) \
+ etype(vf,ATTRG_GROUP_ELEMENTS,group_elements)
+
+#define vs ,
+#define vf
+#define etype(COMMA,e,T) COMMA e
+ public:
+ enum eConstruct {ATTRG_CONST(etype) ,ATTRG_END};
+#undef etype
+#undef vs
+#undef vf
+ protected:
+ construct *m_constructs[ATTRG_END];
+/**
+ * Add setter and getters
+ */
+
+#define vs
+#define vf
+#define etype(v,e,T) \
+ attribute_group_## T * get_##T() const { return dynamic_cast<attribute_group_##T*>(m_constructs[e]);} \
+ void set_##T(attribute_group_##T *c) { m_constructs[ e ] = c;} \
+
+ public:
+ ATTRG_CONST(etype)
+#undef etype
+#undef vs
+ protected:
+ attribute_group_tplt(Adt::AdtClass c,const label &l)
+ : templates(c,l)
+ {
+ memset(m_constructs,0x00,sizeof( construct *) * ATTRG_END);
+ }
+ public:
+ static attribute_group_tplt *Create(const label &l)
+ {
+ return new attribute_group_tplt(Adt::attribute_group_tpltClass,l);
+ }
+};
+
+/**
+ * behaviour_tplt
+ */
+class behaviour_tplt : public templates
+{
+#define BEH_CONST(etype) \
+ etype(vf,BEH_DEFINED_AS,defined_as)
+
+#define vs ,
+#define vf
+#define etype(COMMA,e,T) COMMA e
+ public:
+ enum eConstruct {BEH_CONST(etype) ,BEH_END};
+#undef etype
+#undef vs
+#undef vf
+ protected:
+ construct *m_constructs[BEH_END];
+/**
+ * Add setter and getters
+ */
+
+#define vs
+#define vf
+#define etype(v,e,T) \
+ behaviour_## T * get_##T() const { return dynamic_cast< behaviour_##T*>(m_constructs[e]);} \
+ void set_##T(behaviour_##T *c) { m_constructs[ e ] = c;} \
+
+ public:
+ BEH_CONST(etype)
+#undef etype
+#undef vs
+#undef vf
+ protected:
+ behaviour_tplt(Adt::AdtClass c,const label &l)
+ : templates(c,l)
+ {
+ memset(m_constructs,0x00,sizeof( construct *) * BEH_END);
+ }
+
+ public:
+ static behaviour_tplt *Create(const label &l)
+ {
+ return new behaviour_tplt(Adt::behaviour_tpltClass,l);
+ }
+};
+
+/**
+ * action_tplt
+ */
+class action_tplt : public templates
+{
+#define ACTION_CONST(etype) \
+ etype(vf,ACTION_BEHAVIOUR,behaviour) \
+ etype(vs,ACTION_MODE,mode) \
+ etype(vs,ACTION_PARAMETERS,parameters) \
+ etype(vs,ACTION_WITH_INFORMATION,with_information) \
+ etype(vs,ACTION_WITH_REPLY,with_reply) \
+ etype(vs,ACTION_REGISTERED,registered)
+
+#define vs ,
+#define vf
+#define etype(COMMA,e,T) COMMA e
+ public:
+ enum eConstruct {ACTION_CONST(etype) ,ACTION_END};
+#undef etype
+#undef vs
+#undef vf
+ protected:
+ construct *m_constructs[ACTION_END];
+/**
+ * Add setter and getters
+ */
+
+#define vs
+#define vf
+#define etype(v,e,T) \
+ action_## T * get_##T() const { return dynamic_cast< action_##T*>(m_constructs[e]);} \
+ void set_##T(action_##T *c) { m_constructs[ e ] = c;} \
+
+ public:
+ ACTION_CONST(etype)
+#undef etype
+#undef vs
+#undef vf
+ protected:
+ action_tplt(Adt::AdtClass c,const label &l)
+ : templates(c,l)
+ {
+ memset(m_constructs,0x00,sizeof( construct *) * ACTION_END);
+ }
+ public:
+ static action_tplt *Create(const label &l)
+ {
+ return new action_tplt(Adt::action_tpltClass,l);
+ }
+};
+
+/**
+ * parameter_tplt
+ */
+class parameter_tplt : public templates
+{
+#define PARAMETER_CONST(etype) \
+ etype(vf,PARAMETER_CONTEXT,context) \
+ etype(vs,PARAMETER_SYNTAX,syntax) \
+ etype(vs,PARAMETER_ATTRIBUTE,attribute) \
+ etype(vs,PARAMETER_BEHAVIOUR,behaviour) \
+ etype(vs,PARAMETER_REGISTERED,registered)
+
+#define vs ,
+#define vf
+#define etype(COMMA,e,T) COMMA e
+ public:
+ enum eConstruct {PARAMETER_CONST(etype) ,PARAMETER_END};
+#undef etype
+#undef vs
+#undef vf
+ protected:
+ construct *m_constructs[PARAMETER_END];
+/**
+ * Add setter and getters
+ */
+
+#define vs
+#define vf
+#define etype(v,e,T) \
+ parameter_## T * get_##T() const { return dynamic_cast< parameter_##T*>(m_constructs[e]);} \
+ void set_##T(parameter_##T *c) { m_constructs[ e ] = c;} \
+
+ public:
+ PARAMETER_CONST(etype)
+#undef etype
+#undef vs
+#undef vf
+ protected:
+ parameter_tplt(Adt::AdtClass c,const label &l)
+ : templates(c,l)
+ {
+ memset(m_constructs,0x00,sizeof( construct *) * PARAMETER_END);
+ }
+ public:
+ static parameter_tplt *Create(const label &l)
+ {
+ return new parameter_tplt(Adt::parameter_tpltClass,l);
+ }
+};
+
+/**
+ * notification_tplt
+ */
+class notification_tplt : public templates
+{
+#define NOTIFICATION_CONST(etype) \
+ etype(vf,NOTIFICATION_BEHAVIOUR,behaviour) \
+ etype(vs,NOTIFICATION_MODE,mode) \
+ etype(vs,NOTIFICATION_PARAMETERS,parameters) \
+ etype(vs,NOTIFICATION_WITH_INFORMATION,with_information) \
+ etype(vs,NOTIFICATION_WITH_REPLY,with_reply) \
+ etype(vs,NOTIFICATION_REGISTERED,registered)
+
+#define vs ,
+#define vf
+#define etype(COMMA,e,T) COMMA e
+ public:
+ enum eConstruct {NOTIFICATION_CONST(etype) ,NOTIFICATION_END};
+#undef etype
+#undef vs
+#undef vf
+ protected:
+ construct *m_constructs[NOTIFICATION_END];
+/**
+ * Add setter and getters
+ */
+
+#define vs
+#define vf
+#define etype(v,e,T) \
+ notification_## T * get_##T() const { return dynamic_cast< notification_##T*>(m_constructs[e]);} \
+ void set_##T(notification_##T *c) { m_constructs[ e ] = c;} \
+
+ public:
+ NOTIFICATION_CONST(etype)
+#undef etype
+#undef vs
+#undef vf
+ protected:
+ notification_tplt(Adt::AdtClass c,const label &l)
+ : templates(c,l)
+ {
+ memset(m_constructs,0x00,sizeof( construct *) * NOTIFICATION_END);
+ }
+ public:
+ static notification_tplt *Create(const label &l)
+ {
+ return new notification_tplt(Adt::notification_tpltClass,l);
+ }
+};
+
--- /dev/null
+#ifndef ASTCONSUMER_H__
+#define ASTCONSUMER_H__
+
+/**
+ * Abstract Class to be implemented to traverse the tree
+ * Ideas of consumers :
+ * - graphical view
+ * - regenerate source in sdl form from lds form
+ * - c++ strategy pattern for automaton
+ * - cm automaton files aac aaa eta ptr tra
+ * - and of course a multiplex consumer which is able to launch multiple consumer on one declaration
+ */
+class ASTConsumer {
+ public:
+ ASTConsumer() ;
+ /// Called by ASTParser ....
+ bool HandleToplevelDecl(const ASTContext &c,std::string &decls);
+};
+
+#endif
--- /dev/null
+#ifndef ASTCONTEXT_H
+#define ASTCONTEXT_H
+
+namespace AST {
+class Type;
+class ConstantArrayType;
+class TranslationUnitDecl;
+/**
+ * ASTContext is a placeholder class that contains all defined types and function.
+ * Datatypes are created through this class.
+ * Aligned Memory allocation should be handled by this class to.
+ *
+ */
+class ASTContext
+{
+ public:
+ typedef std::map<std::string, Type *> Typelist;
+ typedef typename Typelist::const_iterator TypelistConstIterator;
+ typedef typename Typelist::iterator TypelistIterator;
+ private:
+ protected:
+ TranslationUnitDecl *m_TranslationUnitDecl;
+ Typelist m_Types;
+ std::vector<ConstantArrayType *> m_ConstantArrays;
+ public:
+
+ // BuiltinTypes ...
+#define BUILTIN_TYPE(Id,Cls) BuiltinType Cls;
+#include "AST/BuiltinTypes.h.def"
+ // Functions that Return Type for various declarations
+ // eg Variable, Pointer, Structure, Parameter variable, Function and so on
+ Type &getRecordType(const RecordDecl *);
+
+ Type &getValueTypeType(const ValueTypeDecl *D);
+
+ Type &getTypedefType(const TypedefDecl *D);
+
+ Type &getFunctionType(Type *RetTy,std::vector<Type *>Parma,const std::string &fn);
+
+ Type &getConstantArrayType(Type *EltTy,long length);
+
+ const Typelist &getTypes() const { return m_Types;};
+ /**
+ * Initialize all builtin types.
+ */
+ void InitBuiltinTypes();
+
+ Type &getTypeDeclType(TypeDecl *Decl,TypeDecl *prevDecl = NULL);
+ /**
+ *
+ */
+ TranslationUnitDecl *getTranslationUnitDecl() const { return m_TranslationUnitDecl; };
+ /**
+ * Create an ASTContext Object.
+ * This object will be used in various places where datatype creation is necessary.
+ */
+ ASTContext() ;
+ ~ASTContext() ;
+};
+
+}
+
+
+#endif /*ASTCONTEXT_H*/
--- /dev/null
+#ifndef ASTRECURSIVEVISITOR_H__
+#define ASTRECURSIVEVISITOR_H__
+
+
+#define UNARYOP_LIST() \
+ OPERATOR(PostInc) OPERATOR(PostDec) OPERATOR(PreInc) \
+ OPERATOR(PreDec) OPERATOR(Plus) OPERATOR(Minus) \
+ OPERATOR(Nor) OPERATOR(LNot)
+
+#define BINOP_LIST() \
+ OPERATOR(Mul) OPERATOR(Div) OPERATOR(Rem) OPERATOR(Add) \
+ OPERATOR(Sub) OPERATOR(Shl) OPERATOR(Shr) OPERATOR(LT) \
+ OPERATOR(GT) OPERATOR(LE) OPERATOR(GE) OPERATOR(EQ) \
+ OPERATOR(NE) OPERATOR(And) OPERATOR(Xor) OPERATOR(Or) \
+ OPERATOR(LAnd) OPERATOR(LOr) OPERATOR(Assign)
+
+namespace AST {
+
+#define TRY_TO(f) do { \
+ if (! getDerived().f ) { \
+ std::cout<<"TRY_TO FAILED calling "<< #f<<std::endl; \
+ return false; \
+ } \
+ } while(0)
+
+
+template <typename Derived>
+class RecursiveVisitor {
+ public:
+ Derived &getDerived() {
+ return *static_cast<Derived *>(this);
+ };
+
+ bool TraverseStmt(Stmt *);
+ bool TraverseDecl(Decl *);
+
+ bool TraverseDeclContextHelper(DeclContext *DC);
+ bool TraverseStmtHelper(Stmt *DC);
+ // WalkupFrom Category
+ //
+ // -- Methods of Stmt
+
+#define STMT(CLASS,PARENT) bool Traverse##CLASS(CLASS *S);
+#include "Stmt.h.inc"
+
+#undef STMT
+
+ bool WalkupFromStmt(Stmt *s) { return getDerived().VisitStmt(s);}
+
+ bool VisitStmt(Stmt *s) {return true;}
+
+#define STMT(CLASS,PARENT) \
+ bool WalkupFrom##CLASS(CLASS *S) { \
+ TRY_TO(WalkupFrom##PARENT(S)); \
+ TRY_TO(Visit##CLASS(S)); \
+ return true; \
+ } \
+ bool Visit##CLASS(CLASS *S) {return true; }
+
+#include "Stmt.h.inc"
+
+#undef STMT
+
+ // --- Unary Operators are Opcodes in UnaryOperator class
+#define OPERATOR(OP) \
+ bool TraverseUnary##OP(UnaryOperator *S) { \
+ TRY_TO(WalkupFromUnary##OP(S) ); \
+ TRY_TO(TraverseStmt(S->getSubExpr(S) ); \
+ return true; \
+ } \
+ bool WalkupUnaryFrom##OP(UnaryOperator *S) { \
+ TRY_TO(WalkupFromUnaryOperator(S)); \
+ TRY_TO(VisitUnary##OP(S)); \
+ return true; \
+ } \
+ bool VisitUnary##OP(UnayOperator *S) { \
+ return true; \
+ } \
+ UNARYOP_LIST()
+#undef OPERATOR
+
+ // -- Binary Operators
+#define OPERATOR(OP) \
+ bool TraverseBin##OP(BinaryOperator *S) { \
+ TRY_TO(WalkupFromBin##OP(S) ); \
+ TRY_TO(TraverseStmt(S->getLHS(S) ); \
+ TRY_TO(TraverseStmt(S->getLHS(S) ); \
+ return true; \
+ } \
+ bool WalkupFromBin##OP(UnaryOperator *S) { \
+ TRY_TO(WalkupFromBinaryOperator(S)); \
+ TRY_TO(VisitBin##OP(S)); \
+ return true; \
+ } \
+ bool VisitBin##OP(BinaryOperator *S) { \
+ return true; \
+ } \
+ BINOP_LIST()
+#undef OPERATOR
+
+
+ // --- Methods on DECL
+ bool WalkupFromDecl(Decl *s) { return getDerived().VisitDecl(s);}
+ bool VisitDecl(Decl *s) {return true;}
+
+#define DECL(CLASS,BASE) \
+ bool Traverse##CLASS (CLASS *d);
+#include "Decl.h.inc"
+
+#define DECL(CLASS,PARENT) \
+ bool WalkupFrom##CLASS(CLASS *S) { \
+ TRY_TO(WalkupFrom##PARENT(S)); \
+ TRY_TO(Visit##CLASS(S)); \
+ return true; \
+ } \
+ bool Visit##CLASS(CLASS *S) {return true; }
+#include "Decl.h.inc"
+
+
+};
+
+/**
+ * Implementation part
+ */
+template <typename Derived>
+bool RecursiveVisitor<Derived>::TraverseStmtHelper(Stmt *S) {
+#if 1
+ if (! S)
+ return true;
+
+ Stmt::range_iterator c = S->children();
+ for ( ; c.first != c.second ; ++c.first) {
+ TRY_TO( TraverseStmt(*(c.first) ) );
+ }
+ return true;
+#endif
+}
+// -- Stmt Traversal
+
+#define DEF_TRAVERSE_STMT(STAMT,CODE) \
+ template <typename Derived> \
+ bool RecursiveVisitor<Derived>::Traverse##STAMT(STAMT *S) { \
+ TRY_TO(WalkupFrom##STAMT(S)); \
+ { CODE ; } \
+ /* Traverse Children to be done*/ \
+ return TraverseStmtHelper(S); \
+ /*return true; */ \
+ } \
+
+
+DEF_TRAVERSE_STMT(SwitchStmt, {})
+DEF_TRAVERSE_STMT(IfStmt, {})
+DEF_TRAVERSE_STMT(WhileStmt, {})
+DEF_TRAVERSE_STMT(GotoStmt, {})
+DEF_TRAVERSE_STMT(ForStmt, {})
+DEF_TRAVERSE_STMT(CompoundStmt, {
+ // std::cout<<"TraverCompoundStmt"<<std::endl ;
+ for ( CompoundStmt::iterator it = S->begin() ; it != S->end() ; ++it) {
+ TraverseStmt(*it);
+ }
+})
+DEF_TRAVERSE_STMT(DeclStmt, {})
+DEF_TRAVERSE_STMT(ReturnStmt, {})
+DEF_TRAVERSE_STMT(LabelStmt, {})
+DEF_TRAVERSE_STMT(BreakStmt, {})
+DEF_TRAVERSE_STMT(SwitchCaseStmt, {
+ TraverseStmt(S->getSubStmt());
+ })
+
+DEF_TRAVERSE_STMT(AsmStmt, {})
+DEF_TRAVERSE_STMT(LdsAsmStmt, {})
+DEF_TRAVERSE_STMT(OutputStmt, {})
+
+DEF_TRAVERSE_STMT(Expr,{
+})
+DEF_TRAVERSE_STMT(ParenExpr, { })
+DEF_TRAVERSE_STMT(ParenListExpr, { })
+DEF_TRAVERSE_STMT(MemberExpr, {
+ TraverseStmt(S->getBase());
+ // TraverseStmt(S->getMember());
+ })
+DEF_TRAVERSE_STMT(ArraySubscriptExpr, {
+ TraverseStmt(S->getBase());
+ TraverseStmt(S->getIndex());
+ })
+DEF_TRAVERSE_STMT(LdsThisExpr, { })
+DEF_TRAVERSE_STMT(CreateExpr, { })
+DEF_TRAVERSE_STMT(PidExpr, { })
+
+DEF_TRAVERSE_STMT(DeclRefExpr, {})
+DEF_TRAVERSE_STMT(CallExpr, {
+ // std::cout<<"Traverse CallExpr"<<std::endl;
+})
+DEF_TRAVERSE_STMT(IntegerLiteral, {})
+DEF_TRAVERSE_STMT(StringLiteral, {})
+DEF_TRAVERSE_STMT(FloatLiteral, {})
+DEF_TRAVERSE_STMT(BinaryOperator, {})
+DEF_TRAVERSE_STMT(UnaryOperator, {})
+DEF_TRAVERSE_STMT(ConditionalOperator, {})
+
+#define DISPATCH(NAME,CLASS,VAR) \
+ return getDerived().Traverse##NAME(static_cast<CLASS *>(VAR))
+
+
+template <typename Derived>
+bool RecursiveVisitor<Derived>::TraverseStmt(Stmt *S) {
+ if (!S)
+ return true;
+ // std::cout<<"RecursiveVisitor<>::TraverseStmt "<<S->getStmtClass()<<std::endl;
+
+#define DISPATCH_STMT(NAME,CLASS,VAR) DISPATCH(NAME,CLASS,VAR)
+ if(BinaryOperator *BinOp = dynamic_cast<BinaryOperator *>(S) ) {
+ // Hey Dispatch according to OpCode
+
+ } else if(UnaryOperator *BinOp = dynamic_cast<UnaryOperator *>(S) ) {
+ // Hey Dispatch according to OpCode
+
+ }
+
+ // Dispatch according to statement
+ switch (S->getStmtClass()) {
+ case Stmt::NoStmtClass:
+ break;
+#define STMT(CLASS,PARENT) \
+ case Stmt::CLASS##Class : \
+ DISPATCH_STMT(CLASS,CLASS,S);
+#include "Stmt.h.inc"
+ }
+ return true;
+}
+
+// -- Decl Traversal
+
+template < typename Derived>
+bool RecursiveVisitor<Derived>::TraverseDeclContextHelper(DeclContext *DC)
+{
+ int i=0;
+ if ( !DC )
+ return true;
+ //std::cout<<" TraverseDeclContextHelper begin "<<(long)(DC)<<std::endl;
+ for (DeclContext::decl_iterator it = DC->begin(); it != DC->end() ; ++it )
+ {
+ //std::cout<<" TraverseDeclContextHelper count "<<i++<<" "<<(long)(*it)<<" "<<(*it)->getKind()<<std::endl;
+ TRY_TO(TraverseDecl(*it));
+ }
+ //std::cout<<" TraverseDeclContextHelper end "<<(long)(DC)<<std::endl;
+ return true;
+}
+
+
+template <typename Derived>
+bool RecursiveVisitor<Derived>::TraverseDecl(Decl *D) {
+
+ if (!D)
+ return true;
+#define DECL(CLASS,BASE) \
+ case DeclBase::CLASS : \
+ if (! getDerived().Traverse##CLASS(static_cast< CLASS *>(D)) ) { \
+ std::cout<<"RecursiveVisitor<erived>::TraverseDecl Failed Traverse"<< #CLASS<<std::endl; \
+ return false; \
+ } \
+ break;
+
+ //std::cout<<"RecursiveVisitor<Derived>::TraverseDecl kind:"<<D->getKind()<<std::endl;
+ switch (D->getKind())
+ {
+#include "Decl.h.inc"
+ default:
+ std::cout<<"TraverseDecl default:"<<std::endl;
+ return true;
+ ;
+ }
+// #undef DECL in Decl.h file
+ return true;
+}
+
+
+// Traverse DECL implementations
+
+#define DEF_TRAVERSE_DECL(DECL,CODE) \
+ template <typename Derived> \
+ bool RecursiveVisitor<Derived>::Traverse##DECL(DECL *d) { \
+ TRY_TO(WalkupFrom##DECL(d)); \
+ { CODE;} \
+ TRY_TO(TraverseDeclContextHelper(dynamic_cast<DeclContext *>(d))); \
+ return true; \
+ } \
+
+DEF_TRAVERSE_DECL(TranslationUnitDecl, {
+ })
+
+DEF_TRAVERSE_DECL(NamedDecl, { })
+
+DEF_TRAVERSE_DECL(GateDecl, { })
+DEF_TRAVERSE_DECL(ChannelEndPointDecl, { })
+DEF_TRAVERSE_DECL(ChannelPathDecl, { })
+DEF_TRAVERSE_DECL(ChannelDecl, { })
+
+DEF_TRAVERSE_DECL(TypeDecl, { })
+DEF_TRAVERSE_DECL(TypedefDecl, { })
+DEF_TRAVERSE_DECL(ValueTypeDecl, { })
+DEF_TRAVERSE_DECL(EnumDecl, { })
+
+
+DEF_TRAVERSE_DECL(AgentTypeDecl, { })
+DEF_TRAVERSE_DECL(AutomatonTypeDecl, { })
+DEF_TRAVERSE_DECL(BlockTypeDecl, { })
+DEF_TRAVERSE_DECL(SystemTypeDecl, { })
+
+DEF_TRAVERSE_DECL(PackageUseDecl, { })
+DEF_TRAVERSE_DECL(ValueDecl, { })
+DEF_TRAVERSE_DECL(EnumConstantDecl, { })
+DEF_TRAVERSE_DECL(VarDecl, { })
+DEF_TRAVERSE_DECL(TimerDecl, { })
+DEF_TRAVERSE_DECL(ParmVarDecl, { })
+
+DEF_TRAVERSE_DECL(FunctionDecl, {
+ for (FunctionDecl::param_iterator it = d->param_begin(); it != d->param_end() ; ++it) {
+ TRY_TO(TraverseDecl(*it));
+ }
+ if (d->getBody() != NULL) {
+ TRY_TO(TraverseStmt(d->getBody())) ;
+ }
+ return true; // Avoid call TraverseDeclContextHelp
+})
+
+DEF_TRAVERSE_DECL(TransitionDecl, {
+ if (d->getBody() != NULL) {
+ TRY_TO(TraverseStmt(d->getBody())) ;
+ }
+ return true; // Avoid call TraverseDeclContextHelp
+})
+
+DEF_TRAVERSE_DECL(StateDecl, {
+ //std::cout<<"RecursiveVisitor::TraverseStateDecl"<<std::endl;
+ // TraverseDeclContextHelper(d);
+ })
+
+DEF_TRAVERSE_DECL(RefStateDecl, { })
+DEF_TRAVERSE_DECL(FieldDecl, { })
+DEF_TRAVERSE_DECL(RecordDecl, { })
+DEF_TRAVERSE_DECL(EventDecl, { })
+DEF_TRAVERSE_DECL(LabelDecl, { })
+
+DEF_TRAVERSE_DECL(AgentDecl, { })
+DEF_TRAVERSE_DECL(AutomatonDecl, { })
+DEF_TRAVERSE_DECL(PackageDecl, { })
+DEF_TRAVERSE_DECL(SystemDecl, { })
+DEF_TRAVERSE_DECL(BlockDecl, { })
+
+
+}
+
+#endif
--- /dev/null
+/**
+ * To be honnest, The code below is inspired from clang / llvm
+ */
+
+#ifndef SIGNED_TYPE
+# define SIGNED_TYPE(Id,SingletonId) BUILTIN_TYPE(Id,SingletonId)
+#endif
+
+#ifndef UNSIGNED_TYPE
+# define UNSIGNED_TYPE(Id,SingletonId) BUILTIN_TYPE(Id,SingletonId)
+#endif
+
+// Void
+BUILTIN_TYPE(Void,VoidTy)
+
+// Boolean
+UNSIGNED_TYPE(Boolean,BooleanTy)
+// Natural
+UNSIGNED_TYPE(Natural,NaturalTy)
+
+// Integer is the only type
+SIGNED_TYPE(Integer,IntegerTy)
+
+/* I think this should be character */
+BUILTIN_TYPE(Char,CharTy)
+// What about string ?
+BUILTIN_TYPE(String,StringTy)
+
+/* Time types */
+BUILTIN_TYPE(Time,TimeTy)
+
+BUILTIN_TYPE(Duration,DurationTy)
+
+// What about Pid ?
+BUILTIN_TYPE(Pid,PidTy)
+
+#undef SIGNED_TYPE
+#undef UNSIGNED_TYPE
+#undef BUILTIN_TYPE
+
--- /dev/null
+#ifndef AST_CONTEXT_H__
+#define AST_CONTEXT_H__
+namespace AST {
+
+class Expr;
+class Stmt;
+class Decl;
+
+/**
+ *
+ *
+ */
+class Context {
+ typedef std::vector<Context *>::iterator iterator;
+ typedef std::vector<Context *>::const_iterator const_iterator;
+
+
+ private:
+ Context(const std::string &_name,Context *_p = NULL) : m_Parent(_p),m_Name(_name) {};
+ virtual ~Context() {};
+
+ public:
+
+ static Context &getRootContext() {
+ static Context *m_Context = NULL;
+ if (m_Context == NULL) {
+ m_Context = new Context("");
+ }
+ return *m_Context;
+ };
+
+ Context &NewContext(const std::string &_name) {
+ m_Contexts.push_back(new Context(_name,this));
+ return * m_Contexts.back();
+ };
+
+ Context &getParent() const {return *m_Parent;};
+ void addExpr(Expr *_e) { m_Exprs.push_back(_e); } ;
+ void addDecl(Decl *_e) { m_Decls.push_back(_e); } ;
+ void addStmt(Stmt *_e) { m_Stmts.push_back(_e); } ;
+
+ protected:
+ std::vector<Context *> m_Contexts;
+
+ std::vector<Decl *> m_Decls;
+ std::vector<Stmt *> m_Stmts;
+ std::vector<Expr *> m_Exprs;
+ Context *m_Parent;
+ std::string m_Name;
+};
+
+}
+#endif
--- /dev/null
+#ifndef DECL_H__
+#define DECL_H__
+
+#include "DeclBase.h"
+
+typedef std::string SignatureNodeID;
+
+namespace AST {
+class DeclContext;
+class TranslationUnitDecl;
+
+class Decl : public DeclBase
+{
+ public:
+ /// Construtor
+ Decl(Kind KD,DeclContext *_ctx) : DeclBase(KD,_ctx) , m_NextDecl(NULL) {};
+ ///
+ virtual Stmt *getBody() { return NULL;};
+ ///
+ virtual void setBody(Stmt *s) { ;};
+ ///
+ void setNextDeclInContext(Decl *d) { m_NextDecl = d;};
+ ///
+
+ Decl *getNextDeclInContext() { return m_NextDecl ;};
+
+ AST::TranslationUnitDecl *getTranslationUnitDecl() ;
+
+ protected:
+ Decl *m_NextDecl;
+};
+
+class NamedDecl;
+typedef std::vector<NamedDecl *> DeclContextLookupResult;
+
+}
+
+#include "DeclContext.h"
+
+#include "Type.h"
+namespace AST {
+#include "DeclNamedDecl.h"
+#include "DeclTypeDecl.h"
+#include "DeclPackageUseDecl.h"
+#include "DeclLabelDecl.h"
+#include "DeclValueDecl.h"
+#include "DeclVarDecl.h"
+#include "DeclParmVarDecl.h"
+#include "DeclFunctionDecl.h"
+#include "DeclRefStateDecl.h"
+#include "DeclFieldDecl.h"
+#include "DeclRecordDecl.h"
+#include "DeclTransitionDecl.h"
+#include "DeclTranslationUnitDecl.h"
+#include "DeclStateDecl.h"
+#include "DeclEventDecl.h"
+#include "DeclAutomatonDecl.h"
+
+}
+#include "TemplateBase.h"
+
+#endif
--- /dev/null
+#ifndef DECL
+ #define DECL
+#endif
+DECL(TranslationUnitDecl,Decl)
+DECL(PackageUseDecl,Decl)
+DECL(NamedDecl,Decl)
+DECL(TypeDecl,Decl)
+DECL(ValueTypeDecl,TypeDecl)
+DECL(TypedefDecl,TypeDecl)
+DECL(RecordDecl,NamedDecl)
+DECL(EnumDecl,TypeDecl)
+DECL(AgentTypeDecl,TypeDecl)
+DECL(AutomatonTypeDecl,AgentTypeDecl)
+DECL(BlockTypeDecl,AgentTypeDecl)
+DECL(SystemTypeDecl,AgentTypeDecl)
+DECL(RefStateDecl,Decl)
+DECL(LabelDecl,NamedDecl)
+DECL(ValueDecl,NamedDecl)
+DECL(EnumConstantDecl,ValueDecl)
+DECL(FieldDecl,ValueDecl)
+DECL(FunctionDecl,ValueDecl)
+DECL(TransitionDecl,ValueDecl)
+DECL(EventDecl,ValueDecl)
+DECL(TimerDecl,ValueDecl)
+DECL(VarDecl,ValueDecl)
+DECL(ParmVarDecl,VarDecl)
+DECL(StateDecl,NamedDecl)
+DECL(AgentDecl,NamedDecl)
+DECL(GateDecl,NamedDecl)
+DECL(ChannelDecl,NamedDecl)
+DECL(ChannelPathDecl,NamedDecl)
+DECL(ChannelEndPointDecl,NamedDecl)
+DECL(AutomatonDecl,AgentDecl)
+DECL(PackageDecl,AgentDecl)
+DECL(SystemDecl,AgentDecl)
+DECL(BlockDecl,AgentDecl)
+#undef DECL
--- /dev/null
+#ifndef DECLAUTOMATONDECL_H__
+#define DECLAUTOMATONDECL_H__
+
+
+
+/**
+ * AgentDecl is a generic class for all kind of agents that can be found in an lds
+ * description.
+ * AutomatonDecl,BlockDecl,PackageDecl,SystemDecl
+ */
+class AgentDecl : public NamedDecl , public DeclContext {
+ public:
+ typedef specific_decl_iterator<AST::EventDecl> event_iterator;
+ protected:
+ AgentDecl(Kind KD,DeclContext *DC,const std::string &l) : NamedDecl(KD,DC,l) ,DeclContext() {
+
+ };
+
+ public:
+
+ event_iterator events_begin() { return event_iterator(begin()) ; };
+ event_iterator events_end() { return event_iterator() ; };
+
+};
+
+
+/**
+ *
+ */
+class AutomatonDecl : public AgentDecl {
+ public:
+ typedef specific_decl_iterator<AST::EventDecl> event_iterator;
+ protected:
+ AutomatonDecl(DeclContext *DC,const std::string &l) : AgentDecl(DeclBase::AutomatonDecl,DC,l) {
+
+ };
+
+ public:
+ static AutomatonDecl *Create(DeclContext *DC,const std::string &name) {
+ return new AutomatonDecl(DC,name);
+ };
+
+ event_iterator events_begin() { return event_iterator(begin()) ; };
+ event_iterator events_end() { return event_iterator() ; };
+
+};
+
+/**
+ * In System description languages there are three kind of agents.
+ * and Packages
+ *
+ */
+class PackageDecl : public AgentDecl {
+ public:
+ typedef specific_decl_iterator<AST::EventDecl> event_iterator;
+ protected:
+ PackageDecl(DeclContext *DC,const std::string &l) : AgentDecl(DeclBase::PackageDecl,DC,l) {
+
+ };
+
+ public:
+ static PackageDecl *Create(DeclContext *DC,const std::string &name) {
+ return new PackageDecl(DC,name);
+ };
+
+ event_iterator events_begin() { return event_iterator(begin()) ; };
+ event_iterator events_end() { return event_iterator() ; };
+
+};
+
+/**
+ * This Class repesents an LDS system
+ *
+ */
+class SystemDecl : public AgentDecl {
+ public:
+ typedef specific_decl_iterator<AST::EventDecl> event_iterator;
+ protected:
+ SystemDecl(DeclContext *DC,const std::string &l) : AgentDecl(DeclBase::SystemDecl,DC,l) {
+
+ };
+
+ public:
+ static SystemDecl *Create(DeclContext *DC,const std::string &name) {
+ return new SystemDecl(DC,name);
+ };
+
+ event_iterator events_begin() { return event_iterator(begin()) ; };
+ event_iterator events_end() { return event_iterator() ; };
+
+};
+
+/**
+ * Represents and LDS Block
+ */
+class BlockDecl : public AgentDecl {
+ public:
+ typedef specific_decl_iterator<AST::EventDecl> event_iterator;
+ protected:
+ BlockDecl(DeclContext *DC,const std::string &l) : AgentDecl(DeclBase::BlockDecl,DC,l) {
+
+ };
+
+ public:
+ static BlockDecl *Create(DeclContext *DC,const std::string &name) {
+ return new BlockDecl(DC,name);
+ };
+
+ event_iterator events_begin() { return event_iterator(begin()) ; };
+ event_iterator events_end() { return event_iterator() ; };
+
+};
+
+
+#endif
--- /dev/null
+#ifndef DECLBASE_H__
+#define DECLBASE_H__
+
+namespace AST {
+
+class DeclContext;
+
+class DeclBase {
+ public:
+ enum Kind {
+ DECL_EMPTY
+ ,DECL_CONST
+ ,DECL_PROTOTYPE
+ ,DECL_BLOCK
+ ,DECL_TYPE
+#define DECL(Class,Base) ,Class
+#include "Decl.h.inc"
+#undef DECL
+ };
+
+ public:
+ DeclBase(Kind KD,DeclContext *_ctx=NULL) : m_DeclContext(_ctx) , m_Kind(KD) {};
+ virtual ~DeclBase() {};
+
+ ///
+ DeclContext *getDeclContext() {return m_DeclContext; } ;
+ ///
+ const DeclContext *getDeclContext() const {return const_cast<DeclContext *>(m_DeclContext); } ;
+
+ Kind getKind() { return m_Kind; };
+ protected:
+ DeclContext *m_DeclContext;
+ Kind m_Kind;
+};
+
+}
+
+#endif
--- /dev/null
+#ifndef BLOCKDECL_H__
+#define BLOCKDECL_H__
+
+
+class BlockDecl : public Decl {
+
+ public:
+ BlockDecl() {};
+ ~BlockDecl() {};
+};
+#endif
--- /dev/null
+#ifndef DECLCONTEXT_H__
+#define DECLCONTEXT_H__
+
+namespace AST {
+
+class Decl;
+/**
+ *
+ *
+ */
+class DeclContext {
+ public:
+ typedef std::vector<Decl *>::iterator iterator;
+ typedef std::vector<Decl *>::const_iterator const_iterator;
+
+ typedef DeclContextLookupResult lookup_result;
+
+ public:
+ DeclContext() : m_FirstDecl(NULL),m_LastDecl(NULL) {};
+ virtual ~DeclContext() {};
+ ///
+ void addHiddenDecl(Decl *d) ;
+ ///
+ void addDecl(Decl *_d)
+ {
+ addHiddenDecl(_d);
+ };
+ /// TOBe coded
+ DeclContext *getParentLookupContext() { return getParent() ; } ;
+
+ ///
+ DeclContext *getParent();
+ ///
+ const DeclContext *getParent() const;
+ /**
+ * Alright, Decl iterator will be a copy of the one from clang.
+ */
+ class decl_iterator {
+ Decl *m_Current;
+
+ public:
+ typedef Decl *value_type;
+ typedef const value_type &reference;
+ typedef const value_type *pointer;
+ typedef ptrdiff_t difference_type;
+
+ typedef std::forward_iterator_tag iterator_category;
+ decl_iterator() : m_Current(NULL) {}
+
+ explicit decl_iterator(Decl *d) : m_Current(d) {}
+
+ reference operator *() const {return m_Current; }
+ value_type operator ->() const { return m_Current; }
+
+ decl_iterator & operator++() {
+ m_Current = m_Current->getNextDeclInContext();
+ return *this;
+ }
+
+ friend bool operator ==(decl_iterator x,decl_iterator y ) {
+ return x.m_Current == y.m_Current;
+ }
+
+ friend bool operator !=(decl_iterator x,decl_iterator y ) {
+ return x.m_Current != y.m_Current;
+ }
+ };
+
+ //
+ // Implemented this to travel only through transitions and events ....
+ // That very usefull iterator
+ //
+ template <typename SpecificDecl>
+ class specific_decl_iterator {
+ DeclContext::decl_iterator Current;
+
+ void SkipToNext() {
+ while (*Current && ! dynamic_cast<SpecificDecl *>(*Current))
+ ++Current;
+ }
+ public:
+ typedef SpecificDecl *value_type;
+ typedef void reference;
+ typedef void pointer;
+ typedef std::iterator_traits<DeclContext::decl_iterator>::difference_type difference_type;
+ typedef std::forward_iterator_tag iterator_category;
+
+ specific_decl_iterator() : Current() {}
+ specific_decl_iterator(const AST::DeclContext::decl_iterator &_c) : Current(_c) {
+ SkipToNext();
+ }
+
+ // Access operators
+ value_type operator *() { return dynamic_cast<SpecificDecl *>(*Current) ; };
+ // Is there a bug here ?
+ value_type operator ->() { return dynamic_cast<SpecificDecl *>(*Current) ; };
+
+ // incr operators
+ specific_decl_iterator & operator ++() {
+ ++Current;
+ SkipToNext();
+ return *this;
+ }
+
+ specific_decl_iterator operator ++(int) {
+ specific_decl_iterator tmp (*this);
+ ++(*this);
+ return tmp;
+ }
+
+ // Comparison functions
+ friend bool operator ==(const specific_decl_iterator &x, const specific_decl_iterator &y) {
+ return (x.Current == y.Current );
+ }
+ friend bool operator !=(const specific_decl_iterator &x, const specific_decl_iterator &y) {
+ return (x.Current != y.Current );
+ }
+ };
+ /**
+ * From Clang DeclContext
+ * I finally added that iterator as well to retrieve DeclRefExpr that reference
+ * events for instance.
+ */
+ template <typename SpecificDecl,bool (SpecificDecl::*Acceptable)() const>
+ class filtered_decl_iterator {
+ DeclContext::decl_iterator Current;
+
+ void SkipToNext() {
+ SpecificDecl *sd = dynamic_cast<SpecificDecl *>(*Current);
+ while (*Current && (!(sd) ||
+ (Acceptable && !(sd->*Acceptable())) ))
+ ++Current;
+ }
+ public:
+ typedef SpecificDecl *value_type;
+ typedef void reference;
+ typedef void pointer;
+ typedef std::iterator_traits<DeclContext::decl_iterator>::difference_type difference_type;
+ typedef std::forward_iterator_tag iterator_category;
+
+ filtered_decl_iterator() : Current() {}
+ filtered_decl_iterator(const AST::DeclContext::decl_iterator &_c) : Current(_c) {
+ SkipToNext();
+ }
+
+ // Access operators
+ value_type operator *() { return dynamic_cast<SpecificDecl *>(*Current) ; };
+ // Is there a bug here ?
+ value_type operator ->() { return dynamic_cast<SpecificDecl *>(*Current) ; };
+
+ // incr operators
+ filtered_decl_iterator & operator ++() {
+ ++Current;
+ SkipToNext();
+ return *this;
+ }
+
+ filtered_decl_iterator operator ++(int) {
+ filtered_decl_iterator tmp (*this);
+ ++(*this);
+ return tmp;
+ }
+
+ // Comparison functions
+ friend bool operator ==(const filtered_decl_iterator &x, const filtered_decl_iterator &y) {
+ return (x.Current == y.Current );
+ }
+ friend bool operator !=(const filtered_decl_iterator &x, const filtered_decl_iterator &y) {
+ return (x.Current != y.Current );
+ }
+ };
+
+ //
+ decl_iterator begin() {return decl_iterator(m_FirstDecl) ;};
+ decl_iterator end() {return decl_iterator() ;};
+
+ lookup_result lookup(const std::string &_n) ;
+ ///
+ bool isTranslationUnit() const ;
+ ///
+ bool isRecord() const ;
+ ///
+ bool isFunction() const ;
+ ///
+ bool isState() const ;
+ ///
+ bool isTransition() const ;
+ ///
+ bool isAutomaton() const ;
+ ///
+ bool isBlock() const ;
+ ///
+ bool isPackage() const ;
+
+ protected:
+ Decl *m_FirstDecl,*m_LastDecl;
+ // Next is contained in Decl. and parent is Decl as well.
+};
+
+}
+#endif
--- /dev/null
+#ifndef EVENTDECL_H__
+#define EVENTDECL_H__
+
+/**
+ * \brief EventDecl is a signal which can be typed. If the signal
+ * has parameters The event is a method of each State that receives as parameter
+ * the types in the signal.
+ * TODO: To be completed to take into account
+ */
+class EventDecl : public ValueDecl,public DeclContext {
+ public:
+ typedef ::std::vector<AST::ParmVarDecl *> parameter_array;
+ typedef std::vector<AST::ParmVarDecl *>::iterator param_iterator;
+ typedef std::vector<AST::ParmVarDecl *>::const_iterator const_param_iterator;
+ protected:
+ EventDecl(DeclContext *DC,const std::string &n,Type *T) : ValueDecl(DeclBase::EventDecl,DC,n,T),DeclContext() {
+ }
+ public:
+ static EventDecl *Create(DeclContext *DC,const std::string &n,Type *T) {return new EventDecl(DC,n,T); };
+
+ unsigned int param_size() const { return m_Parameters.size(); }
+ param_iterator param_begin() { return m_Parameters.begin(); }
+ param_iterator param_end() { return m_Parameters.end(); }
+
+ void add_param(AST::ParmVarDecl *p) { m_Parameters.push_back(p); };
+
+ void set_parameters(const parameter_array &a)
+ { m_Parameters.resize(a.size()); std::copy (a.begin(),a.end(),m_Parameters.begin()); } ;
+
+ AST::ParmVarDecl * get_Parameter(int i) const
+ { return m_Parameters[i]; }
+ const parameter_array ¶meters() const { return m_Parameters; };
+ /// Build Signature of EventDecl. It is Used to store Types
+ void Signature(SignatureNodeID &id);
+ protected:
+ std::vector<AST::ParmVarDecl *> m_Parameters;
+
+};
+
+#endif
--- /dev/null
+#ifndef DECLFIELDDECL_H__
+#define DECLFIELDDECL_H__
+/**
+ * \brief represents the declaration of a :
+ * - variable < in this case it's a lvalue >
+ * - function < in this case it's the function designator >
+ * - enum < a constant>
+ *
+ * Missing the Type argument. A value has a type
+ * and something like QualType (plagia of clang)
+ */
+class FieldDecl : public ValueDecl
+{
+ protected:
+ bool m_Optional;
+ FieldDecl(Kind K,DeclContext *DC,const std::string &DeclName,Type *T,bool opt)
+ : m_Optional(opt), ValueDecl(K,DC,DeclName,T) {};
+ public:
+
+ /// Some Static functions...
+ static FieldDecl *Create(DeclContext *DC,const std::string &name,Type *T,bool opt=false) {
+ return new FieldDecl(DeclBase::FieldDecl,DC,name,T,opt);
+ };
+ bool isOptional() const { return m_Optional; }
+};
+
+#endif
--- /dev/null
+#ifndef DECLFUNCTIONDECL_H__
+#define DECLFUNCTIONDECL_H__
+
+
+class ParmVarDecl;
+
+class FunctionDecl : public ValueDecl , public DeclContext {
+ public:
+ typedef ::std::vector<AST::ParmVarDecl *> parameter_array;
+ typedef std::vector<AST::ParmVarDecl *>::iterator param_iterator;
+ typedef std::vector<AST::ParmVarDecl *>::const_iterator const_param_iterator;
+
+ protected:
+ Stmt *m_Body;
+ /// Missing parmaters
+ FunctionDecl (DeclContext *DC,const std::string &n,Type *T) : m_New(true), ValueDecl(DeclBase::FunctionDecl,DC,n,T), DeclContext() , m_Body(NULL) {
+ };
+ bool m_New; // Because of poor declartion, We check if the seen function call is new or not.
+ public:
+ Stmt *getBody() const { return m_Body; };
+ void setBody(Stmt *b) { m_Body = b; };
+ /// Some Static functions...
+ static FunctionDecl *Create(DeclContext *DC,const std::string &name,Type *T) {
+ return new FunctionDecl(DC,name,T);
+ };
+
+ inline bool isNew() { return m_New; }
+
+ unsigned int param_size() const { return m_Parameters.size(); }
+ param_iterator param_begin() { return m_Parameters.begin(); }
+ param_iterator param_end() { return m_Parameters.end(); }
+
+ void add_param(AST::ParmVarDecl *p) { m_New = false; m_Parameters.push_back(p); };
+
+ bool hasDefinition() { return m_Body != NULL; };
+ //
+ void Signature(SignatureNodeID &id);
+ protected:
+ std::vector<AST::ParmVarDecl *> m_Parameters;
+};
+
+#endif
--- /dev/null
+#ifndef LABELDECL_H__
+#define LABELDECL_H__
+
+/**
+ *
+ */
+class LabelDecl : public NamedDecl {
+
+ LabelDecl(Kind K,DeclContext *DC,const std::string &_n) : NamedDecl(DeclBase::LabelDecl,DC,_n) {};
+
+ LabelDecl(DeclContext *DC,const std::string &_n) : NamedDecl(DeclBase::LabelDecl,DC,_n) {};
+ public:
+ static LabelDecl *Create(DeclContext *DC,const std::string &_n) {
+ return new LabelDecl(DC,_n);
+ }
+
+
+
+};
+
+#endif
--- /dev/null
+#ifndef NAMEDDECL_H__
+#define NAMEDDECL_H__
+
+class NamedDecl : public Decl {
+ std::string m_Name;
+ public:
+ NamedDecl(Kind KD,DeclContext *DC,const std::string &_name) : Decl(KD,DC)
+ ,m_Name(_name)
+ {
+ m_DeclContext = DC;
+ };
+ ///
+ void setName(const std::string &s) {m_Name = s ; };
+ ///
+ //std::string getName() const {return m_Name; } ;
+ const std::string &getName() const {return m_Name; } ;
+};
+
+
+/**
+ * \brief Gate Declaration
+ * It' a Named Declaration that Holds a list a signalsDecl .
+ */
+class GateDecl : public NamedDecl
+{
+ protected:
+ Expr *m_Signals;
+ GateDecl(Kind K,DeclContext *DC,const std::string &DeclName) : NamedDecl(K,DC,DeclName)
+ , m_Signals(NULL)
+ {};
+
+ public:
+
+ /// Some Static functions... Missing Init Expression and Type should be integer I think
+ static GateDecl *Create(ASTContext &C,AST::DeclContext *DC,const std::string &name)
+ {
+ return new GateDecl(DeclBase::GateDecl,DC,name);
+ };
+
+};
+
+
+/**
+ * \brief ChannelEndPoint Declaration
+ * It' a Named Declaration that Holds a list a signalsDecl .
+ */
+class ChannelEndPointDecl : public NamedDecl
+{
+ public:
+ enum ChannelKind {eAGENT,eENV,eTHIS};
+ protected:
+ ChannelEndPointDecl(Kind K,DeclContext *DC,const std::string &DeclName,ChannelKind k)
+ : m_ChannelKind(k), NamedDecl(K,DC,DeclName)
+ {};
+
+ ChannelKind m_ChannelKind;
+ public:
+ /// Some Static functions... Missing Init Expression and Type should be integer I think
+ static ChannelEndPointDecl *Create(ASTContext &C,AST::DeclContext *DC,const std::string &name,ChannelKind k)
+ {
+ return new ChannelEndPointDecl(DeclBase::ChannelEndPointDecl,DC,name,k);
+ };
+
+ bool isAgent() const { return m_ChannelKind == eAGENT; };
+ bool isThis() const { return m_ChannelKind == eTHIS; };
+ bool isEnv() const { return m_ChannelKind == eENV; };
+ /* Missing getVia () return gateName if present */
+};
+
+
+/**
+ * \brief ChannelPath Declaration
+ * It' a Named Declaration that Holds a list a signalsDecl .
+ */
+class ChannelPathDecl : public NamedDecl
+{
+ protected:
+ AST::ChannelEndPointDecl *m_From,*m_To;
+
+ ChannelPathDecl(Kind K,DeclContext *DC,const std::string &DeclName) : NamedDecl(K,DC,DeclName)
+ , m_From(NULL)
+ , m_To(NULL)
+ {};
+
+ public:
+
+ /// Some Static functions... Missing Init Expression and Type should be integer I think
+ static ChannelPathDecl *Create(ASTContext &C,AST::DeclContext *DC,const std::string &name)
+ {
+ return new ChannelPathDecl(DeclBase::ChannelPathDecl,DC,name);
+ };
+
+ void setFrom(AST::ChannelEndPointDecl *d ) { m_From = d; }
+ void setTo(AST::ChannelEndPointDecl *d ) { m_To = d; }
+
+ AST::ChannelEndPointDecl * getFrom() const { return m_From; }
+ AST::ChannelEndPointDecl * getTo() const { return m_To; }
+};
+
+/**
+ * \brief Channel Declaration
+ * It' a Named Declaration that Holds a list a signalsDecl .
+ */
+class ChannelDecl : public NamedDecl , public DeclContext
+{
+ protected:
+ ChannelDecl(Kind K,DeclContext *DC,const std::string &DeclName) : DeclContext(), NamedDecl(K,DC,DeclName)
+ {};
+
+ public:
+
+ /// Some Static functions... Missing Init Expression and Type should be integer I think
+ static ChannelDecl *Create(ASTContext &C,AST::DeclContext *DC,const std::string &name)
+ {
+ return new ChannelDecl(DeclBase::ChannelDecl,DC,name);
+ };
+
+};
+
+
+#endif
--- /dev/null
+#ifndef PACKAGEUSEDECL_H__
+#define PACKAGEUSEDECL_H__
+
+class PackageUseDecl : public Decl {
+ std::string m_Name;
+ protected:
+ PackageUseDecl(ASTContext &AC,DeclContext *DC,std::string _name) : Decl(DeclBase::PackageUseDecl,DC)
+ ,m_Name(_name)
+ {
+ m_DeclContext = DC;
+ };
+ public:
+
+ static PackageUseDecl * Create(ASTContext &AC,DeclContext *DC,std::string _name)
+ {
+ return new PackageUseDecl(AC,DC,_name);
+ }
+ ///
+ void setName(const std::string &s) {m_Name = s ; };
+ ///
+ std::string getName() const {return m_Name; } ;
+};
+
+#endif
--- /dev/null
+#ifndef DECLPARMVARDECL_H__
+#define DECLPARMVARDECL_H__
+
+class ParmVarDecl : public VarDecl
+{
+ protected:
+ ParmVarDecl(Kind K,DeclContext *DC,const std::string &DeclName,Type *T) : VarDecl(K,DC,DeclName,T) {};
+
+ // ParmVarDecl(DeclContext *DC,const std::string &DeclName) : VarDecl(DeclBase::ParmVarDecl,DC,DeclName) {};
+ public:
+
+ /// Some Static functions...
+ static ParmVarDecl *Create(DeclContext *DC,const std::string &name,Type *T) {
+ return new ParmVarDecl(DeclBase::ParmVarDecl,DC,name,T);
+ };
+};
+
+#endif
--- /dev/null
+#ifndef DECLRECORDDECL_H
+#define DECLRECORDDECL_H
+
+
+/**
+ * \brief represents the declaration of a :
+ * - variable < in this case it's a lvalue >
+ * - function < in this case it's the function designator >
+ * - enum < a constant>
+ *
+ * Missing the Type argument. A value has a type
+ * and something like QualType (plagia of clang)
+ *
+ * A Record is either an Union or a Struct type.
+ *
+ */
+class RecordDecl : public TypeDecl , public DeclContext
+{
+ public:
+ enum RecordType {RT_Struct ,RT_Union};
+
+ protected:
+ RecordDecl(Kind K,RecordType _rt,DeclContext *DC,const std::string &DeclName)
+ : TypeDecl(K,DC,DeclName)
+ , DeclContext()
+ , m_RType(_rt)
+ {};
+ RecordType m_RType;
+ public:
+
+ /// Some Static functions...
+ static RecordDecl *CreateStruct(DeclContext *DC,const std::string &name) {
+ return new RecordDecl(DeclBase::RecordDecl,RT_Struct,DC,name);
+ };
+ static RecordDecl *CreateUnion(DeclContext *DC,const std::string &name) {
+ return new RecordDecl(DeclBase::RecordDecl,RT_Union,DC,name);
+ };
+
+ inline bool isStruct() const { return m_RType == RT_Struct ; }
+
+ inline bool isUnion() const { return m_RType == RT_Union; }
+ //
+ void Signature(SignatureNodeID &id);
+
+ typedef specific_decl_iterator<AST::FieldDecl> field_iterator;
+
+ field_iterator field_begin() const;
+ field_iterator field_end() const;
+
+ bool fields_empty() const { return field_begin() == field_end() ; }
+};
+
+
+#endif /*DECLRECORDDECL_H*/
--- /dev/null
+#ifndef DECLREFSTATEDECL_H__
+#define DECLREFSTATEDECL_H__
+
+class Decl;
+class StateDecl;
+/**
+ * Stores a reference to a Value Declaration
+ * Somehow, this makes the connection between Declarations and statement expressions
+ */
+class RefStateDecl : public Decl
+{
+ AST::StateDecl *m_value;
+ public:
+
+ RefStateDecl(AST::StateDecl *v ) : Decl(DeclBase::RefStateDecl,NULL) ,m_value(v) {};
+
+ ~RefStateDecl() {};
+
+ AST::StateDecl *getDecl() const { return m_value ;};
+};
+
+#endif
--- /dev/null
+#ifndef STATEDECL_H__
+#define STATEDECL_H__
+
+/**
+ * \brief StateDecl The body shall probably contain Transitions
+ * The events the State Reponds to as well.
+ * Maybe, this class should inherit from LabelDecl, in order to be able to retrieve the statement
+ */
+class StateDecl : public NamedDecl, public DeclContext {
+ protected:
+
+ StateDecl(DeclContext *DC,const std::string &n) : NamedDecl(DeclBase::StateDecl,DC,n) , DeclContext() {
+ }
+
+ public:
+ static StateDecl *Create(DeclContext *DC,const std::string &n) {return new StateDecl(DC,n); };
+
+ protected:
+
+};
+
+#endif
--- /dev/null
+#ifndef DECLTRANSITIONDECL_H__
+#define DECLTRANSITIONDECL_H__
+
+
+class ParmVarDecl;
+class EventDecl;
+class RefStateDecl;
+class StateDecl;
+/**
+ * \brief a transition is owned by a state.
+ * A transition should react on an event list
+ * A transition know the default destination state that can be SAME
+ * I should complete the interface of the TransitionDecl to reflect the statement above.
+ *
+ */
+class TransitionDecl : public ValueDecl , public DeclContext {
+ public:
+ typedef ::std::vector<AST::ParmVarDecl *> parameter_array;
+ typedef std::vector<AST::ParmVarDecl *>::iterator param_iterator;
+ typedef std::vector<AST::ParmVarDecl *>::const_iterator const_param_iterator;
+
+ typedef DeclContext::specific_decl_iterator<AST::EventDecl> event_iterator;
+
+ protected:
+#define MAX_PARAMETERS 10
+ // AST::ParmVarDecl *m_Parameters[MAX_PARAMETERS];
+ Stmt *m_Body;
+ std::vector<AST::ParmVarDecl *> m_Parameters;
+ /// Missing parmaters
+ TransitionDecl (DeclContext *DC,const std::string &n,AST::RefStateDecl *_rf = NULL,Type *T = NULL) : ValueDecl(DeclBase::TransitionDecl,DC,n,T)
+ , DeclContext()
+ , m_Body(NULL)
+ , m_State(_rf)
+ {
+ };
+
+ std::string m_TargetState;
+ AST::RefStateDecl *m_State;
+ public:
+ Stmt *getBody() const { return m_Body; };
+ void setBody(Stmt *b) { m_Body = b; };
+ /// Some Static functions...
+ static TransitionDecl *Create(DeclContext *DC,const std::string &name,AST::RefStateDecl *_rs = NULL,Type *T =NULL) {
+ return new TransitionDecl(DC,name,_rs,T);
+ };
+
+ // TargetState on Events
+ void setTargetState(const std::string &s) { m_TargetState = s; };
+ std::string getTargetState() const { return m_TargetState ; };
+ inline AST::StateDecl *getState() const { return m_State->getDecl(); };
+ // Iterators
+ unsigned int param_size() const { return m_Parameters.size(); }
+ param_iterator param_begin() { return m_Parameters.begin(); }
+ param_iterator param_end() { return m_Parameters.end(); }
+
+ event_iterator events_begin() { return event_iterator(begin()) ; };
+ event_iterator events_end() { return event_iterator() ; };
+
+
+ void add_param(AST::ParmVarDecl *p) { m_Parameters.push_back(p); };
+
+ bool hasDefinition() { return m_Body != NULL; };
+ protected:
+};
+
+#endif
--- /dev/null
+#ifndef DECLTRANSLATIONUNITDECL_H__
+#define DECLTRANSLATIONUNITDECL_H__
+
+class ASTContext;
+
+class TranslationUnitDecl : public Decl , public DeclContext {
+
+ protected:
+ ASTContext &m_ASTContext;
+ TranslationUnitDecl(ASTContext &AC,DeclContext *DC)
+ : Decl(DeclBase::TranslationUnitDecl,DC) ,DeclContext(),m_ASTContext(AC) {
+
+ };
+
+ public:
+ static TranslationUnitDecl *Create(ASTContext &AC,DeclContext *DC,const std::string &name) {
+ return new TranslationUnitDecl(AC,DC);
+ };
+ ASTContext &getASTContext() const { return m_ASTContext;}
+
+};
+
+#endif
--- /dev/null
+#ifndef DECLTYPEDECL_H
+#define DECLTYPEDECL_H
+
+class ASTContext;
+class EventDecl;
+
+/**
+ * TypeDeclaration base class.
+ */
+class TypeDecl : public NamedDecl
+{
+ friend class ASTContext;
+ protected:
+ TypeDecl(Kind K,DeclContext *DC,const std::string &DeclName)
+ : NamedDecl(K,DC,DeclName) , m_Init(NULL), m_TypeForDecl(NULL)
+ {};
+ Type *m_TypeForDecl;
+ Stmt *m_Init; // Init Expression for global variables and so on
+ public:
+ ///
+ void setInit(Expr *e)
+ { m_Init = e; } ;
+ ///
+ Expr *getInit(Expr *e)
+ { return dynamic_cast<AST::Expr *>(m_Init); };
+
+ ///
+ Type *getTypeForDecl() const { return m_TypeForDecl; };
+ ///
+ void setTypeForDecl(Type *T) { m_TypeForDecl = T; };
+} ;
+
+/**
+ * Typedef acutally for LDS it's more something like syntype
+ */
+class TypedefDecl : public TypeDecl
+{
+ protected:
+ TypedefDecl(DeclContext *DC,const std::string _n)
+ : TypeDecl(DeclBase::TypedefDecl,DC,_n )
+ , m_Constraint(NULL)
+ , m_BaseType(NULL)
+ {}
+ Type *m_BaseType;
+ Stmt *m_Constraint; // Init Expression for global variables and so on
+ public:
+ static TypedefDecl *Create(ASTContext &AC,DeclContext *DC,const std::string &_name)
+ {
+ return new TypedefDecl(DC,_name);
+ }
+ bool hasConstraint() const { return m_Constraint != NULL; }
+ void setConstraint(Stmt *s) { m_Constraint = s ; };
+
+ void setBaseType(AST::Type *bt) { m_BaseType = bt; };
+ AST::Type *getBaseType() const { return m_BaseType ; };
+
+ Expr *getContraint()
+ { return dynamic_cast<AST::Expr *>(m_Init); };
+ /// Missing function to get Canonical Type
+
+ Type *getCanonicalType() const { return NULL; };
+};
+
+/**
+ * LDS it's more something like datatype definition
+ * constructed
+ * or
+ */
+class ValueTypeDecl : public TypeDecl , public DeclContext
+{
+ protected:
+ ValueTypeDecl(DeclContext *DC,const std::string _n)
+ : TypeDecl(DeclBase::ValueTypeDecl,DC,_n )
+ , DeclContext()
+ , m_Specialization(NULL)
+ {}
+
+ Stmt *m_Init; // Init Expression for global variables and so on
+ Type *m_Specialization; //
+ public:
+ static ValueTypeDecl *Create(ASTContext &AC,DeclContext *DC,const std::string &_name)
+ {
+ return new ValueTypeDecl(DC,_name);
+ }
+ /// Some test functions
+ bool isStruct() const ;
+
+ bool isUnion() const ;
+
+ bool isEnum() const ;
+
+ bool isArray() const ;
+
+ void setSpecialization(Type *_t) { m_Specialization = _t ; } ;
+ /// Missing function to get Canonical Type
+};
+
+/**
+ * Enum acutally for LDS it's more something like synon
+ */
+class EnumDecl : public TypeDecl , public DeclContext
+{
+ protected:
+ EnumDecl(DeclContext *DC,const std::string &_n) : TypeDecl(DeclBase::EnumDecl,DC,_n ) , DeclContext() {}
+ public:
+ static EnumDecl *Create(ASTContext &AC,DeclContext *DC,const std::string &_name)
+ {
+ return new EnumDecl(DC,_name);
+ }
+ /// Missing function to get Canonical Type
+};
+
+
+/**
+ *
+ */
+class AgentTypeDecl : public TypeDecl , public DeclContext
+{
+ protected:
+ AgentTypeDecl(Kind K,DeclContext *DC,const std::string &_n) : TypeDecl(K,DC,_n ) , DeclContext() {}
+ public:
+ typedef specific_decl_iterator<AST::EventDecl> event_iterator;
+ /// Missing function Like isAbstract if Parameterized Agent
+ public:
+
+ event_iterator events_begin() { return event_iterator(begin()) ; };
+ event_iterator events_end() { return event_iterator() ; };
+
+};
+
+/**
+ * An AutomatonType is a class that implementes the behavior of the automaton.
+ * An AutomatonDecl is an instance of an automatonTypeDecl.
+ */
+class AutomatonTypeDecl : public AgentTypeDecl
+{
+ protected:
+ AutomatonTypeDecl(DeclContext *DC,const std::string &_n) : AgentTypeDecl(DeclBase::AutomatonTypeDecl,DC,_n ) {}
+ public:
+ static AutomatonTypeDecl *Create(ASTContext &AC,DeclContext *DC,const std::string &_name)
+ {
+ return new AutomatonTypeDecl(DC,_name);
+ }
+};
+
+/**
+ *
+ *
+ */
+class BlockTypeDecl : public AgentTypeDecl
+{
+ protected:
+ BlockTypeDecl(DeclContext *DC,const std::string &_n) : AgentTypeDecl(DeclBase::BlockTypeDecl,DC,_n ) {}
+ public:
+ static BlockTypeDecl *Create(ASTContext &AC,DeclContext *DC,const std::string &_name)
+ {
+ return new BlockTypeDecl(DC,_name);
+ }
+ /// Missing function to
+};
+
+/**
+ * A System Type is the toplevel type description of a system.
+ *
+ */
+class SystemTypeDecl : public AgentTypeDecl
+{
+ protected:
+ SystemTypeDecl(DeclContext *DC,const std::string &_n) : AgentTypeDecl(DeclBase::SystemTypeDecl,DC,_n ) {}
+ public:
+ static SystemTypeDecl *Create(ASTContext &AC,DeclContext *DC,const std::string &_name)
+ {
+ return new SystemTypeDecl(DC,_name);
+ }
+};
+
+/*
+ * vim: et sw=2 ts=2 list:
+ */
+
+#endif
--- /dev/null
+#ifndef DECLVALUEDECL_H__
+#define DECLVALUEDECL_H__
+/**
+ * \brief represents the declaration of a :
+ * - variable < in this case it's a lvalue >
+ * - function < in this case it's the function designator >
+ * - enum < a constant>
+ *
+ * Missing the Type argument. A value has a type
+ */
+class ValueDecl : public NamedDecl
+{
+ protected:
+ Type *m_Type;
+ ValueDecl(Kind K,DeclContext *DC,const std::string &DeclName, Type *T) : NamedDecl(K,DC,DeclName),m_Type(T) {};
+
+ public:
+
+ /// Some Static functions...
+ static ValueDecl *Create(DeclContext *DC,const std::string &name,Type *T) {
+ return new ValueDecl(DeclBase::ValueDecl,DC,name,T);
+ };
+
+ Type *getType() const { return m_Type;}
+
+};
+
+/**
+ * \brief Constants declared in an enum are of type EnumConstantDecl
+ * It' a value.
+ */
+class EnumConstantDecl : public ValueDecl
+{
+ protected:
+ Expr *m_InitExpr;
+ EnumConstantDecl(Kind K,DeclContext *DC,const std::string &DeclName, Type *T) : ValueDecl(K,DC,DeclName,T)
+ , m_InitExpr(NULL)
+ {};
+
+ public:
+
+ /// Some Static functions... Missing Init Expression and Type should be integer I think
+ static EnumConstantDecl *Create(ASTContext &C,AST::EnumDecl *DC,const std::string &name,Type *T = NULL) {
+ return new EnumConstantDecl(DeclBase::EnumConstantDecl,DC,name,T);
+ };
+
+ void setInitExpr(Expr *e) { m_InitExpr =e ; }
+};
+
+
+/**
+ * \brief Timer Declaration
+ * It' a value.
+ */
+class TimerDecl : public ValueDecl
+{
+ protected:
+ Expr *m_InitExpr;
+ TimerDecl(Kind K,DeclContext *DC,const std::string &DeclName, Type *T) : ValueDecl(K,DC,DeclName,T)
+ , m_InitExpr(NULL)
+ {};
+
+ public:
+
+ /// Some Static functions... Missing Init Expression and Type should be integer I think
+ static TimerDecl *Create(ASTContext &C,AST::DeclContext *DC,const std::string &name,Type *T = NULL) {
+ return new TimerDecl(DeclBase::TimerDecl,DC,name,T);
+ };
+
+ void setInitExpr(Expr *e) { m_InitExpr =e ; }
+};
+
+
+
+/*
+ * vim: et sw=2 ts=2 list:
+ */
+#endif
--- /dev/null
+#ifndef DECLVARDECL_H__
+#define DECLVARDECL_H__
+
+/**
+ * TODO: Complete the class so that the type will be associated
+ * with the variable.
+ */
+class VarDecl : public ValueDecl
+{
+ protected:
+ VarDecl(Kind K,DeclContext *DC,const std::string &DeclName,Type *T,Stmt *_init = NULL)
+ : m_Init(_init), ValueDecl(K,DC,DeclName,T) , m_Constant(false) {
+ };
+ //VarDecl(DeclContext *DC,const std::string &DeclName) : ValueDecl(DeclBase::VarDecl,DC,DeclName) {};
+ Stmt *m_Init; // Init Expression for global variables and so on
+ bool m_Constant;
+ public:
+
+ /// Some Static functions...
+ static VarDecl *Create(DeclContext *DC,const std::string &name,Type *T,Stmt *_init = NULL) {
+ return new VarDecl(DeclBase::VarDecl,DC,name,T,_init);
+ };
+ /** */
+ inline bool isConstant() const { return m_Constant; }
+ ///
+ bool hasInit() const
+ { return m_Init != NULL; };
+ ///
+ inline void setConstant(bool _flag) { m_Constant = _flag; };
+ ///
+ void setInit(Expr *e)
+ { m_Init = e; } ;
+ ///
+ Expr *getInit(Expr *e)
+ { return dynamic_cast<AST::Expr *>(m_Init); };
+};
+/*
+ * vim: et sw=2 ts=2 list:
+ */
+#endif
--- /dev/null
+#ifndef EXPR_H__
+#define EXPR_H__
+
+#include "OperationKinds.h"
+#include "Type.h"
+namespace AST {
+
+class ASTContext;
+class ValueDecl;
+/**
+ * An expression has a type.
+ * An expression can be evaluated or not.
+ * An expression can be a constant result. The result be be evaluated.
+ * The state of the evaluation must be kept (avoid to evaluate the same expression several times).
+ *
+ * I should be able to check if the expression is an (enum VK_...) RValue or LValue
+ *
+ */
+class Expr : public Stmt {
+ protected:
+ Type *m_Type;
+ public:
+ Expr(StmtClass SC,Type *_t = NULL) : Stmt(SC) , m_Type(_t) {};
+ virtual ~Expr() {};
+ /**
+ * Result
+ */
+ struct EvalResult {
+ union {
+ long l;
+ bool b;
+ }u;
+ bool m_Error; // Error during evaluation
+ };
+
+ inline void setType( Type *t) { m_Type = t; };
+
+ inline Type *getType( ) { return m_Type ; };
+
+ /**
+ * May be set this function virtual. It might need more
+ * memory
+ */
+ bool evalute(EvalResult &result) ;
+ /**
+ * evaluate constant expression should exist too
+ */
+
+ /** */
+ bool isConstantExpression();
+};
+
+
+/**
+ * Expresssion that reflects an expression in parentheses.
+ *
+ */
+class ParenExpr : public Expr {
+ Stmt *m_Stmt;
+
+ public:
+ ParenExpr(Stmt *s) : Expr(ParenExprClass) , m_Stmt(s) {
+ }
+
+ Stmt *getStmt() const { return m_Stmt; };
+};
+
+/**
+ * Expresssion that reflects a list of expression in parentheses.
+ *
+ */
+class ParenListExpr : public Expr {
+ enum { MAX = 10 };
+ Stmt *m_Stmts[MAX];
+ int m_NbExprs;
+ public:
+ ParenListExpr() ;
+
+ void addExpr(Expr *e) {
+ if (m_NbExprs < MAX && e)
+ m_Stmts[m_NbExprs++] = e;
+ };
+
+ int getNumExprs() {return m_NbExprs; };
+
+ Expr *getExpr(int idx) {
+ return dynamic_cast<Expr *>(m_Stmts[idx]);
+ }
+
+ Expr** getExprs() {
+ return reinterpret_cast<Expr **>(m_Stmts);
+ }
+
+ virtual range_iterator children() ;
+
+};
+
+/**
+ * Expresssion that reflects
+ * a structure or record member access.
+ * M.x M is base and x mem
+ */
+class MemberExpr : public Expr {
+ Stmt *m_Base;
+ ValueDecl *m_Member;
+ protected:
+ /**
+ *
+ * Misssing Value Kind which LValue or RValue
+ */
+ MemberExpr(Expr *base,ValueDecl *mem,Type *Ty) ;
+
+ public:
+
+ static MemberExpr *Create(ASTContext &AC,Expr *base,ValueDecl *_member,Type *Ty);
+
+ Expr* getBase() const
+ {
+ return reinterpret_cast<Expr *>(m_Base);
+ }
+
+ ValueDecl *getMember() const
+ {
+ return (m_Member);
+ }
+};
+
+
+/**
+ * LdsThis represents this is LDS record operators.
+ *
+ */
+class LdsThisExpr : public Expr {
+ public:
+ LdsThisExpr(Type *Ty) : Expr(LdsThisExprClass,Ty)
+ {
+ }
+
+};
+
+
+/**
+ * We need an expression to store array Subcription Eg A[4] for instance
+ */
+class ArraySubscriptExpr : public Expr {
+ Expr *m_Base;
+ Expr *m_Index;
+ protected:
+ /**
+ *
+ * Misssing Value Kind which LValue or RValue
+ */
+ ArraySubscriptExpr(Expr *base,Expr *idx,Type *Ty) ;
+
+ public:
+
+ static ArraySubscriptExpr *Create(ASTContext &AC,Expr *base,Expr *_idx,Type *Ty);
+
+ Expr* getBase() const
+ {
+ return reinterpret_cast<Expr *>(m_Base);
+ }
+
+ Expr *getIndex() const
+ {
+ return (m_Index);
+ }
+};
+
+
+/**
+ * CREATE expression for an Agent
+ * This shall be Pid
+ *
+ */
+class CreateExpr : public Expr {
+ Expr *m_Agent;
+ public:
+ CreateExpr(Expr *agent,Type *Ty) : m_Agent(agent), Expr(CreateExprClass,Ty)
+ {
+ }
+
+ Expr *getAgent() const { return m_Agent; };
+};
+
+/**
+ * CREATE expression for an Agent
+ * This shall be Pid
+ *
+ */
+class PidExpr : public Expr {
+ Expr *m_Agent;
+ public:
+ enum Pid {
+ Self
+ , OffSpring
+ , Parent
+ , Sender
+ , Referenced /* User Identified Pid*/
+ };
+
+ PidExpr(Pid p,Expr *agent,Type *Ty) : m_PidKind(p) , m_Agent(agent), Expr(PidExprClass,Ty)
+ {
+ }
+
+ Pid getKind() const { return m_PidKind; };
+
+ Expr *getAgent() const { return m_Agent; };
+ protected:
+ Pid m_PidKind;
+};
+
+
+#include "ExprIntegerLiteral.h"
+#include "ExprDeclRefExpr.h"
+#include "ExprCallExpr.h"
+// Missing Member Expression example : X.y or X->y
+#include "ExprStringLiteral.h"
+#include "ExprFloatLiteral.h"
+#include "ExprBinaryOperatorExpr.h"
+#include "ExprConditionalOperator.h"
+}
+#endif
--- /dev/null
+#ifndef BINARYOPERATION_H__
+#define BINARYOPERATION_H__
+
+class BinaryOperator : public Expr {
+
+ public:
+ typedef BinaryOperatorKind OpCode;
+ protected:
+
+ enum {LHS,RHS,END_EXPR};
+ Stmt *SubExprs[END_EXPR];
+
+ OpCode m_OpCode;
+ public:
+ BinaryOperator(Expr *lhs,Expr *rhs,OpCode op) : Expr(Stmt::BinaryOperatorClass), m_OpCode(op) {
+ SubExprs[LHS] = lhs;
+ SubExprs[RHS] = rhs;
+ }
+
+ Expr *getLHS() const {return dynamic_cast<Expr *>(SubExprs[LHS]);}
+
+ Expr *getRHS() const {return dynamic_cast<Expr *>(SubExprs[RHS]);}
+
+ OpCode getOpcode() const {return m_OpCode;};
+
+ const char * getOpcodeStr() const;
+};
+
+/**
+ *
+ *
+ */
+class UnaryOperator : public Expr {
+ public:
+ typedef UnaryOperatorKind OpCode;
+ protected:
+ enum {RHS,END_EXPR};
+ Stmt *SubExprs[END_EXPR];
+
+ OpCode m_OpCode;
+ public:
+ UnaryOperator(Expr *rhs,OpCode op) : Expr(Stmt::UnaryOperatorClass),m_OpCode(op) {
+ SubExprs[RHS] = rhs;
+ }
+
+ Expr *getSubExpr() const {return dynamic_cast<Expr *>(SubExprs[RHS]);}
+
+ OpCode getOpcode() const {return m_OpCode;};
+};
+
+/**
+ :vim:et:sw=4:ts=4
+ */
+#endif
--- /dev/null
+#ifndef CALLEXPR_H__
+#define CALLEXPR_H__
+
+
+/**
+ * Is there a type associated to a class expression ?
+ * maybe the result of the call.
+ */
+class CallExpr : public Expr
+{
+ enum {MAX_ARGS = 20} ;
+ enum {FN,ARGS};
+ Stmt *m_Args[MAX_ARGS];
+ int m_NumArgs;
+ public:
+ /**
+ * fn should be a DeclRefExpr. A reference to the function Declation.
+ * The declared function can be undefined, referenced and so on.
+ */
+ CallExpr(const DeclContext *ctx,Expr *fn,std::vector<Expr*> args);
+
+ CallExpr(const DeclContext *DC,Expr *fn) : Expr(CallExprClass) , m_NumArgs(0) {
+ m_Args[FN] = fn;
+ m_Args[1] = NULL;
+ }
+ ~CallExpr() {};
+
+ int getNumArgs() {return m_NumArgs; };
+
+ Expr *getCallee( ) { return dynamic_cast<Expr *>(m_Args[FN]); } ;
+
+ FunctionDecl *getCalleeDecl() const ;
+
+ Expr *getArg(unsigned i)
+ {
+ return static_cast<Expr*>(m_Args[i +1]);
+ }
+ const Expr *getArg(unsigned i) const
+ {
+ return static_cast<Expr*>(m_Args[i +1]);
+ }
+ range_iterator arguments()
+ {
+ return range_iterator(&m_Args[1],&m_Args[getNumArgs()+1]);
+ }
+
+ range_iterator children() {
+ return range_iterator(&m_Args[1],&m_Args[getNumArgs()+1]);
+ }
+ protected:
+};
+
+#endif
--- /dev/null
+#ifndef CONDITIONALOPERATOR_H__
+#define CONDITIONALOPERATOR_H__
+
+class ConditionalOperator : public Expr
+{
+};
+
+#endif
--- /dev/null
+#ifndef DECLREFEXPR_H__
+#define DECLREFEXPR_H__
+
+class Decl;
+class ValueDecl;
+class FunctionDecl;
+class VarDecl;
+/**
+ * Stores a reference to a Value Declaration
+ * Somehow, this makes the connection between Declarations and statement expressions
+ */
+class DeclRefExpr : public Expr
+{
+ ValueDecl *m_value;
+ public:
+ DeclRefExpr(ValueDecl *v ) : Expr(Stmt::DeclRefExprClass) ,m_value(v) {};
+ ~DeclRefExpr() {};
+ /// Return The reference declaration
+ AST::Decl *getDecl() const ;
+ ///
+ bool isRefFunctionDecl() const ;
+
+ bool isRefVarDecl() const ;
+
+ bool isRefParmVarDecl() const ;
+
+};
+
+#endif
--- /dev/null
+#ifndef FLOATLITERALEXPR_H__
+#define FLOATLITERALEXPR_H__
+
+class FloatLiteral : public Expr {
+};
+
+#endif
--- /dev/null
+#ifndef INTEGERLITERAL_H__
+#define INTEGERLITERAL_H__
+
+class IntegerLiteral : public Expr {
+ public:
+ IntegerLiteral(StmtClass SC,unsigned int value) : Expr(SC) ,m_value(value) {
+ }
+ IntegerLiteral(unsigned int value,Type *_t = NULL) : Expr(IntegerLiteralClass,_t) ,m_value(value) {
+ }
+
+ /**
+ * In term should return an APValue or Value type
+ */
+ unsigned int get_value() const { return m_value; };
+
+ protected:
+ unsigned int m_value;
+};
+
+#endif
--- /dev/null
+#ifndef STRINGLITERALEXPR_H__
+#define STRINGLITERALEXPR_H__
+
+/**
+ * This is a constant array of characters
+ * As long as operand5 makes conversions of StringLiterals into
+ * call expressions, I will use the isConstantArray Flag
+ */
+class StringLiteral : public Expr
+{
+ std::string m_string;
+ public:
+ bool isConstantArray;
+ StringLiteral(const std::string &s,Type *_t)
+ : isConstantArray(false), Expr(StringLiteralClass,_t),m_string(s) {
+ }
+
+ std::string getString() const {return m_string; } ;
+
+ void print(std::ostream &os) { os<<m_string;};
+};
+
+#endif
--- /dev/null
+#ifndef FORMAL_CONTEXT_PARAMETER_H__
+#define FORMAL_CONTEXT_PARAMETER_H__
+
+
+namespace AST {
+
+ /**
+ * @brief template parameters and specialization parameters
+ * need to be
+ *
+ */
+ class FormalContextParameter {
+ public
+ :
+ enum ArgKind {
+ /// No Formal Context Parameter for this definition
+ Null = 0
+ /// The Formal Parameter repesents a Type
+ , Type
+ /// The Formal Parameter represents a Declaration
+ , Declaration
+ /// The Formal Parameter represents an Expression
+ , Expression
+ };
+ private:
+ /// Declaration Argument
+ struct DA {
+ unsigned int Kind;
+ ValueDecl *D;
+ };
+
+ struct I {
+ unsigned int Kind;
+ Expr *E;
+ };
+ /// Possible Formal types Decl, Integer, Expression, Type
+ union {
+ struct DA DeclArg;
+ struct I Integer;
+ struct I Expression;
+ }
+ public:
+ /* Constructors */
+ FormalContextParameter(Expr *e);
+
+ FormalContextParameter(Type *e);
+
+ FormalContextParameter(Decl *e);
+
+ /* */
+ ArgKing getKind() const { return DeclArg.Kind; };
+
+ bool isNull() const { return getKind() == Null; }
+ /**/
+ Expr *getAsExpr() const;
+
+ Decl *getAsDecl() const ;
+
+ Type *getAsType() const ;
+ };
+}
+#endif
--- /dev/null
+#ifndef OPERATION_KINDS_H__
+#define OPERATION_KINDS_H__
+
+namespace AST {
+
+enum BinaryOperatorKind {
+ // Operators are listed in ORDER of precedence
+ BO_Mul, BO_Div, BO_Rem, // Multiplicative operators
+ BO_Add, BO_Sub, // Additive operators
+ BO_Shl, BO_Shr, // Bitwise shift operators
+ BO_LT, BO_GT, BO_LE, BO_GE, // Relation operators
+ BO_EQ, BO_NE, // Equal Operators
+ BO_And, // Bitwise And, Xor, Or
+ BO_Xor,
+ BO_Or,
+ BO_LAnd, // Logical And / Or
+ BO_LOr,
+ BO_Assign // Assignement Operators
+};
+
+enum UnaryOperatorKind {
+ UO_PostInc, UO_PostDec, // postfix increment and decrement
+ UO_PreInc, UO_PreDec, // prefix increment and decrement
+ UO_Plus, UO_Minus, // Unary arithmetic
+ UO_Not, UO_LNot, UO_Test //
+};
+
+}
+
+#endif
--- /dev/null
+#ifndef STMT_H__
+#define STMT_H__
+
+
+#include "StmtIterator.h"
+namespace AST {
+
+class DeclContext;
+class Expr;
+class LabelDecl;
+
+
+class ExprIterator
+{
+ Stmt **I;
+ public:
+ ExprIterator(Stmt **i) : I(i) {};
+ ExprIterator() : I(NULL) {};
+ ~ExprIterator() {};
+
+ // Iteration operator
+ ExprIterator &operator ++() { I++ ; return *this ; };
+ ExprIterator operator -(size_t i) { return I - i; };
+ ExprIterator operator +(size_t i) { return I + i ;};
+
+ // Access
+ Expr *operator [](size_t i);
+
+ Expr *operator *() const ;
+ Expr *operator ->() const;
+ // Comparison
+ bool operator ==(const ExprIterator &R) { return I == R.I; } ;
+ bool operator !=(const ExprIterator &R) { return I != R.I; } ;
+ bool operator >(const ExprIterator &R) { return I > R.I; } ;
+ bool operator >=(const ExprIterator &R) { return I >= R.I; } ;
+};
+
+/**
+ *
+ */
+class Stmt {
+ public:
+ enum StmtClass {
+ NoStmtClass = 0
+#define STMT(CLASS,PARENT) , CLASS##Class
+#include "AST/Stmt.h.inc"
+#undef STMT
+ };
+
+ typedef StmtIterator child_iterator;
+ typedef StmtRange range_iterator;
+ public:
+ Stmt(StmtClass SC) : m_StmtClass(SC) {};
+ virtual ~Stmt() {};
+
+ StmtClass getStmtClass() const { return m_StmtClass;};
+
+ virtual range_iterator children() {return range_iterator();}
+
+ child_iterator child_begin() {return children().first; }
+
+ child_iterator child_end() {return children().second; }
+
+ protected:
+ StmtClass m_StmtClass;
+};
+
+#include "StmtCompoundStmt.h"
+#include "StmtSwitchCaseStmt.h"
+#include "StmtBreakStmt.h"
+#include "StmtReturnStmt.h"
+#include "StmtDeclStmt.h"
+#include "StmtLabelStmt.h"
+#include "StmtGotoStmt.h"
+#include "StmtForStmt.h"
+#include "StmtWhileStmt.h"
+#include "StmtSwitchStmt.h"
+#include "StmtIfStmt.h"
+#include "StmtAsmStmt.h"
+#include "StmtOutputStmt.h"
+}
+#endif
--- /dev/null
+#ifndef STMT
+# define STMT(Type,Base)
+#endif
+
+STMT(SwitchCaseStmt,Stmt)
+STMT(BreakStmt,Stmt)
+STMT(ReturnStmt,Stmt)
+STMT(DeclStmt,Stmt)
+STMT(LabelStmt,Stmt)
+STMT(GotoStmt,Stmt)
+STMT(ForStmt,Stmt)
+STMT(WhileStmt,Stmt)
+STMT(SwitchStmt,Stmt)
+STMT(IfStmt,Stmt)
+STMT(OutputStmt,Stmt)
+STMT(AsmStmt,Stmt)
+STMT(LdsAsmStmt,AsmStmt)
+STMT(CompoundStmt,Stmt)
+
+STMT(Expr,Stmt)
+#ifndef EXPR
+# define EXPR(Type,Base) STMT(Type,Base)
+#endif
+
+EXPR(ParenExpr,Expr)
+EXPR(ParenListExpr,Expr)
+EXPR(CallExpr,Expr)
+EXPR(DeclRefExpr,Expr)
+EXPR(MemberExpr,Expr)
+EXPR(ArraySubscriptExpr,Expr)
+EXPR(LdsThisExpr,Expr)
+EXPR(CreateExpr,Expr)
+EXPR(PidExpr,Expr)
+EXPR(StringLiteral,Expr)
+EXPR(IntegerLiteral,Expr)
+EXPR(FloatLiteral,Expr)
+EXPR(BinaryOperator,Expr)
+EXPR(UnaryOperator,Expr)
+EXPR(ConditionalOperator,Expr)
+#undef STMT
--- /dev/null
+#ifndef ASMSTMT_H__
+#define ASMSTMT_H__
+
+class StringLiteral ;
+class TimerDecl;
+class VarDecl;
+/**
+ *
+ */
+class AsmStmt : public Stmt {
+
+ enum {LIT,EXPR,END} ;
+
+ Stmt *m_Stmts[END];
+ std::string m_Op;
+ public:
+ AsmStmt(DeclContext *DC,StmtClass KD,const std::string &op) ;
+
+ StringLiteral *getLiteral() const ;
+
+ VarDecl *getVarDecl() const;
+
+ TimerDecl *getTimerDecl() const;
+
+ void setLiteral(Expr *S) ;
+ /* For set timer. time expression to be evaluated */
+ void setExpr(Expr *S) ;
+
+ /// For SET and RESET Statements
+ bool isArgVariable() const;
+
+ bool isArgTimer() const;
+};
+
+
+/*
+ * Possible ASM opcodes in lds language ....
+ * AEL_RETURN
+ * AEL_RESET FLG
+ * AEL_SET FLG
+ * AEL_JSR_IND FLG
+ */
+class LdsAsmStmt : public AsmStmt {
+
+ public:
+ enum LdsAslOpcodes {
+ AEL_RETURN
+ ,AEL_NOP
+ ,AEL_LOOP_MSG
+ ,AEL_RESET
+ ,AEL_SET
+ ,AEL_JSR_IND
+ ,AEL_RTS
+ };
+ protected:
+ long m_Opcode;
+ public:
+
+ LdsAsmStmt(DeclContext *DC,const std::string &op );
+
+ long getOpcode() const { return m_Opcode ; };
+};
+
+#endif
--- /dev/null
+#ifndef BREAKSTMT_H__
+#define BREAKSTMT_H__
+
+/**
+ *
+ */
+class BreakStmt : public Stmt
+{
+ Stmt *m_Cond;
+
+ public:
+ BreakStmt(DeclContext *DC,Expr *cond);
+
+ Expr *getCond();
+
+};
+
+#endif
--- /dev/null
+#ifndef COMPOUNDSTMT_H__
+#define COMPOUNDSTMT_H__
+
+/**
+ * \brief This class contains a list og Statement. {Stmt Stmt ....}
+ * Can represent a Block
+ */
+class CompoundStmt : public Stmt
+{
+ public:
+ typedef std::vector<Stmt *>::iterator iterator;
+ typedef std::vector<Stmt *>::const_iterator const_iterator;
+ public:
+
+
+ CompoundStmt() : Stmt(Stmt::CompoundStmtClass) {}
+ ///
+ void addStmt(Stmt *_s) { m_Stmts.push_back(_s); } ;
+ ///
+ iterator begin() {return m_Stmts.begin();};
+ ///
+ const_iterator begin() const {return m_Stmts.begin();};
+ ///
+ iterator end() {return m_Stmts.end();};
+ ///
+ const_iterator end() const {return m_Stmts.end();};
+ protected:
+
+ std::vector<Stmt *> m_Stmts;
+};
+#endif
--- /dev/null
+#ifndef DECLSTMT_H__
+#define DECLSTMT_H__
+
+class DeclStmt : public Stmt {
+ protected:
+
+ public:
+
+
+};
+
+#endif
--- /dev/null
+#ifndef FORSTMT_H__
+#define FORSTMT_H__
+
+class ForStmt : public Stmt {
+};
+
+#endif
--- /dev/null
+#ifndef GOTOSTMT_H__
+#define GOTOSTMT_H__
+
+class GotoStmt : public Stmt {
+ LabelDecl *m_Label;
+
+ public:
+ GotoStmt(LabelDecl *_l) : Stmt(Stmt::GotoStmtClass) , m_Label(_l) {
+ }
+ LabelDecl *getLabel() const {return m_Label;};
+
+ void setLabel(LabelDecl *_l) {m_Label = _l;};
+};
+
+#endif
--- /dev/null
+#ifndef IFSTMT_H__
+#define IFSTMT_H__
+
+
+class IfStmt : public Stmt {
+ enum {COND,THEN,ELSE,END} ;
+ Stmt *m_Stmts[END];
+ public:
+ IfStmt(DeclContext *DC,Expr *cond,Stmt *_then,Stmt *_else = NULL) ;
+
+ range_iterator children() ;
+
+ Expr *getCond() const ;
+
+ Stmt *getThen() const { return m_Stmts[THEN]; };
+
+ Stmt *getElse() const { return m_Stmts[ELSE]; };
+
+ void setElse(Stmt *s) { m_Stmts[ELSE] = s;};
+};
+
+#endif
--- /dev/null
+#ifndef STMTITERATOR_H__
+#define STMTITERATOR_H__
+#include <cassert>
+#include <cstddef>
+#include <iterator>
+
+
+namespace AST {
+
+class Stmt;
+/**
+ *
+ *
+ */
+template <typename Derived,typename Reference>
+class StmtIteratorImpl : public std::iterator<std::forward_iterator_tag,Reference,ptrdiff_t,
+ Reference,Reference>
+{
+ protected:
+ Stmt **m_Stmt;
+ public:
+ StmtIteratorImpl() : m_Stmt(NULL) {}
+
+ StmtIteratorImpl(Stmt **s) : m_Stmt(s) {}
+
+ Derived &operator ++() {
+ ++m_Stmt;
+ return static_cast<Derived &>(*this);
+ }
+
+ Derived operator ++(int) {
+ Derived tmp = static_cast<Derived &>(*this);
+ ++m_Stmt;
+ return tmp;
+ }
+
+ bool operator ==(const Derived &RHS) const {
+ return m_Stmt == RHS.m_Stmt;
+ }
+
+ bool operator !=(const Derived &RHS) const {
+ return m_Stmt != RHS.m_Stmt;
+ }
+
+ Reference operator *() const { return *m_Stmt; };
+ Reference operator ->() const { return operator *(); };
+};
+
+
+/**
+ *
+ *
+ */
+struct StmtIterator : public StmtIteratorImpl<StmtIterator,Stmt *&>
+{
+ explicit StmtIterator() : StmtIteratorImpl<StmtIterator,Stmt *&>() {}
+
+ StmtIterator(Stmt **s) : StmtIteratorImpl<StmtIterator,Stmt *&>(s) {}
+};
+
+
+struct ConstStmtIterator : public StmtIteratorImpl<ConstStmtIterator,Stmt *>
+{
+ explicit ConstStmtIterator() : StmtIteratorImpl<ConstStmtIterator,Stmt *>() {}
+
+ ConstStmtIterator(Stmt **s) : StmtIteratorImpl<ConstStmtIterator,Stmt *>(s) {}
+};
+
+/**
+ *
+ *
+ */
+struct StmtRange : std::pair<StmtIterator,StmtIterator> {
+
+ public:
+ StmtRange() {}
+ StmtRange(const StmtIterator &begin,const StmtIterator &end) :
+ std::pair<StmtIterator,StmtIterator>(begin,end) {};
+
+ bool empty() const { return first == second ; }
+
+ Stmt *operator->() const { return first.operator->();}
+
+ Stmt *&operator*() const { return first.operator*();}
+
+ StmtRange &operator++() {
+ assert(!empty());
+ ++first;
+ return *this;
+ }
+ StmtRange operator++(int) {
+ assert(!empty());
+ StmtRange copy = *this;
+ ++first;
+ return copy;
+ }
+
+ friend const StmtIterator &begin(const StmtRange &range) {
+ return range.first;
+ }
+
+ friend const StmtIterator &end(const StmtRange &range) {
+ return range.second;
+ }
+};
+
+
+/**
+ *
+ *
+ */
+struct ConstStmtRange : std::pair<ConstStmtIterator,ConstStmtIterator> {
+
+ public:
+ ConstStmtRange() {}
+ ConstStmtRange(const ConstStmtIterator &begin,const ConstStmtIterator &end) :
+ std::pair<ConstStmtIterator,ConstStmtIterator>(begin,end) {};
+
+ bool empty() const { return first == second ; }
+
+ Stmt *operator->() const { return first.operator->();}
+
+ Stmt *operator*() const { return first.operator*();}
+
+ ConstStmtRange &operator++() {
+ assert(!empty());
+ ++first;
+ return *this;
+ }
+ ConstStmtRange operator++(int) {
+ assert(!empty());
+ ConstStmtRange copy = *this;
+ ++first;
+ return copy;
+ }
+
+ friend const ConstStmtIterator &begin(const ConstStmtRange &range) {
+ return range.first;
+ }
+
+ friend const ConstStmtIterator &end(const ConstStmtRange &range) {
+ return range.second;
+ }
+};
+
+
+
+}
+#endif
--- /dev/null
+#ifndef LABELSTMT_H__
+#define LABELSTMT_H__
+
+
+class LabelStmt : public Stmt {
+};
+
+#endif
--- /dev/null
+#ifndef STMTOUTPUT_H_
+#define STMTOUTPUT_H_
+
+
+class StringLiteral ;
+class TimerDecl;
+class VarDecl;
+class EventDecl;
+class DeclRefExpr;
+
+/**
+ * An output Statment sends a signal to a destination.
+ * The destination is a Pid expression0, agent or channel
+ * A signal can have parameters
+ * Buy default signals are sent to THIS
+ */
+class OutputStmt : public Stmt {
+
+ enum { SIG,DEST,END} ;
+ enum { MAX_ARGS = 20} ;
+ Stmt *m_Args[MAX_ARGS];
+ int m_NumArgs;
+ public:
+
+ Stmt *m_Stmts[END];
+ std::string m_Op;
+ public:
+ /* Sig should be a DeclRefExpr */
+ OutputStmt(DeclContext *DC,const std::string &op,DeclRefExpr *sig,Expr *dest) ;
+
+ inline int getNumArgs() const { return m_NumArgs ; };
+
+ void setArgs(std::vector<AST::Expr *> &_args);
+
+ EventDecl *getEventDecl() const ;
+
+ void setDestination(Expr *dest);
+
+ Expr *getArg(unsigned i);
+
+ const Expr *getArg(unsigned i) const ;
+
+ range_iterator arguments()
+ {
+ return range_iterator(&m_Args[0],&m_Args[getNumArgs()]);
+ }
+
+ range_iterator children() {
+ return range_iterator(&m_Args[0],&m_Args[getNumArgs()]);
+ }
+};
+
+/**
+ * vim: et sw=2 ts=2 list:
+ */
+#endif
--- /dev/null
+#ifndef RETURNSTMT_H__
+#define RETURNSTMT_H__
+
+
+class ReturnStmt : public Stmt {
+ Stmt *m_RetExpr;
+ bool m_Indirect;
+ public:
+ ReturnStmt(Expr *RetVal,bool ind = false) : Stmt(ReturnStmtClass) , m_RetExpr((Stmt *)RetVal) ,m_Indirect(ind) {
+ }
+
+ // If the function was reach through an indirect JUMP, this flag shoud be set to TRUE
+ bool getIndirect() const { return m_Indirect; };
+
+};
+
+#endif
--- /dev/null
+#ifndef SWITCHCASESTMT_H__
+#define SWITCHCASESTMT_H__
+
+class SwitchCaseStmt : public Stmt {
+ Stmt *m_SubStmt;
+ Expr *m_Cond;
+ public:
+
+ SwitchCaseStmt(Expr *_cond,Stmt *stmt) : Stmt(Stmt::SwitchCaseStmtClass) , m_Cond(_cond) , m_SubStmt(stmt) {
+ };
+
+
+
+ Stmt *getSubStmt() const { return m_SubStmt; };
+
+ Expr *getCond() const { return m_Cond; };
+ /* Iterator access */
+};
+
+#endif
--- /dev/null
+#ifndef SWITCHSTMT_H__
+#define SWITCHSTMT_H__
+
+
+
+class SwitchStmt : public Stmt {
+ std::vector<Stmt *> m_CaseStmts;
+ Expr *m_Cond;
+ public:
+ typedef std::vector<Stmt *>::iterator case_iterator;
+ typedef std::vector<Stmt *>::const_iterator const_case_iterator;
+
+ SwitchStmt(Expr *_cond) : Stmt(Stmt::SwitchStmtClass) , m_Cond(_cond) {
+ };
+
+ size_t NbCases() const { return m_CaseStmts.size(); };
+
+ void addCaseStmt(Stmt *_s) { m_CaseStmts.push_back(_s); };
+
+ Stmt *getStmt(int i) const { return m_CaseStmts[i]; };
+
+ Expr *getCond() const { return m_Cond; };
+ /* Iterator access */
+ case_iterator case_begin() { return m_CaseStmts.begin() ; };
+ case_iterator case_end() { return m_CaseStmts.end() ; };
+
+ const_case_iterator case_begin() const { return m_CaseStmts.begin() ; };
+ const_case_iterator case_end() const { return m_CaseStmts.end() ; };
+};
+
+#endif
--- /dev/null
+#ifndef STMTVISITOR_H__
+#define STMTVISITOR_H__
+
+/**
+ * Got the example for clang AST. I really like there way of doing things
+ */
+
+namespace AST {
+
+template <typename Impl, typename RetTy = void>
+class StmtVisitorBase {
+ public:
+ StmtVisitorBase() {}
+ virtual ~StmtVisitorBase() {}
+
+ public:
+#define PTR(x) x *
+#if 0
+ std::cout<<"Visit: DISPATCH "<< # NAME <<" "<<S->getStmtClass()<<std::endl;\
+
+#endif
+#define DISPATCH(NAME,CLASS) \
+ return static_cast<Impl *>(this)->Visit ## NAME( static_cast<CLASS *>(S));
+
+ RetTy Visit(AST::Stmt *S) {
+ if ( PTR(AST::BinaryOperator) BinOp = dynamic_cast<PTR(AST::BinaryOperator)>(S) ) {
+ switch (BinOp->getOpcode()) {
+ case BO_Mul : DISPATCH (BinMul, AST::BinaryOperator);
+ case BO_Div : DISPATCH (BinDiv, AST::BinaryOperator);
+ case BO_Rem : DISPATCH (BinRem, AST::BinaryOperator);
+ case BO_Add : DISPATCH (BinAdd, AST::BinaryOperator);
+ case BO_Sub : DISPATCH (BinSub, AST::BinaryOperator);
+ case BO_Shl : DISPATCH (BinShl, AST::BinaryOperator);
+ case BO_Shr : DISPATCH (BinShr, AST::BinaryOperator);
+ case BO_LT : DISPATCH (BinLT, AST::BinaryOperator);
+ case BO_GT : DISPATCH (BinGT, AST::BinaryOperator);
+ case BO_LE : DISPATCH (BinLE, AST::BinaryOperator);
+ case BO_GE : DISPATCH (BinGE, AST::BinaryOperator);
+ case BO_EQ : DISPATCH (BinEQ, AST::BinaryOperator);
+ case BO_NE : DISPATCH (BinNE, AST::BinaryOperator);
+ case BO_And : DISPATCH (BinAnd, AST::BinaryOperator);
+ case BO_Xor : DISPATCH (BinXor, AST::BinaryOperator);
+ case BO_Or : DISPATCH (BinOr, AST::BinaryOperator);
+ case BO_LAnd : DISPATCH (BinLAnd, AST::BinaryOperator);
+ case BO_LOr : DISPATCH (BinLOr, AST::BinaryOperator);
+ case BO_Assign : DISPATCH (BinAssign , AST::BinaryOperator);
+ };
+
+ } else if (PTR(AST::UnaryOperator) UnOp = dynamic_cast<PTR(AST::UnaryOperator)>(S)) {
+ switch (UnOp->getOpcode()) {
+ case UO_PostInc : DISPATCH (UnaryPostInc, AST::UnaryOperator);
+ case UO_PostDec : DISPATCH (UnaryPostDec, AST::UnaryOperator);
+ case UO_PreInc : DISPATCH (UnaryPreInc, AST::UnaryOperator);
+ case UO_PreDec : DISPATCH (UnaryPreDec, AST::UnaryOperator);
+ case UO_Plus : DISPATCH (UnaryPlus, AST::UnaryOperator);
+ case UO_Minus : DISPATCH (UnaryMinus, AST::UnaryOperator);
+ case UO_Not : DISPATCH (UnaryNot, AST::UnaryOperator);
+ case UO_LNot : DISPATCH (UnaryLNot, AST::UnaryOperator);
+ case UO_Test : DISPATCH (UnaryTest, AST::UnaryOperator);
+ default:
+ ;
+ }
+ }
+ // Maybe if it's not of Type BinOperator nor Unary Operator, Vistit Stamtement TO be done
+#define STMT(CLASS,PARENT) \
+ case AST::Stmt::CLASS ## Class : DISPATCH(CLASS,CLASS);
+
+ switch (S->getStmtClass() ) {
+#include "AST/Stmt.h.inc"
+ default:
+ ;
+ };
+ std::cout<<"ERROR TODO Visit .... "<<S->getStmtClass()<<std::endl;
+ return RetTy();
+ }
+
+ RetTy VisitStmt(PTR(Stmt) S) { return RetTy(); };
+
+#define STMT(CLASS,PARENT) \
+ RetTy Visit ## CLASS (PTR(CLASS) S) { \
+ DISPATCH(PARENT,PARENT); \
+ }
+#include "AST/Stmt.h.inc"
+#undef STMT
+
+ // Default Implementation for Binary Operators
+ //
+#define DEFAULT_BINOP(NAME,UNUSED) \
+ RetTy Visit ## NAME(PTR(AST::BinaryOperator) S) { \
+ DISPATCH ( BinaryOperator,AST::BinaryOperator) \
+ }
+
+ DEFAULT_BINOP(BinMul, AST::BinaryOperator);
+ DEFAULT_BINOP(BinDiv, AST::BinaryOperator);
+ DEFAULT_BINOP(BinRem, AST::BinaryOperator);
+ DEFAULT_BINOP(BinAdd, AST::BinaryOperator);
+ DEFAULT_BINOP(BinSub, AST::BinaryOperator);
+ DEFAULT_BINOP(BinShl, AST::BinaryOperator);
+ DEFAULT_BINOP(BinShr, AST::BinaryOperator);
+ DEFAULT_BINOP(BinLT, AST::BinaryOperator);
+ DEFAULT_BINOP(BinGT, AST::BinaryOperator);
+ DEFAULT_BINOP(BinLE, AST::BinaryOperator);
+ DEFAULT_BINOP(BinGE, AST::BinaryOperator);
+ DEFAULT_BINOP(BinEQ, AST::BinaryOperator);
+ DEFAULT_BINOP(BinNE, AST::BinaryOperator);
+ DEFAULT_BINOP(BinAnd, AST::BinaryOperator);
+ DEFAULT_BINOP(BinXor, AST::BinaryOperator);
+ DEFAULT_BINOP(BinOr, AST::BinaryOperator);
+ DEFAULT_BINOP(BinLAnd, AST::BinaryOperator);
+ DEFAULT_BINOP(BinLOr, AST::BinaryOperator);
+ DEFAULT_BINOP(BinAssign, AST::BinaryOperator);
+
+ // Default Implementation for Unary Opertor
+#define DEFAULT_UNOP(NAME,UNUSED) \
+ RetTy Visit ## NAME(PTR(AST::UnaryOperator) S) { \
+ DISPATCH ( UnaryOperator,AST::UnaryOperator) \
+ }
+ DEFAULT_UNOP(UnaryPostInc, AST::UnaryOperator);
+ DEFAULT_UNOP(UnaryPostDec, AST::UnaryOperator);
+ DEFAULT_UNOP(UnaryPreInc, AST::UnaryOperator);
+ DEFAULT_UNOP(UnaryPreDec, AST::UnaryOperator);
+ DEFAULT_UNOP(UnaryPlus, AST::UnaryOperator);
+ DEFAULT_UNOP(UnaryMinus, AST::UnaryOperator);
+ DEFAULT_UNOP(UnaryNot, AST::UnaryOperator);
+ DEFAULT_UNOP(UnaryLNot, AST::UnaryOperator);
+ DEFAULT_UNOP(UnaryTest, AST::UnaryOperator);
+
+};
+
+template <typename Impl,typename RetTy>
+class StmtVisitor : public StmtVisitorBase<Impl,RetTy> {};
+
+
+
+}
+#endif
--- /dev/null
+#ifndef WHILESTMT_H__
+#define WHILESTMT_H__
+
+class WhileStmt : public Stmt {
+ enum {COND,BODY,ELSE,END} ;
+ Stmt *m_Stmts[END];
+ public:
+ WhileStmt(DeclContext *DC,Expr *cond,Stmt *_body) ;
+
+ Expr *getCond() const ;
+
+ Stmt *getBody() const { return m_Stmts[BODY]; };
+
+};
+
+#endif
--- /dev/null
+#ifndef TEMPLATE_BASE_H
+#define TEMPLATE_BASE_H
+
+namespace AST {
+class ASTContext;
+class RecordDecl;
+class Expr;
+class TypedefDecl;
+
+/**
+ * @brief for syntype and so on, there is a need
+ * to collect the actual context parameters that are
+ * somehome similar to template arguments. For that
+ * I created this class to store either Types, Literals,
+ * Expressions that can be given as acual parameters.
+ * With this class I hope I'll be able to solve the issue
+ * with InfoArray, Vectors and strings.
+ */
+class TemplateArgument
+{
+ protected:
+
+ union TV {
+ Expr *m_Expression;
+ Type *m_Type;
+ } m_TV;
+
+ enum eKind {
+ eNull
+ ,eType
+ ,eExpression
+ } m_Kind;
+
+ TemplateArgument(ASTContext *C,Expr *_a)
+ : m_Kind(eExpression)
+ {
+ m_TV.m_Expression=_a;
+ };
+ TemplateArgument(ASTContext *C,Type *_a)
+ : m_Kind(eType)
+ {
+ m_TV.m_Type=_a;
+ };
+ public:
+
+
+ static TemplateArgument *
+ Create(ASTContext &c,AST::Type *TD )
+ { return new TemplateArgument(&c,TD); };
+
+ static TemplateArgument *
+ Create(ASTContext &c,Expr *E )
+ { return new TemplateArgument(&c,E); };
+
+ bool isExpression() const
+ { return m_Kind == eExpression; }
+
+ bool isType() const
+ { return m_Kind == eType; }
+
+ Type *getType() const
+ { return m_TV.m_Type; }
+
+ Expr *getExpression() const
+ { return m_TV.m_Expression; }
+};
+
+/// Array
+typedef std::vector<AST::TemplateArgument *> TemplateArgumentArray;
+typedef TemplateArgumentArray::iterator TemplateArgIterator;
+typedef TemplateArgumentArray::const_iterator TemplateArgConstIterator;
+
+}
+#endif
--- /dev/null
+#ifndef AST_TYPE_H
+#define AST_TYPE_H
+
+
+namespace AST {
+class ASTContext;
+class RecordDecl;
+class TypedefDecl;
+class ValueTypeDecl;
+
+/**
+ * This class represents an AST Type. There are different kind of types!
+ * Typedef types, Function prototype types, Structures, Builtin Types, Enumerated types,
+ * function pointer types, reference types
+ */
+class Type {
+ public:
+ enum TypeClass {
+ #define TYPE(Class,Base) Class,
+ #define ABSTRACT_TYPE(Class,Base)
+#include "AST/Types.h.inc"
+ };
+ protected:
+ unsigned int TC;
+ /**
+ *
+ */
+ Type(TypeClass Cls);
+ Type(const Type &) {};
+ virtual ~Type() {};
+ friend class AST::ASTContext;
+ public:
+ /**
+ *
+ */
+ TypeClass getClass() const
+ { return static_cast<TypeClass>(TC); };
+
+ const char *getTypeClassName() const {
+ switch (TC) {
+#define ABSTRACT_TYPE(Derived,Base)
+#define TYPE(Derived,Base) case Derived: return #Derived;
+#include "AST/Types.h.inc"
+ default: return "unknown class";
+ }
+ };
+};
+
+/**
+ * Declare the specific type of Types as well
+ */
+class BuiltinType : public Type
+{
+ public:
+ enum Kind {
+#define BUILTIN_TYPE(Id,SigletonId) Id ,
+#include "AST/BuiltinTypes.h.def"
+ noKind
+ } m_Kind;
+ protected:
+ BuiltinType(Kind K) :m_Kind(K), Type(Builtin) {};
+ friend class ASTContext;
+ public:
+ const char *getNameAsStr() const;
+
+ Kind getKind() const { return m_Kind ; }
+};
+
+/**
+ * Function type does not have name. It as a signature
+ * composed of Return Type, Parameter Types, expections
+ * Several Functions can have the same type
+ */
+class FunctionType : public Type
+{
+ protected:
+ /**
+ *
+ */
+ FunctionType(TypeClass tc) : Type(tc) {};
+ friend class ASTContext;
+ public:
+};
+
+/**
+ *
+ */
+class FunctionProtoType : public FunctionType
+{
+ protected:
+ FunctionProtoType() : FunctionType(FunctionProto) {};
+ friend class ASTContext;
+ public:
+};
+
+
+/**
+ *
+ */
+class ReferenceType : public Type
+{
+ protected:
+ ReferenceType(TypeClass tc) : Type(tc) {};
+ public:
+};
+
+/**
+ *
+ */
+class LValueReferenceType : public ReferenceType
+{
+ protected:
+ LValueReferenceType() : ReferenceType(LValueReference) {};
+ friend class ASTContext;
+ public:
+};
+
+/**
+ *
+ */
+class RValueReferenceType : public ReferenceType
+{
+ protected:
+ RValueReferenceType() : ReferenceType(RValueReference) {};
+ friend class ASTContext;
+ public:
+};
+
+/**
+ * A array containes
+ */
+class ArrayType : public Type
+{
+ protected:
+ Type *m_ElementType;
+ ArrayType(TypeClass tc,Type *e)
+ : Type(tc)
+ , m_ElementType(e)
+ {};
+ friend class ASTContext;
+ public:
+ const Type *getElementType() const { return m_ElementType; };
+};
+
+/**
+ *
+ */
+class ConstantArrayType : public ArrayType
+{
+ protected:
+ size_t m_Size;
+ ConstantArrayType(Type *et,size_t s)
+ : ArrayType(ConstantArray,et)
+ , m_Size(s)
+ {};
+ friend class ASTContext;
+ public:
+};
+
+/**
+ *
+ */
+class TypedefType : public Type
+{
+ TypedefDecl *m_Decl;
+ protected:
+ TypedefType(const AST::TypedefDecl *td)
+ : m_Decl(const_cast<AST::TypedefDecl *>(td)), Type(Typedef) {};
+ friend class ASTContext;
+ public:
+ TypedefDecl *getDecl() const { return m_Decl ; }
+};
+
+/**
+ * @brief I'm not sure if I want to use this.
+ */
+class ValueType : public Type
+{
+ ValueTypeDecl *m_Decl;
+ protected:
+ ValueType(const AST::ValueTypeDecl *vt)
+ : m_Decl(const_cast<AST::ValueTypeDecl *>(vt)), Type(Value) {};
+ friend class ASTContext;
+ public:
+ ValueTypeDecl *getDecl() const { return m_Decl ; }
+};
+
+
+/**
+ *
+ */
+class EnumType : public Type
+{
+ protected:
+ EnumType() : Type(Enum) {};
+ public:
+};
+
+/**
+ * I think this can be used for Structure and so on
+ */
+class RecordType : public Type
+{
+ RecordDecl *m_Decl;
+ protected:
+ RecordType(const AST::RecordDecl *decl)
+ : m_Decl(const_cast<AST::RecordDecl *>(decl)),Type(Record) {};
+ friend class ASTContext;
+ public:
+ RecordDecl *getDecl() const { return m_Decl ; }
+};
+
+
+}
+
+#endif /*AST_TYPE_H*/
--- /dev/null
+#ifndef ABSTRACT_TYPE
+# define ABSTRACT_TYPE(Class,Base) TYPE(Class,Base)
+#endif
+
+#ifndef NON_CANONICAL_TYPE
+# define NON_CANONICAL_TYPE(Class,Base) TYPE(Class,Base)
+#endif
+
+
+TYPE(Builtin , Type)
+ABSTRACT_TYPE(Reference , Type)
+TYPE(LValueReference , ReferenceType)
+TYPE(RValueReference , ReferenceType)
+
+TYPE(Array,Type)
+TYPE(ConstantArray,ArrayType)
+
+ABSTRACT_TYPE(Function , Type)
+TYPE(FunctionProto ,FunctionType)
+/* K&R function declaration */
+/* TYPE(FunctionNoProto , FunctionType) */
+/**
+May be those are Builtin Types
+Natural
+Time
+Duration
+*/
+
+NON_CANONICAL_TYPE(Typedef,Type)
+NON_CANONICAL_TYPE(Value,Type)
+
+TYPE(Enum,Type)
+TYPE(Record,Type)
+
+#undef TYPE
+#undef ABSTRACT_TYPE
+#undef NON_CANONICAL_TYPE
--- /dev/null
+#ifndef ASTMULTIPLEXCONSUMER_H__
+#define ASTMULTIPLEXCONSUMER_H__
+
+/**
+ * Simple class that should call Handler.... on each consumer.
+ *
+ */
+class ASTMultiplexConsumer : public ASTConsumer
+{
+ public:
+ ASTMultiplexConsumer(std::vector<ASTConsumer *> &consumers);
+
+ protected:
+ std::vector<ASTConsumer *> m_consumers;
+};
+
+#endif
--- /dev/null
+#ifndef __CGDEBUG_H__
+#define __CGDEBUG_H__
+
+#if defined(DEBUG)
+
+#define CGDBG(fmt) do { fprintf(stderr,fmt "\n"); } while(0)
+#define CGDBG_ARGS(fmt,args...) do { fprintf(stderr,fmt "\n",args); } while(0)
+
+#define CGDBG_EXPR(fmt) do { fprintf(stderr,fmt "\n"); } while(0)
+#define CGDBG_EXPR_ARGS(fmt,args...) do { fprintf(stderr,fmt "\n",args); } while(0)
+
+#if defined(CG_DEBUG_IF)
+#define CGDBG_IF(fmt) do { fprintf(stderr,fmt "\n"); } while(0)
+#define CGDBG_IF_ARGS(fmt,args...) do { fprintf(stderr,fmt "\n",args); } while(0)
+#else
+#define CGDBG_IF(fmt)
+#define CGDBG_IF_ARGS(fmt,args...)
+#endif
+
+#else
+
+#define CGDBG(fmt)
+#define CGDBG_ARGS(fmt,args...)
+
+#define CGDBG_IF(fmt)
+#define CGDBG_IF_ARGS(fmt,args...)
+
+#define CGDBG_EXPR(fmt)
+#define CGDBG_EXPR_ARGS(fmt,args...)
+
+#endif
+
+#endif
--- /dev/null
+#ifndef CM_CONSUMER_H__
+#define CM_CONSUMER_H__
+
+class CMConsumer : public ASTConsumer
+{
+ public:
+ CMConsumer:
+ protected:
+ // should own a RecursiveVisitor
+}
+#endif
--- /dev/null
+#ifndef CODEGENFUNCTION_H__
+#define CODEGENFUNCTION_H__
+#include <stack>
+namespace aeb {
+namespace lds {
+ class SwitchInst;
+namespace CodeGen {
+ class CodGenModule;
+ /**
+ * This class is responsible for IR code generation.
+ * Actually, I would like to be able to generate llvm IR
+ * or LDS IR. LDS is an inhouse VM Very basic with few instructions.
+ *
+ */
+ class CodeGenFunction {
+
+ public:
+ //typedef aeb::dlilist<aeb::lds::BasicBlock> BlockList;
+ // What is needed ?
+ // A Builder that provide Blocks and set
+ Behavior *m_CurFn;
+ AST::FunctionDecl *m_DnDecl;
+ aeb::lds::Builder m_Builder;
+ CodeGenModule &m_CGM;
+ protected:
+ struct BreakContinue {
+ BreakContinue( aeb::lds::BasicBlock *_break
+ , aeb::lds::BasicBlock *_cont
+ , BasicBlock *h)
+ : m_Break(_break),
+ m_Continue(_cont) , m_Hash(h) {} ;
+ ~BreakContinue() {};
+ aeb::lds::BasicBlock *m_Break;
+ aeb::lds::BasicBlock *m_Hash;
+ aeb::lds::BasicBlock *m_Continue;
+ };
+ std::stack<BreakContinue> m_BreakContinueStack;
+
+ // Keep trac of current switch context
+ SwitchInst *m_SwitchInst;
+ BasicBlock *m_SwitchHashBlock;
+ public:
+ CodeGenFunction(aeb::lds::CodeGen::CodeGenModule &_CGM,const aeb::lds::Builder &builder) ;
+
+ aeb::lds::Builder &getBuilder() { return m_Builder; };
+
+ CodeGenModule &getModule() { return m_CGM; };
+
+ aeb::lds::Function *getCurrentFunction() { return dynamic_cast<aeb::lds::Function *>(m_CurFn) ;};
+ void GenerateCode(const AST::FunctionDecl *FnDecl, Function *);
+ // This must disapear
+ //void GenerateCode(const AST::TransitionDecl *FnDecl, Transition *);
+
+ void GenerateCode(const AST::TransitionDecl *FnDecl, Function *);
+
+ void EmitGotoStmt( AST::GotoStmt *S);
+
+ void EmitSwitchStmt( AST::SwitchStmt *S);
+
+ void EmitBreakStmt( AST::BreakStmt *S);
+
+ void EmitSwitchCaseStmt( AST::SwitchCaseStmt *S);
+
+ void EmitWhileStmt( AST::WhileStmt *S);
+
+ void EmitIfStmt(AST::IfStmt *S);
+ // Main entry point
+ void EmitStmt(AST::Stmt *s);
+ //
+ bool EmitSimpleStmt(AST::Stmt *s);
+ //
+ void EmitLdsAsmStmt(AST::LdsAsmStmt *s);
+
+ void EmitOutputStmt(AST::OutputStmt *s);
+
+ void EmitCompoundStmt( AST::CompoundStmt *S);
+ // Function Call
+ void EmitCallExpr( AST::CallExpr *S);
+
+ void EmitVarDecl(const AST::Decl &D);
+
+ void EmitBlock(aeb::lds::BasicBlock *,bool isFinished = false);
+
+ void EmitBranch(aeb::lds::BasicBlock *);
+
+ void EmitCallExpr(AST::Expr *E) {std::cout<<"EmitCallExpr tobe coded"<<std::endl;};
+
+ void EmitScalarExpression(AST::Expr *E);
+
+ aeb::lds::BasicBlock * createBasicBlock(const std::string &n = "",aeb::lds::BasicBlock *parent= NULL,
+ aeb::lds::BasicBlock *before = NULL);
+
+ bool HaveInsertPoint() ;
+
+ void EnsureInsertPoint() {
+ if ( ! HaveInsertPoint())
+ EmitBlock( createBasicBlock("def") );
+ };
+ };
+
+}
+}
+}
+#endif
--- /dev/null
+#ifndef GENCODEMODULE_H__
+#define GENCODEMODULE_H__
+
+namespace aeb {
+namespace lds {
+class GlobalVariable;
+namespace CodeGen {
+class CodeGenFunction;
+ /**
+ * \brief This is the entry class for all the things that needs generation
+ * the class uses GenCodeFunction Object to generate Code for the functions.
+ *
+ * - Other stuff might be needed for States, Events, Transitions.
+ * - Maybe I'm lacking a Module class as well. To hold all the generated code,
+ * variables symbol table and so on,
+ *
+ */
+class CodeGenModule {
+
+ aeb::lds::Module *m_Module;
+ AST::ASTContext &m_Context; /* For type andling */
+ CodeGenType m_CodeGenType;
+ public:
+
+
+ /// Receives as parameter a llvm::Module, a Context
+ CodeGenModule(AST::ASTContext &C, aeb::lds::Module *);
+
+ CodeGenType &getType() { return m_CodeGenType; }
+
+ aeb::lds::Module &getModule()
+ { return *m_Module; }
+ inline AST::ASTContext &getContext() { return m_Context;};
+
+ void EmitGlobalFunctionDefinition(AST::FunctionDecl *_d,bool onlydef = true);
+
+ void EmitGlobalVarDefinition(AST::VarDecl *D);
+
+ void EmitTimerDefinition(AST::TimerDecl *D);
+
+ void EmitGlobalStateDefinition(AST::StateDecl *_d);
+
+ void EmitTopLevelDecl(AST::Decl *_d);
+
+ void EmitConstantValueInit(AST::VarDecl *D);
+
+ void EmitValueTypeDefinition(AST::ValueTypeDecl *D);
+
+ /* Not Sure if this is really necessary */
+ void EmitEvent(AST::EventDecl *D);
+
+ /**
+ *
+ */
+ aeb::lds::Signal *GetSignal(AST::EventDecl *D);
+ /**
+ * Get Or create LDS Variable
+ */
+ aeb::lds::GlobalVariable *GetGlobalVariable(AST::VarDecl *D);
+
+#if 1
+ GlobalVariable * getOrCreateGlobal(const std::string &_flag,bool constant,void *_Ty = NULL);
+#endif
+ GlobalVariable * getOrCreateGlobal(const AST::ValueDecl *D);
+ protected:
+};
+
+}
+}
+}
+
+#endif
--- /dev/null
+#ifndef CODEGENTYPE_H
+#define CODEGENTYPE_H
+
+namespace AST {
+ class ASTContext;
+};
+
+namespace aeb {
+namespace lds {
+class StructType;
+namespace CodeGen {
+class CodeGenModule;
+
+/**
+ * This class is responsible to make the conversion of types between
+ * Front end syntax and IR.
+ *
+ * Right now it's a small ambrion that will be updated according to the
+ * needs and requirements
+ * 09/07/2019: Why not use this class to store the value types, typedefs
+ * and so on? Keep a map of all types so I can easely retrieve them again.
+ * This class is supposed to be the interface between the IR and FE.
+ */
+class CodeGenType
+{
+ typedef std::map<std::string,aeb::lds::StructType *> StructMap;
+ protected:
+ CodeGenModule &m_Module;
+ AST::ASTContext &m_Context;
+ public:
+ CodeGenType(CodeGenModule &CGM);
+
+ aeb::lds::Type *ConvertBuiltinType(AST::BuiltinType *Ty);
+
+ aeb::lds::Type *ConvertType(AST::Type *Ty);
+ /**
+ * @brief lds structures are encapsulated into ValueType type
+ * Maybe I should do the same with Union and Enums.
+ */
+ aeb::lds::StructType *addStructTypeDecl(AST::ValueTypeDecl *_decl);
+};
+
+
+} } }
+#endif /*CODEGENTYPE_H*/
--- /dev/null
+#ifndef MODULE_BUILDER_H__
+#define MODULE_BUILDER_H__
+
+namespace aeb {
+namespace lds {
+namespace CodeGen {
+
+ class CodeGenerator {
+ public:
+ CodeGenerator () {};
+ virtual ~CodeGenerator() {} ;
+ virtual aeb::lds::Module *GetModule() = 0;
+ virtual aeb::lds::CodeGen::CodeGenModule *GetBuilder() = 0;
+ virtual void HandleTopLevelDecl(AST::Decl *_decl) = 0;
+ };
+
+ CodeGenerator *CreateLdsGenerator(AST::ASTContext &C,const std::string &_ModuleName) ;
+}
+}
+}
+
+#endif
--- /dev/null
+#ifndef ARGUMENT_H
+#define ARGUMENT_H
+#include <vector>
+#include "aeb/dlilist_node.h"
+
+namespace aeb {
+
+ template <typename SubClass, typename ParentClass>
+ class SymbolTableTraits ;
+
+ namespace lds {
+ class BasicBlock;
+ class Transition;
+ class Function;
+ class Signal;
+ class Behavior;
+ class Module;
+ /**
+ * This class repesents a Function argument. Will
+ * be usefull to generate better C++ class
+ *
+ */
+ class Argument : public Value, public aeb::dlilist_node<Argument> {
+ Argument(const Argument &) : Value(*this) {}; // Avoid Copy construction
+ //operator =(const Instruction &) ;
+ //
+ std::string m_name;
+ Function *m_Parent;
+
+ public:
+ typedef std::string ArgumentType ;
+ // Constructor
+ Argument(const std::string &Ty,Function *_f = NULL);
+
+ virtual ~Argument() {};
+
+ void setParent(Function *);
+
+ bool operator ==(const std::string &s)
+ { return !s.compare(getName()); };
+
+ std::string getTypeName() const { return m_name ;}
+ inline const Function *getParent() const { return m_Parent; };
+ inline Function *getParent() { return m_Parent; };
+ };
+
+ /**
+ *
+ */
+ class SigArgument : public Value, public aeb::dlilist_node<SigArgument>
+ {
+ Signal *m_Parent;
+ public:
+ SigArgument(const std::string &Ty,Signal *_f = NULL) ;
+
+ const std::string &getTypeName() const {return getName() ; }
+ void setParent(Signal *p) { m_Parent = p;};
+ inline const Signal *getParent() const { return m_Parent; };
+ inline Signal *getParent() { return m_Parent; };
+ };
+ }
+}
+#endif /*ARGUMENT_H*/
+/**
+ * ex: set et sw=4 ts=4 list:
+ */
--- /dev/null
+#ifndef AEB_BASICBLOCK_H__
+#define AEB_BASICBLOCK_H__
+
+#include "aeb/dlilist.h"
+#include "IR/LdsInstruction.h"
+#include "IR/SymbolTableTraits.h"
+
+namespace aeb {
+
+ namespace lds {
+
+ // First attempt for callback invocation
+
+
+ /**
+ *
+ * Need to be able to insert Instuctions in there.
+ * Basic Instructions :
+ * FunctionCall
+ * JUMP ....
+ * LOAD
+ * CMP
+ *
+ * TERMINATOR...
+ *
+ * Blocks are chained ... I still need to figure out how
+ */
+ class BasicBlock :
+ public Value
+ , public aeb::dlilist_node<BasicBlock>
+ {
+ public:
+ // Constains a list of Instruction ....
+ typedef SymbolTable<Instruction> InstList;
+
+ // Instruction Iterator
+ typedef InstList::iterator iterator;
+ typedef InstList::const_iterator const_iterator;
+
+ protected:
+ InstList m_Instructions;
+
+ std::string m_Name;
+ // Copy Constructor
+ BasicBlock(const BasicBlock &p,const std::string &name , BasicBlock *parent = NULL );
+
+ Behavior *m_Parent;
+ public:
+
+ BasicBlock(const std::string &name="Sentinel",BasicBlock *parent = NULL);
+
+ virtual ~BasicBlock();
+
+ const char *getName() { return m_Name.c_str();}
+
+ void setName(const std::string &s) { m_Name = s; };
+ // Parent acces for Block.
+ // Actually, the parent can be a function, a transition need to see how to solve this
+ Behavior *getParent() const { return m_Parent; };
+ //
+ void setParent(Behavior *p) { m_Parent = p; };
+
+ // Iterators
+ inline iterator begin() { return m_Instructions.begin(); }
+ inline const_iterator begin() const { return m_Instructions.begin(); }
+
+ inline iterator end() { return m_Instructions.end(); }
+ inline const_iterator end() const { return m_Instructions.end(); }
+
+ inline size_t size() const { return m_Instructions.size();} ;
+ // Mising front, back, empty , size
+
+ size_t NbOpcode() const ;
+
+ size_t NbOpcode(iterator &c) const ;
+
+
+ static InstList BasicBlock::*getSublistAccess(Instruction*) {
+ return &BasicBlock::m_Instructions;
+ }
+
+ /// Constructors are private
+ static BasicBlock *Create(const std::string &name,BasicBlock *Parent = NULL) {
+ return new BasicBlock(name,Parent); };
+
+
+ const Instruction *getTerminator() {
+ if (m_Instructions.empty() ) return NULL;
+ return dynamic_cast<aeb::lds::TerminatorInst *>(& (m_Instructions.back()));
+ ;
+ }
+ /// Access to the List to modify it
+ InstList &getInstList() { return m_Instructions ; };
+
+ const InstList &getInstList() const { return m_Instructions ; };
+
+ bool Empty() const { return m_Instructions.empty();};
+
+ // Add Instructions and so on
+ };
+
+
+ }
+}
+
+#endif
--- /dev/null
+#ifndef IR_BEHAVIOR_H__
+#define IR_BEHAVIOR_H__
+
+#include "aeb/dlilist.h"
+#include "IR/BasicBlock.h"
+#include "IR/SymbolTableTraits.h"
+
+namespace aeb {
+
+namespace lds {
+
+class State;
+class Function;
+class Module;
+
+
+/**
+ * The behavior class is a generic class for everything that contains behavioral instructions.
+ * - A function implementation is a behaviors.
+ * - A transition contains a behavior that is triggers on several events. I could say that several
+ * events implement the same behaviors
+ *
+ */
+
+class Behavior : public Value
+{
+ protected:
+ //typedef aeb::dlilist<aeb::lds::BasicBlock> BlockListType;
+ typedef aeb::SymbolTable<aeb::lds::BasicBlock> BlockListType;
+ typedef BlockListType::iterator iterator;
+ typedef BlockListType::const_iterator const_iterator;
+ protected:
+
+ BlockListType m_Blocks;
+ std::string m_Name;
+
+ Behavior(const Behavior &p) ;
+ public:
+
+ Behavior(const std::string & m_Name , Type *Ty,unsigned tid) ;
+
+ virtual ~Behavior() ;
+
+ static BlockListType Behavior::*getSublistAccess(BasicBlock *) {
+ return &Behavior::m_Blocks;
+ }
+
+
+ // Iterators,
+ iterator begin() { return m_Blocks.begin() ; };
+ const_iterator begin() const { return m_Blocks.begin(); };
+ iterator end() { return m_Blocks.end() ; }
+ const_iterator end() const { return m_Blocks.end() ; };
+ /// Access to the List to modify it
+ BlockListType &getBlockList() {
+ return m_Blocks ;
+ };
+
+ const BlockListType &getBlockList() const {
+ return m_Blocks ;
+ };
+
+};
+
+
+}
+}
+#endif
--- /dev/null
+#ifndef CONSTANT_H
+#define CONSTANT_H
+
+#include "IR/User.h"
+
+namespace aeb {
+namespace lds {
+class Module;
+/**
+ *
+ * This class represents Constants in a Module.
+ * A Constant can be a Function, a Global Variable,
+ * an Integer used during Initialization phase.
+ *
+ * -TODO
+ *
+ */
+class Constant : public User {
+ protected:
+ // TODO the information bellow are stored in Value
+ // Missing Constant value when constante
+ Constant(const Constant &_g) : User(*this) {}
+
+ Constant(Type *Ty,unsigned vty,Use *u,unsigned int nbOperand)
+ : User(Ty,vty,u,nbOperand) {}
+ public:
+
+ // Need some basic Constructors
+ Constant *getInteger(Type *Ty,long _value) { return NULL ; };
+
+};
+
+}
+}
+#endif /*CONSTANT_H*/
--- /dev/null
+#ifndef IR_FUNCTION_H__
+#define IR_FUNCTION_H__
+
+#include "aeb/dlilist.h"
+#include "IR/Value.h"
+#include "IR/BasicBlock.h"
+#include "IR/Behavior.h"
+#include "IR/Argument.h"
+#include "IR/SymbolTableTraits.h"
+
+namespace aeb {
+template<>
+ struct SymbolTableListSentinelTraits<lds::Argument>
+ : public dlilist_half_embedded_sentinel_traits<lds::Argument> {};
+
+namespace lds {
+class State;
+class Function;
+class Module;
+
+
+/**
+ * A Function can have parameters ...
+ * Argument is the formal description of the argument.
+ * It'a attributes help in code generation (Reference argument
+ * By value arguement, Allocated Arguement)
+ *
+ */
+
+class Function : public Behavior
+ , public aeb::dlilist_node<Function>
+{
+
+ public:
+ /* Tells if the function is a declaration or a local implementation .... */
+ enum FctType {
+ Local
+ ,ExternalLink
+ };
+
+ typedef aeb::SymbolTable<aeb::lds::Argument> ArgumentListType;
+
+ typedef ArgumentListType::iterator ArgumentIterator;
+ typedef ArgumentListType::const_iterator ArgumentConstIterator;
+ protected:
+ Module *m_Parent;
+ FctType m_FctType;
+ long m_NbParam;
+ ArgumentListType m_ArgumentList;
+ public:
+ Function(const std::string &s="DefFct",FctType fc=ExternalLink) ;
+
+ static Function *Create(const std::string &name,FctType ft = ExternalLink) {
+ return new Function(name,ft);
+ }
+ Module *getParent() { return m_Parent;};
+
+ const Module *getParent() const { return m_Parent;};
+
+ void setParent(Module *p) { m_Parent = p; };
+
+ bool isExternal() const { return m_FctType == ExternalLink; };
+ // SymbolTable stuff
+ static ArgumentListType Function::*getSublistAccess(Argument *) {
+ return &Function::m_ArgumentList;
+ };
+
+ static BlockListType Function::*getSublistAccess(BasicBlock *b) {
+ return Behavior::getSublistAccess(b);
+ //m_Blocks;
+ };
+
+ // TODO Temporary, needs to be removed
+ inline long getNbParams() { return m_NbParam; };
+ inline void setNbParams(long i) { m_NbParam = i; };
+ //
+ inline ArgumentListType &args() { return m_ArgumentList;};
+ //
+ bool operator ==(const std::string &s) const { return ! m_Name.compare(s); }
+
+ bool operator !=(const std::string &s) const { return m_Name.compare(s); }
+
+ // Iterators
+ ArgumentIterator arg_begin() { return m_ArgumentList.begin() ; }
+ ArgumentIterator arg_end() { return m_ArgumentList.end() ; }
+
+ ArgumentConstIterator arg_begin() const { return m_ArgumentList.begin() ; }
+ ArgumentConstIterator arg_end() const { return m_ArgumentList.end() ; }
+
+ Argument *getArgument(const std::string &n)
+ {
+ ArgumentIterator it = std::find(arg_begin(),arg_end(),n);
+ return it;
+ } ;
+};
+
+
+}
+}
+#endif
+/**
+ * ex: set et sw=4 ts=4 list:
+ */
--- /dev/null
+#ifndef GLOBALVARIABLE_H__
+#define GLOBALVARIABLE_H__
+
+#include "IR/Constant.h"
+#include "IR/OperandTraits.h"
+namespace aeb {
+// Forward declaration
+template <typename SubClass > class SymbolTableListTraits;
+namespace lds {
+class Module;
+class Constant;
+/**
+ *
+ * This class represents a global Variable in the Module.
+ * it's supposed to be a Flag. (Type is not yet supported and requires a lot
+ * of work. But it should be done if I want to use Abstract Data Types (eg
+ * ASN1, XSD, WSDL ...)
+ *
+ * -TODO
+ * Also Missing the Initializer part. A global variable can be initialized. The
+ * Parser gets the expression and stores it. Now, The IR should also handle it
+ * preperly.
+ * May be, this class should inherit from User instead of Value. Later on, we
+ * can make the connection between the initialize et the variable.
+ *
+ */
+class GlobalVariable : public aeb::dlilist_node<GlobalVariable> , public Constant {
+ protected:
+ friend class SymbolTableListTraits<GlobalVariable>;
+ // TODO the information bellow are stored in Value
+ Module *m_Parent;
+ bool m_IsConstant : 1; /* Is it a constant Global Variable */
+ // Missing Constant value when constante
+ GlobalVariable(const GlobalVariable &_g) : Constant(*this) {}
+ public:
+ GlobalVariable(const std::string &flg , bool constant,Type *_Ty = NULL);
+#if 0
+ : m_IsConstant(constant)
+ , Constant(_Ty, GlobalVariableVal,OperandTraits<GlobalVariable>::op_begin(this),1)
+ , m_Parent(NULL)
+ { Value::setName(flg); } ;
+#endif
+ virtual ~GlobalVariable() {} ;
+
+ inline bool hasInitializer() const { return false; };
+ void setInitializer(Constant *InitVal) ;
+
+ /// Return Initializer if present. Should Not be called if absent
+ Constant *getInitializer() ;
+
+ DECLARE_OPERAND_ACCESS(Value)
+
+ /* Allocate Space for One operand */
+ void * operator new(size_t s)
+ {
+ return User::operator new(s,1);
+ }
+
+ void setParent(Module *p) { m_Parent = p ; } ;
+
+ Module *getParent() const { return m_Parent;} ;
+
+ bool isConstant() const { return m_IsConstant; };
+
+ bool operator ==(const std::string &s) { return ! getName().compare(s); };
+
+ bool operator !=(const std::string &s) { return getName().compare(s); };
+ protected:
+
+
+} ;
+
+template <>
+struct OperandTraits<GlobalVariable> :
+ public FixedNumOperandTraits<GlobalVariable,1>
+{
+};
+DEFINE_OPERAND_ACCESS(GlobalVariable,Value)
+
+}
+}
+#endif
--- /dev/null
+#ifndef IR_IRBUILDER_ADAPTOR_H__
+#define IR_IRBUILDER_ADAPTOR_H__
+
+/**
+ * This template is an adaptor that will contain an IRBuilder implemention
+ * The goal is to be able to use Lds Builder or LLVM which is much more powerfull
+ */
+
+template <typename Builder,typename BBlock>
+class IRBuilderAdaptor {
+ /// Keeps an instance of the Adaptor
+ Builder &m_Instance;
+
+ public:
+ IRBuilderAdaptor(const Build &i) : m_Instance(i) {}
+
+ BBlock *GetInsertBlock();
+
+ void SetInsertPoint(BBlock *BB) {
+ m_Instance.SetInsertPoint(BB);
+ };
+
+ void ClearInsertPoint() {
+ m_Instance.ClearInserPoint();
+ };
+ // Parameters : Value, Block , Block
+ void CreateCondBr( BBlock *Tr, BBlock *Fl) {
+
+ };
+};
+
+};
+#endif
--- /dev/null
+#ifndef AEB_LDS_IRBUILDER_H__
+#define AEB_LDS_IRBUILDER_H__
+
+namespace aeb {
+
+namespace lds {
+ /**
+ *
+ * The Builder handles blocks. Should be easy from here one to
+ * compute jump distances and so one.
+ */
+ class Builder {
+ typedef aeb::lds::BasicBlock Block;
+ typedef aeb::lds::BasicBlock::iterator Iterator;
+
+ aeb::lds::BasicBlock *m_BB;
+ aeb::lds::BasicBlock::iterator m_InsertPt; // Instruction pointer...
+ public:
+
+ Builder() : m_BB(NULL) {};
+ Builder(const Builder &_b) : m_BB(_b.m_BB), m_InsertPt(_b.m_InsertPt) {};
+ BasicBlock *GetInsertBlock( ) const { return m_BB; };
+
+ void SetInsertPoint(aeb::lds::BasicBlock *BB) {
+ m_BB = BB;
+ m_InsertPt = BB->end();
+ };
+
+ void SetInsertPoint(Block *BB,aeb::lds::BasicBlock::iterator &IT ) {
+ m_BB = BB;
+ m_InsertPt = IT;
+ }
+
+ void SetInsertPoint(Instruction *I) {
+ m_BB = I->getParent();
+ m_InsertPt = Iterator(I);
+ }
+
+ void ClearInsertPoint() {
+ m_BB = NULL;
+ m_InsertPt = Iterator(NULL);
+ };
+ // Parameters : Value, Block , Block
+ BranchCondInst *CreateCondBr( aeb::lds::BasicBlock *Tr, aeb::lds::BasicBlock *Fl)
+ {
+ //Create BranchInstruction ...
+ return Insert(BranchCondInst::Create(Tr,Fl),"CondBr");
+ };
+
+ BranchInst *CreateBr(aeb::lds::BasicBlock *Dest) {
+ return Insert(BranchInst::Create(Dest),"Br");
+ }
+
+ BranchSubroutine *CreateJsr(const std::string &flg) {
+ return Insert(BranchSubroutine::CreateJsr(flg),"Jsr");
+ }
+
+ IndirectBranchInst *CreateJsrInd(const std::string &flg) {
+ return Insert(IndirectBranchInst::CreateJsrInd(flg),"JsrInd");
+ }
+
+ GotoStateInst *CreateGotoState(const std::string &sn) {
+ return Insert(GotoStateInst::Create(sn),"");
+ }
+
+ SwitchInst *CreateSwitch(Value *cond,aeb::lds::BasicBlock *jump = NULL) {
+ return Insert(SwitchInst::Create(cond,jump),"");
+ }
+
+
+ CallInst *CreateCall(const std::string &fctn,aeb::lds::BasicBlock *Dest = NULL) {
+ return Insert(CallInst::Create(fctn,Dest),"");
+ }
+
+
+ Instruction *CreateNot(Instruction *value) {
+ return Insert(ComplInst::Create(NULL));
+ }
+ // Load value into Accumulator
+ Instruction *CreateLoad(const std::string &s) {
+ return Insert(LoadInst::CreateLoadA(s));
+ }
+ Instruction *CreateLoad(Value *v) {
+ return Insert(LoadInst::Create(v));
+ }
+ Instruction *CreateExtractValue(Value *v,int idx,const std::string &n) {
+ return Insert(ExtractValueInst::Create(v,idx));
+ }
+ // Store value from accumulator into register
+ Instruction *CreateStore(const std::string &s) {
+ return Insert(StoreInst::CreateStoreA(s));
+ }
+ Instruction *CreateStore(Value *s) {
+ return Insert(StoreInst::Create(s));
+ }
+ // Set Flag
+ Instruction *CreateSet(const std::string &s) {
+ return Insert(FlagInst::CreateSet(s));
+ }
+ // Reset Flag
+ Instruction *CreateReset(const std::string &s) {
+ return Insert(FlagInst::CreateReset(s));
+ }
+
+ // Reset Flag
+ Instruction *CreateNop() {
+ return Insert(NopInst::Create(),"");
+ }
+ Instruction *CreateSendEvent(const Value *S) {
+ return Insert(SendEventInst::Create(S),"");
+ }
+ SendEventInst *CreateOutput(const Value *v) {
+ return Insert(SendEventInst::CreateOutput(v),"");
+ }
+
+
+
+ /**
+ * Binary Operations
+ */
+ Instruction *CreateAnd(aeb::lds::BasicBlock *LHS,aeb::lds::BasicBlock *RHS) {
+ return Insert(aeb::lds::BinaryOperator::CreateAEL_AND(NULL,NULL,NULL));
+ }
+ Instruction *CreateAnd(const std::string &s) {
+ return Insert(aeb::lds::BinaryOperator::CreateAEL_AND(s,NULL));
+ }
+
+ Instruction *CreateOr(aeb::lds::BasicBlock *LHS,aeb::lds::BasicBlock *RHS) {
+ return Insert(aeb::lds::BinaryOperator::CreateAEL_OR(NULL,NULL,NULL));
+ }
+
+ Instruction *CreatePlus(aeb::lds::BasicBlock *LHS,aeb::lds::BasicBlock *RHS) {
+ return Insert(aeb::lds::BinaryOperator::CreateAEL_PLUS(NULL,NULL,NULL));
+ }
+ Instruction *CreatePlus(aeb::lds::Value *LHS,aeb::lds::Value *RHS) {
+ return Insert(aeb::lds::BinaryOperator::CreateAEL_PLUS(LHS,RHS,NULL));
+ }
+
+ Instruction *CreateMoin(aeb::lds::BasicBlock *LHS,aeb::lds::BasicBlock *RHS) {
+ return Insert(aeb::lds::BinaryOperator::CreateAEL_MOIN(NULL,NULL,NULL));
+ }
+ Instruction *CreateMoin(aeb::lds::Value *LHS,aeb::lds::Value *RHS) {
+ return Insert(aeb::lds::BinaryOperator::CreateAEL_MOIN(LHS,RHS,NULL));
+ }
+
+ Instruction *CreateOr(const std::string &s) {
+ return Insert(aeb::lds::BinaryOperator::CreateAEL_OR(s,NULL));
+ }
+
+ Instruction *CreateCmp(aeb::lds::BasicBlock *LHS,aeb::lds::BasicBlock *RHS) {
+ return Insert(CmpInst::Create(NULL),"");
+ }
+ Instruction *CreateCmp(const std::string &S) {
+ return Insert(CmpInst::Create(S),"");
+ }
+ /// S should be: EQ, NE, GT,LT,LE,GE
+ Instruction *CreateCmp(Value *v,const std::string &S) {
+ return Insert(CmpInst::Create(v,S),"");
+ }
+ Instruction *CreateTest(const std::string &S) {
+ return Insert(LoadInst::CreateLoadA(S),"");
+ }
+ Instruction *CreateTest(unsigned long S) {
+ std::ostringstream oss;
+ oss<<S;
+ return Insert(LoadInst::CreateLoadConst(oss.str()),"");
+ }
+ Instruction *CreateCmpInteger(const unsigned long S) {
+ std::ostringstream oss;
+ oss<<S;
+ return Insert(aeb::lds::BinaryOperator::CreateAEL_EQU(oss.str(),NULL));
+ }
+
+ ReturnInst *CreateRet(/* return value does not exits in LDS*/) {
+ return Insert(ReturnInst::Create(),"");
+ }
+ ReturnInst *CreateRetVoid() {
+ return Insert(ReturnInst::Create(),"");
+ }
+ // Return from sub routine
+ ReturnInst *CreateRetSub() {
+ return Insert(ReturnInst::CreateRetSub(),"");
+ }
+ // Powerfull
+ template <typename InstTy>
+ InstTy *Insert(InstTy *I,const std::string &Name = "") {
+ if (m_BB) {
+ m_BB->getInstList().insert(m_InsertPt,I);
+ } else
+ std::cout<<"LdsBuilder::Insert no Block "<<Name<<std::endl;
+ //
+ return I;
+ }
+
+
+ };
+
+}
+}
+#endif
--- /dev/null
+#ifndef INSTR_VISITOR_H__
+#define INSTR_VISITOR_H__
+
+namespace aeb {
+namespace lds {
+
+#define DELEGATE(TO_CLASS) \
+ return static_cast<SubClass *>(this)->visit##TO_CLASS(static_cast<TO_CLASS &>(I)) ; \
+/**
+ * \brief Instruction Visitor Class, I'm wondering if this is going to work !!
+ *
+ *
+ *
+ */
+template <typename SubClass,typename RetType=void>
+class InstrVisitor {
+ public:
+ // Range visiting
+ template <class Iterator>
+ void visit(Iterator Begin,Iterator End) {
+ while (Begin != End ) {
+ static_cast<SubClass *>(this)->visit(*Begin++);
+ }
+ }
+ template <class Iterator>
+ void visitDecl(Iterator Begin,Iterator End) {
+ while (Begin != End ) {
+ static_cast<SubClass *>(this)->visitDecl(*Begin++);
+ }
+ }
+
+ void visit(Module &M) {
+ static_cast<SubClass *>(this)->visitModule(M);
+ // May be I should visit Global Functions first
+ visit(M.global_begin(),M.global_end());
+ visitDecl(M.signal_begin(),M.signal_end());
+ visit(M.signal_begin(),M.signal_end());
+ visit(M.function_begin(),M.function_end());
+ visit(M.state_begin(),M.state_end());
+ }
+
+ void visit(GlobalVariable &T) {
+ static_cast<SubClass *>(this)->visitGlobalVariable(T);
+ //visit(T.begin(),T.end());
+ }
+
+
+ void visit(Function &T) {
+ // std::cout<<"visit Function:"<<T.getName()<<" Empty="<<T.getBlockList().empty()<<std::endl;
+ static_cast<SubClass *>(this)->visitFunction(T);
+ if ( ! T.isExternal())
+ {
+ if (! T.getBlockList().empty() )
+ visit(T.begin(),T.end());
+ }
+ static_cast<SubClass *>(this)->visitFunctionEnd(T);
+ }
+
+ void visit(State &S) {
+ static_cast<SubClass *>(this)->visitState(S);
+ // std::cout<<"visit State:"<<S.getName()<<std::endl;
+ visit(S.transition_begin(),S.transition_end());
+ }
+
+ void visit(Transition &T) {
+ static_cast<SubClass *>(this)->visitTransition(T);
+ // std::cout<<"visit Transition:"<<T.getName()<<" empty? "<<T.getBlockList().empty()<<std::endl;
+ //if ( ! T.getBlockList().empty())
+ // visit(T.begin(),T.end());
+ }
+ void visit(BasicBlock &T) {
+ static_cast<SubClass *>(this)->visitBasicBlock(T);
+ // if ( ! T.getInstList().empty() )
+ visit(T.begin(),T.end());
+ }
+
+
+ void visit(Signal &T) {
+ static_cast<SubClass *>(this)->visitSignal(T);
+ }
+ void visitDecl(Signal &T) {
+ static_cast<SubClass *>(this)->visitDeclSignal(T);
+ }
+
+ // Pointer Version
+ void visit(Module *M) { visit(*M); }
+ void visit(BasicBlock *M) { if ( M ) visit(*M); }
+ void visit(GlobalVariable *M) { visit(*M); }
+ void visit(Function *M) { visit(*M); }
+ void visit(State *M) { visit(*M); }
+ void visit(Transition *M) { visit(*M); }
+
+ RetType visit(Instruction *M) { visit(*M); }
+
+
+
+ RetType visit(Instruction &I) {
+ // std::cout<<"visit(Instruction : "<<I.getOpcode()<<")"<<std::endl;
+ switch (I.getOpcode()) {
+#define OPCODE(NUM,OP,LEN,CLASS) \
+ case Instruction::OP##Opcode : return \
+ static_cast<SubClass *>(this)->visit##OP(static_cast<CLASS &>(I)) ;
+#include "IR/ldsOpcode.h"
+#undef OPCODE
+ default:
+ ; // Empty Instructions are ignored
+ // std::cout<<"visitInstruction: Not Known "<<I.getOpcode()<<std::endl;
+ }
+ }
+
+ // Default Visitor Implementation
+ //
+
+ void visitModule(Module &M) {} ;
+ void visitGlobalVariable(GlobalVariable &M) {} ;
+ void visitFunction(Function &M) {} ;
+ void visitFunctionEnd(Function &M) {} ;
+ void visitState(State &M) {} ;
+ void visitTransition(State &M) {} ;
+ void visitBasicBlock(BasicBlock &M) {} ;
+ void visitInstruction(Instruction &M) {} ;
+ void visitSignal(Signal &M) {} ;
+ void visitDeclSignal(Signal &M) {} ;
+
+#define OPCODE(NUM,OP,LEN,CLASS) \
+ RetType visit##OP(CLASS &I) {\
+ return static_cast<SubClass *>(this)->visitInstruction(I) ; \
+ }
+#include "IR/ldsOpcode.h"
+#undef OPCODE
+
+
+};
+
+
+}
+}
+#endif
--- /dev/null
+#ifndef AEB_LDS_INSTRUCTION_H__
+#define AEB_LDS_INSTRUCTION_H__
+#include <vector>
+#include "aeb/dlilist_node.h"
+
+#include "IR/Value.h"
+#include "IR/User.h"
+#include "IR/OperandTraits.h"
+
+namespace aeb {
+
+ template <typename SubClass, typename ParentClass>
+ class SymbolTableTraits ;
+namespace lds {
+ class BasicBlock;
+ class Transition;
+ class Behavior;
+ class Module;
+ class Value;
+ /**
+ * This class repesents a Intermediate language Instruction Set.
+ * Seee how to interface this with llvm ...
+ */
+ class Instruction : public aeb::dlilist_node<Instruction> , public User {
+ Instruction(const Instruction &i)
+ : User(i) {}; // Avoid Copy construction
+ //operator =(const Instruction &) ;
+ //
+ BasicBlock *m_Parent;
+ protected:
+ unsigned int m_Opcode;
+
+ inline void setOpcode(unsigned int _m) {m_Opcode = _m;};
+ public:
+ enum {
+ NullOpcode
+#define OPCODE(NUM,OP,SIZE,CLASS) , OP##Opcode
+#include "ldsOpcode.h"
+ } Opcodes;
+
+ Instruction(unsigned int Opcode = NullOpcode
+ , BasicBlock *parent = NULL)
+ : User(NULL,InstructionVal,NULL,0) , m_Opcode(Opcode) , m_Parent(parent)
+ { };
+ Instruction(unsigned int Opcode
+ ,Use *OpBegin,unsigned NbOp)
+ : User(NULL,InstructionVal,OpBegin,NbOp)
+ , m_Opcode(Opcode) , m_Parent(NULL)
+ { };
+ // Yeee works
+ virtual ~Instruction() {
+ //std::cout<<"Instruction::~Instruction"<<std::endl;
+ }
+
+ const char *getOpcodeName(int Opcode) const
+ {
+ switch (Opcode) {
+ case NullOpcode : return "undefined";
+#define OPCODE(LEN,OP,SIZE,CLASS) case OP##Opcode : return #OP ;
+#include "ldsOpcode.h"
+ default:
+ std::cout<<"getOpcodeName ERROR"<<std::endl;
+ };
+ return "";
+ }
+ inline const char * getOpcodeString() const
+ { return getOpcodeName(m_Opcode); }
+
+ unsigned int getOpcode() const { return m_Opcode; };
+ // Mainly for original lds generation
+ virtual const char *getOpcodeName()
+ { return getOpcodeName(m_Opcode) ; };
+
+ BasicBlock *getParent() { return m_Parent;};
+
+ const BasicBlock *getParent() const { return m_Parent;};
+
+ void setParent(BasicBlock *p) { m_Parent = p; };
+
+ // Remove Instruction from BasicBlock. No delete
+ void removeFromParent();
+
+ // Remove from Parent and erase;
+ void eraseFromParent();
+
+ // Insert an unlinked instruction Before I
+ void insertBefore(Instruction *I) ;
+ // Insert an unliked instruction After I
+ void insertAfter(Instruction *I) ;
+
+ // Compute the number of Opcode will be used for the instruction
+ virtual size_t NbOpcode() const {return 0;} ;
+
+ };
+
+
+
+ class TerminatorInst : public Instruction
+ {
+ protected:
+ TerminatorInst(unsigned int op) : Instruction(op) {};
+ TerminatorInst(unsigned int op,Use *OpB,unsigned NbOp)
+ : Instruction(op ,OpB, NbOp)
+ {}
+ public:
+ virtual size_t NbOpcode() const {return 1;} ;
+ };
+
+ /**
+ * Basic Required Instructions for LDS VM
+ */
+ class BranchInst : public TerminatorInst
+ {
+ typedef aeb::dlilist<aeb::lds::BasicBlock> BlockListType;
+ enum {BTRUE,BFALSE,BCOND,BEND};
+ BasicBlock *m_Block[BEND];
+
+ void *operator new(size_t s) {
+ return User::operator new(s, 2);
+ }
+ protected:
+ BranchInst(unsigned int op,BasicBlock *IfTrue = NULL
+ ,BasicBlock *IfFalse = NULL) ;
+ ~BranchInst()
+ { }
+
+ DECLARE_OPERAND_ACCESS(Value)
+
+
+ public:
+ static BranchInst *Create( BasicBlock *IfTrue
+ , Instruction *InsertAfter = NULL)
+ {
+ return new BranchInst(AEL_JUMP_PLUSOpcode,IfTrue);
+ }
+
+ static BranchInst *Create( BasicBlock *IfTrue , BasicBlock *IfFalse
+ , BasicBlock *Cond
+ , Instruction *InsertAfter = NULL)
+ {
+ return new BranchInst(AEL_JUMP_PLUSOpcode,IfTrue);
+ }
+ virtual int ThenLength () ;
+
+ aeb::lds::BasicBlock *getTrue() const { return m_Block[BTRUE] ; };
+ aeb::lds::BasicBlock *getFalse() const { return m_Block[BFALSE] ; };
+ aeb::lds::BasicBlock *getCond() const { return m_Block[BCOND] ; };
+
+ bool isUnConditional() const { return getFalse() == NULL;};
+
+ const char *getOpcodeName() ;
+
+ virtual size_t NbOpcode() const ;
+ };
+ template <>
+ struct OperandTraits<BranchInst> : public FixedNumOperandTraits<BranchInst,2>
+ { };
+
+ DEFINE_OPERAND_ACCESS(BranchInst,Value)
+ /**
+ * Basic Required Instructions for LDS VM
+ */
+ class BranchCondInst : public BranchInst
+ {
+ BranchCondInst(unsigned int op , BasicBlock *Then,BasicBlock *Else)
+ : BranchInst(op,Then,Else)
+ {};
+
+ void *operator new(size_t s) {
+ return User::operator new(s, 2);
+ }
+ DECLARE_OPERAND_ACCESS(Value)
+ public:
+ static BranchCondInst *Create(BasicBlock *Then,BasicBlock *Else = NULL)
+ {
+ return new BranchCondInst(AEL_JUMP_PLUS_IF_NOTOpcode, Then,Else);
+ }
+
+ virtual int ThenLength () ;
+
+ const char *getOpcodeName() ;
+
+ virtual size_t NbOpcode() const {return 2;} ;
+ };
+
+ template <>
+ struct OperandTraits<BranchCondInst> : public FixedNumOperandTraits<BranchCondInst,2>
+ { };
+
+ DEFINE_OPERAND_ACCESS(BranchCondInst,Value)
+ /**
+ * Basic Required Branch Subroutine
+ * It's either a defined internal function or a C Function
+ */
+ class BranchSubroutine : public Instruction
+ {
+ BranchSubroutine( unsigned int op
+ , const std::string & _fn
+ , BasicBlock *Then = NULL)
+ : m_Fct(_fn)
+ , Instruction(op)
+ , m_Sub(Then)
+ //, BranchInst(op,Then,NULL)
+ {};
+
+ void *operator new(size_t s) {
+ return User::operator new(s, 0);
+ }
+ std::string m_Fct;
+ BasicBlock *m_Sub;
+ public:
+ static BranchSubroutine *Create(const std::string &_fn,BasicBlock *Then) {
+ return new BranchSubroutine(AEL_JSROpcode, _fn,Then);
+ }
+ static BranchSubroutine *CreateJsr(const std::string &flag) {
+ return new BranchSubroutine(AEL_JSROpcode,flag);
+ }
+ static BranchSubroutine *CreateJsrInd(const std::string &flag) {
+ return new BranchSubroutine(AEL_JSR_INDOpcode,flag);
+ }
+#if 0
+ virtual int ThenLength () ;
+#endif
+ const char *getOpcodeName() ;
+
+ virtual size_t NbOpcode() const {return 2;} ;
+ };
+
+ /**
+ *
+ */
+ class SwitchInst : public TerminatorInst
+ {
+ SwitchInst(unsigned int op, Value *cond,BasicBlock *def)
+ : m_Cond(cond)
+ , TerminatorInst(op)
+ , m_HashBlock(def)
+ {};
+
+ void *operator new(size_t s) {
+ return User::operator new(s, 0);
+ }
+ protected:
+ BasicBlock *m_HashBlock;
+ //std::string m_Var;
+ Value *m_Cond;
+ public:
+ /* First Parameter should be a Value*/
+ static SwitchInst *Create(Value *cond,BasicBlock *hash = NULL) {
+ return new SwitchInst(AEL_JUMP_INDOpcode,cond, hash);
+ }
+
+ void addCase(int value,BasicBlock *doblock) {
+ }
+
+ BasicBlock *getHash() const { return m_HashBlock; };
+
+ virtual int ThenLength () ;
+
+ virtual size_t NbOpcode() const {return 3;} ;
+
+
+ virtual const char *getOpcodeName() ;
+ };
+
+ /**
+ * JMP subroutine
+ */
+ class IndirectBranchInst : public Instruction
+ {
+ IndirectBranchInst( unsigned int op
+ , int _nbp
+ , const std::string &s)
+ : Instruction(op)
+ , m_NbParameters(_nbp)
+ , m_Flag(s)
+ {};
+
+ void *operator new(size_t s) {
+ return User::operator new(s, 0);
+ }
+ protected:
+ std::string m_Flag;
+ int m_NbParameters;
+ public:
+ static IndirectBranchInst *Create(BasicBlock *B) {
+ return new IndirectBranchInst(AEL_JUMP_INDOpcode,2,"");
+ }
+ static IndirectBranchInst *CreateJsr(const std::string &flag) {
+ return new IndirectBranchInst(AEL_JSR_INDOpcode,2,flag);
+ }
+ static IndirectBranchInst *CreateJsrInd(const std::string &flag) {
+ return new IndirectBranchInst(AEL_JSR_INDOpcode,2,flag);
+ }
+
+ virtual size_t NbOpcode() const {return 2;} ;
+
+ virtual const char *getOpcodeName() {
+ static std::string s;
+ s = Instruction::getOpcodeName(m_Opcode) ;
+ s+= " ," ; s+=m_Flag ; return s.c_str(); };
+
+
+ };
+
+ /**
+ * Is AEL_(RE)SET Flag instructions ....
+ */
+ class FlagInst : public Instruction
+ {
+ void *operator new(size_t s) {
+ return User::operator new(s, 0);
+ }
+ protected:
+ std::string m_Flag;
+
+ FlagInst(unsigned int op,const std::string &f)
+ : Instruction(op) , m_Flag(f)
+ {};
+ public:
+ static FlagInst *CreateSet(const std::string &flg) {
+ return new FlagInst(AEL_SETOpcode,flg);
+ }
+ static FlagInst *CreateReset(const std::string &flg) {
+ return new FlagInst(AEL_RESETOpcode,flg);
+ }
+ virtual size_t NbOpcode() const {return 2;} ;
+
+ virtual const char *getOpcodeName() {
+ static std::string s;
+ s = Instruction::getOpcodeName(m_Opcode) ;
+ s+= " ," ; s+=m_Flag ; return s.c_str(); };
+
+
+ };
+
+ /**
+ * Is AEL_(RE)SET Flag instructions ....
+ */
+ class NopInst : public Instruction
+ {
+ void *operator new(size_t s) {
+ return User::operator new(s, 0);
+ }
+ protected:
+
+ NopInst(unsigned int op) : Instruction(op) {};
+ public:
+ static NopInst *Create() {
+ return new NopInst(AEL_NOPOpcode);
+ }
+ virtual size_t NbOpcode() const {return 1;} ;
+
+ };
+
+
+
+ /**
+ * Is AEL_RETURN
+ */
+ class ReturnInst : public TerminatorInst
+ {
+ ReturnInst(unsigned int op) : TerminatorInst(op)
+ {};
+ void *operator new(size_t s) {
+ return User::operator new(s, 0);
+ }
+ public:
+ static ReturnInst *Create(BasicBlock *B = NULL) {
+ return new ReturnInst(AEL_RETURNOpcode);
+ }
+ static ReturnInst *CreateRetSub() {
+ return new ReturnInst(AEL_RTSOpcode);
+ }
+ virtual size_t NbOpcode() const {return 1;} ;
+ };
+
+ /**
+ * Is AEL_RST
+ *
+ */
+ class ResumeInst : public Instruction {
+ ResumeInst();
+ public:
+ static ResumeInst *Create(BasicBlock *B) {
+ return NULL;
+ }
+ };
+ /**
+ * Save given FLAG as parameter into Accumulator
+ * meaning Load working register with value from VM memory
+ */
+ class LoadInst : public Instruction
+ {
+ LoadInst(unsigned int op,const std::string &Flg="",bool _co=false) ;
+
+ LoadInst(unsigned int op,Value *v);
+
+ void *operator new(size_t s) {
+ return User::operator new(s, 0);
+ }
+ public:
+ static LoadInst *Create(BasicBlock *B) {
+ return new LoadInst(AEL_TESTOpcode);
+ }
+
+ static LoadInst *Create(Value *Flg) {
+ return new LoadInst(AEL_TESTOpcode,Flg);
+ }
+
+ /**
+ * Load Accumulator with value from Flag
+ */
+ static LoadInst *CreateLoadA(const std::string &Flg) {
+ return new LoadInst(AEL_TESTOpcode,Flg);
+ }
+ /**
+ * Load Constant into accumulator
+ */
+ static LoadInst *CreateLoadConst(const std::string &B) {
+ return new LoadInst(AEL_TESTOpcode,B,true);
+ }
+
+ virtual size_t NbOpcode() const {return 2;} ;
+
+ virtual const char *getOpcodeName();
+
+ protected:
+ std::string m_Flag;
+ Value *m_Value;
+ bool m_Constant;
+ };
+
+ /**
+ * -- Save Global FLAG into Flag given as parameter
+ * meaning store Working register into VM memory
+ */
+ class StoreInst : public Instruction
+ {
+ StoreInst(unsigned int op,const std::string &Flg="")
+ : m_Value(NULL), Instruction(op),m_Flag(Flg) {};
+ StoreInst(unsigned int op,Value *v);
+ // : Instruction(op),m_Flag(Flg) {};
+ void *operator new(size_t s) {
+ return User::operator new(s, 0);
+ }
+ public:
+ static StoreInst *Create(BasicBlock *B) {
+ return new StoreInst(AEL_CHARGEOpcode);
+ }
+ static StoreInst *Create(Value *v) {
+ return new StoreInst(AEL_CHARGEOpcode,v);
+ }
+ /**
+ * Store value from accumulator into place
+ */
+ static StoreInst *CreateStoreA(const std::string &Flg) {
+ return new StoreInst(AEL_CHARGEOpcode,Flg);
+ }
+ virtual size_t NbOpcode() const {return 2;} ;
+
+ virtual const char *getOpcodeName();
+
+ protected:
+ Value *m_Value;
+ std::string m_Flag;
+ };
+
+
+ class BinaryOperator : public Instruction
+ {
+ BinaryOperator(unsigned int op,Value *V1,Value *V2,BasicBlock *insertAf = NULL) ;
+ // : Instruction(op),m_V1(V1),m_V2(V2) {};
+ BinaryOperator( unsigned int op
+ , const std::string &Flg
+ , BasicBlock *insertAf = NULL)
+ : Instruction(op),m_Flag(Flg) ,
+ m_V1(NULL),m_V2(NULL)
+ {};
+
+ void *operator new(size_t s) {
+ return User::operator new(s, 0);
+ }
+ public:
+ static BinaryOperator *Create(unsigned int op,Value *V1,Value *V2,BasicBlock *insertAf) {
+ return new BinaryOperator(op,V1,V2);
+ }
+
+ static BinaryOperator *Create(unsigned int op,const std::string &Flg,BasicBlock *insertAf) {
+ return new BinaryOperator(op,Flg);
+ }
+ virtual size_t NbOpcode() const {return 3;} ;
+
+ virtual const char *getOpcodeName();
+
+#define HANDLE_BINARY_INST(NUM,OP,SIZE,CLASS) \
+ static BinaryOperator *Create ## OP( Value *V1,Value *V2,BasicBlock *insertAf) { \
+ return new BinaryOperator(OP ## Opcode,V1,V2,insertAf); \
+ } \
+ static BinaryOperator *Create ## OP(const std::string &Flg ,BasicBlock *insertAf) { \
+ return new BinaryOperator(OP ## Opcode,Flg,insertAf); \
+ } \
+
+#include "ldsOpcode.h"
+ protected:
+ Value *m_V1;
+ Value *m_V2;
+ std::string m_Flag; // Variable used for the operation
+ };
+
+ class UnaryOperator : public Instruction {
+ UnaryOperator(unsigned int op) : Instruction(op) {};
+ public:
+ static UnaryOperator *Create(BasicBlock *B) {
+ return NULL;
+ }
+ };
+
+ class ExtractValueInst : public Instruction
+ {
+ ExtractValueInst(Value *v, int idx);
+
+ void *operator new(size_t s) {
+ return User::operator new(s, 0);
+ }
+ public:
+ static ExtractValueInst *Create(Value *v,int idx) {
+ return new ExtractValueInst(v,idx);
+ }
+
+ virtual size_t NbOpcode() const { return 3;}
+
+ virtual const char *getOpcodeName() ;
+ protected:
+ Value *m_Value;
+ //std::string m_Name;
+ int m_Index;
+ };
+ /**
+ * For LDS automatons, COMPL is always followed by FLG_GLOBAL on wich it operates.
+ */
+ class ComplInst : public Instruction
+ {
+ ComplInst(unsigned int op,Instruction *V1)
+ : Instruction(op)
+ , m_V1(V1)
+ {};
+
+ void *operator new(size_t s) {
+ return User::operator new(s, 0);
+ }
+ public:
+ static ComplInst *Create(Instruction *B) {
+ return new ComplInst(AEL_COMPLOpcode,B);
+ }
+ virtual size_t NbOpcode() const { return 2;};
+
+ virtual const char *getOpcodeName() {
+ static std::string s;
+ s = Instruction::getOpcodeName(m_Opcode) ;
+ s+= " ,FLAG_GLOBAL" ; return s.c_str(); };
+ protected:
+ Instruction *m_V1;
+ };
+
+
+ /**
+ * Is the AEL_NAME. references an entry point in ael table.
+ * should be improved
+ * To be simple, need to know number of parameters ...
+ */
+ class CallInst : public Instruction
+ {
+ CallInst(unsigned int op = 0,const std::string &callee = ""
+ ,BasicBlock *B=NULL)
+ : m_callee(callee)
+ , Instruction(op)
+ {};
+
+ void *operator new(size_t s) {
+ return User::operator new(s, 0);
+ }
+
+ std::string m_callee;
+ std::vector<Value *> m_Params;
+ std::string m_ret; // Store computed opcode instruction
+ public:
+
+ const char *getOpcodeName() ;
+
+ /* Missing the FunctionType ....
+ * callee is the called function
+ */
+ static CallInst *Create( const std::string &callee = ""
+ , BasicBlock *B= NULL)
+ {
+ return new CallInst(AEL_CALLOpcode,callee,B);
+ }
+ /*
+ * Parameter should be a Value, Constant Expression, GlobalVariable and so on
+ */
+ void addParam(Value *p)
+ { m_Params.push_back(p) ; } ;
+
+ std::string getCallee() const
+ {
+ return m_callee;
+ }
+
+ size_t getNbParameters() const
+ {
+ return m_Params.size();
+ }
+ Value *getParameter(int i) const
+ {
+ return m_Params[i];
+ }
+ /*
+ * This is wrong with the new virtual machine
+ * TODO: See how to handle this case
+ */
+ virtual size_t NbOpcode() const
+ { return 1 + m_Params.size();};
+ };
+
+ /**
+ * Compare is not part of lds automaton. This is an extension
+ *
+ *
+ */
+ class CmpInst : public Instruction
+ {
+ CmpInst(unsigned int op,const std::string &s="",bool lc=false);
+
+ CmpInst(unsigned int op,Value *v,const std::string &s="",bool lc=false);
+
+ void *operator new(size_t s) {
+ return User::operator new(s, 0);
+ }
+
+ public:
+ static CmpInst *Create(BasicBlock *B) {
+ return new CmpInst(AEL_EQUOpcode);
+ }
+ static CmpInst *Create(const std::string &B) {
+ return new CmpInst(AEL_EQUOpcode,B);
+ }
+ static CmpInst *Create(Value *v,const std::string &B) {
+ return new CmpInst(AEL_EQUOpcode,v,B);
+ }
+
+ virtual size_t NbOpcode() const { return 2;};
+
+ virtual const char *getOpcodeName();
+
+ protected:
+ std::string m_Flag;
+ std::string m_CmpInst;
+ bool m_LoadConstant;
+ unsigned long m_Constant;
+ aeb::lds::Value *m_Value;
+ };
+
+ /*
+ * This is very specific to automatons. Beeing able to send a message internally.
+ *
+ */
+ class SendEventInst : public Instruction {
+ SendEventInst(unsigned int op,const std::string &evt) : Instruction(op) , m_Event(evt) {};
+ std::string m_Event;
+
+ void *operator new(size_t s) {
+ return User::operator new(s, 0);
+ }
+ protected:
+ std::vector<Value *> m_Params;
+ public:
+ static SendEventInst *Create(const Value *evt) {
+ return new SendEventInst(AEL_LOOP_MSGOpcode,evt->getName());
+ };
+ // Send Event to other Agent or Pid
+ static SendEventInst *CreateOutput(const Value *v) {
+ return new SendEventInst(AEL_OUTPUTOpcode,v->getName());
+ };
+ virtual size_t NbOpcode() const
+ { return 2 + m_Params.size();};
+
+ virtual const char *getOpcodeName();
+
+ void addParam(Value *p)
+ { m_Params.push_back(p) ; } ;
+
+ size_t getNbParameters() const
+ {
+ return m_Params.size();
+ }
+ Value *getParameter(int i) const
+ {
+ return m_Params[i];
+ }
+ protected:
+ };
+ /**
+ * In lds, GOTO means set the VM into another State.
+ */
+ class GotoStateInst : public Instruction
+ {
+ GotoStateInst(unsigned int op,const std::string &s)
+ : Instruction(op)
+ ,m_State(s)
+ {};
+
+ void *operator new(size_t s) {
+ return User::operator new(s, 0);
+ }
+ public:
+ static GotoStateInst *Create(const std::string &sn) {
+ return new GotoStateInst(AEL_ETATOpcode,sn);
+ };
+
+ virtual const char *getOpcodeName() {
+ static std::string s;
+ s = Instruction::getOpcodeName(m_Opcode) ;
+ s+= ", " ; s+=m_State; return s.c_str(); };
+ protected:
+ std::string m_State;
+ virtual size_t NbOpcode() const { return 2 ;};
+ };
+}
+}
+/**
+ * ex: set et sw=4 ts=4 list:
+ */
+#endif
--- /dev/null
+#ifndef IR_MODULE_H__
+#define IR_MODULE_H__
+
+#include "aeb/dlilist.h"
+#include "IR/BasicBlock.h"
+#include "IR/Behavior.h"
+#include "IR/Function.h"
+#include "IR/Signal.h"
+#include "IR/Transition.h"
+#include "IR/SymbolTableTraits.h"
+#include "IR/State.h"
+#include "IR/GlobalVariable.h"
+
+namespace aeb {
+
+namespace lds {
+
+/**
+ * The module contains several lists :
+ * -> list of functions
+ * -> list of states
+ * -> list of events
+ * -> list of transitions. Which somehow owns an event. An event owns a function signature and even a Body
+ * Depending on the the State and Transition, the same event might have multiple implementations
+ *
+ * Several iterators a required for that purpose.
+ *
+ */
+class Module {
+ public:
+ typedef SymbolTable<aeb::lds::State> StateListType;
+ typedef SymbolTable<aeb::lds::Function> FunctionListType;
+ typedef SymbolTable<aeb::lds::Signal> SignalListType;
+ typedef SymbolTable<aeb::lds::GlobalVariable> GlobalListType;
+
+ typedef StateListType::iterator state_iterator;
+ typedef FunctionListType::iterator function_iterator;
+ typedef GlobalListType::iterator global_iterator;
+ typedef SignalListType::iterator signal_iterator;
+ protected:
+ std::string m_Name;
+ StateListType m_States;
+ FunctionListType m_Functions;
+ SignalListType m_Signals;
+ GlobalListType m_Globals;
+ public:
+ Module(const std::string &name ="") ;
+ virtual ~Module() ;
+
+ // SymbolTable stuff
+ static GlobalListType Module::*getSublistAccess(GlobalVariable *)
+ {
+ return &Module::m_Globals;
+ }
+
+ static FunctionListType Module::*getSublistAccess(Function *) {
+ return &Module::m_Functions;
+ }
+
+ static SignalListType Module::*getSublistAccess(Signal *) {
+ return &Module::m_Signals;
+ }
+
+ static StateListType Module::*getSublistAccess(State *) {
+ return &Module::m_States;
+ }
+
+
+ std::string getName() const {return m_Name; };
+ // Wrong Return State !!
+ Function *getOrInsertFunction(const std::string &_name,Function *f=NULL,Function::FctType fct=Function::Local);
+
+ State *getOrInsertState(const std::string &_name,State *s=NULL);
+
+ Signal *getOrInsertSignal(const std::string &_name);
+
+ Function *getFunction(const std::string &_name);
+
+ // Iterator
+ state_iterator state_begin() {return m_States.begin() ; }
+ state_iterator state_end() {return m_States.end() ; }
+
+ function_iterator function_begin() {return m_Functions.begin() ; }
+ function_iterator function_end() {return m_Functions.end() ; }
+
+ global_iterator global_begin() {return m_Globals.begin() ; }
+ global_iterator global_end() {return m_Globals.end() ; }
+
+ signal_iterator signal_begin() {return m_Signals.begin() ; }
+ signal_iterator signal_end() {return m_Signals.end() ; }
+ //
+ //
+ //
+ State *getState(const std::string &_name);
+
+ const GlobalListType &getGlobalList() const;
+
+ const FunctionListType &getFunctionList() const;
+
+ GlobalVariable *getGlobal(const std::string &_name);
+
+ void insertGlobal(GlobalVariable *g);
+ // Simple Function when GlobalVariable is just a Flag
+ GlobalVariable *insertGlobal(const std::string &_flag,bool c,Type *_Ty = NULL);
+};
+
+
+
+}
+}
+#endif
+/**
+ * ex: set et sw=4 ts=4 list:
+ */
--- /dev/null
+#ifndef __OPERAND_TRAITS_H__
+#define __OPERAND_TRAITS_H__
+
+namespace aeb {
+namespace lds {
+
+template <typename SubClass, unsigned ARITY>
+struct FixedNumOperandTraits {
+ static Use *op_begin(SubClass* U) {
+ return reinterpret_cast<Use*>(U) - ARITY;
+ }
+ static Use *op_end(SubClass* U) {
+ return reinterpret_cast<Use*>(U);
+ }
+ static unsigned operands(const User*) {
+ return ARITY;
+ }
+};
+
+}
+}
+
+
+#define DECLARE_OPERAND_ACCESS(VALUE) \
+ public: \
+ inline op_iterator op_begin(); \
+ inline const_op_iterator op_begin() const; \
+ inline op_iterator op_end(); \
+ inline const_op_iterator op_end() const; \
+ protected: \
+ template <int Idx> Use &Op(); \
+ public:
+
+#define DEFINE_OPERAND_ACCESS(CLASS,VALUE) \
+ template <int Idx> Use &CLASS::Op() { \
+ return this->OpFrom<Idx>(this); \
+ } \
+ CLASS::op_iterator CLASS::op_begin() { \
+ return OperandTraits<CLASS>::op_begin(this); \
+} \
+CLASS::const_op_iterator CLASS::op_begin() const { \
+ return OperandTraits<CLASS>::op_begin(const_cast<CLASS*>(this)); \
+} \
+CLASS::op_iterator CLASS::op_end() { \
+ return OperandTraits<CLASS>::op_end(this); \
+} \
+CLASS::const_op_iterator CLASS::op_end() const { \
+ return OperandTraits<CLASS>::op_end(const_cast<CLASS*>(this)); \
+} \
+
+
+
+#endif
--- /dev/null
+#ifndef IR_SIGNAL_H__
+#define IR_SIGNAL_H__
+
+#include "aeb/dlilist.h"
+#include "IR/BasicBlock.h"
+#include "IR/Behavior.h"
+#include "IR/Argument.h"
+#include "IR/SymbolTableTraits.h"
+
+namespace aeb {
+
+namespace lds {
+class State;
+class Function;
+class Module;
+
+
+/**
+ * A Signal is a function
+ * Method of a state that can have parameters ...
+ *
+ *
+ */
+class Signal : public Behavior
+ , public aeb::dlilist_node<Signal>
+{
+
+ public:
+ /* Tells if the function is a declaration or a local implementation .... */
+ enum FctType {
+ Local
+ ,ExternalLink
+ };
+
+ typedef aeb::SymbolTable<aeb::lds::SigArgument> ArgumentListType;
+
+ typedef ArgumentListType::iterator ArgumentIterator;
+ typedef ArgumentListType::const_iterator ArgumentConstIterator;
+ protected:
+ Module *m_Parent;
+ FctType m_FctType;
+ long m_NbParam;
+ ArgumentListType m_ArgumentList;
+ public:
+ Signal(const std::string &s="DefFct",FctType fc=ExternalLink) ;
+
+ static Signal *Create(const std::string &name,FctType ft = ExternalLink)
+ {
+ return new Signal(name,ft);
+ }
+ Module *getParent() { return m_Parent;};
+
+ const Module *getParent() const { return m_Parent;};
+
+ void setParent(Module *p) { m_Parent = p; };
+
+ bool isExternal() const { return m_FctType == ExternalLink; };
+ // SymbolTable stuff
+ static ArgumentListType Signal::*getSublistAccess(SigArgument *)
+ {
+ return &Signal::m_ArgumentList;
+ }
+
+ // TODO Temporary, needs to be removed
+ inline long getNbParams() { return args().size(); };
+ inline void setNbParams(long i) { m_NbParam = i; };
+ //
+ inline ArgumentListType &args()
+ { return m_ArgumentList;};
+ //
+ bool operator ==(const std::string &s) const
+ { return ! m_Name.compare(s); }
+
+ bool operator !=(const std::string &s) const
+ { return m_Name.compare(s); }
+
+ // Iterators
+ ArgumentIterator arg_begin() { return m_ArgumentList.begin() ; }
+ ArgumentIterator arg_end() { return m_ArgumentList.end() ; }
+
+ ArgumentConstIterator arg_begin() const
+ { return m_ArgumentList.begin() ; }
+
+ ArgumentConstIterator arg_end() const
+ { return m_ArgumentList.end() ; }
+};
+
+
+}
+}
+#endif
--- /dev/null
+#ifndef IR_STATE_H__
+#define IR_STATE_H__
+
+#include "aeb/dlilist.h"
+#include "IR/BasicBlock.h"
+#include "IR/Transition.h"
+#include "IR/SymbolTableTraits.h"
+
+namespace aeb {
+namespace lds {
+ class State;
+}
+
+namespace lds {
+class Signal;
+/**
+ * The State contains several lists :
+ * -> list of states
+ * -> list of events
+ * -> list of transitions. Which somehow is a function
+ *
+ * Several iterators a required for that purpose.
+ *
+ */
+class State : public aeb::dlilist_node<State> {
+ public:
+ //typedef aeb::dlilist<aeb::lds::Transition> TransitionListType;
+ typedef SymbolTable<aeb::lds::Transition> TransitionListType;
+
+ typedef TransitionListType::iterator transition_iterator;
+ typedef TransitionListType::const_iterator const_transition_iterator;
+
+ protected:
+ std::string m_Name;
+ TransitionListType m_Transitions;
+ Module *m_Parent;
+ public:
+ State(const std::string &_n="") : m_Name(_n) ,m_Parent(NULL) {};
+ virtual ~State() {
+ } ;
+
+ static TransitionListType State::*getSublistAccess(lds::Transition *) {
+ return &State::m_Transitions;
+ }
+
+ void setParent(Module *m) { m_Parent = m ; };
+
+ Module *getParent() { return m_Parent; }
+ const Module *getParent() const { return m_Parent; }
+ std::string getName() const { return m_Name; };
+ // Wrong Return State !!
+ Transition *getOrInsertTransition(const std::string &_name,Transition *t);
+ // A Transition, reacts on an event, executs Function and goes to State ...
+ // What if the state is not yet created ? (forward declaration....)
+ void insertTransition(Transition *t,Signal *evt,Function *fct,const std::string &st);
+
+ // Iterators
+ transition_iterator transition_begin() { return m_Transitions.begin() ; }
+ transition_iterator transition_end() { return m_Transitions.end() ; }
+ //
+ Transition *getTransition(const std::string &_name);
+};
+
+
+
+}
+}
+#endif
--- /dev/null
+#ifndef SYMBOLTABLETRAITS_H__
+#define SYMBOLTABLETRAITS_H__
+
+#include "aeb/dlilist.h"
+
+namespace aeb {
+
+ template <typename NodeTy> class dlilist_iterator;
+ template <typename NodeTy,typename Traits> class dlilist;
+ template <typename NodeTy> struct dlilist_traits ;
+
+ template <typename NodeTy>
+ struct SymbolTableListSentinelTraits : public dlilist_embedded_sentinel_traits<NodeTy> {};
+
+template <typename NodeTy> struct SymbolTableParentType {};
+namespace lds {
+ class Function;
+ class Behaviour;
+ class Argument;
+ class SigArgument;
+ class Intruction;
+ class Signal;
+ class BasicBlock;
+ class GlobalVariable;
+ class Transition;
+ class State;
+}
+
+#define DEF_SYMBOL_TABLE_PARENT_TYPE(node,parent) \
+ template<> struct SymbolTableParentType<lds::node> {typedef lds::parent type; };
+
+DEF_SYMBOL_TABLE_PARENT_TYPE(Instruction,BasicBlock)
+//DEF_SYMBOL_TABLE_PARENT_TYPE(BasicBlock,Function)
+DEF_SYMBOL_TABLE_PARENT_TYPE(BasicBlock,Behavior)
+DEF_SYMBOL_TABLE_PARENT_TYPE(Argument,Function)
+DEF_SYMBOL_TABLE_PARENT_TYPE(SigArgument,Signal)
+DEF_SYMBOL_TABLE_PARENT_TYPE(Function,Module)
+DEF_SYMBOL_TABLE_PARENT_TYPE(GlobalVariable,Module)
+DEF_SYMBOL_TABLE_PARENT_TYPE(Signal,Module)
+DEF_SYMBOL_TABLE_PARENT_TYPE(State,Module)
+DEF_SYMBOL_TABLE_PARENT_TYPE(Transition,State)
+
+#undef DEF_SYMBOL_TABLE_PARENT_TYPE
+
+template <typename NodeTy> class SymbolTable;
+#if 0
+/**
+ * Inspired from llvm that is quiet complicated
+ *
+ * The first idea is to check if the callback mecanism works
+ * 05/02/2015 it just does not work...
+ */
+template <typename SubClass, typename ParentClass>
+class SymbolTableTraits : public dlilist_default_traits<SubClass> {
+
+ typedef dlilist_traits<SubClass> TraitsClass;
+ public:
+
+ /**
+ * would never be able to write such a thing
+ */
+ ParentClass *getListOwner() {
+ // Did not work because of dlilist template parameter wich was wrong
+ size_t Offset(size_t(&((ParentClass*)NULL->*ParentClass::
+ getSublistAccess(static_cast<SubClass*>(NULL)))));
+
+ // This cast does not work :-(
+ aeb::dlilist<SubClass>* Anchor(static_cast< aeb::dlilist<SubClass> * const >(this) );
+
+ return reinterpret_cast<ParentClass*>(reinterpret_cast<char*>(Anchor)-
+ Offset);
+ }
+
+ SymbolTableTraits() { };
+
+ void addNodeToList(SubClass *V) ;
+
+ void removeNodeFromList(SubClass *V);
+
+ void transferNodeFromList(dlilist_traits<SubClass> &L2,
+ dlilist_iterator<SubClass> first,
+ dlilist_iterator<SubClass> last);
+
+} ;
+#endif
+/**
+ * New
+ */
+template <typename SubClass>
+class SymbolTableListTraits
+ : public dlilist_prevnext_traits<SubClass>
+ , public SymbolTableListSentinelTraits<SubClass>
+ , public dlilist_node_traits<SubClass>
+{
+ public:
+ typedef SymbolTable<SubClass> ListTy;
+ typedef typename SymbolTableParentType<SubClass>::type ItemParent;
+
+ SymbolTableListTraits() { };
+
+ private:
+ /**
+ * would never be able to write such a thing
+ */
+ ItemParent *getListOwner() {
+ // Did not work because of dlilist template parameter wich was wrong
+ size_t Offset(size_t(&((ItemParent*)NULL->*ItemParent::
+ getSublistAccess(static_cast<SubClass*>(NULL)))));
+
+ // This cast does not work :-(
+ ListTy* Anchor(static_cast< ListTy * const >(this) );
+
+ return reinterpret_cast<ItemParent*>(reinterpret_cast<char*>(Anchor)-
+ Offset);
+ }
+
+ public:
+ void addNodeToList(SubClass *V) ;
+
+ void removeNodeFromList(SubClass *V);
+
+ void transferNodeFromList(SymbolTableListTraits &L2,
+ dlilist_iterator<SubClass> first,
+ dlilist_iterator<SubClass> last);
+
+} ;
+
+
+template <typename NodeTy>
+class SymbolTable : public aeb::dlilist<NodeTy,SymbolTableListTraits<NodeTy> > {};
+
+}
+#endif
--- /dev/null
+#ifndef SYMBOLTABLELISTTRAITSIMPL_H__
+#define SYMBOLTABLELISTTRAITSIMPL_H__
+
+#include "IR/SymbolTableTraits.h"
+
+namespace aeb {
+
+/* New Implementation ....*/
+#if defined(FUNCTION_SYMTAB)
+template <>
+void SymbolTableListTraits<aeb::lds::Argument>::addNodeToList(aeb::lds::Argument *s)
+{
+ ItemParent *p = getListOwner();
+ if ( !p || s->getParent() != NULL)
+ {
+ std::cerr<<"SymbolTable::addNodeToList Big Problem Parent:";
+ }
+ else
+ {
+ s->setParent(p);
+ // std::cout<<"SymbolTableListTraits "<<p->getName()<<" before: "<<p->getNbParams();
+ if (! p->isExternal())
+ p->setNbParams(p->getNbParams()+1);
+ // std::cout<<" After:"<<p->getNbParams()<<std::endl;
+ }
+}
+
+template <>
+void SymbolTableListTraits<aeb::lds::BasicBlock>::addNodeToList(aeb::lds::BasicBlock *s)
+{
+ ItemParent *p = getListOwner();
+ if ( !p || s->getParent() != NULL)
+ {
+ std::cerr<<"SymbolTable::addNodeToList BB Big Problem Parent:";
+ }
+ else
+ {
+ s->setParent(p);
+#if 0
+ // DEBUG
+ std::cout<<"SymbolTableListTraits BB "<<p->getName();
+ std::cout<<" add node : "<<s->getName()<<"\n";
+#endif
+ }
+}
+#endif
+template <typename SubClass>
+void SymbolTableListTraits<SubClass>::addNodeToList(SubClass *s)
+{
+ ItemParent *p = getListOwner();
+ if ( !p || s->getParent() != NULL)
+ {
+ std::cerr<<"SymbolTable::addNodeToList Big Problem Parent:";
+ }
+ else
+ {
+ s->setParent(p);
+ }
+}
+
+template <typename SubClass>
+void SymbolTableListTraits<SubClass>::removeNodeFromList(SubClass *S)
+{
+ //std::cerr<<"SymbolTable::removeNodeFromList \n";
+ S->setParent(NULL);
+}
+
+template <typename SubClass>
+void SymbolTableListTraits<SubClass>
+::transferNodeFromList(SymbolTableListTraits &L2,
+ dlilist_iterator<SubClass> first,
+ dlilist_iterator<SubClass> last)
+
+{
+ std::cout<<"SymbolTableTraits::transferNodeFromList "<<std::endl;
+}
+
+
+}
+
+#endif
--- /dev/null
+#ifndef IR_TRANSITION_H__
+#define IR_TRANSITION_H__
+
+#include "aeb/dlilist.h"
+#include "IR/BasicBlock.h"
+#include "IR/SymbolTableTraits.h"
+
+namespace aeb {
+#if 0
+ /* This does not work ??? I should try to figure it out always get segfaults */
+ template <> struct dlilist_traits<lds::BasicBlock>
+ : public SymbolTableTraits<lds::BasicBlock,lds::Behavior> {
+
+ dlilist_traits() : SymbolTableTraits<lds::BasicBlock,lds::Behavior>::SymbolTableTraits() {
+ std::cout<<"dlilist_traits<BasicBlock>:: construct "<<std::endl;
+ }
+
+ static void destroySentinel(lds::BasicBlock *) {
+ std::cout<<"dlilist_traits<BasicBlock>::destroySentinel"<<std::endl;
+ }
+
+ lds::BasicBlock *provideInitialHead() const {
+ lds::BasicBlock *h = createSentinel();
+ std::cout<<"dlilist_traits<BasicBlock>::provideInitialHead "<<h<<std::endl;
+ return createSentinel();
+ }
+
+ lds::BasicBlock *ensureHead(lds::BasicBlock *b) const {
+ lds::BasicBlock *h = createSentinel();
+ std::cout<<"dlilist_traits<BasicBlock>::ensureHead "<<b<<" new "<<h<<std::endl;
+ return h;
+ }
+
+ lds::BasicBlock *createStentinel() const {
+ std::cout<<"dlilist_traits<BasicBlock>::createSentinel"<<std::endl;
+ return static_cast<lds::BasicBlock *>(&Sentinel);
+ }
+
+ static void noteHead(lds::BasicBlock *,lds::BasicBlock *) {
+ std::cout<<"dlilist_traits<BasicBlock>::noteHead"<<std::endl;
+ };
+ private:
+ mutable dlilist_half_node<lds::BasicBlock> Sentinel;
+ };
+
+#endif
+namespace lds {
+class State;
+class Signal;
+class Function;
+class Module;
+
+#if 0
+/**
+ * The behavior class is a generic class for everything that contains behavioral instructions.
+ * - A function implementation is a behaviors.
+ * - A transition contains a behavior that is triggers on several events. I could say that several
+ * events implement the same behaviors
+ *
+ */
+
+class Behavior
+ {
+
+ typedef aeb::dlilist<aeb::lds::BasicBlock> BlockListType;
+ typedef BlockListType::iterator iterator;
+ typedef BlockListType::const_iterator const_iterator;
+ protected:
+
+ BlockListType m_Blocks;
+ std::string m_Name;
+
+ Behavior(const Behavior &p) ;
+ public:
+
+ Behavior(const std::string & m_Name = "") ;
+
+ virtual ~Behavior() ;
+
+ static dlilist<lds::BasicBlock> Behavior::*getSublistAccess(BasicBlock *) {
+ return &Behavior::m_Blocks;
+ }
+
+
+ // Iterators,
+ iterator begin() { return m_Blocks.begin() ; };
+ const_iterator begin() const { return m_Blocks.begin(); };
+ iterator end() { return m_Blocks.end() ; }
+ const_iterator end() const { return m_Blocks.end() ; };
+
+ void setName(const std::string &name) { m_Name = name; }
+
+ const char *getName() const { return m_Name.c_str() ; };
+ /// Access to the List to modify it
+ BlockListType &getBlockList() {
+ return m_Blocks ;
+ };
+
+ const BlockListType &getBlockList() const {
+ return m_Blocks ;
+ };
+
+};
+#endif
+
+/**
+ * \brief Transition contains BasicBlocks and Events declaration ...
+ * The events shall be reported to the State the transition belongs to.
+ *
+ * The Parent of the Transition is the State.
+ * The childs of a Transition are Blocks.
+ *
+ *
+ */
+class Transition :
+ public aeb::dlilist_node<Transition>
+{
+
+ protected:
+
+ std::string m_Name;
+ State *m_Parent;
+ Signal *m_Event;
+ std::string m_TargetState;
+ Function *m_Function;
+
+ Transition(const Transition &p) ;
+ public:
+
+ Transition(const std::string & m_Name = "SentinelDef",State *Parent = NULL) ;
+
+ virtual ~Transition() ;
+
+
+ /// Constructors are private
+ static Transition *Create(const std::string &name,State *Parent = NULL) {
+ return new Transition(name,Parent);
+ };
+
+ void setName(const std::string &name) { m_Name = name; }
+ const char *getName() const { return m_Name.c_str() ; };
+
+ State *getParent() { return m_Parent;};
+
+ const State *getParent() const { return m_Parent;};
+
+ void setParent(State *p) { m_Parent = p; };
+
+ // Setters;
+ void setEvent(Signal *s) { m_Event = s ; };
+ const std::string &getEvent() const ;
+
+ void setTargetState(const std::string &s) { m_TargetState = s ; };
+
+ std::string getTargetState() const ;
+
+ void setFunction(Function *s) { m_Function = s ; };
+ Function *getFunction() const { return m_Function; };
+};
+
+
+}
+}
+#endif
+/**
+ * ex: set et sw=4 ts=4 list:
+ */
--- /dev/null
+#ifndef TYPE_H
+#define TYPE_H
+
+namespace aeb {
+
+namespace lds {
+
+/**
+ * Values have type. It's either a BuiltinType or a Constructed type.
+ * The information must be known to be able to generate richer Intermadiate
+ * syntax.
+ */
+class Type
+{
+ public:
+ enum TypeID
+ {
+ // Primitive Types
+ VoidTyID = 0,
+ FloatTyID ,
+ LabelTyID ,
+ PidTyID ,
+ // Derived ID's
+ IntegerTyID ,
+ NaturalTyID ,
+ TimeTyID ,
+ DurationTyID,
+ FunctionTyID,
+ StructTyID ,
+ ArrayTyID ,
+ PointerTyID
+ };
+ protected:
+ TypeID m_TypeID;
+ Type(TypeID tid) ;
+ /// Array of contained types
+ Type *m_ContainedTypes;
+ unsigned m_NbContainedTys;
+ public:
+ TypeID getTypeID() const { return m_TypeID; }
+ // Simple output function
+ void print(std::ostream &os) const;
+ void printLds(std::ostream &os) const;
+ void printNative(std::ostream &os) const;
+
+ bool isVoidTy() const { return getTypeID() == VoidTyID; };
+ bool isFloatTy() const { return getTypeID() == FloatTyID; };
+ bool isPidTy() const { return getTypeID() == PidTyID; };
+ bool isFunctionTy() const { return getTypeID() == FunctionTyID; };
+ bool isArrayTy() const { return getTypeID() == ArrayTyID; };
+ bool isPointerTy() const { return getTypeID() == PointerTyID; };
+ bool isIntegerTy() const { return getTypeID() == IntegerTyID; };
+ bool isNaturalTy() const { return getTypeID() == NaturalTyID; };
+ bool isTimeTy() const { return getTypeID() == TimeTyID; };
+ bool isDurationTy() const { return getTypeID() == DurationTyID; };
+
+ /*Helper function to get instance of type*/
+ static Type *getPrimitiveType(TypeID tyid);
+};
+
+
+/* Put Derived Types here for now */
+
+class CompositeType : public Type {
+ protected:
+ CompositeType(TypeID id) : Type(id) {}
+ public:
+ virtual const Type *getTypeAtIndex(unsigned ) const;
+};
+
+/**
+ * Contains a set of element Types.
+ * I should be able to return, the number of elements and
+ * travel through them (iterator... ).
+ */
+class StructType : public CompositeType {
+ protected:
+ StructType() : CompositeType(StructTyID) {}
+ public:
+ /* Create Type known to IR */
+ static StructType *create(const std::vector<Type *> &_params);
+ /* Element Iterator */
+ /* Random access */
+ unsigned int getNumElements() const { return m_NbContainedTys; }
+ virtual const Type *getTypeAtIndex(unsigned Idx ) const {
+ assert( Idx < m_NbContainedTys && "Element out of range!");
+ return & m_ContainedTypes[Idx];
+ }
+
+};
+
+/**
+ * An array should have a type and a number of elements.
+ * All elements have the same type.
+ */
+class ArrayType : public CompositeType {
+ protected:
+ ArrayType() : CompositeType(ArrayTyID) {}
+
+ public:
+
+};
+
+}
+}
+#endif /*TYPE_H*/
--- /dev/null
+#ifndef __USE_H__
+#define __USE_H__
+
+namespace aeb {
+namespace lds {
+
+class Value;
+/**
+ * Use class makes the connection between a User and it's value. It contains
+ * the edge of the two end points
+ */
+class Use
+{
+ Use(const Use &c) {};
+ protected:
+ Value *m_Value;
+
+ Use() : m_Value(NULL) {};
+ virtual ~Use()
+ {
+ std::cout<<"~Use"<<std::endl;
+ if (m_Value)
+ removeFromList();
+ }
+ public:
+
+ Value *operator =(Value *RV)
+ {
+ set(RV);
+ return RV;
+ };
+ const Use & operator = (const Use &U)
+ {
+ if (this != &U)
+ set(U.m_Value);
+ return *this;
+ }
+ /// Getter functions
+ Value *get() const { return m_Value;}
+
+ operator Value *() const { return m_Value;}
+ // Implemented in Value class
+ inline void set(Value *v) ;
+
+ Value * operator ->() { return m_Value; }
+ const Value * operator ->() const { return m_Value; }
+ protected:
+ // Add internal list traverval feature.
+ Use *m_Next;
+ Use **m_Prev; // Array of Pointers
+
+ void setPrev(Use **useList)
+ {
+ //std::cout<<"Use("<<this<<")::setPrev "<<useList;
+ //std::cout<<" m_Prev ="<<m_Prev<<std::endl;
+ /* Does this work ? */
+ m_Prev = useList;
+ }
+
+ void addToList(Use **useList)
+ {
+ //std::cout<<"Use("<<this<<")::addToList "<<useList;
+ m_Next = *useList;
+ //std::cout<<" m_Next="<<m_Next<<std::endl;
+ if (m_Next)
+ m_Next->setPrev(&m_Next);
+ setPrev(useList);
+ *useList = this;
+ }
+
+ void removeFromList()
+ {
+ std::cout<<"Use::RemoveFromList todo"<<std::endl;
+ }
+
+ friend class Value;
+};
+
+/**
+vim: et sw=2 ts=2 bs=2 et list:
+ */
+// End namespaces aeb.lds
+}};
+#endif
--- /dev/null
+#ifndef __USER_H__
+#define __USER_H__
+
+
+#include "IR/Value.h"
+
+namespace aeb {
+namespace lds {
+
+// Forward template declaration
+template<class>
+struct OperandTraits;
+
+class User;
+
+// Template specialisation for User
+template <>
+struct OperandTraits<User>
+{
+ static inline Use * op_begin(User *);
+ static inline Use * op_end(User *);
+
+ static inline unsigned int operands(User *);
+};
+
+/**
+ * This class implements the mechanism that
+ * makes the connection between an object
+ * that uses another one.
+ *
+ * This class uses a special allocator to prepend
+ * uses before User class. This is achieved by implementing
+ * standard allocator
+ */
+class User : public Value
+{
+ Use *m_Operands;
+ unsigned int m_NumOperands;
+ public:
+ /**
+ *
+ */
+ /// operator delete - free memory allocated for User and Use objects
+ void operator delete(void *Usr);
+ /// placement delete - required by std, but never called.
+ void operator delete(void*, unsigned) {
+ std::cout<<"Constructor throws?"<<std::endl;
+ }
+ /// placement delete - required by std, but never called.
+ void operator delete(void*, unsigned, bool) {
+ std::cout<<"Constructor throws?\n";
+ }
+ protected:
+ User(Type *Ty,unsigned vty,Use *u,unsigned int nbOperand)
+ : Value(Ty,vty), m_Operands(u) , m_NumOperands(nbOperand)
+ {}
+ /* Template functions to access Operands. Real c++ magic */
+ template <int idx,typename U>
+ Use &OpFrom(const U *obj)
+ {
+ return (idx < 0)
+ ? OperandTraits<U>::op_end(const_cast<U *>(obj))[idx]
+ : OperandTraits<U>::op_begin(const_cast<U *>(obj))[idx];
+ }
+ template <int idx>
+ Use &Op() {
+ return OpFrom<idx>(this);
+ };
+ template <int idx>
+ const Use &Op() const {
+ return OpFrom<idx>(this);
+ };
+
+ void * operator new(size_t s,unsigned Us);
+ public:
+
+ unsigned int getNumOperands() const { return m_NumOperands; }
+ /** Operand Iterator Interface */
+ typedef Use *op_iterator;
+ typedef const Use *const_op_iterator;
+
+ inline op_iterator op_begin() { return m_Operands;}
+ inline const_op_iterator op_begin() const { return m_Operands;}
+ inline op_iterator op_end() { return m_Operands + m_NumOperands;}
+ inline const_op_iterator op_end() const { return m_Operands + m_NumOperands;}
+
+};
+
+// Template OperandTraits specialisation implementation
+// Only here because we use User declared methodes
+inline Use * OperandTraits<User>::op_begin(User *u)
+{
+ return u->op_begin();
+}
+
+inline Use * OperandTraits<User>::op_end(User *u)
+{
+ return u->op_end();
+}
+
+inline unsigned int OperandTraits<User>::operands(User *u)
+{
+ return u->getNumOperands();
+}
+
+
+// End namspace
+}};
+/*
+ * vim: et sw=2 ts=2 list:
+ */
+#endif
--- /dev/null
+#ifndef VALUE_H
+#define VALUE_H
+
+
+#include "IR/Use.h"
+
+namespace aeb {
+
+
+namespace lds {
+
+class Type;
+class State;
+class Function;
+class Argument;
+class Instruction;
+class GlobalVariable;
+class Module;
+
+/**
+ * Once it comes to intermediate language we get closer to the computer and memory storage.
+ * At then end, everithing that needs to be generated are bytes stored in memory
+ * These bytes must be well organized aligned and structured. Each data generated is a value.
+ * That means that Instructions are value, GlobalVariables are values, Functions are values, Arguments
+ * are values.
+ * The purpose of this class is to keep track of the kind of value we are handling.
+ *
+ * Each value has a type and can have a name. Example a GlobalVariable.
+ * An Argument.
+ */
+class Value
+{
+ Type *m_VTy;
+ std::string m_Name;
+ unsigned m_SubClassID; // SubClass of Value , eg Intruction, Function, Argument
+ bool m_Used;
+ protected:
+ Use *m_UseList; // Pointer to Use List
+ // Can only be created by sub classes
+ Value(Type *_Ty,unsigned vid);
+ //
+ Value(const Value &_g) : m_Name(_g.m_Name),m_UseList(NULL) {};
+ public:
+ virtual ~Value()
+ { }
+
+ const Type *getType() const { return m_VTy; };
+
+ void setType(Type *_Ty) { m_VTy = _Ty; } ;
+ ///
+ void setName(const std::string &n);
+
+ const std::string &getName() const;
+ /// We need to know if a value is used or not.
+ bool isUsed() const { return m_Used; };
+
+ void addUse(Use &u)
+ {
+ // TODO For debug purpose to be removed
+ //std::cout<<"Value("<<this<<"::"<<getName()<<")::addUse called"<<std::endl;
+ m_Used = true;
+ u.addToList(&m_UseList);
+ };
+ /// An enumeration for keeping track of the concrete subclass of Value that
+ /// is actually instantiated. Values of this enumeration are kept in the
+ /// Value classes SubclassID field. They are used for concrete type
+ /// identification.
+ enum ValueTy {
+ ArgumentVal, // This is an instance of Argument
+ BasicBlockVal, // This is an instance of BasicBlock
+ FunctionVal, // This is an instance of Function
+ SignalVal, // This is an instance of Signal
+ TransitionVal, // This is an instance of Transition
+ GlobalVariableVal, // This is an instance of GlobalVariable
+ UndefValueVal, // This is an instance of UndefValue
+ BlockAddressVal, // This is an instance of BlockAddress
+ ConstantExprVal, // This is an instance of ConstantExpr
+ ConstantDataArrayVal, // This is an instance of ConstantDataArray
+ ConstantIntVal, // This is an instance of ConstantInt
+ ConstantFPVal, // This is an instance of ConstantFP
+ ConstantArrayVal, // This is an instance of ConstantArray
+ ConstantStructVal, // This is an instance of ConstantStruct
+ ConstantVectorVal, // This is an instance of ConstantVector
+ ConstantPointerNullVal, // This is an instance of ConstantPointerNull
+ InlineAsmVal, // This is an instance of InlineAsm
+ InstructionVal, // This is an instance of Instruction
+ // Enum values starting at InstructionVal are used for Instructions;
+ // don't add new values here!
+
+ // Markers:
+ ConstantFirstVal = FunctionVal,
+ ConstantLastVal = ConstantPointerNullVal
+ };
+ inline bool isArgument() const { return m_SubClassID == ArgumentVal ; }
+ inline bool isGlobalVariable() const { return m_SubClassID == GlobalVariableVal ; }
+ inline bool isBasicBlock() const { return m_SubClassID == BasicBlockVal ; }
+};
+
+// Use::set implementation
+void Use::set(Value *v)
+{
+ if (m_Value)
+ {
+ std::cout<<"Use::set Remove previous value "<<m_Value;
+ std::cout<<" from use for "<<v->getName()<<std::endl;
+ removeFromList();
+ }
+ if (v)
+ v->addUse(*this);
+ m_Value = v;
+}
+
+}
+}
+
+/**
+ * ex: sw=2 et list:
+ */
+#endif /*VALUE_H*/
--- /dev/null
+#ifndef OPCODE
+# define OPCODE(NUM,OP,SIZE,CLASS)
+#endif
+#ifndef OPCODE_TABLE
+# define OPCODE_TABLE(OP,SIZE)
+#endif
+
+#ifndef HANDLE_BINARY_INST
+#ifndef OPCODE
+# define HANDLE_BINARY_INST(NUM,OP,SIZE,CLASS)
+#else
+# define HANDLE_BINARY_INST(NUM,OP,SIZE,CLASS) OPCODE(NUM,OP,SIZE,CLASS)
+#endif
+#endif
+
+OPCODE_TABLE(FLAG_TABLE,1)
+OPCODE_TABLE(CASE_TABLE,1)
+OPCODE_TABLE(JUMP_TABLE,1)
+
+OPCODE( 1,AEL_NOP,1,Instruction)
+OPCODE( 2,AEL_RETURN,1,ReturnInst) /* Put at the end of the excution of event action. */
+OPCODE( 3,AEL_ETAT,1,Instruction) /* Switch to state goto translation */
+OPCODE( 4,AEL_JUMP_PLUS,2,BranchInst)
+OPCODE( 5,AEL_JUMP_PLUS_IF,2,BranchCondInst)
+OPCODE( 6,AEL_JUMP_PLUS_IF_NOT,2,BranchCondInst)
+OPCODE( 7,AEL_JUMP_MOINS,2,BranchInst)
+OPCODE( 8,AEL_JUMP_IND,3,BranchInst) /* Jump Indirect used for switch case, jump_ind end idx ,,, end contains jump_mois idx */
+OPCODE( 9,AEL_JSR,1,BranchInst) /* Jump Subroutine */
+OPCODE(10,AEL_JSR_IND,1,BranchInst) /* Jump Subroutine Indirect */
+OPCODE(11,AEL_RTS,1,ReturnInst) /* EXIT end the execution put at end of procedure go back to caller */
+OPCODE(12,AEL_SET,2,Instruction) /* Set value to true*/
+OPCODE(13,AEL_RESET,2,Instruction) /* Set value to false */
+OPCODE(14,AEL_CHARGE,2,LoadInst) /* Load GLOBAL R into REGISTER (second parameter) used to Store result */
+OPCODE(15,AEL_TEST,2,Instruction) /* Load REGISTER into GLOBAL R*/
+
+OPCODE(16,AEL_LOOP_MSG,1,Instruction) /* Send Internal event*/
+OPCODE(17,AEL_CALL,1,CallInst) /* Special opcode ... call user defined function .... */
+
+OPCODE(20,AEL_COMPL,2,BinaryOperator) /* Not operation */
+
+HANDLE_BINARY_INST(21,AEL_AND,1,BinaryOperator) /* Binary operands binary AND operation */
+HANDLE_BINARY_INST(22,AEL_OR,1,BinaryOperator) /* Binary operands binary OR operation */
+HANDLE_BINARY_INST(23,AEL_PLUS,1,BinaryOperator) /* Binary operands binary Addition operation */
+HANDLE_BINARY_INST(24,AEL_MOIN,1,BinaryOperator) /* Binary operands binary Minus operation */
+HANDLE_BINARY_INST(25,AEL_MUL,1,BinaryOperator) /* Binary operands binary Multiplication operation */
+HANDLE_BINARY_INST(26,AEL_EQU,1,BinaryOperator) /* Binary operands binary compare EQ,NE,GT,LT operation */
+
+OPCODE(27,AEL_OUTPUT,1,Instruction) /* Special opcode ... call user defined function .... */
+OPCODE(28,AEL_ALLOCA,1,Instruction) /* Special opcode ... call user defined function .... */
+OPCODE(29,AEL_EXTRACT,1,Instruction) /* Special opcode ... call user defined function .... */
+ /* Missing AEL_CREATE to create an agent */
+/* Begining of user defined AELS */
+OPCODE(30,AEL_END,1,Instruction)
+
+#undef OPCODE
+#undef OPCODE_TABLE
+#undef HANDLE_BINARY_INST
--- /dev/null
+#ifndef AUTOMATONBYTECODE_H
+#define AUTOMATONBYTECODE_H
+
+namespace lds
+{
+
+/**
+ * This class is responsible to generate the
+ * automaton bytecode. maybe read and write
+ * The structure of the binary file is as follow
+ * -> long Magic Number
+ * -> long Version Number
+ * -> short Constant_poll_count
+ * -> cp_info Constant pool[]
+ * ->
+ * -> short State_pool_count can be until 1000 states !
+ * -> state_info State_pool[]
+ *
+ * ->
+ */
+class AutomatonBytecode
+{
+ public:
+ // Default Constructor, Stream can be file or streambuff
+ AutomatonBytecode(std::ostream &os);
+ // Default Destructor
+ ~AutomatonBytecode();
+ // Generate Bytecode
+ void Generate(aeb::lds::Module &m);
+ void Generate(AST::TranslationUnitDecl *);
+ protected:
+ std::ostream &m_ostream;
+};
+
+
+}
+#endif /*AUTOMATONBYTECODE_H*/
--- /dev/null
+#ifndef BYTECODEREADER_H
+#define BYTECODEREADER_H
+
+namespace lds {
+
+/**
+ * Read and LDS bytecode file this should
+ * help the Engine construct the required
+ * binary structures for the excution of
+ * the code
+ *
+ */
+class BytecodeReader
+{
+};
+
+};
+#endif /*BYTECODEREADER_H*/
--- /dev/null
+#ifndef BYTECODEWRITER_H
+#define BYTECODEWRITER_H
+
+namespace lds {
+
+/**
+ * Does the byte code writer need the file ?
+ * I'm not sure.
+ */
+class BytecodeWriter
+{
+ public:
+ BytecodeWriter(std::ostream &o);
+
+ ~BytecodeWriter();
+
+ void WriteInstruction(aeb::lds::Instrcution &i);
+ protected:
+};
+
+};
+
+#endif /*BYTECODEWRITER_H*/
--- /dev/null
+#ifndef LDSEXECUTIONCONTEXT_H
+#define LDSEXECUTIONCONTEXT_H
+
+#define MIN_EC_STACK_SIZE 20
+#define MAX_EC_STACK_SIZE (2 * MIN_EC_STACK_SIZE)
+#define FLAG_GLOBAL 0
+
+namespace lds {
+
+typedef long Instruction;
+
+/** CallInformation Status */
+#define CIST_OAH (1<<0) /* */
+#define CIST_SDL (1<<2) /* Running SDL function */
+#define CIST_HOOKED (1<<3) /* Running Hook Functon */
+#define CIST_FRESH (1<<4) /* Initial Call */
+/**
+ * Call Information is part of the execution context.
+ * Keeps track of the current call and handles call
+ * another function .... to be able to come back
+ */
+struct CallInformation
+{
+ public:
+ CallInformation();
+
+ inline void incPC(int i = 1) { m_pc += i; };
+ inline void decPC(int i = 1) { m_pc -= i; };
+ inline void setPC(long i = 0) { m_pc = (Instruction *)i; };
+ inline Instruction *getPC(void ) { return m_pc; };
+
+ StackIdx m_func; /* Function location in stack */
+ TypeValue *m_top; /* Top position in the stack */
+ // I should separate LDS calls from C calls
+ StackIdx m_base; /* In case of SDL base stack */
+ Instruction *m_pc; /* Program/Inst Counter in PC */
+ // Linked list of CallInformation
+ CallInformation *m_previous;
+ CallInformation *m_next; /* Dynamic call link */
+ int m_call_status; /* Call status */
+};
+
+
+/**
+ * This class will contains the heap (allocated mem)
+ * Program loaded from bytecode
+ */
+struct GlobalContext
+{
+
+};
+
+/**
+ * The execution context is used by The engine
+ * to run the program.
+ *
+ */
+struct ExecutionContext
+{
+ public:
+ //
+ ExecutionContext();
+ //
+ ~ExecutionContext();
+ /**
+ * Load Byte code into Context.
+ * -> Initial m_base_ci with the entry point function
+ * ->
+ */
+ void Load(const std::string &file_name);
+ /* Naming */
+ inline void incIP(int i = 1) { m_ci->incPC(i); };
+ inline void decIP(int i = 1) { m_ci->decPC(i); };
+ inline void setIP(int i = 0) { m_ci->setPC(i); };
+ inline long getIP(void ) { return (long )m_ci->getPC(); };
+ inline long getOpcode(long IP) { return (long)*m_ci->getPC() ;};
+ //
+ inline void setState( long state ) {; };
+ inline long getState( void ) { return 0 ; };
+ //
+ inline TypeValue &Register(long reg) { return m_registers[reg];};
+ inline TypeValue &Accumulator() { return m_registers[0]; };
+ //
+ //
+ inline CallInformation *get_ci() { return m_ci ; };
+
+ inline StackIdx get_top() { return m_top; };
+
+ int precall(StackIdx func,int nresults);
+
+ void postcall(StackIdx func,int nresults);
+ protected:
+ /* Last free entry in stack */
+ StackIdx m_last_stack;
+ /* First free block in stack */
+ StackIdx m_top;
+ /* Pointer to the stack */
+ StackIdx m_stack;
+ /* Current Call Inforamtion */
+ CallInformation *m_ci;
+ /* Initial Call Information */
+ CallInformation m_base_ci;
+ /**/
+ int m_status;
+ TypeValue m_registers[10];
+ private:
+ // I don't want to use dynamic allocation for stack
+ TypeValue m_ec_stack[MAX_EC_STACK_SIZE];
+};
+};
+
+#endif /*LDSEXECUTIONCONTEXT_H*/
--- /dev/null
+#ifndef LDSEXECUTIONENGINE_H
+#define LDSEXECUTIONENGINE_H
+
+
+namespace lds
+{
+
+enum OpCodes {
+ NullOpcode = -1
+#define OPCODE(NUM,OP,SIZE,CLASS) , OP
+#include "IR/ldsOpcode.h"
+} ;
+
+/**
+ * The LDS Virtual Machine
+ */
+class ExecutionEngine
+{
+ public:
+ typedef void (*pEEFunction)(ExecutionContext &);
+
+ ExecutionEngine()
+ {
+#define OPCODE(NUM,OP,SIZE,CLASS) m_BuiltinOp[lds::OP] = &ExecutionEngine::OP ;
+#include "IR/ldsOpcode.h"
+ };
+
+ void Load(const std::string &file_name,ExecutionContext &e);
+
+ void run(ExecutionContext &c);
+ protected:
+ pEEFunction m_BuiltinOp[lds::AEL_END+1];
+ // AEL BUILT IN OPERATIONS
+#define OPCODE(NUM,OP,SIZE,CLASS) static void OP(ExecutionContext &) ;
+#include "IR/ldsOpcode.h"
+};
+
+};
+
+#endif /*LDSEXECUTIONENGINE_H*/
--- /dev/null
+#ifndef LDSOBJECT_H
+#define LDSOBJECT_H
+
+
+namespace lds {
+
+ class ExecutionContext ;
+ typedef int (*ldsCFunction)(lds::ExecutionContext *);
+
+#define LDS_TFUNCTION 0
+#define LDS_TSTRING 1
+#define LDS_TNUMBER 2
+
+/* Variation of basic types */
+
+#define LDS_TCFUNC (LDS_TFUNCTION | (0<<4)) /* raw C function */
+#define LDS_TLFUNC (LDS_TFUNCTION | (1<<4)) /* LDS TASK */
+
+#define LDS_TNUMINT (LDS_TNUMBER | (0<<4))
+#define LDS_TNUMREAL (LDS_TNUMBER | (1<<4))
+
+
+/**
+ * Type Value Handled by the LDS Virtual Machine
+ * Missing Function / Object types
+ */
+typedef struct _LdsTypeValue {
+
+ union {
+ void *p; /* Unknown data */
+ int b; /* boolean */
+ long l; /* Integer */
+ double d; /* Real */
+ ldsCFunction f; /* CFunction */
+ } m_value;
+ int m_type; /* Object Type bits 4-5 variation / bit 3-0 TYPE */
+
+ /* Lets define some operators */
+ _LdsTypeValue &operator ||(const _LdsTypeValue &v)
+ {
+ assert(m_type == v.m_type);
+ return *this;
+ };
+ //
+ _LdsTypeValue &operator &&(const _LdsTypeValue &v)
+ {
+ assert(m_type == v.m_type);
+ return *this;
+ };
+ //
+ bool operator !()
+ {
+ return true;
+ }
+ //
+ _LdsTypeValue &operator =(const _LdsTypeValue &v)
+ {
+ assert(m_type == v.m_type);
+ return *this;
+ }
+ //
+ _LdsTypeValue &operator =(const long v)
+ {
+ assert(m_type == LDS_TNUMINT);
+ return *this;
+ }
+ // Cast to bool
+ operator const bool()
+ {
+ return m_value.b;
+ }
+} TypeValue;
+
+typedef TypeValue *StackIdx;
+
+}
+#endif /*LDSOBJECT_H*/