#ifndef SYNTAX__H    
#define SYNTAX__H 
//**************************************************************************************
//**************************************************************************************


#include <vector>
#include <list>
#include <cstdlib>
#include <iostream>
#include <fstream>
#include "lexScanner.h"
#include "expEvaluator.h"
using namespace std;

#include <conio.h>		//including support to use getch()
						//	to read one raw character from user input


//********************************************************************************
//Given a source code program written in BIOLA language,
// the BIOLA interpreter need to conduct lexical analysis and syntax analysis to
// refine the source code into individual interpreter instructions, which are ready 
// for execution by the interpreter one by one.
//
//interpreterInstructionCategory 
// is an enumeration type specifying the categories of these interpreter instructions.
//********************************************************************************
enum	interpreterInstructionCategory
// Use typedef to define interpreterInstructionCategory
{
	//*****************************************************************************
	//Section 1: simple Non-compound BIOLA statements as intrepter instructions
	//*****************************************************************************

	ASSIGNMENT_STATEMENT,		
	//e.g. x=1+y;
	
	FUNCTION_CALL_ASSIGNMENT_STATEMENT,
	//e.g. x = square(2); 

	DISPLAY_STATEMENT,	
	//e.g. display "The answer of x+y is ", x+y;
	
	READ_STATEMENT, 
	//e.g. read x;

	RETURN_STATEMENT,	
	//e.g. return x-1;

	COMMENTS_STATEMENT,	
	//e.g. // My comments
	//In the current implementation, we will skip comments in the source code
	//and will not translate them into interpreter instructions.

	//****************************************************************************
	//Section 2: Headers of potentially-compound BIOLA statements as
	//                   interpreter instructions.
	//****************************************************************************

	IF_HEADER_IF_STATEMENT,		
	//e.g. if (x>1) 
	
	ELSE_HEADER_IF_STATEMENT,
	//else 

	WHILE_HEADER_WHILE_STATEMENT,
	//e.g. while (x>1) 

	FUNCTION_HEADER_FUNCTION_STATEMENT,	
	//e.g. function square(x)


	//************************************************
	//Section 3: General scope delimites for blocks of statements
	//************************************************

	BEGIN_ONE_BLOCK,	
	//i.e.  a left curly brace to start a block of statements

	END_ONE_BLOCK,	
	//i.e.  a right curly brace to end a block of statements


	//************************************************
	//Section 4: further refinement of section 3 into
	//	Specific scope delimites for different kinds 
	//	of blocks of statements 
	//************************************************


	BEGIN_FUNCTION_DEFINTION_BLOCK,	
	//i.e.  the first left curly brace following the 
	//function definition header start a block of statements
	//to define a funtion

	END_FUNCTION_DEFINTION_BLOCK,	
	//i.e.  a right curly brace to end a function definition block

	BEGIN_IF_BLOCK,	
	//i.e.  the first left curly brace following the 
	//if header of an if statement to start a block of statements
	//that will be executed when the logic condtion of the if
	//statement is true

	END_IF_BLOCK,		
	//i.e.  a right curly brace to end an if block.

	BEGIN_ELSE_BLOCK,	
	//i.e.  a left curly brace immediately following the 
	//else header of an if statement to start a block of statements
	//that will be executed when the logic condtion of the if
	//statement is false

	END_ELSE_BLOCK,		
	//i.e.  a right curly brace to end an else block.

	BEGIN_WHILE_BLOCK,	
	//i.e.  a left curly brace immediately following the 
	//while header of a while statement to start a block of statements
	//that will be executed when the logic condtion of the while
	//statement is true

	END_WHILE_BLOCK,		
	//i.e.  a right curly brace to end a while block.


	//************************************************
	//Section 5: Unknown
	//************************************************

	UNKNOWN_STATEMENT

};



typedef map<string, float> symbolTable; 
// For each function defined in a BIOLA source code program,
//  we need to maintain a symbol table to hold the names (as strings)
//  of all local variables appearing and the numerical values of these variables.
// So we define the type map<string float> as symbolTable.
// Note that symbolTable is exactly the same as
//  floatVarValueTable as defined in expEvaluator.h.
// So we can use a symbolTable object in arithmetic expression evaluation.
//
//In expEvaluator.h we include in the beginning, we have two other related types:
//(i) typedef map<string,float> floatVarValueTable;
//	A variable table recording the names (strings) of variables
//	and the current floating point values of these variables
//(ii) typedef vector<string> expVector;
//	An expression vector is simply a vector of token strings


class functionCodeRecord
//For each function in a source BIOLA program, 
//we keep a functionCodeRecord object to record 
//  (i) the indices of its first and its last interpreter instructions, which
//	    specify the location of the block of interpreter instruction defining 
//		the function, and
//	(ii) the symbol table of all parameters and local variables used in the function.
//
//In addition, during the execution of a function call to the function,
//	we need to record of the progress of execution by recording 
//	(iii) the index of the current interpreter instruction to execute.
{
	public: //Public data members
		//Name of the function
		string functionName;

		//the list of parameters represented as
		//a vector of the names(strings)of parameters 
		vector<string> parametersList;


		//The table of parameters and local variables and their current values
		symbolTable localVariablesTable;

		//The index of the first interpreter instruction 
		// defining the function: 
		int indexOfFirstInterpreterInstruction;

		//The index of the last interpreter instruction 
		//defining the function: 
		int indexOfLastInterpreterInstruction;

	public: //Public methods
		void clear();
		//clear the contents of the functionCodeRecord

		bool isUndefined();
		//if the functionName is empty or is "_UNDEFINED"


	public: //Additional public data members to keep runtime information
		//When a function is called, it corresponding functionCodeRecord
		//	has the following two additional pieces of runtime information
		//*****************************************************************
		//The list of matching arguments as
		//	a vector of the floating point values for the parameters 
		//	when the function is called
		vector<float> argumentsList;
};


class SyntaxAnalyzer
{
	public:
	//********************************************************************
	//*****			Section of Public data members					******
	//********************************************************************

			//********************************************************************
			//******		syntatic and semantic information				******
			//********************************************************************

			SyntaxAnalyzer(bool debugMode = false);
			//Constructor to initialize the syntax analyzer with the debug mode


			vectOfTokenVects vectInterpreterInstructions;
			// Based on the lexical information of the source code,
			//  the interpreter does syntax analysis and
			//  "refines" the source program into this vector of 
			//  interpreter instructions, where each instruction is a vector of
			//	token strings.
			// Each interpreter instruction in vectInterpreterInstructions is
			//	ready for future exeuction by the interpreter, and when the interpreter 
			//	execute the program, it actually executes acccording to
			//	these interpreter instructions 
			// An interpreter instruction is either a token vector of
			//  (i)		a non-compound BIOLA statement, or 
			//  (ii)	a header of a potentially compound BIOLA statement, or
			//  (iii)	curly braces specifying the begining or the end of 
			//			a block of statements.
			// See the description of the enumeration type: 
			//	interpreterInstructionCategory  
			//	for more details and examples


			vector<interpreterInstructionCategory> categoryVectOfAllInterpreterInstructions;
			//A vector to record the categories of the interpreter instructions


			map<int, int>  mapForNextInterpreterInstruction;
			//The is a control-flow map recording the control flow information 
			//	when exeuting conditional instructions like: if, else, while.
			//
			//The key of an entry in this map is the index of 
			//	(i) an if header, an else header, or a while header 
			//		interpreter instruction, or
			//	(ii)END_WHILE_BLOCK interpreter instruction.
			//
			//The value of an entry in this map recording the index of 
			//	the next interpreter instruction to execute after
			//	(i) an if header or a while header interpreter instruction
			//		when the logic condition in the header is not true
			//	(ii)an ELSE (after the if part is done) or an END_WHILE_BLOCK 
			//		interpreter instruction.

			map<string, functionCodeRecord> tableOfFunctionNamesAndCodeRecords;
			//The table of function names and their code records defined in the program.
			//For each function defined in the source code,
			//	there is a function name and a code record pair for the functiona 
			//	in this table.
			//Note that
			//	tableOfFunctionNamesAndCodeRecords
			//	is built by the interpreter along with the interpreter instructions in
			//	vectInterpreterInstructions 
			//	while the interpreter conducts syntax analysis of the source program, and
			//	both play the central roles in program execution


	private:
	//********************************************************************
	//*****			Section of Private data members					******
	//********************************************************************

			//********************************************************************
			//******	raw lexical information	derived from source code	******
			//********************************************************************
			vectOfTokenVects tokenVectsSourcCodeAllLines;
			// The vector of the token vectors of the lines of the source program
			// This lexical information is gained from lexical analysis of source code.

			vectOfCategoryVects categoryVectsSourcCodeAllLines;
			// The vector of the category vectors of the lines of the source program
			// This lexical information is gained from lexical analysis of source code.

			bool debugModeStatus;
			// The status of debug mode: true or false; 

	public:
		//********************************************************************
		//*****			Section of public member functions				******
		//********************************************************************

		bool parseSourceCode( vector<string> & sourceProgram);
		//Parse the source code to build up the lexical and syntatic information

		void clearAllLexicalSyntacticSemanticInfo();
		//clear the lexical, syntactic, semantic information in the interpreter object


		//***********************************************************************
		//***   Other public member functions for displaying syntactic info *****
		//***********************************************************************

		void outputParseTree(const char * outputFileName);
		//Output a parse tree based on 
		//	vectInterpreterInstructions					and 
		//	categoryVectOfAllInterpreterInstructions
		//Save it into the file whose name is tored in outputFileName


		void outputParseStructureOfOneInterpreterInstruction
		(	const vector<string> & thisInstruction, 					//An interpreter instruction
			interpreterInstructionCategory   thisCategory,	//The category of the interpreter instruction
			int scopeCount,			//The depth of its scope
			int index,				//The index of the instruction in the source program
			ofstream & fout			//The file to write to
		);
		//Output the parse structure of thisInstruction of thisCategory
		//	to the file handle fout, with respect to 
		//	the depth of its scope and its index in the vector of instructions

		void displayAllInterpreterInstructions();
		//Display the interpreter instructions derived from the source code
		//	together with the category information and 
		//	the next instruction information.

		void displayOneInterpreterInstruction
		(perLineTokenVector thisInterpreterInstruction);
		//Display a single interpreter instruction derived from the source code,
		//	called by displayAllInterpreterInstructions.


		void displayFunctionCodeRecords();
		//Display the functionCodeRecords for all functions 
		//	defined in the source code.

		void displayFunctionPrototypes();
		//Like displayFunctionCodeRecords(),
		//  but only sisplay the prototypes of the functions 
		//	defined in the source code.

		void displaySymbolTable(symbolTable & localVariablesTable);
		//Display the variables in a symbol table and their current values 

		void displayMapForNextInterpreterInstruction();
		//Display the information in mapForNextInterpreterInstruction



	private:
	//********************************************************************
	//*****			Section of Private member functions				******
	//********************************************************************

			//********************************************************************
			//*****			Private member functions for syntax analysis	******
			//********************************************************************
			bool buildLexicalInformation(const vector<string> & sourceProgram);
			//Use the lexical analysis mechanism implemented in lexScanner.cpp
			//	to derive lexical information from the source program, and store
			//	the lexical information of tokens of the lines in 
			//			tokenVectsSourcCodeAllLines
			//	and the categories of tokens of these lines in
			// 			categoryVectsSourcCodeAllLines
			//*********************************************************************


			//********************************************************************
			//*****	Private member functions for syntax & semantic analysis	******
			//********************************************************************
			bool buildSyntaxSemanticsInformation();
			//Use the syntax analysis mechanism implemented in the functions below
			//	to derive syntactic information from the lexical information and
			//	store the syntactic information of 
			//	(i)		the interpreter instructions ready for execution in
			//				vectInterpreterInstructions,
			//	(ii)	the table of names of functions defined and 
			//			the corresponding fucntion code records in
			//				tableOfFunctionNamesAndCodeRecords,
			// 	(iii)	the categories of the interpreter instructions in
			//				categoryVectOfAllInterpreterInstructions, and
			//	(iv)	the next-instruction-to-execute information for
			//			the contro-flow things like if, else, while in
			//				mapForNextInterpreterInstruction
			//*********************************************************************
				bool deriveNextInterpreterInstruction
					(	size_t fromLine, 
						size_t fromTokenIndex,
						perLineTokenVector & interpreterInstruction,
						perLineCategoryVector & itsCategoryVect,
						size_t & lineToStartNextTime, 
						size_t & tokenIndexToStartNextTime
					);
				//Derive the next interpreter instruction starting from 
				//	fromLine line and fromTokenIndex token in the source program,
				//Store the interpreter instruction and the categories of tokens in it
				//	in interpreterInstruction & itsCategoryVect,
				//Store where to start finding the next interpreter instruction in
				//	lineToStartNextTime and tokenIndexToStartNextTime.
				//Return false if already in the end of the source program,
				//	otherwise return true;


				//****************************************************************
				//Functions called by 
				//	doSyntaxSemanticsAnalysisOfOneInterpreterInstruction
				//****************************************************************
				interpreterInstructionCategory 
				getCategoryOfInterpreterInstruction
					(	perLineTokenVector & interpreterInstruction,
						perLineCategoryVector & itsCategoryVect
					);
				//Determine the category of an interpreter instruction.
				//Note that if the interpreter instruction is a scope delimter, 
				//	this function will only	return 
				//	either 
				//		BEGIN_ONE_BLOCK or 
				//		END_ONE_BLOCK 
				//	as its category.	
				//Code in doSyntaxSemanticsAnalysisOfOneInterpreterInstruction
				//	will later determine the delimiter as one of 	
				//		BEGIN_FUNCTION_DEFINTION_BLOCK,	
				//		END_FUNCTION_DEFINTION_BLOCK,	
				//		BEGIN_IF_BLOCK,	
				//		END_IF_BLOCK,		
				//		BEGIN_ELSE_BLOCK,	
				//		END_ELSE_BLOCK,		
				//		BEGIN_WHILE_BLOCK,	
				//		END_WHILE_BLOCK,	


				bool checkAndProcessVariablesAndExpressions
					(	perLineTokenVector & interpreterInstruction,
						perLineCategoryVector & itsCategoryVect,
						interpreterInstructionCategory instructionCategory,
						symbolTable & localVariablesTable
					);
				//Check the validity of the variables and the expressions 
				//	appear in the interpreter instruction with repsect to
				//	the local symbol table built so far.
				//If all are valid, add new variables that are seen  
				//	for the first time into the local variable table of 
				//	the current functionCode Record.
				//Return true if all are valid; otherwise return false.
				//
				//It calls the following two functions to do the job.

					bool areAllVariablesInSymbolTable
					(	perLineTokenVector & interpreterInstruction,
						perLineCategoryVector &tokenCategoryVect,
						size_t beginIndex,
						size_t endIndex,
						symbolTable & localVariablesTable
					);
					//Check to see whether all variables (tokens with ID_NAME category)
					//	in the range specified by [beginIndex, endIndex) are all already present
					//	in the localVariablesTable
					//	according to the token category information in tokenCategoryVect.
					//Return true if so; otherwise return false.


					bool addAllVariablesIntoSymbolTable
					(	perLineTokenVector & interpreterInstruction,
						perLineCategoryVector &tokenCategoryVect,
						size_t beginIndex,
						size_t endIndex,
						symbolTable & localVariablesTable
					);
					//Add all variables (tokens with ID_NAME category)
					//	in the range specified by [beginIndex, endIndex) are all already present
					//	into the localVariablesTable
					//	according to the token category information in tokenCategoryVect


				bool parseFunctionHeader
				(	perLineTokenVector & functionHeader,
					perLineCategoryVector & itsCategoryVect,
					string & functionName, 
					vector<string>& parametersList
				);
				//When the interprepter instruction is of the category:
				//	FUNCTION_HEADER_FUNCTION_STATEMENT
				//	i.e. a function header,
				//call this function to dertermine the function name and the parameter 
				//	to initialize the new functionCodeRecord
				//	that stores the information of the new function.
				//If something wrong in the function header or newfunctionCodeRecord,
				//	return flase; otherwise, return true.



				bool parseFunctionNameAndArgumentsListFromFunctionCallAssignmemt
				(	vector<string> & functionCallInterpreterInstruction,
					symbolTable & localVariablesTable,
					string & functionName,
					vector<float> & argumentsList
				);
				//Get the function name and the argument list from
				//	a functionCallAssignment Interpreter Instruction.
				//For example, from the following interpreter instruction
				//		x = gcd(4+6, y-1)
				//with variable value 1 for y,
				//	this function will derives "gcd" as the function name and 
				//	a vector of two values: 10 and 0 as the argument list.



				bool checkExpressionsInDisplayInterpreterInstruction
				(	perLineTokenVector & thisInterpreterInstruction,
					perLineCategoryVector & tokenCategoryVect,
					symbolTable & localVariablesTable
				);
				//Check to make sure all expressions in a display statement
				//	are valid. If so, return true; othersie return false.


				void addToTableOfFunctionNamesAndCodeRecords
					(functionCodeRecord & codeRecordToAdd);
				//Add a function code record to tableOfFunctionNamesAndCodeRecords
				//When the interprepter instruction is of the category:
				//	END_FUNCTION_DEFINTION_BLOCK
				//	i.e. a left curly brace ending the current function definition,
				//call this function to wrap up and store the function name
				//	and the contents of currentFunctionCodeRecord
				//	into tableOfFunctionNamesAndCodeRecords permanently.
				//Then empty the contents of currentFunctionCodeRecord.

				void updateMapForNextInterpreterInstruction
					(	int indexThisInterpreterInstruction,
						int indexNextInterpreterInstruction
					);
				//Add the next instruction information of one interpreter instruction
				//into MapForNextInterpreterInstruction.




};

//**************************************************************************************
//**************************************************************************************
#endif // Matching the starting #ifndef SYNTAX_H 