DEADSOFTWARE

Исправлены VAR-параметры, добавлены модули Files и Strings
authorDeaDDooMER <deaddoomer@deadsoftware.ru>
Thu, 17 Aug 2017 19:43:47 +0000 (22:43 +0300)
committerDeaDDooMER <deaddoomer@deadsoftware.ru>
Thu, 17 Aug 2017 19:43:47 +0000 (22:43 +0300)
Files.obn [new file with mode: 0644]
Strings.obn [new file with mode: 0644]
Test.obn
Test19.obn [new file with mode: 0644]
make.sh
notes
obn-run-tests.sh
proguard.conf
rtl/Files.java [new file with mode: 0644]
rtl/SYSTEM.java
src/oberon.c

diff --git a/Files.obn b/Files.obn
new file mode 100644 (file)
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 (file)
index 0000000..0c78543
--- /dev/null
@@ -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.
index 69389899cad06413cb1824a0829eef066767864d..c80345e560b5ed362e18a58a9a1abc772b084c44 100644 (file)
--- 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 (file)
index 0000000..a8f63a0
--- /dev/null
@@ -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 69ffaeee0d35eda542db9c1198480c31c6988241..350fbce526068f057a79249ab6de777ef02ad216 100755 (executable)
--- 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 3db7888cfe034e8b6d9a561489d8c581d380e4cb..a07b3b5a196e2a6711a7b8162612eec4f91a3170 100644 (file)
--- 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)
index 70a1ea639fa66156b76136ee13d8fe1a3ae4b05d..7011dc59ada134164831c80e12cf2bb077d5bdc9 100755 (executable)
@@ -90,3 +90,5 @@ makefail Test17F
 makecomp Test18A
 makefail Test18B
 makefail Test18C
+
+maketest Test19
index 155da5b6a8fbb500cd58af16eafbf25d8363c95d..b341d16d559b34b39e0d23bf70658a6d1775fe32 100644 (file)
@@ -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 (file)
index 0000000..b557fe8
--- /dev/null
@@ -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()
+       {
+
+       }
+}
index 28d8c466df99d528685380520b5429a2248a18e5..ce1b50621e447042154ad9d70dc11136278673ff 100644 (file)
@@ -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);
index 0fff8d7ba4c791846d662f1a6e728c6b2fbfe883..365f47d6a107ac047dbe13e5f3293a5ea138123d 100644 (file)
@@ -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;
 }