/* libsizzle/vector.h - vector function declarations
 
  Copyright (C) 2000 Martin Grabmueller <mgrabmue@cs.tu-berlin.de>
 
  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 this package; see the file COPYING.  If not, write to the
  Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
  MA 02111-1307, USA.  */

#ifndef __SIZZLE_VECTOR_H__
#define __SIZZLE_VECTOR_H__

#if HAVE_CONFIG_H
# include <config.h>
#endif 

#if __SIZZLE_IMPORT__
# define SIZZLE_API __declspec (dllimport)
#elif __SIZZLE_EXPORT__ 
# define SIZZLE_API __declspec (dllexport)
#else
# define SIZZLE_API
#endif

#include "node.h"

/* Discriminator and accessor macros for vectors and hash tables.  */
#define vector_p(c)    (tagged_p(c) && \
                        tagged_type(c) == zzz_tagged_type_vector)
#define ro_vector_p(c) (vector_p(c) && \
                        tagged_info(c) == tagged_info_ro)
#define vector_val(c)  (((zzz_scm_t *) tagged_data0(c)))
#define vector_len(c)  ((zzz_object_t) tagged_data1(c))

#define hashtable_p(c)    (tagged_p(c) && \
                           tagged_type(c) == zzz_tagged_type_hashtable)
#define ro_hashtable_p(c) (hashtable_p(c) && \
                           tagged_info(c) == tagged_info_ro)

/* Tagged types for vector and hash table objects.  */
SIZZLE_API extern zzz_object_t zzz_tagged_type_vector;
SIZZLE_API extern zzz_object_t zzz_tagged_type_hashtable;

/* Accessor macros for the elements of a vector.  */
#if 1
#define zzz_vector_put(vector, index, elem)  vector_val (vector)[index] = elem
#define zzz_vector_get(vector, index)        vector_val (vector)[index]
#endif

/* Put the object @var{elem} into the vector @var{vector} at position
   @var{index}, overwriting the old contents.  */
#ifndef zzz_vector_put
SIZZLE_API void zzz_vector_put (zzz_scm_t vector, unsigned long index,
			       zzz_scm_t elem);
#endif /* !defined (zzz_vector_put) */

/* Get the element at index @var{index} from the vector @var{vector}.  */
#ifndef zzz_vector_get
SIZZLE_API zzz_scm_t zzz_vector_get (zzz_scm_t vector, unsigned long index);
#endif /* !defined (zzz_vector_get) */

/* Create a vector object holding @var{len} objects.  */
SIZZLE_API zzz_scm_t zzz_make_vector (int len);

/* Create a constant vector object holding @var{len} objects.  Vectors
   created using this function cannot be modified using Scheme
   primitives like @code{vector-set!}.  */
SIZZLE_API zzz_scm_t zzz_make_ro_vector (int len);

/* Create a hashtable object with @var{len} buckets.  */
SIZZLE_API zzz_scm_t zzz_make_hashtable (int len);

/* Create a constant hash table object with @var{len} buckets.  Hash tables
   created using this function cannot be modified using Scheme
   primitives like @code{hashq-set!}.  */
SIZZLE_API zzz_scm_t zzz_make_ro_hashtable (int len);

/* First init function for the vector module.  Only defines the vector
   type.  This must be called before various other init functions and
   before the symbol table is created, because the symbol and other
   tables are represented as vectors.  */
SIZZLE_API result_t zzz_init_vector_type (void);

/* Second init function for the vector module.  Defines all Scheme
   primitives for dealing with vector objects.  This must be called
   after @code{zzz_init_vector_type()}.  */
SIZZLE_API result_t zzz_init_vector (void);

#if 0
/* Finalize function for the vector module.  This is needed because
   vectors used in environments are cached in order to speed up
   environment creation and deletion.  */
SIZZLE_API result_t zzz_finalize_vector (void);
#endif

#endif /* not __SIZZLE_VECTOR_H__ */
