From 0833fd8741d5215e8e8576fecd1f5a5f5dfc84f6 Mon Sep 17 00:00:00 2001 From: DeaDDooMER Date: Mon, 24 Jul 2017 22:51:28 +0300 Subject: [PATCH] =?utf8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD?= =?utf8?q?=D0=BE=20=D1=8D=D0=BA=D1=81=D0=BF=D0=BE=D1=80=D1=82=D0=B8=D1=80?= =?utf8?q?=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=20=D0=BE=D0=B1=D1=8A=D0=B5?= =?utf8?q?=D0=BA=D1=82=D0=BE=D0=B2=20=D0=B2=20=D0=BC=D0=BE=D0=B4=D1=83?= =?utf8?q?=D0=BB=D1=8F=D1=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- notes | 2 +- oberon.c | 142 ++++++++++++++++++++++++++---------------------- oberon.h | 2 + test.c | 22 ++------ test/.gitignore | 1 - 5 files changed, 85 insertions(+), 84 deletions(-) delete mode 100644 test/.gitignore diff --git a/notes b/notes index 819b45f..e07d89d 100644 --- a/notes +++ b/notes @@ -1,4 +1,4 @@ -- нету экспорта объектов (всё доступно для чтения и записи) +- нету проверки экспорта для чтения - нету списков переменных/параметров. (* VAR x, y, z : INTEGER; *) - нету комментариев diff --git a/oberon.c b/oberon.c index e12ee36..817da1a 100644 --- a/oberon.c +++ b/oberon.c @@ -134,7 +134,7 @@ oberon_close_scope(oberon_scope_t * scope) } static oberon_object_t * -oberon_define_object(oberon_scope_t * scope, char * name, int class) +oberon_define_object(oberon_scope_t * scope, char * name, int class, int export, int read_only) { oberon_object_t * x = scope -> list; while(x -> next && strcmp(x -> next -> name, name) != 0) @@ -151,6 +151,8 @@ oberon_define_object(oberon_scope_t * scope, char * name, int class) memset(newvar, 0, sizeof *newvar); newvar -> name = name; newvar -> class = class; + newvar -> export = export; + newvar -> read_only = read_only; newvar -> local = scope -> local; newvar -> parent = scope -> parent; @@ -237,64 +239,24 @@ 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) +oberon_define_type(oberon_scope_t * scope, char * name, oberon_type_t * type, int export, int read_only) { oberon_object_t * id; - id = oberon_define_object(scope, name, OBERON_CLASS_TYPE); + id = oberon_define_object(scope, name, OBERON_CLASS_TYPE, export, read_only); id -> type = type; oberon_generator_init_type(scope -> ctx, type); return id; } -/* -static oberon_type_t * -oberon_find_type(oberon_scope_t * scope, char * name) -{ - oberon_object_t * x = oberon_find_object(scope, name); - if(x -> class != OBERON_CLASS_TYPE) - { - oberon_error(scope -> ctx, "%s not a type", name); - } - - return x -> type; -} -*/ - static oberon_object_t * -oberon_define_var(oberon_scope_t * scope, int class, char * name, oberon_type_t * type) +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); + var = oberon_define_object(scope, name, class, export, read_only); var -> type = type; return var; } -/* -static oberon_object_t * -oberon_find_var(oberon_scope_t * scope, char * name) -{ - oberon_object_t * x = oberon_find_object(scope, name); - - if(x -> class != OBERON_CLASS_VAR) - { - oberon_error(scope -> ctx, "%s not a var", name); - } - - return x; -} -*/ - -/* -static oberon_object_t * -oberon_define_proc(oberon_scope_t * scope, char * name, oberon_type_t * signature) -{ - oberon_object_t * proc; - proc = oberon_define_object(scope, name, OBERON_CLASS_PROC); - proc -> type = signature; - return proc; -} -*/ - // ======================================================================= // SCANER // ======================================================================= @@ -1004,6 +966,11 @@ oberon_qualident(oberon_context_t * ctx, char ** xname, int check) name = oberon_assert_ident(ctx); /* Наличие объектов в левых модулях всегда проверяется */ x = oberon_find_object(x -> module -> decl, name, 1); + + if(x -> export == 0) + { + oberon_error(ctx, "not exported"); + } } } @@ -1446,16 +1413,53 @@ oberon_assert_ident(oberon_context_t * ctx) } static void -oberon_var_decl(oberon_context_t * ctx) +oberon_def(oberon_context_t * ctx, int * export, int * read_only) +{ + switch(ctx -> token) + { + case STAR: + oberon_assert_token(ctx, STAR); + *export = 1; + *read_only = 0; + break; + case MINUS: + oberon_assert_token(ctx, MINUS); + *export = 1; + *read_only = 1; + break; + default: + *export = 0; + *read_only = 0; + break; + } +} + +static oberon_object_t * +oberon_ident_def(oberon_context_t * ctx, int class) { char * name; + int export; + int read_only; + oberon_object_t * x; + + name = oberon_assert_ident(ctx); + oberon_def(ctx, &export, &read_only); + + x = oberon_define_object(ctx -> decl, name, class, export, read_only); + return x; +} + +static void +oberon_var_decl(oberon_context_t * ctx) +{ + oberon_object_t * var; oberon_type_t * type; type = oberon_new_type_ptr(OBERON_TYPE_VOID); - name = oberon_assert_ident(ctx); + var = oberon_ident_def(ctx, OBERON_CLASS_VAR); oberon_assert_token(ctx, COLON); oberon_type(ctx, &type); - oberon_define_var(ctx -> decl, OBERON_CLASS_VAR, name, type); + var -> type = type; } static oberon_object_t * @@ -1465,11 +1469,11 @@ oberon_make_param(oberon_context_t * ctx, int token, char * name, oberon_type_t if(token == VAR) { - param = oberon_define_var(ctx -> decl, OBERON_CLASS_VAR_PARAM, name, type); + param = oberon_define_var(ctx -> decl, OBERON_CLASS_VAR_PARAM, name, type, 0, 0); } else if(token == IDENT) { - param = oberon_define_var(ctx -> decl, OBERON_CLASS_PARAM, name, type); + param = oberon_define_var(ctx -> decl, OBERON_CLASS_PARAM, name, type, 0, 0); } else { @@ -1662,7 +1666,10 @@ oberon_proc_decl(oberon_context_t * ctx) } char * name; + int export; + int read_only; name = oberon_assert_ident(ctx); + oberon_def(ctx, &export, &read_only); oberon_scope_t * proc_scope; proc_scope = oberon_open_scope(ctx); @@ -1693,11 +1700,16 @@ oberon_proc_decl(oberon_context_t * ctx) } } + if(proc -> export != export || proc -> read_only != read_only) + { + oberon_error(ctx, "export type not matched"); + } + oberon_compare_signatures(ctx, proc -> type, signature); } else { - proc = oberon_define_object(ctx -> decl, name, OBERON_CLASS_PROC); + proc = oberon_define_object(ctx -> decl, name, OBERON_CLASS_PROC, export, read_only); proc -> type = signature; proc -> scope = proc_scope; oberon_generator_init_proc(ctx, proc); @@ -1715,15 +1727,12 @@ oberon_proc_decl(oberon_context_t * ctx) static void oberon_const_decl(oberon_context_t * ctx) { - char * name; oberon_item_t * value; oberon_object_t * constant; - name = oberon_assert_ident(ctx); + constant = oberon_ident_def(ctx, OBERON_CLASS_CONST); oberon_assert_token(ctx, EQUAL); value = oberon_const_expr(ctx); - - constant = oberon_define_object(ctx -> decl, name, OBERON_CLASS_CONST); constant -> value = value; } @@ -1783,7 +1792,7 @@ oberon_qualident_type(oberon_context_t * ctx, oberon_type_t ** type) } else { - to = oberon_define_object(ctx -> decl, name, OBERON_CLASS_TYPE); + to = oberon_define_object(ctx -> decl, name, OBERON_CLASS_TYPE, 0, 0); to -> type = oberon_new_type_ptr(OBERON_TYPE_VOID); } @@ -1892,13 +1901,16 @@ oberon_type_decl(oberon_context_t * ctx) char * name; oberon_object_t * newtype; oberon_type_t * type; + int export; + int read_only; name = oberon_assert_ident(ctx); + oberon_def(ctx, &export, &read_only); newtype = oberon_find_object(ctx -> decl, name, 0); if(newtype == NULL) { - newtype = oberon_define_object(ctx -> decl, name, OBERON_CLASS_TYPE); + newtype = oberon_define_object(ctx -> decl, name, OBERON_CLASS_TYPE, export, read_only); newtype -> type = oberon_new_type_ptr(OBERON_TYPE_VOID); assert(newtype -> type); } @@ -1913,6 +1925,9 @@ oberon_type_decl(oberon_context_t * ctx) { oberon_error(ctx, "mult definition - already linked"); } + + newtype -> export = export; + newtype -> read_only = read_only; } oberon_assert_token(ctx, EQUAL); @@ -2348,7 +2363,7 @@ oberon_import_module(oberon_context_t * ctx, char * alias, char * name) } oberon_object_t * ident; - ident = oberon_define_object(ctx -> decl, alias, OBERON_CLASS_MODULE); + ident = oberon_define_object(ctx -> decl, alias, OBERON_CLASS_MODULE, 0, 0); ident -> module = m; } @@ -2396,7 +2411,7 @@ oberon_parse_module(oberon_context_t * ctx) ctx -> mod -> name = name1; oberon_object_t * this_module; - this_module = oberon_define_object(ctx -> decl, name1, OBERON_CLASS_MODULE); + this_module = oberon_define_object(ctx -> decl, name1, OBERON_CLASS_MODULE, 0, 0); this_module -> module = ctx -> mod; if(ctx -> token == IMPORT) @@ -2409,13 +2424,12 @@ oberon_parse_module(oberon_context_t * ctx) oberon_decl_seq(ctx); oberon_generate_begin_module(ctx); - if(ctx -> token == BEGIN) { oberon_assert_token(ctx, BEGIN); oberon_statement_seq(ctx); - oberon_generate_end_module(ctx); } + oberon_generate_end_module(ctx); oberon_assert_token(ctx, END); name2 = oberon_assert_ident(ctx); @@ -2442,17 +2456,17 @@ 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); + oberon_define_type(ctx -> world_scope, "INTEGER", ctx -> int_type, 1, 0); ctx -> bool_type = oberon_new_type_boolean(sizeof(int)); - oberon_define_type(ctx -> world_scope, "BOOLEAN", ctx -> bool_type); + oberon_define_type(ctx -> world_scope, "BOOLEAN", ctx -> bool_type, 1, 0); } static void oberon_new_intrinsic(oberon_context_t * ctx, char * name, GenerateFuncCallback f, GenerateProcCallback p) { oberon_object_t * proc; - proc = oberon_define_object(ctx -> decl, name, OBERON_CLASS_PROC); + proc = oberon_define_object(ctx -> decl, name, OBERON_CLASS_PROC, 1, 0); proc -> sysproc = 1; proc -> genfunc = f; proc -> genproc = p; diff --git a/oberon.h b/oberon.h index 9956fdc..86f95de 100644 --- a/oberon.h +++ b/oberon.h @@ -157,6 +157,8 @@ struct oberon_object_s { char * name; int class; + int export; + int read_only; int local; int linked; diff --git a/test.c b/test.c index 297da8d..5b2fc48 100644 --- a/test.c +++ b/test.c @@ -7,33 +7,19 @@ static char source_test[] = "MODULE Test;" "IMPORT I := Imported;" - "TYPE" - " Callback = PROCEDURE() : INTEGER;" - "" "VAR" - " cb : Callback;" - " i : INTEGER;" - " r : I.Rider;" - "" - "PROCEDURE RelBack;" + " x : I.Rider;" "BEGIN" - " i := 666;" - "END RelBack;" - "" - "BEGIN;" - " i := ABS(-1);" - " i := cb();" - " RelBack;" - " I.Ln;" + " I.Ln;" "END Test." ; static char source_imported[] = "MODULE Imported;" "TYPE" - " Rider = RECORD i : INTEGER; END;" + " Rider* = RECORD i : INTEGER; END;" "" - "PROCEDURE Ln;" + "PROCEDURE Ln*;" "END Ln;" "" "BEGIN;" diff --git a/test/.gitignore b/test/.gitignore deleted file mode 100644 index 345e6ae..0000000 --- a/test/.gitignore +++ /dev/null @@ -1 +0,0 @@ -Test -- 2.29.2