/*
 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:   CompileClass.cpp
 * Author: alain
 * 
 * Created on June 7, 2018, 10:26 PM
 */
#include "../SourceCompile/VObjectTypes.h"
#include "../Design/VObject.h"
#include "../Library/Library.h"
#include "../Design/Signal.h"
#include "../Design/FileContent.h"
#include "../Design/ClockingBlock.h"
#include "../SourceCompile/SymbolTable.h"
#include "../ErrorReporting/Error.h"
#include "../ErrorReporting/Location.h"
#include "../ErrorReporting/Error.h"
#include "../CommandLine/CommandLineParser.hpp"
#include "../ErrorReporting/ErrorDefinition.h"
#include "../ErrorReporting/ErrorContainer.h"
#include "../SourceCompile/CompilationUnit.h"
#include "../SourceCompile/PreprocessFile.h"
#include "../SourceCompile/CompileSourceFile.h"
#include "../SourceCompile/ParseFile.h"
#include "../SourceCompile/Compiler.h"
#include "../DesignCompile/CompileDesign.h"
#include "../Testbench/ClassDefinition.h"
#include "CompileClass.h"

using namespace SURELOG;


CompileClass::~CompileClass () { }


int FunctorCompileClass::operator()() const {
    CompileClass* instance = new CompileClass(m_compileDesign, m_class, m_design, m_symbols, m_errors);
    instance->compile();
    delete instance;   
    return true;
}


bool CompileClass::compile() {
  
  FileContent* fC = m_class->m_fileContents[0];
  NodeId nodeId = m_class->m_nodeIds[0];
  Location loc (m_symbols->registerSymbol (fC->getFileName(nodeId)), fC->Line (nodeId), 0, m_symbols->registerSymbol (m_class->getName ()));
  
  Error err1 (ErrorDefinition::COMP_COMPILE_CLASS, loc);
  ErrorContainer* errors = new ErrorContainer (m_symbols);
  errors->regiterCmdLine (m_compileDesign->getCompiler ()->getCommandLineParser ());
  errors->addError (err1);
  errors->printMessage (err1, m_compileDesign->getCompiler ()->getCommandLineParser ()->muteStdout ());
  delete errors;
   if (fC->getSize () == 0)
    return true;
  
  // Package imports 
  std::vector<FileCNodeId> pack_imports;
  // - Local file imports
  for (auto import : fC->getObjects (VObjectType::slPackage_import_item))
    {
      pack_imports.push_back(import);
    }
  // - Parent container imports
  DesignComponent* container = m_class->getContainer ();
  if (container)
    {
      //FileCNodeId itself(container->getFileContents ()[0], container->getNodeIds ()[0]);
      //pack_imports.push_back(itself);
      for (auto import : container->getObjects (VObjectType::slPackage_import_item))
      {
        pack_imports.push_back(import);
      } 
    }

  for (auto pack_import : pack_imports)
    {
      FileContent* pack_fC = pack_import.fC;
      NodeId pack_id = pack_import.nodeId;
      m_helper.importPackage (m_class, m_design, pack_fC, pack_id);
    }

  compile_class_parameters_(fC, nodeId);

  // This
  DataType* thisdt = new DataType(fC, nodeId, "this", VObjectType::slClass_declaration);
  thisdt->setDefinition (m_class);
  Property* prop = new Property (thisdt, fC, nodeId, 0, "this", false, false,
                                 false, false, false);
  m_class->insertProperty (prop);
  
  VObject current = fC->Object (fC->getSize () - 2);
  NodeId id = nodeId;
  if (!id)
    return false;
  std::stack<NodeId> stack;
  stack.push (id);
  bool inFunction_body_declaration = false;
  bool inTask_body_declaration = false;
  while (stack.size ())
    {
      bool skipGuts = false;
      id = stack.top ();
      stack.pop ();
      current = fC->Object (id);
      VObjectType type = fC->Type (id);
      switch (type)
        {
        case VObjectType::slPackage_import_item:
          {
            m_helper.importPackage (m_class, m_design, fC, id);
            break;
          }
        case VObjectType::slClass_constructor_declaration:
        {
          inFunction_body_declaration = true;
          break;
        }
        case VObjectType::slFunction_body_declaration:
        {
          inFunction_body_declaration = true;
          break;
        }
        case VObjectType::slEndfunction:
        {
          inFunction_body_declaration = false;
          break;
        }
        case VObjectType::slTask_body_declaration:
        {
          inTask_body_declaration = true;
          break;
        }
        case VObjectType::slEndtask:
        {
          inTask_body_declaration = false;
          break;
        }
        case VObjectType::slClass_property:
          if (inFunction_body_declaration || inTask_body_declaration)
             break;
          compile_class_property_(fC, id);
          break;
        case VObjectType::slClass_constraint:
          compile_class_constraint_(fC, id);
          break;
        case VObjectType::slClass_declaration:
          if (id != nodeId)
            {
              compile_class_declaration_(fC, id);
              if (current.m_sibling)
                stack.push (current.m_sibling); 
              continue;
            }
          break; 
        case VObjectType::slCovergroup_declaration:
          compile_covergroup_declaration_(fC, id);
          break;
        case VObjectType::slLocal_parameter_declaration:
          compile_local_parameter_declaration_(fC, id);
          break;  
        case VObjectType::slParameter_declaration:
          compile_parameter_declaration_(fC, id);
          break;   
        case VObjectType::slClass_method:
          compile_class_method_(fC, id);
          skipGuts = true;
          break;
        case VObjectType::slClass_type:
          compile_class_type_(fC, id);
        default:
          break;
        }

      if (current.m_sibling)
        stack.push (current.m_sibling);
      if (!skipGuts)
        if (current.m_child)
            stack.push (current.m_child);           
      
    }

  // Default constructor
  DataType* returnType = new DataType();
  FunctionMethod* method = new FunctionMethod (m_class, fC, nodeId, "new", returnType, false, false, false, false, false, false);
  method->compile (m_helper);
  Function* prevDef = m_class->getFunction ("new");
  if (!prevDef)
    {
      m_class->insertFunction (method);
    }
  
  return true;
}

bool CompileClass::compile_class_property_ (FileContent* fC, NodeId id) {
  NodeId data_declaration = fC->Child(id);
  NodeId var_decl = fC->Child(data_declaration);
  VObjectType type = fC->Type (data_declaration);
  bool is_local = false;
  bool is_static = false;
  bool is_protected = false;
  bool is_rand = false;
  bool is_randc = false;
  while ((type == VObjectType::slPropQualifier_ClassItem) ||
         (type == VObjectType::slPropQualifier_Rand) ||
         (type == VObjectType::slPropQualifier_Randc))
    {
       NodeId qualifier = fC->Child(data_declaration);
       VObjectType qualType = fC->Type(qualifier);
       if (qualType == VObjectType::slClassItemQualifier_Protected)
         is_protected = true;
        if (qualType == VObjectType::slClassItemQualifier_Static)
         is_static = true;
       if (qualType == VObjectType::slClassItemQualifier_Local)
         is_local = true;
       if (type == VObjectType::slPropQualifier_Rand)
         is_rand = true;
       if (type == VObjectType::slPropQualifier_Randc)
         is_randc = true;
       data_declaration = fC->Sibling(data_declaration);
       type = fC->Type (data_declaration);
       var_decl = fC->Child(data_declaration);
    }
    
  
  if (type == VObjectType::slData_declaration)
    {
      /*
     n<A> u<3> t<StringConst> p<37> s<12> l<5>
     n<> u<4> t<IntegerAtomType_Int> p<5> l<6>
     n<> u<5> t<Data_type> p<9> c<4> s<8> l<6>
     n<size> u<6> t<StringConst> p<7> l<6>
     n<> u<7> t<Variable_decl_assignment> p<8> c<6> l<6>
     n<> u<8> t<List_of_variable_decl_assignments> p<9> c<7> l<6>
     n<> u<9> t<Variable_declaration> p<10> c<5> l<6>
     n<> u<10> t<Data_declaration> p<11> c<9> l<6>
     n<> u<11> t<Class_property> p<12> c<10> l<6>
     n<> u<12> t<Class_item> p<37> c<11> s<35> l<6>          
       */
      VObjectType var_type = fC->Type (var_decl);
      if (var_type == VObjectType::slVariable_declaration)
        {
          NodeId data_type = fC->Child (var_decl);
          NodeId node_type = fC->Child (data_type);

          VObjectType the_type = fC->Type (node_type);
          std::string typeName;
          if (the_type == VObjectType::slStringConst)
            {
              typeName = fC->SymName (node_type);
            }
          else if (the_type == VObjectType::slClass_scope)
            {
              NodeId class_type = fC->Child (node_type);
              NodeId class_name = fC->Child (class_type);
              typeName = fC->SymName (class_name);
              typeName += "::";
              NodeId symb_id = fC->Sibling(node_type);
              typeName += fC->SymName (symb_id);
            }
          else 
            {
              typeName = VObject::getTypeName (the_type);
            }
          DataType* datatype = m_class->getUsedDataType (typeName);
          if (!datatype)
            {
              DataType* type = new DataType(fC, node_type, typeName, fC->Type(node_type));
              m_class->insertUsedDataType (typeName, type);
              datatype = m_class->getUsedDataType (typeName);
            }

          NodeId list_of_variable_decl_assignments = fC->Sibling (data_type);
          NodeId variable_decl_assignment = fC->Child (list_of_variable_decl_assignments);
          while (variable_decl_assignment)
            {
              NodeId var = fC->Child (variable_decl_assignment);
              NodeId range = fC->Sibling (var);
              std::string varName = fC->SymName (var);

              Property* previous = m_class->getProperty (varName);
              if (previous)
                {
                  Location loc1 (m_symbols->registerSymbol (fC->getFileName (var)), fC->Line (var), 0, m_symbols->registerSymbol (varName));
                  FileContent* prevFile = previous->getFileContent ();
                  NodeId prevNode = previous->getNodeId ();
                  Location loc2 (m_symbols->registerSymbol (prevFile->getFileName (prevNode)), prevFile->Line (prevNode), 0, m_symbols->registerSymbol (varName));
                  Error err (ErrorDefinition::COMP_MULTIPLY_DEFINED_PROPERTY, loc1, loc2);
                  m_errors->addError (err);
                }

              Property* prop = new Property(datatype, fC, var, range, varName, is_local, is_static,
                             is_protected, is_rand, is_randc);
              m_class->insertProperty (prop);

              variable_decl_assignment = fC->Sibling (variable_decl_assignment);
            }
        } 
      else if (var_type == VObjectType::slType_declaration)
        {
          compile_type_declaration_(fC, data_declaration);
        }
    }
  
  return true;
}

bool CompileClass::compile_class_method_ (FileContent* fC, NodeId id)
{
  /*
    n<> u<8> t<MethodQualifier_Virtual> p<21> s<20> l<12>
    n<> u<9> t<Function_data_type> p<10> l<12>
    n<> u<10> t<Function_data_type_or_implicit> p<19> c<9> s<11> l<12>
    n<print_tree1> u<11> t<StringConst> p<19> s<17> l<12>
    n<> u<12> t<IntegerAtomType_Int> p<13> l<12>
    n<> u<13> t<Data_type> p<14> c<12> l<12>
    n<> u<14> t<Data_type_or_implicit> p<16> c<13> s<15> l<12>
    n<a> u<15> t<StringConst> p<16> l<12>
    n<> u<16> t<Tf_port_item> p<17> c<14> l<12>
    n<> u<17> t<Tf_port_list> p<19> c<16> s<18> l<12>
    n<> u<18> t<Endfunction> p<19> l<14>
    n<> u<19> t<Function_body_declaration> p<20> c<10> l<12>
    n<> u<20> t<Function_declaration> p<21> c<19> l<12>
    n<> u<21> t<Class_method> p<22> c<8> l<12>
   */
  NodeId func_decl = fC->Child (id);
  VObjectType func_type = fC->Type (func_decl);
  std::string funcName;
  std::string taskName;
  bool is_virtual = false;
  bool is_extern = false;
  bool is_static = false;
  bool is_local = false;
  bool is_protected = false;
  bool is_pure = false;
  DataType* returnType = new DataType();
  while ((func_type == VObjectType::slMethodQualifier_Virtual) ||
         (func_type == VObjectType::slMethodQualifier_ClassItem) ||
         (func_type == VObjectType::slPure_virtual_qualifier) ||
         (func_type == VObjectType::slExtern_qualifier) ||
         (func_type == VObjectType::slClassItemQualifier_Protected))
    {
      if (func_type == VObjectType::slMethodQualifier_Virtual)
        {
          is_virtual = true;
          func_decl = fC->Sibling (func_decl);
          func_type = fC->Type (func_decl);
        }
      if (func_type == VObjectType::slClassItemQualifier_Protected)
        {
          is_protected = true;
          func_decl = fC->Sibling (func_decl);
          func_type = fC->Type (func_decl);
        }
      if (func_type == VObjectType::slPure_virtual_qualifier)
        {
          is_virtual = true;
          is_pure = true;
          func_decl = fC->Sibling (func_decl);
          func_type = fC->Type (func_decl);
        }
      if (func_type == VObjectType::slExtern_qualifier)
        {
          is_extern = true;
          func_decl = fC->Sibling (func_decl);
          func_type = fC->Type (func_decl);
        }
      if (func_type == VObjectType::slMethodQualifier_ClassItem)
        {
          NodeId qualifier = fC->Child (func_decl);
          VObjectType type = fC->Type (qualifier);
          if (type == VObjectType::slClassItemQualifier_Static)
            is_static = true;
          if (type == VObjectType::slClassItemQualifier_Local)
            is_local = true;
          if (type == VObjectType::slClassItemQualifier_Protected)
            is_protected = true;
          func_decl = fC->Sibling (func_decl);
          func_type = fC->Type (func_decl);
        }
    }
  if (func_type == VObjectType::slFunction_declaration)
    {
      NodeId func_body_decl = fC->Child (func_decl);
      NodeId function_data_type_or_implicit = fC->Child (func_body_decl);
      NodeId function_data_type = fC->Child (function_data_type_or_implicit);
      NodeId data_type = fC->Child (function_data_type);
      NodeId type = fC->Child (data_type);
      VObjectType the_type = fC->Type (type);
      std::string typeName;
      if (the_type == VObjectType::slStringConst)
        {
          typeName = fC->SymName (type);
        }
      else
        {
          typeName = VObject::getTypeName (the_type);
        }
      returnType->init(fC, type, typeName, fC->Type(type));
      NodeId function_name = fC->Sibling (function_data_type_or_implicit);
      funcName = fC->SymName (function_name);

    }
  else if (func_type == VObjectType::slTask_declaration)
    {
      /*
       n<cfg_dut> u<143> t<StringConst> p<146> s<144> l<37>
       n<> u<144> t<Endtask> p<146> s<145> l<39>
       n<cfg_dut> u<145> t<StringConst> p<146> l<39>
       n<> u<146> t<Task_body_declaration> p<147> c<143> l<37>
       n<> u<147> t<Task_declaration> p<148> c<146> l<37>
       n<> u<148> t<Class_method> p<149> c<147> l<37>
       */
      NodeId task_body_decl = fC->Child (func_decl);
      NodeId task_name = fC->Child (task_body_decl);
      taskName = fC->SymName (task_name);
    }
  else if (func_type == VObjectType::slMethod_prototype)
    {
      /*
       n<> u<65> t<IntVec_TypeBit> p<66> l<37>
       n<> u<66> t<Data_type> p<67> c<65> l<37>
       n<> u<67> t<Function_data_type> p<69> c<66> s<68> l<37>
       n<is_active> u<68> t<StringConst> p<69> l<37>
       n<> u<69> t<Function_prototype> p<70> c<67> l<37>
       n<> u<70> t<Method_prototype> p<71> c<69> l<37>
       n<> u<71> t<Class_method> p<72> c<70> l<37>
       */
      NodeId func_prototype = fC->Child (func_decl);
      if (fC->Type (func_prototype) == VObjectType::slTask_prototype)
        {
          NodeId task_name = fC->Child (func_prototype);
          taskName = fC->SymName (task_name);
        }
      else
        {
          NodeId function_data_type = fC->Child (func_prototype);
          NodeId data_type = fC->Child (function_data_type);
          NodeId type = fC->Child (data_type);
          VObjectType the_type = fC->Type (type);
          std::string typeName;
          if (the_type == VObjectType::slStringConst)
            {
              typeName = fC->SymName (type);
            }
          else
            {
              typeName = VObject::getTypeName (the_type);
            }
          returnType->init (fC, type, typeName, fC->Type(type));
          NodeId function_name = fC->Sibling (function_data_type);
          funcName = fC->SymName (function_name);
        }
      is_extern = true;
    }
  else if (func_type == VObjectType::slClass_constructor_declaration)
    {
      funcName = "new";
      returnType->init(fC, 0, "void", VObjectType::slNoType);
    }
  else if (func_type == VObjectType::slClass_constructor_prototype)
    {
      funcName = "new";
    }
  else
    {
      funcName = "UNRECOGNIZED_METHOD_TYPE";
    }
  if (taskName != "")
    {
      TaskMethod* method = new TaskMethod(m_class, fC, id, taskName, is_extern);
      method->compile(m_helper);
      TaskMethod* prevDef = m_class->getTask (taskName);
      if (prevDef)
        {
          Location loc1 (m_symbols->registerSymbol (fC->getFileName (id)), fC->Line (id), 0, m_symbols->registerSymbol (taskName));
          FileContent* prevFile = prevDef->getFileContent ();
          NodeId prevNode = prevDef->getNodeId ();
          Location loc2 (m_symbols->registerSymbol (prevFile->getFileName (prevNode)), prevFile->Line (prevNode), 0, m_symbols->registerSymbol (taskName));
          Error err (ErrorDefinition::COMP_MULTIPLY_DEFINED_TASK, loc1, loc2);
          m_errors->addError (err);
        }
      m_class->insertTask (method);
    }
  else
    {
      FunctionMethod* method = new FunctionMethod(m_class, fC, id, funcName, returnType, is_virtual, is_extern, is_static, is_local, is_protected, is_pure);
      Variable* variable = new Variable(returnType, fC, id, 0, funcName);
      method->addVariable (variable);  
      method->compile(m_helper);
      Function* prevDef = m_class->getFunction (funcName);
      if (prevDef)
        {
          Location loc1 (m_symbols->registerSymbol (fC->getFileName (id)), fC->Line (id), 0, m_symbols->registerSymbol (funcName));
          FileContent* prevFile = prevDef->getFileContent ();
          NodeId prevNode = prevDef->getNodeId ();
          Location loc2 (m_symbols->registerSymbol (prevFile->getFileName (prevNode)), prevFile->Line (prevNode), 0, m_symbols->registerSymbol (funcName));
          Error err (ErrorDefinition::COMP_MULTIPLY_DEFINED_FUNCTION, loc1, loc2);
          m_errors->addError (err);
        }
      m_class->insertFunction (method);
    }
  return true;
}

bool CompileClass::compile_class_constraint_ (FileContent* fC, NodeId class_constraint) {
  NodeId constraint_prototype = fC->Child(class_constraint);
  NodeId constraint_name = fC->Child(constraint_prototype);
  std::string constName = fC->SymName (constraint_name);
  Constraint* prevDef = m_class->getConstraint (constName);
  if (prevDef)
    {
      Location loc1 (m_symbols->registerSymbol (fC->getFileName (class_constraint)), fC->Line (class_constraint), 0, m_symbols->registerSymbol (constName));
      FileContent* prevFile = prevDef->getFileContent ();
      NodeId prevNode = prevDef->getNodeId ();
      Location loc2 (m_symbols->registerSymbol (prevFile->getFileName (prevNode)), prevFile->Line (prevNode), 0, m_symbols->registerSymbol (constName));
      Error err (ErrorDefinition::COMP_MULTIPLY_DEFINED_CONSTRAINT, loc1, loc2);
      m_errors->addError (err);
    }
  Constraint* constraint = new Constraint(fC, class_constraint, constName);
  m_class->insertConstraint (constraint);
  
  return true;
}

bool CompileClass::compile_type_declaration_ (FileContent* fC, NodeId id) {
  /*
    n<> u<8> t<IntegerAtomType_Int> p<9> l<3>
    n<> u<9> t<Data_type> p<11> c<8> s<10> l<3>
    n<my_int> u<10> t<StringConst> p<11> l<3>
    n<> u<11> t<Type_declaration> p<12> c<9> l<3>
    n<> u<12> t<Data_declaration> p<13> c<11> l<3>
    n<> u<13> t<Class_property> p<14> c<12> l<3>
  */
  m_helper.compileTypeDef (m_class, fC, id);
 
  return true;
}

bool CompileClass::compile_class_declaration_ (FileContent* fC, NodeId id)
{
  NodeId class_name_id = fC->Child (id);
  std::string class_name = m_class->getName() + "::" + fC->SymName (class_name_id);
  ClassDefinition* prevDef = m_class->getClass (class_name);
  if (prevDef)
    {
      Location loc1 (m_symbols->registerSymbol (fC->getFileName (class_name_id)), fC->Line (class_name_id), 0, m_symbols->registerSymbol (class_name));
      FileContent* prevFile = prevDef->getFileContent ();
      NodeId prevNode = prevDef->getNodeId ();
      Location loc2 (m_symbols->registerSymbol (prevFile->getFileName (prevNode)), prevFile->Line (prevNode), 0, m_symbols->registerSymbol (class_name));
      Error err (ErrorDefinition::COMP_MULTIPLY_DEFINED_INNER_CLASS, loc1, loc2);
      m_errors->addError (err);
    }
 
  ClassDefinition* the_class = new ClassDefinition(class_name, m_class->getLibrary(), m_class->getContainer(), fC, class_name_id, m_class);
  m_class->insertClass (the_class);
  
  CompileClass* instance = new CompileClass(m_compileDesign, the_class, m_design, m_symbols, m_errors);
  instance->compile();
  delete instance;  

  return true;
}

bool CompileClass::compile_covergroup_declaration_ (FileContent* fC, NodeId id) {
  NodeId covergroup_name = fC->Child(id);
  std::string covergroupName = fC->SymName (covergroup_name);
  CoverGroupDefinition* prevDef = m_class->getCoverGroup (covergroupName);
  if (prevDef)
    {
      Location loc1 (m_symbols->registerSymbol (fC->getFileName (covergroup_name)), fC->Line (covergroup_name), 0, m_symbols->registerSymbol (covergroupName));
      FileContent* prevFile = prevDef->getFileContent ();
      NodeId prevNode = prevDef->getNodeId ();
      Location loc2 (m_symbols->registerSymbol (prevFile->getFileName (prevNode)), prevFile->Line (prevNode), 0, m_symbols->registerSymbol (covergroupName));
      Error err (ErrorDefinition::COMP_MULTIPLY_DEFINED_COVERGROUP, loc1, loc2);
      m_errors->addError (err);
    }
  CoverGroupDefinition* covergroup = new CoverGroupDefinition(fC, id, covergroupName);
  m_class->insertCoverGroup (covergroup);
  
  return true;
}

bool CompileClass::compile_local_parameter_declaration_ (FileContent* fC, NodeId id)
{
  /*
   n<> u<8> t<IntegerAtomType_Int> p<9> l<3>
   n<> u<9> t<Data_type> p<10> c<8> l<3>
   n<> u<10> t<Data_type_or_implicit> p<20> c<9> s<19> l<3>
   n<FOO> u<11> t<StringConst> p<18> s<17> l<3>
   n<3> u<12> t<IntConst> p<13> l<3>
   n<> u<13> t<Primary_literal> p<14> c<12> l<3>
   n<> u<14> t<Constant_primary> p<15> c<13> l<3>
   n<> u<15> t<Constant_expression> p<16> c<14> l<3>
   n<> u<16> t<Constant_mintypmax_expression> p<17> c<15> l<3>
   n<> u<17> t<Constant_param_expression> p<18> c<16> l<3>
   n<> u<18> t<Param_assignment> p<19> c<11> l<3>
   n<> u<19> t<List_of_param_assignments> p<20> c<18> l<3>
   n<> u<20> t<Local_parameter_declaration> p<21> c<10> l<3>
  */
  
  NodeId data_type_or_implicit = fC->Child (id);
  NodeId list_of_param_assignments = fC->Sibling(data_type_or_implicit);
  NodeId param_assignment = fC->Child (list_of_param_assignments);
  while (param_assignment)
    {
      NodeId var = fC->Child (param_assignment);
      std::string name = fC->SymName (var);
      std::pair<FileCNodeId, DesignComponent*>* prevDef = m_class->getNamedObject (name);
      if (prevDef)
        {
          Location loc1 (m_symbols->registerSymbol (fC->getFileName (var)), fC->Line (var), 0, m_symbols->registerSymbol (name));
          FileContent* prevFile = prevDef->first.fC;
          NodeId prevNode = prevDef->first.nodeId;
          Location loc2 (m_symbols->registerSymbol (prevFile->getFileName (prevNode)), prevFile->Line (prevNode), 0, m_symbols->registerSymbol (name));
          Error err (ErrorDefinition::COMP_MULTIPLY_DEFINED_PARAMETER, loc1, loc2);
          m_errors->addError (err);
        }

      FileCNodeId fnid (fC, id);
      m_class->addObject (VObjectType::slLocal_parameter_declaration, fnid);
      m_class->addNamedObject (name, fnid, NULL);
      
      param_assignment = fC->Sibling(param_assignment);
      
    }
  return true;
}

bool
CompileClass::compile_parameter_declaration_ (FileContent* fC, NodeId id)
{
  NodeId data_type_or_implicit = fC->Child (id);
  NodeId list_of_param_assignments = fC->Sibling(data_type_or_implicit);
  NodeId param_assignment = fC->Child (list_of_param_assignments);
  while (param_assignment)
    {
      NodeId var = fC->Child (param_assignment);
      std::string name = fC->SymName (var);
      std::pair<FileCNodeId, DesignComponent*>* prevDef = m_class->getNamedObject (name);
      if (prevDef)
        {
          Location loc1 (m_symbols->registerSymbol (fC->getFileName (var)), fC->Line (var), 0, m_symbols->registerSymbol (name));
          FileContent* prevFile = prevDef->first.fC;
          NodeId prevNode = prevDef->first.nodeId;
          Location loc2 (m_symbols->registerSymbol (prevFile->getFileName (prevNode)), prevFile->Line (prevNode), 0, m_symbols->registerSymbol (name));
          Error err (ErrorDefinition::COMP_MULTIPLY_DEFINED_PARAMETER, loc1, loc2);
          m_errors->addError (err);
        }

      FileCNodeId fnid (fC, id);
      m_class->addObject (VObjectType::slLocal_parameter_declaration, fnid);
      m_class->addNamedObject (name, fnid, NULL);
      
      param_assignment = fC->Sibling(param_assignment);
      
    }
  return true;
}

bool
CompileClass::compile_class_type_ (FileContent* fC, NodeId id)
{
  NodeId parent = fC->Parent (id);
  VObjectType ptype = fC->Type(parent);
  if (ptype != VObjectType::slClass_declaration)
    return true;
  NodeId base_class_id = fC->Child (id);
  std::string base_class_name = fC->SymName (base_class_id);
  while (fC->Sibling(base_class_id) && (fC->Type(fC->Sibling(base_class_id)) == VObjectType::slStringConst))
    {
      base_class_id = fC->Sibling(base_class_id);
      base_class_name += "::" + fC->SymName (base_class_id);
    }
  // Insert base class placeholder
  // Will be bound in UVMElaboration step
  ClassDefinition* base_class = new ClassDefinition(base_class_name, m_class->getLibrary(), m_class->getContainer(), fC, base_class_id, NULL);
  m_class->insertBaseClass (base_class);
    
  return true;
}

bool CompileClass::compile_class_parameters_(FileContent* fC, NodeId id)
{
  /*
  n<all_c> u<1> t<StringConst> p<16> s<14> l<3>
  n<uvm_port_base> u<2> t<StringConst> p<12> s<8> l<7>
  n<IF> u<3> t<StringConst> p<6> s<5> l<7>
  n<uvm_void> u<4> t<StringConst> p<5> l<7>  
  n<> u<5> t<Data_type> p<6> c<4> l<7>
  n<> u<6> t<List_of_type_assignments> p<7> c<3> l<7>
  n<> u<7> t<Parameter_port_declaration> p<8> c<6> l<7>
  n<> u<8> t<Parameter_port_list> p<12> c<7> s<10> l<7>
  n<IF> u<9> t<StringConst> p<10> l<7>
  n<> u<10> t<Class_type> p<12> c<9> s<11> l<7>
  n<> u<11> t<Endclass> p<12> l<8>
  n<> u<12> t<Class_declaration> p<13> c<2> l<7>
   
  or
   
  n<T1> u<3> t<StringConst> p<9> s<5> l<18>
  n<> u<4> t<IntegerAtomType_Int> p<5> l<18>
  n<> u<5> t<Data_type> p<9> c<4> s<6> l<18>
  n<T2> u<6> t<StringConst> p<9> s<8> l<18>
  n<T1> u<7> t<StringConst> p<8> l<18>
  n<> u<8> t<Data_type> p<9> c<7> l<18>
  n<> u<9> t<List_of_type_assignments> p<10> c<3> l<18>
  n<> u<10> t<Parameter_port_declaration> p<11> c<9> l<18>
  n<> u<11> t<Parameter_port_list> p<31> c<10> s<20> l<18> 
   
  */
  
  NodeId className = fC->Child(id);
  NodeId paramList = fC->Sibling(className);
  if (fC->Type(paramList) == VObjectType::slParameter_port_list)
    {
      NodeId parameter_port_declaration = fC->Child (paramList);
      while (parameter_port_declaration)
        {
          NodeId list_of_type_assignments = fC->Child (parameter_port_declaration);
          NodeId typeNameId = fC->Child (list_of_type_assignments);
          while (typeNameId)
            {
              NodeId ntype = fC->Sibling (typeNameId);
              bool skip = false;
              if (ntype && fC->Type (ntype) == VObjectType::slData_type)
                {
                  ntype = fC->Child (ntype);
                  skip = true;
                }
              else
                {
                  ntype = 0;
                }
              Parameter* param = new Parameter(fC, typeNameId, fC->SymName(typeNameId), ntype);
              m_class->insertParameter (param);
              typeNameId = fC->Sibling (typeNameId);
              if (skip)
                typeNameId = fC->Sibling (typeNameId);
            }
           parameter_port_declaration = fC->Sibling (parameter_port_declaration);
        }
    }
  return true;
}
