/* aze_api.h 2006/03/08
   Copyright (c) SOFNEC Co., Ltd.
 */
#ifndef AZE_EXTAPI_H
#define AZE_EXTAPI_H

#include <azprolog.h>

#define AZE_RETURN_NORMAL     0

#define AZE_NULL_TERM         ((AZE_TERM )0)

#define AZE_IS_NULL_TERM(t)   ((t) == AZE_NULL_TERM)

#define AZE_PRED_FAIL         YIELD(FAIL)
#define AZE_PRED_DET_SUCC     YIELD(DET_SUCC)

#define AZE_PRED_BEGIN(fp) \
  if (HP_GE(next_var_cell, var_bottom))	\
    LocalOverflow();			\
  fp->Local = next_var_cell;	\
  fp->Global = next_gvar_cell;	\
  fp->Trail = trail_register;	\
  fp->nVars = 0

#define AZE_ARG(n,i)        (next_var_cell - n + i)

#define AZE_ENV_NULL        NULLFRAME

#define AZE_C_DATA_SET_INT(data, val) \
  (data).type = AZE_C_TYPE_INT;       \
  (data).u.i  = (val)
#define AZE_C_DATA_SET_ATOM(data, val) \
  (data).type = AZE_C_TYPE_ATOM;       \
  (data).u.a  = (val)
#define AZE_C_DATA_SET_DOUBLE(data, val) \
  (data).type = AZE_C_TYPE_DOUBLE;       \
  (data).u.d  = (val)
#define AZE_C_DATA_SET_TERM(data, val) \
  (data).type = AZE_C_TYPE_AZE_TERM;       \
  (data).u.t  = (val)
#define AZE_C_DATA_SET_STRING_TO_ATOM(data, val) \
  (data).type = AZE_C_TYPE_STRING_TO_ATOM;       \
  (data).u.s  = (val)
#define AZE_C_DATA_SET_STRING_TO_LIST(data, val) \
  (data).type = AZE_C_TYPE_STRING_TO_LIST;       \
  (data).u.s  = (val)


#define AZE_C_TYPE_INT              1
#define AZE_C_TYPE_ATOM             2
#define AZE_C_TYPE_DOUBLE           3
#define AZE_C_TYPE_STRING_TO_ATOM   4
#define AZE_C_TYPE_STRING_TO_LIST   5
#define AZE_C_TYPE_AZE_TERM         6

/* types */
typedef Frame*           AZE_ENV;
typedef unsigned long    AZE_ATOM;
typedef TERM*            AZE_TERM;
typedef pred             AZE_C_PRED;
typedef AZE_C_PRED     (*AZE_PRED)(AZE_ENV);
typedef BASEINT          AZE_INT;

typedef struct {
  int type;
  union {
    int      i;
    AZE_ATOM a;
    double   d;
    char*    s;
    AZE_TERM t;
  } u;
} AZE_C_DATA_TYPE;

typedef AZE_C_DATA_TYPE*  AZE_C_DATA;



/* APIs */
extern void     aze_define_pred(char *name, int arity, AZE_PRED c_func);
extern void     aze_raise_error_arg(AZE_ENV Env);
extern AZE_TERM aze_global_cell_new(AZE_ENV Env);
extern void     aze_global_cell_new_cancel(AZE_ENV Env);
extern int      aze_term_value_is_undef(AZE_ENV Env, AZE_TERM t);
extern int      aze_term_value_is_int(AZE_ENV Env, AZE_TERM t);
extern int      aze_term_value_is_list(AZE_ENV Env, AZE_TERM t);
extern AZE_INT  aze_term_value_int(AZE_ENV Env, AZE_TERM t);
extern double   aze_term_value_double(AZE_ENV Env, AZE_TERM t);
extern int      aze_unify_int(AZE_ENV Env, AZE_INT i, AZE_TERM t);
extern int      aze_unify_double(AZE_ENV Env, double d, AZE_TERM t);
extern int      aze_unify_atom(AZE_ENV Env, AZE_ATOM a, AZE_TERM t);
extern int      aze_unify_term(AZE_ENV Env, AZE_TERM t1, AZE_TERM t2);
extern AZE_ATOM aze_cstring_to_atom(AZE_ENV Env, const char *s);
extern AZE_ATOM aze_cstring2_to_atom(AZE_ENV Env, const char *s, int len);
extern AZE_TERM aze_list_at(AZE_ENV Env, AZE_TERM list, int at);
extern int      aze_list_to_term_carray(AZE_ENV Env, AZE_TERM list, AZE_TERM* a);
extern int      aze_atom_list_to_cstring_array(AZE_ENV Env, AZE_TERM arg, char *buf[], int max);
extern AZE_TERM aze_cstring_to_list(AZE_ENV Env, const char *s);
extern int      aze_unify_cell_from_c_data(AZE_ENV Env, AZE_C_DATA data, AZE_TERM cell);
extern AZE_TERM aze_make_cell_from_c_data(AZE_ENV Env, AZE_C_DATA data);
extern int      aze_unify_cell_from_c_data_list(AZE_ENV Env, AZE_C_DATA_TYPE data[], int n, AZE_TERM t);
extern AZE_TERM aze_make_cell_from_c_data_list(AZE_ENV Env, AZE_C_DATA_TYPE data[], int n);

extern void     aze_make_list_error_end(AZE_ENV Env);
extern AZE_TERM aze_make_list_init(AZE_ENV Env, AZE_TERM unify_term);
extern AZE_TERM aze_make_list_add_item(AZE_ENV Env, AZE_TERM head, AZE_TERM *carp);
extern int      aze_make_list_end(AZE_ENV Env, AZE_TERM head);

extern int aze_make_prolog_list_from_atom_array(Frame* Env, TERM* t, AZE_ATOM a[], int n);

/* callback */
/*      AZE_CALLBACK_ERROR < 0 */
#define AZE_CALLBACK_NORMAL  0
#define AZE_CALLBACK_STOP    1

typedef int (*AZE_CALLBACK_LIST_EACH)(AZE_ENV Env, AZE_TERM e, int i, void* arg);

extern int      aze_list_each_callback(AZE_ENV Env, AZE_TERM list, AZE_CALLBACK_LIST_EACH callback_func, void* arg);

/* APIs in aze_cenc.c */
extern void  aze_free(void* addr);
extern void* aze_malloc(int size);
extern unsigned char* aze_new_copy_string(const unsigned char* p);
extern unsigned char* aze_new_copy_string2(const unsigned char* p, int len);

#endif /* AZE_EXTAPI_H */
