aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorhachem <im@hachem.wtf>2026-08-31 17:55:16 +0200
committerhachem <im@hachem.wtf>2026-08-31 17:55:16 +0200
commitcbdb9073480c3e4d8a088b306c23406cf42e25c0 (patch)
tree39f3093654cc8f27ea701ed1338cac84d93f42eb /tests
parent53aed3fadf1f7ad66dea9a8a0b46bf42eda921be (diff)
feat: hex/binary integer literals and constant-folding const expressions
Diffstat (limited to 'tests')
-rw-r--r--tests/codegen_test.c2
-rw-r--r--tests/lexer_test.c9
-rw-r--r--tests/parser_test.c21
-rw-r--r--tests/sema_test.c18
4 files changed, 47 insertions, 3 deletions
diff --git a/tests/codegen_test.c b/tests/codegen_test.c
index 1cb0071..c56ca7a 100644
--- a/tests/codegen_test.c
+++ b/tests/codegen_test.c
@@ -21,7 +21,7 @@ static void test_generate_consts_and_data(struct TestContext* context)
buffer[read] = '\0';
fclose(out);
- check(context, strstr(buffer, "%define N 5") != NULL);
+ check(context, strstr(buffer, "%define N (5)") != NULL);
check(context, strstr(buffer, "section .data") != NULL);
check(context, strstr(buffer, "msg: db `hi`") != NULL);
check(context, strstr(buffer, ".len equ $ - msg") != NULL);
diff --git a/tests/lexer_test.c b/tests/lexer_test.c
index f677793..7260d6c 100644
--- a/tests/lexer_test.c
+++ b/tests/lexer_test.c
@@ -20,6 +20,14 @@ static void test_identifiers_and_integers(struct TestContext* context)
check(context, scan_token(&lexer).type == TOKEN_EOF);
}
+static void test_number_bases(struct TestContext* context)
+{
+ struct Lexer lexer = create_lexer("42 0x1F 0b1010");
+ check(context, token_matches(scan_token(&lexer), TOKEN_INTEGER, "42"));
+ check(context, token_matches(scan_token(&lexer), TOKEN_INTEGER, "0x1F"));
+ check(context, token_matches(scan_token(&lexer), TOKEN_INTEGER, "0b1010"));
+}
+
static void test_operators(struct TestContext* context)
{
struct Lexer lexer = create_lexer("= == += != /");
@@ -76,6 +84,7 @@ static void test_comments(struct TestContext* context)
void run_lexer_tests(struct TestContext* context)
{
test_identifiers_and_integers(context);
+ test_number_bases(context);
test_operators(context);
test_literals(context);
test_keywords(context);
diff --git a/tests/parser_test.c b/tests/parser_test.c
index 3fa3342..5a45e9e 100644
--- a/tests/parser_test.c
+++ b/tests/parser_test.c
@@ -23,9 +23,25 @@ static void test_parse_consts(struct TestContext* context)
check(context, parse_program(&lexer, &program));
check(context, program.const_count == 2);
check(context, text_is(program.consts[0].name, "A"));
- check(context, text_is(program.consts[0].value, "1"));
+ check(context, primary_is(program.consts[0].value, "1"));
check(context, text_is(program.consts[1].name, "B"));
- check(context, text_is(program.consts[1].value, "60"));
+ check(context, primary_is(program.consts[1].value, "60"));
+
+ free_program(&program);
+}
+
+static void test_parse_const_expr(struct TestContext* context)
+{
+ struct Lexer lexer = create_lexer("const A = 1\nconst B = A + 2 * 3\n");
+ struct Program program;
+
+ check(context, parse_program(&lexer, &program));
+
+ struct Expr* value = program.consts[1].value;
+ check(context, value->kind == EXPR_BINARY);
+ check(context, text_is(value->binary.op, "+"));
+ check(context, primary_is(value->binary.left, "A"));
+ check(context, value->binary.right->kind == EXPR_BINARY);
free_program(&program);
}
@@ -271,6 +287,7 @@ static void test_parse_errors(struct TestContext* context)
void run_parser_tests(struct TestContext* context)
{
test_parse_consts(context);
+ test_parse_const_expr(context);
test_parse_data(context);
test_parse_proc_params(context);
test_parse_proc_body(context);
diff --git a/tests/sema_test.c b/tests/sema_test.c
index 2757e6c..2d6e187 100644
--- a/tests/sema_test.c
+++ b/tests/sema_test.c
@@ -76,6 +76,21 @@ static void test_assign_to_const(struct TestContext* context)
check(context, !analyze_source("const K = 5\nproc main\n{\nK = 1\n}\n"));
}
+static void test_const_expr_ok(struct TestContext* context)
+{
+ check(context, analyze_source("const A = 1\nconst B = A + 2 * 3\nproc main\n{\nsyscall\n}\n"));
+}
+
+static void test_const_expr_rejects_register(struct TestContext* context)
+{
+ check(context, !analyze_source("const X = rax + 1\nproc main\n{\nsyscall\n}\n"));
+}
+
+static void test_const_expr_rejects_data(struct TestContext* context)
+{
+ check(context, !analyze_source("data d = \"x\"\nconst X = d\nproc main\n{\nsyscall\n}\n"));
+}
+
static void test_deref_needs_register(struct TestContext* context)
{
check(context, !analyze_source("proc main\n{\nrax = ^MISSING\n}\n"));
@@ -114,6 +129,9 @@ void run_sema_tests(struct TestContext* context)
test_undefined_call(context);
test_call_arg_count(context);
test_assign_to_const(context);
+ test_const_expr_ok(context);
+ test_const_expr_rejects_register(context);
+ test_const_expr_rejects_data(context);
test_deref_needs_register(context);
test_references_resolve(context);
}