/*
  MzScheme
  Copyright (c) 2004 PLT Scheme, Inc.
  Copyright (c) 1995-2001 Matthew Flatt
  All rights reserved.

  Please see the full copyright in the documentation.

  Originally based on:
  libscheme
  Copyright (c) 1994 Brent Benson
  All rights reserved.
*/

/* MzScheme function prototypes */
/* Macros generally shouldn't go in this file; it is used both to
   prototype functions, and as a parsing source for
   declaring scheme_extension_table */

/* The scheme_extension_table "parser" is picky; don't leave a space
   between a function name and it's opening parameter parenthesis. */

/* After this START tag, all comments should start & end on same line */

/* START */

/*========================================================================*/
/*                       setjmpup (continuations)                         */
/*========================================================================*/

MZ_EXTERN void scheme_init_jmpup_buf(Scheme_Jumpup_Buf *b);
MZ_EXTERN int scheme_setjmpup_relative(Scheme_Jumpup_Buf *b, void *base,
				       void * volatile start, Scheme_Jumpup_Buf *cont);
MZ_EXTERN void scheme_longjmpup(Scheme_Jumpup_Buf *b);
MZ_EXTERN void scheme_reset_jmpup_buf(Scheme_Jumpup_Buf *b);

#ifdef USE_MZ_SETJMP
MZ_EXTERN int scheme_mz_setjmp(mz_pre_jmp_buf b);
MZ_EXTERN void scheme_mz_longjmp(mz_pre_jmp_buf b, int v);
#endif

MZ_EXTERN void scheme_clear_escape(void);

MZ_EXTERN Scheme_Jumpup_Buf_Holder *scheme_new_jmpupbuf_holder(void);

/*========================================================================*/
/*                                parameters                              */
/*========================================================================*/

MZ_EXTERN Scheme_Object *scheme_make_config(Scheme_Config *base);
MZ_EXTERN Scheme_Object *scheme_branch_config(void);
MZ_EXTERN int scheme_new_param(void);

MZ_EXTERN Scheme_Object *scheme_param_config(char *name, Scheme_Object *pos,
					     int argc, Scheme_Object **argv,
					     int arity,
					     Scheme_Prim *check, char *expected,
					     int isbool);
MZ_EXTERN Scheme_Object *scheme_register_parameter(Scheme_Prim *function, char *name, int which);
MZ_EXTERN Scheme_Env *scheme_get_env(Scheme_Config *config);

/*========================================================================*/
/*                                threads                                 */
/*========================================================================*/

#ifndef LINK_EXTENSIONS_BY_TABLE
MZ_EXTERN Scheme_Thread *scheme_current_thread;
MZ_EXTERN volatile int scheme_fuel_counter;
#else
MZ_EXTERN Scheme_Thread **scheme_current_thread_ptr;
MZ_EXTERN volatile int *scheme_fuel_counter_ptr;
#endif

MZ_EXTERN void scheme_out_of_fuel(void);

MZ_EXTERN Scheme_Object *scheme_thread(Scheme_Object *thunk, Scheme_Config *config);
MZ_EXTERN Scheme_Object *scheme_thread_w_custodian(Scheme_Object *thunk, Scheme_Config *config,
						   Scheme_Custodian *mgr);
MZ_EXTERN Scheme_Object *scheme_thread_w_custodian_killkind(Scheme_Object *thunk, Scheme_Config *config,
							    Scheme_Custodian *mgr, int normal_kill);
MZ_EXTERN void scheme_kill_thread(Scheme_Thread *p);
MZ_EXTERN void scheme_break_thread(Scheme_Thread *p);

MZ_EXTERN void scheme_thread_block(float sleep_time);
MZ_EXTERN void scheme_swap_thread(Scheme_Thread *process);
MZ_EXTERN void scheme_making_progress();

MZ_EXTERN void scheme_weak_suspend_thread(Scheme_Thread *p);
MZ_EXTERN void scheme_weak_resume_thread(Scheme_Thread *p);

MZ_EXTERN int scheme_block_until(Scheme_Ready_Fun f, Scheme_Needs_Wakeup_Fun, Scheme_Object *, float);

MZ_EXTERN int scheme_in_main_thread(void);

MZ_EXTERN void scheme_cancel_sleep(void);

MZ_EXTERN int scheme_tls_allocate();
MZ_EXTERN void scheme_tls_set(int pos, void *v);
MZ_EXTERN void *scheme_tls_get(int pos);

MZ_EXTERN Scheme_Custodian *scheme_make_custodian(Scheme_Custodian *);
MZ_EXTERN Scheme_Custodian_Reference *scheme_add_managed(Scheme_Custodian *m, Scheme_Object *o,
							 Scheme_Close_Custodian_Client *f, void *data,
							 int strong);
MZ_EXTERN void scheme_custodian_check_available(Scheme_Custodian *m, const char *who, const char *what);
MZ_EXTERN void scheme_remove_managed(Scheme_Custodian_Reference *m, Scheme_Object *o);
MZ_EXTERN void scheme_close_managed(Scheme_Custodian *m);
MZ_EXTERN void scheme_schedule_custodian_close(Scheme_Custodian *c);
MZ_EXTERN void scheme_add_custodian_extractor(Scheme_Type t, Scheme_Custodian_Extractor e);

MZ_EXTERN void scheme_add_atexit_closer(Scheme_Exit_Closer_Func f);

MZ_EXTERN void scheme_add_waitable(Scheme_Type type,
				   Scheme_Ready_Fun ready,
				   Scheme_Needs_Wakeup_Fun wakeup,
				   Scheme_Wait_Filter_Fun filter,
				   int can_redirect);
MZ_EXTERN void scheme_add_waitable_through_sema(Scheme_Type type,
						Scheme_Wait_Sema_Fun sema,
						Scheme_Wait_Filter_Fun filter);
MZ_EXTERN int scheme_is_waitable(Scheme_Object *o);
MZ_EXTERN Scheme_Object *scheme_object_wait_multiple(int argc, Scheme_Object *argv[]);
MZ_EXTERN Scheme_Object *scheme_object_wait_multiple_enable_break(int argc, Scheme_Object *argv[]);

MZ_EXTERN Scheme_Object *scheme_make_waitable_set(int argc, Scheme_Object **argv);

MZ_EXTERN void scheme_add_swap_callback(Scheme_Closure_Func f, Scheme_Object *data);

MZ_EXTERN Scheme_Object *scheme_call_enable_break(Scheme_Prim *prim, int argc, Scheme_Object *argv[]);
MZ_EXTERN int scheme_close_should_force_port_closed();

MZ_EXTERN void scheme_push_kill_action(Scheme_Kill_Action_Func f, void *d);
MZ_EXTERN void scheme_pop_kill_action();

/*========================================================================*/
/*                              error handling                            */
/*========================================================================*/

MZ_EXTERN void scheme_signal_error(const char *msg, ...);
MZ_EXTERN void scheme_raise_exn(int exnid, ...);
MZ_EXTERN void scheme_warning(char *msg, ...);

MZ_EXTERN void scheme_raise(Scheme_Object *exn);

MZ_EXTERN void scheme_wrong_count(const char *name, int minc, int maxc,
				  int argc, Scheme_Object **argv);
MZ_EXTERN void scheme_wrong_count_m(const char *name, int minc, int maxc,
				    int argc, Scheme_Object **argv,
				    int is_method);
MZ_EXTERN void scheme_case_lambda_wrong_count(const char *name, int argc,
					      Scheme_Object **argv, int is_method, int count, ...);
MZ_EXTERN void scheme_wrong_type(const char *name, const char *expected,
				 int which, int argc,
				 Scheme_Object **argv);
MZ_EXTERN void scheme_arg_mismatch(const char *name, const char *msg, Scheme_Object *o);
MZ_EXTERN void scheme_wrong_return_arity(const char *where,
					 int expected, int got,
					 Scheme_Object **argv,
					 const char *context_detail, ...);
MZ_EXTERN void scheme_unbound_global(Scheme_Bucket *b);

MZ_EXTERN Scheme_Object *scheme_dynamic_wind(void (*pre)(void *),
					     Scheme_Object *(* volatile act)(void *),
					     void (* volatile post)(void *),
					     Scheme_Object *(*jmp_handler)(void *),
					     void * volatile data);

/*========================================================================*/
/*                                 types                                  */
/*========================================================================*/

MZ_EXTERN Scheme_Type scheme_make_type(const char *name);

MZ_EXTERN char *scheme_get_type_name(Scheme_Type type);

/*========================================================================*/
/*                              constants                                 */
/*========================================================================*/

MZ_EXTERN Scheme_Object scheme_eof[1];
MZ_EXTERN Scheme_Object *scheme_make_eof(void);
MZ_EXTERN Scheme_Object scheme_null[1];
MZ_EXTERN Scheme_Object *scheme_make_null(void);
MZ_EXTERN Scheme_Object scheme_true[1];
MZ_EXTERN Scheme_Object *scheme_make_true(void);
MZ_EXTERN Scheme_Object scheme_false[1];
MZ_EXTERN Scheme_Object *scheme_make_false(void);
MZ_EXTERN Scheme_Object scheme_void[1];
MZ_EXTERN Scheme_Object *scheme_make_void(void);
MZ_EXTERN Scheme_Object scheme_undefined[1];
MZ_EXTERN Scheme_Object *scheme_tail_call_waiting;
MZ_EXTERN Scheme_Object *scheme_multiple_values;

/*========================================================================*/
/*                              evaluation                                */
/*========================================================================*/

MZ_EXTERN Scheme_Object *scheme_eval(Scheme_Object *obj, Scheme_Env *env);
MZ_EXTERN Scheme_Object *scheme_eval_multi(Scheme_Object *obj, Scheme_Env *env);

MZ_EXTERN Scheme_Object *scheme_eval_compiled(Scheme_Object *obj, Scheme_Env *env);
MZ_EXTERN Scheme_Object *scheme_eval_compiled_multi(Scheme_Object *obj, Scheme_Env *env);
MZ_EXTERN Scheme_Object *_scheme_eval_compiled(Scheme_Object *obj, Scheme_Env *env);
MZ_EXTERN Scheme_Object *_scheme_eval_compiled_multi(Scheme_Object *obj, Scheme_Env *env);

MZ_EXTERN Scheme_Object *scheme_apply(Scheme_Object *rator, int num_rands, Scheme_Object **rands);
MZ_EXTERN Scheme_Object *scheme_apply_multi(Scheme_Object *rator, int num_rands, Scheme_Object **rands);
MZ_EXTERN Scheme_Object *scheme_apply_eb(Scheme_Object *rator, int num_rands, Scheme_Object **rands);
MZ_EXTERN Scheme_Object *scheme_apply_multi_eb(Scheme_Object *rator, int num_rands, Scheme_Object **rands);
MZ_EXTERN Scheme_Object *scheme_apply_to_list(Scheme_Object *rator, Scheme_Object *argss);
MZ_EXTERN Scheme_Object *scheme_eval_string(const char *str, Scheme_Env *env);
MZ_EXTERN Scheme_Object *scheme_eval_string_multi(const char *str, Scheme_Env *env);
MZ_EXTERN Scheme_Object *scheme_eval_string_all(const char *str, Scheme_Env *env, int all);

MZ_EXTERN Scheme_Object *_scheme_apply_known_closed_prim(Scheme_Object *rator, int argc,
					       Scheme_Object **argv);
MZ_EXTERN Scheme_Object *_scheme_apply_known_closed_prim_multi(Scheme_Object *rator, int argc,
						     Scheme_Object **argv);
MZ_EXTERN Scheme_Object *_scheme_apply_closed_prim(Scheme_Object *rator, int argc,
					 Scheme_Object **argv);
MZ_EXTERN Scheme_Object *_scheme_apply_closed_prim_multi(Scheme_Object *rator, int argc,
					       Scheme_Object **argv);

MZ_EXTERN Scheme_Object *scheme_values(int c, Scheme_Object **v);

MZ_EXTERN Scheme_Object *scheme_check_one_value(Scheme_Object *v);

/* Tail calls - only use these when you're writing new functions/syntax */
MZ_EXTERN Scheme_Object *scheme_tail_apply(Scheme_Object *f, int n, Scheme_Object **arg);
MZ_EXTERN Scheme_Object *scheme_tail_apply_no_copy(Scheme_Object *f, int n, Scheme_Object **arg);
MZ_EXTERN Scheme_Object *scheme_tail_apply_to_list(Scheme_Object *f, Scheme_Object *l);

MZ_EXTERN Scheme_Object *scheme_tail_eval_expr(Scheme_Object *obj);

MZ_EXTERN void scheme_set_tail_buffer_size(int s);
MZ_EXTERN Scheme_Object *scheme_force_value(Scheme_Object *);

MZ_EXTERN void scheme_set_cont_mark(Scheme_Object *key, Scheme_Object *val);
MZ_EXTERN void scheme_push_continuation_frame(Scheme_Cont_Frame_Data *);
MZ_EXTERN void scheme_pop_continuation_frame(Scheme_Cont_Frame_Data *);
MZ_EXTERN void scheme_temp_dec_mark_depth();
MZ_EXTERN void scheme_temp_inc_mark_depth();

MZ_EXTERN Scheme_Object *scheme_current_continuation_marks(void);

/* Internal */
MZ_EXTERN Scheme_Object *scheme_do_eval(Scheme_Object *obj, int _num_rands, Scheme_Object **rands, int val);

MZ_EXTERN Scheme_Object *scheme_eval_compiled_stx_string(Scheme_Object *expr, Scheme_Env *env,
							 long shift, Scheme_Object *modidx);
MZ_EXTERN Scheme_Object *scheme_load_compiled_stx_string(const char *str, long len);
MZ_EXTERN Scheme_Object *scheme_compiled_stx_symbol(Scheme_Object *stx);

MZ_EXTERN Scheme_Object *scheme_eval_compiled_sized_string(const char *str, int len, Scheme_Env *env);

/*========================================================================*/
/*                           memory management                            */
/*========================================================================*/

/* The core allocator functions depend on the GC. Macros in scheme.h */
/*  map to the apporpriate core allocation function. */

#ifndef SCHEME_NO_GC
# ifndef SCHEME_NO_GC_PROTO
MZ_EXTERN void *GC_malloc(size_t size_in_bytes);
MZ_EXTERN void *GC_malloc_atomic(size_t size_in_bytes);
#  ifdef MZ_PRECISE_GC
MZ_EXTERN void *GC_malloc_one_tagged(size_t size_in_bytes);
MZ_EXTERN void *GC_malloc_atomic_uncollectable(size_t size_in_bytes);
MZ_EXTERN void *GC_malloc_array_tagged(size_t size_in_bytes);
#  else
MZ_EXTERN void *GC_malloc_stubborn(size_t size_in_bytes);
MZ_EXTERN void *GC_malloc_uncollectable(size_t size_in_bytes);
#  endif
# endif
#endif

MZ_EXTERN void *scheme_malloc_eternal(size_t n);
MZ_EXTERN void scheme_end_stubborn_change(void *p);

MZ_EXTERN void *scheme_calloc(size_t num, size_t size);

MZ_EXTERN char *scheme_strdup(const char *str);
MZ_EXTERN char *scheme_strdup_eternal(const char *str);

MZ_EXTERN void *scheme_malloc_fail_ok(void *(*f)(size_t), size_t);

#ifndef MZ_PRECISE_GC
MZ_EXTERN void scheme_weak_reference(void **p);
MZ_EXTERN void scheme_weak_reference_indirect(void **p, void *v);
MZ_EXTERN void scheme_unweak_reference(void **p);
#endif
MZ_EXTERN void scheme_add_finalizer(void *p, void (*f)(void *p, void *data), void *data);
MZ_EXTERN void scheme_add_finalizer_once(void *p, void (*f)(void *p, void *data), void *data);
MZ_EXTERN void scheme_add_scheme_finalizer(void *p, void (*f)(void *p, void *data), void *data);
MZ_EXTERN void scheme_add_scheme_finalizer_once(void *p, void (*f)(void *p, void *data), void *data);
MZ_EXTERN void scheme_register_finalizer(void *p,
					 void (*f)(void *p, void *data), void *data,
					 void (**oldf)(void *p, void *data),
					 void **olddata);
MZ_EXTERN void scheme_remove_all_finalization(void *p);

MZ_EXTERN void scheme_dont_gc_ptr(void *p);
MZ_EXTERN void scheme_gc_ptr_ok(void *p);

MZ_EXTERN void scheme_collect_garbage(void);

#ifdef MZ_PRECISE_GC
MZ_EXTERN void **GC_variable_stack;
MZ_EXTERN void GC_register_traversers(short tag, Size_Proc size, Mark_Proc mark, Fixup_Proc fixup,
				      int is_constant_size, int is_atomic);
MZ_EXTERN void *GC_resolve(void *p);
MZ_EXTERN void GC_mark(const void *p);
MZ_EXTERN void GC_fixup(void *p);
#endif

/*========================================================================*/
/*                             hash tables                                */
/*========================================================================*/

MZ_EXTERN Scheme_Bucket_Table *scheme_make_bucket_table(int size_hint, int type);
MZ_EXTERN void scheme_add_to_table(Scheme_Bucket_Table *table, const char *key, void *val, int);
MZ_EXTERN void scheme_change_in_table(Scheme_Bucket_Table *table, const char *key, void *new_val);
MZ_EXTERN void *scheme_lookup_in_table(Scheme_Bucket_Table *table, const char *key);
MZ_EXTERN Scheme_Bucket *scheme_bucket_from_table(Scheme_Bucket_Table *table, const char *key);
MZ_EXTERN int scheme_bucket_table_equal(Scheme_Bucket_Table *t1, Scheme_Bucket_Table *t2);

MZ_EXTERN Scheme_Hash_Table *scheme_make_hash_table(int type);
MZ_EXTERN Scheme_Hash_Table *scheme_make_hash_table_equal();
MZ_EXTERN void scheme_hash_set(Scheme_Hash_Table *table, Scheme_Object *key, Scheme_Object *val);
MZ_EXTERN Scheme_Object *scheme_hash_get(Scheme_Hash_Table *table, Scheme_Object *key);
MZ_EXTERN int scheme_hash_table_equal(Scheme_Hash_Table *t1, Scheme_Hash_Table *t2);
MZ_EXTERN int scheme_is_hash_table_equal(Scheme_Object *o);

/*========================================================================*/
/*                   basic Scheme value constructors                      */
/*========================================================================*/

MZ_EXTERN Scheme_Object *scheme_make_prim(Scheme_Prim *prim);
MZ_EXTERN Scheme_Object *scheme_make_noneternal_prim(Scheme_Prim *prim);
MZ_EXTERN Scheme_Object *scheme_make_closed_prim(Scheme_Closed_Prim *prim, void *data);
MZ_EXTERN Scheme_Object *scheme_make_prim_w_arity(Scheme_Prim *prim, const char *name,
					mzshort mina, mzshort maxa);
MZ_EXTERN Scheme_Object *scheme_make_folding_prim(Scheme_Prim *prim,
					const char *name,
					mzshort mina, mzshort maxa,
					short functional);
MZ_EXTERN Scheme_Object *scheme_make_noneternal_prim_w_arity(Scheme_Prim *prim,
						   const char *name,
						   mzshort mina, mzshort maxa);
MZ_EXTERN Scheme_Object *scheme_make_closed_prim_w_arity(Scheme_Closed_Prim *prim,
					       void *data, const char *name,
					       mzshort mina, mzshort maxa);
MZ_EXTERN Scheme_Object *scheme_make_folding_closed_prim(Scheme_Closed_Prim *prim,
					       void *data, const char *name,
					       mzshort mina, mzshort maxa,
					       short functional);
MZ_EXTERN Scheme_Object *scheme_make_prim_w_everything(Scheme_Prim *fun, int eternal,
						       const char *name,
						       mzshort mina, mzshort maxa,
						       short folding,
						       mzshort minr, mzshort maxr);
MZ_EXTERN Scheme_Object *scheme_make_closed_prim_w_everything(Scheme_Closed_Prim *fun,
							      void *data,
							      const char *name,
							      mzshort mina, mzshort maxa,
							      short folding,
							      mzshort minr, mzshort maxr);

MZ_EXTERN void scheme_prim_is_method(Scheme_Object *o);

MZ_EXTERN Scheme_Object *scheme_make_pair(Scheme_Object *car, Scheme_Object *cdr);
MZ_EXTERN Scheme_Object *scheme_make_immutable_pair(Scheme_Object *car, Scheme_Object *cdr);
MZ_EXTERN Scheme_Object *scheme_make_string(const char *chars);
MZ_EXTERN Scheme_Object *scheme_make_sized_string(char *chars, long len, int copy);
MZ_EXTERN Scheme_Object *scheme_make_sized_offset_string(char *chars, long d, long len, int copy);
MZ_EXTERN Scheme_Object *scheme_make_immutable_sized_string(char *chars, long len, int copy);
MZ_EXTERN Scheme_Object *scheme_make_string_without_copying(char *chars);
MZ_EXTERN Scheme_Object *scheme_alloc_string(int size, char fill);
MZ_EXTERN Scheme_Object *scheme_append_string(Scheme_Object *, Scheme_Object *);
MZ_EXTERN Scheme_Object *scheme_make_vector(int size, Scheme_Object *fill);
MZ_EXTERN Scheme_Object *scheme_make_integer_value(long i);
MZ_EXTERN Scheme_Object *scheme_make_integer_value_from_unsigned(unsigned long i);
MZ_EXTERN Scheme_Object *scheme_make_integer_value_from_long_long(unsigned long lowhalf, unsigned long hihalf);
MZ_EXTERN Scheme_Object *scheme_make_integer_value_from_unsigned_long_long(unsigned long lowhalf, unsigned long hihalf);
MZ_EXTERN Scheme_Object *scheme_make_double(double d);
#ifdef MZ_USE_SINGLE_FLOATS
MZ_EXTERN Scheme_Object *scheme_make_float(float f) ;
#endif
MZ_EXTERN Scheme_Object *scheme_make_char(char ch);
MZ_EXTERN Scheme_Object *scheme_make_sema(long v);
MZ_EXTERN void scheme_post_sema(Scheme_Object *o);
MZ_EXTERN void scheme_post_sema_all(Scheme_Object *o);
MZ_EXTERN int scheme_wait_sema(Scheme_Object *o, int just_try);
MZ_EXTERN Scheme_Object **scheme_char_constants;

MZ_EXTERN Scheme_Object *scheme_make_channel();

MZ_EXTERN int scheme_get_int_val(Scheme_Object *o, long *v);
MZ_EXTERN int scheme_get_unsigned_int_val(Scheme_Object *o, unsigned long *v);

MZ_EXTERN double scheme_real_to_double(Scheme_Object *r);

MZ_EXTERN Scheme_Object *scheme_make_cptr(void *cptr, const char *typestr);

MZ_EXTERN const char *scheme_get_proc_name(Scheme_Object *p, int *len, int for_error);

/*========================================================================*/
/*                               bignums                                  */
/*========================================================================*/

MZ_EXTERN Scheme_Object *scheme_make_bignum(long v);
MZ_EXTERN Scheme_Object *scheme_make_bignum_from_unsigned(unsigned long v);
MZ_EXTERN double scheme_bignum_to_double(const Scheme_Object *n);
MZ_EXTERN Scheme_Object *scheme_bignum_from_double(double d);
#ifdef MZ_USE_SINGLE_FLOATS
MZ_EXTERN float scheme_bignum_to_float(const Scheme_Object *n);
MZ_EXTERN Scheme_Object *scheme_bignum_from_float(float d);
#else
# define scheme_bignum_to_float scheme_bignum_to_double
# define scheme_bignum_from_float scheme_bignum_from_double
#endif
MZ_EXTERN char *scheme_bignum_to_string(const Scheme_Object *n, int radix);
MZ_EXTERN char *scheme_bignum_to_allocated_string(const Scheme_Object *n, int radix, int alloc);
MZ_EXTERN Scheme_Object *scheme_read_bignum(const char *str, int offset, int radix);
MZ_EXTERN Scheme_Object *scheme_bignum_normalize(const Scheme_Object *n);

/*========================================================================*/
/*                              rationals                                 */
/*========================================================================*/

MZ_EXTERN Scheme_Object *scheme_make_rational(const Scheme_Object *r, const Scheme_Object *d);
MZ_EXTERN double scheme_rational_to_double(const Scheme_Object *n);
MZ_EXTERN Scheme_Object *scheme_rational_from_double(double d);
#ifdef MZ_USE_SINGLE_FLOATS
MZ_EXTERN float scheme_rational_to_float(const Scheme_Object *n);
MZ_EXTERN Scheme_Object *scheme_rational_from_float(float d);
#else
# define scheme_rational_to_float scheme_rational_to_double
# define scheme_rational_from_float scheme_rational_from_double
#endif
MZ_EXTERN Scheme_Object *scheme_rational_normalize(const Scheme_Object *n);
MZ_EXTERN Scheme_Object *scheme_rational_numerator(const Scheme_Object *n);
MZ_EXTERN Scheme_Object *scheme_rational_denominator(const Scheme_Object *n);

/*========================================================================*/
/*                              complexes                                 */
/*========================================================================*/

MZ_EXTERN Scheme_Object *scheme_make_complex(const Scheme_Object *r, const Scheme_Object *i);
MZ_EXTERN Scheme_Object *scheme_complex_normalize(const Scheme_Object *n);
MZ_EXTERN Scheme_Object *scheme_complex_real_part(const Scheme_Object *n);
MZ_EXTERN Scheme_Object *scheme_complex_imaginary_part(const Scheme_Object *n);

/* Exact/inexact: */
MZ_EXTERN int scheme_is_exact(Scheme_Object *n);
MZ_EXTERN int scheme_is_inexact(Scheme_Object *n);

/*========================================================================*/
/*                 macros, syntax, and compilation                        */
/*========================================================================*/

MZ_EXTERN Scheme_Object *scheme_expand(Scheme_Object *form, Scheme_Env *env);

MZ_EXTERN Scheme_Object *scheme_compile(Scheme_Object *form, Scheme_Env *env, int writeable);

/*========================================================================*/
/*                               ports                                    */
/*========================================================================*/

MZ_EXTERN Scheme_Object *scheme_read(Scheme_Object *port);
MZ_EXTERN Scheme_Object *scheme_read_syntax(Scheme_Object *port, Scheme_Object *stxsrc);
MZ_EXTERN void scheme_write(Scheme_Object *obj, Scheme_Object *port);
MZ_EXTERN void scheme_display(Scheme_Object *obj, Scheme_Object *port);
MZ_EXTERN void scheme_write_w_max(Scheme_Object *obj, Scheme_Object *port, long maxl);
MZ_EXTERN void scheme_display_w_max(Scheme_Object *obj, Scheme_Object *port, long maxl);
MZ_EXTERN void scheme_write_string(const char *str, long len, Scheme_Object *port);
MZ_EXTERN long scheme_put_string(const char *who, Scheme_Object *port,
				 const char *str, long d, long len,
				 int rarely_block);
MZ_EXTERN char *scheme_write_to_string(Scheme_Object *obj, long *len);
MZ_EXTERN char *scheme_display_to_string(Scheme_Object *obj, long *len);
MZ_EXTERN char *scheme_write_to_string_w_max(Scheme_Object *obj, long *len, long maxl);
MZ_EXTERN char *scheme_display_to_string_w_max(Scheme_Object *obj, long *len, long maxl);
MZ_EXTERN void scheme_debug_print(Scheme_Object *obj);
MZ_EXTERN void scheme_flush_output(Scheme_Object *port);

MZ_EXTERN char *scheme_format(char *format, int flen, int argc, Scheme_Object **argv, long *rlen);
MZ_EXTERN void scheme_printf(char *format, int flen, int argc, Scheme_Object **argv);

MZ_EXTERN int scheme_getc(Scheme_Object *port);
MZ_EXTERN int scheme_peekc(Scheme_Object *port);
MZ_EXTERN int scheme_peekc_skip(Scheme_Object *port, Scheme_Object *skip);
MZ_EXTERN int scheme_getc_special_ok(Scheme_Object *port);
MZ_EXTERN int scheme_peekc_special_ok(Scheme_Object *port);
MZ_EXTERN int scheme_peekc_special_ok_skip(Scheme_Object *port, Scheme_Object *skip);
MZ_EXTERN void scheme_ungetc(int ch, Scheme_Object *port);
MZ_EXTERN int scheme_char_ready(Scheme_Object *port);
MZ_EXTERN int scheme_peekc_is_ungetc(Scheme_Object *port);
MZ_EXTERN void scheme_need_wakeup(Scheme_Object *port, void *fds);
MZ_EXTERN long scheme_get_string(const char *who,
				 Scheme_Object *port,
				 char *buffer, long offset, long size,
				 int only_avail,
				 int peek, Scheme_Object *peek_skip);
MZ_EXTERN long scheme_get_chars(Scheme_Object *port, long size, char *buffer, int offset);
MZ_EXTERN long scheme_tell(Scheme_Object *port);
MZ_EXTERN long scheme_output_tell(Scheme_Object *port);
MZ_EXTERN long scheme_tell_line(Scheme_Object *port);
MZ_EXTERN long scheme_tell_column(Scheme_Object *port);
MZ_EXTERN void scheme_count_lines(Scheme_Object *port);
MZ_EXTERN void scheme_close_input_port(Scheme_Object *port);
MZ_EXTERN void scheme_close_output_port(Scheme_Object *port);

MZ_EXTERN Scheme_Object *scheme_make_port_type(const char *name);
MZ_EXTERN Scheme_Input_Port *scheme_make_input_port(Scheme_Object *subtype, void *data,
						    Scheme_Get_String_Fun get_string_fun,
						    Scheme_Peek_String_Fun peek_string_fun,
						    Scheme_In_Ready_Fun char_ready_fun,
						    Scheme_Close_Input_Fun close_fun,
						    Scheme_Need_Wakeup_Input_Fun need_wakeup_fun,
						    int must_close);
MZ_EXTERN Scheme_Output_Port *scheme_make_output_port(Scheme_Object *subtype,
						      void *data,
						      Scheme_Write_String_Fun write_string_fun,
						      Scheme_Out_Ready_Fun ready_fun,
						      Scheme_Close_Output_Fun close_fun,
						      Scheme_Need_Wakeup_Output_Fun need_wakeup_fun,
						      int must_close);

MZ_EXTERN Scheme_Object *scheme_open_input_file(const char *name, const char *who);
MZ_EXTERN Scheme_Object *scheme_open_output_file(const char *name, const char *who);

MZ_EXTERN Scheme_Object *scheme_make_file_input_port(FILE *fp);
MZ_EXTERN Scheme_Object *scheme_make_named_file_input_port(FILE *fp, const char *filename);
MZ_EXTERN Scheme_Object *scheme_make_file_output_port(FILE *fp);

MZ_EXTERN Scheme_Object *scheme_make_string_input_port(const char *str);
MZ_EXTERN Scheme_Object *scheme_make_sized_string_input_port(const char *str, long len);
MZ_EXTERN Scheme_Object *scheme_make_string_output_port();
MZ_EXTERN char *scheme_get_string_output(Scheme_Object *);
MZ_EXTERN char *scheme_get_sized_string_output(Scheme_Object *, long *len);

MZ_EXTERN void scheme_pipe(Scheme_Object **read, Scheme_Object **write);
MZ_EXTERN void scheme_pipe_with_limit(Scheme_Object **write, Scheme_Object **read, int maxsize);

MZ_EXTERN long scheme_set_file_position(Scheme_Object *port, long pos);

MZ_EXTERN int scheme_file_exists(char *filename);
MZ_EXTERN int scheme_directory_exists(char *dirname);
MZ_EXTERN char *scheme_expand_filename(char* filename, int ilen, const char *errorin, int *ex, int guards);

MZ_EXTERN char *scheme_os_getcwd(char *buf, int buflen, int *actlen, int noexn);
MZ_EXTERN int scheme_os_setcwd(char *buf, int noexn);
MZ_EXTERN char *scheme_getdrive(void);

MZ_EXTERN Scheme_Object *scheme_split_pathname(const char *path, int len, Scheme_Object **base, int *isdir);
MZ_EXTERN Scheme_Object *scheme_build_pathname(int argc, Scheme_Object **argv);

#ifdef MACINTOSH_EVENTS
MZ_EXTERN char *scheme_mac_spec_to_path(mzFSSpec *spec);
MZ_EXTERN int scheme_mac_path_to_spec(const char *filename, mzFSSpec *spec);
#endif

MZ_EXTERN void *scheme_alloc_fdset_array(int count, int permanent);
MZ_EXTERN void *scheme_init_fdset_array(void *fdarray, int count);
MZ_EXTERN void *scheme_get_fdset(void *fdarray, int pos);
MZ_EXTERN void scheme_fdzero(void *fd);
MZ_EXTERN void scheme_fdset(void *fd, int pos);
MZ_EXTERN void scheme_fdclr(void *fd, int pos);
MZ_EXTERN int scheme_fdisset(void *fd, int pos);
MZ_EXTERN void scheme_add_fd_handle(void *h, void *fds, int repost);
MZ_EXTERN void scheme_add_fd_eventmask(void *fds, int mask);

MZ_EXTERN void scheme_security_check_file(const char *who, const char *filename, int guards);
MZ_EXTERN void scheme_security_check_network(const char *who, const char *host, int port, int client);

MZ_EXTERN int scheme_get_host_address(const char *address, int id, void *result);

/*========================================================================*/
/*                        namespace/environment                           */
/*========================================================================*/

MZ_EXTERN Scheme_Object *scheme_make_namespace(int argc, Scheme_Object *argv[]);
MZ_EXTERN void scheme_add_namespace_option(Scheme_Object *key, void (*f)(Scheme_Env *));

MZ_EXTERN void scheme_require_from_original_env(Scheme_Env *env, int syntax_only);

MZ_EXTERN void scheme_add_global(const char *name, Scheme_Object *val, Scheme_Env *env);
MZ_EXTERN void scheme_add_global_symbol(Scheme_Object *name, Scheme_Object *val,
			      Scheme_Env *env);

MZ_EXTERN Scheme_Object *scheme_make_envunbox(Scheme_Object *value);

MZ_EXTERN Scheme_Object *scheme_lookup_global(Scheme_Object *symbol, Scheme_Env *env);

MZ_EXTERN Scheme_Bucket *scheme_global_bucket(Scheme_Object *symbol, Scheme_Env *env);
MZ_EXTERN Scheme_Bucket *scheme_global_keyword_bucket(Scheme_Object *symbol, Scheme_Env *env);
MZ_EXTERN Scheme_Bucket *scheme_module_bucket(Scheme_Object *mod, Scheme_Object *var, int pos, Scheme_Env *env);

MZ_EXTERN Scheme_Bucket *scheme_exptime_global_bucket(Scheme_Object *symbol, Scheme_Env *env);
MZ_EXTERN Scheme_Bucket *scheme_exptime_module_bucket(Scheme_Object *mod, Scheme_Object *var, int pos, Scheme_Env *env);

MZ_EXTERN Scheme_Object *scheme_builtin_value(const char *name); /* convenience */

MZ_EXTERN void scheme_set_global_bucket(char *proc, Scheme_Bucket *var, Scheme_Object *val,
			      int set_undef);
MZ_EXTERN void scheme_install_macro(Scheme_Bucket *b, Scheme_Object *v);


MZ_EXTERN void scheme_save_initial_module_set(Scheme_Env *env);
MZ_EXTERN Scheme_Env *scheme_primitive_module(Scheme_Object *name, Scheme_Env *for_env);
MZ_EXTERN void scheme_finish_primitive_module(Scheme_Env *env);

MZ_EXTERN Scheme_Object *scheme_make_modidx(Scheme_Object *path,
				  Scheme_Object *base,
				  Scheme_Object *resolved);

MZ_EXTERN Scheme_Object *scheme_declare_module(Scheme_Object *shape, Scheme_Invoke_Proc ivk,
				     Scheme_Invoke_Proc sivk, void *data, Scheme_Env *env);

/*========================================================================*/
/*                                symbols                                 */
/*========================================================================*/

MZ_EXTERN Scheme_Object *scheme_intern_symbol(const char *name);
MZ_EXTERN Scheme_Object *scheme_intern_exact_symbol(const char *name, unsigned int len);
MZ_EXTERN Scheme_Object *scheme_make_symbol(const char *name); /* Make uninterned */
MZ_EXTERN Scheme_Object *scheme_make_exact_symbol(const char *name, unsigned int len); /* Exact case */
MZ_EXTERN const char *scheme_symbol_name(Scheme_Object *sym);
MZ_EXTERN const char *scheme_symbol_name_and_size(Scheme_Object *sym, unsigned int *l, int flags);
MZ_EXTERN char *scheme_symbol_val(Scheme_Object *sym);

/*========================================================================*/
/*                                structs                                 */
/*========================================================================*/

MZ_EXTERN Scheme_Object **scheme_make_struct_values(Scheme_Object *struct_type,
					  Scheme_Object **names,
					  int count, int flags);
MZ_EXTERN Scheme_Object **scheme_make_struct_names(Scheme_Object *base,
					 Scheme_Object *field_names,
					 int flags, int *count_out);
MZ_EXTERN Scheme_Object *scheme_make_struct_type(Scheme_Object *base,
				       Scheme_Object *parent,
				       Scheme_Object *inspector,
				       int num_fields, int num_uninit_fields,
				       Scheme_Object *uninit_val,
				       Scheme_Object *properties);
MZ_EXTERN Scheme_Object *scheme_make_struct_instance(Scheme_Object *stype,
					   int argc,
					   Scheme_Object **argv);

MZ_EXTERN Scheme_Object *scheme_make_struct_exptime(Scheme_Object **names, int count,
						    Scheme_Object *super_sym,
						    Scheme_Object *super_exptime,
						    int flags);

MZ_EXTERN int scheme_is_struct_instance(Scheme_Object *type, Scheme_Object *v);
MZ_EXTERN Scheme_Object *scheme_struct_ref(Scheme_Object *s, int pos);
MZ_EXTERN void scheme_struct_set(Scheme_Object *s, int pos, Scheme_Object *v);

MZ_EXTERN Scheme_Object *scheme_make_struct_type_property(Scheme_Object *name);
MZ_EXTERN Scheme_Object *scheme_make_struct_type_property_w_guard(Scheme_Object *name, Scheme_Object *guard);
MZ_EXTERN Scheme_Object *scheme_struct_type_property_ref(Scheme_Object *prop, Scheme_Object *s);

/*========================================================================*/
/*                              utilities                                 */
/*========================================================================*/

MZ_EXTERN int scheme_eq(Scheme_Object *obj1, Scheme_Object *obj2);
MZ_EXTERN int scheme_eqv(Scheme_Object *obj1, Scheme_Object *obj2);
MZ_EXTERN int scheme_equal(Scheme_Object *obj1, Scheme_Object *obj2);

#ifdef MZ_PRECISE_GC
MZ_EXTERN long scheme_hash_key(Scheme_Object *o);
#endif
MZ_EXTERN long scheme_equal_hash_key(Scheme_Object *o);
MZ_EXTERN long scheme_equal_hash_key2(Scheme_Object *o);

MZ_EXTERN Scheme_Object *scheme_build_list(int argc, Scheme_Object **argv);
MZ_EXTERN void scheme_make_list_immutable(Scheme_Object *l);

MZ_EXTERN int scheme_list_length(Scheme_Object *list);
MZ_EXTERN int scheme_proper_list_length(Scheme_Object *list);

MZ_EXTERN Scheme_Object *scheme_alloc_list(int size);
MZ_EXTERN Scheme_Object *scheme_map_1(Scheme_Object *(*f)(Scheme_Object*),
			    Scheme_Object *l);

MZ_EXTERN Scheme_Object *scheme_car(Scheme_Object *pair);
MZ_EXTERN Scheme_Object *scheme_cdr(Scheme_Object *pair);
MZ_EXTERN Scheme_Object *scheme_cadr(Scheme_Object *pair);
MZ_EXTERN Scheme_Object *scheme_caddr(Scheme_Object *pair);

MZ_EXTERN Scheme_Object *scheme_vector_to_list(Scheme_Object *vec);
MZ_EXTERN Scheme_Object *scheme_list_to_vector(Scheme_Object *list);

MZ_EXTERN Scheme_Object *scheme_append(Scheme_Object *lstx, Scheme_Object *lsty);

MZ_EXTERN Scheme_Object *scheme_box(Scheme_Object *v);
MZ_EXTERN Scheme_Object *scheme_unbox(Scheme_Object *obj);
MZ_EXTERN void scheme_set_box(Scheme_Object *b, Scheme_Object *v);

MZ_EXTERN Scheme_Object *scheme_make_weak_box(Scheme_Object *v);

MZ_EXTERN Scheme_Object *scheme_load(const char *file);
MZ_EXTERN Scheme_Object *scheme_load_extension(const char *filename, Scheme_Env *env);
MZ_EXTERN void scheme_register_extension_global(void *ptr, long size);

MZ_EXTERN long scheme_get_seconds(void);
MZ_EXTERN long scheme_get_milliseconds(void);
MZ_EXTERN double scheme_get_inexact_milliseconds(void);
MZ_EXTERN long scheme_get_process_milliseconds(void);

MZ_EXTERN char *scheme_banner(void);
MZ_EXTERN char *scheme_version(void);

MZ_EXTERN int scheme_check_proc_arity(const char *where, int a,
			    int which, int argc, Scheme_Object **argv);

MZ_EXTERN char *scheme_make_provided_string(Scheme_Object *o, int count, int *len);
MZ_EXTERN char *scheme_make_args_string(char *s, int which, int argc, Scheme_Object **argv, long *len);

MZ_EXTERN void scheme_no_dumps(char *why);

MZ_EXTERN const char *scheme_system_library_subpath();

MZ_EXTERN void scheme_signal_received(void);
