]> git.unchartedbackwaters.co.uk Git - francis/libjit.git/commitdiff
Put some infrastructure (incomplete) in place to support
authorRhys Weatherley <rweather@southern-storm.com.au>
Thu, 13 May 2004 02:45:48 +0000 (02:45 +0000)
committerRhys Weatherley <rweather@southern-storm.com.au>
Thu, 13 May 2004 02:45:48 +0000 (02:45 +0000)
array index expressions.

ChangeLog
dpas/dpas-parser.y
dpas/dpas-types.c
dpas/dpas-types.h

index 94e2b4e77bb659687d24e17dc394f12a3ea0bc88..6277aa70cf6b9a933ceb51e843a403ead351c0cf 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,10 @@
 
+2004-05-13  Rhys Weatherley  <rweather@southern-storm.com.au>
+
+       * dpas/dpas-parser.y, dpas/dpas-types.c, dpas/dpas-types.h:
+       put some infrastructure (incomplete) in place to support array
+       index expressions.
+
 2004-05-12  Rhys Weatherley  <rweather@southern-storm.com.au>
 
        * jitdynamic/Makefile.am, jitplus/Makefile.am: use both .libs and
index 959d9bea2384bfcc46d4ee6a0d4bb0ed534ecfcd..6e9fba7b94e1cfd313dc2f757c6d308ea16854ee 100644 (file)
@@ -2710,9 +2710,95 @@ Variable
                                jit_free($1);
                        }
        | Variable '[' ExpressionList ']'       {
-                               /* TODO */
-                               dpas_error("array expression not yet implemented");
-                               dpas_sem_set_error($$);
+                               jit_value_t array = 0;
+                               jit_type_t array_type = 0;
+                               jit_type_t elem_type = 0;
+                               jit_value_t *low_bounds = 0;
+                               int rank = $3.len;
+                               if(dpas_sem_is_lvalue($1) || dpas_sem_is_lvalue_ea($1))
+                               {
+                                       elem_type = dpas_sem_get_type($1);
+                                       if(dpas_sem_is_lvalue_ea($1))
+                                       {
+                                               if(dpas_type_is_array(elem_type))
+                                               {
+                                                       array_type = elem_type;
+                                                       array = dpas_sem_get_value($1);
+                                                       rank = dpas_type_get_rank(elem_type);
+                                                       elem_type = dpas_type_get_elem(elem_type);
+                                               }
+                                               else if(dpas_type_is_conformant_array(elem_type))
+                                               {
+                                                       array_type = elem_type;
+                                                       array = dpas_sem_get_value
+                                                               (dpas_lvalue_to_rvalue($1));
+                                                       rank = dpas_type_get_rank(elem_type);
+                                                       elem_type = dpas_type_get_elem(elem_type);
+                                               }
+                                               else if(jit_type_is_pointer(elem_type))
+                                               {
+                                                       array = dpas_sem_get_value
+                                                               (dpas_lvalue_to_rvalue($1));
+                                                       rank = 1;
+                                                       elem_type = jit_type_get_ref(elem_type);
+                                               }
+                                               else
+                                               {
+                                                       dpas_error("value is not an array");
+                                               }
+                                       }
+                                       else
+                                       {
+                                               if(dpas_type_is_array(elem_type))
+                                               {
+                                                       array_type = elem_type;
+                                                       array = jit_insn_address_of
+                                                               (dpas_current_function(),
+                                                                dpas_sem_get_value($1));
+                                                       if(!array)
+                                                       {
+                                                               dpas_out_of_memory();
+                                                       }
+                                                       rank = dpas_type_get_rank(elem_type);
+                                                       elem_type = dpas_type_get_elem(elem_type);
+                                               }
+                                               else if(dpas_type_is_conformant_array(elem_type))
+                                               {
+                                                       array_type = elem_type;
+                                                       array = dpas_sem_get_value($1);
+                                                       rank = dpas_type_get_rank(elem_type);
+                                                       elem_type = dpas_type_get_elem(elem_type);
+                                               }
+                                               else if(jit_type_is_pointer(elem_type))
+                                               {
+                                                       array = dpas_sem_get_value($1);
+                                                       rank = 1;
+                                                       elem_type = jit_type_get_ref(elem_type);
+                                               }
+                                               else
+                                               {
+                                                       dpas_error("value is not an array");
+                                               }
+                                       }
+                               }
+                               if(rank != $3.len)
+                               {
+                                       dpas_error("incorrect number of indices for array");
+                                       dpas_sem_set_error($$);
+                               }
+                               else if(array)
+                               {
+                                       /* TODO */
+                                       dpas_error("array expressions are not fully implemented");
+                                       dpas_sem_set_error($$);
+                               }
+                               else
+                               {
+                                       dpas_error("invalid l-value supplied to array expression");
+                                       dpas_sem_set_error($$);
+                               }
+                               jit_free(low_bounds);
+                               expression_list_free($3.exprs, $3.len);
                        }
        | Variable '.' Identifier                       {
                                /* Fetch the effective address of a record field */
index d93348071665677865a72e65d54514e593ac03a9..910c32ae9c3a94d51cfda4f4acdc3c895d1ecd90 100644 (file)
@@ -870,6 +870,39 @@ jit_type_t dpas_create_conformant_array(jit_type_t elem_type, int num_bounds,
        return type;
 }
 
+jit_type_t dpas_type_get_elem(jit_type_t type)
+{
+       if(jit_type_get_tagged_kind(type) == DPAS_TAG_ARRAY)
+       {
+               return jit_type_get_field(jit_type_normalize(type), 0);
+       }
+       else if(jit_type_get_tagged_kind(type) == DPAS_TAG_CONFORMANT_ARRAY)
+       {
+               return jit_type_get_ref(jit_type_normalize(type));
+       }
+       else
+       {
+               return 0;
+       }
+}
+
+int dpas_type_get_rank(jit_type_t type)
+{
+       if(jit_type_get_tagged_kind(type) == DPAS_TAG_ARRAY)
+       {
+               return ((dpas_array *)jit_type_get_tagged_data(type))->num_bounds;
+       }
+       else if(jit_type_get_tagged_kind(type) == DPAS_TAG_CONFORMANT_ARRAY)
+       {
+               return ((dpas_conformant_array *)
+                                       jit_type_get_tagged_data(type))->num_bounds;
+       }
+       else
+       {
+               return 1;
+       }
+}
+
 void dpas_type_set_name(jit_type_t type, const char *name)
 {
        char *copy;
@@ -1183,6 +1216,16 @@ int dpas_type_is_record(jit_type_t type)
        return (jit_type_is_struct(type) || jit_type_is_union(type));
 }
 
+int dpas_type_is_array(jit_type_t type)
+{
+       return (jit_type_get_tagged_kind(type) == DPAS_TAG_ARRAY);
+}
+
+int dpas_type_is_conformant_array(jit_type_t type)
+{
+       return (jit_type_get_tagged_kind(type) == DPAS_TAG_CONFORMANT_ARRAY);
+}
+
 jit_type_t dpas_type_is_var(jit_type_t type)
 {
        if(jit_type_is_tagged(type) &&
index e7cc9a320800496579811dcdda478d74853f2edc..9af30d0a879f9b3c7990054578bb9671a0bba8d7 100644 (file)
@@ -156,6 +156,16 @@ jit_type_t dpas_create_array(jit_type_t *bounds, int num_bounds,
 jit_type_t dpas_create_conformant_array(jit_type_t elem_type, int num_bounds,
                                                                                int is_packed);
 
+/*
+ * Get an array's element type.
+ */
+jit_type_t dpas_type_get_elem(jit_type_t type);
+
+/*
+ * Get an array's rank.
+ */
+int dpas_type_get_rank(jit_type_t type);
+
 /*
  * Set the name of an enumerated or record type.  Ignored for other types,
  * or types that already have a name.
@@ -191,6 +201,12 @@ int dpas_type_is_boolean(jit_type_t type);
  */
 int dpas_type_is_record(jit_type_t type);
 
+/*
+ * Determine if a type is an array.
+ */
+int dpas_type_is_array(jit_type_t type);
+int dpas_type_is_conformant_array(jit_type_t type);
+
 /*
  * Determine if a type is a "var" parameter, and return its element type.
  */