From d86d70fc7c6751713a6b9f02d9f77814e2f75718 Mon Sep 17 00:00:00 2001 From: Johnny Richard Date: Fri, 21 Apr 2023 15:11:17 +0200 Subject: parser: Parse integers arithmetic expression This patch implements the AST creation for arithmetic expressions. NOTE: The implementation works only for integer numbers. Signed-off-by: Johnny Richard Reviewed-by: Carlos Maniero --- test/parser_test.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 73 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/parser_test.c b/test/parser_test.c index 573296f..2e73fa6 100644 --- a/test/parser_test.c +++ b/test/parser_test.c @@ -19,6 +19,9 @@ #include "lexer.h" #include "parser.h" #include "ast.h" +#include "string.h" + +void assert_string_view_equal(char *expected, string_view_t actual); void make_lexer_from_static_src(lexer_t *lexer, char *src) @@ -55,7 +58,7 @@ test_parse_function(const MunitParameter params[], parser_t parser; lexer_t lexer; - make_lexer_from_static_src(&lexer, "main(): i32 { return 42; }"); + make_lexer_from_static_src(&lexer, "main(): i32 { \nreturn 42;\n }"); parser_init(&parser, &lexer); ast_node_t *ast_function = ast_node_new(); @@ -82,6 +85,74 @@ test_parse_function(const MunitParameter params[], return MUNIT_OK; } +static MunitResult +test_parse_arithmetic_expression(const MunitParameter params[], + void *user_data_or_fixture) +{ + parser_t parser; + lexer_t lexer; + + make_lexer_from_static_src(&lexer, "1 + 3 * 3 / 2 - 1"); + parser_init(&parser, &lexer); + + ast_node_t *ast_expression = ast_node_new(); + bool parsed = parser_parse_expression(&parser, ast_expression); + assert_true(parsed); + + ast_node_t *exp1 = ast_expression; + { + + assert_int(AST_BINARY_OPERATION, ==, exp1->kind); + assert_string_view_equal("-", exp1->data.binary_operation.op); + + ast_node_t *exp2 = exp1->data.binary_operation.left; + { + + assert_int(AST_BINARY_OPERATION, ==, exp2->kind); + assert_string_view_equal("+", exp2->data.binary_operation.op); + + assert_int(AST_LITERAL, ==, exp2->data.binary_operation.left->kind); + assert_int(exp2->data.binary_operation.left->data.literal.value.integer, ==, 1); + + ast_node_t *exp3 = exp2->data.binary_operation.right; + { + + assert_int(AST_BINARY_OPERATION, ==, exp3->kind); + assert_string_view_equal("/", exp3->data.binary_operation.op); + + ast_node_t *exp4 = exp3->data.binary_operation.left; + { + assert_int(AST_BINARY_OPERATION, ==, exp4->kind); + assert_string_view_equal("*", exp4->data.binary_operation.op); + + assert_int(AST_LITERAL, ==, exp4->data.binary_operation.left->kind); + assert_int(exp4->data.binary_operation.left->data.literal.value.integer, ==, 3); + + assert_int(AST_LITERAL, ==, exp4->data.binary_operation.right->kind); + assert_int(exp4->data.binary_operation.right->data.literal.value.integer, ==, 3); + } + + assert_int(AST_LITERAL, ==, exp3->data.binary_operation.right->kind); + assert_int(exp3->data.binary_operation.right->data.literal.value.integer, ==, 2); + } + } + + assert_int(AST_LITERAL, ==, exp1->data.binary_operation.right->kind); + assert_int(exp1->data.binary_operation.right->data.literal.value.integer, ==, 1); + } + + ast_node_destroy(ast_expression); + + return MUNIT_OK; +} + +void assert_string_view_equal(char *expected, string_view_t actual) +{ + size_t expected_len = strlen(expected); + assert_int(expected_len, ==, actual.size); + assert_memory_equal(expected_len, expected, actual.str); +} + static MunitResult test_parse_basic_syntax_errors(const MunitParameter params[], void *user_data_or_fixture) @@ -104,6 +175,7 @@ test_parse_basic_syntax_errors(const MunitParameter params[], static MunitTest tests[] = { { "/test_parse_function", test_parse_function, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL }, { "/test_parse_basic_syntax_errors", test_parse_basic_syntax_errors, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL }, + { "/test_parse_arithmetic_expression", test_parse_arithmetic_expression, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL }, { NULL, NULL, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL } }; -- cgit v1.2.3