src/compiler/lexer.c
static inline Token scan_ident(void)
{
	// If we're in ignore keywords state, simply skip stuff.
	if (lexer.lexer_state == LEXER_STATE_DEFERED_PARSING)
	{
		scan_skipped_ident();
		return make_token(TOKEN_VAR_IDENT);
	}

	TokenType type = 0;
	uint32_t hash = FNV1_SEED;
	while (peek() == '_')
	{
		hash = FNV1a(next(), hash);
	}
	while (1)
	{
		switch (peek())
		{
			case 'a': case 'b': case 'c': case 'd': case 'e':
			case 'f': case 'g': case 'h': case 'i': case 'j':
			case 'k': case 'l': case 'm': case 'n': case 'o':
			case 'p': case 'q': case 'r': case 's': case 't':
			case 'u': case 'v': case 'w': case 'x': case 'y':
			case 'z':
				if (!type)
				{
					type = TOKEN_VAR_IDENT;
				}
				else if (type == TOKEN_CAPS_IDENT)
				{
					type = TOKEN_TYPE_IDENT;
				}
				break;
			case 'A': case 'B': case 'C': case 'D': case 'E':
			case 'F': case 'G': case 'H': case 'I': case 'J':
			case 'K': case 'L': case 'M': case 'N': case 'O':
			case 'P': case 'Q': case 'R': case 'S': case 'T':
			case 'U': case 'V': case 'W': case 'X': case 'Y':
			case 'Z':
				if (!type) type = TOKEN_CAPS_IDENT;
				break;
			case '0': case '1': case '2': case '3': case '4':
			case '5': case '6': case '7': case '8': case '9':
				if (!type) return error_token("A letter must preceed any digit");
			case '_':
				break;
			default:
				goto EXIT;
		}
		hash = FNV1a(next(), hash);
	}
	EXIT:;
	if (type == INVALID_TOKEN) error_token("An identifier may not only consist of '_'");
	uint32_t len = lexer.current - lexer.start;
	const char* interned_string = symtab_add(lexer.start, len, hash, &type);
	return make_string_token(type, interned_string);
}
// Parses identifiers. Note that this is a bit complicated here since
// we split identifiers into 3 types + find keywords.
Parses identifiers. Note that this is a bit complicated here since
we split identifiers into 3 types + find keywords.
Parses identifiers . Note that this is a bit complicated here since we split identifiers into 3 types + find keywords .
static inline Token scan_ident(void)
{
	if (lexer.lexer_state == LEXER_STATE_DEFERED_PARSING)
	{
		scan_skipped_ident();
		return make_token(TOKEN_VAR_IDENT);
	}
	TokenType type = 0;
	uint32_t hash = FNV1_SEED;
	while (peek() == '_')
	{
		hash = FNV1a(next(), hash);
	}
	while (1)
	{
		switch (peek())
		{
			case 'a': case 'b': case 'c': case 'd': case 'e':
			case 'f': case 'g': case 'h': case 'i': case 'j':
			case 'k': case 'l': case 'm': case 'n': case 'o':
			case 'p': case 'q': case 'r': case 's': case 't':
			case 'u': case 'v': case 'w': case 'x': case 'y':
			case 'z':
				if (!type)
				{
					type = TOKEN_VAR_IDENT;
				}
				else if (type == TOKEN_CAPS_IDENT)
				{
					type = TOKEN_TYPE_IDENT;
				}
				break;
			case 'A': case 'B': case 'C': case 'D': case 'E':
			case 'F': case 'G': case 'H': case 'I': case 'J':
			case 'K': case 'L': case 'M': case 'N': case 'O':
			case 'P': case 'Q': case 'R': case 'S': case 'T':
			case 'U': case 'V': case 'W': case 'X': case 'Y':
			case 'Z':
				if (!type) type = TOKEN_CAPS_IDENT;
				break;
			case '0': case '1': case '2': case '3': case '4':
			case '5': case '6': case '7': case '8': case '9':
				if (!type) return error_token("A letter must preceed any digit");
			case '_':
				break;
			default:
				goto EXIT;
		}
		hash = FNV1a(next(), hash);
	}
	EXIT:;
	if (type == INVALID_TOKEN) error_token("An identifier may not only consist of '_'");
	uint32_t len = lexer.current - lexer.start;
	const char* interned_string = symtab_add(lexer.start, len, hash, &type);
	return make_string_token(type, interned_string);
}
static inline Token scan_ident ( void ) { if ( lexer . lexer_state == LEXER_STATE_DEFERED_PARSING ) { scan_skipped_ident ( ) ; return make_token ( TOKEN_VAR_IDENT ) ; } TokenType type = 0 ; uint32_t hash = FNV1_SEED ; while ( peek ( ) == ' ' ) { hash = FNV1a ( next ( ) , hash ) ; } while ( 1 ) { switch ( peek ( ) ) { case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : if ( ! type ) { type = TOKEN_VAR_IDENT ; } else if ( type == TOKEN_CAPS_IDENT ) { type = TOKEN_TYPE_IDENT ; } break ; case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : if ( ! type ) type = TOKEN_CAPS_IDENT ; break ; case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : if ( ! type ) return error_token ( " " ) ; case ' ' : break ; default : goto EXIT ; } hash = FNV1a ( next ( ) , hash ) ; } EXIT : ; if ( type == INVALID_TOKEN ) error_token ( " " ) ; uint32_t len = lexer . current - lexer . start ; const char * interned_string = symtab_add ( lexer . start , len , hash , & type ) ; return make_string_token ( type , interned_string ) ; }
Parses identifiers.
Parses identifiers .
// If we're in ignore keywords state, simply skip stuff.