From 1128fa8566c932e3996abd427fc75bc4c946e656 Mon Sep 17 00:00:00 2001 From: DeaDDooMER Date: Mon, 21 Aug 2017 11:48:23 +0300 Subject: [PATCH] =?utf8?q?=D0=9F=D0=BE=D0=BF=D1=80=D0=B0=D0=B2=D0=BB=D0=B5?= =?utf8?q?=D0=BD=D1=8B=20=D0=BE=D0=B1=D1=8A=D1=8F=D0=B2=D0=BB=D0=B5=D0=BD?= =?utf8?q?=D0=B8=D1=8F=20=D1=82=D0=B8=D0=BF=D0=BE=D0=B2=20=D0=BD=D0=B0?= =?utf8?q?=D0=BF=D0=B5=D1=80=D1=91=D0=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- Test.obn | 8 ++++ obn-run-tests.sh | 1 + src/backends/jvm/generator-jvm.c | 7 ++++ src/oberon.c | 66 +++++++++++++++++++------------- src/oberon.h | 24 ------------ tests/Test21.obn | 23 +++++++++++ 6 files changed, 78 insertions(+), 51 deletions(-) delete mode 100644 src/oberon.h create mode 100644 tests/Test21.obn diff --git a/Test.obn b/Test.obn index 6fae529..be037a2 100644 --- a/Test.obn +++ b/Test.obn @@ -1,3 +1,11 @@ MODULE Test; +TYPE + + PC = ARRAY 3 OF PB; + + B = RECORD z : PC; next : PB END; + + PB = POINTER TO B; + END Test. diff --git a/obn-run-tests.sh b/obn-run-tests.sh index faaf6ea..7cfbb49 100755 --- a/obn-run-tests.sh +++ b/obn-run-tests.sh @@ -90,3 +90,4 @@ makefail Test18C maketest Test19 maketest Test20 +maketest Test21 diff --git a/src/backends/jvm/generator-jvm.c b/src/backends/jvm/generator-jvm.c index e4ea383..be8c929 100644 --- a/src/backends/jvm/generator-jvm.c +++ b/src/backends/jvm/generator-jvm.c @@ -631,6 +631,13 @@ oberon_generator_init_var(oberon_context_t * ctx, oberon_object_t * var) struct gen_class * c; char * name = var -> name; gen_type_t * t = var -> type -> gen_type; + + assert(name); + if(t == NULL) + { + gen_error("uninitialized type class %i", var -> type -> class); + } + switch(var -> class) { case OBERON_CLASS_VAR_PARAM: diff --git a/src/oberon.c b/src/oberon.c index e684e65..4afd4c2 100644 --- a/src/oberon.c +++ b/src/oberon.c @@ -1150,6 +1150,8 @@ oberon_autocast_call(oberon_context_t * ctx, oberon_item_t * desig) int num_args = desig -> num_args; int num_decl = fn -> num_decl; + printf("oberon_autocast_call: num_args %i num_decl %i\n", num_args, num_decl); + if(num_args < num_decl) { oberon_error(ctx, "too few arguments"); @@ -2782,7 +2784,14 @@ oberon_prevent_recursive_pointer(oberon_context_t * ctx, oberon_type_t * type) if(type -> recursive) { - oberon_error(ctx, "recursive pointer declaration"); + if(type -> class == OBERON_TYPE_POINTER) + { + oberon_error(ctx, "recursive pointer declaration"); + } + else + { + oberon_error(ctx, "recursive array declaration (pointer)"); + } } if(type -> class == OBERON_TYPE_POINTER @@ -2935,20 +2944,12 @@ static void oberon_initialize_type(oberon_context_t * ctx, oberon_type_t * type) static void oberon_initialize_record_fields(oberon_context_t * ctx, oberon_type_t * type) { - if(type -> class != OBERON_TYPE_RECORD) - { - return; - } + assert(type -> class == OBERON_TYPE_RECORD); int num_fields = type -> num_decl; oberon_object_t * field = type -> decl; for(int i = 0; i < num_fields; i++) { - if(field -> type -> class == OBERON_TYPE_POINTER) - { - oberon_initialize_type(ctx, field -> type); - } - oberon_initialize_object(ctx, field); field = field -> next; } @@ -2971,39 +2972,50 @@ oberon_initialize_type(oberon_context_t * ctx, oberon_type_t * type) type -> initialized = 1; - if(type -> class == OBERON_TYPE_POINTER) - { - oberon_initialize_type(ctx, type -> base); - oberon_generator_init_type(ctx, type); - } - else if(type -> class == OBERON_TYPE_ARRAY) + if(type -> class == OBERON_TYPE_POINTER || type -> class == OBERON_TYPE_ARRAY) { - if(type -> size != 0) + if(type -> class == OBERON_TYPE_ARRAY + && type -> size != 0 + && type -> base -> class == OBERON_TYPE_ARRAY + && type -> base -> 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_error(ctx, "open array not allowed as array element"); } - oberon_initialize_type(ctx, type -> base); - oberon_generator_init_type(ctx, type); + oberon_type_t * rec = type -> base; + while(rec -> class == OBERON_TYPE_ARRAY || rec -> class == OBERON_TYPE_POINTER) + { + rec = rec -> base; + } + + if(rec -> class == OBERON_TYPE_RECORD + && rec -> initialized == 0) + { + rec -> initialized = 1; + oberon_generator_init_type(ctx, rec); + oberon_initialize_type(ctx, type -> base); + oberon_generator_init_type(ctx, type); + oberon_initialize_record_fields(ctx, rec); + } + else + { + oberon_initialize_type(ctx, type -> base); + oberon_generator_init_type(ctx, type); + } } else if(type -> class == OBERON_TYPE_RECORD) { + printf("Init type: RECORD\n"); oberon_generator_init_type(ctx, type); oberon_initialize_record_fields(ctx, type); } else if(type -> class == OBERON_TYPE_PROCEDURE) { + printf("Init type: PROCEDURE\n"); int num_fields = type -> num_decl; oberon_object_t * field = type -> decl; for(int i = 0; i < num_fields; i++) { - //oberon_initialize_object(ctx, field); oberon_initialize_type(ctx, field -> type); field = field -> next; } diff --git a/src/oberon.h b/src/oberon.h deleted file mode 100644 index 2f51a77..0000000 --- a/src/oberon.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef OBERON_H -#define OBERON_H - -typedef struct oberon_type_t oberon_type_t; - -typedef struct oberon_module_t oberon_module_t; - -typedef struct oberon_context_t oberon_context_t; - -typedef const char * (*ModuleImportCallback)(const char * name); - -extern oberon_context_t * -oberon_create_context(ModuleImportCallback import_module); - -extern void -oberon_destroy_context(oberon_context_t * ctx); - -extern oberon_module_t * -oberon_compile_module(oberon_context_t * ctx, const char * code); - -extern void -oberon_set_out_directory(oberon_context_t * ctx, const char * path); - -#endif // OBERON_H diff --git a/tests/Test21.obn b/tests/Test21.obn new file mode 100644 index 0000000..88c288d --- /dev/null +++ b/tests/Test21.obn @@ -0,0 +1,23 @@ +MODULE Test21; + +TYPE + PA = POINTER TO A; + + PC = POINTER TO C; + + A = RECORD nt : PA END; + B = RECORD (A) z : PC; next : PB END; + + C = ARRAY 3 OF PB; + + PB = POINTER TO B; + +VAR + p : PA; + +BEGIN + NEW(p); + p.nt := NIL; +END Test21. + +Тест определений наперёд. -- 2.29.2