/****************************************************************************
 * KONOHA COPYRIGHT, LICENSE NOTICE, AND DISCRIMER  
 * 
 * Copyright (c) 2005-2008, Kimio Kuramitsu <kimio at ynu.ac.jp>
 *           (c) 2008-      Konoha Software Foundation  
 * All rights reserved.
 * 
 * You may choose one of the following two licenses when you use konoha. 
 * See www.konohaware.org/license.html for further information.
 * 
 * (1) GNU General Public License 2.0      (with    KONOHA_UNDER_GPL2)
 * (2) Konoha Software Foundation License 1.0
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *  
 ****************************************************************************/

#ifndef KONOHAC_T_H_
#define KONOHAC_T_H_

#include<konoha/konoha_t.h>

#include"konoha.h"

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

#ifdef __cplusplus 
extern "C" {
#endif

/* ------------------------------------------------------------------------ */

typedef knh_ushort_t   knh_token_t;
typedef knh_ushort_t   knh_stmt_t;
#define knh_perror_t   int

/* ------------------------------------------------------------------------ */
/* @class Token Object knh_Token */
/* @flag Token.TailWildCard TKF DP(%s)->flag 'is:set:*:*' */
/* @flag Token.TopDot TKF DP(%s)->flag 'is:set:*:*' */
/* @flag Token.Getter TKF DP(%s)->flag 'is:set:*:*' */
/* @flag Token.Setter TKF DP(%s)->flag 'is:set:*:*' */
/* @flag Token.Generated TKF DP(%s)->flag 'is:set:*:*' */

/* @flag Token.ExceptionType TKF DP(%s)->flag 'is:set:*:*' */
/* @flag Token.NotNullType TKF DP(%s)->flag 'is:set:*:*' */
/* @flag Token.IteratorType TKF DP(%s)->flag 'is:set:*:*' */
/* @flag Token.ArrayType TKF DP(%s)->flag 'is:set:*:*' */

/* @flag Token.Typed  TKF DP(%s)->flag 'is:set:*:*' */

typedef struct knh_Token {
	knh_fileid_t fileid;
	knh_line_t   line;
	knh_type_t   type;
	knh_flag_t   flag;
	knh_token_t  tt;
	union {
		knh_token_t   tt_next;
		knh_short_t   index;
		knh_methodn_t mn;
		knh_token_t   tt_op;
		knh_fieldn_t  fn;
		knh_class_t   cid;
	};
	union {
		Object* data;
		struct knh_Array_t*  list;
		struct knh_String_t* str;
		struct knh_Token_t* token;
		struct knh_Method_t* mtd;
	};
} knh_Token;

typedef struct knh_tokens_t {
	struct knh_Token_t** ts;
	int c;
	int e;
} knh_tokens_t;

#define TT_RAW   TT_CONST

/* ------------------------------------------------------------------------ */

/* ------------------------------------------------------------------------ */
/* @class Stmt Object knh_Stmt */
/* @flag Stmt.Adposition STMTF DP(%s)->flag 'is:set:*:*' */
/* @flag Stmt.NonNewLine STMTF DP(%s)->flag 'is:set:*:*' */
/* @flag Stmt.Visible STMTF DP(%s)->flag 'is:set:*:*' */
/* @flag Stmt.Typed STMTF DP(%s)->flag 'is:set:*:*' */

/* ------------------------------------------------------------------------ */

#define KNH_STT_RVALUE  0
#define KNH_RVALUE      0
#define KNH_STT_LVALUE  1
#define KNH_LVALUE      1

typedef struct knh_Stmt {
	knh_fileid_t fileid;
	knh_line_t   line;
	knh_type_t   type;
	knh_flag_t   flag;
	knh_stmt_t   stt;
	knh_line_t   line_end;
	knh_ushort_t size;
	knh_ushort_t capacity;
	union {
		Object** terms;
		struct knh_Token_t** tokens;
		struct knh_Stmt_t** stmts;
	};
	union {
		struct knh_DictMap_t* metaDictMap;
		struct knh_String_t*  errMsg;
	};
	struct knh_Stmt_t* next;
} knh_Stmt;

//typedef void    (*f_stmtvisit)(Ctx*, struct knh_Stmt_t*, Object *, NameSpace *, int);

/* ------------------------------------------------------------------------ */

#define Term         Any
#define IS_Term(o)   (IS_Token((Object*)o)||IS_Stmt((Object*)o))

//typedef struct knh_Term_t {
//	knh_hObject_t h;
//	union {
//		struct knh_Token *tokenbody;
//		struct knh_Stmt  *stmtbody;
//	};
//} knh_Term_t;


/* ------------------------------------------------------------------------ */
/* @class Compiler Object knh_Compiler */
/* @flag Compiler.SyntaxError CPF DP(%s)->flag 'is:set:*:*' */
/* @flag Compiler.Stopped CPF DP(%s)->flag 'is:set:*:*' */
/* @flag Compiler.Cancelled CPF DP(%s)->flag 'is:set:*:*' */

typedef struct knh_Compiler {
	knh_flag_t             flag;     
	knh_class_t            this_cid;
	knh_fileid_t           fileid; 
	knh_ushort_t           step; /* unused */
	struct knh_NameSpace_t *ns;
	struct knh_Method_t    *method;
	knh_ushort_t vars_size;
	knh_ushort_t vars_offset;
	knh_cfield_t* vars;
	int nastep;
	int llstep;
	struct knh_Bytes_t* elf;
	struct knh_Bytes_t* dwarf;
	int line;
	struct knh_DictIdx_t* labelIdDictIdx;
	struct knh_DictSet_t* labelAddrDictSet;
	knh_Array_t*          lstacks;
} knh_Compiler;

/* ------------------------------------------------------------------------ */

struct knh_Compiler_t;
typedef void   (*f_visitdecl)(Ctx*, struct knh_Stmt_t*, struct knh_Compiler_t *, NameSpace *, int);
typedef void   (*f_visitname)(Ctx*, struct knh_Stmt_t*, struct knh_Compiler_t *, NameSpace *, int);
typedef void   (*f_visitcmpl)(Ctx*, struct knh_Stmt_t*, struct knh_Compiler_t *, NameSpace *, knh_type_t, int);

/* ------------------------------------------------------------------------ */
/* @class VirtualMachineCode Object knh_VirtualMachineCode */

typedef struct {
	knh_ushort_t offset;
	knh_ushort_t line;
} knh_dwarf_t;

typedef struct knh_VirtualMachineCode {
	knhvmc_t* code;
	size_t size;
	knh_fileid_t fileid;
	knh_nsid_t nsid;
	knh_dwarf_t* dwarf;
	size_t dsize;
} knh_VirtualMachineCode;


/* ------------------------------------------------------------------------ */

#define KNH_ASMV_ONSTACK 0
#define KNH_ASMV_EBP  0
#define KNH_ASMV_SFP  1
#define KNH_ASMV_OFP  2
#define KNH_ASMV_OBJ  3
#define KNH_ASMV_OIDX 4
#define KNH_ASMV_ERR  5

//typedef struct {
//	knh_uchar_t  potype;
//	knh_uchar_t  index;
//	knh_type_t   type; 
//	Object     *value;
//} knh_asmv_t;
           
/* ======================================================================== */

#define KNH_PERROR_BUFSIZ   1024

#define KNH_PERROR(ctx, fid, line, pe, fmt, ...) \
	if(fmt != NULL){ \
		char buf_[KNH_PERROR_BUFSIZ]; \
		knh_snprintf(buf_, sizeof(buf_), ": " fmt, ## __VA_ARGS__); \
		knh_perror(ctx, fid, line, pe, buf_); \
	}else { \
		knh_perror(ctx, fid, line, pe, NULL); \
	} \

#define KNH_TOKEN_PERROR(ctx, tk, pe, fmt, ...) \
	if(fmt != NULL){ \
		char buf_[KNH_PERROR_BUFSIZ]; \
		knh_snprintf(buf_, sizeof(buf_), ": " fmt, ## __VA_ARGS__); \
		knh_Token_perror(ctx, tk, pe, buf_); \
	}else { \
		knh_Token_perror(ctx, tk, pe, NULL); \
	} \


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

#ifdef __cplusplus 
}
#endif

#endif /*KONOHAC_T_H_*/
