/****************************************************************************
	Kalkulon - A programmable calculator for programmers

	This file is part of the Kalkulon core.
	
	If you find this source code useful, your are encouraged to use it in your own projects.
	Please give me credit!

	COPYRIGHT by Juergen Holetzeck 2003 - 2008
	e-mail:		contact@kalkulon.de
	homepage:	www.kalkulon.de
****************************************************************************/



// Token.h: interface for the Token class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_TOKEN_H__67BE24A6_BFFA_11D6_B257_00300511F21B__INCLUDED_)
#define AFX_TOKEN_H__67BE24A6_BFFA_11D6_B257_00300511F21B__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <string>
#include <list>
#include <ostream>

namespace Kalkulon{
////////////////////////////////////////////////////////////////////////////// 
// Token
struct Token
{
	////////////////////////////////////////////////////////////////////////////// 
	// recognized tokens
	enum TokenId
	{
			UNKNOWN		= 0,
			// recognized by parser
			LSFUNC		= 0x1000,
			FUNC,
			LSNAME,
			NEG,
			PREINC,
			PREDEC,
			POSTINC,
			POSTDEC,
			//statements//
			WHILE,
			DO,
			IF,
			FOR,
			// recognized by lexer
			DATAOBJECT,
			NAME,
			END,
			BLOCKEND,
			CAST_U08,
			CAST_U16,
			CAST_U32,
			CAST_S08,
			CAST_S16,
			CAST_S32,
			CAST_STRING,
			LSHIFT,
			RSHIFT,
			POW,
			LOGICAL_OR,
			LOGICAL_AND,
			EQUAL,
			NOT_EQUAL,
			LESSER_EQUAL,
			GREATER_EQUAL,
			SCOPE,			// "::" scope operator 
			INC,			// "++"
			DEC,			// "--"
			GREATER			= '>',
			LESSER			= '<',
			DELIM			= ';',
			SEP				= ',',
			PLUS			= '+',
			MINUS			= '-',
			MUL				= '*',
			DIV				= '/',
			MOD				= '%',
			NOT				= '~',
			LOGICAL_NOT		= '!',
			AND				= '&',
			XOR				= '^',
			OR				= '|',
 			ASSIGN			= '=',
			LP				= '(',
			RP				= ')',
			LISTBEGIN		= '{',
			LISTEND			= '}',
			INDEXBEGIN		= '[',
			INDEXEND		= ']',
			PUREFUNC		= '\'',
			EVALPF          = '@',	// eval pure function
	};
	
	////////////////////////////////////////////////////////////////////////////// 
	// token flags
	enum TokenFlags
	{
		FLAG_DEFAULT			= 0x00,	
    FLAG_GLOBALSCOPE	= 0x01,
		FLAG_INDEXED			= 0x02
	};
	
	TokenId				tid;	// token ID
	TokenId				sid;	// sub ID e.g. "abc +=..." -> tid=LSNAME, sid=PLUS
  int           pos;
  unsigned int	uid;

  std::string		token_str;
  int           token_int;
  TokenFlags		token_flags;
  DataObject		data;

	// optimization of loops etc.: for functions remember function index and pointer to function list
  size_t			func_idx;
	void*				pfn_list;

  //////////////////////////////////////////////////////////////
  // methods
  Token():tid(UNKNOWN),sid(UNKNOWN),pos(0),uid(0),token_int(0),token_flags(FLAG_DEFAULT),func_idx(0) {}
  Token(TokenId tid_, int pos_=0, unsigned int uid_=0):tid(tid_),sid(UNKNOWN),pos(pos_),uid(uid_),token_int(0),token_flags(FLAG_DEFAULT),func_idx(0) {}

  operator std::string();
  bool  operator== (const Token& rhs) const;
  bool  operator!= (const Token& rhs) const;


  //////////////////////////////////////////////////////////////
  // methods for persisting Token state
  void serialize(std::ostream& os) const;
  static Token deserialize(std::istream& is);
  //

};


}

std::ostream& operator<< (std::ostream& out, Kalkulon::Token& t);



#endif // !defined(AFX_TOKEN_H__67BE24A6_BFFA_11D6_B257_00300511F21B__INCLUDED_)
