/*
	CALCUL DE FORMULES MATHEMATIQUES
	Valentin KIELBASA
	5/12/2004

*/

/*
		GRAMMAIRE

LETTREMAJ ::= 'A'|'B'|'C'|'D'|'E'|'F'|'G'|'H'|'I'|'J'|'K'|'L'|'M'
             |'N'|'O'|'P'|'Q'|'R'|'S'|'T'|'U'|'V'|'W'|'X'|'Y'|'Z'
LETTREMIN ::= 'a'|'b'|'c'|'d'|'e'|'f'|'g'|'h'|'i'|'j'|'k'|'l'|'m'
             |'n'|'o'|'p'|'q'|'r'|'s'|'t'|'u'|'v'|'w'|'x'|'y'|'z'
chiffre   ::= '0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9'
lettre    ::= lettremin|lettremaj

-- Grammaire d'une expression mathématique
//langage := {expression_primaire}
//expression_primaire ::= [variable operateur_affectation] expression ';'
expression ::= [operateur_unaire] [identificateur_fonction] '(' terme|expression|variable [operateur terme|expression|variable] ')'
terme ::= [operateur_unaire] entier_non_signe|flottant_non_signe|hexadecimal|binaire
entier_non_signe ::= chiffre{chiffre}
flottant_non_signe ::= chiffre{chiffre}'.'{chiffre}[symbole_unite | ['e'|'E' ['+'|'-'] chiffre{chiffre}]]
booleen ::= 'True'|'False'
variable ::= lettre {lettre | chiffre | '_' | '[' | ']' | '@'}
hexadecimal ::= '0x' {chiffre|lettre}
binaire ::= '0b' {'0' | '1'}
identificateur_fonction ::= lettre{lettre|chiffre|'_'}
operateur_binaire ::= '*'|'/'|'+'|'-'|'^'|'%'
operateur_comparaison ::= '<' | '>' | '==' | '!='
operateur_booleen ::= '&' | '<<' | '>>' | '|'
operateur_affectation ::= '='
operateur_unaire ::= '-'|'+'|'!'

symbole_unite ::= 'a' | 'f' | 'p' | 'n' | 'µ' | 'm' | 'k' | 'M' | 'G' | 'T'

// expression_conditionnelle ::= 'if(' expression '){' expression '}else{' expression '}'
// fonction ::= identificateur_fonction '(' [parametre] { ',' parametre} ')'
// parametre ::= terme|expression



*/

#ifndef _calc_h_
#define _calc_h_



#define VERSION_ID
#define VERSION_COMPILEDATE
#define VERSION_COMPILETIME
typedef struct _calc_version
{
	int build;
	char *version;//[VERSION_ID+1];
	char *compileDate;//[VERSION_COMPILEDATE+1];
	char *compileTime;//[VERSION_COMPILETIME+1];
}CALC_VERSION;

typedef enum _calc_cerror
{
	CALC_ERR_SUCCESS=1,
	CALC_ERR_COMPILATION,
	CALC_ERR_RUNTIME,
	CALC_ERR_MALLOC,
}CALC_CERROR;

typedef enum _calc_type_msg
{
	CALC_TMSG_UNKNOWN,
	CALC_TMSG_INFO,
	CALC_TMSG_WARNING,
	CALC_TMSG_ERROR,
	CALC_TMSG_SYNTAXERROR,
	CALC_TMSG_RUNTIMEERROR
}CALC_TMSG;

/* Structure définissant un calcul */
typedef struct _calc CALC;

/* Structure pour les messages d'erreurs */
typedef struct _calc_msg
{
	CALC_TMSG tmsg;
	int num;
	int position;
	char *msg_info;
}CALC_MSG;

/* Structure pour l'enregistrement d'une variable */
typedef struct _calc_var
{
	char   *name;
	double  value;
}CALC_VAR;

/* Table des variables */
typedef struct _calc_vartable
{
	int countVar;
	CALC_VAR *vars;
}CALC_VARTABLE;

/* Gestion des fonctions externes */
/* Définit la référence sur une fonction */
typedef struct _calc_function_1param
{
	char *name;
	double (*fn_pointer)(double);
}CALC_FUNCTION_1PARAM;

/* Définit l'entete de la table des fonctions */
typedef struct _calc_functiontable
{
	int count;
	CALC_FUNCTION_1PARAM *functions;
}CALC_FUNCTIONTABLE;


/* Prépare la formule en la compilant pour qu'elle soit prête à être calculée */
/* Retourne un handle sur le contexte */
CALC *CALC_Compile(char *formule);

/* Détruit le contexte associé à la formule */
/* Retourne NULL dans tous les cas */
CALC *CALC_Destroy(CALC *calc);

/* Renvoie le pointeur sur la table des variables */
/* Retourne le nombre de variables */
int CALC_GetVarTable(CALC *calc, CALC_VARTABLE *vt);

/* Définit la table à utiliser pour les variables */
/* Retourne EXIT_SUCCESS / EXIT_FAILURE */
int CALC_SetVarTable(CALC *calc, CALC_VAR *vars, int nbVars);

/* Définit la table de fonctions externes */
/* Retourne EXIT_SUCCESS / EXIT_FAILURE */
int CALC_SetExtFuncTable(CALC *calc, CALC_FUNCTION_1PARAM *fn, int count);

/* Récupère la table des fonctions externes */
/* Renvoie le nombre de fonctions */
int CALC_GetExtFuncTable(CALC *calc, CALC_FUNCTIONTABLE *vt);

/* Renvoie le nom d'affectation du calcul, s'il y en a un (renvoie NULL sinon) */
char *CALC_GetAssignName(CALC *calc);

/* Procède au calcul de la formule */
/* Renvoie la valeur calculée */
double CALC_Calculate(CALC *calc);

/* [en cours] Génération d'un langage intermédiaire */
//double CALC_GenererByteCode(CALC *calc);

/* Indique s'il y a eu une erreur sans préciser laquelle */
/* Retourne VRAI / FAUX */
int CALC_Error(CALC *calc);

/* Permet de récupérer la liste des messages */
CALC_MSG *CALC_ReadMsgNext(CALC *calc);

/* Permet de détruire les informations d'un message */
void CALC_DestroyMsg(CALC_MSG *msg);

/* Récupération des infos de version */
CALC_VERSION *CALC_GetVersionInfos(void);

#endif

