Add support for implicitly declared REF_TO datatypes.
authormjsousa
Mon, 21 Jul 2014 10:39:46 +0100
changeset 916 e14cb81bc310
parent 915 ec3759689efe
child 917 5344b1fc826b
Add support for implicitly declared REF_TO datatypes.
stage4/generate_c/generate_c.cc
stage4/generate_c/generate_c_typedecl.cc
--- a/stage4/generate_c/generate_c.cc	Sun Jul 20 21:57:10 2014 +0100
+++ b/stage4/generate_c/generate_c.cc	Mon Jul 21 10:39:46 2014 +0100
@@ -781,6 +781,9 @@
 
 /* This class will generate a new datatype for each implicitly declared array datatype
  * (i.e. arrays declared in a variable declaration, or a struct datatype declaration...)
+ * It will do the same for implicitly declared RFE_TO datatypes.
+ * 
+ * The class will be called once for each POU declaration, and once for each derived datatype declaration.
  * 
  * e.g.:
  *      VAR  a: ARRAY [1..3] OF INT; END_VAR   <---- ARRAY datatype is implicitly declared inside the variable declaration
@@ -814,6 +817,36 @@
     /*  identifier ':' array_spec_init */
     void *visit(array_type_declaration_c *symbol) {return NULL;} // This is not an implicitly defined array!
 
+    /* ref_spec:  REF_TO (non_generic_type_name | function_block_type_name) */
+    void *visit(ref_spec_c *symbol) {
+      identifier_c *id = generate_unique_id(prefix, symbol);
+      /* Warning: The following is dangerous... 
+       * We are asking the generate_c_typedecl_c visitor to visit a newly created ref_spec_init_c object
+       * that has not been through stage 3, and therefore does not have stage 3 annotations filled in.
+       * This will only work if generate_c_typedecl_c does ot depend on the stage 3 annotations!
+       */
+      ref_spec_init_c   ref_spec(symbol, NULL);
+      ref_type_decl_c   ref_decl(id, &ref_spec);
+      ref_decl.accept(generate_c_typedecl); // Must be done _before_ adding the annotation, due to the way generate_c_typedecl_c works
+      symbol->anotations_map["generate_c_annotaton__implicit_type_id"] = id;
+      return NULL;
+    }
+
+    /* For the moment, we do not support initialising reference data types */
+    /* ref_spec_init: ref_spec [ ASSIGN ref_initialization ] */ 
+    /* NOTE: ref_initialization may be NULL!! */
+    // SYM_REF2(ref_spec_init_c, ref_spec, ref_initialization)
+    void *visit(ref_spec_init_c *symbol) {
+      symbol->ref_spec->accept(*this);
+      int implicit_id_count = symbol->ref_spec->anotations_map.count("generate_c_annotaton__implicit_type_id");
+      if (implicit_id_count  > 1) ERROR;
+      if (implicit_id_count == 1)
+        symbol->anotations_map["generate_c_annotaton__implicit_type_id"] = symbol->ref_spec->anotations_map["generate_c_annotaton__implicit_type_id"];
+      return NULL;
+    }
+
+    /* ref_type_decl: identifier ':' ref_spec_init */
+    void *visit(ref_type_decl_c *symbol) {return NULL;} // This is not an implicitly defined REF_TO!
 
     /******************************************/
     /* B 1.4.3 - Declaration & Initialization */
@@ -822,8 +855,6 @@
     void *visit(en_param_declaration_c       *symbol) {return NULL;}
     void *visit(eno_param_declaration_c      *symbol) {return NULL;}
 
-    void *visit(var1_init_decl_c             *symbol) {return NULL;}
-
     /* array_specification [ASSIGN array_initialization] */
     /* array_initialization may be NULL ! */
     void *visit(array_spec_init_c *symbol) {
@@ -862,6 +893,7 @@
     //SYM_REF2(structured_var_declaration_c, var1_list, structure_type_name)
     void *visit(structured_var_declaration_c *symbol) {return NULL;}
 
+
     /***********************/
     /* B 1.5.1 - Functions */
     /***********************/      
--- a/stage4/generate_c/generate_c_typedecl.cc	Sun Jul 20 21:57:10 2014 +0100
+++ b/stage4/generate_c/generate_c_typedecl.cc	Mon Jul 21 10:39:46 2014 +0100
@@ -629,6 +629,15 @@
 /* ref_spec:  REF_TO (non_generic_type_name | function_block_type_name) */
 // SYM_REF1(ref_spec_c, type_name)
 void *visit(ref_spec_c *symbol) {
+  int implicit_id_count = symbol->anotations_map.count("generate_c_annotaton__implicit_type_id");
+  if (implicit_id_count  > 1) ERROR;
+  if (implicit_id_count == 1) {
+      /* this is part of an implicitly declared datatype (i.e. inside a variable decaration), for which an equivalent C datatype
+       * has already been defined. So, we simly print out the id of that C datatpe...
+       */
+    symbol->anotations_map["generate_c_annotaton__implicit_type_id"]->accept(*basedecl);
+    return NULL;
+  }
   return symbol->type_name->accept(*this);
 }
 
@@ -637,6 +646,15 @@
 /* NOTE: ref_initialization may be NULL!! */
 // SYM_REF2(ref_spec_init_c, ref_spec, ref_initialization)
 void *visit(ref_spec_init_c *symbol) {
+  int implicit_id_count = symbol->anotations_map.count("generate_c_annotaton__implicit_type_id");
+  if (implicit_id_count  > 1) ERROR;
+  if (implicit_id_count == 1) {
+      /* this is part of an implicitly declared datatype (i.e. inside a variable decaration), for which an equivalent C datatype
+       * has already been defined. So, we simly print out the id of that C datatpe...
+       */
+    symbol->anotations_map["generate_c_annotaton__implicit_type_id"]->accept(*basedecl);
+    return NULL;
+  }
   return symbol->ref_spec->accept(*this);
 }