Skip to content

Commit

Permalink
implement immcgen
Browse files Browse the repository at this point in the history
  • Loading branch information
kumachan-mis committed Oct 13, 2023
1 parent f4c96e3 commit 136f6bd
Show file tree
Hide file tree
Showing 6 changed files with 226 additions and 1 deletion.
8 changes: 8 additions & 0 deletions src/immcgen/immcgen.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ Immcgen* new_immcgen(Srt* srt) {
immcgen->next_reg_id = -1;
immcgen->initialized_dtype = NULL;
immcgen->initialized_offset = -1;
immcgen->continue_label_id = -1;
immcgen->break_label_id = -1;
immcgen->return_label_id = -1;
immcgen->label_id = -1;
return immcgen;
Expand Down Expand Up @@ -58,6 +60,12 @@ Vector* immcgen_generate_immcode(Immcgen* immcgen) {
immcgen->tag_table = tagtable_exit_scope(immcgen->tag_table);
immcgen->symbol_table = symboltable_exit_scope(immcgen->symbol_table);
break;
case SRT_CONTINUE_STMT:
codes = gen_continue_stmt_immcode(immcgen);
break;
case SRT_BREAK_STMT:
codes = gen_break_stmt_immcode(immcgen);
break;
case SRT_RET_STMT:
codes = gen_return_stmt_immcode(immcgen);
break;
Expand Down
2 changes: 2 additions & 0 deletions src/immcgen/immcgen.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ typedef struct Immcgen {
int next_reg_id;
DType* initialized_dtype;
int initialized_offset;
int continue_label_id;
int break_label_id;
int return_label_id;
int label_id;
} Immcgen;
Expand Down
28 changes: 28 additions & 0 deletions src/immcgen/statement.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,20 @@ Vector* gen_compound_stmt_immcode(Immcgen* immcgen) {
return codes;
}

Vector* gen_continue_stmt_immcode(Immcgen* immcgen) {
Vector* codes = new_vector(&t_immc);
ImmcOpe* continue_label = new_label_immcope_from_id(immcgen->continue_label_id);
vector_push(codes, new_inst_immc(IMMC_INST_JMP, continue_label, NULL, NULL));
return codes;
}

Vector* gen_break_stmt_immcode(Immcgen* immcgen) {
Vector* codes = new_vector(&t_immc);
ImmcOpe* break_label = new_label_immcope_from_id(immcgen->break_label_id);
vector_push(codes, new_inst_immc(IMMC_INST_JMP, break_label, NULL, NULL));
return codes;
}

Vector* gen_return_stmt_immcode(Immcgen* immcgen) {
Vector* codes = new_vector(&t_immc);
Srt* srt = immcgen->srt;
Expand Down Expand Up @@ -125,7 +139,14 @@ Vector* gen_while_stmt_immcode(Immcgen* immcgen) {
ImmcOpe* end_label = new_label_immcope_from_id(end_label_id);
append_child_jmp_false_immcode(immcgen, codes, 0, end_label);

int original_continue_label_id = immcgen->continue_label_id;
int original_break_label_id = immcgen->break_label_id;

immcgen->continue_label_id = begin_label_id;
immcgen->break_label_id = end_label_id;
append_child_immcode(immcgen, codes, 1);
immcgen->continue_label_id = original_continue_label_id;
immcgen->break_label_id = original_break_label_id;

ImmcOpe* begin_label = new_label_immcope_from_id(begin_label_id);
vector_push(codes, new_inst_immc(IMMC_INST_JMP, begin_label, NULL, NULL));
Expand Down Expand Up @@ -156,7 +177,14 @@ Vector* gen_for_stmt_immcode(Immcgen* immcgen) {
immcgen->srt = srt;
}

int original_continue_label_id = immcgen->continue_label_id;
int original_break_label_id = immcgen->break_label_id;

immcgen->continue_label_id = begin_label_id;
immcgen->break_label_id = end_label_id;
append_child_immcode(immcgen, codes, 3);
immcgen->continue_label_id = original_continue_label_id;
immcgen->break_label_id = original_break_label_id;

append_child_immcode(immcgen, codes, 2);

Expand Down
2 changes: 2 additions & 0 deletions src/immcgen/statement.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#include "./immcgen.h"

Vector* gen_compound_stmt_immcode(Immcgen* immcgen);
Vector* gen_continue_stmt_immcode(Immcgen* immcgen);
Vector* gen_break_stmt_immcode(Immcgen* immcgen);
Vector* gen_return_stmt_immcode(Immcgen* immcgen);
Vector* gen_expression_stmt_immcode(Immcgen* immcgen);
Vector* gen_null_stmt_immcode(void);
Expand Down
185 changes: 185 additions & 0 deletions tests/immcgen/test_statement.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ void test_immcgen_compound_stmt_long_long(void);
void test_immcgen_compound_stmt_unsigned_long_long(void);
void test_immcgen_compound_stmt_void_pointer(void);
void test_immcgen_compound_stmt_empty(void);
void test_immcgen_continue_stmt(void);
void test_immcgen_continue_stmt_nested(void);
void test_immcgen_break_stmt(void);
void test_immcgen_break_stmt_nested(void);
void test_immcgen_return_stmt_non_void(void);
void test_immcgen_return_stmt_void(void);
void test_immcgen_expression_stmt(void);
Expand All @@ -36,6 +40,10 @@ CU_Suite* add_test_suite_stmt_immcgen(void) {
CU_ADD_TEST(suite, test_immcgen_compound_stmt_unsigned_long_long);
CU_ADD_TEST(suite, test_immcgen_compound_stmt_void_pointer);
CU_ADD_TEST(suite, test_immcgen_compound_stmt_empty);
CU_ADD_TEST(suite, test_immcgen_continue_stmt);
CU_ADD_TEST(suite, test_immcgen_continue_stmt_nested);
CU_ADD_TEST(suite, test_immcgen_break_stmt);
CU_ADD_TEST(suite, test_immcgen_break_stmt_nested);
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);
Expand Down Expand Up @@ -713,6 +721,183 @@ void test_immcgen_compound_stmt_empty(void) {
delete_vector(expected);
}

void test_immcgen_continue_stmt(void) {
Srt* input =
new_srt(SRT_WHILE_STMT, 2, // non-terminal
new_iliteral_srt(SRT_INT_EXPR, new_integer_dtype(DTYPE_INT), new_signed_iliteral(INTEGER_INT, 1)),
new_srt(SRT_CMPD_STMT, 1, // non-terminal
new_srt(SRT_CONTINUE_STMT, 0)));

Vector* expected = new_vector(&t_immc);
vector_push(expected, new_label_immc(IMMC_LABEL_NORMAL, IMMC_VIS_NONE, new_string(".L0")));
vector_push(expected,
new_inst_immc(IMMC_INST_LOAD, // inst
new_signed_reg_immcope(IMMC_SUFFIX_LONG, 0), // dst
new_signed_int_immcope(IMMC_SUFFIX_LONG, INTEGER_INT, 1), // fst_src
NULL)); // snd_src
vector_push(expected,
new_inst_immc(IMMC_INST_JEQ, // inst
new_label_immcope(new_string(".L1")), // dst
new_signed_reg_immcope(IMMC_SUFFIX_LONG, 0), // fst_src
new_signed_int_immcope(IMMC_SUFFIX_LONG, INTEGER_INT, 0))); // snd_src
vector_push(expected,
new_inst_immc(IMMC_INST_JMP, // inst
new_label_immcope(new_string(".L0")), // dst
NULL, // fst_src
NULL)); // snd_src
vector_push(expected,
new_inst_immc(IMMC_INST_JMP, // inst
new_label_immcope(new_string(".L0")), // dst
NULL, // fst_src
NULL)); // snd_src
vector_push(expected, new_label_immc(IMMC_LABEL_NORMAL, IMMC_VIS_NONE, new_string(".L1")));

run_stmt_immcgen_test(input, NULL, 0, expected);

delete_vector(expected);
}

void test_immcgen_continue_stmt_nested(void) {
Srt* input =
new_srt(SRT_WHILE_STMT, 2, // non-terminal
new_iliteral_srt(SRT_INT_EXPR, new_integer_dtype(DTYPE_INT), new_signed_iliteral(INTEGER_INT, 1)),
new_srt(SRT_CMPD_STMT, 3, // non-terminal
new_srt(SRT_CONTINUE_STMT, 0),
new_srt(SRT_FOR_STMT, 4, // non-terminal
new_srt(SRT_NULL_STMT, 0), new_srt(SRT_NULL_STMT, 0), new_srt(SRT_NULL_STMT, 0),
new_srt(SRT_CMPD_STMT, 1, // non-terminal
new_srt(SRT_CONTINUE_STMT, 0))),
new_srt(SRT_CONTINUE_STMT, 0)));

Vector* expected = new_vector(&t_immc);
vector_push(expected, new_label_immc(IMMC_LABEL_NORMAL, IMMC_VIS_NONE, new_string(".L0")));
vector_push(expected,
new_inst_immc(IMMC_INST_LOAD, // inst
new_signed_reg_immcope(IMMC_SUFFIX_LONG, 0), // dst
new_signed_int_immcope(IMMC_SUFFIX_LONG, INTEGER_INT, 1), // fst_src
NULL)); // snd_src
vector_push(expected,
new_inst_immc(IMMC_INST_JEQ, // inst
new_label_immcope(new_string(".L1")), // dst
new_signed_reg_immcope(IMMC_SUFFIX_LONG, 0), // fst_src
new_signed_int_immcope(IMMC_SUFFIX_LONG, INTEGER_INT, 0))); // snd_src
vector_push(expected,
new_inst_immc(IMMC_INST_JMP, // inst
new_label_immcope(new_string(".L0")), // dst
NULL, // fst_src
NULL)); // snd_src
vector_push(expected, new_label_immc(IMMC_LABEL_NORMAL, IMMC_VIS_NONE, new_string(".L2")));
vector_push(expected,
new_inst_immc(IMMC_INST_JMP, // inst
new_label_immcope(new_string(".L2")), // dst
NULL, // fst_src
NULL)); // snd_src
vector_push(expected,
new_inst_immc(IMMC_INST_JMP, // inst
new_label_immcope(new_string(".L2")), // dst
NULL, // fst_src
NULL)); // snd_src
vector_push(expected, new_label_immc(IMMC_LABEL_NORMAL, IMMC_VIS_NONE, new_string(".L3")));
vector_push(expected,
new_inst_immc(IMMC_INST_JMP, // inst
new_label_immcope(new_string(".L0")), // dst
NULL, // fst_src
NULL)); // snd_src
vector_push(expected,
new_inst_immc(IMMC_INST_JMP, // inst
new_label_immcope(new_string(".L0")), // dst
NULL, // fst_src
NULL)); // snd_src
vector_push(expected, new_label_immc(IMMC_LABEL_NORMAL, IMMC_VIS_NONE, new_string(".L1")));

run_stmt_immcgen_test(input, NULL, 0, expected);

delete_vector(expected);
}

void test_immcgen_break_stmt(void) {
Srt* input = new_srt(SRT_FOR_STMT, 4, // non-terminal
new_srt(SRT_NULL_STMT, 0), new_srt(SRT_NULL_STMT, 0), new_srt(SRT_NULL_STMT, 0),
new_srt(SRT_CMPD_STMT, 1, // non-terminal
new_srt(SRT_BREAK_STMT, 0)));

Vector* expected = new_vector(&t_immc);
vector_push(expected, new_label_immc(IMMC_LABEL_NORMAL, IMMC_VIS_NONE, new_string(".L0")));
vector_push(expected,
new_inst_immc(IMMC_INST_JMP, // inst
new_label_immcope(new_string(".L1")), // dst
NULL, // fst_src
NULL)); // snd_src
vector_push(expected,
new_inst_immc(IMMC_INST_JMP, // inst
new_label_immcope(new_string(".L0")), // dst
NULL, // fst_src
NULL)); // snd_src
vector_push(expected, new_label_immc(IMMC_LABEL_NORMAL, IMMC_VIS_NONE, new_string(".L1")));

run_stmt_immcgen_test(input, NULL, 0, expected);

delete_vector(expected);
}

void test_immcgen_break_stmt_nested(void) {
Srt* input = new_srt(SRT_FOR_STMT, 4, // non-terminal
new_srt(SRT_NULL_STMT, 0), new_srt(SRT_NULL_STMT, 0), new_srt(SRT_NULL_STMT, 0),
new_srt(SRT_CMPD_STMT, 3, // non-terminal
new_srt(SRT_BREAK_STMT, 0),
new_srt(SRT_WHILE_STMT, 2, // non-terminal
new_iliteral_srt(SRT_INT_EXPR, new_integer_dtype(DTYPE_INT),
new_signed_iliteral(INTEGER_INT, 1)),
new_srt(SRT_CMPD_STMT, 1, // non-terminal
new_srt(SRT_BREAK_STMT, 0))),
new_srt(SRT_BREAK_STMT, 0)));

Vector* expected = new_vector(&t_immc);
vector_push(expected, new_label_immc(IMMC_LABEL_NORMAL, IMMC_VIS_NONE, new_string(".L0")));
vector_push(expected,
new_inst_immc(IMMC_INST_JMP, // inst
new_label_immcope(new_string(".L1")), // dst
NULL, // fst_src
NULL)); // snd_src
vector_push(expected, new_label_immc(IMMC_LABEL_NORMAL, IMMC_VIS_NONE, new_string(".L2")));
vector_push(expected,
new_inst_immc(IMMC_INST_LOAD, // inst
new_signed_reg_immcope(IMMC_SUFFIX_LONG, 0), // dst
new_signed_int_immcope(IMMC_SUFFIX_LONG, INTEGER_INT, 1), // fst_src
NULL)); // snd_src
vector_push(expected,
new_inst_immc(IMMC_INST_JEQ, // inst
new_label_immcope(new_string(".L3")), // dst
new_signed_reg_immcope(IMMC_SUFFIX_LONG, 0), // fst_src
new_signed_int_immcope(IMMC_SUFFIX_LONG, INTEGER_INT, 0))); // snd_src
vector_push(expected,
new_inst_immc(IMMC_INST_JMP, // inst
new_label_immcope(new_string(".L3")), // dst
NULL, // fst_src
NULL)); // snd_src
vector_push(expected,
new_inst_immc(IMMC_INST_JMP, // inst
new_label_immcope(new_string(".L2")), // dst
NULL, // fst_src
NULL)); // snd_src
vector_push(expected, new_label_immc(IMMC_LABEL_NORMAL, IMMC_VIS_NONE, new_string(".L3")));
vector_push(expected,
new_inst_immc(IMMC_INST_JMP, // inst
new_label_immcope(new_string(".L1")), // dst
NULL, // fst_src
NULL)); // snd_src
vector_push(expected,
new_inst_immc(IMMC_INST_JMP, // inst
new_label_immcope(new_string(".L0")), // dst
NULL, // fst_src
NULL)); // snd_src
vector_push(expected, new_label_immc(IMMC_LABEL_NORMAL, IMMC_VIS_NONE, new_string(".L1")));

run_stmt_immcgen_test(input, NULL, 0, expected);

delete_vector(expected);
}

void test_immcgen_return_stmt_non_void(void) {
Srt* input =
new_srt(SRT_RET_STMT, 1,
Expand Down
2 changes: 1 addition & 1 deletion tests/resolver/test_statement.c
Original file line number Diff line number Diff line change
Expand Up @@ -858,7 +858,7 @@ void test_resolve_break_stmt_nested(void) {
new_signed_iliteral(INTEGER_INT, 1)),
new_srt(SRT_CMPD_STMT, 1, // non-terminal
new_srt(SRT_BREAK_STMT, 0))),
new_srt(SRT_BREAK_STMT, 0))); // non-terminal
new_srt(SRT_BREAK_STMT, 0)));

run_stmt_resolver_test(input, NULL, NULL, expected);

Expand Down

0 comments on commit 136f6bd

Please sign in to comment.