--- a/stage1_2/iec.y Mon Jul 11 09:47:27 2011 +0100
+++ b/stage1_2/iec.y Fri Jul 29 16:03:28 2011 +0100
@@ -182,6 +182,14 @@
*/
extern bool allow_function_overloading;
+/* A flag to tell the compiler whether to allow the declaration
+ * of extensible function (i.e. functions that may have a variable number of
+ * input parameters, such as AND(word#33, word#44, word#55, word#66).
+ * This is an extension to the standard syntax.
+ * See comments below for details why we support this!
+ */
+extern bool allow_extensible_function_parameters;
+
/* A global flag used to tell the parser whether to include the full variable location
* when printing out error messages...
*/
@@ -3587,15 +3595,48 @@
;
+/* NOTE:
+ * The syntax
+ * variable_name DOTDOT
+ * is an extension to the standard!!!
+ *
+ * In order to be able to handle extensible standard functions
+ * (i.e. standard functions that may have a variable number of
+ * input parameters, such as AND(word#33, word#44, word#55, word#66),
+ * we have extended the acceptable syntax to allow var_name '..'
+ * in an input variable declaration.
+ *
+ * This allows us to parse the declaration of standard
+ * extensible functions and load their interface definition
+ * into the abstract syntax tree just like we do to other
+ * user defined functions.
+ * This has the advantage that we can later do semantic
+ * checking of calls to functions (be it a standard or user defined
+ * function) in (almost) exactly the same way.
+ *
+ * Of course, we have a flag that disables this syntax when parsing user
+ * written code, so we only allow this extra syntax while parsing the
+ * 'header' file that declares all the standard IEC 61131-3 functions.
+ */
var1_list:
variable_name
{$$ = new var1_list_c(locloc(@$)); $$->add_element($1);
variable_name_symtable.insert($1, prev_declared_variable_name_token);
}
+| variable_name integer DOTDOT
+ {$$ = new var1_list_c(locloc(@$)); $$->add_element(new extensible_input_parameter_c($1, $2, locloc(@$)));
+ variable_name_symtable.insert($1, prev_declared_variable_name_token);
+ if (!allow_extensible_function_parameters) print_err_msg(locf(@1), locl(@2), "invalid syntax in variable name declaration.");
+ }
| var1_list ',' variable_name
{$$ = $1; $$->add_element($3);
variable_name_symtable.insert($3, prev_declared_variable_name_token);
}
+ | var1_list ',' variable_name integer DOTDOT
+ {$$ = $1; $$->add_element(new extensible_input_parameter_c($3, $4, locloc(@$)));
+ variable_name_symtable.insert($3, prev_declared_variable_name_token);
+ if (!allow_extensible_function_parameters) print_err_msg(locf(@1), locl(@2), "invalid syntax in variable name declaration.");
+ }
/* ERROR_CHECK_BEGIN */
| var1_list variable_name
{$$ = $1; print_err_msg(locl(@1), locf(@2), "',' missing in variable list."); yynerrs++;}
@@ -4307,13 +4348,13 @@
{$$ = new single_byte_string_spec_c(NULL, NULL);}
*/
STRING '[' integer ']'
- {$$ = new single_byte_string_spec_c($3, NULL, locloc(@$));}
+ {$$ = new single_byte_string_spec_c(new single_byte_limited_len_string_spec_c(new string_type_name_c(locloc(@1)), $3, locloc(@$)), NULL, locloc(@$));}
/*
| STRING ASSIGN single_byte_character_string
- {$$ = new single_byte_string_spec_c(NULL, $3, locloc(@$));}
+ {$$ = new single_byte_string_spec_c($1, NULL, $3, locloc(@$));}
*/
| STRING '[' integer ']' ASSIGN single_byte_character_string
- {$$ = new single_byte_string_spec_c($3, $6, locloc(@$));}
+ {$$ = new single_byte_string_spec_c(new single_byte_limited_len_string_spec_c(new string_type_name_c(locloc(@1)), $3, locloc(@$)), $6, locloc(@$));}
/* ERROR_CHECK_BEGIN */
| STRING '[' error ']'
{$$ = NULL; print_err_msg(locf(@3), locl(@3), "invalid length value for limited string type specification."); yyerrok;}
@@ -4348,16 +4389,17 @@
double_byte_string_spec:
/* WSTRING
- {$$ = new double_byte_string_spec_c(NULL, NULL, locloc(@$));}
+ {$$ = new double_byte_string_spec_c($1, NULL, NULL, locloc(@$));}
*/
WSTRING '[' integer ']'
- {$$ = new double_byte_string_spec_c($3, NULL, locloc(@$));}
+ {$$ = new double_byte_string_spec_c(new double_byte_limited_len_string_spec_c(new wstring_type_name_c(locloc(@1)), $3, locloc(@$)), NULL, locloc(@$));}
+
/*
| WSTRING ASSIGN double_byte_character_string
- {$$ = new double_byte_string_spec_c(NULL, $3, locloc(@$));}
+ {$$ = new double_byte_string_spec_c($1, NULL, $3, locloc(@$));}
*/
| WSTRING '[' integer ']' ASSIGN double_byte_character_string
- {$$ = new double_byte_string_spec_c($3, $6, locloc(@$));}
+ {$$ = new double_byte_string_spec_c(new double_byte_limited_len_string_spec_c(new wstring_type_name_c(locloc(@1)), $3, locloc(@$)), $6, locloc(@$));}
/* ERROR_CHECK_BEGIN */
| WSTRING '[' error ']'
{$$ = NULL; print_err_msg(locf(@3), locl(@3), "invalid length value for limited double byte string type specification."); yyerrok;}
@@ -4458,27 +4500,18 @@
/* helper symbol for var_spec */
-/* NOTE: The constructs
- *
- * STRING
- * and
- * WSTRING
- *
- * were removed as they are already contained
- * within a simple_specification.
- */
string_spec:
/* STRING
- {$$ = new single_byte_string_spec_c(NULL, NULL, locloc(@$));}
+ {$$ = new single_byte_limited_len_string_spec_c($1, NULL, locloc(@$));}
*/
STRING '[' integer ']'
- {$$ = new single_byte_string_spec_c($3, NULL, locloc(@$));}
+ {$$ = new single_byte_limited_len_string_spec_c(new string_type_name_c(locloc(@1)), $3, locloc(@$));}
/*
| WSTRING
- {$$ = new double_byte_string_spec_c(NULL, NULL, locloc(@$));}
+ {$$ = new double_byte_limited_len_string_spec_c($1, NULL, locloc(@$));}
*/
| WSTRING '[' integer ']'
- {$$ = new double_byte_string_spec_c($3, NULL, locloc(@$));}
+ {$$ = new double_byte_limited_len_string_spec_c(new wstring_type_name_c(locloc(@1)), $3, locloc(@$));}
;
@@ -4665,11 +4698,31 @@
identifier
| prev_declared_derived_function_name
{$$ = $1;
- if (not(allow_function_overloading)) {
+ if (!allow_function_overloading) {
fprintf(stderr, "Function overloading not allowed. Invalid identifier %s\n", ((token_c *)($1))->value);
ERROR;
}
}
+| AND
+ {$$ = new identifier_c("AND", locloc(@$));
+ if (!allow_function_overloading) print_err_msg(locloc(@1), "Function overloading \"AND\" not allowed. Invalid identifier\n");
+ }
+| OR
+ {$$ = new identifier_c("OR", locloc(@$));
+ if (!allow_function_overloading) print_err_msg(locloc(@1), "Function overloading \"OR\" not allowed. Invalid identifier\n");
+ }
+| XOR
+ {$$ = new identifier_c("XOR", locloc(@$));
+ if (!allow_function_overloading) print_err_msg(locloc(@1), "Function overloading \"XOR\" not allowed. Invalid identifier\n");
+ }
+| NOT
+ {$$ = new identifier_c("NOT", locloc(@$));
+ if (!allow_function_overloading) print_err_msg(locloc(@1), "Function overloading \"NOT\" not allowed. Invalid identifier\n");
+ }
+| MOD
+ {$$ = new identifier_c("MOD", locloc(@$));
+ if (!allow_function_overloading) print_err_msg(locloc(@1), "Function overloading \"MOD\" not allowed. Invalid identifier\n");
+ }
;
@@ -7901,6 +7954,28 @@
*/
bool allow_function_overloading = false;
+/* | [var1_list ','] variable_name '..' */
+/* NOTE: This is an extension to the standard!!! */
+/* In order to be able to handle extensible standard functions
+ * (i.e. standard functions that may have a variable number of
+ * input parameters, such as AND(word#33, word#44, word#55, word#66),
+ * we have extended the acceptable syntax to allow var_name '..'
+ * in an input variable declaration.
+ *
+ * This allows us to parse the declaration of standard
+ * extensible functions and load their interface definition
+ * into the abstract syntax tree just like we do to other
+ * user defined functions.
+ * This has the advantage that we can later do semantic
+ * checking of calls to functions (be it a standard or user defined
+ * function) in (almost) exactly the same way.
+ *
+ * Of course, we have a flag that disables this syntax when parsing user
+ * written code, so we only allow this extra syntax while parsing the
+ * 'header' file that declares all the standard IEC 61131-3 functions.
+ */
+bool allow_extensible_function_parameters = false;
+
/* A global flag used to tell the parser whether to include the full variable location
* when printing out error messages...
*/
@@ -7991,6 +8066,22 @@
+/* If function overloading is on, we allow several functions with the same name.
+ *
+ * However, to support standard functions, we also allow functions named
+ * AND, MOD, NOT, OR, XOR, ADD, ...
+ */
+/*
+identifier_c *token_2_identifier_c(char *value, ) {
+ identifier_c tmp = new identifier_c(value, locloc(@$));
+ if (!allow_function_overloading) {
+ fprintf(stderr, "Function overloading not allowed. Invalid identifier %s\n", ((token_c *)($$))->value);
+ ERROR;
+ }
+ }
+}
+*/
+
/* convert between an il_operator to a function name */
/* This a kludge!
* It is required because our language requires more than one
@@ -8124,11 +8215,6 @@
FILE *in_file = NULL, *lib_file = NULL;
char *libfilename = NULL;
- for(int i = 0; standard_function_names[i] != NULL; i++)
- if (library_element_symtable.find_value(standard_function_names[i]) ==
- library_element_symtable.end_value())
- library_element_symtable.insert(standard_function_names[i], standard_function_name_token);
-
if((in_file = fopen(filename, "r")) == NULL) {
char *errmsg = strdup2("Error opening main file ", filename);
perror(errmsg);
@@ -8165,6 +8251,7 @@
*/
yyin = lib_file;
allow_function_overloading = true;
+ allow_extensible_function_parameters = true;
full_token_loc = full_token_loc_;
current_filename = libfilename;
current_tracking = GetNewTracking(yyin);
@@ -8193,6 +8280,7 @@
#endif
yyin = in_file;
allow_function_overloading = false;
+ allow_extensible_function_parameters = false;
full_token_loc = full_token_loc_;
current_filename = filename;
current_tracking = GetNewTracking(yyin);