//--------------------------------------------------------------------------------------
//
// X-BASIC'
// 	内部関数宣言など
//
//--------------------------------------------------------------------------------------

#ifndef	__XB__
#define __XB__	1

#include "XBdefines.h"
#include "fdef.h"
#include "support.h"
#include "myString.h"	// mmmecpy()

//--------------------------------------------------------------------------------------
// エラー情報受け渡し構造体

typedef struct {	// iOSにはこれらの情報さえ渡せば良い
	XB_ERRORNO	eno;	// エラー番号
	slLineNO	lno;	// エラー発生行番号
	char		*mes;	// 外部関数エラー時のエラーメッセージ
} XBERROR_LINE_INFO;

//--------------------------------------------------------------------------------------
// 関数プロトタイプ宣言
//--------------------------------------------------------------------------------------

// XB.m
XB_ERRORNO	xb_compile(void);
XB_ERRORNO	xb_interpreter(void);
void	xb_end(BOOL fskipEend);
void	xb_setStartupLines(uwLineNO startupLines_);
void	xb_fileload(char *fname);
void	setErrorInfoBuff(int errormax,XBERROR_LINE_INFO *xb_errLine_info);
void	setErrorMax(int errormax);
char	*getErrorMes(XB_ERRORNO eNo);
void	setExternalFuncErrmes(char *errmesJ,char *errmesE);
void	setExternalSourceLine(UByte *src);
UByte	*getExternalSourceLine(void);
void	printErrorLine(XB_ERRORNO eNo,uwLineNO lno,UByte *line);
#ifdef CORE_DEBUG
int		printLIneNotSpecifiedError(XB_ERRORNO eNo,int line,char *fname);
void	 _Error(XB_ERRORNO eNo,int line,char *fname)	__attribute__( (noreturn) ) ;	// リターンしない印
void	_IError(XB_ERRORNO eNo,int line,char *fname)	__attribute__( (noreturn) ) ;	// リターンしない印
#define	Error(eNo)		 _Error(eNo,__LINE__,__FILE__);
#define	IError(eNo)		_IError(eNo,__LINE__,__FILE__);
#else
int		printLIneNotSpecifiedError(XB_ERRORNO eNo);
void	Error(XB_ERRORNO eNo)	__attribute__( (noreturn) ) ;	// リターンしない印
void	IError(XB_ERRORNO eNo)	__attribute__( (noreturn) ) ;	// リターンしない印
#endif
void	Warn(XB_WARNNO wNo);
UByte 	*pinpointExecuteLine(uwCODE *wp,uwLineNO *lineNo);
NSString *make1ErrorMessage(XB_ERRORNO	eno,
							uwLineNO	lno,
							char	 *exmes,
							BOOL	finStartup,
							BOOL 	fhtml,
							BOOL	*frecord);
// デバッグ用
#ifdef DMP_INTERNALCODE
void	saveInternalCode();
#else
#define	saveInternalCode()
#endif
//

// XBcompiler.m
uwLineNO	getLineNo(UByte *line);
void	initXBcompiler(UByte *sourceText);
XB_ERRORNO	mainXBcompiler(UByte *sourecText);
void	endXBcompiler(void);
void	externalFunctionRead(void);
void	internalFunction(void);
void	setLabelWithLine(UByte *name,swStrLEN len);
void	arrayParam(UWord *(*pparam));
void	externalFunctionsRoutine(int no);

// XBinterpreter.m
DOUBLE_LONG xbasicMain(uwCODE *internalCode0,int flocal0,SWord numFAC,FAC *facs);
DOUBLE_LONG functionCall(uwTYPE type);

// ダンプ内容フラグ(OR指定)
#define DUMP_NONE				0
#define	DUMP_VAR_INT			BIT0
#define	DUMP_VAR_FLOAT			BIT1
#define	DUMP_VAR_CHAR			BIT2
#define	DUMP_VAR_STR			BIT3
#define DUMP_VAR_ALL			(DUMP_VAR_INT|DUMP_VAR_FLOAT|DUMP_VAR_CHAR|DUMP_VAR_STR)
#define	DUMP_DIM_INT			BIT4
#define	DUMP_DIM_FLOAT			BIT5
#define	DUMP_DIM_CHAR			BIT6
#define	DUMP_DIM_STR			BIT7
#define DUMP_DIM_ALL			(DUMP_DIM_INT|DUMP_DIM_FLOAT|DUMP_DIM_CHAR|DUMP_DIM_STR)
#define	DUMP_DIM_WITH_ELEMENTS	BIT15	// 要素もダンプ
//
#define	DUMP_ONLY_GLOBAL		BIT28	// グローバルのみダンプ
#define	DUMP_ONLY_LOCAL			BIT29	// ローカルのみダンプ
// 上記２つを同時にONにしないこと
#define	DUMP_OFFSET				BIT30	// オフセットもダンプ	BIT31にすると負号になってしまい＋で定数を繋げないので
void varDump( int dumpMode,char    *cmes,void (*debugPrintFunc)(NSString *text)); // char *型
void varDump2(int dumpMode,NSString *mes,void (*debugPrintFunc)(NSString *text)); // NSString *型

// XBintSub.m
STATE	checkBreak(void);
VAR_TYPES	type2VarTypes(uwTYPE type);
VAR_CTRL_EXEC *getVarCtrlExec(VAR_TYPES typeNo,uwCODE code);
VAR_CTRL_EXEC *getVarCtrlExecWithVarNo(VAR_TYPES typeNo,swVarNO *no);
UByte	*getVariableArea(ULong size);
UByte	*strGet0(uwCODE code);
SLong	intGetSub(uwCODE code);
SLong	charGetSub(uwCODE code);
ULong	intGetValue0(uwTYPE *type0);
#define	intGetValue()	intGetValue0(NULL)
SLong	calc2Value(uwCODE code);
CMP_RESULT compare2Value(uwTYPE type);
DOUBLE_LONG getValue(uwTYPE type);
DOUBLE_LONG floatGet0(uwCODE code);
DOUBLE_LONG float_cal(void);

// XBdim.m
UByte	*dimSetSub(slAryNO *yousoNo,swVarNO no,VAR_CTRL_EXEC *var_ctrl_exec);
UByte	*dimSetYousoAndOffset(swJigen jigen,SWord sz1,uwYouso *youso,UByte *varArea);
UByte	*variableInit(UByte *varArea,VARLIST_CHAIN *varListInfo,INTERNAL_CODE_INFO *internalCodesInfo,VAR_CTRL_EXEC *varCtrl,UWord numFAC,FAC facs[]);
void	*getDim1FromFAC(FAC fac[],int no,SWord *size1,uwYouso *youso);
ULong	sizeofArray(DIM1_EXEC *dim1_exec,int *isize1);

// XBstatSub.m
#define	EOL	(0)	// End Of Line = 改行またはプログラム終了
SWord	firstCheckSouceInLine(void);
UByte	skipToChar(UByte cc);
UByte	firstCheckSource(void);
UByte	skipToEndOfLine(void);
UByte	firstCheckSouceComment(void);
int		elseCheck(void);
void	makeHashTable(void);
uwCODE	statementCheck(uwHash hash,swStrLEN len,UByte *name);
void	interpretStatement(uwCODE code);
void	makeHashTable(void);
UByte	calcHash(UByte *p,swStrLEN *len,uwHash *hash0,UByte *(*after));
void	labelHash(swStrLEN *len,uwHash *hash0,UByte *(*original));
void	defineNameInit(void);
void	defineNameFree(void);
UByte	*defineName(UByte *name,swStrLEN len);
void	freeVariableDefineAll(int flocal);
swLabelNO	labelCheckAndDefine(UByte *name,swStrLEN len,int flabel,int *falready);
void	dimInitWithData(swVarNO hno,uwTYPE type,ULong totalYouso);
uwMATHTYPE defineIntWithNoDefinitionVariable(swVarNO *no,UByte *name,uwHash hash,UWord len);
uwTYPE	getTypeWithSource(int *fomit,int *no);
UWord	*defineArrayParam(UWord prm,uwHash hash,UWord len,UByte *name,UWord *param);
void	defineVariableParam(uwPARAMTYPE prmType,uwHash hash,UWord len,UByte *name);
void	variableDefine(VAR_CTRL *varCtrl,uwTYPE type);
swVarNO	defineVariableSub(VAR_CTRL *varCtrl,int size1,uwHash hash,UWord len,UByte *name,DIM1 *(*dim1));
uwTYPE	setLocalVarCtrlFromBit(uwPARAMTYPE prmType,VAR_CTRL *(*varCtrl));
int		checkNestWorkOver(NEST_WORK *next);

// XBstat.m
void	makeupStatementTable(void);
void	makeStatementHashTable(void);
void	determinGotoAdrs(void);
void	enterNest2(NEST_LOOP *nest_loop,NEST_WORK *next,uwCODE *continueAddress);
void	enterNest(NEST_WHILE_FOR_NEXT *nest_while_next,NEST_WORK *next,uwCODE *continueAddress);
void	If_end(void);
void	S_Else(uwCODE code);
void	S_Break(uwCODE code);

// XBmath.m
uwMATHTYPE	interpretMath( uwMATHTYPE msType0,uwCODE *(*kekkaSiki0),SLong *len0);
ULong	interpretFunctions(uwCODE *siki,UWord *param,swVarCNT cnt,swFuncNO fno);
void	determineVariableList(VAR_CTRL varCtrl[]);
#define	determineGlobalVariableList()	determineVariableList(globalVarCtrl)
#define determineLocalVariableList()	determineVariableList(localVarCtrl)

// XBmathSub.m
swVarNO	getVarNo(swVarNO no);
SLong	getIntConstant(void);
double	getFloatConstant(void);
CMP_RESULT compareNameToSource(UByte *name,int fsourceSet);
void	checkParamType(uwPARAMTYPE prm,uwMATHTYPE msType);
uwTYPE	checkImmidiate(void);
SLong	getNumConstant(uwTYPE type,DOUBLE_LONG *dl);
int		sourceStringCopy(UByte *des);
void	makeSystemVariableTable(void);
uwCODE	operatorCheck(void);
uwMATHTYPE	variableCheck(UByte *name ,uwHash hash,UWord len,sbVarSTAT *stat,DIM1 *(*dimInfo),swVarNO *no);
uwPARAMTYPE	functionCheck(UByte *token,uwHash hash,UWord len,swVarCNT *paramCnt,uwCODE *(*paramTable),swFuncNO *fno);
uwPARAMTYPE	funcCheckLoop(FUNCTION1 *func1,UByte *token,uwHash hash,UWord len,swVarCNT *paramCnt0,uwCODE *(*paramTable0),swFuncNO *fno0);

// XBenum.m
void initEnum(void);
void closeEnum(void);
BOOL getEnum(UByte *name,uwHash hash,SWord len,SLong *num,double *fnum,int *fenum);
BOOL storeEnum( uwHash hash,swStrLEN len,UByte *name,int fenum);

//--------------------------------------------------------------------------------------
// 外部変数
//--------------------------------------------------------------------------------------

extern	XB_ERRORNO 	lastErrNo;		// 最新のエラー番号
extern	int			errorCnt;		// エラー発生数
extern	int			errorLimit;		// エラー発生上限（コンパイル時のみ有効）
extern	uwLineNO	startupLines;	// startup.basの行数

// 外部関数ファイル追加時はここにも登録すること
extern	const		INFORMATION_TABLE	InfoStandardFuncs,InfoFileFuncs,InfoExtendFuncs,
										InfoIosGFuncs,
										InfoIosTFuncs,
										InfoIosKFuncs,
										InfoIosSFuncs,
										InfoIosMFuncs,
										InfoIosAFuncs,
										InfoIosSPFuncs,
										InfoX68Funcs,
										InfoCardFuncs,
										InfoMusicFuncs
										;

extern	char		*basicFile;			// BASICのソースファイル名

//--------------------------------------------------------------------------------------

#endif
