summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 7b989fe)
raw | patch | inline | side by side (parent: 7b989fe)
author | DeaDDooMER <deaddoomer@deadsoftware.ru> | |
Thu, 17 Aug 2017 22:14:49 +0000 (01:14 +0300) | ||
committer | DeaDDooMER <deaddoomer@deadsoftware.ru> | |
Thu, 17 Aug 2017 22:14:49 +0000 (01:14 +0300) |
diff --git a/Files.obn b/Files.obn
index 873866687e733ff8b031b030fdc7e87cee65be15..651bff944c0c527489e94f1d461c970d502fe39a 100644 (file)
--- a/Files.obn
+++ b/Files.obn
MODULE Files;
+IMPORT SYSTEM;
+
TYPE
File* = POINTER TO Handle;
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);
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);
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 c80345e560b5ed362e18a58a9a1abc772b084c44..fa347cddf19074ac48f9ac84d99c4993074f5aef 100644 (file)
--- a/Test.obn
+++ b/Test.obn
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 a8f63a0c43d1dde37dab4f9e124395178779068a..323d52829abcee47f89ae98fcde1b5c447a4e8c4 100644 (file)
--- a/Test19.obn
+++ b/Test19.obn
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 b341d16d559b34b39e0d23bf70658a6d1775fe32..3adc0fef4708243054afc1d08219952774f8188a 100644 (file)
--- a/proguard.conf
+++ b/proguard.conf
-dontobfuscate
-dontoptimize
--dontwarn Files**
-keep class ** { void BEGIN(); }
index 27f1c56390802b409621ef18779d6781c6f10595..478a92c6f38cb91acb3c03c3f939c3158023d5f3 100644 (file)
break;
}
break;
+ case OBERON_TYPE_SYSTEM_BYTE:
+ return new_string("B");
+ break;
case OBERON_TYPE_REAL:
switch(type -> size)
{
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:
break;
}
break;
+ case OBERON_TYPE_SYSTEM_BYTE:
+ return 'b';
+ break;
case OBERON_TYPE_CHAR:
switch(size)
{
index 24268e178a7474cf893ec5836b437fedc6197bcf..1ba25c9afe28ee69e957cb10b6c9572814f06176 100644 (file)
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;
{
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)
{
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 703ba6c5e4b4b6eb88fa9bb3f98d94973fd9e56e..c1454d433ff77e38c97ad35569bec8e8a4dd2a15 100644 (file)
--- a/src/oberon-internals.h
+++ b/src/oberon-internals.h
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 *);
struct oberon_module_t
{
char * name;
- int ready;
+ bool ready;
+ bool intrinsic;
oberon_scope_t * decl;
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;
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;
index 60b37c40e76895feb562ccfda9930c8462cd8440..a99a04d37c70652f3add5a483b0ca5b0bf1edbfd 100644 (file)
--- a/src/oberon-type-compat.c
+++ b/src/oberon-type-compat.c
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)
{
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
/* Для параметров-переменных 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
index 904a89c4577de0ee9b270281103e3391b0530e0d..92b67503c78ffe37cfffa3b85c0adf543b648b18 100644 (file)
--- a/src/oberon-type-compat.h
+++ b/src/oberon-type-compat.h
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 365f47d6a107ac047dbe13e5f3293a5ea138123d..0bbeec188b3d5b4e7fafe506285a9d096cb809b7 100644 (file)
--- a/src/oberon.c
+++ b/src/oberon.c
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;
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
// =======================================================================
{
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
{
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)
{
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);
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;
}