#include <stdio.h>		// Keyboard, printf
#include <malloc.h>		// malloc
#include <tchar.h>		// strcopy, ctrcmp

// Section required for MS Visual Studio
#include <io.h>
int isatty(int fd)	{ return _isatty(fd); }
int yywrap()		{ return 1; }
int exit();

// Our favorite error and information messages
#define MSG_E "ERROR IN LINE %d - you've written \"%s\" and I do not understand it\n\n     The lexer will now stop\n\n"
#define MSG_S "\nYour text file is meaningless or I am bugful... Stopped at line %d"
#define MSG_P "[ %3d, %2d ] Type %d, lexeme \"%s\"\n"
#define MSG_G "ERROR: your code has more than one goal!\n"

// Token type numbers, starting from 256
#define T_VAR		256		// Variable
#define T_INT		257		// Integer
#define T_STR		258		// String
#define T_K_IF		259		// Keyword "if"
#define T_K_ELS		260		// Keyword "else"
#define T_K_WHL		261		// Keyword "while"
#define T_K_INT		262		// Keyword "int"
#define T_K_VD		263		// Keyword "void"
#define T_K_DO		264		// Keyword "do"
#define T_K_RTN		265		// Keyword "return"
#define T_PLUS		266		// +
#define T_MINUS		267		// -
#define T_LBR		268		// (
#define T_RBR		269		// )
#define T_COMMA		270		// ,
#define T_SCLN		271		// ;
#define T_EQ		272		// =
#define T_MULT		273		// *
#define T_DIV		274		// /
#define T_PRCNT		275		// %
#define T_BARS		276		// ||
#define T_ANDS		277		// &&

// Hash table size
#define TABLE_SIZE	997		// Hash table size, 997 is a prime number

// Structure of a token
typedef struct token{
	char*			lexeme;	// Stored lexeme
	int				type;	// Type: actually, it is from 0 to 277 so int is a waste!
	struct token*	next;	// Pointer to next element if exists, otherwise NULL
} TOKEN;

// Structure of the tree
typedef struct tree{
	TOKEN*			token;	// The token
	struct tree*	left;	// Pointer to left branch if exists, otherwise NULL
	struct tree*	right;	// Pointer to right branch if exists, otherwise NULL
} TREE;

// Symbol table
TOKEN** sTab;

// Current token
TOKEN* cToken;

// Should I rollback (use cToken instead of yylex()) ?
int rollback = 0;

// Line counter (for better error messages)
int line = 1;

// Indent counter (for better printing)
int indent = 0;

// Function prototypes
int newToken(int TYPE);
int hash(char* text);
printTree(TREE* t);
TREE* is_goal(int n);
TREE* is_expression(int n);
TREE* is_term(int n);
TREE* is_factor(int n);
TREE* is_ifstatement(int n);