summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: ea5cf05)
raw | patch | inline | side by side (parent: ea5cf05)
author | DeaDDooMER <deaddoomer@deadsoftware.ru> | |
Mon, 24 Jul 2017 20:07:06 +0000 (23:07 +0300) | ||
committer | DeaDDooMER <deaddoomer@deadsoftware.ru> | |
Mon, 24 Jul 2017 20:07:06 +0000 (23:07 +0300) |
generator.c | patch | blob | history | |
notes | patch | blob | history | |
oberon.c | patch | blob | history | |
test.c | patch | blob | history | |
test/.gitignore | [new file with mode: 0644] | patch | blob |
test/Test | patch | blob | history | |
test/Test.Mod | patch | blob | history | |
test/Test.c | patch | blob | history |
diff --git a/generator.c b/generator.c
index d54bbfdb408ad0dc720b6095e7b99f8e878ac4a9..b0887aee7c82587beed212c50e56cac179a32b72 100644 (file)
--- a/generator.c
+++ b/generator.c
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;
index ebd198db2fc9f0cb61fe90b31f496dbfa4a13cf9..0576334c3d003d72efdf80e9946f50d4f68ef97d 100644 (file)
--- a/notes
+++ b/notes
-- нету открытых массивов
+- открытые массивы работкают криво как статические аргументы процедур
+ Случай 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 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)
{
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);
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(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, 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);
}
index 1780bafa8ad900781c4af6e7f6b77868710a5119..6175148f461c4c0db1ff690997928e56f560544f 100644 (file)
--- a/test.c
+++ b/test.c
"(* 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
--- /dev/null
+++ b/test/.gitignore
@@ -0,0 +1 @@
+Test
diff --git a/test/Test b/test/Test
index de23f9b639cfb000e82fcdc28851179dcb4907da..1bf0d5aaad38f4e391972869a9b4f55d8b95a049 100755 (executable)
Binary files a/test/Test and b/test/Test differ
Binary files a/test/Test and b/test/Test differ
diff --git a/test/Test.Mod b/test/Test.Mod
index 5d8536d5febdcc37b5d7e8f671723f6e42ceebbe..22bad208f8350fb48acd03124fef64d909750323 100644 (file)
--- a/test/Test.Mod
+++ b/test/Test.Mod
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 8f1b741fb78b8d84351a99400a889a365b784ff5..f40f1381381d285e7d7284048e22e9fc4e24f846 100644 (file)
--- a/test/Test.c
+++ b/test/Test.c
#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);
}
{
__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;
}