#include "../test.h" #include "arc/std/lexer.h" #define ARC_LEXER_TOKEN_NULL 0 #define ARC_LEXER_TOKEN_NUMBER 1 #define ARC_LEXER_TOKEN_ALPHA_LOWER_CHAR 2 #define ARC_LEXER_TOKEN_ALPHA_UPPER_CHAR 3 #define ARC_LEXER_TOKEN_WHITESPACE 4 #define ARC_LEXER_TOKEN_NEWLINE_ID 5 #define ARC_LEXER_TOKEN_NEWLINE_CHAR '\n' #define ARC_LEXER_TOKEN_COLON_ID 6 #define ARC_LEXER_TOKEN_COLON_CHAR ':' #define ARC_LEXER_TOKEN_COLON_TAG "COLON" #define ARC_LEXER_TOKEN_SEMICOLON_ID 7 #define ARC_LEXER_TOKEN_SEMICOLON_CHAR ';' #define ARC_LEXER_TOKEN_SEMICOLON_TAG "SEMICOLON" #define ARC_LEXER_TOKEN_COMMA_ID 8 #define ARC_LEXER_TOKEN_COMMA_CHAR ',' #define ARC_LEXER_TOKEN_COMMA_TAG "COMMA" #define ARC_LEXER_TOKEN_PERIOD_ID 9 #define ARC_LEXER_TOKEN_PERIOD_CHAR '.' #define ARC_LEXER_TOKEN_PERIOD_TAG "PERIOD" #define ARC_LEXER_TOKEN_FORWARD_SLASH_ID 10 #define ARC_LEXER_TOKEN_FORWARD_SLASH_CHAR '/' #define ARC_LEXER_TOKEN_FORWARD_SLASH_TAG "FORWARD_SLASH" #define ARC_LEXER_TOKEN_BACK_SLASH_ID 11 #define ARC_LEXER_TOKEN_BACK_SLASH_CHAR '\\' #define ARC_LEXER_TOKEN_BACK_SLASH_TAG "BACK_SLASH" #define ARC_LEXER_TOKEN_LEFT_PARENTHESIS_ID 12 #define ARC_LEXER_TOKEN_LEFT_PARENTHESIS_CHAR '(' #define ARC_LEXER_TOKEN_LEFT_PARENTHESIS_TAG "LEFT_PARENTHESIS" #define ARC_LEXER_TOKEN_RIGHT_PARENTHESIS_ID 13 #define ARC_LEXER_TOKEN_RIGHT_PARENTHESIS_CHAR ')' #define ARC_LEXER_TOKEN_RIGHT_PARENTHESIS_TAG "RIGHT_PARENTHESIS" #define ARC_LEXER_TOKEN_LEFT_CURLY_BRACE_ID 14 #define ARC_LEXER_TOKEN_LEFT_CURLY_BRACE_CHAR '{' #define ARC_LEXER_TOKEN_LEFT_CURLY_BRACE_TAG "LEFT_CURLY_BRACE" #define ARC_LEXER_TOKEN_RIGHT_CURLY_BRACE_ID 15 #define ARC_LEXER_TOKEN_RIGHT_CURLY_BRACE_CHAR '}' #define ARC_LEXER_TOKEN_RIGHT_CURLY_BRACE_TAG "RIGHT_CURLY_BRACE" #define ARC_LEXER_TOKEN_BANG_ID 16 #define ARC_LEXER_TOKEN_BANG_CHAR '!' #define ARC_LEXER_TOKEN_BANG_TAG "BANG" #define ARC_LEXER_TOKEN_AT_ID 17 #define ARC_LEXER_TOKEN_AT_CHAR '!' #define ARC_LEXER_TOKEN_AT_TAG "AT" #define ARC_LEXER_TOKEN_HASH_ID 18 #define ARC_LEXER_TOKEN_HASH_CHAR '#' #define ARC_LEXER_TOKEN_HASH_TAG "HASH" #define ARC_LEXER_TOKEN_PERCENT_ID 19 #define ARC_LEXER_TOKEN_PERCENT_CHAR '%' #define ARC_LEXER_TOKEN_PERCENT_TAG "PERCENT" void ARC_Lexer_InitBasicTokenRules(ARC_Lexer *lexer){ //null ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_NULL, 0)); //number ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharOrBetween(ARC_LEXER_TOKEN_NUMBER, '0', '9')); //alpha char ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharOrBetween(ARC_LEXER_TOKEN_ALPHA_LOWER_CHAR, 'a', 'z')); ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharOrBetween(ARC_LEXER_TOKEN_ALPHA_UPPER_CHAR, 'A', 'Z')); //whitespace //TODO: fix this ARC_String *whitespaceString; ARC_String_CreateWithStrlen(&whitespaceString, " \t"); ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharInStringRule(ARC_LEXER_TOKEN_WHITESPACE, whitespaceString)); ARC_String_Destroy(whitespaceString); //single char tokens ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_NEWLINE_ID , ARC_LEXER_TOKEN_NEWLINE_CHAR )); ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_COLON_ID , ARC_LEXER_TOKEN_COLON_CHAR )); ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_SEMICOLON_ID , ARC_LEXER_TOKEN_SEMICOLON_CHAR )); ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_COMMA_ID , ARC_LEXER_TOKEN_COMMA_CHAR )); ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_PERIOD_ID , ARC_LEXER_TOKEN_PERIOD_CHAR )); ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_FORWARD_SLASH_ID , ARC_LEXER_TOKEN_FORWARD_SLASH_CHAR )); ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_BACK_SLASH_ID , ARC_LEXER_TOKEN_BACK_SLASH_CHAR )); ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_LEFT_PARENTHESIS_ID , ARC_LEXER_TOKEN_LEFT_PARENTHESIS_CHAR )); ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_RIGHT_PARENTHESIS_ID, ARC_LEXER_TOKEN_RIGHT_PARENTHESIS_CHAR)); ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_LEFT_CURLY_BRACE_ID , ARC_LEXER_TOKEN_LEFT_CURLY_BRACE_CHAR )); ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_RIGHT_CURLY_BRACE_ID, ARC_LEXER_TOKEN_RIGHT_CURLY_BRACE_CHAR)); ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_BANG_ID , ARC_LEXER_TOKEN_BANG_CHAR )); ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_AT_ID , ARC_LEXER_TOKEN_AT_CHAR )); ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_HASH_ID , ARC_LEXER_TOKEN_HASH_CHAR )); ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_PERCENT_ID , ARC_LEXER_TOKEN_PERCENT_CHAR )); } ARC_TEST(Lexer_Char_Match){ ARC_Lexer *lexer; ARC_Lexer_Create(&lexer); ARC_Lexer_InitBasicTokenRules(lexer); ARC_String *simple; ARC_String_CreateWithStrlen(&simple, "::{}!/."); ARC_Lexer_LexString(lexer, &simple); ARC_LexerToken *token; token = ARC_Lexer_GetToken(lexer, 0); ARC_CHECK(token->rule == ARC_LEXER_TOKEN_COLON_ID); token = ARC_Lexer_GetToken(lexer, 1); ARC_CHECK(token->rule == ARC_LEXER_TOKEN_COLON_ID); token = ARC_Lexer_GetToken(lexer, 2); ARC_CHECK(token->rule == ARC_LEXER_TOKEN_LEFT_CURLY_BRACE_ID); token = ARC_Lexer_GetToken(lexer, 3); ARC_CHECK(token->rule == ARC_LEXER_TOKEN_RIGHT_CURLY_BRACE_ID); token = ARC_Lexer_GetToken(lexer, 4); ARC_CHECK(token->rule == ARC_LEXER_TOKEN_BANG_ID); token = ARC_Lexer_GetToken(lexer, 5); ARC_CHECK(token->rule == ARC_LEXER_TOKEN_FORWARD_SLASH_ID); token = ARC_Lexer_GetToken(lexer, 6); ARC_CHECK(token->rule == ARC_LEXER_TOKEN_PERIOD_ID); ARC_Lexer_Destroy(lexer); } ARC_TEST(Lexer_Check_Id_Basic){ ARC_Lexer *lexer; ARC_Lexer_Create(&lexer); ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(0, 0 )); ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(1, ':')); ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(2, ':')); ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(3, ':')); ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(4, ':')); ARC_CHECK(ARC_Lexer_IsContinious(lexer) == ARC_True); ARC_CHECK(ARC_Lexer_IsTokenId(lexer, 0) == ARC_True ); ARC_CHECK(ARC_Lexer_IsTokenId(lexer, 7) == ARC_False); ARC_CHECK(ARC_Lexer_IsTokenId(lexer, 2) == ARC_True ); ARC_CHECK(ARC_Lexer_IsTokenId(lexer, 4) == ARC_True ); ARC_CHECK(ARC_Lexer_IsTokenId(lexer, 5) == ARC_False); ARC_Lexer_Destroy(lexer); } ARC_TEST(Lexer_Check_Id_Unordered_But_Continious){ ARC_Lexer *lexer; ARC_Lexer_Create(&lexer); ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(2, ':')); ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(0, 0 )); ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(3, ':')); ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(1, ':')); ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(4, ':')); ARC_CHECK(ARC_Lexer_IsContinious(lexer) == ARC_True); ARC_CHECK(ARC_Lexer_IsTokenId(lexer, 0) == ARC_True ); ARC_CHECK(ARC_Lexer_IsTokenId(lexer, 7) == ARC_False); ARC_CHECK(ARC_Lexer_IsTokenId(lexer, 2) == ARC_True ); ARC_CHECK(ARC_Lexer_IsTokenId(lexer, 4) == ARC_True ); ARC_CHECK(ARC_Lexer_IsTokenId(lexer, 5) == ARC_False); ARC_Lexer_Destroy(lexer); } ARC_TEST(Lexer_Check_Id_Unordered_Not_Continious){ ARC_Lexer *lexer; ARC_Lexer_Create(&lexer); ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(2, ':')); ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(8, 0 )); ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(3, ':')); ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(1, ':')); ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(4, ':')); ARC_CHECK(ARC_Lexer_IsContinious(lexer) == ARC_False); ARC_CHECK(ARC_Lexer_IsTokenId(lexer, 8) == ARC_True ); ARC_CHECK(ARC_Lexer_IsTokenId(lexer, 7) == ARC_False); ARC_CHECK(ARC_Lexer_IsTokenId(lexer, 2) == ARC_True ); ARC_CHECK(ARC_Lexer_IsTokenId(lexer, 4) == ARC_True ); ARC_CHECK(ARC_Lexer_IsTokenId(lexer, 5) == ARC_False); ARC_Lexer_Destroy(lexer); }