#include <lexer/Lexer.h>

#include <alib/string>

namespace cli {

Lexer::Token Lexer::nextToken ( bool readNextLine ) {
	Token res { "", "", TokenType::ERROR };

	res.m_raw_line = m_source.getLine ( );
	res.m_raw_position = m_source.getPosition ( );

	switch ( m_hint ) {
	case Hint::NONE:
		goto q0;
	case Hint::FILE:
		goto qFile;
	case Hint::TYPE:
		goto qType;
	}

q0:	if ( m_source.getCharacter ( ) == EOF ) {
		res.m_type = TokenType::EOT;
		return res;
	}
	if ( m_source.getCharacter ( ) == '\0' ) {
		res.m_type = TokenType::EOS;
		return res;
	}
	if ( ext::isspace ( m_source.getCharacter ( ) ) ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( readNextLine );
		goto q0;
	}

	res.m_line = m_source.getLine ( );
	res.m_position = m_source.getPosition ( );

	if ( m_source.getCharacter ( ) == '<' ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( readNextLine );
		res.m_type = TokenType::LESS_THAN;
		goto q10;
	}
	if ( m_source.getCharacter ( ) == '>' ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( readNextLine );
		res.m_type = TokenType::MORE_THAN;
		goto q11;
	}
	if ( m_source.getCharacter ( ) == '(' ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( readNextLine );
		res.m_type = TokenType::LEFT_PAREN;
		return res;
	}
	if ( m_source.getCharacter ( ) == ')' ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( readNextLine );
		res.m_type = TokenType::RIGHT_PAREN;
		return res;
	}
	if ( m_source.getCharacter ( ) == '{' ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( readNextLine );
		res.m_type = TokenType::LEFT_BRACE;
		return res;
	}
	if ( m_source.getCharacter ( ) == '}' ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( readNextLine );
		res.m_type = TokenType::RIGHT_BRACE;
		return res;
	}
	if ( m_source.getCharacter ( ) == '[' ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( readNextLine );
		res.m_type = TokenType::LEFT_BRACKET;
		return res;
	}
	if ( m_source.getCharacter ( ) == ']' ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( readNextLine );
		res.m_type = TokenType::RIGHT_BRACKET;
		return res;
	}
	if ( m_source.getCharacter ( ) == '@' ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( readNextLine );
		res.m_type = TokenType::AT_SIGN;
		return res;
	}
	if ( m_source.getCharacter ( ) == '$' ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( readNextLine );
		res.m_type = TokenType::DOLLAR_SIGN;
		return res;
	}
	if ( m_source.getCharacter ( ) == '&' ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( readNextLine );
		res.m_type = TokenType::AMPERSAND_SIGN;
		goto q8;
	}
	if ( m_source.getCharacter ( ) == '|' ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( readNextLine );
		res.m_type = TokenType::PIPE_SIGN;
		goto q9;
	}
	if ( m_source.getCharacter ( ) == '^' ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( readNextLine );
		res.m_type = TokenType::CARET_SIGN;
		return res;
	}
	if ( m_source.getCharacter ( ) == ':' ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( readNextLine );
		res.m_type = TokenType::COLON_SIGN;
		return res;
	}
	if ( m_source.getCharacter ( ) == ';' ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( readNextLine );
		res.m_type = TokenType::SEMICOLON_SIGN;
		return res;
	}
	if ( m_source.getCharacter ( ) == '=' ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( readNextLine );
		res.m_type = TokenType::ASSIGN;
		goto q12;
	}
	if ( m_source.getCharacter ( ) == '#' ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( readNextLine );
		res.m_type = TokenType::HASH_SIGN;
		return res;
	}
	if ( m_source.getCharacter ( ) == ',' ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( readNextLine );
		res.m_type = TokenType::COMMA;
		return res;
	}
	if ( m_source.getCharacter ( ) == '-' ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		res.m_value += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( readNextLine );
		goto q2;
	}
	if ( m_source.getCharacter ( ) == '+' ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( readNextLine );
		res.m_type = TokenType::PLUS_SIGN;
		goto q7;
	}
	if ( m_source.getCharacter ( ) == '/' ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( readNextLine );
		res.m_type = TokenType::SLASH_SIGN;
		goto qComment;
	}
	if ( m_source.getCharacter ( ) == '*' ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( readNextLine );
		res.m_type = TokenType::ASTERISK_SIGN;
		return res;
	}
	if ( m_source.getCharacter ( ) == '~' ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( readNextLine );
		res.m_type = TokenType::TILDE_SIGN;
		return res;
	}
	if ( m_source.getCharacter ( ) == '!' ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( readNextLine );
		res.m_type = TokenType::EXCLAMATION_SIGN;
		goto q13;
	}
	if ( m_source.getCharacter ( ) == '%' ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( readNextLine );
		res.m_type = TokenType::PERCENTAGE_SIGN;
		return res;
	}
	if ( m_source.getCharacter ( ) == '.' ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		res.m_value += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( readNextLine );
		res.m_type = TokenType::DOT;
		goto q14;
	}

	if ( m_source.getCharacter ( ) == '"' ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		res.m_type = TokenType::STRING;
		m_source.advance ( true );
		goto q4;
	}

	if ( ( m_source.getCharacter ( ) >= '0' && m_source.getCharacter ( ) <= '9' ) ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		res.m_value += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( readNextLine );
		goto q1;
	}

	if ( ( m_source.getCharacter ( ) >= 'a' && m_source.getCharacter ( ) <= 'z' )
	  || ( m_source.getCharacter ( ) >= 'A' && m_source.getCharacter ( ) <= 'Z' ) ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		res.m_value += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( readNextLine );
		goto q3;
	}

	if ( m_source.getCharacter ( ) == '\\' ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( true );
		goto q3Escape;
	}

	res.m_type = TokenType::ERROR;
	return res;

q1:	if ( m_source.getCharacter ( ) == '\0' ) {
		res.m_type = TokenType::UNSIGNED;
		return res;
	}
	if ( ( m_source.getCharacter ( ) >= '0' && m_source.getCharacter ( ) <= '9' ) ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		res.m_value += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( readNextLine );
		goto q1;
	} else if ( m_source.getCharacter ( ) == '.' ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		res.m_value += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( readNextLine );
		res.m_type = TokenType::DOUBLE;
		goto q15;
	} else {
		res.m_type = TokenType::UNSIGNED;
		return res;
	}
q2:
	if ( m_source.getCharacter ( ) == '\0' ) {
		res.m_value = "";
		res.m_type = TokenType::MINUS_SIGN;
		return res;
	}
	if ( m_source.getCharacter ( ) == '-' ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		res.m_value += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( readNextLine );
		goto q2Prime;
	}

	if ( ( m_source.getCharacter ( ) >= 'a' && m_source.getCharacter ( ) <= 'z' )
	  || ( m_source.getCharacter ( ) >= 'A' && m_source.getCharacter ( ) <= 'Z' )
	  || ( m_source.getCharacter ( ) == ':' ) ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		res.m_value += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( readNextLine );
		goto q3;
	} else if ( m_source.getCharacter ( ) == '\\' ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( true );
		goto q3Escape;
	}

	res.m_value = "";
	res.m_type = TokenType::MINUS_SIGN;
	return res;

q2Prime:
	if ( m_source.getCharacter ( ) == '\0' ) {
		res.m_value = "";
		res.m_type = TokenType::DEC;
		return res;
	}
	if ( ( m_source.getCharacter ( ) >= '0' && m_source.getCharacter ( ) <= '9' )
	  || ( m_source.getCharacter ( ) >= 'a' && m_source.getCharacter ( ) <= 'z' )
	  || ( m_source.getCharacter ( ) >= 'A' && m_source.getCharacter ( ) <= 'Z' )
	  || ( m_source.getCharacter ( ) == ':' ) ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		res.m_value += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( readNextLine );
		goto q3;
	} else if ( m_source.getCharacter ( ) == '\\' ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( true );
		goto q3Escape;
	}

	res.m_value = "";
	res.m_type = TokenType::DEC;
	return res;

q3:	if ( m_source.getCharacter ( ) == '\0' ) {
		res.m_type = is_kw ( res.m_value );
		return res;
	}
	if ( ( m_source.getCharacter ( ) >= '0' && m_source.getCharacter ( ) <= '9' )
	  || ( m_source.getCharacter ( ) >= 'a' && m_source.getCharacter ( ) <= 'z' )
	  || ( m_source.getCharacter ( ) >= 'A' && m_source.getCharacter ( ) <= 'Z' )
	  || ( m_source.getCharacter ( ) == ':' ) ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		res.m_value += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( readNextLine );
		goto q3;
	} else if ( m_source.getCharacter ( ) == '\\' ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( true );
		goto q3Escape;
	} else {
		res.m_type = is_kw ( res.m_value );
		return res;
	}

q3Escape:
	if ( m_source.getCharacter ( ) == '\0' ) {
		res.m_type = TokenType::ERROR;
		return res;
	}

	res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
	res.m_value += static_cast < char > ( m_source.getCharacter ( ) );
	m_source.advance ( readNextLine );
	goto q3;

q4:	if ( m_source.getCharacter ( ) == '\0' ) {
		res.m_type = TokenType::ERROR;
		return res;
	}
	if ( m_source.getCharacter ( ) == '"' ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( readNextLine );
		goto q6;
	}
	if ( m_source.getCharacter ( ) == '\\' ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( true );
		goto q5;
	} else {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		res.m_value += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( true );
		goto q4;
	}

q5:	if ( m_source.getCharacter ( ) == '\0' ) {
		res.m_type = TokenType::ERROR;
		return res;
	}

	if ( m_source.getCharacter ( ) == 'n' ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		res.m_value += '\n';
	} else if ( m_source.getCharacter ( ) == 't' ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		res.m_value += '\t';
	} else if ( m_source.getCharacter ( ) == '"' ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		res.m_value += '"';
	} else {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		res.m_value += static_cast < char > ( m_source.getCharacter ( ) );
	}

	m_source.advance ( true );
	goto q4;

q6:	if ( m_source.getCharacter ( ) == '\0' ) {
		return res;
	}
	if ( ext::isspace ( m_source.getCharacter ( ) ) ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( readNextLine );
		goto q6;
	}
	if ( m_source.getCharacter ( ) == '"' ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( true );
		goto q4;
	} else {
		return res;
	}

q7: if ( m_source.getCharacter ( ) == EOF ) {
		return res;
	}
	if ( m_source.getCharacter ( ) == '\0' ) {
		return res;
	}
	if ( m_source.getCharacter ( ) == '+' ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( readNextLine );
		res.m_type = TokenType::INC;
	} else {
		return res;
	}

q8: if ( m_source.getCharacter ( ) == EOF ) {
		return res;
	}
	if ( m_source.getCharacter ( ) == '\0' ) {
		return res;
	}
	if ( m_source.getCharacter ( ) == '&' ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( readNextLine );
		res.m_type = TokenType::AND;
	} else {
		return res;
	}

q9: if ( m_source.getCharacter ( ) == EOF ) {
		return res;
	}
	if ( m_source.getCharacter ( ) == '\0' ) {
		return res;
	}
	if ( m_source.getCharacter ( ) == '|' ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( readNextLine );
		res.m_type = TokenType::OR;
	} else {
		return res;
	}

q10:
	if ( m_source.getCharacter ( ) == EOF ) {
		return res;
	}
	if ( m_source.getCharacter ( ) == '\0' ) {
		return res;
	}
	if ( m_source.getCharacter ( ) == '=' ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( readNextLine );
		res.m_type = TokenType::LESS_THAN_OR_EQUAL;
	} else {
		return res;
	}

q11:
	if ( m_source.getCharacter ( ) == EOF ) {
		return res;
	}
	if ( m_source.getCharacter ( ) == '\0' ) {
		return res;
	}
	if ( m_source.getCharacter ( ) == '=' ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( readNextLine );
		res.m_type = TokenType::MORE_THAN_OR_EQUAL;
	} else {
		return res;
	}

q12:
	if ( m_source.getCharacter ( ) == EOF ) {
		return res;
	}
	if ( m_source.getCharacter ( ) == '\0' ) {
		return res;
	}
	if ( m_source.getCharacter ( ) == '=' ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( readNextLine );
		res.m_type = TokenType::EQUAL;
	} else {
		return res;
	}

q13:
	if ( m_source.getCharacter ( ) == EOF ) {
		return res;
	}
	if ( m_source.getCharacter ( ) == '\0' ) {
		return res;
	}
	if ( m_source.getCharacter ( ) == '=' ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( readNextLine );
		res.m_type = TokenType::NOT_EQUAL;
	} else {
		return res;
	}

q14:
	if ( m_source.getCharacter ( ) == EOF ) {
		return res;
	}
	if ( m_source.getCharacter ( ) == '\0' ) {
		return res;
	}
	if ( ( m_source.getCharacter ( ) >= '0' && m_source.getCharacter ( ) <= '9' ) ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		res.m_value += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( readNextLine );
		res.m_type = TokenType::DOUBLE;
		goto q15;
	} else {
		return res;
	}

q15:
	if ( m_source.getCharacter ( ) == EOF ) {
		return res;
	}
	if ( m_source.getCharacter ( ) == '\0' ) {
		return res;
	}
	if ( ( m_source.getCharacter ( ) >= '0' && m_source.getCharacter ( ) <= '9' ) ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		res.m_value += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( readNextLine );
		goto q15;
	} else {
		return res;
	}

qFile:
	if ( m_source.getCharacter ( ) == EOF ) {
		res.m_type = TokenType::EOT;
		return res;
	}
	if ( m_source.getCharacter ( ) == '\0' ) {
		res.m_type = TokenType::EOS;
		return res;
	}
	if ( ext::isspace ( m_source.getCharacter ( ) ) ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( readNextLine );
		goto qFile;
	}
	if ( ( m_source.getCharacter ( ) >= '0' && m_source.getCharacter ( ) <= '9' )
	  || ( m_source.getCharacter ( ) >= 'a' && m_source.getCharacter ( ) <= 'z' )
	  || ( m_source.getCharacter ( ) >= 'A' && m_source.getCharacter ( ) <= 'Z' )
	  ||   m_source.getCharacter ( ) == '/' || m_source.getCharacter ( ) == '.' || m_source.getCharacter ( ) == '-'
	  ||   m_source.getCharacter ( ) == '~' || m_source.getCharacter ( ) == '_' || m_source.getCharacter ( ) == ':' ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		res.m_value += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( readNextLine );
		goto qFile2;
	} else {
		goto q0;
	}

qFile2:
	if ( m_source.getCharacter ( ) == '\0' ) {
		res.m_type = TokenType::FILE;
		return res;
	}
	if ( ( m_source.getCharacter ( ) >= '0' && m_source.getCharacter ( ) <= '9' )
	  || ( m_source.getCharacter ( ) >= 'a' && m_source.getCharacter ( ) <= 'z' )
	  || ( m_source.getCharacter ( ) >= 'A' && m_source.getCharacter ( ) <= 'Z' )
	  ||   m_source.getCharacter ( ) == '/' || m_source.getCharacter ( ) == '.' || m_source.getCharacter ( ) == '-'
	  ||   m_source.getCharacter ( ) == '~' || m_source.getCharacter ( ) == '_' || m_source.getCharacter ( ) == ':' ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		res.m_value += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( readNextLine );
		goto qFile2;
	} else if ( m_source.getCharacter ( ) == '\\' ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( true );
		goto qFileEscape;
	} else {
		res.m_type = TokenType::FILE;
		return res;
	}

qFileEscape:
	if ( m_source.getCharacter ( ) == '\0' ) {
		res.m_type = TokenType::ERROR;
		return res;
	}

	res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
	res.m_value += static_cast < char > ( m_source.getCharacter ( ) );
	m_source.advance ( readNextLine );
	goto qFile2;

qType:
	if ( m_source.getCharacter ( ) == EOF ) {
		res.m_type = TokenType::EOT;
		return res;
	}
	if ( m_source.getCharacter ( ) == '\0' ) {
		res.m_type = TokenType::EOS;
		return res;
	}
	if ( ext::isspace ( m_source.getCharacter ( ) ) ) {
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( readNextLine );
		goto qType;
	}
	if ( m_source.getCharacter ( ) == ')' ) {
		goto q0;
	}

	{
		unsigned lparens = 0;
		while ( m_source.getCharacter ( ) != '\0' ) {
			if ( m_source.getCharacter ( ) == '(' )
				++ lparens;
			else if ( m_source.getCharacter ( ) == ')' && lparens > 0 )
				-- lparens;
			else if ( m_source.getCharacter ( ) == ')' ) {
				break;
			}
			res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
			res.m_value += static_cast < char > ( m_source.getCharacter ( ) );
			m_source.advance ( readNextLine );
		}
		res.m_value = ext::rtrim ( res.m_value );

		res.m_type = TokenType::TYPE;
		return res;
	}

qComment :
	if ( m_source.getCharacter ( ) == EOF ) {
		return res;
	}
	if ( m_source.getCharacter ( ) == '\0' ) {
		return res;
	}

	if ( m_source.getCharacter ( ) == '/' ) {
		res.m_value = "";
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( readNextLine );

		while ( m_source.getCharacter ( ) != EOF && m_source.getCharacter ( ) != '\n' && m_source.getCharacter ( ) != '\0' ) {
			res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
			m_source.advance ( readNextLine );
		}

		if ( m_source.getCharacter ( ) == '\n' ) {
			res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
			m_source.advance ( readNextLine );
		}
	} else if ( m_source.getCharacter ( ) == '*' ) {
		res.m_value = "";
		res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
		m_source.advance ( true );

		do {
			while ( m_source.getCharacter ( ) != EOF && m_source.getCharacter ( ) != '*' && m_source.getCharacter ( ) != '\0' ) {
				res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
				m_source.advance ( true );
			}

			if ( m_source.getCharacter ( ) == '*' ) {
				res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
				m_source.advance ( true );
			}
		} while ( m_source.getCharacter ( ) != EOF && m_source.getCharacter ( ) != '/' && m_source.getCharacter ( ) != '\0' );

		if ( m_source.getCharacter ( ) == '/' ) {
			res.m_raw += static_cast < char > ( m_source.getCharacter ( ) );
			m_source.advance ( readNextLine );
		}
	} else {
		return res;
	}

	goto q0;

}

} /* namespace cli */
