stage4/generate_iec/generate_iec.cc
changeset 350 2c3c4dc34979
parent 311 8fcea60029de
child 453 4733f662362a
--- a/stage4/generate_iec/generate_iec.cc	Mon Jul 11 09:47:27 2011 +0100
+++ b/stage4/generate_iec/generate_iec.cc	Fri Jul 29 16:03:28 2011 +0100
@@ -704,6 +704,32 @@
 
 void *visit(var1_list_c *symbol) {return print_list(symbol, "", ", ");}
 
+/* | [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.
+ */
+void *visit(extensible_input_parameter_c *symbol) {
+  symbol->var_name->accept(*this);
+  s4o.print(" .. ");
+  return NULL;
+}
+
 
 /* var1_list ':' array_spec_init */
 void *visit(array_var_init_decl_c *symbol) {
@@ -930,14 +956,10 @@
   return NULL;
 }
 
-/*  STRING ['[' integer ']'] [ASSIGN single_byte_character_string] */
-/* integer ->may be NULL ! */
+/*  single_byte_limited_len_string_spec [ASSIGN single_byte_character_string] */
 /* single_byte_character_string ->may be NULL ! */
 void *visit(single_byte_string_spec_c *symbol) {
-  s4o.print("STRING [");
-  if (symbol->integer != NULL)
-    symbol->integer->accept(*this);
-  s4o.print("]");
+  symbol->string_spec->accept(*this);
   if (symbol->single_byte_character_string != NULL) {
     s4o.print(" := ");
     symbol->single_byte_character_string->accept(*this);
@@ -945,6 +967,18 @@
   return NULL;
 }
 
+/*  STRING ['[' integer ']'] */
+/* integer ->may be NULL ! */
+void *visit(single_byte_limited_len_string_spec_c *symbol) {
+  symbol->string_type_name->accept(*this);
+  if (symbol->character_string_len != NULL) {
+    s4o.print(" [");
+    symbol->character_string_len->accept(*this);
+    s4o.print("]");
+  }
+  return NULL;
+}
+
 /*  var1_list ':' double_byte_string_spec */
 void *visit(double_byte_string_var_declaration_c *symbol) {
   symbol->var1_list->accept(*this);
@@ -953,14 +987,11 @@
   return NULL;
 }
 
-/*  WSTRING ['[' integer ']'] [ASSIGN double_byte_character_string] */
+/*  double_byte_limited_len_string_spec [ASSIGN double_byte_character_string] */
 /* integer ->may be NULL ! */
 /* double_byte_character_string ->may be NULL ! */
 void *visit(double_byte_string_spec_c *symbol) {
-  s4o.print("WSTRING [");
-  if (symbol->integer != NULL)
-    symbol->integer->accept(*this);
-  s4o.print("]");
+  symbol->string_spec->accept(*this);
   if (symbol->double_byte_character_string != NULL) {
     s4o.print(" := ");
     symbol->double_byte_character_string->accept(*this);
@@ -968,6 +999,18 @@
   return NULL;
 }
 
+/* WSTRING ['[' integer ']'] */
+/* integer ->may be NULL ! */
+void *visit(double_byte_limited_len_string_spec_c *symbol) {
+  symbol->string_type_name->accept(*this);
+  if (symbol->character_string_len != NULL) {
+    s4o.print(" [");
+    symbol->character_string_len->accept(*this);
+    s4o.print("]");
+  }
+  return NULL;
+}
+
 /*| VAR [RETAIN|NON_RETAIN] incompl_located_var_decl_list END_VAR */
 /* option ->may be NULL ! */
 void *visit(incompl_located_var_declarations_c *symbol) {