Merge pull request #102 from hzeller/modernize-value

Code-clean: Modernize class Value and its implementations.
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c1944ac..8298559 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -123,7 +123,6 @@
   ${PROJECT_SOURCE_DIR}/src/parser/SV3_1aSplitterParser.cpp
   ${PROJECT_SOURCE_DIR}/src/parser/SV3_1aSplitterParserListener.cpp
   ${PROJECT_SOURCE_DIR}/src/SourceCompile/VObjectTypes.cpp
-  ${PROJECT_SOURCE_DIR}/src/*.cpp
   ${PROJECT_SOURCE_DIR}/src/API/*.cpp
   ${PROJECT_SOURCE_DIR}/src/Design/*.cpp
   ${PROJECT_SOURCE_DIR}/src/Library/*.cpp
@@ -155,25 +154,55 @@
   ${PROJECT_SOURCE_DIR}/src/Package/*.cpp
   )
 
-add_executable(surelog ${surelog_SRC})
+set (SURELOG_PUBLIC_HEADERS
+  ${PROJECT_SOURCE_DIR}/src/surelog.h
+) 
+  
 
+add_library(surelog STATIC ${surelog_SRC})
+set_target_properties(surelog PROPERTIES PUBLIC_HEADER "${SURELOG_PUBLIC_HEADERS}")
+
+add_executable(surelog-bin ${PROJECT_SOURCE_DIR}/src/main.cpp
+)
+set_target_properties(surelog-bin
+  PROPERTIES OUTPUT_NAME surelog
+)
+
+add_executable(hellosureworld ${PROJECT_SOURCE_DIR}/src/hellosureworld.cpp)
+
+add_dependencies(surelog-bin surelog)
 add_dependencies(surelog flatc)
 add_dependencies(surelog antlr4_static)
 add_dependencies(surelog flatbuffers)
 add_dependencies(surelog GenerateParser)
 add_dependencies(surelog GenerateSerializer)
 
+set (ALL_LIBRARIES_FOR_SURELOG
+  surelog
+  ${PYTHON_LIBRARIES}
+  -L${PROJECT_SOURCE_DIR}/dist/ libantlr4-runtime.a
+  -L${PROJECT_SOURCE_DIR}/build/third_party/flatbuffers libflatbuffers.a
+  dl util m rt pthread tcmalloc
+)
+
 # Linkage instructions
 target_link_libraries(
-  surelog ${PYTHON_LIBRARIES}
+  surelog-bin ${ALL_LIBRARIES_FOR_SURELOG} 
 )
+
+add_dependencies(hellosureworld surelog)
+add_dependencies(hellosureworld flatc)
+add_dependencies(hellosureworld antlr4_static)
+add_dependencies(hellosureworld flatbuffers)
+add_dependencies(hellosureworld GenerateParser)
+add_dependencies(hellosureworld GenerateSerializer)
 target_link_libraries(
-  surelog -L${PROJECT_SOURCE_DIR}/dist/ libantlr4-runtime.a -L${PROJECT_SOURCE_DIR}/build/third_party/flatbuffers libflatbuffers.a dl util m rt pthread tcmalloc
+  hellosureworld ${ALL_LIBRARIES_FOR_SURELOG} 
 )
 
 # Creation of the distribution directory,
 # Precompiled package creation
-add_custom_command(TARGET surelog POST_BUILD
+add_custom_command(TARGET surelog-bin POST_BUILD
   COMMAND echo "       Creating staging for precompiled packages"
   COMMAND mkdir -p ${CMAKE_BINARY_DIR}/dist/${CMAKE_BUILD_TYPE}/sv
   COMMAND mkdir -p ${CMAKE_BINARY_DIR}/dist/${CMAKE_BUILD_TYPE}/python
@@ -197,8 +226,13 @@
 
 # Installation target
 INSTALL(
-  TARGETS surelog
+  TARGETS surelog-bin
   RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+  )
+INSTALL(
+  TARGETS surelog
+  ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}/surelog
+  PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/surelog
 )
 INSTALL(
   DIRECTORY   ${CMAKE_BINARY_DIR}/dist/${CMAKE_BUILD_TYPE}/python
@@ -206,3 +240,98 @@
               ${CMAKE_BINARY_DIR}/dist/${CMAKE_BUILD_TYPE}/pkg
   DESTINATION ${CMAKE_INSTALL_LIBDIR}/surelog
 )
+INSTALL(
+  FILES  ${PROJECT_SOURCE_DIR}/src/CommandLine/CommandLineParser.h
+  DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/surelog/CommandLine
+)
+INSTALL(
+  FILES  
+  ${PROJECT_SOURCE_DIR}/src/SourceCompile/SymbolTable.h
+  ${PROJECT_SOURCE_DIR}/src/SourceCompile/CompilationUnit.h
+  ${PROJECT_SOURCE_DIR}/src/SourceCompile/PreprocessFile.h
+  ${PROJECT_SOURCE_DIR}/src/SourceCompile/CompileSourceFile.h
+  ${PROJECT_SOURCE_DIR}/src/SourceCompile/Compiler.h
+  DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/surelog/SourceCompile
+  )
+INSTALL(
+  FILES
+  ${PROJECT_SOURCE_DIR}/src/ErrorReporting/ErrorContainer.h
+  ${PROJECT_SOURCE_DIR}/src/ErrorReporting/Report.h
+  ${PROJECT_SOURCE_DIR}/src/ErrorReporting/Waiver.h
+  DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/surelog/ErrorReporting
+  )
+INSTALL(
+  FILES
+  ${PROJECT_SOURCE_DIR}/src/API/PythonAPI.h
+  ${PROJECT_SOURCE_DIR}/src/API/SLAPI.h
+  DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/surelog/API
+  )
+INSTALL(
+  FILES
+  ${PROJECT_SOURCE_DIR}/src/Common/ClockingBlockHolder.h
+  DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/surelog/Common
+  )
+INSTALL(
+  FILES
+  ${PROJECT_SOURCE_DIR}/src/Design/ClockingBlock.h
+  ${PROJECT_SOURCE_DIR}/src/Design/Design.h
+  ${PROJECT_SOURCE_DIR}/src/Design/Instance.h
+  ${PROJECT_SOURCE_DIR}/src/Design/Signal.h
+  ${PROJECT_SOURCE_DIR}/src/Design/ValuedComponentI.h
+  ${PROJECT_SOURCE_DIR}/src/Design/DataType.h
+  ${PROJECT_SOURCE_DIR}/src/Design/Enum.h
+  ${PROJECT_SOURCE_DIR}/src/Design/ModuleDefinition.h
+  ${PROJECT_SOURCE_DIR}/src/Design/Statement.h
+  ${PROJECT_SOURCE_DIR}/src/Design/VObject.h
+  ${PROJECT_SOURCE_DIR}/src/Design/DefParam.h
+  ${PROJECT_SOURCE_DIR}/src/Design/FileCNodeId.h
+  ${PROJECT_SOURCE_DIR}/src/Design/ModuleInstance.h
+  ${PROJECT_SOURCE_DIR}/src/Design/Task.h
+  ${PROJECT_SOURCE_DIR}/src/Design/DesignComponent.h
+  ${PROJECT_SOURCE_DIR}/src/Design/FileContent.h
+  ${PROJECT_SOURCE_DIR}/src/Design/Parameter.h
+  ${PROJECT_SOURCE_DIR}/src/Design/TfPortItem.h
+  ${PROJECT_SOURCE_DIR}/src/Design/DesignElement.h
+  ${PROJECT_SOURCE_DIR}/src/Design/Function.h
+  ${PROJECT_SOURCE_DIR}/src/Design/Scope.h
+  ${PROJECT_SOURCE_DIR}/src/Design/TimeInfo.h
+  DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/surelog/Design
+  )
+INSTALL(
+  FILES
+  ${PROJECT_SOURCE_DIR}/src/Testbench/ClassDefinition.h
+  ${PROJECT_SOURCE_DIR}/src/Testbench/CoverGroupDefinition.h
+  ${PROJECT_SOURCE_DIR}/src/Testbench/Property.h
+  ${PROJECT_SOURCE_DIR}/src/Testbench/Variable.h
+  ${PROJECT_SOURCE_DIR}/src/Testbench/ClassObject.h
+  ${PROJECT_SOURCE_DIR}/src/Testbench/FunctionMethod.h
+  ${PROJECT_SOURCE_DIR}/src/Testbench/TaskMethod.h
+  ${PROJECT_SOURCE_DIR}/src/Testbench/Constraint.h
+  ${PROJECT_SOURCE_DIR}/src/Testbench/Program.h
+  ${PROJECT_SOURCE_DIR}/src/Testbench/TypeDef.h
+  DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/surelog/Testbench
+  )
+INSTALL(
+  FILES
+  ${PROJECT_SOURCE_DIR}/src/Package/Package.h
+  DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/surelog/Package
+)
+INSTALL(
+  FILES
+  ${PROJECT_SOURCE_DIR}/src/Library/Library.h
+  ${PROJECT_SOURCE_DIR}/src/Library/LibrarySet.h
+  DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/surelog/Library
+  )
+INSTALL(
+  FILES
+  ${PROJECT_SOURCE_DIR}/src/Config/Config.h
+  ${PROJECT_SOURCE_DIR}/src/Config/ConfigSet.h
+  DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/surelog/Config
+  )
+INSTALL(
+  FILES
+  ${PROJECT_SOURCE_DIR}/src/Expression/ExprBuilder.h
+  ${PROJECT_SOURCE_DIR}/src/Expression/Expr.h
+  ${PROJECT_SOURCE_DIR}/src/Expression/Value.h
+  DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/surelog/Expression
+  )
diff --git a/Makefile b/Makefile
index 2c32c9e..d223a0f 100644
--- a/Makefile
+++ b/Makefile
@@ -5,6 +5,13 @@
 	cd build; cmake ../ -DCMAKE_BUILD_TYPE=Release
 	$(MAKE) -C build
 	cd build; ../tests/regression.tcl mt=0 show_diff
+debug:
+	mkdir -p dbuild/tests;
+	mkdir -p dbuild/dist;
+	mkdir -p dist;
+	cd dbuild; cmake ../ -DCMAKE_BUILD_TYPE=Debug
+	$(MAKE) -C dbuild
+
 
 test:
 	mkdir -p build/tests;
diff --git a/src/API/PythonAPI.cpp b/src/API/PythonAPI.cpp
index 8896ffe..300ab52 100644
--- a/src/API/PythonAPI.cpp
+++ b/src/API/PythonAPI.cpp
@@ -201,7 +201,10 @@
           }
       }
   }
-  Py_SetProgramName(L"surelog"); /* optional but recommended */
+  // Before Python 3.7, the parameter to SetProgramName() was not a
+  // const wchar_t* but a wchar_t (even though never written to).
+  static wchar_t progname[] = L"surelog";
+  Py_SetProgramName(progname);
 
   PyImport_AppendInittab("slapi", &PyInit_slapi);
 
diff --git a/src/CommandLine/CommandLineParser.h b/src/CommandLine/CommandLineParser.h
index cec2ed5..6253976 100644
--- a/src/CommandLine/CommandLineParser.h
+++ b/src/CommandLine/CommandLineParser.h
@@ -104,7 +104,7 @@
   bool elaborate() { return m_elaborate; }
   bool pythonListener() { return m_pythonListener && m_pythonAllowed; }
   bool pythonAllowed() { return m_pythonAllowed; }
-
+  void noPython() { m_pythonAllowed = false; }
   bool pythonEvalScriptPerFile() {
     return m_pythonEvalScriptPerFile && m_pythonAllowed;
   }
diff --git a/src/README.md b/src/README.md
index 5ce0a60..83d1a71 100644
--- a/src/README.md
+++ b/src/README.md
@@ -12,15 +12,16 @@
  * cd Surelog
 ```bash
 make
-```
-```bash
 make install (/usr/local/bin and /usr/local/lib/surelog by default, use DESTDIR= for alternative locations)
 ```
 
 ### Run a test
 
 * dist/Release/surelog -help
-* dist/Release/surelog -writepp -parse tests/UnitTest/top.v
+
+* dist/Release/surelog -writepp -parse ../tests/UnitElabBlock/top.v
+
+* dist/Release/hellosureworld ../tests/UnitElabBlock/top.v -parse -mutestdout
 
 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 ## Modus operanti for grammar development:
diff --git a/src/SourceCompile/Compiler.cpp b/src/SourceCompile/Compiler.cpp
index f965a4c..9a5d4de 100644
--- a/src/SourceCompile/Compiler.cpp
+++ b/src/SourceCompile/Compiler.cpp
@@ -47,6 +47,8 @@
 #include <mutex>
 #include <thread>
 #include <vector>
+#include <iostream>
+#include <fstream>
 using namespace SURELOG;
 
 Compiler::Compiler(CommandLineParser* commandLineParser, ErrorContainer* errors,
@@ -229,12 +231,38 @@
   return true;
 }
 
+bool Compiler::createFileList_()
+{
+  if (m_commandLineParser->writePpOutput() ||
+          (m_commandLineParser->writePpOutputFileId() != 0)) {
+    SymbolTable* symbolTable = getSymbolTable();
+    const std::string& directory =
+            symbolTable->getSymbol(m_commandLineParser->getFullCompileDir());
+    std::ofstream ofs;
+    std::string fileList = directory + "/file.lst";
+    ofs.open(fileList);
+    if (ofs.good()) {
+      unsigned int size = m_compilers.size();
+      for (unsigned int i = 0; i < size; i++) {
+        std::string fileName = m_compilers[i]->getSymbolTable()->getSymbol(
+                m_compilers[i]->getPpOutputFileId());
+        fileName = StringUtils::replaceAll(fileName, "//", "/");
+        ofs << fileName << std::flush << std::endl;
+      }
+      ofs.close();
+    } else {
+      std::cout << "Could not create filelist: " << fileList << std::endl;
+    }
+  }
+}
+ 
+
 bool Compiler::parseinit_() {
   Precompiled* prec = Precompiled::getSingleton();
   // Single out the large files.
   // Small files are going to be scheduled in multiple threads based on size.
   // Large files are going to be compiled in a different batch in multithread
-
+  
   if (!m_commandLineParser->fileunit()) {
     unsigned int size = m_symbolTables.size();
     for (unsigned int i = 0; i < size; i++) {
@@ -564,7 +592,7 @@
     profile += msg;
     tmr.reset();
   }
-
+  createFileList_();
   // Parse
   bool parserInitialized = false;
   if (m_commandLineParser->parse() || m_commandLineParser->pythonListener() ||
diff --git a/src/SourceCompile/Compiler.h b/src/SourceCompile/Compiler.h
index 80c182b..3e3cbd8 100644
--- a/src/SourceCompile/Compiler.h
+++ b/src/SourceCompile/Compiler.h
@@ -74,6 +74,7 @@
   bool parseLibrariesDef_();
 
   bool ppinit_();
+  bool createFileList_();
   bool parseinit_();
   bool pythoninit_();
   bool compileFileSet_(CompileSourceFile::Action action, bool allowMultithread,
diff --git a/src/hellosureworld.cpp b/src/hellosureworld.cpp
new file mode 100644
index 0000000..62b8403
--- /dev/null
+++ b/src/hellosureworld.cpp
@@ -0,0 +1,69 @@
+/*
+ Copyright 2019 Alain Dargelas
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+/*
+ * File:   hellosureworld.cpp
+ * Author: alain
+ *
+ * Created on November 20, 2019, 08:07 PM
+ */
+
+// Example of usage:
+// cd tests/UnitElabBlock
+// hellosureworld top.v -parse -mutestdout
+
+#include "surelog.h"
+
+int main(int argc, const char** argv) {
+  // Read command line, compile a design, use -parse argument
+  unsigned int code = 0;
+  SURELOG::SymbolTable* symbolTable = new SURELOG::SymbolTable();
+  SURELOG::ErrorContainer* errors = new SURELOG::ErrorContainer(symbolTable);
+  SURELOG::CommandLineParser* clp =
+      new SURELOG::CommandLineParser(errors, symbolTable, false, false);
+  clp->noPython();
+  bool success = clp->parseCommandLine(argc, argv);
+  errors->printMessages(clp->muteStdout());
+  SURELOG::Design* design = NULL;
+  if (success && (!clp->help())) {
+    SURELOG::Compiler* compiler =
+        new SURELOG::Compiler(clp, errors, symbolTable);
+    success = compiler->compile();
+    design = compiler->getDesign();
+    delete compiler;
+    auto stats = errors->getErrorStats();
+    code = (!success) | stats.nbFatal | stats.nbSyntax | stats.nbError;
+  }
+  delete clp;
+  delete symbolTable;
+  delete errors;
+
+  // Browse the Data Model
+  if (design) {
+    for (auto& top : design->getTopLevelModuleInstances()) {
+      std::function<void(SURELOG::ModuleInstance*)> inst_visit =
+          [&inst_visit](SURELOG::ModuleInstance* inst) {
+            std::cout << "Inst: " << inst->getFullPathName() << std::endl;
+            for (auto i = 0; i < inst->getNbChildren(); i++) {
+              inst_visit(inst->getChildren(i));
+            }
+          };
+      inst_visit(top);
+    }
+  }
+  delete design;
+  return code;
+}
diff --git a/src/surelog.h b/src/surelog.h
new file mode 100644
index 0000000..bcf78d4
--- /dev/null
+++ b/src/surelog.h
@@ -0,0 +1,85 @@
+/*
+ Copyright 2019 Alain Dargelas
+ 
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ 
+ http://www.apache.org/licenses/LICENSE-2.0
+ 
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+// Header file for Surelog library
+
+// Compilation control classes
+#include "CommandLine/CommandLineParser.h"
+#include "SourceCompile/SymbolTable.h"
+#include "SourceCompile/CompilationUnit.h"
+#include "SourceCompile/PreprocessFile.h"
+#include "SourceCompile/CompileSourceFile.h"
+#include "SourceCompile/Compiler.h"
+#include "ErrorReporting/ErrorContainer.h"
+#include "ErrorReporting/Report.h"
+#include "ErrorReporting/Waiver.h"
+
+// Antlr headers
+#include "antlr4-runtime.h"
+using namespace antlr4;
+
+// Python API (optional - needed to be enabled early in the main with PythonAPI::init if needed)
+#include "API/PythonAPI.h"
+
+// Full C++ DataModel API
+#include "Common/ClockingBlockHolder.h"
+#include "Design/ClockingBlock.h"
+#include "Design/Design.h"
+#include "Design/Instance.h"
+#include "Design/Signal.h"
+#include "Design/ValuedComponentI.h"
+#include "Design/DataType.h"
+#include "Design/Enum.h"
+#include "Design/ModuleDefinition.h"
+#include "Design/Statement.h"
+#include "Design/VObject.h"
+#include "Design/DefParam.h"
+#include "Design/FileCNodeId.h"
+#include "Design/ModuleInstance.h"
+#include "Design/Task.h"
+#include "Design/DesignComponent.h"
+#include "Design/FileContent.h"
+#include "Design/Parameter.h"
+#include "Design/TfPortItem.h"
+#include "Design/DesignElement.h"
+#include "Design/Function.h"
+#include "Design/Scope.h"
+#include "Design/TimeInfo.h"
+#include "Testbench/ClassDefinition.h"
+#include "Testbench/CoverGroupDefinition.h"
+#include "Testbench/Property.h"
+#include "Testbench/Variable.h"
+#include "Testbench/ClassObject.h"
+#include "Testbench/FunctionMethod.h"
+#include "Testbench/TaskMethod.h"
+#include "Testbench/Constraint.h"
+#include "Testbench/Program.h"
+#include "Testbench/TypeDef.h"
+#include "Package/Package.h"
+#include "Library/Library.h"
+#include "Library/LibrarySet.h"
+#include "Config/Config.h"
+#include "Config/ConfigSet.h"
+#include "Expression/ExprBuilder.h"
+#include "Expression/Expr.h"
+#include "Expression/Value.h"
+
+// Limited C-like API
+#include "API/SLAPI.h"
+
+
+
+
diff --git a/tests/UnitLibrary/UnitLibrary.sl b/tests/UnitLibrary/UnitLibrary.sl
index 06f921e..bea6c27 100644
--- a/tests/UnitLibrary/UnitLibrary.sl
+++ b/tests/UnitLibrary/UnitLibrary.sl
@@ -1 +1 @@
-  -map lib.map  -cfgfile  configs.cfg -cfg top -cfg bad -writepp -parse -verbose -d lib  -d inst  +incdir+../../../UVM/ovm-2.1.2/src/  +incdir+../../../UVM/vmm-1.1.1a/sv  -mt max -fileunit
+ -map lib.map -cfgfile configs.cfg -cfg top -cfg bad -parse -verbose -d lib  -d inst -mt 0 -fileunit