From: DeaDDooMER Date: Mon, 24 Jul 2017 20:07:06 +0000 (+0300) Subject: Добавлены открытые массивы X-Git-Url: http://deadsoftware.ru/gitweb?a=commitdiff_plain;h=e763da864f7330c2b53029782c6b0d85543eb4d2;p=dsw-obn.git Добавлены открытые массивы --- diff --git a/generator.c b/generator.c index d54bbfd..b0887ae 100644 --- a/generator.c +++ b/generator.c @@ -372,6 +372,7 @@ oberon_generator_get_type_size(oberon_context_t * ctx, oberon_type_t * type) case OBERON_TYPE_ARRAY: size = type -> size; type = type -> base; + size = (size == 0) ? (1) : (size); size *= oberon_generator_get_type_size(ctx, type); printf("array size: %i\n", size); break; diff --git a/notes b/notes index ebd198d..0576334 100644 --- a/notes +++ b/notes @@ -1,4 +1,27 @@ -- нету открытых массивов +- открытые массивы работкают криво как статические аргументы процедур + Случай 1: не проходит проверки libgccjit + (* + TYPE Ar = ARRAY OF INTEGER; + VAR a : POINTER TO Ar; + + (* так же и с VAR-параметром *) + PROCEDURE Ax(x : Ar); + END Ax; + + Ax(a); + *) + Случай 2: массив должен быть указателем, да и ещё копироваться + (* + TYPE Ar = ARRAY OF INTEGER; + VAR a : POINTER TO Ar; + + (* при использовании VAR-параметра работает *) + PROCEDURE Ax(x : Ar); + END Ax; + + Ax(a^); + *) + - нет символов и строк - нужен автокаст int -> real для DIV. Да и вообще каст типов. diff --git a/oberon.c b/oberon.c index 4b20dad..16043c2 100644 --- 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); } +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) { @@ -2044,7 +2055,11 @@ oberon_type(oberon_context_t * ctx, oberon_type_t ** type) 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); @@ -2052,7 +2067,14 @@ oberon_type(oberon_context_t * ctx, oberon_type_t ** type) 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) { @@ -2360,6 +2382,17 @@ oberon_initialize_type(oberon_context_t * ctx, oberon_type_t * type) } 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); } @@ -2402,9 +2435,19 @@ oberon_initialize_object(oberon_context_t * ctx, oberon_object_t * x) 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_FIELD: 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"); } - if(num_args > 1) - { - oberon_error(ctx, "too mach arguments"); - } - 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; + int max_args = 1; 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"); } + if(num_args > max_args) + { + oberon_error(ctx, "too mach arguments"); + } + oberon_assign(ctx, src, dst); } diff --git a/test.c b/test.c index 1780baf..6175148 100644 --- a/test.c +++ b/test.c @@ -8,30 +8,24 @@ static char source_test[] = "(* Main module *)" "MODULE Test;" "IMPORT Out;" - "CONST" - " real = 0.1E3;" + "TYPE Ar = ARRAY OF ARRAY OF INTEGER;" + "VAR a : POINTER TO Ar;" "" - "VAR" - " nx- : INTEGER;" - " p : POINTER TO ARRAY 3 OF RECORD i, j, k : INTEGER END;" - " q : POINTER TO RECORD x, y, z : INTEGER END;" - "" - "PROCEDURE ChParam(VAR i : INTEGER);" + "PROCEDURE Ax(VAR x : POINTER TO Ar);" "BEGIN" - " i := 1234;" - "END ChParam;" + " x[0, 0] := 777;" + "END Ax;" "" "BEGIN;" - " NEW(p);" - " p[2].k := 1;" - " NEW(q);" - " " + " NEW(a, 2, 2);" + " a[0, 0] := 666;" " Out.Open;" - " ChParam(nx);" - " Out.Int(nx, 0);" - " Out.Ln;" - " Out.Real(real / 3.0, 0);" + " Out.Int(a[0, 0], 0);" " Out.Ln;" + "" + " Ax(a);" +// " Out.Int(a[0, 0], 0);" +// " Out.Ln;" "END Test." ; diff --git a/test/.gitignore b/test/.gitignore new file mode 100644 index 0000000..345e6ae --- /dev/null +++ b/test/.gitignore @@ -0,0 +1 @@ +Test diff --git a/test/Test b/test/Test index de23f9b..1bf0d5a 100755 Binary files a/test/Test and b/test/Test differ diff --git a/test/Test.Mod b/test/Test.Mod index 5d8536d..22bad20 100644 --- a/test/Test.Mod +++ b/test/Test.Mod @@ -2,19 +2,15 @@ MODULE Test; IMPORT Out; -TYPE - PVector = POINTER TO Vector; - Vector = ARRAY 3 OF INTEGER; - VAR - a : PVector; - b : Vector; + a : ARRAY 3 OF INTEGER; +PROCEDURE Ax(VAR x : ARRAY OF INTEGER); BEGIN - Out.Open; - - NEW(a); - a^ := b; +END Ax; - Out.Flush; +BEGIN + Out.Open; + Ax(a); + Out.Flush; END Test. diff --git a/test/Test.c b/test/Test.c index 8f1b741..f40f138 100644 --- a/test/Test.c +++ b/test/Test.c @@ -8,22 +8,15 @@ #include "SYSTEM.h" #include "Out.h" -typedef - INT16 Test_Vector[3]; -typedef - Test_Vector *Test_PVector; +static INT16 Test_a[3]; -static Test_PVector Test_a; -static Test_Vector Test_b; +static void Test_Ax (INT16 *x, ADDRESS x__len); - - -static void EnumPtrs(void (*P)(void*)) +static void Test_Ax (INT16 *x, ADDRESS x__len) { - P(Test_a); } @@ -31,11 +24,10 @@ export int main(int argc, char **argv) { __INIT(argc, argv); __MODULE_IMPORT(Out); - __REGMAIN("Test", EnumPtrs); + __REGMAIN("Test", 0); /* BEGIN */ Out_Open(); - Test_a = __NEWARR(NIL, 2, 2, 1, 0, ((INT64)(3))); - __MOVE(Test_b, *Test_a, 6); + Test_Ax((void*)Test_a, 3); Out_Flush(); __FINI; }