From 30258bc09e8b73575b71cf32de9ff8faef369b01 Mon Sep 17 00:00:00 2001 From: Kumachan <29433058+kumachan-mis@users.noreply.github.com> Date: Mon, 9 Oct 2023 11:43:45 +0900 Subject: [PATCH] feat: support null statement (#130) --- src/ast/ast.h | 1 + src/immcgen/immcgen.c | 3 +++ src/immcgen/statement.c | 4 ++++ src/immcgen/statement.h | 1 + src/parser/statement.c | 7 +++++++ src/resolver/statement.c | 8 ++++++++ src/resolver/statement.h | 1 + src/srt/srt.h | 1 + test-fixtures/exprstmt/main.c | 2 ++ tests/immcgen/test_statement.c | 12 ++++++++++++ tests/parser/test_statement.c | 14 ++++++++++++++ tests/resolver/test_statement.c | 12 ++++++++++++ 12 files changed, 66 insertions(+) diff --git a/src/ast/ast.h b/src/ast/ast.h index d51b9baa..53bb7760 100644 --- a/src/ast/ast.h +++ b/src/ast/ast.h @@ -56,6 +56,7 @@ typedef enum AstType { AST_CMPD_STMT, AST_RET_STMT, AST_EXPR_STMT, + AST_NULL_STMT, AST_IF_STMT, AST_WHILE_STMT, diff --git a/src/immcgen/immcgen.c b/src/immcgen/immcgen.c index ff8fc13a..4c551754 100644 --- a/src/immcgen/immcgen.c +++ b/src/immcgen/immcgen.c @@ -64,6 +64,9 @@ Vector* immcgen_generate_immcode(Immcgen* immcgen) { case SRT_EXPR_STMT: codes = gen_expression_stmt_immcode(immcgen); break; + case SRT_NULL_STMT: + codes = gen_null_stmt_immcode(); + break; case SRT_IF_STMT: codes = gen_if_else_stmt_immcode(immcgen); break; diff --git a/src/immcgen/statement.c b/src/immcgen/statement.c index b91e1650..1cd70c30 100644 --- a/src/immcgen/statement.c +++ b/src/immcgen/statement.c @@ -38,6 +38,10 @@ Vector* gen_expression_stmt_immcode(Immcgen* immcgen) { return codes; } +Vector* gen_null_stmt_immcode(void) { + return new_vector(&t_immc); +} + Vector* gen_if_else_stmt_immcode(Immcgen* immcgen) { Vector* gen_if_without_else_stmt_immcode(Immcgen * immcgen); Vector* gen_if_with_else_stmt_immcode(Immcgen * immcgen); diff --git a/src/immcgen/statement.h b/src/immcgen/statement.h index c4cb5d40..4c6c1607 100644 --- a/src/immcgen/statement.h +++ b/src/immcgen/statement.h @@ -6,6 +6,7 @@ Vector* gen_compound_stmt_immcode(Immcgen* immcgen); Vector* gen_return_stmt_immcode(Immcgen* immcgen); Vector* gen_expression_stmt_immcode(Immcgen* immcgen); +Vector* gen_null_stmt_immcode(void); Vector* gen_if_else_stmt_immcode(Immcgen* immcgen); Vector* gen_while_stmt_immcode(Immcgen* immcgen); diff --git a/src/parser/statement.c b/src/parser/statement.c index 56cca2d0..7943543a 100644 --- a/src/parser/statement.c +++ b/src/parser/statement.c @@ -103,6 +103,13 @@ ParserReturn* parse_expression_stmt(Parser* parser) { Ast* ast = NULL; Error* err = NULL; + CToken* ctoken = vector_at(parser->ctokens, parser->index); + if (ctoken->type == CTOKEN_SEMICOLON) { + parser->index++; + ast = new_ast(AST_NULL_STMT, 0); + return new_parserret(ast); + } + parserret_assign(&ast, &err, parse_expr(parser)); if (err != NULL) { return new_parserret_error(err); diff --git a/src/resolver/statement.c b/src/resolver/statement.c index 77b6d60c..7266ce56 100644 --- a/src/resolver/statement.c +++ b/src/resolver/statement.c @@ -25,6 +25,9 @@ ResolverReturn* resolve_stmt(Resolver* resolver) { case AST_EXPR_STMT: resolverret_assign(&srt, &errs, resolve_expression_stmt(resolver)); break; + case AST_NULL_STMT: + resolverret_assign(&srt, &errs, resolve_null_stmt()); + break; case AST_IF_STMT: resolverret_assign(&srt, &errs, resolve_if_else_stmt(resolver)); break; @@ -156,6 +159,11 @@ ResolverReturn* resolve_expression_stmt(Resolver* resolver) { return new_resolverret(srt); } +ResolverReturn* resolve_null_stmt(void) { + Srt* srt = new_srt(SRT_NULL_STMT, 0); + return new_resolverret(srt); +} + ResolverReturn* resolve_if_else_stmt(Resolver* resolver) { Srt* srt = new_srt(SRT_IF_STMT, 0); Srt* child_srt = NULL; diff --git a/src/resolver/statement.h b/src/resolver/statement.h index 5f7a20e2..db8108d6 100644 --- a/src/resolver/statement.h +++ b/src/resolver/statement.h @@ -7,6 +7,7 @@ ResolverReturn* resolve_stmt(Resolver* resolver); ResolverReturn* resolve_compound_stmt(Resolver* resolver); ResolverReturn* resolve_return_stmt(Resolver* resolver); ResolverReturn* resolve_expression_stmt(Resolver* resolver); +ResolverReturn* resolve_null_stmt(void); ResolverReturn* resolve_if_else_stmt(Resolver* resolver); ResolverReturn* resolve_while_stmt(Resolver* resolver); diff --git a/src/srt/srt.h b/src/srt/srt.h index 324ccc8d..a537a553 100644 --- a/src/srt/srt.h +++ b/src/srt/srt.h @@ -26,6 +26,7 @@ typedef enum SrtType { SRT_CMPD_STMT, SRT_RET_STMT, SRT_EXPR_STMT, + SRT_NULL_STMT, SRT_IF_STMT, SRT_WHILE_STMT, diff --git a/test-fixtures/exprstmt/main.c b/test-fixtures/exprstmt/main.c index 0b520d56..22e5015f 100644 --- a/test-fixtures/exprstmt/main.c +++ b/test-fixtures/exprstmt/main.c @@ -2,9 +2,11 @@ void put_int(int x); int main(void) { int x, y; + ; x = 1 + 3; y = x - 2; put_int(x); put_int(y); + ; return 0; } diff --git a/tests/immcgen/test_statement.c b/tests/immcgen/test_statement.c index e5560cfe..1268a59a 100644 --- a/tests/immcgen/test_statement.c +++ b/tests/immcgen/test_statement.c @@ -14,6 +14,7 @@ void test_immcgen_compound_stmt_empty(void); void test_immcgen_return_stmt_non_void(void); void test_immcgen_return_stmt_void(void); void test_immcgen_expression_stmt(void); +void test_immcgen_null_stmt(void); void test_immcgen_if_stmt(void); void test_immcgen_if_else_stmt(void); void test_immcgen_if_else_stmt_chain(void); @@ -35,6 +36,7 @@ CU_Suite* add_test_suite_stmt_immcgen(void) { CU_ADD_TEST(suite, test_immcgen_return_stmt_non_void); CU_ADD_TEST(suite, test_immcgen_return_stmt_void); CU_ADD_TEST(suite, test_immcgen_expression_stmt); + CU_ADD_TEST(suite, test_immcgen_null_stmt); CU_ADD_TEST(suite, test_immcgen_if_stmt); CU_ADD_TEST(suite, test_immcgen_if_else_stmt); CU_ADD_TEST(suite, test_immcgen_if_else_stmt_chain); @@ -771,6 +773,16 @@ void test_immcgen_expression_stmt(void) { delete_vector(expected); } +void test_immcgen_null_stmt(void) { + Srt* input = new_srt(SRT_NULL_STMT, 0); + + Vector* expected = new_vector(&t_immc); + + run_stmt_immcgen_test(input, NULL, -1, expected); + + delete_vector(expected); +} + void test_immcgen_if_stmt(void) { Srt* input = new_srt( SRT_IF_STMT, 2, // non-terminal diff --git a/tests/parser/test_statement.c b/tests/parser/test_statement.c index 3f38f31a..79aead8b 100644 --- a/tests/parser/test_statement.c +++ b/tests/parser/test_statement.c @@ -16,6 +16,7 @@ void test_parse_compound_stmt_empty(void); void test_parse_return_stmt_non_void(void); void test_parse_return_stmt_void(void); void test_parse_expression_stmt(void); +void test_parse_null_stmt(void); void test_parse_if_stmt(void); void test_parse_if_else_stmt(void); void test_parse_if_else_stmt_chain(void); @@ -38,6 +39,7 @@ CU_Suite* add_test_suite_stmt_parser(void) { CU_ADD_TEST(suite, test_parse_return_stmt_non_void); CU_ADD_TEST(suite, test_parse_return_stmt_void); CU_ADD_TEST(suite, test_parse_expression_stmt); + CU_ADD_TEST(suite, test_parse_null_stmt); CU_ADD_TEST(suite, test_parse_if_stmt); CU_ADD_TEST(suite, test_parse_if_else_stmt); CU_ADD_TEST(suite, test_parse_if_else_stmt_chain); @@ -744,6 +746,18 @@ void test_parse_expression_stmt(void) { delete_ast(expected); } +void test_parse_null_stmt(void) { + Vector* input = new_vector(&t_ctoken); + vector_push(input, new_ctoken(CTOKEN_SEMICOLON)); + vector_push(input, new_ctoken(CTOKEN_EOF)); + + Ast* expected = new_ast(AST_NULL_STMT, 0); + + run_stmt_parser_test(input, expected); + + delete_ast(expected); +} + void test_parse_if_stmt(void) { Vector* input = new_vector(&t_ctoken); vector_push(input, new_ctoken(CTOKEN_LBRACE)); diff --git a/tests/resolver/test_statement.c b/tests/resolver/test_statement.c index 04f3b928..565bdfad 100644 --- a/tests/resolver/test_statement.c +++ b/tests/resolver/test_statement.c @@ -20,6 +20,7 @@ void test_resolve_return_stmt_void(void); void test_resolve_expression_stmt_scalar(void); void test_resolve_expression_stmt_array(void); void test_resolve_expression_stmt_function(void); +void test_resolve_null_stmt(void); void test_resolve_if_stmt(void); void test_resolve_if_else_stmt(void); void test_resolve_if_else_stmt_chain(void); @@ -47,6 +48,7 @@ CU_Suite* add_test_suite_stmt_resolver(void) { CU_ADD_TEST(suite, test_resolve_expression_stmt_scalar); CU_ADD_TEST(suite, test_resolve_expression_stmt_array); CU_ADD_TEST(suite, test_resolve_expression_stmt_function); + CU_ADD_TEST(suite, test_resolve_null_stmt); CU_ADD_TEST(suite, test_resolve_if_stmt); CU_ADD_TEST(suite, test_resolve_if_else_stmt); CU_ADD_TEST(suite, test_resolve_if_else_stmt_chain); @@ -898,6 +900,16 @@ void test_resolve_expression_stmt_function(void) { delete_srt(expected); } +void test_resolve_null_stmt(void) { + Ast* input = new_ast(AST_NULL_STMT, 0); + + Srt* expected = new_srt(SRT_NULL_STMT, 0); + + run_stmt_resolver_test(input, NULL, NULL, expected); + + delete_srt(expected); +} + void test_resolve_if_stmt(void) { Ast* input = new_ast(AST_CMPD_STMT, 2, // non-terminal new_ast(AST_IF_STMT, 2, // non-terminal