#ifndef _COMMON_MACRO_HPP_
#define _COMMON_MACRO_HPP_
#ifndef _COMMON_STRING_HPP_
#include <common/string.hpp>
#endif
#ifndef _COMMON_BLOCK_HPP_
#include <common/block.hpp>
#endif
#ifndef _COMMON_WINDOWS_HPP_
#include <common/windows.hpp>
#endif

class SymbolTable
{
public:
	SymbolTable();
	~SymbolTable();
	void pushSymbol(char symbol);
	void popSymbol(char &symbol);
	void popSymbol(void);
	void popSymbol(int numSymbols);
	WORD isInSymbols(char symbol);
private:
	enum {DefaultTableSize=256};
	String mSymbolTable;
	int mCurrentSymbols;
	int mTableSize;
};

inline
SymbolTable::SymbolTable()
: mCurrentSymbols(0), mTableSize(DefaultTableSize)
{
	mSymbolTable.reserve(DefaultTableSize);
}

inline
SymbolTable::~SymbolTable()
{
}

inline
void SymbolTable::pushSymbol(char symbol)
{
	if(mCurrentSymbols>=mTableSize)return;
	*((LPSTR)mSymbolTable+mCurrentSymbols)=symbol;
	mCurrentSymbols++;
}

inline
void SymbolTable::popSymbol(char &symbol)
{
	if(!mCurrentSymbols)return;
	--mCurrentSymbols;
	symbol=*((LPSTR)mSymbolTable+mCurrentSymbols);
}

inline
void SymbolTable::popSymbol(void)
{
	if(!mCurrentSymbols)return;
	--mCurrentSymbols;
}

inline
void SymbolTable::popSymbol(int numSymbols)
{
	if(mCurrentSymbols-numSymbols<0)return;
	mCurrentSymbols-=numSymbols;
}

// **********************************************************************************

class Macro : public SymbolTable
{
public:
	Macro(void);
	~Macro();
	void processEmbeddedMacro(String &someString);
private:
	enum Symbols{EnvMacroStart='$',EnvMacroSync='(',EnvMacroMid=',',EnvMacroEnd=')'};
	void expandEmbeddedMacro(void);
	void extractString(String &macroString);
	String locateFirstEnvironmentString(Block<String> &envStrings);
	WORD expandFunction(String &atFunction)const;
  WORD expandLiteral(String &literalString)const;
	WORD expect(char symbol);

  String mUnsetString;
	String mInputString;
	char *mlpPtrString;
};
#endif

