Initial import from SVN
authorEbersold <aebersol@n3150.home>
Mon, 20 Dec 2021 20:37:26 +0000 (21:37 +0100)
committerEbersold <aebersol@n3150.home>
Mon, 20 Dec 2021 20:37:26 +0000 (21:37 +0100)
177 files changed:
ADT/CMakeLists.txt [new file with mode: 0644]
ADT/asn1/Asn1Boolean.cpp [new file with mode: 0644]
ADT/asn1/Asn1Choice.cpp [new file with mode: 0644]
ADT/asn1/Asn1Class.cpp [new file with mode: 0644]
ADT/asn1/Asn1Constraint.cpp [new file with mode: 0644]
ADT/asn1/Asn1Context.cpp [new file with mode: 0644]
ADT/asn1/Asn1Decl.cpp [new file with mode: 0644]
ADT/asn1/Asn1Field.cpp [new file with mode: 0644]
ADT/asn1/Asn1Integer.cpp [new file with mode: 0644]
ADT/asn1/Asn1Module.cpp [new file with mode: 0644]
ADT/asn1/Asn1Object.cpp [new file with mode: 0644]
ADT/asn1/Asn1Oid.cpp [new file with mode: 0644]
ADT/asn1/Asn1Sequence.cpp [new file with mode: 0644]
ADT/asn1/Asn1Set.cpp [new file with mode: 0644]
ADT/asn1/Asn1Type.cpp [new file with mode: 0644]
ADT/asn1/CMakeLists.txt [new file with mode: 0644]
AST/ASTContext.cpp [new file with mode: 0644]
AST/CMakeLists.txt [new file with mode: 0644]
AST/DeclBase.cpp [new file with mode: 0644]
AST/DeclContext.cpp [new file with mode: 0644]
AST/DeclTypeDecl.cpp [new file with mode: 0644]
AST/Expr.cpp [new file with mode: 0644]
AST/ExprCallExpr.cpp [new file with mode: 0644]
AST/ExprDeclRefExpr.cpp [new file with mode: 0644]
AST/StmtAsmStmt.cpp [new file with mode: 0644]
AST/StmtIfStmt.cpp [new file with mode: 0644]
AST/StmtOutputStmt.cpp [new file with mode: 0644]
AST/StmtWhileStmt.cpp [new file with mode: 0644]
AST/Type.cpp [new file with mode: 0644]
CMakeLists.txt [new file with mode: 0644]
CodeGen/CGExprScalar.cpp [new file with mode: 0644]
CodeGen/CGFunction.cpp [new file with mode: 0644]
CodeGen/CGModule.cpp [new file with mode: 0644]
CodeGen/CMakeLists.txt [new file with mode: 0644]
CodeGen/CodeGenType.cpp [new file with mode: 0644]
CodeGen/ModuleBuilder.cpp [new file with mode: 0644]
IR/Argument.cpp [new file with mode: 0644]
IR/BasicBlock.cpp [new file with mode: 0644]
IR/CMakeLists.txt [new file with mode: 0644]
IR/GlobalVariable.cpp [new file with mode: 0644]
IR/LdsInstruction.cpp [new file with mode: 0644]
IR/Module.cpp [new file with mode: 0644]
IR/State.cpp [new file with mode: 0644]
IR/Transition.cpp [new file with mode: 0644]
IR/Type.cpp [new file with mode: 0644]
IR/User.cpp [new file with mode: 0644]
IR/Value.cpp [new file with mode: 0644]
LDSBytecode/AutomatonBytecode.cpp [new file with mode: 0644]
LDSBytecode/CMakeLists.txt [new file with mode: 0644]
LDSExecutionEngine/CMakeLists.txt [new file with mode: 0644]
LDSExecutionEngine/LdsExecutionContext.cpp [new file with mode: 0644]
LDSExecutionEngine/LdsExecutionEngine.cpp [new file with mode: 0644]
UnitTests/CMakeLists.txt [new file with mode: 0644]
UnitTests/UNIT-TEST-adt-sdl.cpp [new file with mode: 0644]
UnitTests/UNIT-TEST-adt-sdl.h [new file with mode: 0644]
UnitTests/main_test.cpp [new file with mode: 0644]
include/ADT/Adt.h [new file with mode: 0644]
include/ADT/Adt.h.inc [new file with mode: 0644]
include/ADT/AdtChoice.h [new file with mode: 0644]
include/ADT/AdtContainer.h [new file with mode: 0644]
include/ADT/AdtField.h [new file with mode: 0644]
include/ADT/AdtModule.h [new file with mode: 0644]
include/ADT/AdtPrimitiveType.h [new file with mode: 0644]
include/ADT/AdtStruct.h [new file with mode: 0644]
include/ADT/AdtTypeRefType.h [new file with mode: 0644]
include/ADT/asn1/Asn1Boolean.h [new file with mode: 0644]
include/ADT/asn1/Asn1Choice.h [new file with mode: 0644]
include/ADT/asn1/Asn1Class.h [new file with mode: 0644]
include/ADT/asn1/Asn1Constraint.h [new file with mode: 0644]
include/ADT/asn1/Asn1Context.h [new file with mode: 0644]
include/ADT/asn1/Asn1Decl.h [new file with mode: 0644]
include/ADT/asn1/Asn1Field.h [new file with mode: 0644]
include/ADT/asn1/Asn1Integer.h [new file with mode: 0644]
include/ADT/asn1/Asn1Module.h [new file with mode: 0644]
include/ADT/asn1/Asn1Object.h [new file with mode: 0644]
include/ADT/asn1/Asn1ObjectSet.h [new file with mode: 0644]
include/ADT/asn1/Asn1Oid.h [new file with mode: 0644]
include/ADT/asn1/Asn1Sequence.h [new file with mode: 0644]
include/ADT/asn1/Asn1Set.h [new file with mode: 0644]
include/ADT/asn1/Asn1Type.h [new file with mode: 0644]
include/ADT/asn1/type.h.def [new file with mode: 0644]
include/ADT/gdmo/Gdmo.h [new file with mode: 0644]
include/ADT/gdmo/Gdmo.h.inc [new file with mode: 0644]
include/ADT/gdmo/GdmoTemplates.h [new file with mode: 0644]
include/AST/ASTConsumer.h [new file with mode: 0644]
include/AST/ASTContext.h [new file with mode: 0644]
include/AST/ASTRecursiveVisitor.h [new file with mode: 0644]
include/AST/BuiltinTypes.h.def [new file with mode: 0644]
include/AST/Context.h [new file with mode: 0644]
include/AST/Decl.h [new file with mode: 0644]
include/AST/Decl.h.inc [new file with mode: 0644]
include/AST/DeclAutomatonDecl.h [new file with mode: 0644]
include/AST/DeclBase.h [new file with mode: 0644]
include/AST/DeclBlockDecl.h [new file with mode: 0644]
include/AST/DeclContext.h [new file with mode: 0644]
include/AST/DeclEventDecl.h [new file with mode: 0644]
include/AST/DeclFieldDecl.h [new file with mode: 0644]
include/AST/DeclFunctionDecl.h [new file with mode: 0644]
include/AST/DeclLabelDecl.h [new file with mode: 0644]
include/AST/DeclNamedDecl.h [new file with mode: 0644]
include/AST/DeclPackageUseDecl.h [new file with mode: 0644]
include/AST/DeclParmVarDecl.h [new file with mode: 0644]
include/AST/DeclRecordDecl.h [new file with mode: 0644]
include/AST/DeclRefStateDecl.h [new file with mode: 0644]
include/AST/DeclStateDecl.h [new file with mode: 0644]
include/AST/DeclTransitionDecl.h [new file with mode: 0644]
include/AST/DeclTranslationUnitDecl.h [new file with mode: 0644]
include/AST/DeclTypeDecl.h [new file with mode: 0644]
include/AST/DeclValueDecl.h [new file with mode: 0644]
include/AST/DeclVarDecl.h [new file with mode: 0644]
include/AST/Expr.h [new file with mode: 0644]
include/AST/ExprBinaryOperatorExpr.h [new file with mode: 0644]
include/AST/ExprCallExpr.h [new file with mode: 0644]
include/AST/ExprConditionalOperator.h [new file with mode: 0644]
include/AST/ExprDeclRefExpr.h [new file with mode: 0644]
include/AST/ExprFloatLiteral.h [new file with mode: 0644]
include/AST/ExprIntegerLiteral.h [new file with mode: 0644]
include/AST/ExprStringLiteral.h [new file with mode: 0644]
include/AST/ExprUnaryOperatorExpr.h [new file with mode: 0644]
include/AST/FormalContextParameter.h [new file with mode: 0644]
include/AST/OperationKinds.h [new file with mode: 0644]
include/AST/Stmt.h [new file with mode: 0644]
include/AST/Stmt.h.inc [new file with mode: 0644]
include/AST/StmtAsmStmt.h [new file with mode: 0644]
include/AST/StmtBreakStmt.h [new file with mode: 0644]
include/AST/StmtCompoundStmt.h [new file with mode: 0644]
include/AST/StmtDeclStmt.h [new file with mode: 0644]
include/AST/StmtForStmt.h [new file with mode: 0644]
include/AST/StmtGotoStmt.h [new file with mode: 0644]
include/AST/StmtIfStmt.h [new file with mode: 0644]
include/AST/StmtIterator.h [new file with mode: 0644]
include/AST/StmtLabelStmt.h [new file with mode: 0644]
include/AST/StmtNullStmt.h [new file with mode: 0644]
include/AST/StmtOutputStmt.h [new file with mode: 0644]
include/AST/StmtReturnStmt.h [new file with mode: 0644]
include/AST/StmtSwitchCaseStmt.h [new file with mode: 0644]
include/AST/StmtSwitchStmt.h [new file with mode: 0644]
include/AST/StmtVisitor.h [new file with mode: 0644]
include/AST/StmtWhileStmt.h [new file with mode: 0644]
include/AST/TemplateBase.h [new file with mode: 0644]
include/AST/Type.h [new file with mode: 0644]
include/AST/Types.h.inc [new file with mode: 0644]
include/CodeGen/ASTMuliplexConsumer.h [new file with mode: 0644]
include/CodeGen/CGDebug.h [new file with mode: 0644]
include/CodeGen/CMConsumer.h [new file with mode: 0644]
include/CodeGen/CodeGenFunction.h [new file with mode: 0644]
include/CodeGen/CodeGenModule.h [new file with mode: 0644]
include/CodeGen/CodeGenType.h [new file with mode: 0644]
include/CodeGen/ModuleBuilder.h [new file with mode: 0644]
include/IR/Argument.h [new file with mode: 0644]
include/IR/BasicBlock.h [new file with mode: 0644]
include/IR/Behavior.h [new file with mode: 0644]
include/IR/Constant.h [new file with mode: 0644]
include/IR/Function.h [new file with mode: 0644]
include/IR/GlobalVariable.h [new file with mode: 0644]
include/IR/IRBuilderAdaptor.h [new file with mode: 0644]
include/IR/LdsBuilder.h [new file with mode: 0644]
include/IR/LdsInstrVisitor.h [new file with mode: 0644]
include/IR/LdsInstruction.h [new file with mode: 0644]
include/IR/Module.h [new file with mode: 0644]
include/IR/OperandTraits.h [new file with mode: 0644]
include/IR/Signal.h [new file with mode: 0644]
include/IR/State.h [new file with mode: 0644]
include/IR/SymbolTableTraits.h [new file with mode: 0644]
include/IR/SymbolTableTraitsImpl.h [new file with mode: 0644]
include/IR/Transition.h [new file with mode: 0644]
include/IR/Type.h [new file with mode: 0644]
include/IR/Use.h [new file with mode: 0644]
include/IR/User.h [new file with mode: 0644]
include/IR/Value.h [new file with mode: 0644]
include/IR/ldsOpcode.h [new file with mode: 0644]
include/LDSBytecode/AutomatonBytecode.h [new file with mode: 0644]
include/LDSBytecode/BytecodeReader.h [new file with mode: 0644]
include/LDSBytecode/BytecodeWriter.h [new file with mode: 0644]
include/LDSExecutionEngine/LdsExecutionContext.h [new file with mode: 0644]
include/LDSExecutionEngine/LdsExecutionEngine.h [new file with mode: 0644]
include/LDSExecutionEngine/LdsObject.h [new file with mode: 0644]

diff --git a/ADT/CMakeLists.txt b/ADT/CMakeLists.txt
new file mode 100644 (file)
index 0000000..2263e26
--- /dev/null
@@ -0,0 +1,3 @@
+
+
+SUBDIRS(asn1)
diff --git a/ADT/asn1/Asn1Boolean.cpp b/ADT/asn1/Asn1Boolean.cpp
new file mode 100644 (file)
index 0000000..86d290a
--- /dev/null
@@ -0,0 +1,16 @@
+#include <iostream>
+#include "ADT/asn1/Asn1Boolean.h"
+    
+//
+Asn1Boolean::Asn1Boolean()
+{
+}
+//
+Asn1Boolean::Asn1Boolean(const Asn1Boolean   &o)
+{
+}
+
+//
+Asn1Boolean::~Asn1Boolean()
+{
+}
diff --git a/ADT/asn1/Asn1Choice.cpp b/ADT/asn1/Asn1Choice.cpp
new file mode 100644 (file)
index 0000000..c51128f
--- /dev/null
@@ -0,0 +1,17 @@
+#include <iostream>
+#include "ADT/asn1/Asn1Choice.h"
+    
+// default Contructor
+Asn1Choice::Asn1Choice()
+{
+}
+
+//
+Asn1Choice::Asn1Choice(const Asn1Choice   &o)
+{
+}
+
+// default Desctructor
+Asn1Choice::~Asn1Choice()
+{
+}
diff --git a/ADT/asn1/Asn1Class.cpp b/ADT/asn1/Asn1Class.cpp
new file mode 100644 (file)
index 0000000..4fec3fe
--- /dev/null
@@ -0,0 +1,17 @@
+#include <iostream>
+#include "ADT/asn1/Asn1Class.h"
+    
+// default Contructor
+Asn1Class::Asn1Class()
+{
+}
+
+//
+Asn1Class::Asn1Class(const Asn1Class   &o)
+{
+}
+
+// default Desctructor
+Asn1Class::~Asn1Class()
+{
+}
diff --git a/ADT/asn1/Asn1Constraint.cpp b/ADT/asn1/Asn1Constraint.cpp
new file mode 100644 (file)
index 0000000..a9eb4fe
--- /dev/null
@@ -0,0 +1,19 @@
+#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()
+{
+}
diff --git a/ADT/asn1/Asn1Context.cpp b/ADT/asn1/Asn1Context.cpp
new file mode 100644 (file)
index 0000000..268c19e
--- /dev/null
@@ -0,0 +1,18 @@
+#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()
+{
+}
diff --git a/ADT/asn1/Asn1Decl.cpp b/ADT/asn1/Asn1Decl.cpp
new file mode 100644 (file)
index 0000000..f972e1f
--- /dev/null
@@ -0,0 +1,17 @@
+#include <iostream>
+#include "ADT/asn1/Asn1Decl.h"
+    
+// default Contructor
+Asn1Decl::Asn1Decl()
+{
+}
+
+//
+Asn1Decl::Asn1Decl(const Asn1Decl   &o)
+{
+}
+
+// default Desctructor
+Asn1Decl::~Asn1Decl()
+{
+}
diff --git a/ADT/asn1/Asn1Field.cpp b/ADT/asn1/Asn1Field.cpp
new file mode 100644 (file)
index 0000000..dbe9655
--- /dev/null
@@ -0,0 +1,17 @@
+#include <iostream>
+#include "ADT/asn1/Asn1Field.h"
+    
+// default Contructor
+Asn1Field::Asn1Field()
+{
+}
+
+//
+Asn1Field::Asn1Field(const Asn1Field   &o)
+{
+}
+
+// default Desctructor
+Asn1Field::~Asn1Field()
+{
+}
diff --git a/ADT/asn1/Asn1Integer.cpp b/ADT/asn1/Asn1Integer.cpp
new file mode 100644 (file)
index 0000000..fe0f563
--- /dev/null
@@ -0,0 +1,17 @@
+#include <iostream>
+#include "ADT/asn1/Asn1Integer.h"
+    
+// default Contructor
+Asn1Integer::Asn1Integer()
+{
+}
+
+//
+Asn1Integer::Asn1Integer(const Asn1Integer   &o)
+{
+}
+
+// default Desctructor
+Asn1Integer::~Asn1Integer()
+{
+}
diff --git a/ADT/asn1/Asn1Module.cpp b/ADT/asn1/Asn1Module.cpp
new file mode 100644 (file)
index 0000000..dc54a1b
--- /dev/null
@@ -0,0 +1,17 @@
+#include <iostream>
+#include "ADT/asn1/Asn1Module.h"
+    
+// default Contructor
+Asn1Module::Asn1Module()
+{
+}
+
+//
+Asn1Module::Asn1Module(const Asn1Module   &o)
+{
+}
+
+// default Desctructor
+Asn1Module::~Asn1Module()
+{
+}
diff --git a/ADT/asn1/Asn1Object.cpp b/ADT/asn1/Asn1Object.cpp
new file mode 100644 (file)
index 0000000..99144c2
--- /dev/null
@@ -0,0 +1,17 @@
+#include <iostream>
+#include "ADT/asn1/Asn1Object.h"
+    
+// default Contructor
+Asn1Object::Asn1Object()
+{
+}
+
+//
+Asn1Object::Asn1Object(const Asn1Object   &o)
+{
+}
+
+// default Desctructor
+Asn1Object::~Asn1Object()
+{
+}
diff --git a/ADT/asn1/Asn1Oid.cpp b/ADT/asn1/Asn1Oid.cpp
new file mode 100644 (file)
index 0000000..c856cb9
--- /dev/null
@@ -0,0 +1,18 @@
+#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()
+{
+}
diff --git a/ADT/asn1/Asn1Sequence.cpp b/ADT/asn1/Asn1Sequence.cpp
new file mode 100644 (file)
index 0000000..88b4b33
--- /dev/null
@@ -0,0 +1,17 @@
+#include <iostream>
+#include "ADT/asn1/Asn1Sequence.h"
+    
+// default Contructor
+Asn1Sequence::Asn1Sequence()
+{
+}
+
+//
+Asn1Sequence::Asn1Sequence(const Asn1Sequence   &o)
+{
+}
+
+// default Desctructor
+Asn1Sequence::~Asn1Sequence()
+{
+}
diff --git a/ADT/asn1/Asn1Set.cpp b/ADT/asn1/Asn1Set.cpp
new file mode 100644 (file)
index 0000000..b660b69
--- /dev/null
@@ -0,0 +1,17 @@
+#include <iostream>
+#include "ADT/asn1/Asn1Set.h"
+    
+// default Contructor
+Asn1Set::Asn1Set()
+{
+}
+
+//
+Asn1Set::Asn1Set(const Asn1Set   &o)
+{
+}
+
+// default Desctructor
+Asn1Set::~Asn1Set()
+{
+}
diff --git a/ADT/asn1/Asn1Type.cpp b/ADT/asn1/Asn1Type.cpp
new file mode 100644 (file)
index 0000000..28e2747
--- /dev/null
@@ -0,0 +1,17 @@
+#include <iostream>
+#include "ADT/asn1/Asn1Type.h"
+    
+// default Contructor
+Asn1Type::Asn1Type()
+{
+}
+
+//
+Asn1Type::Asn1Type(const Asn1Type   &o)
+{
+}
+
+// default Desctructor
+Asn1Type::~Asn1Type()
+{
+}
diff --git a/ADT/asn1/CMakeLists.txt b/ADT/asn1/CMakeLists.txt
new file mode 100644 (file)
index 0000000..b601467
--- /dev/null
@@ -0,0 +1,19 @@
+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
+    )
diff --git a/AST/ASTContext.cpp b/AST/ASTContext.cpp
new file mode 100644 (file)
index 0000000..fa93557
--- /dev/null
@@ -0,0 +1,142 @@
+#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()
+{
+}
+
+
+}
diff --git a/AST/CMakeLists.txt b/AST/CMakeLists.txt
new file mode 100644 (file)
index 0000000..798ef53
--- /dev/null
@@ -0,0 +1,16 @@
+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
+    )
diff --git a/AST/DeclBase.cpp b/AST/DeclBase.cpp
new file mode 100644 (file)
index 0000000..e56c925
--- /dev/null
@@ -0,0 +1,72 @@
+#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));
+}
+
+}
diff --git a/AST/DeclContext.cpp b/AST/DeclContext.cpp
new file mode 100644 (file)
index 0000000..d15ad3e
--- /dev/null
@@ -0,0 +1,152 @@
+#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;
+    }
+}
diff --git a/AST/DeclTypeDecl.cpp b/AST/DeclTypeDecl.cpp
new file mode 100644 (file)
index 0000000..36600f2
--- /dev/null
@@ -0,0 +1,67 @@
+#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;
+}
+
+
+}
diff --git a/AST/Expr.cpp b/AST/Expr.cpp
new file mode 100644 (file)
index 0000000..dbce1f0
--- /dev/null
@@ -0,0 +1,139 @@
+#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";
+    }
+}
+
+}
diff --git a/AST/ExprCallExpr.cpp b/AST/ExprCallExpr.cpp
new file mode 100644 (file)
index 0000000..23fe9f5
--- /dev/null
@@ -0,0 +1,32 @@
+
+#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;
+}
+
+
+}
diff --git a/AST/ExprDeclRefExpr.cpp b/AST/ExprDeclRefExpr.cpp
new file mode 100644 (file)
index 0000000..c453db1
--- /dev/null
@@ -0,0 +1,30 @@
+#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 ; }
+
+
+}
diff --git a/AST/StmtAsmStmt.cpp b/AST/StmtAsmStmt.cpp
new file mode 100644 (file)
index 0000000..ed7fb28
--- /dev/null
@@ -0,0 +1,95 @@
+#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)
+    }
+
+};
diff --git a/AST/StmtIfStmt.cpp b/AST/StmtIfStmt.cpp
new file mode 100644 (file)
index 0000000..8d28375
--- /dev/null
@@ -0,0 +1,32 @@
+#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);
+    }
+}
diff --git a/AST/StmtOutputStmt.cpp b/AST/StmtOutputStmt.cpp
new file mode 100644 (file)
index 0000000..fbea3fe
--- /dev/null
@@ -0,0 +1,62 @@
+#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:
+ */ 
diff --git a/AST/StmtWhileStmt.cpp b/AST/StmtWhileStmt.cpp
new file mode 100644 (file)
index 0000000..2eb1a3e
--- /dev/null
@@ -0,0 +1,43 @@
+#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); };
+
+
+
+
+}
diff --git a/AST/Type.cpp b/AST/Type.cpp
new file mode 100644 (file)
index 0000000..ded5323
--- /dev/null
@@ -0,0 +1,37 @@
+#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";
+  };
+}
+
+
+}
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644 (file)
index 0000000..04fd1ba
--- /dev/null
@@ -0,0 +1,8 @@
+
+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)
diff --git a/CodeGen/CGExprScalar.cpp b/CodeGen/CGExprScalar.cpp
new file mode 100644 (file)
index 0000000..b3a815c
--- /dev/null
@@ -0,0 +1,389 @@
+#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);
+}
+
+}
+}
+}
diff --git a/CodeGen/CGFunction.cpp b/CodeGen/CGFunction.cpp
new file mode 100644 (file)
index 0000000..5e3b1b6
--- /dev/null
@@ -0,0 +1,751 @@
+#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;
+}
+
+
+}
+}
+}
+
diff --git a/CodeGen/CGModule.cpp b/CodeGen/CGModule.cpp
new file mode 100644 (file)
index 0000000..1322811
--- /dev/null
@@ -0,0 +1,331 @@
+#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:
+ */ 
diff --git a/CodeGen/CMakeLists.txt b/CodeGen/CMakeLists.txt
new file mode 100644 (file)
index 0000000..10670be
--- /dev/null
@@ -0,0 +1,13 @@
+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
+    )
diff --git a/CodeGen/CodeGenType.cpp b/CodeGen/CodeGenType.cpp
new file mode 100644 (file)
index 0000000..a38e8f0
--- /dev/null
@@ -0,0 +1,102 @@
+#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:
+ */
diff --git a/CodeGen/ModuleBuilder.cpp b/CodeGen/ModuleBuilder.cpp
new file mode 100644 (file)
index 0000000..2a70306
--- /dev/null
@@ -0,0 +1,114 @@
+#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);
+}
+
+        }
+    }
+}
diff --git a/IR/Argument.cpp b/IR/Argument.cpp
new file mode 100644 (file)
index 0000000..5727d5c
--- /dev/null
@@ -0,0 +1,66 @@
+#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);
+      }
+    }
+
+
+}
+}
diff --git a/IR/BasicBlock.cpp b/IR/BasicBlock.cpp
new file mode 100644 (file)
index 0000000..3874bcf
--- /dev/null
@@ -0,0 +1,56 @@
+#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 &current) const
+{
+    size_t s = 0;
+    for ( const_iterator i = begin() ; i != current ; ++i)
+        s+= (&(*i))->NbOpcode();
+    return s;
+}
+
+
+}
+}
diff --git a/IR/CMakeLists.txt b/IR/CMakeLists.txt
new file mode 100644 (file)
index 0000000..6dc44e5
--- /dev/null
@@ -0,0 +1,18 @@
+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
+    )
diff --git a/IR/GlobalVariable.cpp b/IR/GlobalVariable.cpp
new file mode 100644 (file)
index 0000000..08b2b51
--- /dev/null
@@ -0,0 +1,40 @@
+#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;
+}
+
+}
+}
diff --git a/IR/LdsInstruction.cpp b/IR/LdsInstruction.cpp
new file mode 100644 (file)
index 0000000..2980090
--- /dev/null
@@ -0,0 +1,559 @@
+#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:
+ */ 
+
diff --git a/IR/Module.cpp b/IR/Module.cpp
new file mode 100644 (file)
index 0000000..9b2aa96
--- /dev/null
@@ -0,0 +1,146 @@
+#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);
+        }
+    }
+
+}
+}
diff --git a/IR/State.cpp b/IR/State.cpp
new file mode 100644 (file)
index 0000000..582a860
--- /dev/null
@@ -0,0 +1,34 @@
+#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);
+    }
+
+}
+}
diff --git a/IR/Transition.cpp b/IR/Transition.cpp
new file mode 100644 (file)
index 0000000..3d8fd2b
--- /dev/null
@@ -0,0 +1,93 @@
+#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)
+{
+}
+
+}
+}
diff --git a/IR/Type.cpp b/IR/Type.cpp
new file mode 100644 (file)
index 0000000..d9e9c80
--- /dev/null
@@ -0,0 +1,126 @@
+#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:
+ */
diff --git a/IR/User.cpp b/IR/User.cpp
new file mode 100644 (file)
index 0000000..fd203be
--- /dev/null
@@ -0,0 +1,41 @@
+#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 */
+}
+}
diff --git a/IR/Value.cpp b/IR/Value.cpp
new file mode 100644 (file)
index 0000000..f8908a8
--- /dev/null
@@ -0,0 +1,40 @@
+#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;
+}
+
+
+
+}
+}
diff --git a/LDSBytecode/AutomatonBytecode.cpp b/LDSBytecode/AutomatonBytecode.cpp
new file mode 100644 (file)
index 0000000..0d9b0d6
--- /dev/null
@@ -0,0 +1,246 @@
+#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;
+      }
+  }
+}
+
+
+}
diff --git a/LDSBytecode/CMakeLists.txt b/LDSBytecode/CMakeLists.txt
new file mode 100644 (file)
index 0000000..79c17f8
--- /dev/null
@@ -0,0 +1,9 @@
+PROJECT(pldsbc)
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../include/)
+INCLUDE_DIRECTORIES(${aebutils_SOURCE_DIR})
+
+
+ADD_LIBRARY(ldsbytecode
+    AutomatonBytecode.cpp
+    )
diff --git a/LDSExecutionEngine/CMakeLists.txt b/LDSExecutionEngine/CMakeLists.txt
new file mode 100644 (file)
index 0000000..03107fd
--- /dev/null
@@ -0,0 +1,10 @@
+PROJECT(pldsvm)
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../include/)
+INCLUDE_DIRECTORIES(${aebutils_SOURCE_DIR})
+
+
+ADD_LIBRARY(ldsvm
+    LdsExecutionContext.cpp
+    LdsExecutionEngine.cpp
+    )
diff --git a/LDSExecutionEngine/LdsExecutionContext.cpp b/LDSExecutionEngine/LdsExecutionContext.cpp
new file mode 100644 (file)
index 0000000..d8fc24e
--- /dev/null
@@ -0,0 +1,49 @@
+#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)
+{
+}
+
+}
diff --git a/LDSExecutionEngine/LdsExecutionEngine.cpp b/LDSExecutionEngine/LdsExecutionEngine.cpp
new file mode 100644 (file)
index 0000000..b26b561
--- /dev/null
@@ -0,0 +1,268 @@
+#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;
+    }
+
+  }
+}
+
+
+}
diff --git a/UnitTests/CMakeLists.txt b/UnitTests/CMakeLists.txt
new file mode 100644 (file)
index 0000000..615db68
--- /dev/null
@@ -0,0 +1,54 @@
+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
diff --git a/UnitTests/UNIT-TEST-adt-sdl.cpp b/UnitTests/UNIT-TEST-adt-sdl.cpp
new file mode 100644 (file)
index 0000000..84cf6a0
--- /dev/null
@@ -0,0 +1,63 @@
+#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);
+}
diff --git a/UnitTests/UNIT-TEST-adt-sdl.h b/UnitTests/UNIT-TEST-adt-sdl.h
new file mode 100644 (file)
index 0000000..c96ae66
--- /dev/null
@@ -0,0 +1,29 @@
+#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
diff --git a/UnitTests/main_test.cpp b/UnitTests/main_test.cpp
new file mode 100644 (file)
index 0000000..ebb6b4d
--- /dev/null
@@ -0,0 +1,46 @@
+#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;
+
+}
diff --git a/include/ADT/Adt.h b/include/ADT/Adt.h
new file mode 100644 (file)
index 0000000..2a81ee7
--- /dev/null
@@ -0,0 +1,70 @@
+#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
diff --git a/include/ADT/Adt.h.inc b/include/ADT/Adt.h.inc
new file mode 100644 (file)
index 0000000..a7a6a75
--- /dev/null
@@ -0,0 +1,105 @@
+/**
+ * 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
diff --git a/include/ADT/AdtChoice.h b/include/ADT/AdtChoice.h
new file mode 100644 (file)
index 0000000..4a14901
--- /dev/null
@@ -0,0 +1,37 @@
+#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
diff --git a/include/ADT/AdtContainer.h b/include/ADT/AdtContainer.h
new file mode 100644 (file)
index 0000000..bc9621d
--- /dev/null
@@ -0,0 +1,80 @@
+#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
diff --git a/include/ADT/AdtField.h b/include/ADT/AdtField.h
new file mode 100644 (file)
index 0000000..c9a7088
--- /dev/null
@@ -0,0 +1,31 @@
+#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
diff --git a/include/ADT/AdtModule.h b/include/ADT/AdtModule.h
new file mode 100644 (file)
index 0000000..63eae6d
--- /dev/null
@@ -0,0 +1,59 @@
+#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
diff --git a/include/ADT/AdtPrimitiveType.h b/include/ADT/AdtPrimitiveType.h
new file mode 100644 (file)
index 0000000..30b4762
--- /dev/null
@@ -0,0 +1,37 @@
+#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
diff --git a/include/ADT/AdtStruct.h b/include/ADT/AdtStruct.h
new file mode 100644 (file)
index 0000000..cb8faf5
--- /dev/null
@@ -0,0 +1,37 @@
+#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
diff --git a/include/ADT/AdtTypeRefType.h b/include/ADT/AdtTypeRefType.h
new file mode 100644 (file)
index 0000000..3fcdb9f
--- /dev/null
@@ -0,0 +1,31 @@
+#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
diff --git a/include/ADT/asn1/Asn1Boolean.h b/include/ADT/asn1/Asn1Boolean.h
new file mode 100644 (file)
index 0000000..d764376
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef ASN1BOOLEAN_H
+#define ASN1BOOLEAN_H
+
+class Asn1Boolean {
+  public:
+    //
+    Asn1Boolean() ;
+    //
+    Asn1Boolean(const Asn1Boolean &o) ;
+    //
+    ~Asn1Boolean() ;
+  protected:
+};
+#endif /*ASN1BOOLEAN_H*/
diff --git a/include/ADT/asn1/Asn1Choice.h b/include/ADT/asn1/Asn1Choice.h
new file mode 100644 (file)
index 0000000..7b92f37
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef ASN1CHOICE_H
+#define ASN1CHOICE_H
+
+
+class Asn1Choice {
+  public:
+    //
+    Asn1Choice() ;
+    //
+    Asn1Choice(const Asn1Choice &o) ;
+    //
+    ~Asn1Choice() ;
+  protected:
+};
+
+
+#endif /*ASN1CHOICE_H*/
diff --git a/include/ADT/asn1/Asn1Class.h b/include/ADT/asn1/Asn1Class.h
new file mode 100644 (file)
index 0000000..295ba5c
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef ASN1CLASS_H
+#define ASN1CLASS_H
+
+/**
+ * class Asn1Class
+ *
+ * \brief
+ * \author
+ */
+class Asn1Class {
+  public:
+    //
+    Asn1Class() ;
+    //
+    Asn1Class(const Asn1Class &o) ;
+    //
+    ~Asn1Class() ;
+  protected:
+};
+
+
+#endif /*ASN1CLASS_H*/
diff --git a/include/ADT/asn1/Asn1Constraint.h b/include/ADT/asn1/Asn1Constraint.h
new file mode 100644 (file)
index 0000000..418e11a
--- /dev/null
@@ -0,0 +1,22 @@
+#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*/
diff --git a/include/ADT/asn1/Asn1Context.h b/include/ADT/asn1/Asn1Context.h
new file mode 100644 (file)
index 0000000..1904c96
--- /dev/null
@@ -0,0 +1,26 @@
+#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*/
diff --git a/include/ADT/asn1/Asn1Decl.h b/include/ADT/asn1/Asn1Decl.h
new file mode 100644 (file)
index 0000000..070a625
--- /dev/null
@@ -0,0 +1,25 @@
+#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*/
diff --git a/include/ADT/asn1/Asn1Field.h b/include/ADT/asn1/Asn1Field.h
new file mode 100644 (file)
index 0000000..70b856b
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef ASN1FIELD_H
+#define ASN1FIELD_H
+
+/**
+ * class Asn1Field
+ *
+ * \brief
+ * \author
+ */
+class Asn1Field {
+  public:
+    //
+    Asn1Field() ;
+    //
+    Asn1Field(const Asn1Field &o) ;
+    //
+    ~Asn1Field() ;
+  protected:
+};
+
+
+#endif /*ASN1FIELD_H*/
diff --git a/include/ADT/asn1/Asn1Integer.h b/include/ADT/asn1/Asn1Integer.h
new file mode 100644 (file)
index 0000000..7ab6467
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef ASN1INTEGER_H
+#define ASN1INTEGER_H
+
+
+/**
+ * class Asn1Intger
+ *
+ * \brief
+ * \author
+ */
+class Asn1Integer {
+  public:
+    //
+    Asn1Integer() ;
+    //
+    Asn1Integer(const Asn1Integer &o) ;
+    //
+    ~Asn1Integer() ;
+  protected:
+};
+
+
+#endif /*ASN1INTEGER_H*/
diff --git a/include/ADT/asn1/Asn1Module.h b/include/ADT/asn1/Asn1Module.h
new file mode 100644 (file)
index 0000000..ee9413d
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef ASN1MODULE_H
+#define ASN1MODULE_H
+
+
+/**
+ * class Asn1Module
+ *
+ * \brief
+ * \author
+ */
+class Asn1Module {
+  public:
+    //
+    Asn1Module() ;
+    //
+    Asn1Module(const Asn1Module &o) ;
+    //
+    ~Asn1Module() ;
+  protected:
+};
+
+
+#endif /*ASN1MODULE_H*/
diff --git a/include/ADT/asn1/Asn1Object.h b/include/ADT/asn1/Asn1Object.h
new file mode 100644 (file)
index 0000000..4db0a5c
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef ASN1OBJECT_H
+#define ASN1OBJECT_H
+
+/**
+ * class Asn1Object
+ *
+ * \brief
+ * \author
+ */
+class Asn1Object {
+  public:
+    //
+    Asn1Object() ;
+    //
+    Asn1Object(const Asn1Object &o) ;
+    //
+    ~Asn1Object() ;
+  protected:
+};
+
+
+#endif /*ASN1OBJECT_H*/
diff --git a/include/ADT/asn1/Asn1ObjectSet.h b/include/ADT/asn1/Asn1ObjectSet.h
new file mode 100644 (file)
index 0000000..9626e40
--- /dev/null
@@ -0,0 +1,24 @@
+#ifndef ASN1OBJECTSET_H
+#define ASN1OBJECTSET_H
+
+
+/**
+ * class Asn1ObjectSet
+ *
+ * \brief
+ * \author
+ */
+class Asn1ObjectSet {
+  public:
+    //
+    Asn1ObjectSet() ;
+    //
+    Asn1ObjectSet(const Asn1ObjectSet &o) ;
+    //
+    ~Asn1ObjectSet() ;
+  protected:
+};
+
+
+
+#endif /*ASN1OBJECTSET_H*/
diff --git a/include/ADT/asn1/Asn1Oid.h b/include/ADT/asn1/Asn1Oid.h
new file mode 100644 (file)
index 0000000..b533aeb
--- /dev/null
@@ -0,0 +1,23 @@
+#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*/
diff --git a/include/ADT/asn1/Asn1Sequence.h b/include/ADT/asn1/Asn1Sequence.h
new file mode 100644 (file)
index 0000000..9d8aa23
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef ASN1SEQUENCE_H
+#define ASN1SEQUENCE_H
+
+
+/**
+ * class Asn1Sequence
+ *
+ * \brief
+ * \author
+ */
+class Asn1Sequence {
+  public:
+    //
+    Asn1Sequence() ;
+    //
+    Asn1Sequence(const Asn1Sequence &o) ;
+    //
+    ~Asn1Sequence() ;
+  protected:
+};
+
+
+#endif /*ASN1SEQUENCE_H*/
diff --git a/include/ADT/asn1/Asn1Set.h b/include/ADT/asn1/Asn1Set.h
new file mode 100644 (file)
index 0000000..dc9162f
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef ASN1SET_H
+#define ASN1SET_H
+
+/**
+ * class Asn1Set
+ *
+ * \brief
+ * \author
+ */
+class Asn1Set {
+  public:
+    //
+    Asn1Set() ;
+    //
+    Asn1Set(const Asn1Set &o) ;
+    //
+    ~Asn1Set() ;
+  protected:
+};
+
+
+
+#endif /*ASN1SET_H*/
diff --git a/include/ADT/asn1/Asn1Type.h b/include/ADT/asn1/Asn1Type.h
new file mode 100644 (file)
index 0000000..8ada6ad
--- /dev/null
@@ -0,0 +1,24 @@
+#ifndef ASN1TYPE_H
+#define ASN1TYPE_H
+
+
+/**
+ * class Asn1Type
+ *
+ * \brief
+ * \author
+ */
+class Asn1Type {
+  public:
+    //
+    Asn1Type() ;
+    //
+    Asn1Type(const Asn1Type &o) ;
+    //
+    ~Asn1Type() ;
+  protected:
+};
+
+
+
+#endif /*ASN1TYPE_H*/
diff --git a/include/ADT/asn1/type.h.def b/include/ADT/asn1/type.h.def
new file mode 100644 (file)
index 0000000..f99d882
--- /dev/null
@@ -0,0 +1,86 @@
+#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
diff --git a/include/ADT/gdmo/Gdmo.h b/include/ADT/gdmo/Gdmo.h
new file mode 100644 (file)
index 0000000..2924610
--- /dev/null
@@ -0,0 +1,400 @@
+#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*/
diff --git a/include/ADT/gdmo/Gdmo.h.inc b/include/ADT/gdmo/Gdmo.h.inc
new file mode 100644 (file)
index 0000000..d61707e
--- /dev/null
@@ -0,0 +1,108 @@
+#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
diff --git a/include/ADT/gdmo/GdmoTemplates.h b/include/ADT/gdmo/GdmoTemplates.h
new file mode 100644 (file)
index 0000000..749460c
--- /dev/null
@@ -0,0 +1,450 @@
+
+
+/**
+ * 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); 
+   }                                    
+};                                      
+
diff --git a/include/AST/ASTConsumer.h b/include/AST/ASTConsumer.h
new file mode 100644 (file)
index 0000000..3a65295
--- /dev/null
@@ -0,0 +1,20 @@
+#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
diff --git a/include/AST/ASTContext.h b/include/AST/ASTContext.h
new file mode 100644 (file)
index 0000000..93ef8e5
--- /dev/null
@@ -0,0 +1,64 @@
+#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*/
diff --git a/include/AST/ASTRecursiveVisitor.h b/include/AST/ASTRecursiveVisitor.h
new file mode 100644 (file)
index 0000000..25c48db
--- /dev/null
@@ -0,0 +1,354 @@
+#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
diff --git a/include/AST/BuiltinTypes.h.def b/include/AST/BuiltinTypes.h.def
new file mode 100644 (file)
index 0000000..c2803a3
--- /dev/null
@@ -0,0 +1,40 @@
+/**
+ * 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
+
diff --git a/include/AST/Context.h b/include/AST/Context.h
new file mode 100644 (file)
index 0000000..78c15b0
--- /dev/null
@@ -0,0 +1,53 @@
+#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
diff --git a/include/AST/Decl.h b/include/AST/Decl.h
new file mode 100644 (file)
index 0000000..0ed47d1
--- /dev/null
@@ -0,0 +1,62 @@
+#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
diff --git a/include/AST/Decl.h.inc b/include/AST/Decl.h.inc
new file mode 100644 (file)
index 0000000..f6d2686
--- /dev/null
@@ -0,0 +1,37 @@
+#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
diff --git a/include/AST/DeclAutomatonDecl.h b/include/AST/DeclAutomatonDecl.h
new file mode 100644 (file)
index 0000000..4e71b7c
--- /dev/null
@@ -0,0 +1,115 @@
+#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
diff --git a/include/AST/DeclBase.h b/include/AST/DeclBase.h
new file mode 100644 (file)
index 0000000..ae2a79f
--- /dev/null
@@ -0,0 +1,38 @@
+#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
diff --git a/include/AST/DeclBlockDecl.h b/include/AST/DeclBlockDecl.h
new file mode 100644 (file)
index 0000000..2a58a4e
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef BLOCKDECL_H__
+#define BLOCKDECL_H__
+
+
+class BlockDecl : public Decl {
+
+    public:
+        BlockDecl() {};
+        ~BlockDecl() {};
+};
+#endif
diff --git a/include/AST/DeclContext.h b/include/AST/DeclContext.h
new file mode 100644 (file)
index 0000000..c5f8e7a
--- /dev/null
@@ -0,0 +1,201 @@
+#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
diff --git a/include/AST/DeclEventDecl.h b/include/AST/DeclEventDecl.h
new file mode 100644 (file)
index 0000000..d8c7f1f
--- /dev/null
@@ -0,0 +1,40 @@
+#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 &parameters() 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
diff --git a/include/AST/DeclFieldDecl.h b/include/AST/DeclFieldDecl.h
new file mode 100644 (file)
index 0000000..f03823b
--- /dev/null
@@ -0,0 +1,27 @@
+#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
diff --git a/include/AST/DeclFunctionDecl.h b/include/AST/DeclFunctionDecl.h
new file mode 100644 (file)
index 0000000..a0d695d
--- /dev/null
@@ -0,0 +1,42 @@
+#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
diff --git a/include/AST/DeclLabelDecl.h b/include/AST/DeclLabelDecl.h
new file mode 100644 (file)
index 0000000..e819f0c
--- /dev/null
@@ -0,0 +1,21 @@
+#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
diff --git a/include/AST/DeclNamedDecl.h b/include/AST/DeclNamedDecl.h
new file mode 100644 (file)
index 0000000..7bc53ac
--- /dev/null
@@ -0,0 +1,121 @@
+#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
diff --git a/include/AST/DeclPackageUseDecl.h b/include/AST/DeclPackageUseDecl.h
new file mode 100644 (file)
index 0000000..5ef8e87
--- /dev/null
@@ -0,0 +1,24 @@
+#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
diff --git a/include/AST/DeclParmVarDecl.h b/include/AST/DeclParmVarDecl.h
new file mode 100644 (file)
index 0000000..eeb2fa2
--- /dev/null
@@ -0,0 +1,18 @@
+#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
diff --git a/include/AST/DeclRecordDecl.h b/include/AST/DeclRecordDecl.h
new file mode 100644 (file)
index 0000000..911fbe2
--- /dev/null
@@ -0,0 +1,54 @@
+#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*/
diff --git a/include/AST/DeclRefStateDecl.h b/include/AST/DeclRefStateDecl.h
new file mode 100644 (file)
index 0000000..0fe244b
--- /dev/null
@@ -0,0 +1,22 @@
+#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
diff --git a/include/AST/DeclStateDecl.h b/include/AST/DeclStateDecl.h
new file mode 100644 (file)
index 0000000..d5fc5c6
--- /dev/null
@@ -0,0 +1,22 @@
+#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
diff --git a/include/AST/DeclTransitionDecl.h b/include/AST/DeclTransitionDecl.h
new file mode 100644 (file)
index 0000000..8a0df84
--- /dev/null
@@ -0,0 +1,66 @@
+#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
diff --git a/include/AST/DeclTranslationUnitDecl.h b/include/AST/DeclTranslationUnitDecl.h
new file mode 100644 (file)
index 0000000..3cca9b4
--- /dev/null
@@ -0,0 +1,23 @@
+#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
diff --git a/include/AST/DeclTypeDecl.h b/include/AST/DeclTypeDecl.h
new file mode 100644 (file)
index 0000000..6d3d374
--- /dev/null
@@ -0,0 +1,181 @@
+#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
diff --git a/include/AST/DeclValueDecl.h b/include/AST/DeclValueDecl.h
new file mode 100644 (file)
index 0000000..8a2ffb4
--- /dev/null
@@ -0,0 +1,78 @@
+#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
diff --git a/include/AST/DeclVarDecl.h b/include/AST/DeclVarDecl.h
new file mode 100644 (file)
index 0000000..db5d67f
--- /dev/null
@@ -0,0 +1,40 @@
+#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
diff --git a/include/AST/Expr.h b/include/AST/Expr.h
new file mode 100644 (file)
index 0000000..bb47fe9
--- /dev/null
@@ -0,0 +1,223 @@
+#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
diff --git a/include/AST/ExprBinaryOperatorExpr.h b/include/AST/ExprBinaryOperatorExpr.h
new file mode 100644 (file)
index 0000000..6c1fa84
--- /dev/null
@@ -0,0 +1,54 @@
+#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
diff --git a/include/AST/ExprCallExpr.h b/include/AST/ExprCallExpr.h
new file mode 100644 (file)
index 0000000..5b40b6a
--- /dev/null
@@ -0,0 +1,53 @@
+#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
diff --git a/include/AST/ExprConditionalOperator.h b/include/AST/ExprConditionalOperator.h
new file mode 100644 (file)
index 0000000..403aac1
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef CONDITIONALOPERATOR_H__
+#define CONDITIONALOPERATOR_H__
+
+class ConditionalOperator : public Expr
+{
+};
+
+#endif
diff --git a/include/AST/ExprDeclRefExpr.h b/include/AST/ExprDeclRefExpr.h
new file mode 100644 (file)
index 0000000..2ebb267
--- /dev/null
@@ -0,0 +1,29 @@
+#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
diff --git a/include/AST/ExprFloatLiteral.h b/include/AST/ExprFloatLiteral.h
new file mode 100644 (file)
index 0000000..f1ee61e
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef FLOATLITERALEXPR_H__
+#define FLOATLITERALEXPR_H__
+
+class FloatLiteral : public Expr {
+};
+
+#endif
diff --git a/include/AST/ExprIntegerLiteral.h b/include/AST/ExprIntegerLiteral.h
new file mode 100644 (file)
index 0000000..6ac26ff
--- /dev/null
@@ -0,0 +1,20 @@
+#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
diff --git a/include/AST/ExprStringLiteral.h b/include/AST/ExprStringLiteral.h
new file mode 100644 (file)
index 0000000..f8dad6f
--- /dev/null
@@ -0,0 +1,23 @@
+#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
diff --git a/include/AST/ExprUnaryOperatorExpr.h b/include/AST/ExprUnaryOperatorExpr.h
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/include/AST/FormalContextParameter.h b/include/AST/FormalContextParameter.h
new file mode 100644 (file)
index 0000000..4035d2b
--- /dev/null
@@ -0,0 +1,62 @@
+#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
diff --git a/include/AST/OperationKinds.h b/include/AST/OperationKinds.h
new file mode 100644 (file)
index 0000000..7b88aa7
--- /dev/null
@@ -0,0 +1,30 @@
+#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
diff --git a/include/AST/Stmt.h b/include/AST/Stmt.h
new file mode 100644 (file)
index 0000000..1b5f142
--- /dev/null
@@ -0,0 +1,82 @@
+#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
diff --git a/include/AST/Stmt.h.inc b/include/AST/Stmt.h.inc
new file mode 100644 (file)
index 0000000..cd3a0ee
--- /dev/null
@@ -0,0 +1,40 @@
+#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
diff --git a/include/AST/StmtAsmStmt.h b/include/AST/StmtAsmStmt.h
new file mode 100644 (file)
index 0000000..5cae5dc
--- /dev/null
@@ -0,0 +1,64 @@
+#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
diff --git a/include/AST/StmtBreakStmt.h b/include/AST/StmtBreakStmt.h
new file mode 100644 (file)
index 0000000..e166223
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef BREAKSTMT_H__
+#define BREAKSTMT_H__
+
+/**
+ *
+ */
+class BreakStmt : public Stmt
+{
+    Stmt *m_Cond;
+    
+  public:
+    BreakStmt(DeclContext *DC,Expr *cond);
+
+    Expr *getCond();
+
+};
+
+#endif 
diff --git a/include/AST/StmtCompoundStmt.h b/include/AST/StmtCompoundStmt.h
new file mode 100644 (file)
index 0000000..6faab55
--- /dev/null
@@ -0,0 +1,31 @@
+#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
diff --git a/include/AST/StmtDeclStmt.h b/include/AST/StmtDeclStmt.h
new file mode 100644 (file)
index 0000000..676e750
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef DECLSTMT_H__
+#define DECLSTMT_H__
+
+class DeclStmt : public Stmt {
+    protected:
+
+    public:
+
+
+};
+
+#endif
diff --git a/include/AST/StmtForStmt.h b/include/AST/StmtForStmt.h
new file mode 100644 (file)
index 0000000..4e33291
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef FORSTMT_H__
+#define FORSTMT_H__
+
+class ForStmt : public  Stmt {
+};
+
+#endif
diff --git a/include/AST/StmtGotoStmt.h b/include/AST/StmtGotoStmt.h
new file mode 100644 (file)
index 0000000..96476f4
--- /dev/null
@@ -0,0 +1,15 @@
+#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
diff --git a/include/AST/StmtIfStmt.h b/include/AST/StmtIfStmt.h
new file mode 100644 (file)
index 0000000..2236640
--- /dev/null
@@ -0,0 +1,22 @@
+#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
diff --git a/include/AST/StmtIterator.h b/include/AST/StmtIterator.h
new file mode 100644 (file)
index 0000000..b2d5641
--- /dev/null
@@ -0,0 +1,149 @@
+#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
diff --git a/include/AST/StmtLabelStmt.h b/include/AST/StmtLabelStmt.h
new file mode 100644 (file)
index 0000000..d706378
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef LABELSTMT_H__
+#define LABELSTMT_H__
+
+
+class LabelStmt : public Stmt {
+};
+
+#endif
diff --git a/include/AST/StmtNullStmt.h b/include/AST/StmtNullStmt.h
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/include/AST/StmtOutputStmt.h b/include/AST/StmtOutputStmt.h
new file mode 100644 (file)
index 0000000..032cca6
--- /dev/null
@@ -0,0 +1,56 @@
+#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
diff --git a/include/AST/StmtReturnStmt.h b/include/AST/StmtReturnStmt.h
new file mode 100644 (file)
index 0000000..77c1281
--- /dev/null
@@ -0,0 +1,17 @@
+#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
diff --git a/include/AST/StmtSwitchCaseStmt.h b/include/AST/StmtSwitchCaseStmt.h
new file mode 100644 (file)
index 0000000..9288da5
--- /dev/null
@@ -0,0 +1,20 @@
+#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
diff --git a/include/AST/StmtSwitchStmt.h b/include/AST/StmtSwitchStmt.h
new file mode 100644 (file)
index 0000000..25d2706
--- /dev/null
@@ -0,0 +1,31 @@
+#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
diff --git a/include/AST/StmtVisitor.h b/include/AST/StmtVisitor.h
new file mode 100644 (file)
index 0000000..26408c2
--- /dev/null
@@ -0,0 +1,136 @@
+#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
diff --git a/include/AST/StmtWhileStmt.h b/include/AST/StmtWhileStmt.h
new file mode 100644 (file)
index 0000000..c5c3706
--- /dev/null
@@ -0,0 +1,16 @@
+#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
diff --git a/include/AST/TemplateBase.h b/include/AST/TemplateBase.h
new file mode 100644 (file)
index 0000000..d5fd064
--- /dev/null
@@ -0,0 +1,74 @@
+#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
diff --git a/include/AST/Type.h b/include/AST/Type.h
new file mode 100644 (file)
index 0000000..b5e80b1
--- /dev/null
@@ -0,0 +1,216 @@
+#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*/
diff --git a/include/AST/Types.h.inc b/include/AST/Types.h.inc
new file mode 100644 (file)
index 0000000..e814de0
--- /dev/null
@@ -0,0 +1,37 @@
+#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
diff --git a/include/CodeGen/ASTMuliplexConsumer.h b/include/CodeGen/ASTMuliplexConsumer.h
new file mode 100644 (file)
index 0000000..695be75
--- /dev/null
@@ -0,0 +1,17 @@
+#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
diff --git a/include/CodeGen/CGDebug.h b/include/CodeGen/CGDebug.h
new file mode 100644 (file)
index 0000000..a9c7c62
--- /dev/null
@@ -0,0 +1,33 @@
+#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
diff --git a/include/CodeGen/CMConsumer.h b/include/CodeGen/CMConsumer.h
new file mode 100644 (file)
index 0000000..4ff4ba5
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef CM_CONSUMER_H__
+#define CM_CONSUMER_H__
+
+class CMConsumer : public ASTConsumer 
+{
+  public:
+    CMConsumer:
+  protected:
+    // should own a RecursiveVisitor
+}
+#endif
diff --git a/include/CodeGen/CodeGenFunction.h b/include/CodeGen/CodeGenFunction.h
new file mode 100644 (file)
index 0000000..5b246fe
--- /dev/null
@@ -0,0 +1,104 @@
+#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
diff --git a/include/CodeGen/CodeGenModule.h b/include/CodeGen/CodeGenModule.h
new file mode 100644 (file)
index 0000000..f0fc896
--- /dev/null
@@ -0,0 +1,72 @@
+#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
diff --git a/include/CodeGen/CodeGenType.h b/include/CodeGen/CodeGenType.h
new file mode 100644 (file)
index 0000000..e4df026
--- /dev/null
@@ -0,0 +1,45 @@
+#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*/
diff --git a/include/CodeGen/ModuleBuilder.h b/include/CodeGen/ModuleBuilder.h
new file mode 100644 (file)
index 0000000..58e4e72
--- /dev/null
@@ -0,0 +1,22 @@
+#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
diff --git a/include/IR/Argument.h b/include/IR/Argument.h
new file mode 100644 (file)
index 0000000..304cc3a
--- /dev/null
@@ -0,0 +1,66 @@
+#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:
+ */
diff --git a/include/IR/BasicBlock.h b/include/IR/BasicBlock.h
new file mode 100644 (file)
index 0000000..f01d197
--- /dev/null
@@ -0,0 +1,106 @@
+#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
diff --git a/include/IR/Behavior.h b/include/IR/Behavior.h
new file mode 100644 (file)
index 0000000..d5190b1
--- /dev/null
@@ -0,0 +1,68 @@
+#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
diff --git a/include/IR/Constant.h b/include/IR/Constant.h
new file mode 100644 (file)
index 0000000..d3bd301
--- /dev/null
@@ -0,0 +1,35 @@
+#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*/
diff --git a/include/IR/Function.h b/include/IR/Function.h
new file mode 100644 (file)
index 0000000..256eb6a
--- /dev/null
@@ -0,0 +1,103 @@
+#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:
+ */
diff --git a/include/IR/GlobalVariable.h b/include/IR/GlobalVariable.h
new file mode 100644 (file)
index 0000000..81a99d2
--- /dev/null
@@ -0,0 +1,82 @@
+#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
diff --git a/include/IR/IRBuilderAdaptor.h b/include/IR/IRBuilderAdaptor.h
new file mode 100644 (file)
index 0000000..742967b
--- /dev/null
@@ -0,0 +1,33 @@
+#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
diff --git a/include/IR/LdsBuilder.h b/include/IR/LdsBuilder.h
new file mode 100644 (file)
index 0000000..327d089
--- /dev/null
@@ -0,0 +1,200 @@
+#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
diff --git a/include/IR/LdsInstrVisitor.h b/include/IR/LdsInstrVisitor.h
new file mode 100644 (file)
index 0000000..afb7d7e
--- /dev/null
@@ -0,0 +1,138 @@
+#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
diff --git a/include/IR/LdsInstruction.h b/include/IR/LdsInstruction.h
new file mode 100644 (file)
index 0000000..fe79f5e
--- /dev/null
@@ -0,0 +1,734 @@
+#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
diff --git a/include/IR/Module.h b/include/IR/Module.h
new file mode 100644 (file)
index 0000000..901b70f
--- /dev/null
@@ -0,0 +1,114 @@
+#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:
+ */
diff --git a/include/IR/OperandTraits.h b/include/IR/OperandTraits.h
new file mode 100644 (file)
index 0000000..16096be
--- /dev/null
@@ -0,0 +1,53 @@
+#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
diff --git a/include/IR/Signal.h b/include/IR/Signal.h
new file mode 100644 (file)
index 0000000..9d44d93
--- /dev/null
@@ -0,0 +1,91 @@
+#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
diff --git a/include/IR/State.h b/include/IR/State.h
new file mode 100644 (file)
index 0000000..762b8b2
--- /dev/null
@@ -0,0 +1,68 @@
+#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
diff --git a/include/IR/SymbolTableTraits.h b/include/IR/SymbolTableTraits.h
new file mode 100644 (file)
index 0000000..39e1daa
--- /dev/null
@@ -0,0 +1,133 @@
+#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
diff --git a/include/IR/SymbolTableTraitsImpl.h b/include/IR/SymbolTableTraitsImpl.h
new file mode 100644 (file)
index 0000000..a0c0fd9
--- /dev/null
@@ -0,0 +1,81 @@
+#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
diff --git a/include/IR/Transition.h b/include/IR/Transition.h
new file mode 100644 (file)
index 0000000..4683df6
--- /dev/null
@@ -0,0 +1,167 @@
+#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:
+ */
diff --git a/include/IR/Type.h b/include/IR/Type.h
new file mode 100644 (file)
index 0000000..2aa746b
--- /dev/null
@@ -0,0 +1,106 @@
+#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*/
diff --git a/include/IR/Use.h b/include/IR/Use.h
new file mode 100644 (file)
index 0000000..3bfd204
--- /dev/null
@@ -0,0 +1,84 @@
+#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
diff --git a/include/IR/User.h b/include/IR/User.h
new file mode 100644 (file)
index 0000000..f37d535
--- /dev/null
@@ -0,0 +1,112 @@
+#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
diff --git a/include/IR/Value.h b/include/IR/Value.h
new file mode 100644 (file)
index 0000000..440e0ec
--- /dev/null
@@ -0,0 +1,119 @@
+#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*/
diff --git a/include/IR/ldsOpcode.h b/include/IR/ldsOpcode.h
new file mode 100644 (file)
index 0000000..c82eed2
--- /dev/null
@@ -0,0 +1,57 @@
+#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
diff --git a/include/LDSBytecode/AutomatonBytecode.h b/include/LDSBytecode/AutomatonBytecode.h
new file mode 100644 (file)
index 0000000..32707cc
--- /dev/null
@@ -0,0 +1,37 @@
+#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*/
diff --git a/include/LDSBytecode/BytecodeReader.h b/include/LDSBytecode/BytecodeReader.h
new file mode 100644 (file)
index 0000000..de6cf1b
--- /dev/null
@@ -0,0 +1,18 @@
+#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*/
diff --git a/include/LDSBytecode/BytecodeWriter.h b/include/LDSBytecode/BytecodeWriter.h
new file mode 100644 (file)
index 0000000..84420dc
--- /dev/null
@@ -0,0 +1,23 @@
+#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*/
diff --git a/include/LDSExecutionEngine/LdsExecutionContext.h b/include/LDSExecutionEngine/LdsExecutionContext.h
new file mode 100644 (file)
index 0000000..4fd983f
--- /dev/null
@@ -0,0 +1,112 @@
+#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*/
diff --git a/include/LDSExecutionEngine/LdsExecutionEngine.h b/include/LDSExecutionEngine/LdsExecutionEngine.h
new file mode 100644 (file)
index 0000000..4f9c109
--- /dev/null
@@ -0,0 +1,40 @@
+#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*/
diff --git a/include/LDSExecutionEngine/LdsObject.h b/include/LDSExecutionEngine/LdsObject.h
new file mode 100644 (file)
index 0000000..08a1edc
--- /dev/null
@@ -0,0 +1,77 @@
+#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*/