/*
   FILE NAME:   sprut-ird.c

   Copyright (C) 1997-2007 Vladimir Makarov.

   Written by Vladimir Makarov <vmakarov@users.sourceforge.net>

   This file is part of the tool SPRUT.

   This is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This software is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with GNU CC; see the file COPYING.  If not, write to the Free
   Software Foundation, 59 Temple Place - Suite 330, Boston, MA
   02111-1307, USA.

   TITLE:       Implementation file of standard procedural interface (SPI)
                of internal representation for SPRUT (internal representation
                description translator) itself

   DESCRIPTION: This file is created manually and contains
                variables and functions which are standard procedural
                interface (SPI -- see documentation of SPRUT) for internal
                representation of SPRUT itself.

   SPECIAL CONSIDERATION:
         This file is created manually and defines SPI analogous to
       part of SPI generated automatically by SPRUT itself from file
       `ird.sprut'.  The important difference is absence of abstract node
       types which are used in file `ird.sprut' for convenience.
   
*/

#ifdef HAVE_CONFIG_H
#include "cocom-config.h"
#else /* In this case we are oriented to ANSI C */
#ifndef HAVE_MEMCPY
#define HAVE_MEMCPY
#endif
#ifndef HAVE_MEMSET
#define HAVE_MEMSET
#endif
#endif /* #ifdef HAVE_CONFIG_H */

#include <stdlib.h>
#include <string.h>
#include "ird.h"

#ifndef HAVE_MEMCPY

static void *
memcpy (void *to, const void *from, size_t size)
{
  char *cto = (char *) to;
  const char *cfrom = (const char *) from;

  while (size > 0)
    {
      *cto++ = *cfrom;
      size--;
    }
  return to;
}

#endif /* #ifndef HAVE_MEMCPY */

#ifndef HAVE_MEMSET

static void *
memset (void *to, int value, size_t size)
{
  char *cto  = (char *) to;

  while (size > 0)
    {
      *cto++ = value;
      size--;
    }
  return to;
}

#endif /* #ifndef HAVE_MEMSET */



/* All internal representation storage is implemented by object stack.  See
   package `object-stack'. */

os_t irp;

/* This variable is array mapping values of type `IR_node_mode_t' to
   size of corresponding structures on C. */

int IR_node_size [] =
{
  sizeof (_root_node),
  sizeof (_error_node),
  sizeof (identifier_node),
  sizeof (double_declaration_node),
  sizeof (code_insertion_node),
  sizeof (expression_node),
  sizeof (local_code_node),
  sizeof (import_code_node),
  sizeof (export_code_node),
  sizeof (constraint_node),
  sizeof (action_node),
  sizeof (field_node),
  sizeof (node_type_node),
  sizeof (super_type_list_element_node),
  sizeof (predefined_type_node),
  sizeof (additional_code_node),
  sizeof (description_part_node)
};

/* The following function initiates internal representation storage
   management.  The function is an analog of function `IR_start'
   generated by SPRUT (see SPRUT documentation).  This function is to be
   called before any work with internal representation. */

void
IR_start (void)
{
  IR_START_ALLOC ();
}

/* The folowing function finishes internal representation storage
   management.  The function is an analog of function `IR_stop'
   generated by SPRUT (see SPRUT documentation).  The call of this
   function is to be last. */

void
IR_stop (void)
{
  IR_STOP_ALLOC ();
}

/* This function allocates storage for node of given mode, sets up
   node mode make zeroing all fields of the node.  The function is an
   analog of function `IR_create_node' generated by SPRUT (see SPRUT
   documentation).  The function returns created node. */

IR_node_t
IR_create_node (IR_node_mode_t node_mode)
{
  IR_node_t result;

  IR_ALLOC (result, IR_node_size [node_mode], IR_node_t);
  memset (result, '\0', IR_node_size [node_mode]);
  IR_NODE_MODE (result) = node_mode;
  return result;
}

/* This function makes copy of given node.  The function is an analog
   of function `IR_copy_node' generated by SPRUT (see SPRUT
   documentation).  The function returns new copied node or NULL if
   the parameter value is equal to NULL. */

IR_node_t
IR_copy_node (IR_node_t node)
{
  IR_node_t result;
  IR_node_mode_t node_mode;

  if (node == NULL)
    return NULL;
  node_mode = IR_NODE_MODE (node);
  result = IR_create_node (node_mode);
  (void) memcpy (result, node, IR_node_size [node_mode]);
  return result;
}
