#include #include #include static void test_lexer_ok(char const* oracle, char const* source) { lexer_t lex; lexer_init(&lex, source, NULL); node_t* tok = lexer_try_new_next(&lex); cr_assert(tok != NULL, "error -> %s", source); size_t const SZ = 512; char str[SZ]; node_str(tok, str, SZ); cr_assert_str_eq(str, oracle, "error -> %s", source); node_free(tok); lexer_free(&lex); } static void test_lexer_ko(char const* source) { lexer_t lex; err_t err; err_init(&err); lexer_init(&lex, source, &err); node_t* tok = lexer_try_new_next(&lex); cr_assert(tok == NULL, "error -> %s", source); cr_assert(err.size > 0); err_free(&err); lexer_free(&lex); } static void test_lexer(char const* source, size_t n, ...) { va_list lst; va_start(lst, n); lexer_t lexer; lexer_init(&lexer, source, NULL); for (size_t i=0; i %s", source); size_t const SZ = 256; char tok_str[SZ]; node_str(tok, tok_str, SZ); char* oracle = va_arg(lst, char*); cr_assert_str_eq(tok_str, oracle); node_free(tok); } lexer_free(&lexer); va_end(lst); } Test(lexer, num) { test_lexer_ok("NUM[35]", " 35 "); test_lexer_ok("NUM[-270]", " -270 "); test_lexer_ok("NUM[0.7]", "0.7"); test_lexer_ok("NUM[3.]", "3."); test_lexer_ok("NUM[.4]", ".4"); test_lexer_ok("NUM[-3.14]", "-3.14"); test_lexer("-2 4.1 6", 3, "NUM[-2]", "NUM[4.1]", "NUM[6]"); test_lexer_ko("-3..14"); test_lexer_ko("..2"); test_lexer_ko("2.."); } Test(lexer, bool) { test_lexer_ko("true3"); test_lexer_ko("1true"); test_lexer_ko("afalse"); test_lexer_ko("falset"); test_lexer("true 3 false", 3, "BOOL[true]", "NUM[3]", "BOOL[false]"); } Test(lexer, str) { test_lexer_ko("\"hello"); test_lexer_ko("hello\""); test_lexer(" \"bonjour\" \" monde \"", 2, "STR[bonjour]", "STR[ monde ]"); test_lexer("\"the \\\"cat\\\"\"", 1, "STR[the \"cat\"]"); test_lexer("\"hello\\n\\tworld\"", 1, "STR[hello\n\tworld]"); } Test(lexer, assert) { test_lexer("assert", 1, "ASSERT"); } Test(lexer, cmp) { test_lexer("== !=", 2, "EQ", "NE"); test_lexer("false==true", 3, "BOOL[false]", "EQ", "BOOL[true]"); test_lexer("false!=true", 3, "BOOL[false]", "NE", "BOOL[true]"); test_lexer("1< <= > >=5", 6, "NUM[1]", "LT", "LE", "GT", "GE", "NUM[5]"); }