#include "Symbol.h"
#include "String.h"
#include "Value.h"
#include "Function.h"

//-----------------------------------------------------------------------------
// Heap access functions
//-----------------------------------------------------------------------------
#if defined(WINVER)
// malloc() and free() don't work correctly when they're used across
// Windows' DLL boundary. see KB190799 in MSDN.
void *operator new (size_t bytes)
{
	return ::LocalAlloc(LMEM_FIXED, bytes);
}

void operator delete (void *p)
{
	::LocalFree(p);
}
#endif

namespace AScript {

const int MAX_STACK_LEVEL = 20000;

//-----------------------------------------------------------------------------
// global functions
//-----------------------------------------------------------------------------
const Symbol *GetValueTypeSymbol(ValueType valType)
{
	return
		(valType == VTYPE_Invalid)?		AScript_Symbol(nil) :
		(valType == VTYPE_Number)?		AScript_Symbol(number) :
		(valType == VTYPE_Boolean)?		AScript_Symbol(boolean) :
		(valType == VTYPE_Symbol)?		AScript_Symbol(symbol) :
		(valType == VTYPE_String)?		AScript_Symbol(string) :
		(valType == VTYPE_Complex)?		AScript_Symbol(complex) :
		(valType == VTYPE_Module)?		AScript_Symbol(Module) :
		(valType == VTYPE_Class)?		AScript_Symbol(Class) :
		(valType == VTYPE_Object)?		AScript_Symbol(Object) :
		(valType == VTYPE_Function)?	AScript_Symbol(Function) :
		(valType == VTYPE_List)?		AScript_Symbol(List) :
		(valType == VTYPE_Dict)?		AScript_Symbol(Dict) :
		(valType == VTYPE_File)?		AScript_Symbol(File) :
		(valType == VTYPE_FileStat)?	AScript_Symbol(FileStat) :
		(valType == VTYPE_DateTime)?	AScript_Symbol(DateTime) :
		(valType == VTYPE_Expr)?		AScript_Symbol(Expr) :
		(valType == VTYPE_Environment)?	AScript_Symbol(Environment) :
		(valType == VTYPE_Error)?		AScript_Symbol(Error) :
		(valType == VTYPE_Struct)?		AScript_Symbol(Struct) :
		AScript_Symbol(unknown);
}

const Symbol *GetOccurPatternSymbol(OccurPattern occurPattern)
{
	return
		(occurPattern == OCCUR_ZeroOrOnce)? AScript_Symbol(Char_Question) :
		(occurPattern == OCCUR_ZeroOrMore)? AScript_Symbol(Char_Multiply) :
		(occurPattern == OCCUR_OnceOrMore)? AScript_Symbol(Char_Plus) :
		AScript_Symbol(Str_Empty);
}

const TCHAR *GetSignalTypeName(SignalType sigType)
{
	static const struct {
		SignalType sigType;
		const TCHAR *name;
	} tbl[] = {
		{ SIGTYPE_None,		_T("none"),		},
		{ SIGTYPE_Error,	_T("error"),	},
		{ SIGTYPE_Break,	_T("break"),	},
		{ SIGTYPE_Continue,	_T("continue"),	},
		{ SIGTYPE_Return,	_T("return"),	},
	};
	for (int i = 0; i < NUMBEROF(tbl); i++) {
		if (tbl[i].sigType == sigType) return tbl[i].name;
	}
	return _T("unknown");
}

const TCHAR *GetEnvTypeName(EnvType envType)
{
	static const struct {
		EnvType envType;
		const TCHAR *name;
	} tbl[] = {
		{ ENVTYPE_Invalid,	_T("invalid"),	},
		{ ENVTYPE_Root,		_T("root"),		},
		{ ENVTYPE_Local,	_T("local"),	},
		{ ENVTYPE_Block,	_T("block"),	},
		{ ENVTYPE_Module,	_T("module"),	},
		{ ENVTYPE_Class,	_T("class"),	},
		{ ENVTYPE_Instance,	_T("instance"),	},
		{ ENVTYPE_Method,	_T("method"),	},
	};
	for (int i = 0; i < NUMBEROF(tbl); i++) {
		if (tbl[i].envType == envType) return tbl[i].name;
	}
	return _T("unknown");
}

const TCHAR *GetErrorTypeName(ErrorType errType)
{
	static const struct {
		ErrorType errType;
		const TCHAR *name;
	} tbl[] = {
		{ ERR_None,					_T("None")				},
		{ ERR_SyntaxError,			_T("SyntaxError")		},
		{ ERR_ArithmeticError,		_T("ArithmeticError")	},
		{ ERR_TypeError,			_T("TypeError")			},
		{ ERR_ZeroDivisionError,	_T("ZeroDivisionError")	},
		{ ERR_ValueError,			_T("ValueError")		},
		{ ERR_SystemError,			_T("SyntaxError")		},
		{ ERR_IOError,				_T("IOError")			},
		{ ERR_IndexError,			_T("IndexError")		},
		{ ERR_KeyError,				_T("KeyError")			},
		{ ERR_ImportError,			_T("ImportError")		},
		{ ERR_AttributeError,		_T("AttributeError")	},
	};
	for (int i = 0; i < NUMBEROF(tbl); i++) {
		if (tbl[i].errType == errType) return tbl[i].name;
	}
	return _T("unknown");
}

}
