152 lines
3.1 KiB
C
152 lines
3.1 KiB
C
#include <criterion/criterion.h>
|
|
#include <vec.h>
|
|
#include <node.h>
|
|
#include <lexer.h>
|
|
|
|
static void test_lexer(char const* source, size_t size, ...)
|
|
{
|
|
va_list lst;
|
|
va_start(lst, size);
|
|
|
|
struct vec tokens;
|
|
vec_init(&tokens, 1);
|
|
|
|
struct lexer lex;
|
|
lexer_init(&lex, source);
|
|
int err = lexer_extract(&lex, &tokens);
|
|
cr_assert_eq(0, err, "%s", lex.error_msg);
|
|
cr_assert_eq(size, tokens.size,
|
|
"size (%zu) != tokens.size (%zu)",
|
|
size, tokens.size);
|
|
|
|
for (size_t i=0; i<size; i++)
|
|
{
|
|
size_t SZ = 256;
|
|
char buf[SZ];
|
|
node_str(tokens.data[i], buf, SZ);
|
|
cr_assert_str_eq(va_arg(lst, char*), buf);
|
|
}
|
|
|
|
va_end(lst);
|
|
|
|
lexer_free(&lex);
|
|
vec_free_elements(&tokens);
|
|
vec_free(&tokens);
|
|
}
|
|
|
|
Test(lexer, builtins) {
|
|
test_lexer("true false;", 3,
|
|
"BOOL[true]",
|
|
"BOOL[false]",
|
|
"SEMICOLON");
|
|
}
|
|
|
|
Test(lexer, error) {
|
|
struct vec tokens;
|
|
vec_init(&tokens, 1);
|
|
|
|
struct lexer lex;
|
|
lexer_init(&lex, " true § false;");
|
|
|
|
int res = lexer_extract(&lex, &tokens);
|
|
cr_assert_neq(0, res);
|
|
|
|
lexer_free(&lex);
|
|
vec_free_elements(&tokens);
|
|
vec_free(&tokens);
|
|
}
|
|
|
|
Test(lexer, assert) {
|
|
test_lexer("assert", 1, "ASSERT");
|
|
}
|
|
|
|
|
|
Test(lexer, comment) {
|
|
test_lexer("assert # salut \n assert", 2, "ASSERT", "ASSERT");
|
|
}
|
|
|
|
Test(lexer, bool_arith) {
|
|
test_lexer("&&||!", 3, "AND", "OR", "NOT");
|
|
}
|
|
|
|
Test(lexer, eqne) {
|
|
test_lexer("!= ==", 2, "NE", "EQ");
|
|
}
|
|
|
|
Test(lexer, int) {
|
|
test_lexer("5 -27", 2, "INT[5]", "INT[-27]");
|
|
}
|
|
|
|
Test(lexer, float) {
|
|
test_lexer("0.5 -2.7", 2, "FLOAT[0.5]", "FLOAT[-2.7]");
|
|
}
|
|
|
|
Test(lexer, string) {
|
|
test_lexer("'hello world ' \" bim\" '\\\"hello\\\"'", 3,
|
|
"STRING[hello world ]",
|
|
"STRING[ bim]",
|
|
"STRING[\"hello\"]");
|
|
|
|
test_lexer("' \\'coucou\\' '", 1,
|
|
"STRING[ 'coucou' ]");
|
|
|
|
test_lexer("' \\'cou\\ncou\\' '", 1,
|
|
"STRING[ 'cou\ncou' ]");
|
|
|
|
test_lexer("' \\'cou\\r\\tcou\\' '", 1,
|
|
"STRING[ 'cou\r\tcou' ]");
|
|
}
|
|
|
|
Test(lexer, arithemtic) {
|
|
test_lexer("+-*/%**", 6,
|
|
"ADD",
|
|
"SUB",
|
|
"MUL",
|
|
"DIV",
|
|
"MOD",
|
|
"POW");
|
|
|
|
}
|
|
|
|
Test(lexer, comparisons) {
|
|
test_lexer(">>=<<=", 4,
|
|
"GT",
|
|
"GE",
|
|
"LT",
|
|
"LE");
|
|
}
|
|
|
|
Test(lexer, var_decl) {
|
|
test_lexer(":=var", 3, "COLON", "ASSIGN", "VAR");
|
|
}
|
|
|
|
Test(lexer, ident) {
|
|
test_lexer("atrue salut! coucou32 az_za?", 4,
|
|
"IDENT[atrue]", "IDENT[salut!]",
|
|
"IDENT[coucou32]", "IDENT[az_za?]");
|
|
}
|
|
|
|
Test(lexer, var_types) {
|
|
test_lexer("int float bool string ^", 5,
|
|
"TYPE[int]", "TYPE[float]",
|
|
"TYPE[bool]", "TYPE[string]",
|
|
"PTR");
|
|
}
|
|
|
|
Test(lexer, blocks) {
|
|
test_lexer("{}", 2, "OBRACE", "CBRACE");
|
|
}
|
|
|
|
Test(lexer, flow_control) {
|
|
test_lexer("if else cond while for break continue", 7,
|
|
"IF", "ELSE", "COND", "WHILE", "FOR", "BREAK", "CONTINUE");
|
|
}
|
|
|
|
Test(lexer, fun) {
|
|
test_lexer("-> fun return,", 4, "RARROW", "FUN", "RETURN", "COMMA");
|
|
}
|
|
|
|
Test(lexer, mem) {
|
|
test_lexer("new free", 2, "NEW", "FREE");
|
|
}
|