# HG changeset patch # User mjsousa # Date 1411918544 -3600 # Node ID 76324f461aed5d0900c04c1a77de1bd9ad574d2c # Parent 061824c45a5b79fb1fb2d4c72c20be1809be92d5 Add support for de-referencing of REF_TO datatypes (Note: dereferencing of arrays and structs not yet supported!) diff -r 061824c45a5b -r 76324f461aed absyntax/absyntax.def --- a/absyntax/absyntax.def Sat Sep 27 20:09:19 2014 +0100 +++ b/absyntax/absyntax.def Sun Sep 28 16:35:44 2014 +0100 @@ -1139,16 +1139,17 @@ /***********************/ /* B 3.1 - Expressions */ /***********************/ -SYM_REF1(ref_expression_c, exp) /* an extension to the IEC 61131-3 standard - based on the IEC 61131-3 v3 standard. Returns address of the varible! */ -SYM_REF2(or_expression_c, l_exp, r_exp) +SYM_REF1( ref_expression_c, exp) /* an extension to the IEC 61131-3 standard - based on the IEC 61131-3 v3 standard. Returns address of the varible! */ +SYM_REF1(deref_expression_c, exp) /* an extension to the IEC 61131-3 standard - based on the IEC 61131-3 v3 standard. Dereferences an address! */ +SYM_REF2( or_expression_c, l_exp, r_exp) SYM_REF2(xor_expression_c, l_exp, r_exp) SYM_REF2(and_expression_c, l_exp, r_exp) SYM_REF2(equ_expression_c, l_exp, r_exp) SYM_REF2(notequ_expression_c, l_exp, r_exp) -SYM_REF2(lt_expression_c, l_exp, r_exp) -SYM_REF2(gt_expression_c, l_exp, r_exp) -SYM_REF2(le_expression_c, l_exp, r_exp) -SYM_REF2(ge_expression_c, l_exp, r_exp) +SYM_REF2( lt_expression_c, l_exp, r_exp) +SYM_REF2( gt_expression_c, l_exp, r_exp) +SYM_REF2( le_expression_c, l_exp, r_exp) +SYM_REF2( ge_expression_c, l_exp, r_exp) SYM_REF2(add_expression_c, l_exp, r_exp, bool deprecated_operation;) SYM_REF2(sub_expression_c, l_exp, r_exp, bool deprecated_operation;) SYM_REF2(mul_expression_c, l_exp, r_exp, bool deprecated_operation;) diff -r 061824c45a5b -r 76324f461aed lib/C/accessor.h --- a/lib/C/accessor.h Sat Sep 27 20:09:19 2014 +0100 +++ b/lib/C/accessor.h Sun Sep 28 16:35:44 2014 +0100 @@ -111,6 +111,15 @@ #define __GET_LOCATED_REF(name, ...)\ (&((*(name.value)) __VA_ARGS__)) +#define __GET_VAR_DREF(name, ...)\ + (*(name.value __VA_ARGS__)) +#define __GET_EXTERNAL_DREF(name, ...)\ + (*((*(name.value)) __VA_ARGS__)) +#define __GET_EXTERNAL_FB_DREF(name, ...)\ + (*(__GET_VAR(((*name) __VA_ARGS__)))) +#define __GET_LOCATED_DREF(name, ...)\ + (*((*(name.value)) __VA_ARGS__)) + // variable setting macros #define __SET_VAR(prefix, name, suffix, new_value)\ diff -r 061824c45a5b -r 76324f461aed main.cc --- a/main.cc Sat Sep 27 20:09:19 2014 +0100 +++ b/main.cc Sun Sep 28 16:35:44 2014 +0100 @@ -122,7 +122,7 @@ /******************************************************/ printf(" -s : allow use of safe datatypes (SAFEBOOL, etc.) (defined in PLCOpen Safety)\n"); printf(" -n : allow use of nested comments (an IEC 61131-3 v3 feature)\n"); - printf(" -r : allow use of references (REF_TO, REF, NULL) (an IEC 61131-3 v3 feature)\n"); + printf(" -r : allow use of references (REF_TO, REF, ^, NULL) (an IEC 61131-3 v3 feature)\n"); printf(" -R : allow use of REF_TO ANY datatypes (a non-standard extension!)\n"); printf(" as well as REF_TO in ARRAYs and STRUCTs (a non-standard extension!)\n"); printf(" -c : create conversion functions for enumerated data types\n"); diff -r 061824c45a5b -r 76324f461aed stage1_2/iec_bison.yy --- a/stage1_2/iec_bison.yy Sat Sep 27 20:09:19 2014 +0100 +++ b/stage1_2/iec_bison.yy Sun Sep 28 16:35:44 2014 +0100 @@ -416,6 +416,7 @@ /* Keywords in IEC 61131-3 v3 */ %token REF +%token DREF %token REF_TO %token NULL_token /* cannot use simply 'NULL', as it conflicts with the NULL keyword in C++ */ @@ -1319,7 +1320,8 @@ * are not required. Their values are integrated * directly into other rules... */ -%type ref_expression /* an extension to the IEC 61131-3 v2 standard, based on the IEC 61131-3 v3 standard */ +%type ref_expression /* an extension to the IEC 61131-3 v2 standard, based on the IEC 61131-3 v3 standard */ +%type deref_expression /* an extension to the IEC 61131-3 v2 standard, based on the IEC 61131-3 v3 standard */ %type expression %type xor_expression %type and_expression @@ -3399,7 +3401,27 @@ | identifier {$$ = new symbolic_variable_c($1, locloc(@$));} */ -; +| symbolic_variable '^' + /* Dereferencing operator defined in IEC 61131-3 v3. However, implemented here differently then how it is defined in the standard! See following note for explanation! */ + {$$ = new deref_expression_c($1, locloc(@$));} +; +/* + * NOTE: The syntax defined in the v3 standard for the dereferencing operator '^' seems to me to be un-intentionally + * limited. For example + * ref_to_bool_var := REF( array_of_bool [1] ); <--- Allowed! + * ref_to_bool_var := REF( ref_to_array_of_bool^[1] ); <--- Allowed! + * bool_var := array_of_ref_to_bool[1]^; <--- NOT Allowed! + * ref_to_array_of_bool^[1] := FALSE; <--- Allowed! + * I consider this a bug in the v3 standard!! + * I have therefore opted to implement this by simply adding a rule to symbolic_variable + * symbolic_variable: + * ... + * | symbolic_variable '^' + * This simple rule should be able to cover all the needed dereferencing syntax! + * I have also added a dereferencing expression for the DREF() operator. + * Since both of them do the exact same operation, they will both be translated to the exact same + * entry type in the abstract syntax tree (an deref_expression_c) + */ /* NOTE: in section B 1.7, when configuring a program, symbolic_variable @@ -7233,7 +7255,8 @@ /***********************/ expression: xor_expression -| ref_expression /* an extension to the IEC 61131-3 v2 standard, based on the IEC 61131-3 v3 standard */ +| ref_expression /* an extension to the IEC 61131-3 v2 standard, based on the IEC 61131-3 v3 standard */ +| deref_expression /* an extension to the IEC 61131-3 v2 standard, based on the IEC 61131-3 v3 standard */ | expression OR xor_expression {$$ = new or_expression_c($1, $3, locloc(@$));} /* ERROR_CHECK_BEGIN */ @@ -7254,6 +7277,14 @@ {$$ = new ref_expression_c($3, locloc(@$));} ; +/* DREF(var_name) */ +/* This is an extension to the IEC 61131-3 standard. It is actually defined in the IEC 61131-3 v3 standard */ +/* The DREF() operator accesses the variable stored in the specified address. Basically, it dereferences a pointer to the variable */ +deref_expression: + DREF '(' symbolic_variable ')' + {$$ = new deref_expression_c($3, locloc(@$));} +; + xor_expression: and_expression | xor_expression XOR and_expression diff -r 061824c45a5b -r 76324f461aed stage1_2/iec_flex.ll --- a/stage1_2/iec_flex.ll Sat Sep 27 20:09:19 2014 +0100 +++ b/stage1_2/iec_flex.ll Sun Sep 28 16:35:44 2014 +0100 @@ -1252,6 +1252,7 @@ REF {if (get_opt_ref_operator()) return REF; else{REJECT;}} /* Keyword in IEC 61131-3 v3 */ +DREF {if (get_opt_ref_operator()) return DREF; else{REJECT;}} /* Keyword in IEC 61131-3 v3 */ REF_TO {if (get_opt_ref_operator()) return REF_TO; else{REJECT;}} /* Keyword in IEC 61131-3 v3 */ NULL {if (get_opt_ref_operator()) return NULL_token; else{REJECT;}} /* Keyword in IEC 61131-3 v3 */ diff -r 061824c45a5b -r 76324f461aed stage3/fill_candidate_datatypes.cc --- a/stage3/fill_candidate_datatypes.cc Sat Sep 27 20:09:19 2014 +0100 +++ b/stage3/fill_candidate_datatypes.cc Sun Sep 28 16:35:44 2014 +0100 @@ -1889,9 +1889,26 @@ /***********************/ /* B 3.1 - Expressions */ /***********************/ +/* SYM_REF1(deref_expression_c, exp) --> an extension to the IEC 61131-3 standard - based on the IEC 61131-3 v3 standard. Returns address of the varible! */ +void *fill_candidate_datatypes_c::visit(deref_expression_c *symbol) { + symbol->exp->accept(*this); + + for (unsigned int i = 0; i < symbol->exp->candidate_datatypes.size(); i++) { + /* Determine whether the datatype is a ref_spec_c, as this is the class used as the */ + /* canonical/base datatype of REF_TO types (see search_base_type_c ...) */ + ref_spec_c *ref_spec = dynamic_cast(symbol->exp->candidate_datatypes[i]); + + if (NULL != ref_spec) + add_datatype_to_candidate_list(symbol, ref_spec->type_name); + } + + return NULL; +} + + /* SYM_REF1(ref_expression_c, exp) --> an extension to the IEC 61131-3 standard - based on the IEC 61131-3 v3 standard. Returns address of the varible! */ void *fill_candidate_datatypes_c::visit( ref_expression_c *symbol) { - /* We must first determine the datatype of the expression passe to the REF() operator, with no ambiguities! + /* We must first determine the datatype of the expression passed to the REF() operator, with no ambiguities! * To do this, we could use the complete standard fill/narrow algorithm for determining the datatype * of the expression. This is actually possible, as nothing stops us from directly calling the narrow_candidate_datatypes_c * from this method inside fill_candidate_datatypes_c, to complete the fill/narrow algorithm on this @@ -1910,9 +1927,8 @@ if (symbol->exp->candidate_datatypes.size() == 1) symbol->exp->datatype = symbol->exp->candidate_datatypes[0]; - /* Create a new object of ref_spec_c, as this is the class used as the canonical/base datatype of REF_TO types - * (see search_base_type_c ...) - */ + /* Create a new object of ref_spec_c, as this is the class used as the */ + /* canonical/base datatype of REF_TO types (see search_base_type_c ...) */ ref_spec_c *ref_spec = new ref_spec_c(symbol->exp->datatype); add_datatype_to_candidate_list(symbol, ref_spec); return NULL; diff -r 061824c45a5b -r 76324f461aed stage3/fill_candidate_datatypes.hh --- a/stage3/fill_candidate_datatypes.hh Sat Sep 27 20:09:19 2014 +0100 +++ b/stage3/fill_candidate_datatypes.hh Sun Sep 28 16:35:44 2014 +0100 @@ -337,24 +337,25 @@ /***********************/ /* B 3.1 - Expressions */ /***********************/ - void *visit(ref_expression_c *symbol); - void *visit(or_expression_c *symbol); - void *visit(xor_expression_c *symbol); - void *visit(and_expression_c *symbol); - void *visit(equ_expression_c *symbol); - void *visit(notequ_expression_c *symbol); - void *visit(lt_expression_c *symbol); - void *visit(gt_expression_c *symbol); - void *visit(le_expression_c *symbol); - void *visit(ge_expression_c *symbol); - void *visit(add_expression_c *symbol); - void *visit(sub_expression_c *symbol); - void *visit(mul_expression_c *symbol); - void *visit(div_expression_c *symbol); - void *visit(mod_expression_c *symbol); - void *visit(power_expression_c *symbol); - void *visit(neg_expression_c *symbol); - void *visit(not_expression_c *symbol); + void *visit( deref_expression_c *symbol); + void *visit( ref_expression_c *symbol); + void *visit( or_expression_c *symbol); + void *visit( xor_expression_c *symbol); + void *visit( and_expression_c *symbol); + void *visit( equ_expression_c *symbol); + void *visit( notequ_expression_c *symbol); + void *visit( lt_expression_c *symbol); + void *visit( gt_expression_c *symbol); + void *visit( le_expression_c *symbol); + void *visit( ge_expression_c *symbol); + void *visit( add_expression_c *symbol); + void *visit( sub_expression_c *symbol); + void *visit( mul_expression_c *symbol); + void *visit( div_expression_c *symbol); + void *visit( mod_expression_c *symbol); + void *visit( power_expression_c *symbol); + void *visit( neg_expression_c *symbol); + void *visit( not_expression_c *symbol); void *visit(function_invocation_c *symbol); /*********************************/ diff -r 061824c45a5b -r 76324f461aed stage3/narrow_candidate_datatypes.cc --- a/stage3/narrow_candidate_datatypes.cc Sat Sep 27 20:09:19 2014 +0100 +++ b/stage3/narrow_candidate_datatypes.cc Sun Sep 28 16:35:44 2014 +0100 @@ -1378,6 +1378,23 @@ /***********************/ /* B 3.1 - Expressions */ /***********************/ +/* SYM_REF1(deref_expression_c, exp) --> an extension to the IEC 61131-3 standard - based on the IEC 61131-3 v3 standard. Returns address of the varible! */ +void *narrow_candidate_datatypes_c::visit(deref_expression_c *symbol) { + for (unsigned int i = 0; i < symbol->exp->candidate_datatypes.size(); i++) { + /* Determine whether the datatype is a ref_spec_c, as this is the class used as the */ + /* canonical/base datatype of REF_TO types (see search_base_type_c ...) */ + ref_spec_c *ref_spec = dynamic_cast(symbol->exp->candidate_datatypes[i]); + + if ((NULL != ref_spec) && get_datatype_info_c::is_type_equal(ref_spec->type_name, symbol->datatype)) + /* if it points to the required datatype for symbol, then that is the required datatype for symbol->exp */ + symbol->exp->datatype = ref_spec; + } + + symbol->exp->accept(*this); + return NULL; +} + + /* SYM_REF1(ref_expression_c, exp) --> an extension to the IEC 61131-3 standard - based on the IEC 61131-3 v3 standard. Returns address of the varible! */ void *narrow_candidate_datatypes_c::visit( ref_expression_c *symbol) { if (symbol->exp->candidate_datatypes.size() > 0) { diff -r 061824c45a5b -r 76324f461aed stage3/narrow_candidate_datatypes.hh --- a/stage3/narrow_candidate_datatypes.hh Sat Sep 27 20:09:19 2014 +0100 +++ b/stage3/narrow_candidate_datatypes.hh Sun Sep 28 16:35:44 2014 +0100 @@ -308,25 +308,25 @@ /***********************/ /* B 3.1 - Expressions */ /***********************/ - void *visit(ref_expression_c *symbol); - void *visit(or_expression_c *symbol); - void *visit(xor_expression_c *symbol); - void *visit(and_expression_c *symbol); - void *visit(equ_expression_c *symbol); - void *visit(notequ_expression_c *symbol); - void *visit(lt_expression_c *symbol); - void *visit(gt_expression_c *symbol); - void *visit(le_expression_c *symbol); - void *visit(ge_expression_c *symbol); - void *visit(add_expression_c *symbol); - void *visit(sub_expression_c *symbol); - void *visit(mul_expression_c *symbol); - void *visit(div_expression_c *symbol); - void *visit(mod_expression_c *symbol); - void *visit(power_expression_c *symbol); - void *visit(neg_expression_c *symbol); - void *visit(not_expression_c *symbol); - + void *visit( deref_expression_c *symbol); + void *visit( ref_expression_c *symbol); + void *visit( or_expression_c *symbol); + void *visit( xor_expression_c *symbol); + void *visit( and_expression_c *symbol); + void *visit( equ_expression_c *symbol); + void *visit( notequ_expression_c *symbol); + void *visit( lt_expression_c *symbol); + void *visit( gt_expression_c *symbol); + void *visit( le_expression_c *symbol); + void *visit( ge_expression_c *symbol); + void *visit( add_expression_c *symbol); + void *visit( sub_expression_c *symbol); + void *visit( mul_expression_c *symbol); + void *visit( div_expression_c *symbol); + void *visit( mod_expression_c *symbol); + void *visit( power_expression_c *symbol); + void *visit( neg_expression_c *symbol); + void *visit( not_expression_c *symbol); void *visit(function_invocation_c *symbol); /*********************************/ diff -r 061824c45a5b -r 76324f461aed stage3/print_datatypes_error.cc --- a/stage3/print_datatypes_error.cc Sat Sep 27 20:09:19 2014 +0100 +++ b/stage3/print_datatypes_error.cc Sun Sep 28 16:35:44 2014 +0100 @@ -1044,6 +1044,15 @@ /***********************/ /* B 3.1 - Expressions */ /***********************/ +/* SYM_REF1(deref_expression_c, exp) --> an extension to the IEC 61131-3 standard - based on the IEC 61131-3 v3 standard. Returns address of the varible! */ +void *print_datatypes_error_c::visit(deref_expression_c *symbol) { + symbol->exp->accept(*this); + /* we should really check whether the expression is merely a variable. For now, leave it for the future! */ + if ((symbol->candidate_datatypes.size() == 0) && (symbol->exp->candidate_datatypes.size() > 0)) + STAGE3_ERROR(0, symbol, symbol, "DREF operator must be used with a value of type REF_TO."); + return NULL; +} + /* SYM_REF1(ref_expression_c, exp) --> an extension to the IEC 61131-3 standard - based on the IEC 61131-3 v3 standard. Returns address of the varible! */ void *print_datatypes_error_c::visit( ref_expression_c *symbol) { symbol->exp->accept(*this); diff -r 061824c45a5b -r 76324f461aed stage3/print_datatypes_error.hh --- a/stage3/print_datatypes_error.hh Sat Sep 27 20:09:19 2014 +0100 +++ b/stage3/print_datatypes_error.hh Sun Sep 28 16:35:44 2014 +0100 @@ -288,24 +288,25 @@ /***********************/ /* B 3.1 - Expressions */ /***********************/ - void *visit(ref_expression_c *symbol); - void *visit(or_expression_c *symbol); - void *visit(xor_expression_c *symbol); - void *visit(and_expression_c *symbol); - void *visit(equ_expression_c *symbol); - void *visit(notequ_expression_c *symbol); - void *visit(lt_expression_c *symbol); - void *visit(gt_expression_c *symbol); - void *visit(le_expression_c *symbol); - void *visit(ge_expression_c *symbol); - void *visit(add_expression_c *symbol); - void *visit(sub_expression_c *symbol); - void *visit(mul_expression_c *symbol); - void *visit(div_expression_c *symbol); - void *visit(mod_expression_c *symbol); - void *visit(power_expression_c *symbol); - void *visit(neg_expression_c *symbol); - void *visit(not_expression_c *symbol); + void *visit( deref_expression_c *symbol); + void *visit( ref_expression_c *symbol); + void *visit( or_expression_c *symbol); + void *visit( xor_expression_c *symbol); + void *visit( and_expression_c *symbol); + void *visit( equ_expression_c *symbol); + void *visit( notequ_expression_c *symbol); + void *visit( lt_expression_c *symbol); + void *visit( gt_expression_c *symbol); + void *visit( le_expression_c *symbol); + void *visit( ge_expression_c *symbol); + void *visit( add_expression_c *symbol); + void *visit( sub_expression_c *symbol); + void *visit( mul_expression_c *symbol); + void *visit( div_expression_c *symbol); + void *visit( mod_expression_c *symbol); + void *visit( power_expression_c *symbol); + void *visit( neg_expression_c *symbol); + void *visit( not_expression_c *symbol); void *visit(function_invocation_c *symbol); /*********************************/ diff -r 061824c45a5b -r 76324f461aed stage4/generate_c/generate_c.cc --- a/stage4/generate_c/generate_c.cc Sat Sep 27 20:09:19 2014 +0100 +++ b/stage4/generate_c/generate_c.cc Sun Sep 28 16:35:44 2014 +0100 @@ -138,6 +138,11 @@ #define GET_EXTERNAL_FB_REF "__GET_EXTERNAL_FB_REF" #define GET_LOCATED_REF "__GET_LOCATED_REF" +#define GET_VAR_DREF "__GET_VAR_DREF" +#define GET_EXTERNAL_DREF "__GET_EXTERNAL_DREF" +#define GET_EXTERNAL_FB_DREF "__GET_EXTERNAL_FB_DREF" +#define GET_LOCATED_DREF "__GET_LOCATED_DREF" + #define GET_VAR_BY_REF "__GET_VAR_BY_REF" #define GET_EXTERNAL_BY_REF "__GET_EXTERNAL_BY_REF" #define GET_EXTERNAL_FB_BY_REF "__GET_EXTERNAL_FB_BY_REF" diff -r 061824c45a5b -r 76324f461aed stage4/generate_c/generate_c_st.cc --- a/stage4/generate_c/generate_c_st.cc Sat Sep 27 20:09:19 2014 +0100 +++ b/stage4/generate_c/generate_c_st.cc Sun Sep 28 16:35:44 2014 +0100 @@ -463,6 +463,48 @@ /***********************/ /* B 3.1 - Expressions */ /***********************/ +void *visit(deref_expression_c *symbol) { + s4o.print("("); + if (this->is_variable_prefix_null()) { + /* For code in FUNCTIONs */ + s4o.print("*"); + symbol->exp->accept(*this); + s4o.print(""); + } else { + /* For code in FBs, and PROGRAMS... */ + s4o.print("("); + unsigned int vartype = analyse_variable_c::first_nonfb_vardecltype(symbol->exp, scope_); + if (vartype == search_var_instance_decl_c::external_vt) { + if (!get_datatype_info_c::is_type_valid (symbol->exp->datatype)) ERROR; + if ( get_datatype_info_c::is_function_block(symbol->exp->datatype)) + s4o.print(GET_EXTERNAL_FB_DREF); + else + s4o.print(GET_EXTERNAL_DREF); + } + else if (vartype == search_var_instance_decl_c::located_vt) + s4o.print(GET_LOCATED_DREF); + else + s4o.print(GET_VAR_DREF); + + variablegeneration_t old_wanted_variablegeneration = wanted_variablegeneration; + s4o.print("("); + wanted_variablegeneration = complextype_base_vg; + print_variable_prefix(); + symbol->exp->accept(*this); + s4o.print(","); + wanted_variablegeneration = complextype_suffix_vg; + symbol->exp->accept(*this); + s4o.print(")"); + wanted_variablegeneration = old_wanted_variablegeneration; + + s4o.print(")"); + } + s4o.print(")"); + + return NULL; +} + + void *visit(ref_expression_c *symbol) { s4o.print("("); if (this->is_variable_prefix_null()) { diff -r 061824c45a5b -r 76324f461aed stage4/generate_iec/generate_iec.cc --- a/stage4/generate_iec/generate_iec.cc Sat Sep 27 20:09:19 2014 +0100 +++ b/stage4/generate_iec/generate_iec.cc Sun Sep 28 16:35:44 2014 +0100 @@ -1917,24 +1917,25 @@ /***********************/ /* B 3.1 - Expressions */ /***********************/ -void *visit(ref_expression_c *symbol) {return s4o.print("REF("); symbol->exp->accept(*this); s4o.print(")");} /* an extension to the IEC 61131-3 standard - based on the IEC 61131-3 v3 standard. Returns address of the varible! */ -void *visit(or_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " OR ");} -void *visit(xor_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " XOR ");} -void *visit(and_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " AND ");} -void *visit(equ_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " = ");} +void *visit( ref_expression_c *symbol) {return s4o.print( "REF("); symbol->exp->accept(*this); s4o.print(")");} /* an extension to the IEC 61131-3 standard - based on the IEC 61131-3 v3 standard. Returns address of the varible! */ +void *visit( deref_expression_c *symbol) {return s4o.print("DREF("); symbol->exp->accept(*this); s4o.print(")");} /* an extension to the IEC 61131-3 standard - based on the IEC 61131-3 v3 standard. Returns address of the varible! */ +void *visit( or_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " OR ");} +void *visit( xor_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " XOR ");} +void *visit( and_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " AND ");} +void *visit( equ_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " = ");} void *visit(notequ_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " <> ");} -void *visit(lt_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " < ");} -void *visit(gt_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " > ");} -void *visit(le_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " <= ");} -void *visit(ge_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " >= ");} -void *visit(add_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " + ");} -void *visit(sub_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " - ");} -void *visit(mul_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " * ");} -void *visit(div_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " / ");} -void *visit(mod_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " MOD ");} -void *visit(power_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " ** ");} -void *visit(neg_expression_c *symbol) {return print_unary_expression(symbol, symbol->exp, "-");} -void *visit(not_expression_c *symbol) {return print_unary_expression(symbol, symbol->exp, "NOT ");} +void *visit( lt_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " < ");} +void *visit( gt_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " > ");} +void *visit( le_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " <= ");} +void *visit( ge_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " >= ");} +void *visit( add_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " + ");} +void *visit( sub_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " - ");} +void *visit( mul_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " * ");} +void *visit( div_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " / ");} +void *visit( mod_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " MOD ");} +void *visit( power_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " ** ");} +void *visit( neg_expression_c *symbol) {return print_unary_expression (symbol, symbol->exp, "-");} +void *visit( not_expression_c *symbol) {return print_unary_expression (symbol, symbol->exp, "NOT ");} void *visit(function_invocation_c *symbol) { symbol->function_name->accept(*this);