From c81c2b2f5bf223bc1bdc986d31039b36240962c5 Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Thu, 13 May 2004 02:45:48 +0000 Subject: [PATCH] Put some infrastructure (incomplete) in place to support array index expressions. --- ChangeLog | 6 +++ dpas/dpas-parser.y | 92 ++++++++++++++++++++++++++++++++++++++++++++-- dpas/dpas-types.c | 43 ++++++++++++++++++++++ dpas/dpas-types.h | 16 ++++++++ 4 files changed, 154 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 94e2b4e..6277aa7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,10 @@ +2004-05-13 Rhys Weatherley + + * 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 * jitdynamic/Makefile.am, jitplus/Makefile.am: use both .libs and diff --git a/dpas/dpas-parser.y b/dpas/dpas-parser.y index 959d9be..6e9fba7 100644 --- a/dpas/dpas-parser.y +++ b/dpas/dpas-parser.y @@ -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 */ diff --git a/dpas/dpas-types.c b/dpas/dpas-types.c index d933480..910c32a 100644 --- a/dpas/dpas-types.c +++ b/dpas/dpas-types.c @@ -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) && diff --git a/dpas/dpas-types.h b/dpas/dpas-types.h index e7cc9a3..9af30d0 100644 --- a/dpas/dpas-types.h +++ b/dpas/dpas-types.h @@ -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. */ -- 2.47.3