diff --git a/oberon.c b/oberon.c
index 4b20dad3d30de42797478959dc92d2cd1e8929b9..16043c2f7aa0e4bdcd658130a5765b126b385b11 100644 (file)
--- a/oberon.c
+++ b/oberon.c
@@ -1024,15 +1024,18 @@ oberon_make_array_selector(oberon_context_t * ctx, oberon_expr_t * desig, oberon
}
// Статическая проверка границ массива
}
// Статическая проверка границ массива
- if(index -> is_item)
+ if(desig -> result -> size != 0)
{
{
- if(index -> item.mode == MODE_INTEGER)
+ if(index -> is_item)
{
{
- int arr_size = desig -> result -> size;
- int index_int = index -> item.integer;
- if(index_int < 0 || index_int > arr_size - 1)
+ if(index -> item.mode == MODE_INTEGER)
{
{
- oberon_error(ctx, "not in range (dimension size 0..%i)", arr_size - 1);
+ int arr_size = desig -> result -> size;
+ int index_int = index -> item.integer;
+ if(index_int < 0 || index_int > arr_size - 1)
+ {
+ oberon_error(ctx, "not in range (dimension size 0..%i)", arr_size - 1);
+ }
}
}
}
}
}
}
@@ -2031,6 +2034,14 @@ oberon_make_multiarray(oberon_context_t * ctx, oberon_expr_t * sizes, oberon_typ
oberon_make_array_type(ctx, sizes, dim, type);
}
oberon_make_array_type(ctx, sizes, dim, type);
}
+static void
+oberon_make_open_array(oberon_context_t * ctx, oberon_type_t * base, oberon_type_t * type)
+{
+ type -> class = OBERON_TYPE_ARRAY;
+ type -> size = 0;
+ type -> base = base;
+}
+
static void
oberon_type(oberon_context_t * ctx, oberon_type_t ** type)
{
static void
oberon_type(oberon_context_t * ctx, oberon_type_t ** type)
{
int num_sizes = 0;
oberon_expr_t * sizes;
int num_sizes = 0;
oberon_expr_t * sizes;
- oberon_expr_list(ctx, &num_sizes, &sizes, 1);
+
+ if(ISEXPR(ctx -> token))
+ {
+ oberon_expr_list(ctx, &num_sizes, &sizes, 1);
+ }
oberon_assert_token(ctx, OF);
oberon_assert_token(ctx, OF);
base = oberon_new_type_ptr(OBERON_TYPE_VOID);
oberon_type(ctx, &base);
base = oberon_new_type_ptr(OBERON_TYPE_VOID);
oberon_type(ctx, &base);
- oberon_make_multiarray(ctx, sizes, base, type);
+ if(num_sizes == 0)
+ {
+ oberon_make_open_array(ctx, base, *type);
+ }
+ else
+ {
+ oberon_make_multiarray(ctx, sizes, base, type);
+ }
}
else if(ctx -> token == RECORD)
{
}
else if(ctx -> token == RECORD)
{
}
else if(type -> class == OBERON_TYPE_ARRAY)
{
}
else if(type -> class == OBERON_TYPE_ARRAY)
{
+ if(type -> size != 0)
+ {
+ if(type -> base -> class == OBERON_TYPE_ARRAY)
+ {
+ if(type -> base -> size == 0)
+ {
+ oberon_error(ctx, "open array not allowed as array element");
+ }
+ }
+ }
+
oberon_initialize_type(ctx, type -> base);
oberon_generator_init_type(ctx, type);
}
oberon_initialize_type(ctx, type -> base);
oberon_generator_init_type(ctx, type);
}
oberon_initialize_type(ctx, x -> type);
break;
case OBERON_CLASS_VAR:
oberon_initialize_type(ctx, x -> type);
break;
case OBERON_CLASS_VAR:
+ case OBERON_CLASS_FIELD:
+ if(x -> type -> class == OBERON_TYPE_ARRAY)
+ {
+ if(x -> type -> size == 0)
+ {
+ oberon_error(ctx, "open array not allowed as variable or field");
+ }
+ }
+ oberon_initialize_type(ctx, x -> type);
+ oberon_generator_init_var(ctx, x);
+ break;
case OBERON_CLASS_PARAM:
case OBERON_CLASS_VAR_PARAM:
case OBERON_CLASS_PARAM:
case OBERON_CLASS_VAR_PARAM:
- case OBERON_CLASS_FIELD:
oberon_initialize_type(ctx, x -> type);
oberon_generator_init_var(ctx, x);
break;
oberon_initialize_type(ctx, x -> type);
oberon_generator_init_var(ctx, x);
break;
@@ -2725,11 +2768,6 @@ oberon_make_new_call(oberon_context_t * ctx, int num_args, oberon_expr_t * list_
oberon_error(ctx, "too few arguments");
}
oberon_error(ctx, "too few arguments");
}
- if(num_args > 1)
- {
- oberon_error(ctx, "too mach arguments");
- }
-
oberon_expr_t * dst;
dst = list_args;
oberon_expr_t * dst;
dst = list_args;
@@ -2748,37 +2786,58 @@ oberon_make_new_call(oberon_context_t * ctx, int num_args, oberon_expr_t * list_
src -> item.num_args = 0;
src -> item.args = NULL;
src -> item.num_args = 0;
src -> item.args = NULL;
+ int max_args = 1;
if(type -> class == OBERON_TYPE_ARRAY)
{
if(type -> class == OBERON_TYPE_ARRAY)
{
- // Пригодится при работе с открытыми массивами
- /*
- int dim = 1;
- oberon_expr_t * sizes = NULL;
- oberon_expr_t * last_size = NULL;
- sizes = last_size = oberon_new_item(MODE_INTEGER, ctx -> int_type, 1);
- sizes -> item.integer = type -> size;
- oberon_type_t * base = type -> base;
- while(base -> class == OBERON_TYPE_ARRAY)
+ if(type -> size == 0)
{
{
- oberon_expr_t * size;
- size = last_size = oberon_new_item(MODE_INTEGER, ctx -> int_type, 1);
- size -> item.integer = base -> size;
+ oberon_type_t * x = type;
+ while(x -> class == OBERON_TYPE_ARRAY)
+ {
+ if(x -> size == 0)
+ {
+ max_args += 1;
+ }
+ x = x -> base;
+ }
+ }
- last_size -> next = size;
- last_size = size;
- base = base -> base;
- dim += 1;
+ if(num_args < max_args)
+ {
+ oberon_error(ctx, "too few arguments");
}
}
- */
- src -> item.num_args = 0;
- src -> item.args = NULL;
+ if(num_args > max_args)
+ {
+ oberon_error(ctx, "too mach arguments");
+ }
+
+ int num_sizes = max_args - 1;
+ oberon_expr_t * size_list = list_args -> next;
+
+ oberon_expr_t * arg = size_list;
+ for(int i = 0; i < max_args - 1; i++)
+ {
+ if(arg -> result -> class != OBERON_TYPE_INTEGER)
+ {
+ oberon_error(ctx, "size must be integer");
+ }
+ arg = arg -> next;
+ }
+
+ src -> item.num_args = num_sizes;
+ src -> item.args = size_list;
}
else if(type -> class != OBERON_TYPE_RECORD)
{
oberon_error(ctx, "oberon_make_new_call: wat");
}
}
else if(type -> class != OBERON_TYPE_RECORD)
{
oberon_error(ctx, "oberon_make_new_call: wat");
}
+ if(num_args > max_args)
+ {
+ oberon_error(ctx, "too mach arguments");
+ }
+
oberon_assign(ctx, src, dst);
}
oberon_assign(ctx, src, dst);
}