#ifndef __SIGNAL_H__
#define __SIGNAL_H__

#include "Common.h"

namespace AScript {

class Expr;

//-----------------------------------------------------------------------------
// Signal
//-----------------------------------------------------------------------------
class Signal {
private:
	struct Message {
		SignalType sigType;
		ErrorType errType;
		ErrorType errTypeSaved;
		String str;
		String strSaved;
		std::auto_ptr<Value> pValue;
		const Expr *pExprCause;
		Message();
	};
private:
	Message *_pMsg;
	int _stackLevel;
public:
	Signal();
	Signal(const Signal &sig);
	inline bool IsSignalled() const	{ return _pMsg->sigType != SIGTYPE_None; }
	inline bool IsError() const		{ return _pMsg->sigType == SIGTYPE_Error; }
	inline bool IsBreak() const		{ return _pMsg->sigType == SIGTYPE_Break; }
	inline bool IsContinue() const	{ return _pMsg->sigType == SIGTYPE_Continue; }
	inline bool IsReturn() const	{ return _pMsg->sigType == SIGTYPE_Return; }
	inline const TCHAR *GetSignalName() const { return GetSignalTypeName(_pMsg->sigType); }
	inline const TCHAR *GetErrorName() const { return GetErrorTypeName(_pMsg->errType); }
	inline const TCHAR *GetSavedString() const { return _pMsg->strSaved.c_str(); }
	inline Value &GetValue() const { return *_pMsg->pValue; }
	inline void ClearSignal() {
		_pMsg->sigType = SIGTYPE_None, _pMsg->errType = ERR_None;
		_pMsg->pExprCause = NULL;
	}
	inline void SetSignal(SignalType sigType, const Value &value) {
		_pMsg->sigType = sigType, *_pMsg->pValue = value;
	}
	inline void SaveError() {
		_pMsg->errTypeSaved = _pMsg->errType, _pMsg->strSaved = _pMsg->str;
	}
	inline void SetExprCause(const Expr *pExpr) {
		if (_pMsg->pExprCause == NULL) _pMsg->pExprCause = pExpr;
	}
	inline const Expr *GetExprCause() const { return _pMsg->pExprCause; }
	String GetErrString() const;
	inline GetSavedErrorType() const { return _pMsg->errTypeSaved; }
	void SetError(ErrorType errType, const TCHAR *format, ...);
	void SetErrorV(ErrorType errType,
			const TCHAR *format, va_list list, const TCHAR *textPre = _T(""));
};

}

#endif
