瀏覽代碼

Out.Real: now works

Arthur Yefimov 3 年之前
父節點
當前提交
5acf885b5e
共有 4 個文件被更改,包括 64 次插入90 次删除
  1. 4 4
      src/In.Mod
  2. 16 18
      src/Out.Mod
  3. 43 67
      src/Reals.Mod
  4. 1 1
      src/edit.sh

+ 4 - 4
src/In.Mod

@@ -202,15 +202,15 @@ END Name;
 PROCEDURE Real*(VAR x: SHORTREAL);
 VAR s: ARRAY 16 OF CHAR;
 BEGIN StartAndSkip; Word(s);
-  x := Reals.Val(s)
-  (*!FIXME Set Done*)
+  x := Reals.Val(s);
+  IF ~Reals.Done THEN Done := FALSE END
 END Real;
 
 PROCEDURE LongReal*(VAR x: REAL);
 VAR s: ARRAY 16 OF CHAR;
 BEGIN StartAndSkip; Word(s);
-  x := Reals.LongVal(s)
-  (*!FIXME Set Done*)
+  x := Reals.LongVal(s);
+  IF ~Reals.Done THEN Done := FALSE END
 END LongReal;
 
 BEGIN

+ 16 - 18
src/Out.Mod

@@ -75,7 +75,7 @@ PROCEDURE Int*(x, n: HUGEINT);
 BEGIN
   negative := x < 0;
   IF x = MIN(HUGEINT) THEN
-    s := "8085774586302733229"; i := 19
+    s := '8085774586302733229'; i := 19
   ELSE
     IF x < 0 THEN x := - x END;
     s[0] := SHORT(CHR(zero + (x MOD 10))); x := x DIV 10;
@@ -131,7 +131,7 @@ BEGIN r := 1.0E0; power := 1.0E1;
   RETURN r
 END Ten;
 
-PROCEDURE -Entier64(x: LONGREAL): SYSTEM.INT64 "(LONGINT)(x)";
+PROCEDURE -Entier64(x: LONGREAL): SYSTEM.INT64 '(LONGINT)(x)';
 
 PROCEDURE RealP(x: LONGREAL; n: INTEGER; long: BOOLEAN);
 (** Writes the long real number x to the end of the output
@@ -190,19 +190,20 @@ BEGIN
       IF e >= 0 THEN x := x / Ten(e) ELSE x := Ten(SHORT(-e)) * x END;
       IF x >= 10.0E0 THEN x := 0.1E0 * x; INC(e) END;
 
-      (* Generate the exponent digits *)
-      en := e < 0; IF en THEN e := SHORT(-e) END;
-      WHILE el > 0 DO digit(e, s, i); e := SHORT(e DIV 10); DEC(el) END;
-      DEC(i); IF en THEN s[i] := '-' ELSE s[i] := '+' END;
-
       (* Scale x to enough significant digits to reliably test for trailing
          zeroes or to the amount of space available, if greater. *)
-      x0 := Ten(SHORT(d-1));
+      x0 := Ten(SHORT(d - 1));
       x  := x0 * x;
       x  := x + 0.5E0; (* Do not combine with previous line as doing so
                           introduces a least significant bit difference
                           between 32 bit and 64 bit builds. *)
-      IF x >= 10.0E0 * x0 THEN x := 0.1E0 * x; INC(e); Char('#') END;
+      IF x >= 10.0E0 * x0 THEN x := 0.1E0 * x; INC(e) END;
+
+      (* Generate the exponent digits *)
+      IF e < 0 THEN en := TRUE; e := SHORT(-e) ELSE en := FALSE END;
+      WHILE el > 0 DO digit(e, s, i); e := SHORT(e DIV 10); DEC(el) END;
+      DEC(i); IF en THEN s[i] := '-' ELSE s[i] := '+' END;
+
       m := Entier64(x)
     END;
 
@@ -224,10 +225,8 @@ BEGIN
   (* Render prepared number from right end of buffer s *)
   IF nn THEN Char('-') END;
   WHILE i < LEN(s) DO Char(s[i]); INC(i) END
-  ;Char('[');Int(e,0);Char(']')
 END RealP;
 
-
 PROCEDURE Real*(x: REAL; n: INTEGER);
 BEGIN RealP(x, n, FALSE)
 END Real;
@@ -240,7 +239,7 @@ END LongReal;
    The value is stored backwards, i.e. least significant digit
    first. n digits are written, with trailing zeros fill.
    On entry x has been scaled to the number of digits required. *)
-PROCEDURE ConvertL*(x: LONGREAL; n: INTEGER; VAR d: ARRAY OF CHAR);
+PROCEDURE ConvertL(x: LONGREAL; n: INTEGER; VAR d: ARRAY OF CHAR);
   VAR i, j, k: HUGEINT;
 BEGIN
   IF x < 0 THEN x := -x END;
@@ -294,17 +293,17 @@ BEGIN e := Expo(x);
   ELSIF e = 255 THEN Chars(' ', n - 3); String('NaN')
   ELSE e := (e - 127) * 77 DIV 256;
     IF x < 0 THEN minus := 1; x := -x ELSE minus := 0 END;
-    IF e >= 0 THEN  (*x >= 1.0,  77/256 = log 2*) x := SHORT(x / Ten(e))
+    IF e >= 0 THEN (* x >= 1.0, 77/256 = log 2 *) x := SHORT(x / Ten(e))
       ELSE (*x < 1.0*) x := SHORT(Ten(-e) * x)
     END;
     IF x >= 10.0 THEN x := 0.1 * x; INC(e) END;
     (* 1 <= x < 10 *)
     IF k + e >= maxD - 1 THEN k := maxD - 1 - e
-    ELSIF k + e < 0 THEN (*k := -e;*) x := 0.0
+    ELSIF k + e < 0 THEN (* k := -e; !FIXME Why??? *) x := 0.0
     END;
     x0 := SHORT(Ten(k + e)); x := x0 * x + 0.5;
     IF x >= 10.0 * x0 THEN INC(e) END;
-    (*e = no. of digits before decimal point*)
+    (* e = no. of digits before decimal point *)
     INC(e); i := k + e; ConvertL(x, i, d);
     IF e > 0 THEN
       IF k > 0 THEN p := 0 ELSE p := 1 END;
@@ -314,14 +313,13 @@ BEGIN e := Expo(x);
       IF k > 0 THEN Char('.'); DigitsOut(k) END
     ELSE
       IF k + e > 0 THEN p := 0 ELSE p := 1 END;
-      (*Char('[');Int(e,0);Char(':');Int(k,0);Char(']');*)
       N := n - k - 2 - minus + p;
       IF (k > 0) & (k + e < 0) THEN DEC(N) END;
       Chars(' ', N);
       IF minus # 0 THEN Char('-') END;
       Char('0');
-      IF k + e > 0 THEN Char('.'); Chars('*', -e); DigitsOut(k + e)
-      ELSIF k > 0 THEN Char('.'); Chars('#', k)
+      IF k + e > 0 THEN Char('.'); Chars('0', -e); DigitsOut(k + e)
+      ELSIF k > 0 THEN Char('.'); Chars('0', k)
       END
     END
   END

+ 43 - 67
src/Reals.Mod

@@ -1,9 +1,11 @@
 MODULE Reals;
 
+TYPE LONGREAL = REAL; (* REAL64 *) REAL = SHORTREAL; (* REAL32 *)
+
 VAR Done-: BOOLEAN;
 
-PROCEDURE Ten(e: INTEGER): SHORTREAL;
-VAR r, power: REAL;
+PROCEDURE Ten(e: INTEGER): REAL;
+VAR r, power: LONGREAL;
 BEGIN r := 1.0; power := 10.0;
   WHILE e > 0 DO
     IF ODD(e) THEN r := r * power END;
@@ -11,76 +13,50 @@ BEGIN r := 1.0; power := 10.0;
   END ;
 RETURN SHORT(r) END Ten;
 
-PROCEDURE Val*(IN s: ARRAY OF CHAR): SHORTREAL;
-VAR p, e: SHORTINT; y, g: SHORTREAL; neg, negE: BOOLEAN;
-BEGIN
+PROCEDURE LongVal*(IN s: ARRAY OF CHAR): LONGREAL;
+VAR p, e: INTEGER; y, g: LONGREAL; neg, negE: BOOLEAN;
+BEGIN Done := FALSE;
   p := 0;
-  WHILE (s[p] = ' ') OR (s[p] = '0') DO INC(p) END;
+  WHILE (s[p] # 0X) & (s[p] <= ' ') DO INC(p) END;
   IF s[p] = '-' THEN neg := TRUE; INC(p) ELSE neg := FALSE END;
-  WHILE (s[p] = ' ') OR (s[p] = '0') DO INC(p) END;
-  
-  y := 0;
-  WHILE ('0' <= s[p]) & (s[p] <= '9') DO
-    y := y * 10 + (ORD(s[p]) - 30H);
-    INC(p)
-  END;
-  IF s[p] = '.' THEN
-    INC(p); g := 1; 
-    WHILE ('0' <= s[p]) & (s[p] <= '9') DO
-      g := g / 10; y := y + g * (ORD(s[p]) - 30H);
-      INC(p)
-    END
-  END;
-  IF (s[p] = 'D') OR (s[p] = 'E') THEN
-    INC(p); e := 0;
-    IF s[p] = '-' THEN negE := TRUE; INC(p) ELSE negE := FALSE END;
-    WHILE (s[p] = '0') DO INC(p) END;
-    WHILE ('0' <= s[p]) & (s[p] <= '9') DO
-      e := SHORT(e * 10 + (ORD(s[p]) - 30H));
-      INC(p)
-    END;
-    IF negE THEN y := y / Ten(e)
-    ELSE y := y * Ten(e)
-    END
-  END;
-  IF neg THEN y := -y END;
-  Done := TRUE ; (*!FIXME*)
-RETURN y END Val;
 
-PROCEDURE LongVal*(IN s: ARRAY OF CHAR): REAL;
-VAR p, e: INTEGER; y, g: REAL; neg, negE: BOOLEAN;
-BEGIN
-  p := 0;
-  WHILE (s[p] = ' ') OR (s[p] = '0') DO INC(p) END;
-  IF s[p] = '-' THEN neg := TRUE; INC(p) ELSE neg := FALSE END;
-  WHILE (s[p] = ' ') OR (s[p] = '0') DO INC(p) END;
-  y := 0;
-  WHILE ('0' <= s[p]) & (s[p] <= '9') DO
-    y := y * 10 + (ORD(s[p]) - 30H);
-    INC(p)
-  END;
-  IF s[p] = '.' THEN
-    INC(p); g := 1; 
-    WHILE ('0' <= s[p]) & (s[p] <= '9') DO
-      g := g / 10; y := y + g * (ORD(s[p]) - 30H);
-      INC(p)
-    END
-  END;
-  IF (s[p] = 'D') OR (s[p] = 'E') THEN
-    INC(p); e := 0;
-    IF s[p] = '-' THEN negE := TRUE; INC(p) ELSE negE := FALSE END;
-    WHILE (s[p] = '0') DO INC(p) END;
-    WHILE ('0' <= s[p]) & (s[p] <= '9') DO
-      e := e * 10 + ORD(s[p]) - 30H;
-      INC(p)
-    END;
-    IF negE THEN y := y / Ten(e)
-    ELSE y := y * Ten(e)
+  IF ('0' <= s[p]) & (s[p] <= '9') THEN
+    y := 0;
+    REPEAT y := y * 10 + (ORD(s[p]) - ORD('0')); INC(p)
+    UNTIL ~(('0' <= s[p]) & (s[p] <= '9'));
+
+    IF s[p] = '.' THEN
+      INC(p); g := 1;
+      WHILE ('0' <= s[p]) & (s[p] <= '9') DO
+        g := g * 0.1; y := y + g * (ORD(s[p]) - ORD('0'));
+        INC(p)
+      END;
+
+      IF (s[p] = 'D') OR (s[p] = 'E') THEN
+        INC(p); e := 0;
+        IF s[p] = '-' THEN negE := TRUE; INC(p)
+        ELSE negE := FALSE;
+          IF s[p] = '+' THEN INC(p) END
+        END;
+        IF ('0' <= s[p]) & (s[p] <= '9') THEN
+          WHILE ('0' <= s[p]) & (s[p] <= '9') DO
+            e := e * 10 + ORD(s[p]) - ORD('0');
+            INC(p)
+          END;
+          IF negE THEN y := y / Ten(e) ELSE y := y * Ten(e) END;
+        END
+      END;
+      IF neg THEN y := -y END;
+      Done := TRUE
     END
-  END;
-  IF neg THEN y := -y END;
-  Done := TRUE ; (*!FIXME*)
+  END ;
 RETURN y END LongVal;
 
+PROCEDURE Val*(IN s: ARRAY OF CHAR): REAL;
+VAR y: LONGREAL;
+BEGIN
+  RETURN SHORT(LongVal(s))
+END Val;
+
 BEGIN Done := TRUE
 END Reals.

+ 1 - 1
src/edit.sh

@@ -1,3 +1,3 @@
 #!/bin/bash
-vim -p FreeOberon.Mod Graph.Mod Allegro5.Mod ../Data/bin/*.sh
+vim -p Out.Mod
 #vim -p Texts.Mod Files.Mod FreeOberon.Mod FoStrings.Mod ../Data/Texts/ru.dat Texts.Mod OV.Mod