roza/tests/units/parser.c

142 lines
3.5 KiB
C

#include <criterion/criterion.h>
#include <lexer.h>
#include <parser.h>
static void test_parser_ok(char const* oracle, char const* source)
{
err_t err;
err_init(&err);
err.quiet = 1;
lexer_t lex;
lexer_init(&lex, source, &err);
parser_t parser;
parser_init(&parser, &lex, &err);
node_t* node = parser_try_new_tree(&parser);
cr_assert(NULL != node, "error -> %s", source);
size_t const SZ = 256;
char msg[SZ];
node_str(node, msg, SZ);
cr_assert_str_eq(msg, oracle);
node_free(node);
free(node);
parser_free(&parser);
lexer_free(&lex);
err_free(&err);
}
static void test_parser_ko(char const* source)
{
err_t err;
err_init(&err);
err.quiet = 1;
lexer_t lex;
lexer_init(&lex, source, &err);
parser_t parser;
parser_init(&parser, &lex, &err);
node_t* node = parser_try_new_tree(&parser);
cr_assert(NULL == node);
cr_assert_gt(err.total, 0);
parser_free(&parser);
lexer_free(&lex);
err_free(&err);
}
Test(parser, num) {
test_parser_ok("MOD", "");
test_parser_ok("MOD(NUM[37],NUM[29])", "37 29");
test_parser_ko(" § ");
}
Test(parser, bool) {
test_parser_ok("MOD(BOOL[true],BOOL[false])", "true false");
}
Test(parser, str) {
test_parser_ok("MOD(STR[bim bam bum])", " \"bim bam bum\"");
}
Test(parser, assert) {
test_parser_ok("MOD(ASSERT(BOOL[false]))", " assert false ");
test_parser_ok("MOD(ASSERT(BOOL[true]))", " assert true ");
}
Test(parser, eqne) {
test_parser_ok("MOD(EQ(NUM[3],NUM[3]))", " 3 == 3 ");
test_parser_ok("MOD(NE(NUM[3],NUM[3]))", " 3 != 3 ");
}
Test(parser, cmp) {
test_parser_ok("MOD(LT(NUM[3],NUM[3]))", " 3 < 3 ");
test_parser_ok("MOD(LE(NUM[3],NUM[3]))", " 3 <= 3 ");
test_parser_ok("MOD(GT(NUM[3],NUM[3]))", " 3 > 3 ");
test_parser_ok("MOD(GE(NUM[3],NUM[3]))", " 3 >= 3 ");
}
Test(parser, num_arith) {
test_parser_ok("MOD(ADD(NUM[1],MUL(NUM[2],NUM[3])))", " 1 + 2 * 3 ");
test_parser_ok("MOD(MUL(ADD(NUM[1],NUM[2]),NUM[3]))", " (1 + 2) * 3 ");
test_parser_ok("MOD(SUB(NUM[1],DIV(NUM[2],NUM[3])))", " 1 - 2 / 3 ");
test_parser_ok("MOD(DIV(SUB(NUM[1],NUM[2]),NUM[3]))", " (1 - 2) / 3 ");
test_parser_ok("MOD(POW(NUM[2],ADD(NUM[1],NUM[2])))", " 2^(1+2) ");
}
Test(parser, bool_arith) {
test_parser_ok("MOD(OR(AND(BOOL[true],BOOL[false]),NOT(BOOL[true])))",
" true and false or not true ");
test_parser_ok("MOD(ASSERT(AND(BOOL[true],BOOL[false])))",
" assert (true and false) ");
}
Test(parser, var_decl) {
test_parser_ok("MOD(VARDECL(IDENT[x],NUM[33]))",
" let x = 33 ");
test_parser_ok("MOD(VARDECL(IDENT[bim],MUL(NUM[3],NUM[6])))",
" let bim = 3 * 6 ");
}
Test(parser, var_set) {
test_parser_ok("MOD(VARSET(IDENT[y],BOOL[true]))",
" y = true ");
}
Test(parser, block) {
test_parser_ok("MOD(SCOPE(BLOCK))",
" begin end ");
test_parser_ok("MOD(SCOPE(BLOCK(ADD(NUM[1],NUM[2]))))",
" begin 1 + 2 end ");
test_parser_ok("MOD(SCOPE(BLOCK(VARSET(IDENT[y],BOOL[true])"
",VARSET(IDENT[z],BOOL[false]))))",
" begin y = true z = false end ");
}
Test(parser, if_then_else) {
test_parser_ok("MOD(IF(IDENT[x],BLOCK(IDENT[y])))",
"if x then y end");
test_parser_ok("MOD(IF(IDENT[x],BLOCK(IDENT[y]),BLOCK(IDENT[z])))",
"if x then y else z end");
test_parser_ok("MOD(IF(IDENT[x],"
"BLOCK(IDENT[y]),"
"IF(IDENT[z],BLOCK(IDENT[u]),BLOCK(IDENT[v]))))",
"if x then y else if z then u else v end");
}