--- a/stage4/generate_c/generate_c_st.cc Mon Jul 11 09:47:27 2011 +0100
+++ b/stage4/generate_c/generate_c_st.cc Fri Jul 29 16:03:28 2011 +0100
@@ -35,6 +35,9 @@
*/
+
+#include "../../util/strdup.hh"
+
/***********************************************************************/
/***********************************************************************/
/***********************************************************************/
@@ -434,7 +437,7 @@
ERROR;
if (search_expression_type->is_time_type(left_type) ||
search_expression_type->is_string_type(left_type))
- return print_compare_function("__eq_", left_type, symbol->l_exp, symbol->r_exp);
+ return print_compare_function("EQ_", left_type, symbol->l_exp, symbol->r_exp);
return print_binary_expression(symbol->l_exp, symbol->r_exp, " == ");
}
@@ -445,7 +448,7 @@
ERROR;
if (search_expression_type->is_time_type(left_type) ||
search_expression_type->is_string_type(left_type))
- return print_compare_function("__ne_", left_type, symbol->l_exp, symbol->r_exp);
+ return print_compare_function("NE_", left_type, symbol->l_exp, symbol->r_exp);
return print_binary_expression(symbol->l_exp, symbol->r_exp, " != ");
}
@@ -456,7 +459,7 @@
ERROR;
if (search_expression_type->is_time_type(left_type) ||
search_expression_type->is_string_type(left_type))
- return print_compare_function("__lt_", left_type, symbol->l_exp, symbol->r_exp);
+ return print_compare_function("LT_", left_type, symbol->l_exp, symbol->r_exp);
if (!search_base_type.type_is_enumerated(left_type))
return print_binary_expression(symbol->l_exp, symbol->r_exp, " < ");
ERROR;
@@ -470,7 +473,7 @@
ERROR;
if (search_expression_type->is_time_type(left_type) ||
search_expression_type->is_string_type(left_type))
- return print_compare_function("__gt_", left_type, symbol->l_exp, symbol->r_exp);
+ return print_compare_function("GT_", left_type, symbol->l_exp, symbol->r_exp);
if (!search_base_type.type_is_enumerated(left_type))
return print_binary_expression(symbol->l_exp, symbol->r_exp, " > ");
ERROR;
@@ -484,7 +487,7 @@
ERROR;
if (search_expression_type->is_time_type(left_type) ||
search_expression_type->is_string_type(left_type))
- return print_compare_function("__le_", left_type, symbol->l_exp, symbol->r_exp);
+ return print_compare_function("LE_", left_type, symbol->l_exp, symbol->r_exp);
if (!search_base_type.type_is_enumerated(left_type))
return print_binary_expression(symbol->l_exp, symbol->r_exp, " <= ");
ERROR;
@@ -498,7 +501,7 @@
ERROR;
if (search_expression_type->is_time_type(left_type) ||
search_expression_type->is_string_type(left_type))
- return print_compare_function("__ge_", left_type, symbol->l_exp, symbol->r_exp);
+ return print_compare_function("GE_", left_type, symbol->l_exp, symbol->r_exp);
if (!search_base_type.type_is_enumerated(left_type))
return print_binary_expression(symbol->l_exp, symbol->r_exp, " >= ");
ERROR;
@@ -511,7 +514,7 @@
if ((typeid(*left_type) == typeid(time_type_name_c) && typeid(*right_type) == typeid(time_type_name_c)) ||
(typeid(*left_type) == typeid(tod_type_name_c) && typeid(*right_type) == typeid(time_type_name_c)) ||
(typeid(*left_type) == typeid(dt_type_name_c) && typeid(*right_type) == typeid(time_type_name_c)))
- return print_binary_function("__TIME_ADD", symbol->l_exp, symbol->r_exp);
+ return print_binary_function("__time_add", symbol->l_exp, symbol->r_exp);
if (!search_expression_type->is_same_type(left_type, right_type))
ERROR;
if (search_expression_type->is_integer_type(left_type) || search_expression_type->is_real_type(left_type))
@@ -529,7 +532,7 @@
(typeid(*left_type) == typeid(tod_type_name_c) && typeid(*right_type) == typeid(tod_type_name_c)) ||
(typeid(*left_type) == typeid(dt_type_name_c) && typeid(*right_type) == typeid(time_type_name_c)) ||
(typeid(*left_type) == typeid(dt_type_name_c) && typeid(*right_type) == typeid(dt_type_name_c)))
- return print_binary_function("__TIME_SUB", symbol->l_exp, symbol->r_exp);
+ return print_binary_function("__time_sub", symbol->l_exp, symbol->r_exp);
if (!search_expression_type->is_same_type(left_type, right_type))
ERROR;
if (search_expression_type->is_integer_type(left_type) || search_expression_type->is_real_type(left_type))
@@ -543,7 +546,7 @@
symbol_c *right_type = search_expression_type->get_type(symbol->r_exp);
if ((typeid(*left_type) == typeid(time_type_name_c) && search_expression_type->is_integer_type(right_type)) ||
(typeid(*left_type) == typeid(time_type_name_c) && search_expression_type->is_real_type(right_type)))
- return print_binary_function("__TIME_MUL", symbol->l_exp, symbol->r_exp);
+ return print_binary_function("__time_mul", symbol->l_exp, symbol->r_exp);
if (!search_expression_type->is_same_type(left_type, right_type))
ERROR;
if (search_expression_type->is_integer_type(left_type) || search_expression_type->is_real_type(left_type))
@@ -557,7 +560,7 @@
symbol_c *right_type = search_expression_type->get_type(symbol->r_exp);
if ((typeid(*left_type) == typeid(time_type_name_c) && search_expression_type->is_integer_type(right_type)) ||
(typeid(*left_type) == typeid(time_type_name_c) && search_expression_type->is_real_type(right_type)))
- return print_binary_function("__TIME_DIV", symbol->l_exp, symbol->r_exp);
+ return print_binary_function("__time_div", symbol->l_exp, symbol->r_exp);
if (!search_expression_type->is_same_type(left_type, right_type))
ERROR;
if (search_expression_type->is_integer_type(left_type) || search_expression_type->is_real_type(left_type))
@@ -614,71 +617,89 @@
function_call_param_iterator_c function_call_param_iterator(symbol);
- function_declaration_c *f_decl = function_symtable.find_value(symbol->function_name);
- if (f_decl == function_symtable.end_value()) {
- /* The function called is not in the symtable, so we test if it is a
- * standard function defined in standard */
-
- function_type_t current_function_type = get_function_type((identifier_c *)symbol->function_name);
- if (current_function_type == function_none) ERROR;
-
- symbol_c *function_return_type = search_expression_type->get_type(symbol);
-
- int nb_param = ((list_c *)parameter_assignment_list)->n;
-
- symbol_c *en_param_name = (symbol_c *)(new identifier_c("EN"));
- /* Get the value from EN param */
- symbol_c *EN_param_value = function_call_param_iterator.search_f(en_param_name);
- if (EN_param_value == NULL)
- EN_param_value = (symbol_c*)(new boolean_literal_c((symbol_c*)(new bool_type_name_c()), new boolean_true_c()));
- else
- nb_param --;
- ADD_PARAM_LIST(en_param_name, EN_param_value, (symbol_c*)(new bool_type_name_c()), function_param_iterator_c::direction_in)
-
- symbol_c *eno_param_name = (symbol_c *)(new identifier_c("ENO"));
- /* Get the value from ENO param */
- symbol_c *ENO_param_value = function_call_param_iterator.search_f(eno_param_name);
- if (ENO_param_value != NULL)
- nb_param --;
- ADD_PARAM_LIST(eno_param_name, ENO_param_value, (symbol_c*)(new bool_type_name_c()), function_param_iterator_c::direction_out)
-
- #include "st_code_gen.c"
-
- }
- else {
- function_name = symbol->function_name;
-
- /* loop through each function parameter, find the value we should pass
- * to it, and then output the c equivalent...
+ function_declaration_c *f_decl = (function_declaration_c *)symbol->called_function_declaration;
+ if (f_decl == NULL) ERROR;
+
+ function_name = symbol->function_name;
+
+ /* loop through each function parameter, find the value we should pass
+ * to it, and then output the c equivalent...
+ */
+ function_param_iterator_c fp_iterator(f_decl);
+ identifier_c *param_name;
+ /* flag to cirreclty handle calls to extensible standard functions (i.e. functions with variable number of input parameters) */
+ bool found_first_extensible_parameter = false;
+ for(int i = 1; (param_name = fp_iterator.next()) != NULL; i++) {
+ if (fp_iterator.is_extensible_param() && (!found_first_extensible_parameter)) {
+ /* We are calling an extensible function. Before passing the extensible
+ * parameters, we must add a dummy paramater value to tell the called
+ * function how many extensible parameters we will be passing.
+ *
+ * Note that stage 3 has already determined the number of extensible
+ * paramters, and stored that info in the abstract syntax tree. We simply
+ * re-use that value.
+ */
+ /* NOTE: we are not freeing the malloc'd memory. This is not really a bug.
+ * Since we are writing a compiler, which runs to termination quickly,
+ * we can consider this as just memory required for the compilation process
+ * that will be free'd when the program terminates.
+ */
+ char *tmp = (char *)malloc(32); /* enough space for a call with 10^31 (larger than 2^64) input parameters! */
+ if (tmp == NULL) ERROR;
+ int res = snprintf(tmp, 32, "%d", symbol->extensible_param_count);
+ if ((res >= 32) || (res < 0)) ERROR;
+ identifier_c *param_value = new identifier_c(tmp);
+ uint_type_name_c *param_type = new uint_type_name_c();
+ identifier_c *param_name = new identifier_c("");
+ ADD_PARAM_LIST(param_name, param_value, param_type, function_param_iterator_c::direction_in)
+ found_first_extensible_parameter = true;
+ }
+
+ if (fp_iterator.is_extensible_param()) {
+ /* since we are handling an extensible parameter, we must add the index to the
+ * parameter name so we can go looking for the value passed to the correct
+ * extended parameter (e.g. IN1, IN2, IN3, IN4, ...)
+ */
+ char *tmp = (char *)malloc(32); /* enough space for a call with 10^31 (larger than 2^64) input parameters! */
+ int res = snprintf(tmp, 32, "%d", fp_iterator.extensible_param_index());
+ if ((res >= 32) || (res < 0)) ERROR;
+ param_name = new identifier_c(strdup2(param_name->value, tmp));
+ if (param_name->value == NULL) ERROR;
+ }
+
+ symbol_c *param_type = fp_iterator.param_type();
+ if (param_type == NULL) ERROR;
+
+ function_param_iterator_c::param_direction_t param_direction = fp_iterator.param_direction();
+
+ symbol_c *param_value = NULL;
+
+ /* Get the value from a foo(<param_name> = <param_value>) style call */
+ if (param_value == NULL)
+ param_value = function_call_param_iterator.search_f(param_name);
+
+ /* Get the value from a foo(<param_value>) style call */
+ if ((param_value == NULL) && !fp_iterator.is_en_eno_param_implicit()) {
+ param_value = function_call_param_iterator.next_nf();
+ }
+
+ /* if no more parameter values in function call, and the current parameter
+ * of the function declaration is an extensible parameter, we
+ * have reached the end, and should simply jump out of the for loop.
*/
- function_param_iterator_c fp_iterator(f_decl);
- identifier_c *param_name;
- for(int i = 1; (param_name = fp_iterator.next()) != NULL; i++) {
-
- symbol_c *param_type = fp_iterator.param_type();
- if (param_type == NULL) ERROR;
-
- function_param_iterator_c::param_direction_t param_direction = fp_iterator.param_direction();
-
- /* Get the value from a foo(<param_name> = <param_value>) style call */
- symbol_c *param_value = function_call_param_iterator.search_f(param_name);
-
- /* Get the value from a foo(<param_value>) style call */
- if (param_value == NULL) {
- param_value = function_call_param_iterator.next_nf();
- if (param_value != NULL && fp_iterator.is_en_eno_param_implicit()) ERROR;
- }
-
- if (param_value == NULL && param_direction == function_param_iterator_c::direction_in) {
- /* No value given for parameter, so we must use the default... */
- /* First check whether default value specified in function declaration...*/
- param_value = fp_iterator.default_value();
- }
-
- ADD_PARAM_LIST(param_name, param_value, param_type, param_direction)
- } /* for(...) */
- // symbol->parameter_assignment->accept(*this);
- }
+ if ((param_value == NULL) && (fp_iterator.is_extensible_param())) {
+ break;
+ }
+
+ if ((param_value == NULL) && (param_direction == function_param_iterator_c::direction_in)) {
+ /* No value given for parameter, so we must use the default... */
+ /* First check whether default value specified in function declaration...*/
+ param_value = fp_iterator.default_value();
+ }
+
+ ADD_PARAM_LIST(param_name, param_value, param_type, param_direction)
+ } /* for(...) */
+ // symbol->parameter_assignment->accept(*this);
if (function_call_param_iterator.next_nf() != NULL) ERROR;
@@ -686,15 +707,18 @@
if (!this->is_variable_prefix_null()) {
PARAM_LIST_ITERATOR() {
- if ((PARAM_DIRECTION == function_param_iterator_c::direction_out ||
- PARAM_DIRECTION == function_param_iterator_c::direction_inout) &&
- PARAM_VALUE != NULL) {
- if (!has_output_params) {
- has_output_params = true;
- }
- }
- }
- }
+ if ((PARAM_DIRECTION == function_param_iterator_c::direction_out ||
+ PARAM_DIRECTION == function_param_iterator_c::direction_inout) &&
+ PARAM_VALUE != NULL) {
+ has_output_params = true;
+ }
+ }
+ }
+
+ /* Check whether we are calling an overloaded function! */
+ /* (fdecl_mutiplicity==2) => calling overloaded function */
+ int fdecl_mutiplicity = function_symtable.multiplicity(symbol->function_name);
+ if (fdecl_mutiplicity == 0) ERROR;
if (function_type_prefix != NULL) {
s4o.print("(");
@@ -702,20 +726,32 @@
s4o.print(")");
}
if (function_type_suffix != NULL) {
- function_type_suffix = search_expression_type->default_literal_type(function_type_prefix);
+ function_type_suffix = search_expression_type->default_literal_type(function_type_prefix);
}
if (has_output_params) {
- fcall_number++;
- s4o.print("__");
+ fcall_number++;
+ s4o.print("__");
fbname->accept(*this);
s4o.print("_");
function_name->accept(*this);
+ if (fdecl_mutiplicity == 2) {
+ /* function being called is overloaded! */
+ s4o.print("__");
+ print_function_parameter_data_types_c overloaded_func_suf(&s4o);
+ f_decl->accept(overloaded_func_suf);
+ }
if (function_type_suffix != NULL)
function_type_suffix->accept(*this);
s4o.print_integer(fcall_number);
}
else {
function_name->accept(*this);
+ if (fdecl_mutiplicity == 2) {
+ /* function being called is overloaded! */
+ s4o.print("__");
+ print_function_parameter_data_types_c overloaded_func_suf(&s4o);
+ f_decl->accept(overloaded_func_suf);
+ }
if (function_type_suffix != NULL)
function_type_suffix->accept(*this);
}
@@ -845,7 +881,10 @@
symbol_c *param_value = function_call_param_iterator.search_f(param_name);
/* Get the value from a foo(<param_value>) style call */
- if (param_value == NULL)
+ /* When using the informal invocation style, user can not pass values to EN or ENO parameters if these
+ * were implicitly defined!
+ */
+ if ((param_value == NULL) && !fp_iterator.is_en_eno_param_implicit())
param_value = function_call_param_iterator.next_nf();
symbol_c *param_type = fp_iterator.param_type();
@@ -889,7 +928,10 @@
symbol_c *param_value = function_call_param_iterator.search_f(param_name);
/* Get the value from a foo(<param_value>) style call */
- if (param_value == NULL)
+ /* When using the informal invocation style, user can not pass values to EN or ENO parameters if these
+ * were implicitly defined!
+ */
+ if ((param_value == NULL) && !fp_iterator.is_en_eno_param_implicit())
param_value = function_call_param_iterator.next_nf();
/* now output the value assignment */