From 1233fb1d5d8f67a8f5e970386c1c4cbb6691ec04 Mon Sep 17 00:00:00 2001 From: DeaDDooMER Date: Fri, 18 Aug 2017 01:14: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=BC=D0=BE=D0=B4=D1=83=D0=BB=D1=8C=20SYSTEM=20=D0=B8=20?= =?utf8?q?=D1=82=D0=B8=D0=BF=20SYSTEM.TYPE?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- Files.obn | 14 ++-- Test.obn | 7 +- Test19.obn | 7 +- proguard.conf | 1 - src/backends/jvm/generator-jvm-basic.c | 7 ++ src/backends/jvm/generator-jvm.c | 13 +++- src/oberon-internals.h | 11 ++- src/oberon-type-compat.c | 29 +++++++- src/oberon-type-compat.h | 3 + src/oberon.c | 93 +++++++++++++++++++------- 10 files changed, 138 insertions(+), 47 deletions(-) diff --git a/Files.obn b/Files.obn index 8738666..651bff9 100644 --- a/Files.obn +++ b/Files.obn @@ -1,5 +1,7 @@ MODULE Files; +IMPORT SYSTEM; + TYPE File* = POINTER TO Handle; @@ -46,8 +48,7 @@ BEGIN RETURN 0 END Pos; PROCEDURE Base*(VAR r : Rider) : File; BEGIN RETURN NIL END Base; -(* PROCEDURE Read*(VAR r : Rider; VAR x : SYSTEM.BYTE); *) -PROCEDURE Read*(VAR r : Rider; VAR x : SHORTINT); +PROCEDURE Read*(VAR r : Rider; VAR x : SYSTEM.BYTE); END Read; PROCEDURE ReadInt*(VAR R : Rider; VAR x : INTEGER); @@ -74,12 +75,10 @@ END ReadSet; PROCEDURE ReadBool*(VAR R : Rider; VAR x : BOOLEAN); END ReadBool; -(* PROCEDURE ReadBytes*(VAR r : Rider; VAR x : ARRAY OF SYSTEM.BYTE; n : LONGINT); *) -PROCEDURE ReadBytes (VAR r : Rider; VAR x : ARRAY OF SHORTINT; n : LONGINT); +PROCEDURE ReadBytes*(VAR r : Rider; VAR x : ARRAY OF SYSTEM.BYTE; n : LONGINT); END ReadBytes; -(* PROCEDURE Write*(VAR r: Rider; x: SYSTEM.BYTE); *) -PROCEDURE Write*(VAR r : Rider; x : SHORTINT); +PROCEDURE Write*(VAR r: Rider; x: SYSTEM.BYTE); END Write; PROCEDURE WriteInt*(VAR R : Rider; x : INTEGER); @@ -106,8 +105,7 @@ END WriteSet; PROCEDURE WriteBool*(VAR R : Rider; x : BOOLEAN); END WriteBool; -(* PROCEDURE WriteBytes*(VAR r : Rider; VAR x : ARRAY OF SYSTEM.BYTE; n : LONGINT); *) -PROCEDURE WriteBytes*(VAR r : Rider; VAR x : ARRAY OF SHORTINT; n : LONGINT); +PROCEDURE WriteBytes*(VAR r : Rider; VAR x : ARRAY OF SYSTEM.BYTE; n : LONGINT); END WriteBytes; END Files. diff --git a/Test.obn b/Test.obn index c80345e..fa347cd 100644 --- a/Test.obn +++ b/Test.obn @@ -5,16 +5,17 @@ IMPORT Files, Out; VAR f : Files.File; r : Files.Rider; - i, len : LONGINT; - g : SHORTINT; + len : LONGINT; x : POINTER TO ARRAY OF CHAR; BEGIN f := Files.Old("Test.obn"); ASSERT(f # NIL); Files.Set(r, f, 0); + len := Files.Length(f); NEW(x, len + 1); - FOR i := 0 TO len - 1 DO Files.Read(r, g); x[i] := CHR(g) END; + + Files.ReadBytes(r, x, len); Out.String(x^); Out.Ln; END Test. diff --git a/Test19.obn b/Test19.obn index a8f63a0..323d528 100644 --- a/Test19.obn +++ b/Test19.obn @@ -5,17 +5,18 @@ IMPORT Files, Out; VAR f : Files.File; r : Files.Rider; - i, len : LONGINT; - g : SHORTINT; + len : LONGINT; x : POINTER TO ARRAY OF CHAR; BEGIN f := Files.Old("Test19.obn"); ASSERT(f # NIL); Files.Set(r, f, 0); + len := Files.Length(f); NEW(x, len + 1); - FOR i := 0 TO len - 1 DO Files.Read(r, g); x[i] := CHR(g) END; + + Files.ReadBytes(r, x, len); Out.String(x^); Out.Ln; END Test19. diff --git a/proguard.conf b/proguard.conf index b341d16..3adc0fe 100644 --- a/proguard.conf +++ b/proguard.conf @@ -2,5 +2,4 @@ -dontobfuscate -dontoptimize --dontwarn Files** -keep class ** { void BEGIN(); } diff --git a/src/backends/jvm/generator-jvm-basic.c b/src/backends/jvm/generator-jvm-basic.c index 27f1c56..478a92c 100644 --- a/src/backends/jvm/generator-jvm-basic.c +++ b/src/backends/jvm/generator-jvm-basic.c @@ -77,6 +77,9 @@ jvm_get_descriptor(oberon_type_t * type) break; } break; + case OBERON_TYPE_SYSTEM_BYTE: + return new_string("B"); + break; case OBERON_TYPE_REAL: switch(type -> size) { @@ -187,6 +190,7 @@ jvm_get_prefix(oberon_type_t * type) case OBERON_TYPE_INTEGER: case OBERON_TYPE_CHAR: case OBERON_TYPE_SET: + case OBERON_TYPE_SYSTEM_BYTE: return (size <= 4) ? ('i') : ('l'); break; case OBERON_TYPE_PROCEDURE: @@ -237,6 +241,9 @@ jvm_get_postfix(oberon_type_t * type) break; } break; + case OBERON_TYPE_SYSTEM_BYTE: + return 'b'; + break; case OBERON_TYPE_CHAR: switch(size) { diff --git a/src/backends/jvm/generator-jvm.c b/src/backends/jvm/generator-jvm.c index 24268e1..1ba25c9 100644 --- a/src/backends/jvm/generator-jvm.c +++ b/src/backends/jvm/generator-jvm.c @@ -492,6 +492,7 @@ oberon_generator_init_type(oberon_context_t * ctx, oberon_type_t * type) case OBERON_TYPE_STRING: case OBERON_TYPE_SET: case OBERON_TYPE_NIL: + case OBERON_TYPE_SYSTEM_BYTE: break; case OBERON_TYPE_RECORD: m = type -> module -> gen_mod; @@ -750,7 +751,10 @@ oberon_generate_begin_module(oberon_context_t * ctx) { if(x -> class == OBERON_CLASS_MODULE) { - jvm_generate(p, 0, 0, "invokestatic %s/BEGIN()V", x -> module -> gen_mod -> class -> full_name); + if(!x -> module -> intrinsic) + { + jvm_generate(p, 0, 0, "invokestatic %s/BEGIN()V", x -> module -> gen_mod -> class -> full_name); + } } else if(x -> class == OBERON_CLASS_VAR) { @@ -1044,13 +1048,16 @@ push_varptr(gen_proc_t * p, oberon_expr_t * expr) jvm_generate_ldst_prepare(p, expr -> item.var -> gen_var); break; case MODE_INDEX: - push_item(p, (oberon_item_t *) expr -> item.parent); + push_item(p, expr -> item.parent); push_expr(p, expr -> item.args); break; case MODE_FIELD: - push_item(p, (oberon_item_t *) expr -> item.parent); + push_item(p, expr -> item.parent); jvm_generate_ldst_prepare(p, expr -> item.var -> gen_var); break; + case MODE_DEREF: + push_varptr(p, (oberon_expr_t *) expr -> item.parent); + break; default: gen_error("push_varptr: wat %i", expr -> item.mode); break; diff --git a/src/oberon-internals.h b/src/oberon-internals.h index 703ba6c..c1454d4 100644 --- a/src/oberon-internals.h +++ b/src/oberon-internals.h @@ -47,7 +47,8 @@ enum oberon_type_kind OBERON_TYPE_CHAR, OBERON_TYPE_STRING, OBERON_TYPE_SET, - OBERON_TYPE_NIL + OBERON_TYPE_NIL, + OBERON_TYPE_SYSTEM_BYTE }; typedef oberon_expr_t * (*GenerateFuncCallback)(oberon_context_t *, int, oberon_expr_t *); @@ -118,7 +119,8 @@ struct oberon_object_t struct oberon_module_t { char * name; - int ready; + bool ready; + bool intrinsic; oberon_scope_t * decl; @@ -148,6 +150,7 @@ struct oberon_context_t oberon_module_t * mod; /*** END PARSER DATA ***/ + oberon_scope_t * world_scope; oberon_type_t * notype_type; oberon_type_t * nil_type; oberon_type_t * bool_type; @@ -161,7 +164,9 @@ struct oberon_context_t oberon_type_t * string_type; oberon_type_t * set_type; - oberon_scope_t * world_scope; + oberon_module_t * system_module; + oberon_type_t * system_byte_type; + oberon_module_t * module_list; ModuleImportCallback import_module; gen_context_t * gen_context; diff --git a/src/oberon-type-compat.c b/src/oberon-type-compat.c index 60b37c4..a99a04d 100644 --- a/src/oberon-type-compat.c +++ b/src/oberon-type-compat.c @@ -39,6 +39,18 @@ oberon_is_integer_type(oberon_type_t * t) return t -> class == OBERON_TYPE_INTEGER; } +bool +oberon_is_system_byte_type(oberon_type_t * t) +{ + return t -> class == OBERON_TYPE_SYSTEM_BYTE; +} + +bool +oberon_is_byte_type(oberon_type_t * t) +{ + return oberon_is_integer_type(t) && t -> size == 1; +} + bool oberon_is_number_type(oberon_type_t * t) { @@ -100,6 +112,12 @@ oberon_is_array_of_char_type(oberon_type_t * t) return oberon_is_array_type(t) && oberon_is_char_type(t -> base); } +bool +oberon_is_array_of_system_byte_type(oberon_type_t * t) +{ + return oberon_is_array_type(t) && oberon_is_system_byte_type(t -> base); +} + bool oberon_is_nil_type(oberon_type_t * t) { @@ -272,6 +290,8 @@ oberon_is_assignment_compatible_expressions(oberon_expr_t * e, oberon_type_t * T /* совпадают с параметрами Tv. */ /* Доп: Tv - символ, е - строковая константа из одного символа */ + /* SYSTEM: переменным типа BYTE можно присваивать значения переменных типа CHAR или SHORTINT. */ + oberon_type_t * Te = e -> result; /* @@ -296,7 +316,8 @@ oberon_is_assignment_compatible_expressions(oberon_expr_t * e, oberon_type_t * T || ((oberon_is_pointer_type(Tv) || oberon_is_procedure_type(Tv)) && oberon_is_nil_type(Te)) || (oberon_is_array_of_char_type(Tv) && !oberon_is_open_array(Tv) && oberon_is_const_string(e) && (strlen(e -> item.string) < Tv -> size)) || (oberon_is_procedure_type(Tv) && e -> is_item && e -> item.var -> class == OBERON_CLASS_PROC && oberon_is_some_procedure_signatures(Tv, e -> result)) - || (oberon_is_char_type(Tv) && oberon_is_const_string(e) && strlen(e -> item.string) == 1); + || (oberon_is_char_type(Tv) && oberon_is_const_string(e) && strlen(e -> item.string) == 1) + || (oberon_is_system_byte_type(Tv) && (oberon_is_char_type(Te) || oberon_is_byte_type(Te))); } static bool @@ -429,8 +450,12 @@ oberon_is_compatible_var_param(oberon_type_t * Tf, oberon_type_t * Ta) /* Для параметров-переменных Ta и Tf должны быть одинаковыми типами */ /* или Tf должен быть типом запись, а Ta - расширением Tf. */ + /* SYSTEM: Если формальный параметр-переменная имеет тип ARRAY OF BYTE, */ + /* то соответствующий фактический параметр может иметь любой тип. */ + return oberon_is_some_types(Tf, Ta) - || (oberon_is_record_type(Tf) && oberon_extension_of(Ta, Tf)); + || (oberon_is_record_type(Tf) && oberon_extension_of(Ta, Tf)) + || (oberon_is_array_of_system_byte_type(Tf)); } void diff --git a/src/oberon-type-compat.h b/src/oberon-type-compat.h index 904a89c..92b6750 100644 --- a/src/oberon-type-compat.h +++ b/src/oberon-type-compat.h @@ -10,6 +10,9 @@ oberon_is_real_type(oberon_type_t * t); bool oberon_is_integer_type(oberon_type_t * t); +bool +oberon_is_system_byte_type(oberon_type_t * t); + bool oberon_is_number_type(oberon_type_t * t); diff --git a/src/oberon.c b/src/oberon.c index 365f47d..0bbeec1 100644 --- a/src/oberon.c +++ b/src/oberon.c @@ -261,7 +261,6 @@ oberon_find_object_in_list(oberon_object_t * list, char * name) oberon_object_t * x = list; while(x -> next && strcmp(x -> next -> name, name) != 0) { - printf("inlist: '%s' != '%s'\n", x -> next -> name, name); x = x -> next; } return x -> next; @@ -290,7 +289,6 @@ oberon_find_object(oberon_scope_t * scope, char * name, bool check_it) static oberon_object_t * oberon_create_object(oberon_scope_t * scope, char * name, int class, bool export, bool read_only) { - printf("oberon_create_object: '%s'\n", name); oberon_object_t * newvar = GC_MALLOC(sizeof *newvar); memset(newvar, 0, sizeof *newvar); newvar -> name = name; @@ -318,7 +316,6 @@ oberon_define_object(oberon_scope_t * scope, char * name, int class, bool export oberon_object_t * x = scope -> list; while(x -> next && strcmp(x -> next -> name, name) != 0) { - printf("inlist: '%s' != '%s'\n", x -> next -> name, name); x = x -> next; } @@ -334,16 +331,6 @@ oberon_define_object(oberon_scope_t * scope, char * name, int class, bool export return newvar; } -static oberon_object_t * -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, false, false); - id -> type = type; - oberon_generator_init_type(scope -> ctx, type); - return id; -} - // ======================================================================= // SCANER // ======================================================================= @@ -1137,7 +1124,8 @@ oberon_autocast_call(oberon_context_t * ctx, oberon_item_t * desig) { oberon_check_compatible_var_param(ctx, param -> type, arg -> result); } - casted[i] = oberon_cast_expr(ctx, arg, param -> type); + casted[i] = arg; + //casted[i] = oberon_cast_expr(ctx, arg, param -> type); } else { @@ -4476,34 +4464,36 @@ register_default_types(oberon_context_t * ctx) oberon_generator_init_type(ctx, ctx -> string_type); ctx -> bool_type = oberon_new_type_boolean(); - oberon_define_type(ctx -> world_scope, "BOOLEAN", ctx -> bool_type, 1); + oberon_generator_init_type(ctx, ctx -> bool_type); ctx -> char_type = oberon_new_type_char(1); - oberon_define_type(ctx -> world_scope, "CHAR", ctx -> char_type, 1); + oberon_generator_init_type(ctx, ctx -> char_type); ctx -> byte_type = oberon_new_type_integer(1); - oberon_define_type(ctx -> world_scope, "SHORTINT", ctx -> byte_type, 1); + oberon_generator_init_type(ctx, ctx -> byte_type); ctx -> shortint_type = oberon_new_type_integer(2); - oberon_define_type(ctx -> world_scope, "INTEGER", ctx -> shortint_type, 1); + oberon_generator_init_type(ctx, ctx -> shortint_type); ctx -> int_type = oberon_new_type_integer(4); - oberon_define_type(ctx -> world_scope, "LONGINT", ctx -> int_type, 1); + oberon_generator_init_type(ctx, ctx -> int_type); ctx -> longint_type = oberon_new_type_integer(8); - oberon_define_type(ctx -> world_scope, "HUGEINT", ctx -> longint_type, 1); + oberon_generator_init_type(ctx, ctx -> longint_type); ctx -> real_type = oberon_new_type_real(4); - oberon_define_type(ctx -> world_scope, "REAL", ctx -> real_type, 1); + oberon_generator_init_type(ctx, ctx -> real_type); ctx -> longreal_type = oberon_new_type_real(8); - oberon_define_type(ctx -> world_scope, "LONGREAL", ctx -> longreal_type, 1); + oberon_generator_init_type(ctx, ctx -> longreal_type); ctx -> set_type = oberon_new_type_set(4); - oberon_define_type(ctx -> world_scope, "SET", ctx -> set_type, 1); - + oberon_generator_init_type(ctx, ctx -> set_type); + ctx -> system_byte_type = oberon_new_type_ptr(OBERON_TYPE_SYSTEM_BYTE); + oberon_generator_init_type(ctx, ctx -> system_byte_type); + /* LONG / SHORT support */ ctx -> byte_type -> shorter = NULL; ctx -> byte_type -> longer = ctx -> shortint_type; @@ -4534,6 +4524,41 @@ oberon_new_intrinsic(oberon_context_t * ctx, char * name, GenerateFuncCallback f proc -> type -> genproc = p; } +static void oberon_new_intrinsic_type(oberon_context_t * ctx, char * name, oberon_type_t * type) +{ + oberon_object_t * id; + id = oberon_define_object(ctx -> decl, name, OBERON_CLASS_TYPE, true, false, false); + id -> type = type; +} + +static void +oberon_begin_intrinsic_module(oberon_context_t * ctx, char * name, oberon_module_t ** m) +{ + oberon_scope_t * module_scope; + module_scope = oberon_open_scope(ctx); + + oberon_module_t * module; + module = GC_MALLOC(sizeof *module); + memset(module, 0, sizeof *module); + module -> name = name; + module -> intrinsic = true; + module -> decl = module_scope; + module -> next = ctx -> module_list; + + ctx -> mod = module; + ctx -> module_list = module; + + *m = module; +} + +static void +oberon_end_intrinsic_module(oberon_context_t * ctx, oberon_module_t * m) +{ + oberon_close_scope(m -> decl); + m -> ready = true; + ctx -> mod = NULL; +} + oberon_context_t * oberon_create_context(ModuleImportCallback import_module) { @@ -4548,12 +4573,24 @@ oberon_create_context(ModuleImportCallback import_module) oberon_generator_init_context(ctx); + /* Types */ register_default_types(ctx); /* Constants */ oberon_new_const(ctx, "TRUE", oberon_make_boolean(ctx, true)); oberon_new_const(ctx, "FALSE", oberon_make_boolean(ctx, false)); + /* Types */ + oberon_new_intrinsic_type(ctx, "BOOLEAN", ctx -> bool_type); + oberon_new_intrinsic_type(ctx, "CHAR", ctx -> char_type); + oberon_new_intrinsic_type(ctx, "SHORTINT", ctx -> byte_type); + oberon_new_intrinsic_type(ctx, "INTEGER", ctx -> shortint_type); + oberon_new_intrinsic_type(ctx, "LONGINT", ctx -> int_type); + oberon_new_intrinsic_type(ctx, "HUGEINT", ctx -> longint_type); + oberon_new_intrinsic_type(ctx, "REAL", ctx -> real_type); + oberon_new_intrinsic_type(ctx, "LONGREAL", ctx -> longreal_type); + oberon_new_intrinsic_type(ctx, "SET", ctx -> set_type); + /* Functions */ oberon_new_intrinsic(ctx, "ABS", oberon_make_abs_call, NULL); oberon_new_intrinsic(ctx, "ASH", oberon_make_ash_call, NULL); @@ -4579,6 +4616,14 @@ oberon_create_context(ModuleImportCallback import_module) oberon_new_intrinsic(ctx, "INCL", NULL, oberon_make_incl_call); oberon_new_intrinsic(ctx, "NEW", NULL, oberon_make_new_call); + /* MODULE SYSTEM */ + oberon_begin_intrinsic_module(ctx, "SYSTEM", &ctx -> system_module); + + /* Types */ + oberon_new_intrinsic_type(ctx, "BYTE", ctx -> system_byte_type); + + oberon_end_intrinsic_module(ctx, ctx -> system_module); + return ctx; } -- 2.29.2