diff --git a/src/tools/ainedit/jaf.h b/src/tools/ainedit/jaf.h index cccb3e1..abd6e1b 100644 --- a/src/tools/ainedit/jaf.h +++ b/src/tools/ainedit/jaf.h @@ -311,6 +311,7 @@ void jaf_copy_type(struct jaf_type_specifier *dst, struct jaf_type_specifier *sr struct jaf_declarator *jaf_declarator(struct string *name); struct jaf_declarator *jaf_array_allocation(struct string *name, struct jaf_expression *dim); +struct jaf_declarator *jaf_array_dimension(struct jaf_declarator *d, struct jaf_expression *dim); struct jaf_declarator_list *jaf_declarators(struct jaf_declarator_list *head, struct jaf_declarator *tail); struct jaf_block *jaf_parameter(struct jaf_type_specifier *type, struct jaf_declarator *declarator); diff --git a/src/tools/ainedit/jaf_ast.c b/src/tools/ainedit/jaf_ast.c index ebff146..86ba87c 100644 --- a/src/tools/ainedit/jaf_ast.c +++ b/src/tools/ainedit/jaf_ast.c @@ -45,7 +45,7 @@ struct jaf_expression *jaf_parse_integer(struct string *text) errno = 0; int i = strtol(text->text, &endptr, 0); if (errno || *endptr != '\0') - ERROR("Invalid integer constant"); + ERROR("Invalid integer constant: %s", text->text); free_string(text); return jaf_integer(i); } @@ -232,11 +232,20 @@ struct jaf_declarator *jaf_array_allocation(struct string *name, struct jaf_expr struct jaf_declarator *d = xcalloc(1, sizeof(struct jaf_declarator)); d->name = name; d->array_rank = 1; - d->array_dims = xmalloc(sizeof(size_t)); + d->array_dims = xmalloc(sizeof(struct jaf_expression*)); d->array_dims[0] = dim; return d; } +struct jaf_declarator *jaf_array_dimension(struct jaf_declarator *d, struct jaf_expression *dim) +{ + int no = d->array_rank; + d->array_dims = xrealloc_array(d->array_dims, no, no+1, sizeof(struct jaf_expression*)); + d->array_dims[no] = dim; + d->array_rank++; + return d; +} + struct jaf_declarator_list *jaf_declarators(struct jaf_declarator_list *head, struct jaf_declarator *tail) { if (!head) { diff --git a/src/tools/ainedit/jaf_parser.y b/src/tools/ainedit/jaf_parser.y index 90623e8..5281754 100644 --- a/src/tools/ainedit/jaf_parser.y +++ b/src/tools/ainedit/jaf_parser.y @@ -462,7 +462,7 @@ declarator array_allocation : IDENTIFIER '[' constant ']' { $$ = jaf_array_allocation($1, $3); } - | array_allocation '[' constant ']' { ERROR("Multi-dimensional arrays not supported"); } + | array_allocation '[' constant ']' { $$ = jaf_array_dimension($1, $3); } ; initializer diff --git a/src/tools/ainedit/jaf_types.c b/src/tools/ainedit/jaf_types.c index a39bd5e..4264be9 100644 --- a/src/tools/ainedit/jaf_types.c +++ b/src/tools/ainedit/jaf_types.c @@ -496,15 +496,41 @@ static enum ain_data_type array_data_type(enum ain_data_type type) } } +static void jaf_type_check_array(struct jaf_expression *expr) +{ + switch (expr->valuetype.data) { + case AIN_ARRAY_TYPE: + case AIN_REF_ARRAY_TYPE: + return; + case AIN_ARRAY: + ERROR("ain v11+ arrays not supported"); + default: + TYPE_ERROR(expr, AIN_ARRAY); + } +} + +static void array_deref_type(struct ain_type *dst, struct ain_type *src) +{ + if (src->rank > 1) { + dst->data = src->data; + dst->struc = src->struc; + dst->rank = src->rank - 1; + } else { + assert(src->rank == 1); + dst->data = array_data_type(src->data); + dst->struc = src->struc; + dst->rank = 0; + } +} + static void jaf_check_types_subscript(struct jaf_env *env, struct jaf_expression *expr) { jaf_derive_types(env, expr->subscript.expr); jaf_derive_types(env, expr->subscript.index); + jaf_type_check_array(expr->subscript.expr); jaf_type_check_int(expr->subscript.index); - expr->valuetype.data = array_data_type(expr->subscript.expr->valuetype.data); - expr->valuetype.struc = expr->subscript.expr->valuetype.struc; - if (expr->valuetype.data == AIN_VOID) - TYPE_ERROR(expr->subscript.expr, AIN_ARRAY); + + array_deref_type(&expr->valuetype, &expr->subscript.expr->valuetype); } void jaf_derive_types(struct jaf_env *env, struct jaf_expression *expr) diff --git a/src/tools/ainedit/test/run-tests.sh b/src/tools/ainedit/test/run-tests.sh index 21b9b10..eff4a7c 100755 --- a/src/tools/ainedit/test/run-tests.sh +++ b/src/tools/ainedit/test/run-tests.sh @@ -76,6 +76,7 @@ cd $(dirname "$0") ./test-runner.sh array-int.jaf ./test-runner.sh array-string.jaf ./test-runner.sh array-arg.jaf +./test-runner.sh array-multi.jaf ./test-runner.sh ref-array-item.jaf ./test-runner.sh ref-array-int.jaf