From 6ec95e41159f9d13bfa56417750689862db92a3b Mon Sep 17 00:00:00 2001 From: Krishna-13-cyber Date: Sat, 25 Jun 2022 11:12:43 +0530 Subject: [PATCH 1/8] Skeleton of return statements added --- include/ast.h | 3 +- src/ast.c | 3 +- src/code_printer.c | 13 +++-- src/parser.y | 73 ++-------------------------- src/semantic.c | 23 --------- test.py | 2 +- tests/run_anywhere/return.sim | 13 +++++ tests/run_anywhere/return.sim.output | 1 + 8 files changed, 27 insertions(+), 104 deletions(-) create mode 100644 tests/run_anywhere/return.sim create mode 100644 tests/run_anywhere/return.sim.output diff --git a/include/ast.h b/include/ast.h index 3b90a36..624c821 100644 --- a/include/ast.h +++ b/include/ast.h @@ -303,7 +303,6 @@ struct ast_node_range_expression sym_ptr symbol_entry; ast_node_param *params; ast_node_compound_statement *body; - ast_node_expression *return_statment; }; struct ast_node_param @@ -375,7 +374,7 @@ ast_node_conditional_else_if *add_else_if_node(ast_node_conditional_else_if *par ast_node_loop_for *create_loop_for_node(ast_node_variable *init, ast_node_range_expression *range, ast_node_compound_statement *body); ast_node_loop_while *create_loop_while_node(ast_node_expression *condition, ast_node_compound_statement *body); ast_node_loop_control *create_loop_control_node(int node_type); -ast_node_function_def *create_function_def_node(sym_ptr symbol_entry, ast_node_param *params, ast_node_compound_statement *body, ast_node_expression *return_stmt); +ast_node_function_def *create_function_def_node(sym_ptr symbol_entry, ast_node_param *params, ast_node_compound_statement *body); ast_node_param *create_parameter_node(); ast_node_param *add_parameter_node(ast_node_param *parent, ast_node_variable *var); ast_node_function_call *create_function_call_node(sym_ptr symbol, ast_node_arguments *arguments); diff --git a/src/ast.c b/src/ast.c index 3fb7bb8..624e9fd 100644 --- a/src/ast.c +++ b/src/ast.c @@ -292,7 +292,7 @@ ast_node_loop_control *create_loop_control_node(int node_type) return loop_control; } -ast_node_function_def *create_function_def_node(sym_ptr symbol_entry, ast_node_param *params, ast_node_compound_statement *body, ast_node_expression *return_stmt) +ast_node_function_def *create_function_def_node(sym_ptr symbol_entry, ast_node_param *params, ast_node_compound_statement *body) { ast_node_function_def *function_def = (ast_node_function_def*)malloc(sizeof(ast_node_function_def)); @@ -300,7 +300,6 @@ ast_node_function_def *create_function_def_node(sym_ptr symbol_entry, ast_node_p function_def->symbol_entry = symbol_entry; function_def->params = params; function_def->body = body; - function_def->return_statment = return_stmt; return function_def; } diff --git a/src/code_printer.c b/src/code_printer.c index 7ff71b0..5c87e35 100644 --- a/src/code_printer.c +++ b/src/code_printer.c @@ -51,6 +51,12 @@ void ast_compound_statement_printer(ast_node_compound_statement *cmpd_stmt, FILE fprintf(handle, "%s", ";\n"); break; + case AST_NODE_FUNC_RETURN: + fprintf(handle, "\t%s ", "return"); + ast_expression_printer(((ast_node_statements*)temp)->child_nodes.return_statement, handle); + fprintf(handle, "%s", ";\n"); + break; + case AST_NODE_LOOP_BREAK: if (((ast_node_statements*)temp)->child_nodes.loop_control->node_type == AST_NODE_LOOP_BREAK) { @@ -626,13 +632,6 @@ void ast_function_definition(ast_node_function_def *def, FILE* handle) } fprintf(handle, "%s", ")\n"); ast_compound_statement_printer(def->body, handle, 1); - - if (def->return_statment != NULL) - { - fprintf(handle, "\t%s ", "return"); - ast_expression_printer(def->return_statment, handle); - fprintf(handle, "%s", ";\n"); - } fprintf(handle, "%s", "}\n"); } } diff --git a/src/parser.y b/src/parser.y index 29bfe90..ab6c4b5 100644 --- a/src/parser.y +++ b/src/parser.y @@ -784,96 +784,31 @@ function_definition: KW_DEF IDENTIFIER COLON DT_INT { if ($2 == NULL){yyerror("function name already defined");} temp = $2; temp->data_type = DT_INTEGER;} COLON parameters compound_statement { - if (vec_last(&$8->child_nodes)->node_type == AST_NODE_FUNC_RETURN) - { - $$ = create_function_def_node($2, $7, $8, vec_pop(&$8->child_nodes)->child_nodes.return_statement); - } - else if (vec_last(&$8->child_nodes)->node_type != AST_NODE_FUNC_RETURN && $2->data_type == DT_VOID_) - { - $$ = create_function_def_node($2, $7, $8, NULL); - } - else if (vec_last(&$8->child_nodes)->node_type != AST_NODE_FUNC_RETURN && $2->data_type != DT_VOID_) - { - yyerror("return statement missing in a non void function"); - } - temp = NULL; - - if (check_function_definition($$) == -1) - { - yyerror("return statement different from return type"); - } + $$ = create_function_def_node($2, $7, $8); printf("func\n"); } | KW_DEF IDENTIFIER COLON DT_BOOL { if ($2 == NULL){yyerror("function name already defined");} temp = $2; temp->data_type = DT_BOOLEAN;} COLON parameters compound_statement { - if (vec_last(&$8->child_nodes)->node_type == AST_NODE_FUNC_RETURN) - { - $$ = create_function_def_node($2, $7, $8, vec_pop(&$8->child_nodes)->child_nodes.return_statement); - } - else if (vec_last(&$8->child_nodes)->node_type != AST_NODE_FUNC_RETURN && $2->data_type == DT_VOID_) - { - $$ = create_function_def_node($2, $7, $8, NULL); - } - else if (vec_last(&$8->child_nodes)->node_type != AST_NODE_FUNC_RETURN && $2->data_type != DT_VOID_) - { - yyerror("return statement missing in a non void function"); - } + $$ = create_function_def_node($2, $7, $8); temp = NULL; - - if (check_function_definition($$) == -1) - { - yyerror("return statement different from return type"); - } printf("func\n"); } | KW_DEF IDENTIFIER COLON DT_CHAR { if ($2 == NULL){yyerror("function name already defined");} temp = $2; temp->data_type = DT_CHAR_;} COLON parameters compound_statement { - if (vec_last(&$8->child_nodes)->node_type == AST_NODE_FUNC_RETURN) - { - $$ = create_function_def_node($2, $7, $8, vec_pop(&$8->child_nodes)->child_nodes.return_statement); - } - else if (vec_last(&$8->child_nodes)->node_type != AST_NODE_FUNC_RETURN && $2->data_type == DT_VOID_) - { - $$ = create_function_def_node($2, $7, $8, NULL); - } - else if (vec_last(&$8->child_nodes)->node_type != AST_NODE_FUNC_RETURN && $2->data_type != DT_VOID_) - { - yyerror("return statement missing in a non void function"); - } + $$ = create_function_def_node($2, $7, $8); temp = NULL; - - if (check_function_definition($$) == -1) - { - yyerror("return statement different from return type"); - } printf("func\n"); } | KW_DEF IDENTIFIER COLON DT_VOID { if ($2 == NULL){yyerror("function name already defined");} temp = $2; temp->data_type = DT_VOID_;} COLON parameters compound_statement { - if (vec_last(&$8->child_nodes)->node_type == AST_NODE_FUNC_RETURN) - { - $$ = create_function_def_node($2, $7, $8, vec_pop(&$8->child_nodes)->child_nodes.return_statement); - } - else if (vec_last(&$8->child_nodes)->node_type != AST_NODE_FUNC_RETURN && $2->data_type == DT_VOID_) - { - $$ = create_function_def_node($2, $7, $8, NULL); - } - else if (vec_last(&$8->child_nodes)->node_type != AST_NODE_FUNC_RETURN && $2->data_type != DT_VOID_) - { - yyerror("return statement missing in a non void function"); - } + $$ = create_function_def_node($2, $7, $8); temp = NULL; - - if (check_function_definition($$) == -1) - { - yyerror("return statement different from return type"); - } printf("func\n"); } ; diff --git a/src/semantic.c b/src/semantic.c index 18adb8d..a246b95 100644 --- a/src/semantic.c +++ b/src/semantic.c @@ -38,26 +38,3 @@ int check_function_call(ast_node_function_call *function_call) return -1; } -int check_function_definition(ast_node_function_def *function_defs) -{ - if (function_defs->symbol_entry != NULL) - { - int expected_dt = function_defs->symbol_entry->data_type; - - if (function_defs->return_statment == NULL && expected_dt == DT_VOID_) - { - return 1; - } - else if (function_defs->return_statment->node_type == AST_NODE_ARITHMETIC_EXP - && (expected_dt == DT_INTEGER || expected_dt == DT_CHAR_)) - { - return 1; - } - else if (function_defs->return_statment->node_type == AST_NODE_BOOLEAN_EXP && expected_dt == DT_BOOLEAN) - { - return 1; - } - } - - return -1; -} \ No newline at end of file diff --git a/test.py b/test.py index e945808..eff9f17 100644 --- a/test.py +++ b/test.py @@ -26,7 +26,7 @@ if fnmatch(file, "*.sim"): print("Running test ", file) - transpile_output = subprocess.run(f"bin/simppru --preprocess -t tests/run_anywhere/{file}", shell=True, capture_output=True) + transpile_output = subprocess.run(f"bin/simppru-1.4 --preprocess -t tests/run_anywhere/{file}", shell=True, capture_output=True) if transpile_output.returncode != 0: print(f"**** ****TEST FAILED**** ****: {file}") diff --git a/tests/run_anywhere/return.sim b/tests/run_anywhere/return.sim new file mode 100644 index 0000000..2a405b0 --- /dev/null +++ b/tests/run_anywhere/return.sim @@ -0,0 +1,13 @@ +def add_subtract: int: int a, int b, bool control { + int c; + if: control { + c := a + b; + return c; + } + else { + c := a * b; + return c; + } +} +result := add_subtract(3, 4, true); +print(result); \ No newline at end of file diff --git a/tests/run_anywhere/return.sim.output b/tests/run_anywhere/return.sim.output new file mode 100644 index 0000000..7f8f011 --- /dev/null +++ b/tests/run_anywhere/return.sim.output @@ -0,0 +1 @@ +7 From 111d1db12557ebf98d2bae15becff7f7d9aea5ed Mon Sep 17 00:00:00 2001 From: Krishna-13-cyber Date: Mon, 25 Jul 2022 13:28:46 +0530 Subject: [PATCH 2/8] Added support for return statements --- src/lexer.l | 21 ++++++++++++++++++++- tests/run_anywhere/return.sim | 2 +- tests/run_anywhere/return.sim.output | 2 +- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/lexer.l b/src/lexer.l index d13a1a7..31e669d 100644 --- a/src/lexer.l +++ b/src/lexer.l @@ -9,6 +9,9 @@ int function_flag = 0; int inside_loop = 0; int brackets = 0; + int func=0; + int inside_func=0; + int brac=0; void yyerror(char* s); int yylex(); @@ -54,6 +57,10 @@ comma ([,]) {braces} { if (!strcmp(yytext, "{")) { + brac++; + if(func==1){ + inside_func=1; + } if (for_loop_flag == -1) { for_loop_flag = 0; @@ -76,8 +83,13 @@ comma ([,]) } else if (!strcmp(yytext, "}")) { + brac--; decrement_scope(); + if(inside_func==1 && brac==0){ + inside_func-=1; + func=0; + } if (inside_loop) { brackets -= 1; @@ -305,7 +317,14 @@ comma ([,]) {function} { if (!strcmp(yytext, "return")) { + if (inside_func!=1) + { + yyerror("cannot call return outside function definition"); + } + if(inside_func==1) + { return KW_RETURN; + } } else if (!strcmp(yytext, "void")) { @@ -314,7 +333,7 @@ comma ([,]) else if (!strcmp(yytext, "def")) { function_flag = 1; - + func=1; return KW_DEF; } } diff --git a/tests/run_anywhere/return.sim b/tests/run_anywhere/return.sim index 2a405b0..93b468f 100644 --- a/tests/run_anywhere/return.sim +++ b/tests/run_anywhere/return.sim @@ -9,5 +9,5 @@ def add_subtract: int: int a, int b, bool control { return c; } } -result := add_subtract(3, 4, true); +int result := add_subtract(3, 4, true); print(result); \ No newline at end of file diff --git a/tests/run_anywhere/return.sim.output b/tests/run_anywhere/return.sim.output index 7f8f011..c793025 100644 --- a/tests/run_anywhere/return.sim.output +++ b/tests/run_anywhere/return.sim.output @@ -1 +1 @@ -7 +7 \ No newline at end of file From 19165fb786384de238dff58a465c18c4c0941973 Mon Sep 17 00:00:00 2001 From: Krishna-13-cyber Date: Tue, 26 Jul 2022 00:19:19 +0530 Subject: [PATCH 3/8] Removed the redundant --- src/parser.y | 1 + test.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/parser.y b/src/parser.y index ab6c4b5..93599f3 100644 --- a/src/parser.y +++ b/src/parser.y @@ -785,6 +785,7 @@ function_definition: KW_DEF IDENTIFIER COLON DT_INT { temp = $2; temp->data_type = DT_INTEGER;} COLON parameters compound_statement { $$ = create_function_def_node($2, $7, $8); + temp = NULL; printf("func\n"); } | KW_DEF IDENTIFIER COLON DT_BOOL { diff --git a/test.py b/test.py index eff9f17..e945808 100644 --- a/test.py +++ b/test.py @@ -26,7 +26,7 @@ if fnmatch(file, "*.sim"): print("Running test ", file) - transpile_output = subprocess.run(f"bin/simppru-1.4 --preprocess -t tests/run_anywhere/{file}", shell=True, capture_output=True) + transpile_output = subprocess.run(f"bin/simppru --preprocess -t tests/run_anywhere/{file}", shell=True, capture_output=True) if transpile_output.returncode != 0: print(f"**** ****TEST FAILED**** ****: {file}") From a8c6533ab7eb37ae9e4cc57bb4d3024f08cca9cb Mon Sep 17 00:00:00 2001 From: Krishna-13-cyber Date: Tue, 26 Jul 2022 13:36:19 +0530 Subject: [PATCH 4/8] Added the error messages for functions without return statements --- src/lexer.l | 8 +++++++- tests/run_anywhere/return.sim | 6 +++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/lexer.l b/src/lexer.l index 31e669d..253e209 100644 --- a/src/lexer.l +++ b/src/lexer.l @@ -12,6 +12,7 @@ int func=0; int inside_func=0; int brac=0; + int ret=0; void yyerror(char* s); int yylex(); @@ -86,6 +87,10 @@ comma ([,]) brac--; decrement_scope(); + if(inside_func == 1 && ret == 0 && brac ==0) + { + yyerror("No return statement for function "); + } if(inside_func==1 && brac==0){ inside_func-=1; func=0; @@ -317,11 +322,12 @@ comma ([,]) {function} { if (!strcmp(yytext, "return")) { + ret++; if (inside_func!=1) { yyerror("cannot call return outside function definition"); } - if(inside_func==1) + if(inside_func==1 && ret > 0) { return KW_RETURN; } diff --git a/tests/run_anywhere/return.sim b/tests/run_anywhere/return.sim index 93b468f..2509540 100644 --- a/tests/run_anywhere/return.sim +++ b/tests/run_anywhere/return.sim @@ -1,4 +1,4 @@ -def add_subtract: int: int a, int b, bool control { +def testing: int: int a, int b, bool control { int c; if: control { c := a + b; @@ -9,5 +9,5 @@ def add_subtract: int: int a, int b, bool control { return c; } } -int result := add_subtract(3, 4, true); -print(result); \ No newline at end of file +int result := testing(3, 4, true); +print(result); From 3c7d0f8aead0556580ee844d6b67ed0676ff5f91 Mon Sep 17 00:00:00 2001 From: Krishna-13-cyber Date: Tue, 26 Jul 2022 16:18:05 +0530 Subject: [PATCH 5/8] Updated with formatting and fixing the known changes --- src/lexer.l | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/lexer.l b/src/lexer.l index 253e209..918be12 100644 --- a/src/lexer.l +++ b/src/lexer.l @@ -9,10 +9,10 @@ int function_flag = 0; int inside_loop = 0; int brackets = 0; - int func=0; - int inside_func=0; - int brac=0; - int ret=0; + int func = 0; + int inside_func = 0; + int brac = 0; + int ret = 0; void yyerror(char* s); int yylex(); @@ -58,9 +58,9 @@ comma ([,]) {braces} { if (!strcmp(yytext, "{")) { - brac++; - if(func==1){ - inside_func=1; + brac++ ; + if(func == 1){ + inside_func = 1; } if (for_loop_flag == -1) { @@ -87,13 +87,13 @@ comma ([,]) brac--; decrement_scope(); - if(inside_func == 1 && ret == 0 && brac ==0) + if(inside_func == 1 && ret == 0 && brac == 0) { - yyerror("No return statement for function "); + yyerror("No return statement for a non void function "); } - if(inside_func==1 && brac==0){ - inside_func-=1; - func=0; + if(inside_func == 1 && brac == 0){ + inside_func -= 1; + func = 0; } if (inside_loop) { @@ -323,11 +323,11 @@ comma ([,]) if (!strcmp(yytext, "return")) { ret++; - if (inside_func!=1) + if (inside_func != 1) { - yyerror("cannot call return outside function definition"); + yyerror("Cannot call return outside function definition"); } - if(inside_func==1 && ret > 0) + if(inside_func == 1 && ret > 0) { return KW_RETURN; } @@ -339,7 +339,7 @@ comma ([,]) else if (!strcmp(yytext, "def")) { function_flag = 1; - func=1; + func = 1; return KW_DEF; } } From c49f9120294c108e224e3d3bd754c93f3ce35067 Mon Sep 17 00:00:00 2001 From: Krishna-13-cyber Date: Wed, 27 Jul 2022 17:28:48 +0530 Subject: [PATCH 6/8] Removed the function from include file --- include/semantic.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/semantic.h b/include/semantic.h index d4e7913..d185348 100644 --- a/include/semantic.h +++ b/include/semantic.h @@ -5,6 +5,5 @@ #include "symbol_table.h" int check_function_call(ast_node_function_call *function_call); -int check_function_definition(ast_node_function_def *function_defs); #endif \ No newline at end of file From 511b4ba5844aae87a7e0ab8fcbcdf82bfd8b67b6 Mon Sep 17 00:00:00 2001 From: Krishna-13-cyber Date: Sun, 31 Jul 2022 00:11:12 +0530 Subject: [PATCH 7/8] Updated with removing the redundant --- src/lexer.l | 16 +++++++++------- test.py | 2 +- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/lexer.l b/src/lexer.l index 918be12..3e15be3 100644 --- a/src/lexer.l +++ b/src/lexer.l @@ -58,8 +58,9 @@ comma ([,]) {braces} { if (!strcmp(yytext, "{")) { - brac++ ; - if(func == 1){ + brac += 1; + if (func == 1) + { inside_func = 1; } if (for_loop_flag == -1) @@ -84,14 +85,15 @@ comma ([,]) } else if (!strcmp(yytext, "}")) { - brac--; + brac -= 1; decrement_scope(); - if(inside_func == 1 && ret == 0 && brac == 0) + if (inside_func == 1 && ret == 0 && brac == 0) { yyerror("No return statement for a non void function "); } - if(inside_func == 1 && brac == 0){ + if (inside_func == 1 && brac == 0) + { inside_func -= 1; func = 0; } @@ -322,12 +324,12 @@ comma ([,]) {function} { if (!strcmp(yytext, "return")) { - ret++; + ret += 1; if (inside_func != 1) { yyerror("Cannot call return outside function definition"); } - if(inside_func == 1 && ret > 0) + if (inside_func == 1 && ret > 0) { return KW_RETURN; } diff --git a/test.py b/test.py index e945808..eff9f17 100644 --- a/test.py +++ b/test.py @@ -26,7 +26,7 @@ if fnmatch(file, "*.sim"): print("Running test ", file) - transpile_output = subprocess.run(f"bin/simppru --preprocess -t tests/run_anywhere/{file}", shell=True, capture_output=True) + transpile_output = subprocess.run(f"bin/simppru-1.4 --preprocess -t tests/run_anywhere/{file}", shell=True, capture_output=True) if transpile_output.returncode != 0: print(f"**** ****TEST FAILED**** ****: {file}") From 4c0dce3936e2058f9f340c9be9bf17b37fccec44 Mon Sep 17 00:00:00 2001 From: Krishna-13-cyber Date: Thu, 11 Aug 2022 22:38:57 +0530 Subject: [PATCH 8/8] Removed simppru version from test script --- src/lexer.l | 2 +- test.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lexer.l b/src/lexer.l index 3e15be3..3352c84 100644 --- a/src/lexer.l +++ b/src/lexer.l @@ -88,7 +88,7 @@ comma ([,]) brac -= 1; decrement_scope(); - if (inside_func == 1 && ret == 0 && brac == 0) + if (inside_func == 1 && ret == 0 && brac == 0) { yyerror("No return statement for a non void function "); } diff --git a/test.py b/test.py index eff9f17..e945808 100644 --- a/test.py +++ b/test.py @@ -26,7 +26,7 @@ if fnmatch(file, "*.sim"): print("Running test ", file) - transpile_output = subprocess.run(f"bin/simppru-1.4 --preprocess -t tests/run_anywhere/{file}", shell=True, capture_output=True) + transpile_output = subprocess.run(f"bin/simppru --preprocess -t tests/run_anywhere/{file}", shell=True, capture_output=True) if transpile_output.returncode != 0: print(f"**** ****TEST FAILED**** ****: {file}")