/**********************************************************************
 
	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_TYPES_H___
#define ___GBLISP_TYPES_H___

#include	<stdio.h>
#include	"long_char.h"
#include	"stream.h"
#include	"unit.h"

#define YYTEXTLEN	10

#define T_TTEXT		0x100
#define T_FIELD		0x200
#define T_TAG_END_C	0x302	/* ]]> */
#define T_TAG_END_Q	0x303	/* ?> */
#define T_TAG_END_E	0x304	/* !> */
#define T_TAG_END_P	0x305	/* ]> */
#define T_TAG_END_EMP	0x307	/* /> */
#define T_TAG_END_COMMENT 0x308 /* --> */
#define T_TAG		0x400	/* <....> */
#define T_TAG_F		0x401	/* <.... */
#define T_TAG_C		0x402	/* <[CDATA[ */
#define T_TAG_Q		0x403	/* <?... */
#define T_TAG_E		0x404	/* <!... */
#define T_TAG_P		0x405	/* <[ */
#define T_TAG_N		0x406	/* </... */
#define T_TAG_EMP	0x407	/* <..../> */
#define T_TAG_COMMENT	0x408	/* <!-- */
#define T_SEXP		0x500
#define T_ERR		0x600

#define TM_TYPE		0xff00
#define TM_SUBTYPE	0x00ff

#define TT_TAG_END	0x300
#define TT_TAG		0x400

#define ENV_HASH_SIZE	103

typedef struct entity {
	struct entity *	next;
	L_CHAR *	name;
	L_CHAR *	data;
} ENTITY;

typedef struct entity_stack {
	struct entity_stack *	up;
	ENTITY *		ent;
	L_CHAR * 		ptr;
	int			mode;
#define EST_IGNORE	0
#define EST_REPLACE	1
#define EST_ENTITY	2
#define EST_ENTITY_1	3
#define EST_ENTITY_2	4
} ENTITY_STACK;

typedef struct xl_file {
	struct xl_file *next;
	struct xl_file *prev;

	L_CHAR *	name;
	L_CHAR *	site;
	L_CHAR *	comment;

	STREAM *	st;
	CODE_METHOD *	cm;
	void *		cm_work;

#define XLFILE_BUFFER_SIZE	4096
	char		rb[XLFILE_BUFFER_SIZE];
	short		rb_len;
	short		rb_ptr;
	L_CHAR		buf;
	int		buf_ent_flag;
	int		error;
	int		mode;
#define XLM_X_CRSP		(-13)
#define XLM_X_NUMBER		(-12)
#define XLM_X_COMMENT2		(-11)
#define XLM_X_COMMENT1		(-10)
#define XLM_X_COMMENT		(-9)
#define XLM_X_TAG_END_Q1	(-8)
#define XLM_X_TAG_END1		(-7)
#define XLM_X_TAG_END		(-6)
#define XLM_X_TWAIT		(-5)
#define XLM_X_TFIELD		(-4)
#define XLM_X_TTEXT		(-3)
#define XLM_X_TAG		(-2)
#define XLM_X_TEXT		(-1)
#define XLM_X_WAIT		0
#define XLM_L_WAIT		1
#define XLM_L_SYMBOL		2
#define XLM_L_TEXT		3
#define XLM_L_COMMENT		4
#define XLM_L_RAW		5
	int		flags;
#define XLF_FIX_LINE	1
#define XLF_CLOSE	2
#define XLF_X_NO_CR	4
#define XLF_X_NO_SP	8
#define XLF_EQUAL	0x00010000
#define XLF_L_MODE	0x00020000
#define XLF_PARSE	0x00040000
#define XLF_HTML	0x00000010
#define XLF_TEXT	0x00000020
#define XLF_DONT_CLOSE	0x01000000
	int		line;
	int		token_head_line;
	L_CHAR *	yytext;
	int		yylen;
	int		yytextlen;
	union xl_sexp *	sexp;
	struct xl_delay *stack;
	union xl_sexp * lex_error;

	ENTITY *	entity;
	ENTITY_STACK *	ent_stack;

	void		(*func_11)();
	void		(*func_12)();
	void		(*func_14)();
	void *		work;

#define CF_CLOSE	1
#define CF_GC		2

	void 		(*close_func)(int,void*);
	void * 		close_work;
} XL_FILE;


typedef struct xl_header {
	XL_FILE * 	file;
	int		line;
	int		type;
#define XLT_NULL	0
#define XLT_ERROR	1
#define XLT_PAIR	2
#define XLT_SYMBOL	3
#define XLT_STRING	4
#define XLT_INTEGER	5
#define XLT_FLOAT	6
#define XLT_FUNC	7
#define XLT_DELAY	8
#define XLT_PTR		9
#define XLT_RAW		10
#define XLT_ENV		11
#define XLT_MAX		12
	int		flags;
#define GBF_XML		0x00000001
} XL_SEXP_HEADER;

typedef struct xl_pair {
	XL_SEXP_HEADER	h;
	union xl_sexp *	car;
	union xl_sexp *	cdr;
} XL_PAIR;

typedef struct xl_sym_field {
	struct xl_sym_field *	next;
	L_CHAR *		name;
	L_CHAR *		data;
} XL_SYM_FIELD;


typedef struct xl_symbol {
	XL_SEXP_HEADER	h;
	L_CHAR *	data;
	XL_SYM_FIELD *	field;
} XL_SYMBOL;

typedef struct xl_string {
	XL_SEXP_HEADER	h;
	L_CHAR *	data;
} XL_STRING;

typedef struct xl_integer {
	XL_SEXP_HEADER	h;
	L_CHAR *	unit;
	int		data;
} XL_INTEGER;

typedef struct xl_float {
	XL_SEXP_HEADER	h;
	L_CHAR *	unit;
	double		data;
} XL_FLOAT;

typedef struct xl_func {
	XL_SEXP_HEADER		h;
	char			type;
#define FT_PRIM			1
#define FT_LAMBDA		2
	char			order;
#define FO_NORMAL		0
#define FO_APPLICATIVE		1
	char			min;
	char			max;
	union xlisp_env *	args_env;
	union xlisp_env * 	sp_env;
	union xl_sexp *		(*prim)();
	union xl_sexp *		l_params;
	union xl_sexp *		l_body;
} XL_FUNC;

typedef struct xl_ptr {
	XL_SEXP_HEADER	h;
	void *		ptr;
	void		(*gc)();
} XL_PTR;

typedef struct delay_func {
	union xl_sexp *	(*func)(union xl_sexp *);
	void		(*gc_func)();
	int		(*check_func)();
} DELAY_FUNC;


typedef struct xl_delay {
	XL_SEXP_HEADER	h;
	int		dtype;
#define GBDT_FILE	1
#define GBDT_FILE_QUOTE	2
#define GBDT_FUNC	3
	union {
		struct {
			XL_FILE *	f;
			union xl_sexp *	tag;
			int		mode;
/*
#define XLF_L_MODE
*/
		}		file;
		DELAY_FUNC *	func;
	}		d;
	struct xl_delay * next;
} XL_DELAY;

#define CDT_WAIT_ERR	0
#define CDT_WAIT	1
#define CDT_READY	2
#define CDT_NONDELAY	3
#define CDT_STREAM	4
#define CDT_DEMAND	5

#define CDF_WAIT_ERR	(1<<CDT_WAIT_ERR)
#define CDF_WAIT	(1<<CDT_WAIT)
#define CDF_READY	(1<<CDT_READY)
#define CDF_NONDELAY	(1<<CDT_NONDELAY)
#define CDF_STREAM	(1<<CDT_STREAM)
#define CDF_DEMAND	(1<<CDT_DEMAND)

#define CDF_ALL		(	CDF_WAIT_ERR|		\
				CDF_WAIT|		\
				CDF_READY|		\
				CDF_NONDELAY|		\
				CDF_STREAM|		\
				CDF_DEMAND		\
			)


typedef struct xl_raw {
	XL_SEXP_HEADER	h;
	int		size;
	char *		data;
} XL_RAW;

typedef struct xl_error {
	XL_SEXP_HEADER	h;
	L_CHAR *	site;
	L_CHAR *	filename;
	int		line;
	L_CHAR *	func;
	int		code;
	union xl_sexp *	data;
} XL_ERROR;

typedef struct xl_xlisp_env {
	XL_SEXP_HEADER		h;
	union xlisp_env *	data;
} XL_XLISP_ENV;

typedef union xl_sexp {
	XL_SEXP_HEADER	h;
	XL_PAIR		pair;
	XL_SYMBOL	symbol;
	XL_STRING	string;
	XL_INTEGER	integer;
	XL_FLOAT	floating;
	XL_FUNC		func;
	XL_DELAY	delay;
	XL_PTR		ptr;
	XL_RAW		raw;
	XL_ERROR	err;
	XL_XLISP_ENV	env;
} XL_SEXP;


typedef struct element {
	L_CHAR *	sym;
	struct element * next;
	XL_SEXP *	data;
} ELEMENT;

typedef struct xl_env_pair {
	int			type;
	union xlisp_env *	env[2];
} XL_ENV_PAIR;

typedef struct xl_env {
	int			type;
	union xlisp_env *	parent;
	void *			work;
	int			flags;
#define GBLE_ROOT		1
	ELEMENT *		hash[ENV_HASH_SIZE];
	ELEMENT *		default_sym;
	UNIT_ENV *		uenv;
} XL_ENV;

typedef union xlisp_env {
	int			type;
#define	GBET_PAIR		1
#define GBET_ENV		2
	XL_ENV_PAIR		p;
	XL_ENV			e;
} XLISP_ENV;

typedef struct binary_table {
	XL_SEXP * 	(*conv1)(XL_SEXP*);
	XL_SEXP *	(*conv2)(XL_SEXP*);
	XL_SEXP *	(*binary)(XLISP_ENV *,XL_SEXP*,XL_SEXP*);
} BINARY_TABLE;

typedef struct cu_table {
	char	system[30];
	struct {
		char	name[30];
		double	rate;
	} 	unit[10];
} CU_TABLE;


typedef struct cs_list {
	struct cs_list *	next;
	L_CHAR			code;
	int			count;
} CS_LIST;

typedef struct cs_work {
	CS_LIST *		lst;
	int			str_max;
} CS_WORK;

void lock_gblisp(XL_FILE * f);
void unlock_gblisp(XL_FILE * f);
void init_gblisp_lock(XL_FILE * f);
int cs_sexp_on_mem(CS_WORK * ,XL_SEXP *);
void free_cs_work(CS_WORK*);

#endif
