/*
 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:   CompileHelper.cpp
 * Author: alain
 * 
 * Created on May 14, 2019, 8:03 PM
 */

#include "../Expression/Value.h"
#include "../Expression/ExprBuilder.h"
#include "../Design/Enum.h"
#include "../Design/Function.h"
#include "../Testbench/Property.h"
#include "../SourceCompile/CompilationUnit.h"
#include "../SourceCompile/PreprocessFile.h"
#include "../SourceCompile/CompileSourceFile.h"
#include "../SourceCompile/ParseFile.h"
#include "../SourceCompile/Compiler.h"
#include "../Design/Design.h"
#include "CompileHelper.h"
#include <iostream>
using namespace SURELOG;


CompileHelper::~CompileHelper () { }

bool CompileHelper::importPackage(DesignComponent* scope, Design* design, FileContent* fC, NodeId id)
{
  FileCNodeId fnid (fC, id);
  scope->addObject (VObjectType::slPackage_import_item, fnid);

  NodeId nameId = fC->Child (id);
  std::string pack_name = fC->SymName (nameId);
  Package* def = design->getPackage (pack_name);
  if (def)
    {
      scope->addAccessPackage (def);
      auto& classSet = def->getObjects (VObjectType::slClass_declaration);
      for (unsigned int i = 0; i < classSet.size (); i++)
        {
          FileContent* packageFile = classSet[i].fC;
          NodeId classDef = classSet[i].nodeId;
          std::string name = packageFile->SymName (classDef);
          std::string fullName = def->getName () + "::" + name;
          DesignComponent* comp = packageFile->getComponentDefinition (fullName);
          FileCNodeId fnid (packageFile, classDef);
          scope->addNamedObject (name, fnid, comp);
        }

      auto& typeSet = def->getDataTypeMap ();
      for (auto& type : typeSet)
        {
          scope->insertDataType (type.first, type.second);
        }

      auto& variableSet = def->getVariables ();
      for (auto& var : variableSet)
        {
          scope->addVariable (var.second);
          Value* val = def->getValue (var.first);
          if (val)
            {
              scope->setValue (var.first, val, *def->getExprBuilder());
            }
        }

    }
  else
    {
      Location loc (m_symbols->registerSymbol (fC->getFileName (id)), fC->Line (id), 0, m_symbols->registerSymbol (pack_name));
      Error err (ErrorDefinition::COMP_UNDEFINED_PACKAGE, loc);
      m_errors->addError (err);
    }
 
  return true;
}


bool CompileHelper::compileTfPortList(Procedure* parent, FileContent* fC, NodeId tf_port_list, TfPortList& targetList) {
  bool result = true;
  /*
   n<c1> u<7> t<StringConst> p<29> s<27> l<10>
   n<> u<8> t<IntegerAtomType_Int> p<9> l<12>
   n<> u<9> t<Data_type> p<10> c<8> l<12>
   n<> u<10> t<Function_data_type> p<11> c<9> l<12>
   n<> u<11> t<Function_data_type_or_implicit> p<24> c<10> s<12> l<12>
   n<try_get> u<12> t<StringConst> p<24> s<22> l<12>
   n<> u<13> t<IntegerAtomType_Int> p<14> l<12>
   n<> u<14> t<Data_type> p<15> c<13> l<12>
   n<> u<15> t<Data_type_or_implicit> p<21> c<14> s<16> l<12>
   n<keyCount> u<16> t<StringConst> p<21> s<20> l<12>
   n<1> u<17> t<IntConst> p<18> l<12>
   n<> u<18> t<Primary_literal> p<19> c<17> l<12>
   n<> u<19> t<Primary> p<20> c<18> l<12>
   n<> u<20> t<Expression> p<21> c<19> l<12>
   n<> u<21> t<Tf_port_item> p<22> c<15> l<12>
   n<> u<22> t<Tf_port_list> p<24> c<21> s<23> l<12>
   n<> u<23> t<Endfunction> p<24> l<13>
   n<> u<24> t<Function_body_declaration> p<25> c<11> l<12>
   n<> u<25> t<Function_declaration> p<26> c<24> l<12>
   n<> u<26> t<Class_method> p<27> c<25> l<12>
  */
  /*
   Or
   n<get> u<47> t<StringConst> p<55> s<53> l<18>
   n<> u<48> t<PortDir_Ref> p<49> l<18>
   n<> u<49> t<Tf_port_direction> p<52> c<48> s<50> l<18>
   n<> u<50> t<Data_type_or_implicit> p<52> s<51> l<18>
   n<message> u<51> t<StringConst> p<52> l<18>
   n<> u<52> t<Tf_port_item> p<53> c<49> l<18>   
  */
  // Compile arguments
  if (tf_port_list && (fC->Type(tf_port_list) == VObjectType::slTf_port_list))
    {
      NodeId tf_port_item = fC->Child(tf_port_list);
      while (tf_port_item)
        {
          Value* value = NULL;
          NodeId tf_data_type_or_implicit = fC->Child(tf_port_item);
          NodeId tf_data_type = fC->Child(tf_data_type_or_implicit);
          VObjectType tf_port_direction_type = fC->Type(tf_data_type_or_implicit);
          NodeId tf_param_name = fC->Sibling(tf_data_type_or_implicit);
          if (tf_port_direction_type == VObjectType::slTfPortDir_Ref ||
              tf_port_direction_type == VObjectType::slTfPortDir_ConstRef ||
              tf_port_direction_type == VObjectType::slTfPortDir_Inp ||
              tf_port_direction_type == VObjectType::slTfPortDir_Out ||
              tf_port_direction_type == VObjectType::slTfPortDir_Inout)
            {
              tf_data_type = fC->Sibling(tf_data_type_or_implicit);
              tf_param_name = fC->Sibling(tf_data_type);
            }
          else 
            {
              tf_port_direction_type = VObjectType::slNull_rule;
            }
          NodeId type = fC->Child(tf_data_type);
          VObjectType the_type = fC->Type(type);
          std::string typeName;
          if (the_type == VObjectType::slStringConst)
            {
              typeName = fC->SymName (type);
            }
          else if (the_type == VObjectType::slClass_scope)
            {
              NodeId class_type = fC->Child (type);
              NodeId class_name = fC->Child (class_type);
              typeName = fC->SymName (class_name);
              typeName += "::";
              NodeId symb_id = fC->Sibling(type);
              typeName += fC->SymName (symb_id);
            }
          else 
            {
              typeName = VObject::getTypeName (the_type);
            }
          std::string name = fC->SymName(tf_param_name);
          NodeId expression = fC->Sibling(tf_param_name);
          DataType* dtype = new DataType(fC, type, typeName, fC->Type(type));

          if (expression && (fC->Type(expression) != VObjectType::slVariable_dimension)
                         && (dtype->getType() != VObjectType::slStringConst) )
            {
              value = m_exprBuilder.evalExpr (fC, expression, parent->getParent ()); 
            }
          NodeId range = 0;
          TfPortItem* param = new TfPortItem(parent, fC, tf_port_item, range, name, dtype, value, tf_port_direction_type);
          targetList.push_back(param);
          tf_port_item = fC->Sibling(tf_port_item);
        }
    }
  return result;
}

DataType*
CompileHelper::compileTypeDef (DesignComponent* scope, FileContent* fC, NodeId data_declaration)
{
  DataType* newType = NULL;
  /*
   n<> u<1> t<IntVec_TypeBit> p<12> s<11> l<5>
   n<1> u<2> t<IntConst> p<3> l<5>
   n<> u<3> t<Primary_literal> p<4> c<2> l<5>
   n<> u<4> t<Constant_primary> p<5> c<3> l<5>
   n<> u<5> t<Constant_expression> p<10> c<4> s<9> l<5>
   n<0> u<6> t<IntConst> p<7> l<5>
   n<> u<7> t<Primary_literal> p<8> c<6> l<5>
   n<> u<8> t<Constant_primary> p<9> c<7> l<5>
   n<> u<9> t<Constant_expression> p<10> c<8> l<5>
   n<> u<10> t<Constant_range> p<11> c<5> l<5>
   n<> u<11> t<Packed_dimension> p<12> c<10> l<5>
   n<> u<12> t<Enum_base_type> p<21> c<1> s<14> l<5>
   n<UVM_INFO> u<13> t<StringConst> p<14> l<7>
   n<> u<14> t<Enum_name_declaration> p<21> c<13> s<16> l<7>
   n<UVM_WARNING> u<15> t<StringConst> p<16> l<8>
   n<> u<16> t<Enum_name_declaration> p<21> c<15> s<18> l<8>
   n<UVM_ERROR> u<17> t<StringConst> p<18> l<9>
   n<> u<18> t<Enum_name_declaration> p<21> c<17> s<20> l<9>
   n<UVM_FATAL> u<19> t<StringConst> p<20> l<10>
   n<> u<20> t<Enum_name_declaration> p<21> c<19> l<10>
   n<> u<21> t<Data_type> p<23> c<12> s<22> l<5>
   n<uvm_severity> u<22> t<StringConst> p<23> l<11>
   n<> u<23> t<Type_declaration> p<24> c<21> l<5>
   n<> u<24> t<Data_declaration> p<25> c<23> l<5>
   */
  
  NodeId type_declaration = fC->Child (data_declaration);
  NodeId data_type = fC->Child (type_declaration);
  
  VObjectType dtype = fC->Type(data_type);
  
   
  if ( dtype == VObjectType::slClass_keyword
    || dtype == VObjectType::slStruct_keyword
    || dtype == VObjectType::slUnion_keyword
    || dtype == VObjectType::slInterface_class_keyword
    || dtype == VObjectType::slEnum_keyword)
    {
      NodeId type_name = fC->Sibling (data_type);
      std::string name = fC->SymName (type_name);
      TypeDef* prevDef = scope->getTypeDef (name);
      if (prevDef)
        return prevDef;
      NodeId stype = fC->Sibling (data_type);
      if (fC->Type (stype) == VObjectType::slStringConst)
        {
          TypeDef* newTypeDef = new TypeDef (fC, type_declaration, stype, name);
          scope->insertTypeDef (newTypeDef);
          newType = newTypeDef;
          return newType;
        }    
    }
  
  
  if (dtype != VObjectType::slData_type)
    {
      return NULL;
    }

  NodeId type_name = fC->Sibling (data_type);
  std::string name = fC->SymName (type_name);
  TypeDef* prevDef = scope->getTypeDef (name);
  if (prevDef)
    {
      Location loc1 (m_symbols->registerSymbol (fC->getFileName (data_type)), fC->Line (data_type), 0, m_symbols->registerSymbol (name));
      FileContent* prevFile = prevDef->getFileContent ();
      NodeId prevNode = prevDef->getNodeId ();
      Location loc2 (m_symbols->registerSymbol (prevFile->getFileName (prevNode)), prevFile->Line (prevNode), 0, m_symbols->registerSymbol (name));
      Error err (ErrorDefinition::COMP_MULTIPLY_DEFINED_TYPEDEF, loc1, loc2);
      m_errors->addError (err);
    }

  VObjectType base_type = fC->Type (data_type);
  
  DataType* type = new DataType (fC, data_type, name, base_type);
  scope->insertDataType (name, type); 
 
  // Enum or Struct or Union
  NodeId enum_base_type = fC->Child (data_type);
  bool enumType   = false;
  bool structType = false;
  NodeId enum_base_type_node = VObjectType::slNull_rule;
  VObjectType enum_base_type_type = VObjectType::slNull_rule;
  NodeId enum_name_declaration = VObjectType::slNull_rule;
  if (fC->Type (enum_base_type) == VObjectType::slEnum_base_type)
    {
      enum_base_type_node = fC->Child (enum_base_type);
      enum_base_type_type = fC->Type (enum_base_type_node);
      enum_name_declaration = fC->Sibling (enum_base_type);
      enumType = true;
    }
  else if (fC->Type (enum_base_type) == VObjectType::slEnum_name_declaration)
    {
      enumType = true;
      enum_name_declaration = enum_base_type;
      enum_base_type = 0;
      enum_base_type_type = VObjectType::slIntegerAtomType_Byte;
    }
  else if (fC->Type (enum_base_type) == VObjectType::slStruct_union)
    {
      structType = true;
      //NodeId struct_or_union = fC->Child(enum_base_type);
      //VObjectType struct_or_union_type = fC->Type(struct_or_union);
      NodeId struct_or_union_member = fC->Sibling(enum_base_type);
      while (struct_or_union_member)
        {
          
          struct_or_union_member = fC->Sibling(struct_or_union_member);
        }
      TypeDef* newTypeDef = new TypeDef (fC, type_declaration, type_name, name);
      scope->insertTypeDef (newTypeDef);
    }
  if (enumType)
    {
      TypeDef* newTypeDef = new TypeDef (fC, type_declaration, enum_base_type, name);
      int val = 0;
      Enum* the_enum = new Enum (name, fC, enum_base_type, enum_base_type_type);
      newTypeDef->setEnum (the_enum);
      newTypeDef->setDefinition (the_enum);
      newType = newTypeDef;
      while (enum_name_declaration)
        {
          NodeId enumNameId = fC->Child (enum_name_declaration);
          std::string enumName = fC->SymName (enumNameId);
          NodeId enumValueId = fC->Sibling (enumNameId);
          Value* value = NULL;
          if (enumValueId)
            {
              value = m_exprBuilder.evalExpr (fC, enumValueId, NULL);
            }
          else
            {
              value = m_exprBuilder.getValueFactory ().newLValue ();
              value->set (val, Value::Integer, 32);
            }
          the_enum->addValue (enumName, value);
          enum_name_declaration = fC->Sibling (enum_name_declaration);
          val++;
          scope->setValue (enumName, value, m_exprBuilder);
          Variable* variable = new Variable (type, fC, enumValueId, 0, enumName);
          scope->addVariable (variable);
        }

      type->setDefinition (newTypeDef);
      scope->insertTypeDef (newTypeDef);

    }
  else if (structType)
    {
      
    }
  else
    {
      NodeId stype = fC->Child (data_type);
      if (fC->Type (stype) == VObjectType::slStringConst)
        {
          TypeDef* newTypeDef = new TypeDef (fC, type_declaration, stype, name);
          type->setDefinition (newTypeDef);
          scope->insertTypeDef (newTypeDef);
          newType = newTypeDef;
        }
    }
  
  return newType;
}

bool CompileHelper::compileScopeBody(Scope* parent, Statement* parentStmt, FileContent* fC, NodeId function_statement_or_null) {
  bool result = true;
  while (function_statement_or_null)
    {
      VObjectType nodeType = fC->Type (function_statement_or_null);
      switch (nodeType)
        {
        case VObjectType::slFunction_statement_or_null:
        case VObjectType::slStatement_or_null:
          {
            NodeId statement = fC->Child (function_statement_or_null);
            NodeId statement_item = fC->Child (statement);
            NodeId item = fC->Child (statement_item);
            VObjectType stmtType = fC->Type (item);
            switch (stmtType)
              {
              case VObjectType::slSubroutine_call_statement:
                {
                  compileSubroutine_call(parent, parentStmt, fC, item);
                  break;
                }
              case VObjectType::slSeq_block:
                compileSeqBlock_stmt(parent,parentStmt, fC, item);
                break;
              case VObjectType::slLoop_statement:
                compileLoop_stmt(parent, parentStmt, fC, item);
                break;
              default: // stmtType
                break;
              }
            break;
          }
        case VObjectType::slStatement:  
          {
            NodeId statement = function_statement_or_null;
            NodeId statement_item = fC->Child (statement);
            NodeId item = fC->Child (statement_item);
            VObjectType stmtType = fC->Type (item);
            switch (stmtType)
              {
              case VObjectType::slSubroutine_call_statement:
                {
                  compileSubroutine_call(parent, parentStmt, fC, item);
                  break;
                }
              case VObjectType::slSeq_block:
                compileSeqBlock_stmt(parent,parentStmt, fC, item);
                break;
              case VObjectType::slLoop_statement:
                compileLoop_stmt(parent, parentStmt, fC, item);
                break;
              default: // stmtType
                break;
              }
            break;
          }
          break;
        case VObjectType::slBlock_item_declaration:
          compileScopeVariable (parent, fC, function_statement_or_null);
          break;
        case VObjectType::slSuper_dot_new:
          {
            NodeId list_of_arguments = fC->Sibling (function_statement_or_null);
            NodeId expression = fC->Child (list_of_arguments);
            std::vector<SubRoutineArg*> args;
            while (expression)
              {
                SubRoutineArg* arg = new SubRoutineArg (expression, NULL);
                args.push_back (arg);
                expression = fC->Sibling (expression);
              }
            std::vector<NodeId> var_chain;
            var_chain.push_back(function_statement_or_null);
            SubRoutineCallStmt* stmt = new SubRoutineCallStmt (parent, parentStmt, fC, function_statement_or_null, VObjectType::slSubroutine_call_statement,
                                                               var_chain, "new", args, false, false);
            parent->addStmt (stmt);
            if (parentStmt)
              parentStmt->addStatement (stmt);
          break;
        }
        default:
          break;
        }
      function_statement_or_null = fC->Sibling (function_statement_or_null);
    }
  
  return result;
}


bool CompileHelper::compileSubroutine_call(Scope* parent, Statement* parentStmt, FileContent* fC, NodeId subroutine_call_statement)
{
  /*
  n<d> u<44> t<StringConst> p<48> s<45> l<15>
  n<> u<45> t<Constant_bit_select> p<48> s<46> l<15>
  n<get_current_item> u<46> t<StringConst> p<48> s<47> l<15>
  n<> u<47> t<List_of_arguments> p<48> l<15>
  n<> u<48> t<Subroutine_call> p<49> c<44> l<15>
  n<> u<49> t<Subroutine_call_statement> p<50> c<48> l<15>
  n<> u<50> t<Statement_item> p<51> c<49> l<15>
  n<> u<51> t<Statement> p<52> c<50> l<15>
  n<> u<52> t<Function_statement_or_null> p<61> c<51> s<59> l<15>
  n<foo> u<53> t<StringConst> p<55> s<54> l<16>
  n<> u<54> t<List_of_arguments> p<55> l<16>
  n<> u<55> t<Subroutine_call> p<56> c<53> l<16>
  n<> u<56> t<Subroutine_call_statement> p<57> c<55> l<16>
  n<> u<57> t<Statement_item> p<58> c<56> l<16>
  n<> u<58> t<Statement> p<59> c<57> l<16>
  n<> u<59> t<Function_statement_or_null> p<61> c<58> s<60> l<16> 
   */
  std::vector<NodeId> var_chain;
  NodeId subroutine_call = fC->Child (subroutine_call_statement);
  NodeId base_name = fC->Child (subroutine_call);
  NodeId next_name = base_name;
  bool static_call = false;
  bool system_call = false;
  if (fC->Type (base_name) == VObjectType::slDollar_keyword)
    {
      // system calls
      base_name = fC->Sibling (base_name);
      next_name = base_name;
      system_call = true;
    }
  else if (fC->Type (base_name) == VObjectType::slImplicit_class_handle)
    {
      next_name = fC->Sibling (base_name);
      base_name = fC->Child (base_name);
      var_chain.push_back (base_name);
    }
  else if (fC->Type (base_name) == VObjectType::slClass_scope)
    {
      next_name = fC->Sibling (base_name);
      base_name = fC->Child (base_name);
      base_name = fC->Child (base_name);
      while (base_name)
        {
          VObjectType ntype = fC->Type (base_name);
          if (ntype == VObjectType::slParameter_value_assignment)
            {
              base_name = fC->Sibling (base_name);
            }
          if (base_name == 0)
            break;
          var_chain.push_back (base_name);
          base_name = fC->Sibling (base_name);
        }
      static_call = true;
    }
  while (next_name)
    {
      VObjectType ntype = fC->Type (next_name);
      if (ntype == VObjectType::slConstant_bit_select)
        {
          next_name = fC->Sibling (next_name);
        }
      if (ntype == VObjectType::slSelect)
        {
          next_name = fC->Sibling (next_name);
        }
      if (next_name == 0)
        break;
      if (ntype == VObjectType::slList_of_arguments)
        {
          break;
        }
      var_chain.push_back (next_name);

      next_name = fC->Sibling (next_name);
    }
  std::string funcName = fC->SymName (var_chain[var_chain.size () - 1]);
  var_chain.pop_back ();

  NodeId list_of_arguments = next_name;
  NodeId expression = fC->Child (list_of_arguments);
  std::vector<SubRoutineArg*> args;
  while (expression)
    {
      SubRoutineArg* arg = new SubRoutineArg (expression, NULL);
      args.push_back (arg);
      expression = fC->Sibling (expression);
    }

  SubRoutineCallStmt* stmt = new SubRoutineCallStmt (parent, parentStmt, fC, subroutine_call, VObjectType::slSubroutine_call_statement,
                                                     var_chain, funcName, args, static_call, system_call);
  parent->addStmt (stmt);
  if (parentStmt)
    parentStmt->addStatement (stmt);
  return true;
}

bool CompileHelper::compileSeqBlock_stmt(Scope* parent, Statement* parentStmt, FileContent* fC, NodeId seq_block) {
   NodeId item = fC->Child(seq_block);
   std::string name = "";
   SeqBlock* block = new SeqBlock(name, parent, parentStmt, fC, seq_block);
   parent->addScope(block);
   parent->addStmt (block);
   if (parentStmt)
     parentStmt->addStatement (block);
   compileScopeBody(block, block, fC, item);
   return true;
}

bool CompileHelper::compileLoop_stmt(Scope* parent, Statement* parentStmt, FileContent* fC, NodeId loop_statement)
{
  NodeId loop = fC->Child(loop_statement);
  NodeId expression = fC->Sibling(loop);
  switch (fC->Type(loop))
    {
    case VObjectType::slFor_initialization:
    case VObjectType::slExpression:
      compileForLoop_stmt(parent, parentStmt, fC, loop);
      break;    
    case VObjectType::slStatement_or_null:
      if (expression)
        {
          // Do loop
        }
      else
        compileForLoop_stmt(parent, parentStmt, fC, loop);
      break;
    case VObjectType::slPs_or_hierarchical_array_identifier:
      compileForeachLoop_stmt(parent, parentStmt, fC, loop);
    default:
      break;
    }     
  return true;
}

bool CompileHelper::compileForeachLoop_stmt(Scope* parent, Statement* parentStmt, FileContent* fC, NodeId ps_or_hierarchical_array_identifier) {
  NodeId loop_variables = fC->Sibling(ps_or_hierarchical_array_identifier);
  NodeId statement = fC->Sibling(loop_variables);
  ForeachLoopStmt* stmt = new ForeachLoopStmt("", fC->Child(ps_or_hierarchical_array_identifier), parent, parentStmt, fC, ps_or_hierarchical_array_identifier, VObjectType::slPs_or_hierarchical_array_identifier);
  parent->addStmt (stmt);
  parent->addScope(stmt);
  loop_variables = fC->Child(loop_variables);
  while (loop_variables)
    {
      stmt->addIteratorId (loop_variables);
      loop_variables = fC->Sibling(loop_variables);
    }
  if (parentStmt)
    parentStmt->addStatement (stmt);
  compileScopeBody(parent, stmt, fC, statement);

  return true;
}

  
bool CompileHelper::compileForLoop_stmt(Scope* parent, Statement* parentStmt, FileContent* fC, NodeId first_node) {
  VObjectType init_type = fC->Type(first_node);
  NodeId for_initialization = 0;
  NodeId expression         = 0;
  NodeId for_step           = 0;
  NodeId statement_or_null  = 0;
  NodeId itr_data_type      = 0;
  ForLoopStmt* stmt = NULL;
  if (init_type == VObjectType::slStatement_or_null)
    {
      // for ( ; ; )
      statement_or_null = first_node;
      stmt = new ForLoopStmt("", parent, parentStmt, fC, first_node, VObjectType::slStatement_or_null);
    }
  else if (init_type == VObjectType::slFor_initialization)
    {
      // for ( int i = 0; xxx ; xxx )
      for_initialization = first_node;
      expression = fC->Sibling(for_initialization);
      if (fC->Type(expression) == VObjectType::slExpression)        
        for_step = fC->Sibling(expression);
      else 
        {
          for_step = expression;
          expression = 0;               
        }
      if (fC->Type(for_step) == VObjectType::slFor_step)
          statement_or_null = fC->Sibling(for_step);
      else
        {
          statement_or_null = for_step;
          for_step = 0;
        }
      stmt = new ForLoopStmt("", parent, parentStmt, fC, for_initialization, VObjectType::slFor_initialization);
      NodeId for_variable_declaration = fC->Child (for_initialization);
      if (for_variable_declaration)
        itr_data_type = fC->Child (for_variable_declaration);
      NodeId the_data_type = fC->Child (itr_data_type);
      VObjectType the_type = fC->Type (the_data_type);
      stmt->setIteratorType (the_type);
    }
  else if (init_type == VObjectType::slExpression)
    {
      // for ( ; i < 1 ; xxx )
      expression = first_node;
      for_step = fC->Sibling(expression);
      if (fC->Type(for_step) == VObjectType::slFor_step)
          statement_or_null = fC->Sibling(for_step);
      else
        {
          statement_or_null = for_step;
          for_step = 0;
        }
      stmt = new ForLoopStmt("", parent, parentStmt, fC, first_node, VObjectType::slExpression);
    }
  parent->addStmt (stmt);
  parent->addScope(stmt);

  if (expression != 0)
    stmt->setConditionId (expression);
 
  if (itr_data_type)
    {
      NodeId iterator = fC->Sibling (itr_data_type);
      while (iterator)
        {
          NodeId expression = fC->Sibling (iterator);
          if (expression)
            {
              stmt->addIteratorId (iterator, expression);
              iterator = fC->Sibling (expression);
            }
          else 
            {
               stmt->addIteratorId (iterator, 0);
               break;
            }
        }
    }
  
  
  if (for_step)
    {
      NodeId for_step_assignment = fC->Child (for_step);
      while (for_step_assignment)
        {
          NodeId incr = fC->Child (for_step_assignment);
          stmt->addIteratorStepId (incr);
          for_step_assignment = fC->Sibling (for_step_assignment);
        }
    }
  
  if (parentStmt)
    parentStmt->addStatement (stmt);
  compileScopeBody(parent, stmt, fC, statement_or_null);
    
  return true;
}

bool CompileHelper::compileScopeVariable (Scope* parent, FileContent* fC, NodeId id) {
  NodeId data_declaration = fC->Child(id);
  NodeId var_decl = fC->Child(data_declaration);
  VObjectType type = fC->Type (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 = parent->getUsedDataType (typeName);
          if (!datatype)
            {
              DataType* type = new DataType(fC, node_type, typeName, fC->Type(node_type));
              parent->insertUsedDataType (typeName, type);
              datatype = parent->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);
              VObjectType varType = fC->Type(var);
              NodeId range = fC->Sibling(var);
              if (varType == VObjectType::slList_of_arguments)
                {
                  // new ()
                }
              else 
                {
                  std::string varName = fC->SymName (var);

                  Variable* previous = parent->getVariable (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_VARIABLE, loc1, loc2);
                      m_errors->addError (err);
                    }

                  Variable* variable = new Variable(datatype, fC, var, range, varName);
                  parent->addVariable (variable);
                }
              
              variable_decl_assignment = fC->Sibling (variable_decl_assignment);
            }
        } 
      else if (var_type == VObjectType::slType_declaration)
        {
          // compile_type_declaration_(fC, var_decl);
        }
    }
  
  return true;
}

Function* CompileHelper::compileFunctionPrototype(DesignComponent* scope, FileContent* fC, NodeId id) {
   DataType* returnType = new DataType();
   std::string funcName;
  /*
  n<"DPI-C"> u<2> t<StringLiteral> p<15> s<3> l<3>
  n<> u<3> t<Context_keyword> p<15> s<14> l<3>
  n<> u<4> t<IntVec_TypeBit> p<5> l<3>
  n<> u<5> t<Data_type> p<6> c<4> l<3>
  n<> u<6> t<Function_data_type> p<14> c<5> s<7> l<3>
  n<SV2C_peek> u<7> t<StringConst> p<14> s<13> l<3>
  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<12> c<9> s<11> l<3>
  n<x_id> u<11> t<StringConst> p<12> l<3>
  n<> u<12> t<Tf_port_item> p<13> c<10> l<3>
  n<> u<13> t<Tf_port_list> p<14> c<12> l<3>
  n<> u<14> t<Function_prototype> p<15> c<6> l<3>
  n<> u<15> t<Dpi_import_export> p<16> c<2> l<3>
   */
   VObjectType type = fC->Type(id);
   
   if (type == VObjectType::slDpi_import_export)
     {
       NodeId dpiType = fC->Child(id);
       std::string stringtype;
 //      bool context = false;
 //      bool pure = false;
       if (fC->Type(dpiType) == VObjectType::slStringLiteral)
         {
           stringtype = fC->SymName(dpiType);
         }
       NodeId prop = fC->Sibling(dpiType);
       if (fC->Type(prop) == VObjectType::slContext_keyword)
         {
           //context = true;
           prop = fC->Sibling(prop);
         }
       if (fC->Type(prop) == VObjectType::slPure_keyword)
         {
           //pure = true;
           prop = fC->Sibling(prop);
         }
      NodeId func_prototype = prop;
      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 if (the_type == VObjectType::slClass_scope)
        {
          NodeId class_type = fC->Child (type);
          NodeId class_name = fC->Child (class_type);
          typeName = fC->SymName (class_name);
          typeName += "::";
          NodeId symb_id = fC->Sibling (type);
          typeName += fC->SymName (symb_id);
        }
      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);
      
     }
   
   Function* result = new Function(scope, fC, id, funcName, returnType);
   Variable* variable = new Variable(returnType, fC, id, 0, funcName);
   result->addVariable (variable);  
   result->compile (*this);
   return result;
}
