/******************************** -*- C -*- ****************************
 *
 *	Public definitions for extensions to Smalltalk.
 *
 *
 ***********************************************************************/


/***********************************************************************
 *
 * Copyright 1988,89,90,91,92,94,95,99,2000,2001,2002,2006
 * Free Software Foundation, Inc.
 * Written by Steve Byrne and Paolo Bonzini.
 *
 * This file is part of GNU Smalltalk.
 *
 * GNU Smalltalk 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.
 * 
 * Linking GNU Smalltalk statically or dynamically with other modules is
 * making a combined work based on GNU Smalltalk.  Thus, the terms and
 * conditions of the GNU General Public License cover the whole
 * combination.
 *
 * In addition, as a special exception, the Free Software Foundation
 * give you permission to combine GNU Smalltalk with free software
 * programs or libraries that are released under the GNU LGPL and with
 * independent programs running under the GNU Smalltalk virtual machine.
 *
 * You may copy and distribute such a system following the terms of the
 * GNU GPL for GNU Smalltalk and the licenses of the other code
 * concerned, provided that you include the source code of that other
 * code when and as the GNU GPL requires distribution of source code.
 *
 * Note that people who make modified versions of GNU Smalltalk are not
 * obligated to grant this special exception for their modified
 * versions; it is their choice whether to do so.  The GNU General
 * Public License gives permission to release a modified version without
 * this exception; this exception also makes it possible to release a
 * modified version which carries forward this exception.
 *
 * GNU Smalltalk 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 Smalltalk; see the file COPYING.  If not, write to the Free Software
 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  
 *
 ***********************************************************************/


#ifndef GST_GSTPUB_H
#define GST_GSTPUB_H

/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */
#if defined(c_plusplus) && !defined(__cplusplus)
#define __cplusplus c_plusplus
#endif

#ifdef __cplusplus
#include <cstddef>
extern "C"
{
#else

#include <stddef.h>
#endif

#include "gst.h"

#ifndef __PROTO
# ifndef __STDC__
#  define __PROTO(args) ()
# else
#  define __PROTO(args) args
# endif
#endif

typedef struct VMProxy
{
  OOP nilOOP, trueOOP, falseOOP;

  OOP (*msgSend) __PROTO ((OOP receiver,
			   OOP selector, 
			   ...));
  OOP (*vmsgSend) __PROTO ((OOP receiver,
			    OOP selector,
			    OOP * args));
  OOP (*nvmsgSend) __PROTO ((OOP receiver,
			     OOP selector,
			     OOP * args,
			     int nargs));
    
  OOP (*strMsgSend) __PROTO ((OOP receiver,
			      const char * selector,
			      ...));
  void (*msgSendf) __PROTO ((PTR resultPtr,
			     const char *fmt,
			     ...));
  OOP (*evalExpr) __PROTO ((const char *str));
  void (*evalCode) __PROTO ((const char *str));

  OOP (*objectAlloc) __PROTO ((OOP classOOP,
			       int size));
  int (*basicSize) __PROTO ((OOP oop));
  
  /* Actually funcAddr is a function pointer, but we don't know the
     returned type so we must declare it as PTR */
  void (*defineCFunc) __PROTO ((const char *funcName,
				PTR funcAddr));
  OOP (*registerOOP) __PROTO ((OOP oop));
  void (*unregisterOOP) __PROTO ((OOP oop));

  /* Convert C datatypes to Smalltalk types */
  
  OOP (*idToOOP) __PROTO ((long i));
  OOP (*intToOOP) __PROTO ((long i));
  OOP (*floatToOOP) __PROTO ((double f));
  OOP (*boolToOOP) __PROTO ((int b));
  OOP (*charToOOP) __PROTO ((char c));
  OOP (*classNameToOOP) __PROTO ((const char *name));
  OOP (*stringToOOP) __PROTO ((const char *str));
  OOP (*byteArrayToOOP) __PROTO ((const char *str,
				  int n));
  OOP (*symbolToOOP) __PROTO ((const char *str));
  OOP (*cObjectToOOP) __PROTO ((PTR co));
  OOP (*typeNameToOOP) __PROTO ((const char *name));
  void (*setCObject) __PROTO ((OOP oop, PTR co));

  /* Convert Smalltalk datatypes to C data types */

  long (*OOPToC) __PROTO ((OOP oop));	/* sometimes answers a PTR */
  long (*OOPToId) __PROTO ((OOP oop));
  long (*OOPToInt) __PROTO ((OOP oop));
  double (*OOPToFloat) __PROTO ((OOP oop));
  int (*OOPToBool) __PROTO ((OOP oop));
  char (*OOPToChar) __PROTO ((OOP oop));
  char *(*OOPToString) __PROTO ((OOP oop));
  char *(*OOPToByteArray) __PROTO ((OOP oop));
  PTR (*OOPToCObject) __PROTO ((OOP oop));

  /* Smalltalk process support */
  void (*asyncSignal) __PROTO ((OOP semaphoreOOP));
  void (*syncWait) __PROTO ((OOP semaphoreOOP));
  void (*asyncSignalAndUnregister) __PROTO ((OOP semaphoreOOP));

  /* Array-of-OOP registry support.  Move these above
     when we break binary compatibility.  */
  void (*registerOOPArray) __PROTO ((OOP **first, OOP **last));
  void (*unregisterOOPArray) __PROTO ((OOP **first));

  /* More conversions.  */
  long double (*OOPToLongDouble) __PROTO ((OOP oop));
  OOP (*longDoubleToOOP) __PROTO ((long double f));

  /* More functions, added in 2.2.  */
  OOP (*getObjectClass) __PROTO ((OOP oop));
  OOP (*getSuperclass) __PROTO ((OOP oop));
  mst_Boolean (*classIsKindOf) __PROTO ((OOP oop, OOP candidate));
  mst_Boolean (*objectIsKindOf) __PROTO ((OOP oop, OOP candidate));
  OOP (*perform) __PROTO ((OOP oop, OOP selector));
  OOP (*performWith) __PROTO ((OOP oop, OOP selector, OOP arg));
  mst_Boolean (*classImplementsSelector) __PROTO ((OOP classOOP, OOP selector));
  mst_Boolean (*classCanUnderstand) __PROTO ((OOP classOOP, OOP selector));
  mst_Boolean (*respondsTo) __PROTO ((OOP oop, OOP selector));
  size_t (*OOPSize) __PROTO ((OOP oop));
  OOP (*OOPAt) __PROTO ((OOP oop, size_t index));
  OOP (*OOPAtPut) __PROTO ((OOP oop, size_t index, OOP newOOP));

  /* Some system classes.  */
  OOP objectClass, arrayClass, stringClass, characterClass, smallIntegerClass,
    floatDClass, floatEClass, byteArrayClass, objectMemoryClass, classClass,
    behaviorClass, blockClosureClass, contextPartClass, blockContextClass,
    methodContextClass, compiledMethodClass, compiledBlockClass,
    fileDescriptorClass, fileStreamClass, processClass, semaphoreClass,
    cObjectClass;

  /* More system objects.  */
  OOP processorOOP;

  /* More functions, added in 2.3.  */
  OOP (*wcharToOOP) __PROTO ((wchar_t wc));
  OOP (*wstringToOOP) __PROTO ((const wchar_t *str));
  wchar_t (*OOPToWChar) __PROTO ((OOP oop));
  wchar_t *(*OOPToWString) __PROTO ((OOP oop));
} VMProxy;

#define INDEXED_WORD(obj, n)   ( ((long *) ((obj) + 1))		    [(n)-1] )
#define INDEXED_BYTE(obj, n)   ( ((char *) ((obj) + 1))		    [(n)-1] )
#define INDEXED_OOP(obj, n)    ( ((OOP  *) ((obj) + 1))		    [(n)-1] )
#define ARRAY_OOP_AT(obj, n)   ( ((OOP  *) ((gst_object) obj)->data) [(n)-1] )
#define STRING_OOP_AT(obj, n)  ( ((char *) ((gst_object) obj)->data) [(n)-1] )

/* Compatibility section */
#define indexedWord(obj, n)   INDEXED_WORD(obj, n)
#define indexedByte(obj, n)   INDEXED_BYTE(obj, n)
#define indexedOOP(obj, n)    INDEXED_OOP(obj, n)
#define arrayOOPAt(obj, n)    ARRAY_OOP_AT(obj, n)
#define stringOOPAt(obj, n)   STRING_OOP_AT(obj, n)
#define oopToObj(oop)         OOP_TO_OBJ(oop)
#define oopClass(oop)         OOP_CLASS(oop)
#define isInt(oop)            IS_INT(oop)
#define isOOP(oop)            IS_OOP(oop)

/* These are extern in case one wants to link to libgst.a; these
   are not meant to be called by a module, which is brought up by
   GNU Smalltalk when the VM is already up and running.  */

/* This loads the image and prepares the Smalltalk environment.
   Return -1 if the Smalltalk main loop should not be run but
   without returning an erroneous exit code, 0 if it should be
   run, and >0 if there was an error (such as the inability
   to bootstrap).  */
extern int gst_init_smalltalk __PROTO ((void));

/* This sets the arguments to be passed to the Smalltalk library,
   which are the same that are available by the `gst' executable.  */
extern void gst_smalltalk_args __PROTO ((int argc,
					 const char **argv));

/* This processes files passed to gst_smalltalk_args and, if none
   was passed, stdin is looked for input.  */
extern void gst_top_level_loop __PROTO ((void));

/* This is exclusively for programs who link with libgst.a; plugins
   should not use this VMProxy but rather the one they receive in
   gst_initModule.  */
extern VMProxy gst_interpreter_proxy;

#ifdef __cplusplus
}
#endif

#undef __PROTO

#endif /* GST_GSTPUB_H */
