From 56540110475558bb4cb3d1dad559f9050b35e80f Mon Sep 17 00:00:00 2001 From: DeaDDooMER Date: Tue, 1 Aug 2017 18:47:49 +0300 Subject: [PATCH] =?utf8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD?= =?utf8?q?=20=D0=B0=D0=B2=D1=82=D0=BE=D0=BA=D0=B0=D1=81=D1=82=20=D1=82?= =?utf8?q?=D0=B8=D0=BF=D0=BE=D0=B2-=D0=B7=D0=B0=D0=BF=D0=B8=D1=81=D0=B5?= =?utf8?q?=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- notes | 1 - src/oberon.c | 35 ++++++++++++++++++++++------------- src/test.c | 7 ++++--- 3 files changed, 26 insertions(+), 17 deletions(-) diff --git a/notes b/notes index 22d31b0..2f6fc26 100644 --- a/notes +++ b/notes @@ -1,5 +1,4 @@ - Нет оператора IS -- Нет автокаста записей - Нужно изменить передачу информации о вызываемой процедуре в MODE_CALL На данный момент конкретная процедура передаётся в поле var, вместо parent Что не позволяет делать процедуры-переменные в полях записей, массивах и т.д. diff --git a/src/oberon.c b/src/oberon.c index 6aa94d6..cefd469 100644 --- a/src/oberon.c +++ b/src/oberon.c @@ -767,6 +767,18 @@ oberon_cast_expr(oberon_context_t * ctx, oberon_expr_t * expr, oberon_type_t * p return cast; } +static oberon_expr_t * +oberno_make_record_cast(oberon_context_t * ctx, oberon_expr_t * expr, oberon_type_t * rec) +{ + if(expr -> result -> class != OBERON_TYPE_RECORD + || rec -> class != OBERON_TYPE_RECORD) + { + oberon_error(ctx, "must be record type"); + } + + return oberon_cast_expr(ctx, expr, rec); +} + static oberon_type_t * oberon_get_equal_expr_type(oberon_context_t * ctx, oberon_type_t * a, oberon_type_t * b) { @@ -841,11 +853,20 @@ oberon_autocast_to(oberon_context_t * ctx, oberon_expr_t * expr, oberon_type_t * } else if(pref -> class == OBERON_TYPE_RECORD) { - if(expr -> result != pref) + oberon_type_t * t = expr -> result; + while(t != NULL && t != pref) + { + t = t -> base; + } + if(t == NULL) { printf("oberon_autocast_to: rec %p != %p\n", expr -> result, pref); oberon_error(ctx, "incompatible record types"); } + if(expr -> result != pref) + { + expr = oberno_make_record_cast(ctx, expr, pref); + } } else if(pref -> class == OBERON_TYPE_POINTER) { @@ -1195,18 +1216,6 @@ oberon_qualident(oberon_context_t * ctx, char ** xname, int check) return x; } -static oberon_expr_t * -oberno_make_record_cast(oberon_context_t * ctx, oberon_expr_t * expr, oberon_type_t * rec) -{ - if(expr -> result -> class != OBERON_TYPE_RECORD - || rec -> class != OBERON_TYPE_RECORD) - { - oberon_error(ctx, "must be record type"); - } - - return oberon_cast_expr(ctx, expr, rec); -} - static oberon_expr_t * oberon_designator(oberon_context_t * ctx) { diff --git a/src/test.c b/src/test.c index 7a449d6..c6d49e4 100644 --- a/src/test.c +++ b/src/test.c @@ -20,12 +20,13 @@ static char source_test[] = "" "VAR" " baser : Baser;" - " r : R1;" - " inv : R2;" + " r : R1;" + " inv : R2;" "" "BEGIN" " r.a := 1;" - " baser := r(Baser);" + " baser := baser;" + " baser := r;" "END Test." ; -- 2.29.2