From 7b989fe6cfb3cf6e529b888bb6827714c45c62c6 Mon Sep 17 00:00:00 2001 From: DeaDDooMER Date: Thu, 17 Aug 2017 22:43:47 +0300 Subject: [PATCH] =?utf8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB=D0=B5?= =?utf8?q?=D0=BD=D1=8B=20VAR-=D0=BF=D0=B0=D1=80=D0=B0=D0=BC=D0=B5=D1=82?= =?utf8?q?=D1=80=D1=8B,=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD?= =?utf8?q?=D1=8B=20=D0=BC=D0=BE=D0=B4=D1=83=D0=BB=D0=B8=20Files=20=D0=B8?= =?utf8?q?=20Strings?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- Files.obn | 113 +++++++++++++++ Strings.obn | 52 +++++++ Test.obn | 31 ++--- Test19.obn | 22 +++ make.sh | 2 +- notes | 4 +- obn-run-tests.sh | 2 + proguard.conf | 2 + rtl/Files.java | 353 +++++++++++++++++++++++++++++++++++++++++++++++ rtl/SYSTEM.java | 9 ++ src/oberon.c | 9 +- 11 files changed, 578 insertions(+), 21 deletions(-) create mode 100644 Files.obn create mode 100644 Strings.obn create mode 100644 Test19.obn create mode 100644 rtl/Files.java diff --git a/Files.obn b/Files.obn new file mode 100644 index 0000000..8738666 --- /dev/null +++ b/Files.obn @@ -0,0 +1,113 @@ +MODULE Files; + +TYPE + File* = POINTER TO Handle; + + Handle = RECORD END; + + Rider* = RECORD + eof* : BOOLEAN; + res* : LONGINT; + END; + +PROCEDURE Old*(name : ARRAY OF CHAR) : File; +BEGIN RETURN NIL END Old; + +PROCEDURE New*(name : ARRAY OF CHAR) : File; +BEGIN RETURN NIL END New; + +PROCEDURE Register*(f : File); +END Register; + +PROCEDURE Close*(f : File); +END Close; + +PROCEDURE Purge*(f : File); +END Purge; + +PROCEDURE Delete*(name : ARRAY OF CHAR; VAR res : INTEGER); +END Delete; + +PROCEDURE Rename*(old, new : ARRAY OF CHAR; VAR res : INTEGER); +END Rename; + +PROCEDURE Length*(f : File) : LONGINT; +BEGIN RETURN 0 END Length; + +PROCEDURE GetDate*(f : File; VAR t, d : LONGINT); +END GetDate; + +PROCEDURE Set*(VAR r : Rider; f : File; pos : LONGINT); +END Set; + +PROCEDURE Pos*(VAR r : Rider) : LONGINT; +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); +END Read; + +PROCEDURE ReadInt*(VAR R : Rider; VAR x : INTEGER); +END ReadInt; + +PROCEDURE ReadLInt*(VAR R : Rider; VAR x : LONGINT); +END ReadLInt; + +PROCEDURE ReadReal*(VAR R : Rider; VAR x : REAL); +END ReadReal; + +PROCEDURE ReadLReal*(VAR R : Rider; VAR x : LONGREAL); +END ReadLReal; + +PROCEDURE ReadNum*(VAR R : Rider; VAR x : LONGINT); +END ReadNum; + +PROCEDURE ReadString*(VAR R : Rider; VAR x : ARRAY OF CHAR); +END ReadString; + +PROCEDURE ReadSet*(VAR R : Rider; VAR x : SET); +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); +END ReadBytes; + +(* PROCEDURE Write*(VAR r: Rider; x: SYSTEM.BYTE); *) +PROCEDURE Write*(VAR r : Rider; x : SHORTINT); +END Write; + +PROCEDURE WriteInt*(VAR R : Rider; x : INTEGER); +END WriteInt; + +PROCEDURE WriteLInt*(VAR R : Rider; x : LONGINT); +END WriteLInt; + +PROCEDURE WriteReal*(VAR R : Rider; x : REAL); +END WriteReal; + +PROCEDURE WriteLReal*(VAR R : Rider; x : LONGREAL); +END WriteLReal; + +PROCEDURE WriteNum*(VAR R : Rider; x : LONGINT); +END WriteNum; + +PROCEDURE WriteString*(VAR R : Rider; x : ARRAY OF CHAR); +END WriteString; + +PROCEDURE WriteSet*(VAR R : Rider; x : SET); +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); +END WriteBytes; + +END Files. diff --git a/Strings.obn b/Strings.obn new file mode 100644 index 0000000..0c78543 --- /dev/null +++ b/Strings.obn @@ -0,0 +1,52 @@ +MODULE Strings; + +PROCEDURE Length*(s : ARRAY OF CHAR) : INTEGER; +VAR + i : INTEGER; +BEGIN + WHILE s[i] # 0X DO INC(i) END; + RETURN i; +END Length; + +(* +PROCEDURE Insert*(source : ARRAY OF CHAR; pos : INTEGER; VAR dest : ARRAY OF CHAR); +END Insert; +*) + +(* +PROCEDURE Append*(extra : ARRAY OF CHAR; VAR dest : ARRAY OF CHAR); +END Append; +*) + +(* +PROCEDURE Delete*(VAR s : ARRAY OF CHAR; pos, n : INTEGER); +END Delete; +*) + +(* +PROCEDURE Replace*(source : ARRAY OF CHAR; pos : INTEGER; VAR dest : ARRAY OF CHAR); +END Replace; +*) + +(* +PROCEDURE Extract*(source : ARRAY OF CHAR; pos, n : INTEGER; VAR dest : ARRAY OF CHAR); +END Extract; +*) + +(* +PROCEDURE Pos*(pattern, s : ARRAY OF CHAR; pos : INTEGER): INTEGER; +BEGIN + RETURN 0; +END Pos; +*) + +PROCEDURE Cap*(VAR s : ARRAY OF CHAR); +VAR + i : INTEGER; +BEGIN + FOR i := 0 TO Length(s) - 1 DO + s[i] := CAP(s[i]) + END; +END Cap; + +END Strings. diff --git a/Test.obn b/Test.obn index 6938989..c80345e 100644 --- a/Test.obn +++ b/Test.obn @@ -1,23 +1,20 @@ MODULE Test; -TYPE - File* = POINTER TO Handle; +IMPORT Files, Out; - Handle = RECORD END; +VAR + f : Files.File; + r : Files.Rider; + i, len : LONGINT; + g : SHORTINT; + x : POINTER TO ARRAY OF CHAR; - Rider* = RECORD - eof* : BOOLEAN; - res* : LONGINT; - END; - -PROCEDURE Old*(name : ARRAY OF CHAR) : File; -BEGIN - RETURN NIL -END Old; - -PROCEDURE New*(name : ARRAY OF CHAR) : File; BEGIN - RETURN NIL -END New; - + 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; + Out.String(x^); Out.Ln; END Test. diff --git a/Test19.obn b/Test19.obn new file mode 100644 index 0000000..a8f63a0 --- /dev/null +++ b/Test19.obn @@ -0,0 +1,22 @@ +MODULE Test19; + +IMPORT Files, Out; + +VAR + f : Files.File; + r : Files.Rider; + i, len : LONGINT; + g : SHORTINT; + 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; + Out.String(x^); Out.Ln; +END Test19. + +Тест модуля Files. Должно выводить содержимое файла Test19.obn. diff --git a/make.sh b/make.sh index 69ffaee..350fbce 100755 --- a/make.sh +++ b/make.sh @@ -3,7 +3,7 @@ set -e CC="gcc" -CFLAGS="-g -Wall -Werror -std=c11 -lm -lgc" +CFLAGS="-g -DGC_DEBUG -std=gnu11 -Wall -Werror -std=c11 -lm -lgc" case "$1" in jvm) diff --git a/notes b/notes index 3db7888..a07b3b5 100644 --- a/notes +++ b/notes @@ -1,3 +1,5 @@ +- Не полная реализация модуля Strings +- Не полная реализация модуля Files - Сделать проверку повторов в CASE. - Сделать нормальную проверку наличия RETURN. - Нет процедур привязанных к типм @@ -15,8 +17,6 @@ 3.6 Underscores in Identifiers 3.7 In-line Exponentiation 5.13 Read only VAR Parameters - 1.2.5 Module Files - 1.2.6 Module Strings 1.2.7 Module Math and MathL - Примеры -5 DIV 3 и -5 MOD 3 работают не так как в (8.2.2) diff --git a/obn-run-tests.sh b/obn-run-tests.sh index 70a1ea6..7011dc5 100755 --- a/obn-run-tests.sh +++ b/obn-run-tests.sh @@ -90,3 +90,5 @@ makefail Test17F makecomp Test18A makefail Test18B makefail Test18C + +maketest Test19 diff --git a/proguard.conf b/proguard.conf index 155da5b..b341d16 100644 --- a/proguard.conf +++ b/proguard.conf @@ -1,4 +1,6 @@ -dontshrink -dontobfuscate -dontoptimize + +-dontwarn Files** -keep class ** { void BEGIN(); } diff --git a/rtl/Files.java b/rtl/Files.java new file mode 100644 index 0000000..b557fe8 --- /dev/null +++ b/rtl/Files.java @@ -0,0 +1,353 @@ +import java.io.*; +import java.util.*; + +class Files +{ + /* File / Handle */ + public static class RECORD0 + { + String fname; + File f, fr; + + public static void $COPY$(RECORD0 src, RECORD0 dst) + { + dst.fname = src.fname; + dst.f = src.f; + dst.fr = src.fr; + } + } + + /* Rider */ + public static class RECORD1 + { + RandomAccessFile raf = null; + RECORD0 base = new RECORD0(); + + public boolean[] eof = new boolean[1]; + public int[] res = new int[1]; + + public static void $COPY$(RECORD1 src, RECORD1 dst) + throws + FileNotFoundException + { + if(src.base == null || src.base.f == null) + { + dst.raf = null; + } + else + { + dst.raf = new RandomAccessFile(src.base.f, "rw"); + } + dst.base = src.base; + dst.eof[0] = src.eof[0]; + dst.res[0] = src.res[0]; + } + } + + public static RECORD0 Old(byte name[]) + { + String fname = SYSTEM.STRING(name); + File f = new File(fname); + + if(!f.exists()) + { + System.out.println("Files.Old: " + fname + " not exists / not a file"); + return null; + } + + RECORD0 obfile = new RECORD0(); + obfile.fname = fname; + obfile.f = f; + obfile.fr = f; + return obfile; + } + + private static String RandomString(int len) + { + Random x = new Random(); + String s = new String(); + for(int i = 0; i < len; i++) + { + s += (char) (x.nextInt(25) + 65); + } + return s; + } + + public static RECORD0 New(byte name[]) + { + String fname = SYSTEM.STRING(name); + String tempname = RandomString(8); + File f, fr; + + try + { + fr = new File(fname); + f = File.createTempFile(tempname, "tmp"); + } + catch(IOException e) + { + return null; + } + + RECORD0 obfile = new RECORD0(); + obfile.fname = fname; + obfile.f = f; + return obfile; + } + + public static void Register(RECORD0 f) + { + f.f.renameTo(f.fr); + } + + public static void Close(RECORD0 f) + { + } + + public static void Purge(RECORD0 f) + throws + IOException + { + f.f.delete(); + f.f.createNewFile(); + } + + public static void Delete(byte name[], short res[], int res$) + { + String fname = SYSTEM.STRING(name); + File f = new File(fname); + res[res$] = f.delete() ? ((short)0) : ((short)1); + } + + public static void Rename(byte old[], byte _new[], short res[], int res$) + { + String foname = SYSTEM.STRING(old); + String fnname = SYSTEM.STRING(_new); + File fo = new File(foname); + File fn = new File(fnname); + res[res$] = fo.renameTo(fn) ? ((short)0) : ((short)1); + } + + public static int Length(RECORD0 f) + { + return (int) f.f.length(); + } + + public static void GetDate(RECORD0 f, int t[], int t$, int d[], int d$) + { + long time = f.f.lastModified(); + Calendar cal = Calendar.getInstance(); + cal.setTimeInMillis(time); + t[t$] = cal.get(Calendar.HOUR_OF_DAY) * 4096 + cal.get(Calendar.MINUTE) * 64 + cal.get(Calendar.SECOND); + d[d$] = cal.get(Calendar.YEAR) * 512 + cal.get(Calendar.MONTH) * 32 + cal.get(Calendar.DAY_OF_WEEK); + } + + public static void Set(RECORD1 r[], int r$, RECORD0 f, int pos) + throws + IOException + { + int len = Length(f); + pos = (pos > len) ? (len) : ((pos < 0) ? (0) : (pos)); + r[r$].eof[0] = true; + + r[r$].base = f; + r[r$].raf = new RandomAccessFile(f.f, "rw"); + r[r$].raf.seek(pos); + r[r$].eof[0] = false; + } + + public static int Pos(RECORD1 r[], int r$) + throws + IOException + { + return (int) r[r$].raf.getFilePointer(); + } + + public static RECORD0 Base(RECORD1 r[], int r$) + { + return r[r$].base; + } + + public static void Read(RECORD1 r[], int r$, byte x[], int x$) + { + try + { + x[x$] = (byte) r[r$].raf.read(); + } + catch(IOException e) + { + r[r$].res[0] = 1; + r[r$].eof[0] = true; + } + } + + public static void ReadInt(RECORD1 R[], int R$, short x[], int x$) + { + try + { + byte[] buf = new byte[2]; + R[R$].res[0] = R[R$].raf.read(buf, 0, 2); + R[R$].eof[0] = (R[R$].res[0] != 0); + x[x$] = (short) (((buf[1] & 0xff) << 8) | (buf[0] & 0xff)); + } + catch(IOException e) + { + R[R$].res[0] = 2; + R[R$].eof[0] = true; + } + } + + public static void ReadLInt(RECORD1 R[], int R$, int x[], int x$) + { + try + { + byte[] buf = new byte[4]; + R[R$].res[0] = R[R$].raf.read(buf, 0, 4); + R[R$].eof[0] = (R[R$].res[0] != 0); + x[x$] = ((buf[3] & 0xff) << 24) | ((buf[2] & 0xff) << 16) | ((buf[1] & 0xff) << 8) | (buf[0] & 0xff); + } + catch(IOException e) + { + R[R$].res[0] = 4; + R[R$].eof[0] = true; + } + } + + public static void ReadReal(RECORD1 R[], int R$, float x[], int x$) + { + try + { + x[x$] = R[R$].raf.readFloat(); + } + catch(IOException e) + { + R[R$].res[0] = 4; + R[R$].eof[0] = true; + } + } + + public static void ReadLReal(RECORD1 R[], int R$, double x[], int x$) + { + try + { + x[x$] = R[R$].raf.readDouble(); + } + catch(IOException e) + { + R[R$].res[0] = 8; + R[R$].eof[0] = true; + } + } + + public static void ReadNum(RECORD1 R[], int R$, int x[], int x$) + { + SYSTEM.TRAP(-3); + } + + public static void ReadString(RECORD1 R[], int R$, byte x[][], int x$) + { + int i = 0; + try + { + int ch; + do { + ch = x[x$][i] = (byte) R[R$].raf.read(); + i += 1; + } while(ch != 0); + } + catch(IOException e) + { + x[x$][i] = 0; + R[R$].res[0] = 1; + R[R$].eof[0] = true; + } + } + + public static void ReadSet(RECORD1 R[], int R$, int x[], int x$) + { + ReadLInt(R, R$, x, x$); + } + + public static void ReadBool(RECORD1 R[], int R$, boolean x[], int x$) + { + try + { + int i = R[R$].raf.read(); + x[x$] = (i != 0); + } + catch(IOException e) + { + R[R$].res[0] = 1; + R[R$].eof[0] = true; + } + } + + public static void ReadBytes(RECORD1 r[], int r$, byte x[][], int x$, int n) + { + try + { + r[r$].res[0] = r[r$].raf.read(x[x$], 0, n); + r[r$].eof[0] = (r[r$].res[0] != 0); + } + catch(IOException e) + { + r[r$].res[0] = n; + r[r$].eof[0] = true; + } + } + + public static void Write(RECORD1 r[], int r$, byte x) + { + SYSTEM.TRAP(-3); + } + + public static void WriteInt(RECORD1 R[], int R$, short x) + { + SYSTEM.TRAP(-3); + } + + public static void WriteLInt(RECORD1 R[], int R$, int x) + { + SYSTEM.TRAP(-3); + } + + public static void WriteReal(RECORD1 R[], int R$, float x) + { + SYSTEM.TRAP(-3); + } + + public static void WriteLReal(RECORD1 R[], int R$, double x) + { + SYSTEM.TRAP(-3); + } + + public static void WriteNum(RECORD1 R[], int R$, int x) + { + SYSTEM.TRAP(-3); + } + + public static void WriteString(RECORD1 R[], int R$, byte x[]) + { + SYSTEM.TRAP(-3); + } + + public static void WriteSet(RECORD1 R[], int R$, int x) + { + SYSTEM.TRAP(-3); + } + + public static void WriteBool(RECORD1 R[], int R$, boolean x) + { + SYSTEM.TRAP(-3); + } + + public static void WriteBytes(RECORD1 r[], int r$, byte[][] x, int x$, int n) + { + SYSTEM.TRAP(-3); + } + + public static void BEGIN() + { + + } +} diff --git a/rtl/SYSTEM.java b/rtl/SYSTEM.java index 28d8c46..ce1b506 100644 --- a/rtl/SYSTEM.java +++ b/rtl/SYSTEM.java @@ -17,6 +17,11 @@ public class SYSTEM return i; } + public static String STRING(byte[] x) + { + return new String(x, 0, LEN(x)); + } + public static void COPY(byte[] x, byte[] v) { int ix = LEN(x); @@ -67,6 +72,10 @@ public class SYSTEM { throw new RuntimeException("WITH TRAP"); } + else if(n == -3) + { + throw new RuntimeException("NOT IMPLEMENTED"); + } else { throw new RuntimeException("TRAP CODE " + n); diff --git a/src/oberon.c b/src/oberon.c index 0fff8d7..365f47d 100644 --- a/src/oberon.c +++ b/src/oberon.c @@ -261,6 +261,7 @@ 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; @@ -289,6 +290,7 @@ 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; @@ -316,6 +318,7 @@ 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; } @@ -1047,10 +1050,14 @@ oberon_cast_expr(oberon_context_t * ctx, oberon_expr_t * expr, oberon_type_t * p cast = oberon_new_item(MODE_CHAR, ctx -> char_type, true); cast -> item.integer = expr -> item.string[0]; } - else + else if(!oberon_is_some_types(expr -> result, pref)) { cast = oberon_new_operator(OP_CAST, pref, expr, NULL); } + else + { + cast = expr; + } return cast; } -- 2.29.2