/* MasC interpreter/compiler
   (Master Assembly Script Container)
   written by Jared Bruni
   
   After reading Writing Compilers and Interpreters A approach using C++ by Ronald Mak
   and the Dragon Book
   code completly re-written but using concepts teached in this book
*/
// parser (syntax anaylizer) function implementations

#include "parser.h"



// Skip Comments
char *skipSpaces(char *p_c)
{
	if(*p_c == '#')
    	while(*p_c != '\n')
		{
			p_c++;
		}

	return p_c;
}

// Convert to Intermediate Code (Byte Code)
void parse(struct text_in *ti, struct Token *tokens)
{
	unsigned long line = 0;
	int tokens_count = 0;
	char text[max_string_size];
	FILE *f_ptr;
	int pos = 0; 
	int ident_count = 0;

	if(lexAnaylize(ti) != 1) // only continue to parse the file if it passes the lexical anyalizer phase
		return;


	ti->ptr_c = ti->buff;

	f_ptr = fopen(outfile, "wb");

	put_byte(f_ptr, 101);
	put_int(f_ptr, 100);
	put_int(f_ptr, 100);
	if(!f_ptr) 
	{
		printError("Could not create file.\n");
		return;
	}
	while(*ti->ptr_c != 0)
	{
		if(*ti->ptr_c == '\n' && *ti->ptr_c != '#')
		{
			ti->ptr_c = skipSpaces(ti->ptr_c);
		}                 
		else
			ti->ptr_c = skipSpaces(ti->ptr_c);

		if(*ti->ptr_c == '\"') {
			do {
				if(*ti->ptr_c == '\\')
				{
					ti->ptr_c++;
					switch(*ti->ptr_c)
					{
					case 'n':
						text[pos] = '\n';
						break;
					case 't':
						text[pos] = '\t';
						break;
					case '\"':
						text[pos] = '\"';
						break;                              
					}

					pos++;
					ti->ptr_c++;
				} else {

					text[pos++] = *ti->ptr_c;
					ti->ptr_c++;
			}
			} while (*ti->ptr_c != '\"');
		}
		else {
			*ti->ptr_c = tolower(*ti->ptr_c);
		}

		if(*ti->ptr_c != ' ' && *ti->ptr_c != 0 && *ti->ptr_c != ';' && *ti->ptr_c != '\n' && *ti->ptr_c != '\r' && *ti->ptr_c != ',') {
			text[pos++] = *ti->ptr_c;
		}
		else
		{
			int ident = 0;
			if(*ti->ptr_c == '\n')
			{
				line++;
			}

			text[pos] = 0;
			ident = convertIdentifier(text);
			if(ident == NOT_FOUND)
			{
				int c =(int)strlen(text);
				if(c != 0) {
					if(isdigit(text[0]))
					{
						put_byte(f_ptr,99);
						put_int(f_ptr, c);
						put_strc(f_ptr,text);
					}
					else {
						put_byte(f_ptr, 100);
						put_int(f_ptr, c);
						put_strc(f_ptr, text);
					}
					ident_count++;
				}
			}
			else
				put_byte(f_ptr,ident);

			tokens_count++;
			pos = 0;
			text[pos] = 0;
		}
		ti->ptr_c++;
		ti->ptr_c = skipSpaces(ti->ptr_c);

	}

	put_byte(f_ptr, End);
	line_count = line;
	fgoto(f_ptr, sizeof(char));
	put_int(f_ptr, ident_count);
	put_int(f_ptr, tokens_count);
	fclose(f_ptr);
}




// convert a Identifier as a string to its code
int convertIdentifier(char *str)
{
	int i;

	if(strcmp(" mas", str) == 0)
			return MAS;

	for(i = 0; syntax_str[i+1] != NULL; i++)
	{
		if(strcmp(syntax_str[i], str) == 0)
			return i;   
		if(strcmp(syntax_str[i+1], str) == 0)
			return i+1;
	}   

	return NOT_FOUND;
}

// get Reserved symbols list
int getReservedLen()
{
	int i;
	for(i = 0; syntax_str[i] != NULL; i++) {}
	return i;
}

// put a byte to the file stream
void put_byte(FILE *fptr, char byte_)
{
	if(verbose == 1) 
		printf("put byte[%d]\n", byte_);


	fwrite((char*)&byte_,sizeof(char),1, fptr); 
}

// put a string to the file stream
void put_strc(FILE *fptr, const char *str)
{
	if(strlen(str) != 0) {

		if(verbose == 1)
			printf("put string[%s]\n", str);

		fwrite((char*)str, sizeof(char), strlen(str), fptr);
	}
}
// put a integer to the file stream
void put_int(FILE *fptr, const int integer)
{
	if(verbose == 1)
		printf("put integer [%d]\n", integer);

	fwrite((char*)&integer, sizeof(int), 1, fptr);
}

// put a float to the file stream
void put_float(FILE *ptr, const float the_float)
{
	if(verbose == 1)
		printf("put float [%f]\n", the_float);

	fwrite((char*)&the_float, sizeof(float), 1, ptr);
}
// seek position in file stream
void fgoto(FILE *fptr, int loc)
{
	fseek(fptr, loc, SEEK_SET);
}

// check bounds of array 
int checkBounds(struct BackEnd *bend, int size)
{
	if(bend->inc_len < size)
		return 0;

	return 1;   
}
// here comes the Sun and I say its alright
// I wanna be a paperback writer
