/* --- The following code comes from C:\Program Files\lcc\lib\wizard\textmode.tpl. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <io.h>
#include <direct.h>
#include <dislin.h>
#include <conio.h>

#include "delta_encrier.h"

/*#define TEST
#define TESTLEX*/


/* table des lexemes */
ECHANT *Techant;
long nb_echant;

/* table des types de variables */
TYPE_VARIABLE tab_type_variable[MAX_TYPE_VARIABLE];
int nb_tab_type_variable=0;

/* table des instructions */
INSTRUCTION tab_instruction[MAX_INSTRUCTION];
int nb_instruction=0;

/* table des fonctions */
FONCTION tab_fonction[MAX_FONCTION];
int nb_fonction=0;

/* table des routines */
SUBROUTINE tab_subroutine[MAX_SUBROUTINE];
int nb_subroutine=0;

/* table des taches */
TACHE tab_tache[MAX_TACHE];
int nb_tache=0;


/* table des mutex */
TAB_MUTEX tab_mutex[MAX_MUTEX];
int nb_mutex=0;

/* programme */
PROGRAM program;



char nom_fic[100];
long limite;
FILE *file_conf;

char buffer_courant[1000];
long ligne_lu=0;
long limite;


int  ignore_chaine;
char chaine_ignoree[300];


int   index_lexeme=0;
int   type_token;
char  token[MAX_IDENT];
char  module[100];
int   ligne_courante;
int   cr;

int recherche_type(char *);

int boucle; /* compteur de boucle */
int flag_return; /* flag fonction */

int traceaff; /* 1 on affiche, 0 on n'affiche pas */



 /* lit un token */
extern int lire_token();
/* repositionne au token precedent */
extern int retour_arriere();
/* analyse lexicale */
extern void analyse_lexicale(char *);
/* analyse lexicale define */
extern void analyse_lexicale_define(char *);
/* fonction d'initialisation des types */
extern void init_type_variable(char *);
/* fonction d'analyse des variables */
extern void analyse_variable(char *);
/* fonction d'analyse synatxique du corps du programme */
extern void analyse_corps(char *);
/* fonction qui affiche le type  */
extern void affiche_type(TYPE_VARIABLE *,int);
/* fonction qui affiche la definition de la variable */
extern void affiche_variable(int);
/* fonction qui affiche les instructions */
extern void affichage_instruction(INSTRUCTION *inst);
/* fonction de generation de codes */
extern void generation_de_code(char *);
/* nb de defines */
extern int nb_define;


/* choix du fichier à compiler */

int etat_trace=0;
int etat_trace1=0;
int etat_trace2=0;

/*int etat_lib1=1;
int etat_lib2=1;
int etat_lib3=1;
int etat_lib4=1;
int etat_lib5=1;
int etat_lib6=1;
int etat_lib7=1;*/

int etat_sema=1;

void callback_trace(int id)
 {
	 /*printf("\n Ancien Etat trace = %d",etat_trace);*/
	 etat_trace=1-etat_trace;
	 /*printf("\n Nouvel Etat trace =%d",etat_trace);*/
 }


void callback_trace1(int id)
 {
	 /*printf("\n Ancien Etat trace1 = %d",etat_trace1);*/
	 etat_trace1=1-etat_trace1;
	 /*printf("\n Nouvel Etat trace1 =%d",etat_trace1);*/
 }


void callback_trace2(int id)
 {
	/* printf("\n Ancien Etat trace2 = %d",etat_trace2);*/
	 etat_trace2=1-etat_trace2;
	 /*printf("\n Nouvel Etat trace2 =%d",etat_trace2);*/
 }


void callback_sema(int id)
 {
	/* printf("\n Ancien Etat trace2 = %d",etat_trace2);*/
	 etat_sema=1-etat_sema;
	 /*printf("\n Nouvel Etat trace2 =%d",etat_trace2);*/
 }

/*void callback_lib1(int id)
 {
	 etat_lib1=1-etat_lib1;
 }

void callback_lib2(int id)
 {
	 etat_lib2=1-etat_lib2;
 }

void callback_lib3(int id)
 {
	 etat_lib3=1-etat_lib3;
 }

void callback_lib4(int id)
 {
	 etat_lib4=1-etat_lib4;
 }

void callback_lib5(int id)
 {
	 etat_lib5=1-etat_lib5;
 }

void callback_lib6(int id)
 {
	 etat_lib6=1-etat_lib6;
 }

void callback_lib7(int id)
 {
	 etat_lib7=1-etat_lib7;
 }*/


long choix_du_fichier(char *choix)
 {


  int 	ip,id_fic;
  int   bouton;
  int   choix_trace,choix_trace1,choix_trace2,choix_sema;
  /*int   lib1,lib2,lib3,lib4,lib5,lib6,lib7;*/

  char chelp[200];

  strcpy (chelp, "Cop Compiler 1.2|");
  strcat (chelp, "Author: Olivier POURCHER,|");
  strcat (chelp, "28/08/2007");

  swgtit ("Cop compiler");

  swghlp (chelp);

  swgwth (60);
  swgtyp ("SCROLL", "LIST");
  swgpop ("NOOK");

  ip=wgini ("hori");

  id_fic=wgfil(ip,"Choix du fichier .cop.txt","\\source\\essai_test_struct.cop.txt","*.cop.txt");

  bouton=wgbas(ip, "vert");
  wglab(bouton,"Traces  ");

  /* */

  choix_trace=wgbut(bouton,"Syntax Parsing traces",0);
  swgcbk(choix_trace,callback_trace);

  choix_trace1=wgbut(bouton,"Syntax tree, types and variables",0);
  swgcbk(choix_trace1,callback_trace1);

  choix_trace2=wgbut(bouton,"Code generation traces",0);
  swgcbk(choix_trace2,callback_trace2);

  wglab(bouton,"__________________________________________________________");

  choix_sema=wgbut(bouton,"Automatic generation of mutex",1);
  swgcbk(choix_sema,callback_sema);


  wglab(bouton,"__________________________________________________________");

  /* */

  /*lib1=wgbut(bouton,"Library : display",1);
  swgcbk(lib1,callback_lib1);

  lib2=wgbut(bouton,"Library : file"   ,1);
  swgcbk(lib2,callback_lib2);

  lib3=wgbut(bouton,"Library : motor"  ,1);
  swgcbk(lib3,callback_lib3);

  lib4=wgbut(bouton,"Library : sensor" ,1);
  swgcbk(lib4,callback_lib4);

  lib5=wgbut(bouton,"Library : sound"  ,1);
  swgcbk(lib5,callback_lib5);

  lib6=wgbut(bouton,"Library : string" ,1);
  swgcbk(lib6,callback_lib6);

  lib7=wgbut(bouton,"Library : system" ,1);
  swgcbk(lib7,callback_lib7); */

  wgok(ip);

 /* printf("\n avant sortie \n"); */

  wgfin ();

  /* printf("\n après sortie \n");*/

  gwgfil(id_fic,choix);

  /*printf("\n extension % s",((char *)choix+strlen(choix)-3));*/

  return(-1);

 }


void analyse_syntaxique(void)
 {
	 int i;

	 program.nb_vg=0; /* au départ 0 variable */
	 nb_tache=0; /* au départ 0 tache */
	 nb_mutex=0; /* au depart 0 mutex */
	 nb_subroutine=0; /* au depart 0 routine */
	 nb_fonction=0; /* au depart 0 fonction */
	 nb_instruction=0; /* au depart 0 instruction */
	 boucle=0; /* 0 profondeur de boucle */
	 nb_fonctions_appelees=0; /* nb de fonctions appelees */

	 traceaff=etat_trace;

	 init_type_variable("0"); /* création de type atomiques */

	 analyse_variable("0"); /* analyse syntaxique des variables globales et types globaux */

	 printf("\n End of parsing of global variables ");

	 analyse_corps("0");

	 printf("\n End of parsing of functions and tasks");

	 if(etat_trace1==1)
		 {
	 		 traceaff=1;
			 printf("\n\n\n\n\n\n\n LISTE DES TYPES ");

	  		 for(i=0;i<nb_tab_type_variable;i++)
		 		{
					printf("\n\n#################################\n TYPE VARIABLE %d",i);
		 			affiche_type(&tab_type_variable[i],0);
				}


			 printf("\n LISTE DES MUTEX ");

			  for(i=0;i<nb_mutex;i++)
		 		{
					printf("\n\n#################################\n MUTEX %d \n ident ='%s' module '%s' ligne '%d' ",
						i,
						tab_mutex[i].ident,
						tab_mutex[i].module,
						tab_mutex[i].ligne);
		 		}

	 		 printf("\n LISTE DES VARIABLES ");

	 		 for(i=0;i<program.nb_vg;i++)
		 		{
					printf("\n\n#################################\n VARIABLE %d",i);
		 			affiche_variable(i);
		 		}

			 /*message_erreur("stop");*/

			 printf("\n LISTE DES INSTRUCTIONS ");

	 		 for(i=0;i<nb_fonction;i++)
		   	   {
					printf("\n\n#################################\n FONCTION %d '%s' nb_instruction %d ",i,tab_fonction[i].ident_fonction,tab_fonction[i].nb_instruction);
		 			affichage_instruction(tab_fonction[i].liste_instruction);
		 	   }


	 		for(i=0;i<nb_tache;i++)
		 	   {
					printf("\n\n#################################\n TACHE %d '%s' nb_instruction %d",i,tab_tache[i].ident_tache,tab_tache[i].nb_instruction);
		 			affichage_instruction(tab_tache[i].liste_instruction);
			   }
		}

	  printf("\n compiled line = %d\n # of types =%d\n # of variables = %d\n # of functions = %d\n # of tasks = %d",ligne_lu,nb_tab_type_variable,program.nb_vg,nb_fonction,nb_tache);

  }

/********/
/* MAIN */
/********/
int main(void)
{
	int cumul=0;

    printf("\n _____________________________________");
	printf("\n COP Compiler v.1.2 / 28 th August 2007");
	printf("\n Author : Olivier POURCHER");
	printf("\n _____________________________________");

	/* choix du fichier à compiler */
	limite=choix_du_fichier(nom_fic);

	/*strcpy(nom_fic,"D:\\DELTA\\lcc1\\essai_struc.cop.txt");*/


	/* analyse lexicale define */

	nb_define=0;

	analyse_lexicale_define(nom_fic);

	printf("\n\n\n\n PASS #1 : pre-processing ( defines lexical parsing of define completed");

	printf("\n Lexical parsing of define completed : %s - %d lines",nom_fic,ligne_lu);

	ligne_lu=0;

	/*if(etat_lib1==1)*/
		{
			analyse_lexicale_define("lib\\display.cop.lib.txt");
			printf("\n Lexical parsing of define completed : %s - %d lines","lib\\display.cop.lib.txt",ligne_lu);
			ligne_lu=0;
		}
	/*if(etat_lib2==1)*/
		{
			analyse_lexicale_define("lib\\file.cop.lib.txt");
			printf("\n Lexical parsing of define completed : %s - %d lines","lib\\file.cop.lib.txt",ligne_lu);
			ligne_lu=0;
		}
	/*if(etat_lib3==1)*/
		{
			analyse_lexicale_define("lib\\motor.cop.lib.txt");
			printf("\n Lexical parsing of define completed : %s - %d lines","lib\\motor.cop.lib.txt",ligne_lu);
			ligne_lu=0;
		}
	/*if(etat_lib4==1)*/
		{
			analyse_lexicale_define("lib\\sensor.cop.lib.txt");
			printf("\n Lexical parsing of define completed : %s - %d lines","lib\\sensor.cop.lib.txt",ligne_lu);
			ligne_lu=0;
		}
	/*if(etat_lib5==1)*/
		{
			analyse_lexicale_define("lib\\sound.cop.lib.txt");
			printf("\n Lexical parsing of define completed : %s - %d lines","lib\\sound.cop.lib.txt",ligne_lu);
			ligne_lu=0;
		}
	/*if(etat_lib6==1)*/
		{
			analyse_lexicale_define("lib\\string.cop.lib.txt");
			printf("\n Lexical parsing of define completed : %s - %d lines","lib\\string.cop.lib.txt",ligne_lu);
			ligne_lu=0;
		}
	/*if(etat_lib7==1)*/
		{
			analyse_lexicale_define("lib\\system.cop.lib.txt");
			printf("\n Lexical parsing of define completed : %s - %d lines","lib\\system.cop.lib.txt",ligne_lu);
			ligne_lu=0;
		}

	printf("\n PASS #1 : Successfully completed / %d 'defines' parsed",nb_define);

	printf("\n");

	printf("\n\n\n\n PASS #2 : Lexical parsing of libraries and module to be compiled");

	/* analyse lexicale librairie */

	/*if(etat_lib1==1)*/
		{
			analyse_lexicale("lib\\display.cop.lib.txt");
			cumul+=ligne_lu;
			printf("\n Lexical parsing completed : %s - %d lines","lib\\display.cop.lib.txt",ligne_lu);
			ligne_lu=0;
		}
	/*if(etat_lib2==1)*/
		{
			analyse_lexicale("lib\\file.cop.lib.txt");
			cumul+=ligne_lu;
			printf("\n Lexical parsing completed : %s - %d lines","lib\\file.cop.lib.txt",ligne_lu);
			ligne_lu=0;
		}
	/*if(etat_lib3==1)*/
		{
			analyse_lexicale("lib\\motor.cop.lib.txt");
			cumul+=ligne_lu;
			printf("\n Lexical parsing completed : %s - %d lines","lib\\motor.cop.lib.txt",ligne_lu);
			ligne_lu=0;
		}
	/*if(etat_lib4==1)*/
		{
			analyse_lexicale("lib\\sensor.cop.lib.txt");
			cumul+=ligne_lu;
			printf("\n Lexical parsing completed : %s - %d lines","lib\\sensor.cop.lib.txt",ligne_lu);
			ligne_lu=0;
		}
	/*if(etat_lib5==1)*/
		{
			analyse_lexicale("lib\\sound.cop.lib.txt");
			cumul+=ligne_lu;
			printf("\n Lexical parsing completed : %s - %d lines","lib\\sound.cop.lib.txt",ligne_lu);
			ligne_lu=0;
		}
	/*if(etat_lib6==1)*/
		{
			analyse_lexicale("lib\\string.cop.lib.txt");
			cumul+=ligne_lu;
			printf("\n Lexical parsing completed : %s - %d lines","lib\\string.cop.lib.txt",ligne_lu);
			ligne_lu=0;
		}
	/*if(etat_lib7==1)*/
		{
			analyse_lexicale("lib\\system.cop.lib.txt");
			cumul+=ligne_lu;
			printf("\n Lexical parsing completed : %s - %d lines","lib\\system.cop.lib.txt",ligne_lu);
			ligne_lu=0;
		}

	/* analyse lexicale */
	analyse_lexicale(nom_fic);
	cumul+=ligne_lu;

	printf("\n PASS #2 : Successfully completed ");
	printf("\n PASS #2 : Lexical parsing completed : %s  - %d lines ",nom_fic,ligne_lu);

	printf("\n\n\n\n PASS #3 : Syntax parsing of libraries and module to be compiled");
    /* analyse syntaxique */
	analyse_syntaxique();
	printf("\n PASS #3 : Successfully completed ");
	printf("\n PASS #3 : Syntax parsing completed %s - total compiled lines = %d",nom_fic,cumul);

	printf("\n\n\n\n PASS #4 : Code generation of libraries (only those called) and module to be compiled");
	/* generation de code */
	generation_de_code(nom_fic);
	printf("\n Code generation completed %s",nom_fic);
	printf("\n PASS #4 : Successfully completed ");


	printf("\n\n\n Press a key to terminate %s",nom_fic);
	for(;kbhit()==0;){}

	return 0;
}

