DEADSOFTWARE

Добавлены открытые массивы
authorDeaDDooMER <deaddoomer@deadsoftware.ru>
Mon, 24 Jul 2017 20:07:06 +0000 (23:07 +0300)
committerDeaDDooMER <deaddoomer@deadsoftware.ru>
Mon, 24 Jul 2017 20:07:06 +0000 (23:07 +0300)
generator.c
notes
oberon.c
test.c
test/.gitignore [new file with mode: 0644]
test/Test
test/Test.Mod
test/Test.c

index d54bbfdb408ad0dc720b6095e7b99f8e878ac4a9..b0887aee7c82587beed212c50e56cac179a32b72 100644 (file)
@@ -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 ebd198db2fc9f0cb61fe90b31f496dbfa4a13cf9..0576334c3d003d72efdf80e9946f50d4f68ef97d 100644 (file)
--- 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. Да и вообще каст типов.
 
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);
 }
 
+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 1780bafa8ad900781c4af6e7f6b77868710a5119..6175148f461c4c0db1ff690997928e56f560544f 100644 (file)
--- 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 (file)
index 0000000..345e6ae
--- /dev/null
@@ -0,0 +1 @@
+Test
index de23f9b639cfb000e82fcdc28851179dcb4907da..1bf0d5aaad38f4e391972869a9b4f55d8b95a049 100755 (executable)
Binary files a/test/Test and b/test/Test differ
index 5d8536d5febdcc37b5d7e8f671723f6e42ceebbe..22bad208f8350fb48acd03124fef64d909750323 100644 (file)
@@ -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.
index 8f1b741fb78b8d84351a99400a889a365b784ff5..f40f1381381d285e7d7284048e22e9fc4e24f846 100644 (file)
@@ -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;
 }