# HG changeset patch # User Mario de Sousa # Date 1351089168 -3600 # Node ID 966f32af570dc9506c3e079659c64dba68a9f9ba # Parent e837adad24376a40982fbec42c7de7f1aee2bd6f Major code cleanup: IL code generation now uses symbol.datatype (filled in during stage3 data type checking) instead of determining the symbol's datatype by itself. diff -r e837adad2437 -r 966f32af570d stage4/generate_c/generate_c_il.cc --- a/stage4/generate_c/generate_c_il.cc Thu Oct 18 10:57:13 2012 +0100 +++ b/stage4/generate_c/generate_c_il.cc Wed Oct 24 15:32:48 2012 +0100 @@ -48,7 +48,7 @@ /***********************************************************************/ -/* A new class to ouput the il default variable to c++ code +/* A new class to ouput the IL implicit variable to c++ code * We use this class, inheriting from symbol_c, so it may be used * as any other symbol_c object in the intermediate parse tree, * more specifically, so it can be used as any other il operand. @@ -77,7 +77,7 @@ /* A class to print out to the resulting C++ code - * the IL default variable name. + * the IL implicit variable name. * * It includes a reference to its name, * and the data type of the data currently stored @@ -86,7 +86,7 @@ * of the union top reference!! * * Note that we also need to keep track of the data type of - * the value currently being stored in the default variable. + * the value currently being stored in the IL implicit variable. * This is required so we can process parenthesis, * * e.g. : @@ -102,7 +102,7 @@ * When we do execute the 'AND (' operation, we need to know the data type * of the operand, which in this case is the result of the evaluation of the * instruction list inside the parenthesis. We can only know this if we - * keep track of the data type currently stored in the default variable! + * keep track of the data type currently stored in the IL implicit variable! * * We use the current_type inside the generate_c_il::default_variable_name variable * to track this! @@ -110,7 +110,6 @@ class il_default_variable_c: public symbol_c { public: symbol_c *var_name; /* in principle, this should point to an indentifier_c */ - symbol_c *current_type; public: il_default_variable_c(const char *var_name_str, symbol_c *current_type); @@ -140,29 +139,28 @@ } variablegeneration_t; private: - /* The initial value that should be given to the IL default variable - * imediately after a parenthesis is opened. - * This variable is only used to pass data from the - * il_expression_c visitor to the simple_instr_list_c visitor. - * - * e.g.: - * LD var1 - * AND ( var2 - * OR var3 - * ) - * - * In the above code sample, the line 'AND ( var2' constitutes - * an il_expression_c, where var2 should be loaded into the - * il default variable before continuing with the expression - * inside the parenthesis. - * Unfortunately, only the simple_instr_list_c may do the - * initial laoding of the var2 bariable following the parenthesis, - * so the il_expression_c visitor will have to pass 'var2' as a - * parameter to the simple_instr_list_c visitor. - * Ergo, the existance of the following parameter...! + /* Label to which the current IL jump operation should jump to... */ + /* This variable is used to pass data from the + * il_jump_operation_c visitor + * to the il jump operator visitors (i.e. JMP_operator_c, + * JMPC_operator_c, JMPCN_operator_c, ...) */ - symbol_c *il_default_variable_init_value; - + symbol_c *jump_label; + + /* the data type of the IL implicit variable... */ + #define IL_DEFVAR_T VAR_LEADER "IL_DEFVAR_T" + /* The name of the IL implicit variable... */ + #define IL_DEFVAR VAR_LEADER "IL_DEFVAR" + /* The name of the variable used to pass the result of a + * parenthesised instruction list to the immediately preceding + * scope ... + */ + #define IL_DEFVAR_BACK VAR_LEADER "IL_DEFVAR_BACK" + + il_default_variable_c implicit_variable_current; /* the current implicit variable, with the datatype resulting from the previous IL operation */ + il_default_variable_c implicit_variable_result; /* the resulting implicit variable, with the datatype resulting from the current IL operation */ + il_default_variable_c implicit_variable_result_back; + /* Operand to the IL operation currently being processed... */ /* These variables are used to pass data from the * il_simple_operation_c and il_expression_c visitors @@ -170,43 +168,6 @@ * LDN_operator_c, ST_operator_c, STN_operator_c, ...) */ symbol_c *current_operand; - symbol_c *current_operand_type; - - /* Label to which the current IL jump operation should jump to... */ - /* This variable is used to pass data from the - * il_jump_operation_c visitor - * to the il jump operator visitors (i.e. JMP_operator_c, - * JMPC_operator_c, JMPCN_operator_c, ...) - */ - symbol_c *jump_label; - - /* The result of the comparison IL operations (GT, EQ, LT, ...) - * is a boolean variable. - * This class keeps track of the current data type stored in the - * il default variable. This is usually done by keeping a reference - * to the data type of the last operand. Nevertheless, in the case of - * the comparison IL operators, the data type of the result (a boolean) - * is not the data type of the operand. We therefore need an object - * of the boolean data type to keep as a reference of the current - * data type. - * The following object is it... - */ - bool_type_name_c bool_type; - lint_type_name_c lint_type; - lword_type_name_c lword_type; - lreal_type_name_c lreal_type; - - /* the data type of the IL default variable... */ - #define IL_DEFVAR_T VAR_LEADER "IL_DEFVAR_T" - /* The name of the IL default variable... */ - #define IL_DEFVAR VAR_LEADER "IL_DEFVAR" - /* The name of the variable used to pass the result of a - * parenthesised instruction list to the immediately preceding - * scope ... - */ - #define IL_DEFVAR_BACK VAR_LEADER "IL_DEFVAR_BACK" - il_default_variable_c default_variable_name; - il_default_variable_c default_variable_back_name; /* When calling a function block, we must first find it's type, * by searching through the declarations of the variables currently @@ -237,16 +198,15 @@ public: generate_c_il_c(stage4out_c *s4o_ptr, symbol_c *name, symbol_c *scope, const char *variable_prefix = NULL) : generate_c_typedecl_c(s4o_ptr), - default_variable_name(IL_DEFVAR, NULL), - default_variable_back_name(IL_DEFVAR_BACK, NULL) + implicit_variable_current (IL_DEFVAR, NULL), + implicit_variable_result (IL_DEFVAR, NULL), + implicit_variable_result_back(IL_DEFVAR_BACK, NULL) { search_fb_instance_decl = new search_fb_instance_decl_c (scope); search_varfb_instance_type = new search_varfb_instance_type_c(scope); search_var_instance_decl = new search_var_instance_decl_c (scope); current_operand = NULL; - current_operand_type = NULL; - il_default_variable_init_value = NULL; current_array_type = NULL; current_param_type = NULL; fcall_number = 0; @@ -265,25 +225,32 @@ il->accept(*this); } - /* Declare the backup to the default variable, that will store the result - * of the IL operations executed inside a parenthesis... - */ - void declare_backup_variable(void) { + private: + /* Declare an implicit IL variable... */ + void declare_implicit_variable(il_default_variable_c *implicit_var) { s4o.print(s4o.indent_spaces); s4o.print(IL_DEFVAR_T); s4o.print(" "); - print_backup_variable(); + implicit_var->datatype = NULL; + implicit_var->accept(*this); s4o.print(";\n"); } - void print_backup_variable(void) { - this->default_variable_back_name.accept(*this); - } - - void reset_default_variable_name(void) { - this->default_variable_name.current_type = NULL; - this->default_variable_back_name.current_type = NULL; - } + public: + /* Declare the default variable, that will store the result of the IL operations */ + void declare_implicit_variable(void) { + declare_implicit_variable(&this->implicit_variable_result); + } + + /* Declare the backup to the default variable, that will store the result of the IL operations executed inside a parenthesis... */ + void declare_implicit_variable_back(void) { + declare_implicit_variable(&this->implicit_variable_result_back); + } + + void print_implicit_variable_back(void) { + this->implicit_variable_result_back.accept(*this); + } + private: /* a small helper function */ @@ -308,11 +275,11 @@ } /* A helper function... */ - void *XXX_function(const char *func, symbol_c *lo, symbol_c *ro) { - if ((NULL == lo) || (NULL == ro)) ERROR; - if (NULL == func) ERROR; - - lo->accept(*this); + void *XXX_function(symbol_c *res, const char *func, symbol_c *lo, symbol_c *ro) { + if ((NULL == res) || (NULL == lo) || (NULL == ro)) ERROR; + if (NULL == func) ERROR; + + res->accept(*this); s4o.print(" = "); s4o.print(func); s4o.print("("); @@ -323,7 +290,7 @@ return NULL; } - /* A helper function... */ + /* A helper function... used for implicit FB calls: S1, R1, CLK, CU, CD, PV, IN, and PT */ void *XXX_CAL_operator(const char *param_name, symbol_c *fb_name) { if (wanted_variablegeneration != expression_vg) { s4o.print(param_name); @@ -340,7 +307,7 @@ //SYM_REF3(il_param_assignment_c, il_assign_operator, il_operand, simple_instr_list) il_assign_operator_c il_assign_operator(¶m); - il_param_assignment_c il_param_assignment(&il_assign_operator, &this->default_variable_name, NULL); + il_param_assignment_c il_param_assignment(&il_assign_operator, &this->implicit_variable_current, NULL); // SYM_LIST(il_param_list_c) il_param_list_c il_param_list; il_param_list.add_element(&il_param_assignment); @@ -353,81 +320,48 @@ } /* A helper function... */ - void *CMP_operator(symbol_c *o, const char *operation) { - if (NULL == o) ERROR; - if (NULL == this->default_variable_name.current_type) ERROR; - - symbol_c *backup = this->default_variable_name.current_type; - this->default_variable_name.current_type = &(this->bool_type); - this->default_variable_name.accept(*this); - this->default_variable_name.current_type = backup; - + void *CMP_operator(symbol_c *operand, const char *operation) { + if (NULL == operand) ERROR; + if (NULL == operand->datatype) ERROR; + if (NULL == this->implicit_variable_current.datatype) ERROR; + + this->implicit_variable_result.accept(*this); s4o.print(" = "); s4o.print(operation); - this->default_variable_name.current_type->accept(*this); + operand->datatype->accept(*this); + /* NOTE: we are calling a standard Function: + * 1st parameter: EN (enable) + * 2nd parameter: ENO (enable output) + * 3rd parameter: number of operands we will be passing (required because we are calling an extensible standard function!) + * 4th parameter: the left hand side of the comparison expression (in out case, the IL implicit variable) + * 4th parameter: the right hand side of the comparison expression (in out case, current operand) + */ s4o.print("(__BOOL_LITERAL(TRUE), NULL, 2, "); - this->default_variable_name.accept(*this); + this->implicit_variable_current.accept(*this); s4o.print(", "); - o->accept(*this); + operand->accept(*this); s4o.print(")"); - /* the data type resulting from this operation... */ - this->default_variable_name.current_type = &(this->bool_type); return NULL; } /* A helper function... */ void C_modifier(void) { - if (get_datatype_info_c::is_BOOL_compatible(default_variable_name.current_type)) { - s4o.print("if ("); - this->default_variable_name.accept(*this); - s4o.print(") "); - } - else {ERROR;} + if (!get_datatype_info_c::is_BOOL_compatible(implicit_variable_current.datatype)) ERROR; + s4o.print("if ("); + this->implicit_variable_current.accept(*this); + s4o.print(") "); } /* A helper function... */ void CN_modifier(void) { - if (get_datatype_info_c::is_BOOL_compatible(default_variable_name.current_type)) { - s4o.print("if (!"); - this->default_variable_name.accept(*this); - s4o.print(") "); - } - else {ERROR;} - } - - void BYTE_operator_result_type(void) { - if (get_datatype_info_c::is_ANY_INT_literal(this->default_variable_name.current_type)) { - if (get_datatype_info_c::is_ANY_INT_literal(this->current_operand_type)) - this->default_variable_name.current_type = &(this->lword_type); - else - this->default_variable_name.current_type = this->current_operand_type; - } - else if (get_datatype_info_c::is_ANY_INT_literal(this->current_operand_type)) - this->current_operand_type = this->default_variable_name.current_type; - } - - void NUM_operator_result_type(void) { - if (get_datatype_info_c::is_ANY_REAL_literal(this->default_variable_name.current_type)) { - if (get_datatype_info_c::is_ANY_INT_literal(this->current_operand_type) || - get_datatype_info_c::is_ANY_REAL_literal(this->current_operand_type)) - this->default_variable_name.current_type = &(this->lreal_type); - else - this->default_variable_name.current_type = this->current_operand_type; - } - else if (get_datatype_info_c::is_ANY_INT_literal(this->default_variable_name.current_type)) { - if (get_datatype_info_c::is_ANY_INT_literal(this->current_operand_type)) - this->default_variable_name.current_type = &(this->lint_type); - else if (get_datatype_info_c::is_ANY_REAL_literal(this->current_operand_type)) - this->default_variable_name.current_type = &(this->lreal_type); - else - this->default_variable_name.current_type = this->current_operand_type; - } - else if (get_datatype_info_c::is_ANY_INT_literal(this->current_operand_type) || - get_datatype_info_c::is_ANY_REAL_literal(this->current_operand_type)) - this->current_operand_type = this->default_variable_name.current_type; - } + if (!get_datatype_info_c::is_BOOL_compatible(implicit_variable_current.datatype)) ERROR; + s4o.print("if (!"); + this->implicit_variable_current.accept(*this); + s4o.print(") "); + } + void *print_getter(symbol_c *symbol) { unsigned int vartype = search_var_instance_decl->get_vartype(symbol); @@ -496,7 +430,7 @@ symbol->accept(*this); s4o.print(","); if (negative) { - if (get_datatype_info_c::is_BOOL_compatible(this->current_operand_type)) + if (get_datatype_info_c::is_BOOL_compatible(this->current_operand->datatype)) s4o.print("!"); else s4o.print("~"); @@ -516,12 +450,9 @@ public: void *visit(il_default_variable_c *symbol) { symbol->var_name->accept(*this); - if (NULL != symbol->current_type) { + if (NULL != symbol->datatype) { s4o.print("."); - if ( get_datatype_info_c::is_ANY_INT_literal(symbol->current_type)) this->lint_type.accept(*this); - else if ( get_datatype_info_c::is_ANY_REAL_literal(this->default_variable_name.current_type)) this->lreal_type.accept(*this); - else if ( get_datatype_info_c::is_BOOL_compatible(this->default_variable_name.current_type)) this->bool_type.accept(*this); - else symbol->current_type->accept(*this); + symbol->datatype->accept(*this); s4o.print("var"); } return NULL; } @@ -529,21 +460,6 @@ private: -#if 0 -I NEED TO FIX THIS!!! -TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO -void *visit(eno_param_c *symbol) { - if (this->is_variable_prefix_null()) { - s4o.print("*"); - } - else { - this->print_variable_prefix(); - } - s4o.print("ENO"); - return NULL; -} -TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO -#endif /********************************/ @@ -764,23 +680,17 @@ /*| instruction_list il_instruction */ void *visit(instruction_list_c *symbol) { - /* Declare the backup to the default variable, that will store the result - * of the IL operations executed inside a parenthesis... - */ - declare_backup_variable(); - - /* Declare the default variable, that will store the result of the IL operations... */ + /* Declare the IL implicit variable, that will store the result of the IL operations... */ + declare_implicit_variable(); + + /* Declare the backup to the IL implicit variable, that will store the result of the IL operations executed inside a parenthesis... */ + declare_implicit_variable_back(); + /* s4o.print(s4o.indent_spaces); - s4o.print(IL_DEFVAR_T); - s4o.print(" "); - this->default_variable_name.accept(*this); - s4o.print(";\n"); - s4o.print(s4o.indent_spaces); - print_backup_variable(); + this->implicit_variable_result_back.accept(*this); s4o.print(".INTvar = 0;\n\n"); - + */ print_list(symbol, s4o.indent_spaces, ";\n" + s4o.indent_spaces, ";\n"); - return NULL; } @@ -788,32 +698,32 @@ /* | label ':' [il_incomplete_instruction] eol_list */ // SYM_REF2(il_instruction_c, label, il_instruction) void *visit(il_instruction_c *symbol) { + /* all previous IL instructions should have the same datatype (checked in stage3), so we get the datatype from the first previous IL instruction we find */ + implicit_variable_current.datatype = (symbol->prev_il_instruction.empty())? NULL : symbol->prev_il_instruction[0]->datatype; + implicit_variable_result .datatype = symbol->datatype; + if (NULL != symbol->label) { symbol->label->accept(*this); s4o.print(":\n"); s4o.print(s4o.indent_spaces); } + if (NULL != symbol->il_instruction) { symbol->il_instruction->accept(*this); } - return NULL; -} + + implicit_variable_result .datatype = NULL; + implicit_variable_current.datatype = NULL; + return NULL; +} + /* | il_simple_operator [il_operand] */ //SYM_REF2(il_simple_operation_c, il_simple_operator, il_operand) void *visit(il_simple_operation_c *symbol) { this->current_operand = symbol->il_operand; - if (NULL == this->current_operand) { - this->current_operand_type = NULL; - } else { - this->current_operand_type = this->current_operand->datatype; - if (NULL == this->current_operand_type) ERROR; - } - symbol->il_simple_operator->accept(*this); - this->current_operand = NULL; - this->current_operand_type = NULL; return NULL; } @@ -826,19 +736,11 @@ symbol_c* function_type_suffix = NULL; DECLARE_PARAM_LIST() - symbol_c *param_data_type = default_variable_name.current_type; - symbol_c *return_data_type = NULL; - function_call_param_iterator_c function_call_param_iterator(symbol); function_declaration_c *f_decl = (function_declaration_c *)symbol->called_function_declaration; if (f_decl == NULL) ERROR; - /* determine the base data type returned by the function being called... */ - search_base_type_c search_base_type; - return_data_type = (symbol_c *)f_decl->type_name->accept(search_base_type); - if (NULL == return_data_type) ERROR; - function_name = symbol->function_name; /* loop through each function parameter, find the value we should pass @@ -846,7 +748,7 @@ */ function_param_iterator_c fp_iterator(f_decl); identifier_c *param_name; - /* flag to remember whether we have already used the value stored in the default variable to pass to the first parameter */ + /* flag to remember whether we have already used the value stored in the implicit variable to pass to the first parameter */ bool used_defvar = false; /* flag to cirreclty handle calls to extensible standard functions (i.e. functions with variable number of input parameters) */ bool found_first_extensible_parameter = false; @@ -897,13 +799,13 @@ /* if it is the first parameter in a non-formal function call (which is the * case being handled!), semantics specifies that we should - * get the value off the IL default variable! + * get the value off the IL implicit variable! * * However, if the parameter is an implicitly defined EN or ENO parameter, we should not - * use the default variable as a source of data to pass to those parameters! + * use the IL implicit variable as a source of data to pass to those parameters! */ if ((param_value == NULL) && (!used_defvar) && !fp_iterator.is_en_eno_param_implicit()) { - param_value = &this->default_variable_name; + param_value = &this->implicit_variable_current; used_defvar = true; } @@ -948,9 +850,7 @@ int fdecl_mutiplicity = function_symtable.multiplicity(symbol->function_name); if (fdecl_mutiplicity == 0) ERROR; - default_variable_name.current_type = return_data_type; - this->default_variable_name.accept(*this); - default_variable_name.current_type = param_data_type; + this->implicit_variable_result.accept(*this); s4o.print(" = "); if (function_type_prefix != NULL) { @@ -1044,8 +944,6 @@ } s4o.print(")"); - /* the data type returned by the function, and stored in the il default variable... */ - default_variable_name.current_type = return_data_type; CLEAR_PARAM_LIST() @@ -1056,60 +954,94 @@ /* | il_expr_operator '(' [il_operand] eol_list [simple_instr_list] ')' */ //SYM_REF4(il_expression_c, il_expr_operator, il_operand, simple_instr_list, unused) void *visit(il_expression_c *symbol) { - /* We will be recursevely interpreting an instruction list, - * so we store a backup of the data type of the value currently stored - * in the default variable, and set the current data type to NULL + LD_operator_c *tmp_LD_operator = NULL; + il_simple_operation_c *tmp_il_simple_operation = NULL; + il_simple_instruction_c *tmp_il_simple_instruction = NULL; + + /* We will be recursevely interpreting an instruction list, so we store a backup of the implicit_variable_result/current. + * Notice that they will be overwriten while processing the parenthsized instruction list. */ - symbol_c *old_current_default_variable_data_type = this->default_variable_name.current_type; - this->default_variable_name.current_type = NULL; - - /* Pass the symbol->il_operand to the simple_instr_list visitor - * using the il_default_variable_init_value parameter... - * Note that the simple_instr_list_c visitor will set this parameter - * to NULL as soon as it does not require it any longer, - * so we don't do it here again after the - * symbol->simple_instr_list->accept(*this); - * returns... - */ - this->il_default_variable_init_value = symbol->il_operand; + il_default_variable_c old_implicit_variable_current = this->implicit_variable_current; + il_default_variable_c old_implicit_variable_result = this->implicit_variable_result; + + /* If the symbol->il_operand is not NULL, then we instantiate a 'LD' operation and insert it into the simple_instr_list + * (i.e. add an equivalent LD operation to the Abstract Syntax Tree), and let it be handled like any other LD operation! + */ + if (NULL != symbol->il_operand) { + tmp_LD_operator = new LD_operator_c(); + if (NULL == tmp_LD_operator) ERROR; + /* copy all the location, datatpe, etc.. data from symbol->il_operand to the new object! */ + *((symbol_c *)tmp_LD_operator) = *(symbol->il_operand); + + tmp_il_simple_operation = new il_simple_operation_c(tmp_LD_operator, symbol->il_operand); + if (NULL == tmp_il_simple_operation) ERROR; + /* copy all the location, datatpe, etc.. data from symbol->il_operand to the new object! */ + *((symbol_c *)tmp_il_simple_operation) = *(symbol->il_operand); + + tmp_il_simple_instruction = new il_simple_instruction_c(tmp_il_simple_operation); + if (NULL == tmp_il_simple_instruction) ERROR; + /* copy all the location, datatpe, etc.. data from symbol->il_operand to the new object! */ + *((symbol_c *)tmp_il_simple_instruction) = *(symbol->il_operand); + + if (NULL == symbol->simple_instr_list) { + symbol->simple_instr_list = new simple_instr_list_c(); + if (NULL == symbol->simple_instr_list) ERROR; + /* copy all the location, datatpe, etc.. data from symbol->il_operand to the new object! */ + *((symbol_c *)symbol->simple_instr_list) = *(symbol->il_operand); + } + list_c *tmp_list = dynamic_cast (symbol->simple_instr_list); + if (NULL == tmp_list) ERROR; + tmp_list->insert_element(tmp_il_simple_instruction, 0); + } /* Now do the parenthesised instructions... */ - /* NOTE: the following code line will get the variable - * this->default_variable_name.current_type updated! - */ + /* NOTE: the following code line will overwrite the variables implicit_variable_current and implicit_variable_result */ symbol->simple_instr_list->accept(*this); + /* delete/undo any changes made to the AST above */ + if (NULL != symbol->il_operand) { + delete tmp_LD_operator; + delete tmp_il_simple_operation; + delete tmp_il_simple_instruction; + list_c *tmp_list = dynamic_cast (symbol->simple_instr_list); + if (NULL == tmp_list) ERROR; + delete tmp_list->elements[0]; + tmp_list->remove_element(0); + if (0 == tmp_list->n) { + delete symbol->simple_instr_list; + symbol->simple_instr_list = NULL; + } + } + /* Now do the operation, using the previous result! */ - /* NOTE: The result of the previous instruction list will be stored + /* NOTE: The result of the previous instruction list in the parenthesis will be stored * in a variable named IL_DEFVAR_BACK. This is done in the visitor * to instruction_list_c objects... */ - this->current_operand = &(this->default_variable_back_name); - this->current_operand_type = this->default_variable_back_name.current_type; - - this->default_variable_name.current_type = old_current_default_variable_data_type; - if (NULL == this->current_operand_type) ERROR; + this->implicit_variable_result_back.datatype = symbol->simple_instr_list->datatype; + this->current_operand = &(this->implicit_variable_result_back); + + this->implicit_variable_current = old_implicit_variable_current; + this->implicit_variable_result = old_implicit_variable_result; symbol->il_expr_operator->accept(*this); this->current_operand = NULL; - this->current_operand_type = NULL; - this->default_variable_back_name.current_type = NULL; - return NULL; -} + this->implicit_variable_result_back.datatype = NULL; + return NULL; +} + /* il_jump_operator label */ // SYM_REF2(il_jump_operation_c, il_jump_operator, label) void *visit(il_jump_operation_c *symbol) { - /* Pass the symbol->label to the il_jump_operation visitor - * using the jump_label parameter... - */ + /* Pass the symbol->label to the il_jump_operation visitor using the jump_label parameter... */ this->jump_label = symbol->label; symbol->il_jump_operator->accept(*this); this->jump_label = NULL; - - return NULL; -} + return NULL; +} + /* il_call_operator prev_declared_fb_name * | il_call_operator prev_declared_fb_name '(' ')' @@ -1235,18 +1167,11 @@ symbol_c* function_type_suffix = NULL; DECLARE_PARAM_LIST() - symbol_c *return_data_type = NULL; - function_call_param_iterator_c function_call_param_iterator(symbol); function_declaration_c *f_decl = (function_declaration_c *)symbol->called_function_declaration; if (f_decl == NULL) ERROR; - /* determine the base data type returned by the function being called... */ - search_base_type_c search_base_type; - return_data_type = (symbol_c *)f_decl->type_name->accept(search_base_type); - if (NULL == return_data_type) ERROR; - function_name = symbol->function_name; /* loop through each function parameter, find the value we should pass @@ -1357,8 +1282,7 @@ /* function being called is NOT overloaded! */ f_decl = NULL; - default_variable_name.current_type = return_data_type; - this->default_variable_name.accept(*this); + this->implicit_variable_result.accept(*this); s4o.print(" = "); if (function_type_prefix != NULL) { @@ -1451,7 +1375,6 @@ // symbol->parameter_assignment->accept(*this); s4o.print(")"); - /* the data type returned by the function, and stored in the il default variable... */ CLEAR_PARAM_LIST() @@ -1467,8 +1390,7 @@ /* | simple_instr_list il_simple_instruction */ // SYM_LIST(simple_instr_list_c) void *visit(simple_instr_list_c *symbol) { - /* A simple_instr_list_c is used to store a list of il operations - * being done within parenthesis... + /* A simple_instr_list_c is used to store a list of il operations being done within parenthesis... * * e.g.: * LD var1 @@ -1477,11 +1399,12 @@ * OR var4 * ) * + * NOTE 1: * This will be converted to C++ by defining a new scope - * with a new il default variable, and executing the il operands + * with a new il implicit variable, and executing the il operands * within this new scope. * At the end of the scope the result, i.e. the value currently stored - * in the il default variable is copied to the variable used to take this + * in the il implicit variable is copied to the variable used to take this * value to the outside scope... * * The above example will result in the following C++ code: @@ -1502,59 +1425,31 @@ * * } * - * The intial value of the il default variable (in the above - * example 'var2') is passed to this simple_instr_list_c visitor - * using the il_default_variable_init_value parameter. - * Since it is possible to have parenthesis inside other parenthesis - * recursively, we reset the il_default_variable_init_value to NULL - * as soon as we no longer require it, as it may be used once again - * in the line - * print_list(symbol, s4o.indent_spaces, ";\n" + s4o.indent_spaces, ";\n"); - * + * NOTE 2: + * If the intial value of the il implicit variable (in the above + * example 'var2') exists, then the il_expression_c will insert an equivalent + * LD operation into the parenthesized instruction list- This means we do not + * need to do anything here to handle this special situation! */ - /* Declare the default variable, that will store the result of the IL operations... */ + /* Declare the IL implicit variable, that will store the result of the IL operations... */ s4o.print("{\n"); s4o.indent_right(); - - s4o.print(s4o.indent_spaces); - s4o.print(IL_DEFVAR_T); - s4o.print(" "); - this->default_variable_name.accept(*this); - s4o.print(";\n\n"); - - /* Check whether we should initiliase the il default variable... */ - if (NULL != this->il_default_variable_init_value) { - /* Yes, we must... */ - /* We will do it by instatiating a LD operator, and having this - * same generate_c_il_c class visiting it! - */ - LD_operator_c ld_oper; - il_simple_operation_c il_simple_oper(&ld_oper, this->il_default_variable_init_value); - - s4o.print(s4o.indent_spaces); - il_simple_oper.accept(*this); - s4o.print(";\n"); - } - - /* this parameter no longer required... */ - this->il_default_variable_init_value = NULL; - + declare_implicit_variable(); + print_list(symbol, s4o.indent_spaces, ";\n" + s4o.indent_spaces, ";\n"); - /* copy the result in the default variable to the variable - * used to pass the data out to the scope enclosing - * the current scope! - * - * We also need to update the data type currently stored within - * the variable used to pass the data to the outside scope... + /* copy the result in the IL implicit variable to the variable + * used to pass the data out to the scope enclosing the current scope! */ - this->default_variable_back_name.current_type = this->default_variable_name.current_type; + this->implicit_variable_result_back.datatype = symbol->datatype; + this->implicit_variable_result .datatype = symbol->datatype; + s4o.print("\n"); s4o.print(s4o.indent_spaces); - this->default_variable_back_name.accept(*this); + this->implicit_variable_result_back.accept(*this); s4o.print(" = "); - this->default_variable_name.accept(*this); + this->implicit_variable_result.accept(*this); s4o.print(";\n"); s4o.indent_left(); @@ -1564,103 +1459,87 @@ return NULL; } + // SYM_REF1(il_simple_instruction_c, il_simple_instruction, symbol_c *prev_il_instruction;) -void *visit(il_simple_instruction_c *symbol) { - return symbol->il_simple_instruction->accept(*this); -} - +void *visit(il_simple_instruction_c *symbol) {return symbol->il_simple_instruction->accept(*this);} /* | il_initial_param_list il_param_instruction */ // SYM_LIST(il_param_list_c) -void *visit(il_param_list_c *symbol) {ERROR; return NULL;} // should never get called! +void *visit(il_param_list_c *symbol) {ERROR; return NULL;} // should never get called! /* il_assign_operator il_operand * | il_assign_operator '(' eol_list simple_instr_list ')' */ // SYM_REF4(il_param_assignment_c, il_assign_operator, il_operand, simple_instr_list, unused) -void *visit(il_param_assignment_c *symbol) {ERROR; return NULL;} // should never get called! +void *visit(il_param_assignment_c *symbol) {ERROR; return NULL;} // should never get called! /* il_assign_out_operator variable */ // SYM_REF2(il_param_out_assignment_c, il_assign_out_operator, variable); -void *visit(il_param_out_assignment_c *symbol) {ERROR; return NULL;} // should never get called! +void *visit(il_param_out_assignment_c *symbol) {ERROR; return NULL;} // should never get called! + /*******************/ /* B 2.2 Operators */ /*******************/ -void *visit(LD_operator_c *symbol) { +void *visit(LD_operator_c *symbol) { if (wanted_variablegeneration != expression_vg) { s4o.print("LD"); return NULL; } - - /* the data type resulting from this operation... */ - this->default_variable_name.current_type = this->current_operand_type; - XXX_operator(&(this->default_variable_name), " = ", this->current_operand); - return NULL; -} - -void *visit(LDN_operator_c *symbol) { - /* the data type resulting from this operation... */ - this->default_variable_name.current_type = this->current_operand_type; - XXX_operator(&(this->default_variable_name), - get_datatype_info_c::is_BOOL_compatible(this->current_operand_type)?" = !":" = ~", - this->current_operand); - return NULL; -} - -void *visit(ST_operator_c *symbol) { - symbol_c *operand_type = search_varfb_instance_type->get_type_id(this->current_operand); - if (get_datatype_info_c::is_ANY_INT_literal(this->default_variable_name.current_type) || - get_datatype_info_c::is_ANY_REAL_literal(this->default_variable_name.current_type)) - this->default_variable_name.current_type = this->current_operand_type; + XXX_operator(&(this->implicit_variable_result), " = ", this->current_operand); + return NULL; +} + + +void *visit(LDN_operator_c *symbol) { + XXX_operator(&(this->implicit_variable_result), get_datatype_info_c::is_BOOL_compatible(this->current_operand->datatype)?" = !":" = ~", this->current_operand); + return NULL; +} + + +void *visit(ST_operator_c *symbol) { if (this->is_variable_prefix_null()) { this->current_operand->accept(*this); s4o.print(" = "); - print_check_function(operand_type, (symbol_c*)&(this->default_variable_name)); + print_check_function(this->current_operand->datatype, (symbol_c*)&(this->implicit_variable_current)); } else { - print_setter(this->current_operand, operand_type, (symbol_c*)&(this->default_variable_name)); - } - /* the data type resulting from this operation is unchanged. */ - return NULL; -} - -void *visit(STN_operator_c *symbol) { - symbol_c *operand_type = search_varfb_instance_type->get_type_id(this->current_operand); - if (get_datatype_info_c::is_ANY_INT_literal(this->default_variable_name.current_type)) - this->default_variable_name.current_type = this->current_operand_type; - + print_setter(this->current_operand, this->current_operand->datatype, (symbol_c*)&(this->implicit_variable_current)); + } + return NULL; +} + + +void *visit(STN_operator_c *symbol) { if (this->is_variable_prefix_null()) { this->current_operand->accept(*this); s4o.print(" = "); - if (get_datatype_info_c::is_BOOL_compatible(this->current_operand_type)) + if (get_datatype_info_c::is_BOOL_compatible(this->current_operand->datatype)) s4o.print("!"); else - s4o.print("~"); - this->default_variable_name.accept(*this); + s4o.print("~"); + this->implicit_variable_current.accept(*this); } else { - print_setter(this->current_operand, operand_type, (symbol_c*)&(this->default_variable_name), NULL, NULL, true); - } - /* the data type resulting from this operation is unchanged. */ - return NULL; -} - -void *visit(NOT_operator_c *symbol) { + print_setter(this->current_operand, this->current_operand->datatype, (symbol_c*)&(this->implicit_variable_current), NULL, NULL, true); + } + return NULL; +} + + +void *visit(NOT_operator_c *symbol) { /* NOTE: the standard allows syntax in which the NOT operator is followed by an optional * NOT [] * However, it does not define the semantic of the NOT operation when the is specified. * We therefore consider it an error if an il_operand is specified! * The error is caught in stage 3! */ - if ((NULL != this->current_operand) || (NULL != this->current_operand_type)) ERROR; - XXX_operator(&(this->default_variable_name), - get_datatype_info_c::is_BOOL_compatible(this->default_variable_name.current_type)?" = !":" = ~", - &(this->default_variable_name)); - /* the data type resulting from this operation is unchanged. */ - return NULL; -} + if (NULL != this->current_operand) ERROR; + XXX_operator(&(this->implicit_variable_result), get_datatype_info_c::is_BOOL_compatible(symbol->datatype)?" = !":" = ~", &(this->implicit_variable_current)); + return NULL; +} + void *visit(S_operator_c *symbol) { if (wanted_variablegeneration != expression_vg) { @@ -1668,22 +1547,21 @@ return NULL; } - if ((NULL == this->current_operand) || (NULL == this->current_operand_type)) ERROR; + if ((NULL == this->current_operand) || (NULL == this->current_operand->datatype)) ERROR; C_modifier(); this->current_operand->accept(*this); s4o.print(" = __"); - if (get_datatype_info_c::is_BOOL_compatible(this->current_operand_type)) + if (get_datatype_info_c::is_BOOL_compatible(this->current_operand->datatype)) { s4o.print("BOOL_LITERAL(TRUE)"); - else if (get_datatype_info_c::is_ANY_INT_compatible(this->current_operand_type)) { - this->current_operand_type->accept(*this); + } else if (get_datatype_info_c::is_ANY_INT_compatible(this->current_operand->datatype)) { + this->current_operand->datatype->accept(*this); s4o.print("_LITERAL(1)"); - } - else + } else ERROR; - /* the data type resulting from this operation is unchanged! */ - return NULL; -} + return NULL; +} + void *visit(R_operator_c *symbol) { if (wanted_variablegeneration != expression_vg) { @@ -1691,171 +1569,99 @@ return NULL; } - if ((NULL == this->current_operand) || (NULL == this->current_operand_type)) ERROR; + if ((NULL == this->current_operand) || (NULL == this->current_operand->datatype)) ERROR; C_modifier(); this->current_operand->accept(*this); s4o.print(" = __"); - if (get_datatype_info_c::is_BOOL_compatible(this->current_operand_type)) + if (get_datatype_info_c::is_BOOL_compatible(this->current_operand->datatype)) { s4o.print("BOOL_LITERAL(FALSE)"); - else if (get_datatype_info_c::is_ANY_INT_compatible(this->current_operand_type)) { - this->current_operand_type->accept(*this); + } else if (get_datatype_info_c::is_ANY_INT_compatible(this->current_operand->datatype)) { + this->current_operand->datatype->accept(*this); s4o.print("_LITERAL(0)"); - } - else + } else ERROR; /* the data type resulting from this operation is unchanged! */ return NULL; } -void *visit(S1_operator_c *symbol) {return XXX_CAL_operator("S1", this->current_operand);} -void *visit(R1_operator_c *symbol) {return XXX_CAL_operator("R1", this->current_operand);} + +void *visit( S1_operator_c *symbol) {return XXX_CAL_operator( "S1", this->current_operand);} +void *visit( R1_operator_c *symbol) {return XXX_CAL_operator( "R1", this->current_operand);} void *visit(CLK_operator_c *symbol) {return XXX_CAL_operator("CLK", this->current_operand);} -void *visit(CU_operator_c *symbol) {return XXX_CAL_operator("CU", this->current_operand);} -void *visit(CD_operator_c *symbol) {return XXX_CAL_operator("CD", this->current_operand);} -void *visit(PV_operator_c *symbol) {return XXX_CAL_operator("PV", this->current_operand);} -void *visit(IN_operator_c *symbol) {return XXX_CAL_operator("IN", this->current_operand);} -void *visit(PT_operator_c *symbol) {return XXX_CAL_operator("PT", this->current_operand);} +void *visit( CU_operator_c *symbol) {return XXX_CAL_operator( "CU", this->current_operand);} +void *visit( CD_operator_c *symbol) {return XXX_CAL_operator( "CD", this->current_operand);} +void *visit( PV_operator_c *symbol) {return XXX_CAL_operator( "PV", this->current_operand);} +void *visit( IN_operator_c *symbol) {return XXX_CAL_operator( "IN", this->current_operand);} +void *visit( PT_operator_c *symbol) {return XXX_CAL_operator( "PT", this->current_operand);} void *visit(AND_operator_c *symbol) { - if (get_datatype_info_c::is_ANY_BIT_compatible(this->default_variable_name.current_type)) { - BYTE_operator_result_type(); - XXX_operator(&(this->default_variable_name), " &= ", this->current_operand); - /* the data type resulting from this operation... */ - this->default_variable_name.current_type = this->current_operand_type; - } - else {ERROR;} + if (!get_datatype_info_c::is_ANY_BIT_compatible(symbol->datatype)) ERROR; + XXX_operator(&(this->implicit_variable_result), " &= ", this->current_operand); return NULL; } void *visit(OR_operator_c *symbol) { - if (get_datatype_info_c::is_ANY_BIT_compatible(this->default_variable_name.current_type)) { - BYTE_operator_result_type(); - XXX_operator(&(this->default_variable_name), " |= ", this->current_operand); - /* the data type resulting from this operation... */ - this->default_variable_name.current_type = this->current_operand_type; - } - else {ERROR;} + if (!get_datatype_info_c::is_ANY_BIT_compatible(symbol->datatype)) ERROR; + XXX_operator(&(this->implicit_variable_result), " |= ", this->current_operand); return NULL; } void *visit(XOR_operator_c *symbol) { - if (get_datatype_info_c::is_ANY_BIT_compatible(this->default_variable_name.current_type)) { - BYTE_operator_result_type(); - // '^' is a bit by bit exclusive OR !! Also seems to work with boolean types! - XXX_operator(&(this->default_variable_name), " ^= ", this->current_operand); - /* the data type resulting from this operation... */ - this->default_variable_name.current_type = this->current_operand_type; - } - else {ERROR;} + if (!get_datatype_info_c::is_ANY_BIT_compatible(symbol->datatype)) ERROR; + // '^' is a bit by bit exclusive OR !! Also seems to work with boolean types! + XXX_operator(&(this->implicit_variable_result), " ^= ", this->current_operand); return NULL; } void *visit(ANDN_operator_c *symbol) { - if (get_datatype_info_c::is_ANY_BIT_compatible(this->default_variable_name.current_type)) { - BYTE_operator_result_type(); - XXX_operator(&(this->default_variable_name), - get_datatype_info_c::is_BOOL_compatible(this->current_operand_type)?" &= !":" &= ~", - this->current_operand); - /* the data type resulting from this operation... */ - this->default_variable_name.current_type = this->current_operand_type; - } - else {ERROR;} + if (!get_datatype_info_c::is_ANY_BIT_compatible(symbol->datatype)) ERROR; + XXX_operator(&(this->implicit_variable_result), get_datatype_info_c::is_BOOL_compatible(this->current_operand->datatype)?" &= !":" &= ~", this->current_operand); return NULL; } void *visit(ORN_operator_c *symbol) { - if (get_datatype_info_c::is_ANY_BIT_compatible(this->default_variable_name.current_type)) { - BYTE_operator_result_type(); - XXX_operator(&(this->default_variable_name), - get_datatype_info_c::is_BOOL_compatible(this->current_operand_type)?" |= !":" |= ~", - this->current_operand); - /* the data type resulting from this operation... */ - this->default_variable_name.current_type = this->current_operand_type; - } - else {ERROR;} + if (!get_datatype_info_c::is_ANY_BIT_compatible(symbol->datatype)) ERROR; + XXX_operator(&(this->implicit_variable_result), get_datatype_info_c::is_BOOL_compatible(this->current_operand->datatype)?" |= !":" |= ~", this->current_operand); return NULL; } void *visit(XORN_operator_c *symbol) { - if (get_datatype_info_c::is_ANY_BIT_compatible(this->default_variable_name.current_type)) { - BYTE_operator_result_type(); - XXX_operator(&(this->default_variable_name), - // bit by bit exclusive OR !! Also seems to work with boolean types! - get_datatype_info_c::is_BOOL_compatible(this->current_operand_type)?" ^= !":" ^= ~", - this->current_operand); - /* the data type resulting from this operation... */ - this->default_variable_name.current_type = this->current_operand_type; - } - else {ERROR;} - return NULL; -} - + if (!get_datatype_info_c::is_ANY_BIT_compatible(symbol->datatype)) ERROR; + // bit by bit exclusive OR !! Also seems to work with boolean types! + XXX_operator(&(this->implicit_variable_result), get_datatype_info_c::is_BOOL_compatible(this->current_operand->datatype)?" ^= !":" ^= ~", this->current_operand); + return NULL; +} void *visit(ADD_operator_c *symbol) { - if (get_datatype_info_c::is_TIME_compatible (symbol->datatype) || - get_datatype_info_c::is_ANY_DATE_compatible (symbol->datatype)) { - XXX_function("__time_add", &(this->default_variable_name), this->current_operand); - /* the data type resulting from this operation... */ - this->default_variable_name.current_type = this->current_operand_type; - } else { - NUM_operator_result_type(); - XXX_operator(&(this->default_variable_name), " += ", this->current_operand); - /* the data type resulting from this operation... */ - this->default_variable_name.current_type = this->current_operand_type; - } + if (get_datatype_info_c::is_TIME_compatible(symbol->datatype) || get_datatype_info_c::is_ANY_DATE_compatible (symbol->datatype)) + XXX_function(&(this->implicit_variable_result), "__time_add", &(this->implicit_variable_current), this->current_operand); + else XXX_operator(&(this->implicit_variable_result), " += ", this->current_operand); return NULL; } void *visit(SUB_operator_c *symbol) { - if (get_datatype_info_c::is_TIME_compatible (symbol->datatype) || - get_datatype_info_c::is_ANY_DATE_compatible (symbol->datatype)) { - XXX_function("__time_sub", &(this->default_variable_name), this->current_operand); - /* the data type resulting from this operation... */ - this->default_variable_name.current_type = this->current_operand_type; - } else { - NUM_operator_result_type(); - XXX_operator(&(this->default_variable_name), " -= ", this->current_operand); - /* the data type resulting from this operation... */ - this->default_variable_name.current_type = this->current_operand_type; - } + if (get_datatype_info_c::is_TIME_compatible(symbol->datatype) || get_datatype_info_c::is_ANY_DATE_compatible (symbol->datatype)) + XXX_function(&(this->implicit_variable_result), "__time_sub", &(this->implicit_variable_current), this->current_operand); + else XXX_operator(&(this->implicit_variable_result), " -= ", this->current_operand); return NULL; } void *visit(MUL_operator_c *symbol) { - if (get_datatype_info_c::is_TIME_compatible (symbol->datatype)) { - XXX_function("__time_mul", &(this->default_variable_name), this->current_operand); - /* the data type resulting from this operation is unchanged! */ - } else { - NUM_operator_result_type(); - XXX_operator(&(this->default_variable_name), " *= ", this->current_operand); - /* the data type resulting from this operation... */ - this->default_variable_name.current_type = this->current_operand_type; - } + if (get_datatype_info_c::is_TIME_compatible(symbol->datatype)) + XXX_function(&(this->implicit_variable_result), "__time_mul", &(this->implicit_variable_current), this->current_operand); + else XXX_operator(&(this->implicit_variable_result), " *= ", this->current_operand); return NULL; } void *visit(DIV_operator_c *symbol) { - if (get_datatype_info_c::is_TIME_compatible (symbol->datatype)) { - XXX_function("__time_div", &(this->default_variable_name), this->current_operand); - /* the data type resulting from this operation is unchanged! */ - } else { - NUM_operator_result_type(); - XXX_operator(&(this->default_variable_name), " /= ", this->current_operand); - /* the data type resulting from this operation... */ - this->default_variable_name.current_type = this->current_operand_type; - return NULL; - } - return NULL; -} - -void *visit(MOD_operator_c *symbol) { - NUM_operator_result_type(); - XXX_operator(&(this->default_variable_name), " %= ", this->current_operand); - /* the data type resulting from this operation... */ - this->default_variable_name.current_type = this->current_operand_type; - return NULL; -} + if (get_datatype_info_c::is_TIME_compatible(symbol->datatype)) + XXX_function(&(this->implicit_variable_result), "__time_div", &(this->implicit_variable_current), this->current_operand); + else XXX_operator(&(this->implicit_variable_result), " /= ", this->current_operand); + return NULL; +} + +void *visit(MOD_operator_c *symbol) {XXX_operator(&(this->implicit_variable_result), " %= ", this->current_operand); return NULL;} void *visit(GT_operator_c *symbol) {CMP_operator(this->current_operand, "GT_"); return NULL;} void *visit(GE_operator_c *symbol) {CMP_operator(this->current_operand, "GE_"); return NULL;} @@ -1911,32 +1717,26 @@ //SYM_REF0(JMP_operator_c) void *visit(JMP_operator_c *symbol) { if (NULL == this->jump_label) ERROR; - s4o.print("goto "); this->jump_label->accept(*this); - /* the data type resulting from this operation is unchanged! */ return NULL; } // SYM_REF0(JMPC_operator_c) void *visit(JMPC_operator_c *symbol) { if (NULL == this->jump_label) ERROR; - C_modifier(); s4o.print("goto "); this->jump_label->accept(*this); - /* the data type resulting from this operation is unchanged! */ return NULL; } // SYM_REF0(JMPCN_operator_c) void *visit(JMPCN_operator_c *symbol) { if (NULL == this->jump_label) ERROR; - CN_modifier(); s4o.print("goto "); this->jump_label->accept(*this); - /* the data type resulting from this operation is unchanged! */ return NULL; } @@ -2002,5 +1802,5 @@ this->var_name = new identifier_c(var_name_str); if (NULL == this->var_name) ERROR; - this->current_type = current_type; -} + this->datatype = current_type; +} diff -r e837adad2437 -r 966f32af570d stage4/generate_c/generate_c_sfc.cc --- a/stage4/generate_c/generate_c_sfc.cc Thu Oct 18 10:57:13 2012 +0100 +++ b/stage4/generate_c/generate_c_sfc.cc Wed Oct 24 15:32:48 2012 +0100 @@ -344,7 +344,7 @@ case transitiontestdebug_sg: // Transition condition is in IL if (symbol->transition_condition_il != NULL) { - generate_c_il->declare_backup_variable(); + generate_c_il->declare_implicit_variable_back(); s4o.print(s4o.indent_spaces); symbol->transition_condition_il->accept(*generate_c_il); s4o.print(SET_VAR); @@ -358,8 +358,8 @@ s4o.print("transition_list["); print_transition_number(); s4o.print("],"); - generate_c_il->print_backup_variable(); - generate_c_il->reset_default_variable_name(); + generate_c_il->print_implicit_variable_back(); + // generate_c_il->reset_default_variable_name(); // generate_c_il does not require his anymore s4o.print(");\n"); } // Transition condition is in ST