mirror of
https://github.com/nunuhara/xsystem4.git
synced 2026-10-07 06:18:14 +03:00
jaf: multi-dimensional arrays
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user