From 3818049ca3679e8fcc432345d41a2d930f7874e4 Mon Sep 17 00:00:00 2001 From: DeaDDooMER Date: Mon, 24 Jul 2017 22:53:43 +0300 Subject: [PATCH] =?utf8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD?= =?utf8?q?=D1=8B=20=D1=81=D0=BF=D0=B8=D1=81=D0=BA=D0=B8=20=D0=BE=D0=B1?= =?utf8?q?=D1=8A=D1=8F=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- generator.c | 32 ++++++++------- notes | 2 +- oberon.c | 110 ++++++++++++++++++++++++++++------------------------ test.c | 10 ++++- 4 files changed, 86 insertions(+), 68 deletions(-) diff --git a/generator.c b/generator.c index b7c24b3..991b6dd 100644 --- a/generator.c +++ b/generator.c @@ -153,34 +153,36 @@ oberon_generator_init_record(oberon_context_t * ctx, oberon_type_t * type) } static void -oberon_generator_get_full_name(char * name, int max_len, oberon_object_t * o) +oberon_generator_get_full_name(char * name, int max_len, oberon_object_t * x) { - if(!o) + if(!x) { name[0] = 0; return; } char parent[256]; - oberon_generator_get_full_name(parent, 256, o -> parent); - - char * xname; -// if(o -> class == OBERON_CLASS_MODULE) -// { -// xname = o -> module -> name; -// } -// else -// { - xname = o -> name; -// } + parent[0] = 0; + + switch(x -> class) + { + case OBERON_CLASS_FIELD: + case OBERON_CLASS_PARAM: + case OBERON_CLASS_VAR_PARAM: + /* В локальных областях префиксы излишни */ + break; + default: + oberon_generator_get_full_name(parent, 256, x -> parent); + break; + } if(strlen(parent) > 0) { - snprintf(name, max_len, "%s_%s", parent, xname); + snprintf(name, max_len, "%s_%s", parent, x -> name); } else { - snprintf(name, max_len, "%s", xname); + snprintf(name, max_len, "%s", x -> name); } } diff --git a/notes b/notes index e07d89d..148c0b4 100644 --- a/notes +++ b/notes @@ -1,5 +1,5 @@ +- поля структур всегда доступны - нету проверки экспорта для чтения -- нету списков переменных/параметров. (* VAR x, y, z : INTEGER; *) - нету комментариев - нету тестовых процедур для ввода-вывода diff --git a/oberon.c b/oberon.c index 817da1a..5b4c4ea 100644 --- a/oberon.c +++ b/oberon.c @@ -161,6 +161,7 @@ oberon_define_object(oberon_scope_t * scope, char * name, int class, int export, return newvar; } +/* static void oberon_define_field(oberon_context_t * ctx, oberon_type_t * rec, char * name, oberon_type_t * type) { @@ -188,6 +189,7 @@ oberon_define_field(oberon_context_t * ctx, oberon_type_t * rec, char * name, o rec -> num_decl += 1; x -> next = field; } +*/ static oberon_object_t * oberon_find_object_in_list(oberon_object_t * list, char * name) @@ -239,24 +241,15 @@ oberon_find_field(oberon_context_t * ctx, oberon_type_t * rec, char * name) } static oberon_object_t * -oberon_define_type(oberon_scope_t * scope, char * name, oberon_type_t * type, int export, int read_only) +oberon_define_type(oberon_scope_t * scope, char * name, oberon_type_t * type, int export) { oberon_object_t * id; - id = oberon_define_object(scope, name, OBERON_CLASS_TYPE, export, read_only); + id = oberon_define_object(scope, name, OBERON_CLASS_TYPE, export, 0); id -> type = type; oberon_generator_init_type(scope -> ctx, type); return id; } -static oberon_object_t * -oberon_define_var(oberon_scope_t * scope, int class, char * name, oberon_type_t * type, int export, int read_only) -{ - oberon_object_t * var; - var = oberon_define_object(scope, name, class, export, read_only); - var -> type = type; - return var; -} - // ======================================================================= // SCANER // ======================================================================= @@ -1449,51 +1442,52 @@ oberon_ident_def(oberon_context_t * ctx, int class) return x; } +static void +oberon_ident_list(oberon_context_t * ctx, int class, int * num, oberon_object_t ** list) +{ + *num = 1; + *list = oberon_ident_def(ctx, class); + while(ctx -> token == COMMA) + { + oberon_assert_token(ctx, COMMA); + oberon_ident_def(ctx, class); + *num += 1; + } +} + static void oberon_var_decl(oberon_context_t * ctx) { - oberon_object_t * var; + int num; + oberon_object_t * list; oberon_type_t * type; type = oberon_new_type_ptr(OBERON_TYPE_VOID); - var = oberon_ident_def(ctx, OBERON_CLASS_VAR); + oberon_ident_list(ctx, OBERON_CLASS_VAR, &num, &list); oberon_assert_token(ctx, COLON); oberon_type(ctx, &type); - var -> type = type; -} - -static oberon_object_t * -oberon_make_param(oberon_context_t * ctx, int token, char * name, oberon_type_t * type) -{ - oberon_object_t * param; - if(token == VAR) + oberon_object_t * var = list; + for(int i = 0; i < num; i++) { - param = oberon_define_var(ctx -> decl, OBERON_CLASS_VAR_PARAM, name, type, 0, 0); + var -> type = type; + var = var -> next; } - else if(token == IDENT) - { - param = oberon_define_var(ctx -> decl, OBERON_CLASS_PARAM, name, type, 0, 0); - } - else - { - oberon_error(ctx, "oberon_make_param: wat"); - } - - return param; } static oberon_object_t * oberon_fp_section(oberon_context_t * ctx, int * num_decl) { - int modifer_token = ctx -> token; + int class = OBERON_CLASS_PARAM; if(ctx -> token == VAR) { oberon_read_token(ctx); + class = OBERON_CLASS_VAR_PARAM; } - char * name; - name = oberon_assert_ident(ctx); + int num; + oberon_object_t * list; + oberon_ident_list(ctx, class, &num, &list); oberon_assert_token(ctx, COLON); @@ -1501,11 +1495,15 @@ oberon_fp_section(oberon_context_t * ctx, int * num_decl) type = oberon_new_type_ptr(OBERON_TYPE_VOID); oberon_type(ctx, &type); - oberon_object_t * first; - first = oberon_make_param(ctx, modifer_token, name, type); + oberon_object_t * param = list; + for(int i = 0; i < num; i++) + { + param -> type = type; + param = param -> next; + } - *num_decl += 1; - return first; + *num_decl += num; + return list; } #define ISFPSECTION \ @@ -1761,14 +1759,23 @@ oberon_field_list(oberon_context_t * ctx, oberon_type_t * rec) { if(ctx -> token == IDENT) { - char * name; + int num; + oberon_object_t * list; oberon_type_t * type; type = oberon_new_type_ptr(OBERON_TYPE_VOID); - name = oberon_assert_ident(ctx); + oberon_ident_list(ctx, OBERON_CLASS_FIELD, &num, &list); oberon_assert_token(ctx, COLON); oberon_type(ctx, &type); - oberon_define_field(ctx, rec, name, type); + + oberon_object_t * field = list; + for(int i = 0; i < num; i++) + { + field -> type = type; + field = field -> next; + } + + rec -> num_decl += num; } } @@ -1850,11 +1857,12 @@ oberon_type(oberon_context_t * ctx, oberon_type_t ** type) oberon_type_t * rec; rec = *type; rec -> class = OBERON_TYPE_RECORD; - oberon_object_t * list = malloc(sizeof *list); - memset(list, 0, sizeof *list); - rec -> num_decl = 0; - rec -> base = NULL; - rec -> decl = list; + + oberon_scope_t * record_scope; + record_scope = oberon_open_scope(ctx); + // TODO parent object + //record_scope -> parent = NULL; + record_scope -> local = 1; oberon_assert_token(ctx, RECORD); oberon_field_list(ctx, rec); @@ -1865,7 +1873,9 @@ oberon_type(oberon_context_t * ctx, oberon_type_t ** type) } oberon_assert_token(ctx, END); - rec -> decl = rec -> decl -> next; + rec -> decl = record_scope -> list -> next; + oberon_close_scope(record_scope); + *type = rec; } else if(ctx -> token == POINTER) @@ -2456,10 +2466,10 @@ register_default_types(oberon_context_t * ctx) oberon_generator_init_type(ctx, ctx -> void_ptr_type); ctx -> int_type = oberon_new_type_integer(sizeof(int)); - oberon_define_type(ctx -> world_scope, "INTEGER", ctx -> int_type, 1, 0); + oberon_define_type(ctx -> world_scope, "INTEGER", ctx -> int_type, 1); ctx -> bool_type = oberon_new_type_boolean(sizeof(int)); - oberon_define_type(ctx -> world_scope, "BOOLEAN", ctx -> bool_type, 1, 0); + oberon_define_type(ctx -> world_scope, "BOOLEAN", ctx -> bool_type, 1); } static void diff --git a/test.c b/test.c index 5b2fc48..4bef02c 100644 --- a/test.c +++ b/test.c @@ -8,16 +8,22 @@ static char source_test[] = "MODULE Test;" "IMPORT I := Imported;" "VAR" - " x : I.Rider;" + " x, y : I.Rider;" + "PROCEDURE Proc(x, y, z : INTEGER);" + "END Proc;" "BEGIN" + " x.i := 1;" " I.Ln;" + " I.i := 666;" "END Test." ; static char source_imported[] = "MODULE Imported;" "TYPE" - " Rider* = RECORD i : INTEGER; END;" + " Rider* = RECORD i, j, k : INTEGER; END;" + "VAR" + " i- : INTEGER;" "" "PROCEDURE Ln*;" "END Ln;" -- 2.29.2