roza/tests/units/lexer.c

173 lines
3.3 KiB
C
Raw Permalink Normal View History

2023-12-09 17:24:41 +00:00
#include <stdarg.h>
#include <criterion/criterion.h>
#include <lexer.h>
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);
2023-12-09 17:24:41 +00:00
size_t const SZ = 512;
char str[SZ];
node_str(tok, str, SZ);
cr_assert_str_eq(str, oracle, "error -> %s", source);
2023-12-09 17:24:41 +00:00
node_free(tok);
lexer_free(&lex);
}
static void test_lexer_ko(char const* source)
{
lexer_t lex;
err_t err;
err_init(&err);
err.quiet = 1;
2023-12-09 17:24:41 +00:00
lexer_init(&lex, source, &err);
node_t* tok = lexer_try_new_next(&lex);
cr_assert(tok == NULL, "error -> %s", source);
cr_assert_gt(err.total, 0);
2023-12-09 17:24:41 +00:00
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<n; i++)
{
node_t* tok = lexer_try_new_next(&lexer);
cr_assert(NULL != tok, "error token %ld: %s", i, source);
2023-12-09 17:24:41 +00:00
size_t const SZ = 256;
char tok_str[SZ];
node_str(tok, tok_str, SZ);
char* oracle = va_arg(lst, char*);
2023-12-10 21:43:48 +00:00
cr_assert_str_eq(tok_str, oracle);
2023-12-09 17:24:41 +00:00
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]");
2023-12-15 21:31:01 +00:00
test_lexer_ko("3..14");
2023-12-09 17:24:41 +00:00
test_lexer_ko("..2");
test_lexer_ko("2..");
}
2023-12-09 21:59:24 +00:00
Test(lexer, bool) {
test_lexer_ko("1true");
test_lexer("true 3 false", 3,
"BOOL[true]",
"NUM[3]",
"BOOL[false]");
}
2023-12-10 03:49:28 +00:00
Test(lexer, str) {
test_lexer(" \"bonjour\" \" monde \"", 2,
"STR[bonjour]",
"STR[ monde ]");
2023-12-10 21:43:48 +00:00
test_lexer("\"the \\\"cat\\\"\"", 1, "STR[the \"cat\"]");
test_lexer("\"hello\\n\\tworld\"", 1, "STR[hello\n\tworld]");
2023-12-10 03:49:28 +00:00
}
2023-12-11 17:01:22 +00:00
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]");
2023-12-15 20:32:17 +00:00
test_lexer("1< <= > >=5", 6,
"NUM[1]",
"LT",
"LE",
"GT",
"GE",
"NUM[5]");
}
2023-12-15 21:31:01 +00:00
Test(lexer, num_arith) {
test_lexer("()+-*/^%", 8,
"OPAR",
"CPAR",
"ADD",
"SUB",
"MUL",
"DIV",
"POW",
"MODULO");
}
2023-12-16 18:12:20 +00:00
Test(lexer, bool_arith) {
test_lexer("and or not", 3,
"AND",
"OR",
"NOT");
}
Test(lexer, let_var) {
test_lexer("let x = 3", 4,
"LET",
"IDENT[x]",
"ASSIGN",
"NUM[3]");
}
Test(lexer, blocks) {
2023-12-18 18:34:31 +00:00
test_lexer("if then else", 3,
"IF",
"THEN",
"ELSE");
}
2023-12-20 19:54:58 +00:00
Test(lexer, fun) {
test_lexer("fun return,", 3,
"FUN",
"RETURN",
"COMMA");
}