/**********************************************************************
 
	Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
	This program is free software; you can redistribute it 
	and/or modify it under the terms of the GLOBALBASE 
	Library General Public License (G-LGPL) as published by 

	http://www.globalbase.org/
 
	This program 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.

**********************************************************************/


#ifndef ___GBLISP_H___
#define ___GBLISP_H___
/*
#define LEX_DEBUG
#define PARSE_DEBUG
*/

#include	"stream.h"
#include	"xllisp_types.h"

/* errors */

#ifndef E_OK
#define E_OK		0
#define E_SYS		(-1)
#endif

#define E_GBOPEN	(-0x101)

/* print_sexp flags */
#define PF_RAW_DISABLE	0x00000010
#define PF_RAW_CLEAR	0x00000020
#define PF_MULTI_ROOT	0x00000040
#define PF_INDENT	0x00000080
#define PF_LISP_MODE	0x00000100
#define PF_TEXT		0x00000200

#define PFM_FORMAT	0x00000003
#define PF_LISP		0x00000000
#define PF_XML		0x00000001
#define PF_HTML		0x00000002

int curret_check(XL_SEXP *);

unsigned int hash_key(L_CHAR*);

void print_sexp(STREAM *,XL_SEXP * ,int);

XL_SEXP * get_sexp(XL_FILE*,int);
XL_SEXP * get_sexp_inh(XL_FILE*,int,XL_SEXP*);
XL_SEXP * realize_sexp(XL_SEXP * s);
XL_SEXP * car(XL_SEXP*);
XL_SEXP * cdr(XL_SEXP*);
int get_type(XL_SEXP*);
XL_SEXP * list(XL_SEXP *,...);
XL_SEXP * List(XL_SEXP *,...);
XL_SEXP * append(XL_SEXP *,XL_SEXP *);
XL_SEXP * cons(XL_SEXP *,XL_SEXP *);
XL_SEXP * cons_inh_2(XL_SEXP *,XL_SEXP *);
XL_SEXP * gb_let(XLISP_ENV *,XL_SEXP *);
XL_SEXP * get_symbol(L_CHAR*);
void set_attribute(XL_SEXP *,L_CHAR *,L_CHAR *);
XL_SEXP * n_get_symbol(char *);
XL_SEXP * get_string(L_CHAR*);
XL_SEXP * n_get_string(char*);
XL_SEXP * get_integer(int,L_CHAR*);
XL_SEXP * n_get_integer(int,char*);
XL_SEXP * get_floating(double,L_CHAR*);
XL_SEXP * n_get_floating(double,char*);
XL_SEXP * get_raw(char * data,int size);
XL_SEXP * get_raw_set_data(char * data,int size);
XL_SEXP * get_error(
	XL_FILE *	f,
	int		line,
	int		er_code,
	L_CHAR *	func,
	XL_SEXP * 	s);
XL_SEXP * get_error_line(XL_SEXP * ,int);
XL_SEXP * get_func_prim(XL_SEXP * (*)(),int,XLISP_ENV*,int,int);
XL_SEXP * get_func_prim_sp(XL_SEXP * (*)(),int,XLISP_ENV*,XLISP_ENV*,
			   int,int);
XL_SEXP * get_ptr(void *,void (*)());
XL_SEXP * get_env(XLISP_ENV *);
XL_SEXP * init_parse(STREAM *,L_CHAR*,L_CHAR*);
XL_SEXP * init_delay_func(DELAY_FUNC *);
int cmp_sexp(XL_SEXP * a,XL_SEXP * b);
XL_SEXP * get_el(XL_SEXP *,int);
XL_SEXP * get_el_by_symbol(XL_SEXP *,L_CHAR *, ...);
int list_length(XL_SEXP *);
XLISP_ENV * new_env(XLISP_ENV *);
XLISP_ENV * new_env_pair(XLISP_ENV *,XLISP_ENV *);
void init_gblisp();
XL_SEXP * eval(XLISP_ENV * env,XL_SEXP * sym);
XL_SEXP *
binary(BINARY_TABLE bt[XLT_MAX][XLT_MAX],XLISP_ENV *,XL_SEXP *,XL_SEXP *);
ELEMENT *
search_env(XLISP_ENV * env,L_CHAR * sym);
void set_env(XLISP_ENV * env,L_CHAR * sym,XL_SEXP *);
void del_env(XLISP_ENV * env,L_CHAR * sym);
void set_default_env(XLISP_ENV * env,XL_SEXP *);
void del_default_env(XLISP_ENV * env);
int set_sym(XLISP_ENV *,L_CHAR * sym,XL_SEXP *);
UNIT_ENV * get_uenv(XLISP_ENV *);
void set_uenv(XLISP_ENV *,UNIT_ENV *);

XL_SEXP * gb_list(XLISP_ENV * , XL_SEXP * );
XL_SEXP * gb_div(XLISP_ENV *, XL_SEXP *);
XL_SEXP * gb_define(XLISP_ENV *,XL_SEXP *);
XL_SEXP * gb_while(XLISP_ENV *,XL_SEXP *);
XL_SEXP * gb_equ(XLISP_ENV*,XL_SEXP *);
XL_SEXP * gb_leq(XLISP_ENV*,XL_SEXP *);
XL_SEXP * gb_add(XLISP_ENV*,XL_SEXP *);
XL_SEXP * gb_mul(XLISP_ENV*,XL_SEXP *);
XL_SEXP * gb_sub(XLISP_ENV*,XL_SEXP *);
XL_SEXP * gb_set(XLISP_ENV*,XL_SEXP *);
XL_SEXP * inherit(XL_SEXP *,XL_SEXP *);
XL_SEXP * set_line_fix(XLISP_ENV *,XL_SEXP *);
XL_SEXP * gb_quote(XLISP_ENV*,XL_SEXP *);
XL_SEXP * gb_quote_trace(XLISP_ENV*,XL_SEXP*,L_CHAR*);
XL_SEXP * gb_quote_long(XLISP_ENV*,XL_SEXP *,XLISP_ENV *,XL_SYM_FIELD*);
XL_SEXP * gb_save(XLISP_ENV * ,XL_SEXP* );
XL_SEXP * gb_load(XLISP_ENV * ,XL_SEXP *);
XL_SEXP * gb_quote(XLISP_ENV * ,XL_SEXP *);
XL_SEXP * gb_shell(XLISP_ENV *,XL_SEXP *);
XL_SEXP * gb_wait(XLISP_ENV *,XL_SEXP *);
XL_SEXP * gb_lambda(XLISP_ENV * ,XL_SEXP *);
XL_SEXP * gb_if(XLISP_ENV *,XL_SEXP *);
XL_SEXP * gb_append(XLISP_ENV *,XL_SEXP *);
XL_SEXP * gb_cons(XLISP_ENV *,XL_SEXP *);
XL_SEXP * gb_car(XLISP_ENV *,XL_SEXP *);
XL_SEXP * gb_cdr(XLISP_ENV *,XL_SEXP *);
XL_SEXP * gb_null_func();
XL_SEXP * search_error(XL_SEXP *);
void set_env_work(XLISP_ENV *,void*);
void * get_env_work(XLISP_ENV *);
L_CHAR * get_symbol_field(XL_SEXP *,L_CHAR *);
L_CHAR * get_sf_attribute(XL_SYM_FIELD * sf,L_CHAR * name);
XL_SEXP * get_env_symbol(XLISP_ENV *,L_CHAR *);
void
set_parseflags(XL_FILE * f,int set_flags,int res_flags);
void set_file_line(XL_FILE * ,int);

XLISP_ENV * get_root_env(XLISP_ENV *);
XL_SEXP * list_error(XL_SEXP *);
XL_SYM_FIELD *
set_sym_field(XL_SYM_FIELD *,L_CHAR *,L_CHAR *);

int gblisp_error(XL_FILE * f,int line,int er_code,
		 char * type,XL_SEXP * s);
int gblisp_relay_error(XL_FILE * to,int line,XL_FILE * from);

CODE_METHOD * get_cm(XL_SEXP *);

void set_close_func(XL_FILE * f,void (*func)(),void * work);

void setcr_lock();
void setcr_unlock();

extern L_CHAR * gblisp_site;
extern int (*error_handler)();
extern XLISP_ENV *	gblisp_top_env0;
extern XLISP_ENV *	gblisp_top_env1;
extern XL_FILE * std_file;
extern XL_SEXP * (*break_check)();

void gc_push(void * s,void (*gc)(),char * msg);
void gc_pop(void * s,void (*gc)());

STREAM * get_sexp_stream(XL_SEXP *);
L_CHAR * get_base_unit(XL_SEXP *);


/* conversion prototype */

XL_SEXP * conv_if(XL_SEXP * s);
XL_SEXP * conv_is(XL_SEXP * s);
XL_SEXP * conv_fs(XL_SEXP * s);
XL_SEXP * not_equal(XLISP_ENV *,XL_SEXP *,XL_SEXP *);

XL_SEXP * div_ii(XLISP_ENV *,XL_SEXP * s1,XL_SEXP * s2);
XL_SEXP * div_ff(XLISP_ENV *,XL_SEXP * s1,XL_SEXP * s2);
XL_SEXP * rem_ii(XLISP_ENV *,XL_SEXP * s1,XL_SEXP * s2);
XL_SEXP * rem_ff(XLISP_ENV *,XL_SEXP * s1,XL_SEXP * s2);

XL_SEXP * equ_str(XLISP_ENV *,XL_SEXP *,XL_SEXP *);
XL_SEXP * equ_sym(XLISP_ENV *,XL_SEXP *,XL_SEXP *);
XL_SEXP * equ_int(XLISP_ENV *,XL_SEXP *,XL_SEXP *);
XL_SEXP * equ_float(XLISP_ENV *,XL_SEXP *,XL_SEXP *);
XL_SEXP * equ_func(XLISP_ENV *,XL_SEXP *,XL_SEXP *);
XL_SEXP * equ_pair(XLISP_ENV *,XL_SEXP *,XL_SEXP *);

XL_SEXP * leq_str(XLISP_ENV *,XL_SEXP *,XL_SEXP *);
XL_SEXP * leq_int(XLISP_ENV *,XL_SEXP *,XL_SEXP *);
XL_SEXP * leq_float(XLISP_ENV *,XL_SEXP *,XL_SEXP *);
XL_SEXP * leq_pair(XLISP_ENV *,XL_SEXP *,XL_SEXP *);
XL_SEXP * leq_null(XLISP_ENV *,XL_SEXP *,XL_SEXP *);
XL_SEXP * leq_sym(XLISP_ENV *,XL_SEXP *,XL_SEXP *);
XL_SEXP * leq_diff(XLISP_ENV *,XL_SEXP *,XL_SEXP *);

XL_SEXP * lt_str(XLISP_ENV *,XL_SEXP *,XL_SEXP *);
XL_SEXP * lt_int(XLISP_ENV *,XL_SEXP *,XL_SEXP *);
XL_SEXP * lt_float(XLISP_ENV *,XL_SEXP *,XL_SEXP *);
XL_SEXP * lt_pair(XLISP_ENV *,XL_SEXP *,XL_SEXP *);
XL_SEXP * lt_null(XLISP_ENV *,XL_SEXP *,XL_SEXP *);
XL_SEXP * lt_diff(XLISP_ENV *,XL_SEXP *,XL_SEXP *);
XL_SEXP * lt_sym(XLISP_ENV *,XL_SEXP *,XL_SEXP *);

XL_SEXP * add_str(XLISP_ENV *,XL_SEXP *,XL_SEXP *);
XL_SEXP * add_int(XLISP_ENV *,XL_SEXP *,XL_SEXP *);
XL_SEXP * add_float(XLISP_ENV *,XL_SEXP *,XL_SEXP *);

XL_SEXP * mul_int(XLISP_ENV *,XL_SEXP *,XL_SEXP *);
XL_SEXP * mul_float(XLISP_ENV *,XL_SEXP *,XL_SEXP *);

XL_SEXP * sub_int(XLISP_ENV *,XL_SEXP *,XL_SEXP *);
XL_SEXP * sub_float(XLISP_ENV *,XL_SEXP *,XL_SEXP *);

XL_SEXP * and_int(XLISP_ENV *,XL_SEXP *,XL_SEXP *);

XL_SEXP * or_int(XLISP_ENV *,XL_SEXP *,XL_SEXP *);

XL_SEXP * xor_int(XLISP_ENV *,XL_SEXP *,XL_SEXP *);

XL_SEXP * And_int(XLISP_ENV *,XL_SEXP *,XL_SEXP *);
XL_SEXP * And_float(XLISP_ENV *,XL_SEXP *,XL_SEXP *);
XL_SEXP * And_int_float(XLISP_ENV *,XL_SEXP *,XL_SEXP *);
XL_SEXP * And_float_int(XLISP_ENV *,XL_SEXP *,XL_SEXP *);

XL_SEXP * Or_int(XLISP_ENV *,XL_SEXP *,XL_SEXP *);
XL_SEXP * Or_float(XLISP_ENV *,XL_SEXP *,XL_SEXP *);
XL_SEXP * Or_int_float(XLISP_ENV *,XL_SEXP *,XL_SEXP *);
XL_SEXP * Or_float_int(XLISP_ENV *,XL_SEXP *,XL_SEXP *);

XL_SEXP * Xor_int(XLISP_ENV *,XL_SEXP *,XL_SEXP *);
XL_SEXP * Xor_float(XLISP_ENV *,XL_SEXP *,XL_SEXP *);
XL_SEXP * Xor_int_float(XLISP_ENV *,XL_SEXP *,XL_SEXP *);
XL_SEXP * Xor_float_int(XLISP_ENV *,XL_SEXP *,XL_SEXP *);

int
equ_conv_int(XLISP_ENV * env,int * i1,int * i2,XL_SEXP * s1,XL_SEXP * s2);
int
equ_conv_float(XLISP_ENV * env,
	       double * i1,double * i2,XL_SEXP * s1,XL_SEXP * s2);

int check_delay(XL_SEXP * s,int key);


#endif
