diff --git a/Makefile b/Makefile index 3c965a6..e2688d9 100644 --- a/Makefile +++ b/Makefile @@ -23,7 +23,7 @@ release_set: $(eval OPT_TYPE=release) debug_set: - $(eval OPT_FLAGS=-DDEBUG_INFO -g3 -fsanitize=undefined -fsanitize=address -fsanitize=enum -fsanitize=signed-integer-overflow -fsanitize=undefined -Wall -Wno-switch -Wno-misleading-indentation) + $(eval OPT_FLAGS=-DDEBUG_INFO -g3 -Wall -Wno-switch -Wno-misleading-indentation) $(eval OPT_TYPE=debug) bin/ode_shell: src/ode_shell.c build/code_converter.o build/pipe_utils.o build/commands.o build/command_corrector.o build/string_utils.o build/model_config.o build/inotify_helpers.o build/to_latex.o build/md5.o build/gnuplot_utils.o build/libfort.a build/libcompiler.a diff --git a/src/code_converter.c b/src/code_converter.c index 3150a0a..8084a9a 100644 --- a/src/code_converter.c +++ b/src/code_converter.c @@ -13,36 +13,37 @@ #define WRITE_NEQ fprintf(file, "#define NEQ %d\n", (int) arrlen(initial)); -static solver_type solver = EULER_ADPT_SOLVER; - struct var_declared_entry_t *var_declared = NULL; struct var_declared_entry_t *ode_position = NULL; -static sds ast_to_c(ast *a, unsigned int *indentation_level); +static sds ast_to_c(ast *a, solver_config *solver_config); extern char *indent_spaces[]; -static sds expression_stmt_to_c(ast *a, unsigned int *indentation_level) { +static sds expression_stmt_to_c(ast *a, solver_config *solver_config) { if(a->expr_stmt != NULL) { - return ast_to_c(a->expr_stmt, indentation_level); + sds tmp = ast_to_c(a->expr_stmt, solver_config); + return tmp; } return sdsempty(); } -static sds return_stmt_to_c(ast *a, unsigned int *indentation_level) { +static sds return_stmt_to_c(ast *a, solver_config *solver_config) { sds buf = sdsempty(); if(a->return_stmt.return_values != NULL) { + int n = arrlen(a->return_stmt.return_values); + unsigned int indentation_level = solver_config->indentation_level; if(n == 1) { - sds tmp = ast_to_c(a->return_stmt.return_values[0], indentation_level); - buf = sdscatprintf(buf, "%sreturn %s;", indent_spaces[*indentation_level], tmp); + sds tmp = ast_to_c(a->return_stmt.return_values[0], solver_config); + buf = sdscatprintf(buf, "%sreturn %s;", indent_spaces[indentation_level], tmp); sdsfree(tmp); } else { for(int i = 0; i < n; i++) { - sds tmp = ast_to_c(a->return_stmt.return_values[i], indentation_level); - buf = sdscatfmt(buf, "%s*ret_val_%i = %s;\n", indent_spaces[*indentation_level], i, tmp); + sds tmp = ast_to_c(a->return_stmt.return_values[i], solver_config); + buf = sdscatfmt(buf, "%s*ret_val_%i = %s;\n", indent_spaces[indentation_level], i, tmp); sdsfree(tmp); } } @@ -51,10 +52,12 @@ static sds return_stmt_to_c(ast *a, unsigned int *indentation_level) { return buf; } -static sds assignment_stmt_to_c(ast *a, unsigned int *indentation_level) { +static sds assignment_stmt_to_c(ast *a, solver_config *solver_config) { sds buf = sdsempty(); char *var_type; + unsigned int indentation_level = solver_config->indentation_level; + if(a->tag == ast_assignment_stmt || a->tag == ast_ode_stmt) { if(a->assignment_stmt.value->tag == ast_boolean_literal || a->assignment_stmt.value->tag == ast_if_expr) { var_type = "bool"; @@ -67,8 +70,8 @@ static sds assignment_stmt_to_c(ast *a, unsigned int *indentation_level) { int global = a->assignment_stmt.name->identifier.global; if(global) { - sds tmp = ast_to_c(a->assignment_stmt.value, indentation_level); - buf = sdscatfmt(buf, "%s%s = %s", indent_spaces[*indentation_level], a->assignment_stmt.name->identifier.value, tmp); + sds tmp = ast_to_c(a->assignment_stmt.value, solver_config); + buf = sdscatfmt(buf, "%s%s = %s", indent_spaces[indentation_level], a->assignment_stmt.name->identifier.value, tmp); sdsfree(tmp); } else { int declared = shgeti(var_declared, a->assignment_stmt.name->identifier.value) != -1; @@ -76,28 +79,28 @@ static sds assignment_stmt_to_c(ast *a, unsigned int *indentation_level) { if(has_ode_symbol) { uint32_t position = a->assignment_stmt.declaration_position; - //TODO: remove the global solver dependency for this function - if(solver == CVODE_SOLVER) { - sds tmp = ast_to_c(a->assignment_stmt.value, indentation_level); - buf = sdscatprintf(buf, "%sNV_Ith_S(rDY, %d) = %s;", indent_spaces[*indentation_level], position - 1, tmp); + + if(solver_config->solver_type == CVODE_SOLVER) { + sds tmp = ast_to_c(a->assignment_stmt.value, solver_config); + buf = sdscatprintf(buf, "%sNV_Ith_S(rDY, %d) = %s;", indent_spaces[indentation_level], position - 1, tmp); sdsfree(tmp); - } else if(solver == EULER_ADPT_SOLVER) { - sds tmp = ast_to_c(a->assignment_stmt.value, indentation_level); - buf = sdscatprintf(buf, "%srDY[%d] = %s;", indent_spaces[*indentation_level], position - 1, tmp); + } else if(solver_config->solver_type == EULER_ADPT_SOLVER) { + sds tmp = ast_to_c(a->assignment_stmt.value, solver_config); + buf = sdscatprintf(buf, "%srDY[%d] = %s;", indent_spaces[indentation_level], position - 1, tmp); sdsfree(tmp); } } else { if(!declared) { - sds tmp = ast_to_c(a->assignment_stmt.value, indentation_level); - buf = sdscatfmt(buf, "%s%s %s = %s;", indent_spaces[*indentation_level], var_type, a->assignment_stmt.name->identifier.value, tmp); + sds tmp = ast_to_c(a->assignment_stmt.value, solver_config); + buf = sdscatfmt(buf, "%s%s %s = %s;", indent_spaces[indentation_level], var_type, a->assignment_stmt.name->identifier.value, tmp); if(a->assignment_stmt.unit != NULL) { buf = sdscatfmt(buf, " //%s", a->assignment_stmt.unit); } shput(var_declared, a->assignment_stmt.name->identifier.value, 1); sdsfree(tmp); } else { - sds tmp = ast_to_c(a->assignment_stmt.value, indentation_level); - buf = sdscatfmt(buf, "%s%s = %s;", indent_spaces[*indentation_level], a->assignment_stmt.name->identifier.value, tmp); + sds tmp = ast_to_c(a->assignment_stmt.value, solver_config); + buf = sdscatfmt(buf, "%s%s = %s;", indent_spaces[indentation_level], a->assignment_stmt.name->identifier.value, tmp); sdsfree(tmp); } } @@ -117,15 +120,15 @@ static sds assignment_stmt_to_c(ast *a, unsigned int *indentation_level) { int global = variables[0]->identifier.global; if(global) { - sds tmp = ast_to_c(call_expr, indentation_level); - buf = sdscatfmt(buf, "%s%s = %s;\n", indent_spaces[*indentation_level], id_name, tmp); + sds tmp = ast_to_c(call_expr, solver_config); + buf = sdscatfmt(buf, "%s%s = %s;\n", indent_spaces[indentation_level], id_name, tmp); sdsfree(tmp); } else { int declared = shgeti(var_declared, id_name) != -1; if(!declared) { - sds tmp = ast_to_c(call_expr, indentation_level); - buf = sdscatfmt(buf, "%s%s %s = %s;\n", indent_spaces[*indentation_level], var_type, id_name, tmp); + sds tmp = ast_to_c(call_expr, solver_config); + buf = sdscatfmt(buf, "%s%s %s = %s;\n", indent_spaces[indentation_level], var_type, id_name, tmp); if(a->assignment_stmt.unit != NULL) { tmp = sdscatfmt(tmp, " //%s", a->assignment_stmt.unit); } @@ -133,8 +136,8 @@ static sds assignment_stmt_to_c(ast *a, unsigned int *indentation_level) { shput(var_declared, id_name, 1); sdsfree(tmp); } else { - sds tmp = ast_to_c(call_expr, indentation_level); - buf = sdscatfmt(buf, "%s%s = %s;\n", indent_spaces[*indentation_level], id_name, tmp); + sds tmp = ast_to_c(call_expr, solver_config); + buf = sdscatfmt(buf, "%s%s = %s;\n", indent_spaces[indentation_level], id_name, tmp); sdsfree(tmp); } } @@ -150,7 +153,7 @@ static sds assignment_stmt_to_c(ast *a, unsigned int *indentation_level) { int declared = shgeti(var_declared, id->identifier.value) != -1; if(!declared) { - buf = sdscatfmt(buf, "%s%s %s;\n", indent_spaces[*indentation_level], var_type, id->identifier.value); + buf = sdscatfmt(buf, "%s%s %s;\n", indent_spaces[indentation_level], var_type, id->identifier.value); shput(var_declared, id->identifier.value, 1); } } @@ -161,18 +164,18 @@ static sds assignment_stmt_to_c(ast *a, unsigned int *indentation_level) { int n_real_args = arrlen(b->call_expr.arguments); - sds tmp = ast_to_c(b->call_expr.function_identifier, indentation_level); - buf = sdscatfmt(buf, "%s%s", indent_spaces[*indentation_level], tmp); + sds tmp = ast_to_c(b->call_expr.function_identifier, solver_config); + buf = sdscatfmt(buf, "%s%s", indent_spaces[indentation_level], tmp); sdsfree(tmp); buf = sdscat(buf, "("); if(n_real_args) { - tmp = ast_to_c(b->call_expr.arguments[0], indentation_level); + tmp = ast_to_c(b->call_expr.arguments[0], solver_config); buf = sdscat(buf, tmp); sdsfree(tmp); for(int i = 1; i < n_real_args; i++) { - tmp = ast_to_c(b->call_expr.arguments[i], indentation_level); + tmp = ast_to_c(b->call_expr.arguments[i], solver_config); buf = sdscatfmt(buf, ", %s", tmp); sdsfree(tmp); } @@ -223,14 +226,14 @@ static sds string_literal_to_c(ast *a) { return buf; } -static sds prefix_expr_to_c(ast *a, unsigned int *indentation_level) { +static sds prefix_expr_to_c(ast *a, solver_config *solver_config) { sds buf = sdsempty(); buf = sdscat(buf, "("); buf = sdscatfmt(buf, "%s", a->prefix_expr.op); - sds tmp = ast_to_c(a->prefix_expr.right, indentation_level); + sds tmp = ast_to_c(a->prefix_expr.right, solver_config); buf = sdscatfmt(buf, "%s", tmp); sdsfree(tmp); buf = sdscat(buf, ")"); @@ -238,13 +241,13 @@ static sds prefix_expr_to_c(ast *a, unsigned int *indentation_level) { return buf; } -static sds infix_expr_to_c(ast *a, unsigned int *indentation_level) { +static sds infix_expr_to_c(ast *a, solver_config *solver_config) { sds buf = sdsempty(); sds tmp; buf = sdscat(buf, "("); - tmp = ast_to_c(a->infix_expr.left, indentation_level); + tmp = ast_to_c(a->infix_expr.left, solver_config); buf = sdscatfmt(buf, "%s", tmp); sdsfree(tmp); @@ -256,7 +259,7 @@ static sds infix_expr_to_c(ast *a, unsigned int *indentation_level) { buf = sdscatfmt(buf, "%s", a->infix_expr.op); } - tmp = ast_to_c(a->infix_expr.right, indentation_level); + tmp = ast_to_c(a->infix_expr.right, solver_config); buf = sdscatfmt(buf, "%s", tmp); buf = sdscat(buf, ")"); sdsfree(tmp); @@ -264,22 +267,20 @@ static sds infix_expr_to_c(ast *a, unsigned int *indentation_level) { return buf; } -static sds if_expr_to_c(ast *a, unsigned int *indentation_level) { +static sds if_expr_to_c(ast *a, solver_config *solver_config) { + unsigned int *indentation_level = &solver_config->indentation_level; sds buf = sdsempty(); - - sds tmp; - buf = sdscatfmt(buf, "%sif", indent_spaces[*indentation_level]); + sds tmp = ast_to_c(a->if_expr.condition, solver_config); - tmp = ast_to_c(a->if_expr.condition, indentation_level); buf = sdscatfmt(buf, "%s {\n", tmp); sdsfree(tmp); (*indentation_level)++; int n = arrlen(a->if_expr.consequence); for(int i = 0; i < n; i++) { - tmp = ast_to_c(a->if_expr.consequence[i], indentation_level); + tmp = ast_to_c(a->if_expr.consequence[i], solver_config); buf = sdscatfmt(buf, "%s\n", tmp); sdsfree(tmp); } @@ -293,7 +294,7 @@ static sds if_expr_to_c(ast *a, unsigned int *indentation_level) { buf = sdscat(buf, " else {\n"); (*indentation_level)++; for(int i = 0; i < n; i++) { - tmp = ast_to_c(a->if_expr.alternative[i], indentation_level); + tmp = ast_to_c(a->if_expr.alternative[i], solver_config); buf = sdscatfmt(buf, "%s\n", tmp); sdsfree(tmp); } @@ -302,7 +303,7 @@ static sds if_expr_to_c(ast *a, unsigned int *indentation_level) { buf = sdscatfmt(buf, "%s}\n", indent_spaces[*indentation_level]); } else if(a->if_expr.elif_alternative) { - tmp = ast_to_c(a->if_expr.elif_alternative, indentation_level); + tmp = ast_to_c(a->if_expr.elif_alternative, solver_config); buf = sdscatfmt(buf, " else %s", tmp); sdsfree(tmp); } else { @@ -312,21 +313,22 @@ static sds if_expr_to_c(ast *a, unsigned int *indentation_level) { return buf; } -static sds while_stmt_to_c(ast *a, unsigned int *indentation_level) { +static sds while_stmt_to_c(ast *a, solver_config *solver_config) { sds buf = sdsempty(); sds tmp; - buf = sdscatfmt(buf, "%swhile", indent_spaces[*indentation_level]); - tmp = ast_to_c(a->while_stmt.condition, indentation_level); - buf = sdscatfmt(buf, "(%s) {\n", tmp); + unsigned int *indentation_level = &solver_config->indentation_level; + buf = sdscatfmt(buf, "%swhile", indent_spaces[*indentation_level]); + tmp = ast_to_c(a->while_stmt.condition, solver_config); + buf = sdscatfmt(buf, "(%s) {\n", tmp); sdsfree(tmp); int n = arrlen(a->while_stmt.body); (*indentation_level)++; for(int i = 0; i < n; i++) { - tmp = ast_to_c(a->while_stmt.body[i], indentation_level); + tmp = ast_to_c(a->while_stmt.body[i], solver_config); buf = sdscatfmt(buf, "%s%s\n", tmp, indent_spaces[*indentation_level]); sdsfree(tmp); } @@ -336,14 +338,12 @@ static sds while_stmt_to_c(ast *a, unsigned int *indentation_level) { return buf; } -static sds call_expr_to_c(ast *a, unsigned int *indentation_level) { +static sds call_expr_to_c(ast *a, solver_config *solver_config) { sds buf = sdsempty(); + sds fn_name = ast_to_c(a->call_expr.function_identifier, solver_config); + buf = sdscatfmt(buf, "%s", fn_name); - - sds fn_name = ast_to_c(a->call_expr.function_identifier, indentation_level); - - buf = sdscat(buf, fn_name); buf = sdscat(buf, "("); int n = arrlen(a->call_expr.arguments); @@ -356,7 +356,7 @@ static sds call_expr_to_c(ast *a, unsigned int *indentation_level) { is_export_fn = true; } - sds tmp = ast_to_c(a->call_expr.arguments[0], indentation_level); + sds tmp = ast_to_c(a->call_expr.arguments[0], solver_config); //TODO: this should only be allowed inside a endfn function if(is_export_fn) { sds ode_name = sdsdup(tmp); @@ -370,7 +370,7 @@ static sds call_expr_to_c(ast *a, unsigned int *indentation_level) { sdsfree(tmp); for(int i = 1; i < n; i++) { - tmp = ast_to_c(a->call_expr.arguments[i], indentation_level); + tmp = ast_to_c(a->call_expr.arguments[i], solver_config); buf = sdscatfmt(buf, ", %s", tmp); sdsfree(tmp); } @@ -382,10 +382,10 @@ static sds call_expr_to_c(ast *a, unsigned int *indentation_level) { return buf; } -static sds global_variable_to_c(ast *a, unsigned int *indentation_level) { +static sds global_variable_to_c(ast *a, solver_config *solver_config) { sds buf = sdsempty(); - sds tmp = ast_to_c(a->assignment_stmt.value, indentation_level); + sds tmp = ast_to_c(a->assignment_stmt.value, solver_config); buf = sdscatfmt(buf, "const real %s = %s;", a->assignment_stmt.name->identifier.value, tmp); if(a->assignment_stmt.unit != NULL) { @@ -397,22 +397,22 @@ static sds global_variable_to_c(ast *a, unsigned int *indentation_level) { return buf; } -static sds ast_to_c(ast *a, unsigned int *indentation_level) { +static sds ast_to_c(ast *a, solver_config *solver_config) { if(a->tag == ast_assignment_stmt || a->tag == ast_grouped_assignment_stmt || a->tag == ast_ode_stmt) { - return assignment_stmt_to_c(a, indentation_level); + return assignment_stmt_to_c(a, solver_config); } if(a->tag == ast_global_stmt) { - return global_variable_to_c(a, indentation_level); + return global_variable_to_c(a, solver_config); } if(a->tag == ast_return_stmt) { - return return_stmt_to_c(a, indentation_level); + return return_stmt_to_c(a, solver_config); } if(a->tag == ast_expression_stmt) { - return expression_stmt_to_c(a, indentation_level); + return expression_stmt_to_c(a, solver_config); } if(a->tag == ast_number_literal) { @@ -431,23 +431,23 @@ static sds ast_to_c(ast *a, unsigned int *indentation_level) { } if(a->tag == ast_prefix_expression) { - return prefix_expr_to_c(a, indentation_level); + return prefix_expr_to_c(a, solver_config); } if(a->tag == ast_infix_expression) { - return infix_expr_to_c(a, indentation_level); + return infix_expr_to_c(a, solver_config); } if(a->tag == ast_if_expr) { - return if_expr_to_c(a, indentation_level); + return if_expr_to_c(a, solver_config); } if(a->tag == ast_while_stmt) { - return while_stmt_to_c(a, indentation_level); + return while_stmt_to_c(a, solver_config); } if(a->tag == ast_call_expression) { - return call_expr_to_c(a, indentation_level); + return call_expr_to_c(a, solver_config); } printf("[WARN] Line %d of file %s - to_c not implemented to operator %d\n", a->token.line_number, a->token.file_name, a->tag); @@ -455,7 +455,7 @@ static sds ast_to_c(ast *a, unsigned int *indentation_level) { return NULL; } -void write_initial_conditions(program p, FILE *file) { +void write_initial_conditions(program p, FILE *file, solver_config *solver_config) { int n_stmt = arrlen(p); for(int i = 0; i < n_stmt; i++) { @@ -465,13 +465,13 @@ void write_initial_conditions(program p, FILE *file) { uint32_t position = a->assignment_stmt.declaration_position; - if(solver == CVODE_SOLVER) { + if(solver_config->solver_type == CVODE_SOLVER) { if(a->assignment_stmt.unit != NULL) { fprintf(file, " NV_Ith_S(x0, %d) = values[%d]; //%s %s\n", position - 1, position - 1, a->assignment_stmt.name->identifier.value, a->assignment_stmt.unit); } else { fprintf(file, " NV_Ith_S(x0, %d) = values[%d]; //%s\n", position - 1, position - 1, a->assignment_stmt.name->identifier.value); } - } else if(solver == EULER_ADPT_SOLVER) { + } else if(solver_config->solver_type == EULER_ADPT_SOLVER) { if(a->assignment_stmt.unit != NULL) { fprintf(file, " x0[%d] = values[%d]; //%s %s\n", position - 1, position - 1, a->assignment_stmt.name->identifier.value, a->assignment_stmt.unit); } else { @@ -580,7 +580,7 @@ static void create_export_functions(FILE *f) { fprintf(f, "}\n\n"); } -static sds generate_exposed_ode_values_for_loop() { +static sds generate_exposed_ode_values_for_loop(enum solver_type_t solver) { sds code = sdsempty(); code = sdscatfmt(code, "__exposed_ode_value__ tmp;\n"); @@ -598,7 +598,7 @@ static sds generate_exposed_ode_values_for_loop() { } -static bool generate_initial_conditions_values(program p, FILE *file, unsigned int *indentation_level) { +static bool generate_initial_conditions_values(program p, FILE *file, solver_config *solver_config) { int n_stmt = arrlen(p); @@ -608,7 +608,7 @@ static bool generate_initial_conditions_values(program p, FILE *file, unsigned i ast *a = p[i]; uint32_t position = a->assignment_stmt.declaration_position; - sds value = ast_to_c(a->assignment_stmt.value, indentation_level); + sds value = ast_to_c(a->assignment_stmt.value, solver_config); fprintf(file, " values[%d] = %s; //%s\n", position - 1, value, a->assignment_stmt.name->identifier.value); sdsfree(value); } @@ -626,7 +626,7 @@ static bool generate_initial_conditions_values(program p, FILE *file, unsigned i return error; } -void write_odes_old_values(program p, FILE *file) { +void write_odes_old_values(program p, FILE *file, solver_config *solver_config) { int n_stmt = arrlen(p); for(int i = 0; i < n_stmt; i++) { @@ -637,10 +637,10 @@ void write_odes_old_values(program p, FILE *file) { uint32_t position = a->assignment_stmt.declaration_position; - if(solver == CVODE_SOLVER) { + if(solver_config->solver_type == CVODE_SOLVER) { fprintf(file, " const real %.*s = NV_Ith_S(sv, %d);\n", (int) strlen(a->assignment_stmt.name->identifier.value) - 1, a->assignment_stmt.name->identifier.value, position - 1); - } else if(solver == EULER_ADPT_SOLVER) { + } else if(solver_config->solver_type == EULER_ADPT_SOLVER) { fprintf(file, " const real %.*s = sv[%d];\n", (int) strlen(a->assignment_stmt.name->identifier.value) - 1, a->assignment_stmt.name->identifier.value, position - 1); } @@ -667,35 +667,40 @@ sds out_file_header(program p) { return ret; } -void write_variables_or_body(program p, FILE *file, unsigned int *indentation_level) { +void write_variables_or_body(program p, FILE *file, solver_config *solver_config) { int n_stmt = arrlen(p); for(int i = 0; i < n_stmt; i++) { ast *a = p[i]; if(a->tag == ast_ode_stmt) { uint32_t position = a->assignment_stmt.declaration_position; - sds tmp = ast_to_c(a->assignment_stmt.value, indentation_level); - sds name = ast_to_c(a->assignment_stmt.name, indentation_level); + sds tmp = ast_to_c(a->assignment_stmt.value, solver_config); + sds name = ast_to_c(a->assignment_stmt.name, solver_config); shput(ode_position, name, position); sdsfree(name); - if(solver == CVODE_SOLVER) { + if(solver_config->solver_type == CVODE_SOLVER) { fprintf(file, " NV_Ith_S(rDY, %d) = %s;\n", position - 1, tmp); - } else if(solver == EULER_ADPT_SOLVER) { + } else if(solver_config->solver_type == EULER_ADPT_SOLVER) { fprintf(file, " rDY[%d] = %s;\n", position - 1, tmp); } sdsfree(tmp); } else { - sds buf = ast_to_c(a, indentation_level); - fprintf(file, "%s\n", buf); + sds buf = ast_to_c(a, solver_config); + if (a->tag == ast_expression_stmt && a->expr_stmt != NULL && a->expr_stmt->tag == ast_call_expression) + fprintf(file, "%s;\n", buf); + else + fprintf(file, "%s\n", buf); sdsfree(buf); } } } -static void write_functions(program p, FILE *file, bool write_end_functions, unsigned int *indentation_level) { +static void write_functions(program p, FILE *file, bool write_end_functions, solver_config *solver_config) { - int n_stmt = arrlen(p); + int n_stmt = arrlen(p); + + unsigned int *indentation_level = &solver_config->indentation_level; for(int i = 0; i < n_stmt; i++) { @@ -724,11 +729,11 @@ static void write_functions(program p, FILE *file, bool write_end_functions, uns int n = arrlen(a->function_stmt.parameters); if(n) { - sds tmp = ast_to_c(a->function_stmt.parameters[0], indentation_level); + sds tmp = ast_to_c(a->function_stmt.parameters[0], solver_config); fprintf(file, "real %s", tmp); sdsfree(tmp); for(int j = 1; j < n; j++) { - tmp = ast_to_c(a->function_stmt.parameters[j], indentation_level); + tmp = ast_to_c(a->function_stmt.parameters[j], solver_config); fprintf(file, ", real %s", tmp); sdsfree(tmp); } @@ -754,13 +759,13 @@ static void write_functions(program p, FILE *file, bool write_end_functions, uns (*indentation_level)++; for(int j = 0; j < n; j++) { ast *ast_a = a->function_stmt.body[j]; - sds tmp = ast_to_c(ast_a, indentation_level); + sds tmp = ast_to_c(ast_a, solver_config); if((ast_a->tag == ast_expression_stmt && ast_a->expr_stmt->tag == ast_if_expr) || ast_a->tag == ast_while_stmt || ast_a->tag == ast_return_stmt) { fprintf(file, "%s\n", tmp); } else { fprintf(file, "%s;\n", tmp); - } + } sdsfree(tmp); } (*indentation_level)--; @@ -783,7 +788,9 @@ static sds generate_end_functions(program functions) { return result; } -static bool write_cvode_solver(FILE *file, program initial, program globals, program functions, program main_body, sds out_header, unsigned int *indentation_level) { +static bool write_cvode_solver(FILE *file, program initial, program globals, program functions, program main_body, sds out_header, solver_config *solver_config) { + + unsigned int *indentation_level = &solver_config->indentation_level; fprintf(file, COMMON_INCLUDES "#include \n" @@ -801,31 +808,31 @@ static bool write_cvode_solver(FILE *file, program initial, program globals, pro create_dynamic_array_headers(file); create_export_functions(file); - write_variables_or_body(globals, file, indentation_level); + write_variables_or_body(globals, file, solver_config); fprintf(file, "\n"); - write_functions(functions, file, false, indentation_level); + write_functions(functions, file, false, solver_config); fprintf(file, "void set_initial_conditions(N_Vector x0, real *values) { \n\n"); - write_initial_conditions(initial, file); + write_initial_conditions(initial, file, solver_config); fprintf(file, "\n}\n\n"); // RHS CPU fprintf(file, "static int solve_model(realtype time, N_Vector sv, N_Vector rDY, void *f_data) {\n\n"); fprintf(file, " //State variables\n"); - write_odes_old_values(main_body, file); + write_odes_old_values(main_body, file, solver_config); fprintf(file, "\n"); fprintf(file, " //Parameters\n"); (*indentation_level)++; - write_variables_or_body(main_body, file, indentation_level); + write_variables_or_body(main_body, file, solver_config); (*indentation_level)--; fprintf(file, "\n return 0; \n\n}\n\n"); - sds export_code = generate_exposed_ode_values_for_loop(); + sds export_code = generate_exposed_ode_values_for_loop(solver_config->solver_type); fprintf(file, "static int check_flag(void *flagvalue, const char *funcname, int opt) {\n" "\n" @@ -925,7 +932,7 @@ static bool write_cvode_solver(FILE *file, program initial, program globals, pro export_code); sdsfree(export_code); - write_functions(functions, file, true, indentation_level); + write_functions(functions, file, true, solver_config); bool error; @@ -934,7 +941,7 @@ static bool write_cvode_solver(FILE *file, program initial, program globals, pro " SUNContext_Create(NULL, &sunctx);\n" " N_Vector x0 = N_VNew_Serial(NEQ, sunctx);\n" "\n"); - error = generate_initial_conditions_values(initial, file, indentation_level); + error = generate_initial_conditions_values(initial, file, solver_config); sds end_functions = generate_end_functions(functions); fprintf(file, " set_initial_conditions(x0, values);\n" @@ -960,7 +967,9 @@ static bool write_cvode_solver(FILE *file, program initial, program globals, pro return error; } -static bool write_adpt_euler_solver(FILE *file, program initial, program globals, program functions, program main_body, sds out_header, unsigned int *indentation_level) { +static bool write_adpt_euler_solver(FILE *file, program initial, program globals, program functions, program main_body, sds out_header, solver_config *solver_config) { + + unsigned int *indentation_level = &solver_config->indentation_level; fprintf(file, COMMON_INCLUDES " \n\n"); @@ -970,29 +979,29 @@ static bool write_adpt_euler_solver(FILE *file, program initial, program globals create_dynamic_array_headers(file); create_export_functions(file); - write_variables_or_body(globals, file, indentation_level); + write_variables_or_body(globals, file, solver_config); fprintf(file, "\n"); - write_functions(functions, file, false, indentation_level); + write_functions(functions, file, false, solver_config); fprintf(file, "void set_initial_conditions(real *x0, real *values) { \n\n"); - write_initial_conditions(initial, file); + write_initial_conditions(initial, file, solver_config); fprintf(file, "\n}\n\n"); // RHS CPU fprintf(file, "static int solve_model(real time, real *sv, real *rDY) {\n\n"); fprintf(file, " //State variables\n"); - write_odes_old_values(main_body, file); + write_odes_old_values(main_body, file, solver_config); fprintf(file, "\n"); fprintf(file, " //Parameters\n"); (*indentation_level)++; - write_variables_or_body(main_body, file, indentation_level); + write_variables_or_body(main_body, file, solver_config); (*indentation_level)--; - sds export_code = generate_exposed_ode_values_for_loop(); + sds export_code = generate_exposed_ode_values_for_loop(solver_config->solver_type); fprintf(file, "\n return 0; \n\n}\n\n"); @@ -1140,14 +1149,14 @@ static bool write_adpt_euler_solver(FILE *file, program initial, program globals sdsfree(export_code); - write_functions(functions, file, true, indentation_level); + write_functions(functions, file, true, solver_config); fprintf(file, "\nint main(int argc, char **argv) {\n" "\n" " real *x0 = (real*) malloc(sizeof(real)*NEQ);\n" "\n"); - bool error = generate_initial_conditions_values(initial, file, indentation_level); + bool error = generate_initial_conditions_values(initial, file, solver_config); sds end_functions = generate_end_functions(functions); fprintf(file, @@ -1175,21 +1184,19 @@ static bool write_adpt_euler_solver(FILE *file, program initial, program globals return error; } -bool convert_to_c(program prog, FILE *file, solver_type p_solver) { - - unsigned int indentation_level = 0; +bool convert_to_c(program prog, FILE *file, solver_type solver) { - solver = p_solver; + solver_config solver_config = {0, solver}; - program main_body = NULL; - program functions = NULL; - program initial = NULL; - program globals = NULL; - program imports = NULL; + program main_body = NULL; + program functions = NULL; + program initial = NULL; + program globals = NULL; + program imports = NULL; - int n_stmt = arrlen(prog); + int n_stmt = arrlen(prog); - bool error = false; + bool error = false; for(int i = 0; i < n_stmt; i++) { ast *a = prog[i]; @@ -1218,10 +1225,10 @@ bool convert_to_c(program prog, FILE *file, solver_type p_solver) { switch(solver) { case CVODE_SOLVER: - error = write_cvode_solver(file, initial, globals, functions, main_body, out_header, &indentation_level); + error = write_cvode_solver(file, initial, globals, functions, main_body, out_header, &solver_config); break; case EULER_ADPT_SOLVER: - error = write_adpt_euler_solver(file, initial, globals, functions, main_body, out_header, &indentation_level); + error = write_adpt_euler_solver(file, initial, globals, functions, main_body, out_header, &solver_config); break; default: fprintf(stderr, "Error: invalid solver type!\n"); diff --git a/src/code_converter.h b/src/code_converter.h index d5991a0..e824a3e 100644 --- a/src/code_converter.h +++ b/src/code_converter.h @@ -1,8 +1,8 @@ #ifndef __C_CONVERTER_H -#define __C_CONVERTER_H +#define __C_CONVERTER_H -#include #include "compiler/parser.h" +#include #define EXPOSED_ODE_VALUES_NAME "__exposed_odes_values__" @@ -11,11 +11,16 @@ struct var_declared_entry_t { int value; }; -typedef enum solver_type_t{ +typedef enum solver_type_t { CVODE_SOLVER, EULER_ADPT_SOLVER } solver_type; +typedef struct solver_config_t { + unsigned int indentation_level; + solver_type solver_type; +} solver_config; + bool convert_to_c(program p, FILE *out, solver_type solver); #endif /* __C_CONVERTER_H */ diff --git a/src/compiler/Makefile b/src/compiler/Makefile index f4672d1..00c810d 100644 --- a/src/compiler/Makefile +++ b/src/compiler/Makefile @@ -16,7 +16,7 @@ release_set: $(eval OPT_FLAGS=-O2) debug_set: - $(eval OPT_FLAGS=-g3 -fsanitize=address -Wall -Wno-switch -Wno-stringop-overflow -Wno-misleading-indentation -mavx -maes) + $(eval OPT_FLAGS=-g3 -DDEBUG_INFO -Wall -Wno-switch -Wno-stringop-overflow -Wno-misleading-indentation -mavx -maes) common: libcompiler.a diff --git a/src/libfort/src/Makefile b/src/libfort/src/Makefile index 7651cd4..c1fea53 100644 --- a/src/libfort/src/Makefile +++ b/src/libfort/src/Makefile @@ -7,7 +7,7 @@ release_set: $(eval OPT_FLAGS=-O2) debug_set: - $(eval OPT_FLAGS=-g3 -fsanitize=address -Wall -Wno-switch -Wno-stringop-overflow -Wno-misleading-indentation -mavx -maes) + $(eval OPT_FLAGS=-g3 -Wall -Wno-switch -Wno-stringop-overflow -Wno-misleading-indentation -mavx -maes) common: libfort.a diff --git a/src/string/sds.c b/src/string/sds.c index b7575dd..865af42 100644 --- a/src/string/sds.c +++ b/src/string/sds.c @@ -817,7 +817,7 @@ int sdscmp(const sds s1, const sds s2) { } sds *sdssplit(const char *s, const char *sep, int *count) { - sdssplitlen(s, strlen(s), sep, strlen(sep), count); + return sdssplitlen(s, strlen(s), sep, strlen(sep), count); } /* Split 's' with separator in 'sep'. An array diff --git a/teste b/teste deleted file mode 100644 index 04e2bdb..0000000 --- a/teste +++ /dev/null @@ -1,309 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - - -#define NEQ 3 -typedef double real; -//------------------ Support functions and data --------------- - -#define print(X) \ -_Generic((X), \ -real: print_real, \ -char*: print_string, \ -bool: print_boolean)(X) - -void print_string(char *c) { - printf("%s",c); -} - -void print_real(real f) { - printf("%lf",f); -} - -void print_boolean(bool b) { - printf("%d",b); -} - -typedef struct __exposed_ode_value__t { - real value; - real time; -} __exposed_ode_value__; - -typedef uint64_t u64; -typedef uint32_t u32; - -struct header { - u64 size; - u64 capacity; -}; - - -//INTERNALS MACROS -#define __original_address__(__l) ( (char*)(__l) - sizeof(struct header) ) -#define __len__(__l) ( ((struct header *)(__original_address__(__l)))->size ) -#define __cap__(__l) ( ((struct header* )(__original_address__(__l)))->capacity ) -#define __internal_len__(__l) ( ((struct header *)(__l))->size ) -#define __internal_cap__(__l) ( ((struct header *)(__l))->capacity ) - - -//API -#define append(__l, __item) ( (__l) = maybe_grow( (__l), sizeof(*(__l)) ), __l[__len__(__l)++] = (__item) ) -#define arrlength(__l) ( (__l) ? __len__(__l) : 0 ) -#define arrcapacity(__l) ( (__l) ? __cap__(__l) : 0 ) -#define arrfree(__l) free(__original_address__(__l)) - -void * maybe_grow(void *list, u64 data_size_in_bytes) { - - u64 m = 2; - - if(list == NULL) { - list = malloc(data_size_in_bytes * m + sizeof(struct header)); - if(!list) return NULL; - __internal_cap__(list) = m; - __internal_len__(list) = 0; - } - else { - - u64 list_size = __len__(list); - m = __cap__(list); - - if ((list_size + 1) > m) { - m = m * 2; - list = realloc(__original_address__(list), data_size_in_bytes * m + sizeof(struct header)); - if(!list) return NULL; - __internal_cap__(list) = m; - } - else { - return list; - } - } - - return (char*) list + sizeof(struct header); -} - -__exposed_ode_value__ **__exposed_odes_values__ = NULL; -static int __ode_last_iteration__ = 1; - -real ode_get_value(int ode_position, int timestep) { - return __exposed_odes_values__[ode_position][timestep].value; -} - -real ode_get_time(int ode_position, int timestep) { - return __exposed_odes_values__[ode_position][timestep].time; -} - -int ode_get_num_iterations() { - return __ode_last_iteration__; -} - -const real n = 1.000000e+03; //dimensionless -const real init_i = 3.000000e+00; - -void set_initial_conditions(real *x0, real *values) { - - x0[0] = values[0]; //S - x0[1] = values[1]; //I - x0[2] = values[2]; //R - -} - -static int solve_model(real time, real *sv, real *rDY) { - - //State variables - const real S = sv[0]; - const real I = sv[1]; - const real R = sv[2]; - - //Parameters - real beta = (4.000000e-01/n); - real gamma = 4.000000e-02; //dimensionless - rDY[0] = (((-beta)*S)*I); - rDY[1] = (((beta*S)*I)-(gamma*I)); - rDY[2] = (gamma*I); - - return 0; - -} - -void solve_ode(real *sv, float final_time, FILE *f, char *file_name) { - - real rDY[NEQ]; - - real reltol = 1e-5; - real abstol = 1e-5; - real _tolerances_[NEQ]; - real _aux_tol = 0.0; - //initializes the variables - real dt = 0.000001; - real time_new = 0.0; - real previous_dt = dt; - - real edos_old_aux_[NEQ]; - real edos_new_euler_[NEQ]; - real *_k1__ = (real*) malloc(sizeof(real)*NEQ); - real *_k2__ = (real*) malloc(sizeof(real)*NEQ); - real *_k_aux__; - - const real _beta_safety_ = 0.8; - - const real __tiny_ = pow(abstol, 2.0f); - - if(time_new + dt > final_time) { - dt = final_time - time_new; - } - - solve_model(time_new, sv, rDY); - time_new += dt; - - for(int i = 0; i < NEQ; i++){ - _k1__[i] = rDY[i]; - } - - real min[NEQ]; - real max[NEQ]; - - for(int i = 0; i < NEQ; i++) { - min[i] = DBL_MAX; - max[i] = DBL_MIN; - } - - while(1) { - - for(int i = 0; i < NEQ; i++) { - //stores the old variables in a vector - edos_old_aux_[i] = sv[i]; - //computes euler method - edos_new_euler_[i] = _k1__[i] * dt + edos_old_aux_[i]; - //steps ahead to compute the rk2 method - sv[i] = edos_new_euler_[i]; - } - - time_new += dt; - solve_model(time_new, sv, rDY); - time_new -= dt;//step back - - double greatestError = 0.0, auxError = 0.0; - for(int i = 0; i < NEQ; i++) { - // stores the new evaluation - _k2__[i] = rDY[i]; - _aux_tol = fabs(edos_new_euler_[i]) * reltol; - _tolerances_[i] = (abstol > _aux_tol) ? abstol : _aux_tol; - - // finds the greatest error between the steps - auxError = fabs(((dt / 2.0) * (_k1__[i] - _k2__[i])) / _tolerances_[i]); - - greatestError = (auxError > greatestError) ? auxError : greatestError; - } - ///adapt the time step - greatestError += __tiny_; - previous_dt = dt; - ///adapt the time step - dt = _beta_safety_ * dt * sqrt(1.0f/greatestError); - - if (time_new + dt > final_time) { - dt = final_time - time_new; - } - - //it doesn't accept the solution - if ((greatestError >= 1.0f) && dt > 0.00000001) { - //restore the old values to do it again - for(int i = 0; i < NEQ; i++) { - sv[i] = edos_old_aux_[i]; - } - //throw the results away and compute again - } else{//it accepts the solutions - - if (time_new + dt > final_time) { - dt = final_time - time_new; - } - - _k_aux__ = _k2__; - _k2__ = _k1__; - _k1__ = _k_aux__; - - //it steps the method ahead, with euler solution - for(int i = 0; i < NEQ; i++){ - sv[i] = edos_new_euler_[i]; - } - fprintf(f, "%lf ", time_new); - for(int i = 0; i < NEQ; i++) { - fprintf(f, "%lf ", sv[i]); - if(sv[i] < min[i]) min[i] = sv[i]; - if(sv[i] > max[i]) max[i] = sv[i]; - __exposed_ode_value__ tmp; - tmp.time = time_new; - tmp.value = sv[i]; - append(__exposed_odes_values__[i], tmp); - - } - - __ode_last_iteration__ += 1; - fprintf(f, "\n"); - - if(time_new + previous_dt >= final_time) { - if(final_time == time_new) { - break; - } else if(time_new < final_time) { - dt = previous_dt = final_time - time_new; - time_new += previous_dt; - break; - } - } else { - time_new += previous_dt; - } - - } - } - - char *min_max = malloc(strlen(file_name) + 9); - sprintf(min_max, "%s_min_max", file_name); - FILE* min_max_file = fopen(min_max, "w"); - for(int i = 0; i < NEQ; i++) { - fprintf(min_max_file, "%e;%e\n", min[i], max[i]); - } - fclose(min_max_file); - free(min_max); - - free(_k1__); - free(_k2__); -} - - -int main(int argc, char **argv) { - - real *x0 = (real*) malloc(sizeof(real)*NEQ); - - real values[3]; - values[0] = (n-init_i); //S - values[1] = init_i; //I - values[2] = 0.000000e+00; //R - - for(int i = 0; i < 3; i++) { - __exposed_ode_value__ *__ode_values_array__ = NULL; - __exposed_ode_value__ __tmp__; - append(__exposed_odes_values__, NULL); - __tmp__.value = values[i]; - __tmp__.time = 0; - append(__ode_values_array__, __tmp__); - __exposed_odes_values__[i] = __ode_values_array__; - } - set_initial_conditions(x0, values); - FILE *f = fopen(argv[2], "w"); - fprintf(f, "#t, S, I, R\n"); - fprintf(f, "0.0 "); - for(int i = 0; i < NEQ; i++) { - fprintf(f, "%lf ", x0[i]); - } - fprintf(f, "\n"); - - - solve_ode(x0, strtod(argv[1], NULL), f, argv[2]); - free(x0); - - return (0); -} \ No newline at end of file diff --git a/tests/Makefile b/tests/Makefile index a10affb..a606081 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -8,7 +8,7 @@ all: build_dir libcompiler.a debug: debug_set all debug_set: - $(eval OPT_FLAGS=-DDEBUG_INFO -g3 -fsanitize=undefined -fsanitize=address -fsanitize=enum -fsanitize=signed-integer-overflow -fsanitize=undefined -Wall -Wno-switch -Wno-misleading-indentation) + $(eval OPT_FLAGS=-DDEBUG_INFO -g3 -Wall -Wno-switch -Wno-misleading-indentation) $(eval OPT_TYPE=debug)