stage1_2/iec.y
changeset 350 2c3c4dc34979
parent 328 66cd5d9893dd
--- 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);