|
@@ -7,13 +7,13 @@ MODULE In;
|
|
IMPORT Platform, SYSTEM, Reals, Out, Utf8;
|
|
IMPORT Platform, SYSTEM, Reals, Out, Utf8;
|
|
|
|
|
|
CONST
|
|
CONST
|
|
- pending = 0; (* readstate when at start of input or end of line. Implies nextch undefined. *)
|
|
|
|
- ready = 1; (* readstate when nextch is defined and contains next character on current line. *)
|
|
|
|
- eof = 2; (* readstate when at end of file. *)
|
|
|
|
|
|
+ pending = 0; (* readState when at start of input or end of line. Implies nextch undefined. *)
|
|
|
|
+ ready = 1; (* readState when nextch is defined and contains next character on current line. *)
|
|
|
|
+ eof = 2; (* readState when at end of file. *)
|
|
|
|
|
|
- (* Codepages, see cp below *)
|
|
|
|
|
|
+ (* Codepages, values of cp *)
|
|
singleByte = 1;
|
|
singleByte = 1;
|
|
- utf8 = 2; (*!TODO also add UTF16 = 2 *)
|
|
|
|
|
|
+ utf8 = 2; (*!TODO also add UTF16 *)
|
|
|
|
|
|
TYPE
|
|
TYPE
|
|
SBYTE = BYTE;
|
|
SBYTE = BYTE;
|
|
@@ -22,16 +22,17 @@ TYPE
|
|
VAR
|
|
VAR
|
|
Done-: BOOLEAN;
|
|
Done-: BOOLEAN;
|
|
nextch: CHAR; (* Maintains 1 character read ahaead except at end of line. *)
|
|
nextch: CHAR; (* Maintains 1 character read ahaead except at end of line. *)
|
|
- readstate: INTEGER;
|
|
|
|
|
|
+ readState: INTEGER;
|
|
cp: INTEGER; (* Input Code Page *)
|
|
cp: INTEGER; (* Input Code Page *)
|
|
|
|
|
|
PROCEDURE Open*;
|
|
PROCEDURE Open*;
|
|
VAR error: Platform.ErrorCode;
|
|
VAR error: Platform.ErrorCode;
|
|
BEGIN
|
|
BEGIN
|
|
- error := Platform.Seek(Platform.StdIn, 0, Platform.SeekSet); (* Rewind STDIN to beginning of file. *)
|
|
|
|
|
|
+ (* Rewind STDIN to beginning of file. *)
|
|
|
|
+ error := Platform.Seek(Platform.StdIn, 0, Platform.SeekSet);
|
|
cp := utf8;
|
|
cp := utf8;
|
|
nextch := 0X;
|
|
nextch := 0X;
|
|
- readstate := pending;
|
|
|
|
|
|
+ readState := pending;
|
|
Done := error = 0
|
|
Done := error = 0
|
|
END Open;
|
|
END Open;
|
|
|
|
|
|
@@ -40,49 +41,63 @@ VAR error: Platform.ErrorCode; x, n: INTEGER;
|
|
m: ARRAY 1 OF SBYTE;
|
|
m: ARRAY 1 OF SBYTE;
|
|
BEGIN
|
|
BEGIN
|
|
error := Platform.ReadBuf(Platform.StdIn, m, n); x := m[0] MOD 256;
|
|
error := Platform.ReadBuf(Platform.StdIn, m, n); x := m[0] MOD 256;
|
|
- IF (error = 0) & (n = 1) THEN readstate := ready
|
|
|
|
- ELSE readstate := eof; x := 0
|
|
|
|
|
|
+ IF (error = 0) & (n = 1) THEN readState := ready
|
|
|
|
+ ELSE readState := eof; x := 0
|
|
END;
|
|
END;
|
|
RETURN x
|
|
RETURN x
|
|
END GetByte;
|
|
END GetByte;
|
|
|
|
|
|
|
|
+PROCEDURE GetChar(VAR x: CHAR): BOOLEAN;
|
|
|
|
+VAR error: Platform.ErrorCode; n: INTEGER; ok: BOOLEAN;
|
|
|
|
+ m: ARRAY 1 OF CHAR;
|
|
|
|
+BEGIN
|
|
|
|
+ error := Platform.ReadBufW(Platform.StdIn, m, n); x := m[0];
|
|
|
|
+ IF (error = 0) & (n = 1) THEN readState := ready; ok := TRUE
|
|
|
|
+ ELSE readState := eof; x := 0X; ok := FALSE
|
|
|
|
+ END ;
|
|
|
|
+RETURN ok END GetChar;
|
|
|
|
+
|
|
PROCEDURE Byte*(VAR x: BYTE);
|
|
PROCEDURE Byte*(VAR x: BYTE);
|
|
BEGIN x := SYSTEM.VAL(BYTE, SHORT(SHORT(GetByte())))
|
|
BEGIN x := SYSTEM.VAL(BYTE, SHORT(SHORT(GetByte())))
|
|
END Byte;
|
|
END Byte;
|
|
|
|
|
|
PROCEDURE ReadChar;
|
|
PROCEDURE ReadChar;
|
|
VAR x, y: INTEGER;
|
|
VAR x, y: INTEGER;
|
|
-BEGIN x := GetByte();
|
|
|
|
- IF readstate = ready THEN
|
|
|
|
- IF cp = utf8 THEN
|
|
|
|
- IF x > 80H THEN y := GetByte() MOD 64; (* Not 1 byte *)
|
|
|
|
- IF x DIV 32 = 6 THEN (* 2 bytes *)
|
|
|
|
- x := x MOD 32 * 64 + y
|
|
|
|
- ELSIF y DIV 16 = 14 THEN (* 3 bytes *)
|
|
|
|
- x := (x MOD 16 * 64 + y) * 64 + GetByte() MOD 64
|
|
|
|
- ELSIF y DIV 8 = 30 THEN (* 4 bytes *)
|
|
|
|
- x := ((x MOD 8 * 64 + y) * 64 + GetByte() MOD 64) * 64 + GetByte() MOD 64
|
|
|
|
- ELSE x := 0
|
|
|
|
|
|
+ c: CHAR;
|
|
|
|
+BEGIN
|
|
|
|
+ IF GetChar(c) THEN nextch := c
|
|
|
|
+ ELSE x := GetByte();
|
|
|
|
+ IF readState = ready THEN
|
|
|
|
+ IF cp = utf8 THEN
|
|
|
|
+ IF x >= 80H THEN y := GetByte() MOD 64; (* Not 1 byte *)
|
|
|
|
+ IF x DIV 32 = 6 THEN (* 2 bytes *)
|
|
|
|
+ x := x MOD 32 * 64 + y
|
|
|
|
+ ELSIF y DIV 16 = 14 THEN (* 3 bytes *)
|
|
|
|
+ x := (x MOD 16 * 64 + y) * 64 + GetByte() MOD 64
|
|
|
|
+ ELSIF y DIV 8 = 30 THEN (* 4 bytes *)
|
|
|
|
+ x := ((x MOD 8 * 64 + y) * 64 + GetByte() MOD 64) * 64 + GetByte() MOD 64
|
|
|
|
+ ELSE x := 0
|
|
|
|
+ END
|
|
END
|
|
END
|
|
- END
|
|
|
|
- END;
|
|
|
|
- nextch := CHR(x)
|
|
|
|
|
|
+ END;
|
|
|
|
+ nextch := CHR(x)
|
|
|
|
+ END
|
|
END
|
|
END
|
|
END ReadChar;
|
|
END ReadChar;
|
|
|
|
|
|
-PROCEDURE StartRead; (* Ensure either nextch is valid or we're at EOF. *)
|
|
|
|
-BEGIN Out.Flush; IF readstate = pending THEN ReadChar END
|
|
|
|
|
|
+PROCEDURE StartRead; (* Ensure either nextch is valid or we are at EOF. *)
|
|
|
|
+BEGIN Out.Flush; IF readState = pending THEN ReadChar END
|
|
END StartRead;
|
|
END StartRead;
|
|
|
|
|
|
PROCEDURE StartAndSkip; (* Like StartRead, but also skip over blanks, CR, LF, tab. *)
|
|
PROCEDURE StartAndSkip; (* Like StartRead, but also skip over blanks, CR, LF, tab. *)
|
|
BEGIN StartRead;
|
|
BEGIN StartRead;
|
|
- WHILE (readstate = ready) & (nextch <= ' ') DO ReadChar END
|
|
|
|
|
|
+ WHILE (readState = ready) & (nextch <= ' ') DO ReadChar END
|
|
END StartAndSkip;
|
|
END StartAndSkip;
|
|
|
|
|
|
PROCEDURE Char*(VAR ch: CHAR);
|
|
PROCEDURE Char*(VAR ch: CHAR);
|
|
BEGIN StartRead;
|
|
BEGIN StartRead;
|
|
- IF readstate = ready THEN ch := nextch;
|
|
|
|
- IF ch = 0AX THEN readstate := pending ELSE ReadChar END
|
|
|
|
|
|
+ IF readState = ready THEN ch := nextch;
|
|
|
|
+ IF ch = 0AX THEN readState := pending ELSE ReadChar END
|
|
ELSE Done := FALSE; ch := 0X
|
|
ELSE Done := FALSE; ch := 0X
|
|
END
|
|
END
|
|
END Char;
|
|
END Char;
|
|
@@ -92,13 +107,13 @@ VAR ok, neg, hex, endofnum: BOOLEAN;
|
|
decacc, hexacc, digit: LONGINT;
|
|
decacc, hexacc, digit: LONGINT;
|
|
BEGIN StartAndSkip;
|
|
BEGIN StartAndSkip;
|
|
ok := FALSE;
|
|
ok := FALSE;
|
|
- IF readstate = ready THEN
|
|
|
|
|
|
+ IF readState = ready THEN
|
|
neg := nextch = '-'; IF neg THEN ReadChar END;
|
|
neg := nextch = '-'; IF neg THEN ReadChar END;
|
|
hex := FALSE;
|
|
hex := FALSE;
|
|
endofnum := FALSE;
|
|
endofnum := FALSE;
|
|
decacc := 0;
|
|
decacc := 0;
|
|
hexacc := 0;
|
|
hexacc := 0;
|
|
- WHILE (readstate = ready) & ~endofnum DO
|
|
|
|
|
|
+ WHILE (readState = ready) & ~endofnum DO
|
|
digit := -1;
|
|
digit := -1;
|
|
IF (nextch >= '0') & (nextch <= '9') THEN
|
|
IF (nextch >= '0') & (nextch <= '9') THEN
|
|
digit := ORD(nextch) MOD 16
|
|
digit := ORD(nextch) MOD 16
|
|
@@ -123,37 +138,36 @@ BEGIN StartAndSkip;
|
|
ELSE h := 0
|
|
ELSE h := 0
|
|
END
|
|
END
|
|
END;
|
|
END;
|
|
- WHILE (readstate = ready) & (nextch <= ' ') & (nextch # 0AX) DO ReadChar END;
|
|
|
|
- IF (readstate = ready) & (nextch = 0AX) THEN readstate := pending END;
|
|
|
|
|
|
+ WHILE (readState = ready) & (nextch <= ' ') & (nextch # 0AX) DO ReadChar END;
|
|
|
|
+ IF (readState = ready) & (nextch = 0AX) THEN readState := pending END;
|
|
IF ~ok THEN Done := FALSE END
|
|
IF ~ok THEN Done := FALSE END
|
|
END HugeInt;
|
|
END HugeInt;
|
|
|
|
|
|
PROCEDURE Int16*(VAR i: SHORTINT);
|
|
PROCEDURE Int16*(VAR i: SHORTINT);
|
|
VAR h: LONGINT;
|
|
VAR h: LONGINT;
|
|
-BEGIN HugeInt(h); i := SHORT(SHORT(h)) (*!FIXME check range?*)
|
|
|
|
|
|
+BEGIN HugeInt(h); i := SHORT(SHORT(h)) (*!FIXME check range, update Done*)
|
|
END Int16;
|
|
END Int16;
|
|
|
|
|
|
-PROCEDURE LongInt*(VAR i: INTEGER);
|
|
|
|
-VAR h: LONGINT;
|
|
|
|
-BEGIN HugeInt(h); i := SHORT(h) (*!FIXME check range?*)
|
|
|
|
-END LongInt;
|
|
|
|
-
|
|
|
|
PROCEDURE Int*(VAR i: INTEGER); (*32-bit INTEGER alias*)
|
|
PROCEDURE Int*(VAR i: INTEGER); (*32-bit INTEGER alias*)
|
|
VAR h: LONGINT;
|
|
VAR h: LONGINT;
|
|
-BEGIN HugeInt(h); i := SHORT(h) (*!FIXME check range?*)
|
|
|
|
|
|
+BEGIN HugeInt(h); i := SHORT(h) (*!FIXME check range, update Done*)
|
|
END Int;
|
|
END Int;
|
|
|
|
|
|
|
|
+PROCEDURE LongInt*(VAR i: INTEGER);
|
|
|
|
+BEGIN Int(i)
|
|
|
|
+END LongInt;
|
|
|
|
+
|
|
PROCEDURE Line*(VAR line: ARRAY OF CHAR);
|
|
PROCEDURE Line*(VAR line: ARRAY OF CHAR);
|
|
VAR i: INTEGER;
|
|
VAR i: INTEGER;
|
|
BEGIN StartRead; i := 0;
|
|
BEGIN StartRead; i := 0;
|
|
- IF readstate # ready THEN Done := FALSE END;
|
|
|
|
- WHILE (readstate = ready) & (nextch # 0DX) & (nextch # 0AX) &
|
|
|
|
- (i < LEN(line) - 1) DO
|
|
|
|
- line[i] := nextch; INC(i); ReadChar
|
|
|
|
|
|
+ IF readState # ready THEN Done := FALSE END;
|
|
|
|
+ WHILE (readState = ready) & (nextch # 0DX) & (nextch # 0AX) DO
|
|
|
|
+ IF i < LEN(line) - 1 THEN line[i] := nextch; INC(i) ELSE Done := FALSE END;
|
|
|
|
+ ReadChar
|
|
END;
|
|
END;
|
|
line[i] := 0X;
|
|
line[i] := 0X;
|
|
- IF (readstate = ready) & (nextch = 0DX) THEN ReadChar END;
|
|
|
|
- IF (readstate = ready) & (nextch = 0AX) THEN readstate := pending END
|
|
|
|
|
|
+ IF (readState = ready) & (nextch = 0DX) THEN ReadChar END;
|
|
|
|
+ IF (readState = ready) & (nextch = 0AX) THEN readState := pending END
|
|
END Line;
|
|
END Line;
|
|
|
|
|
|
(** Skip whitespaces, read characters until a whitespace, skip whitespaces
|
|
(** Skip whitespaces, read characters until a whitespace, skip whitespaces
|
|
@@ -161,26 +175,26 @@ END Line;
|
|
PROCEDURE Word*(VAR s: ARRAY OF CHAR);
|
|
PROCEDURE Word*(VAR s: ARRAY OF CHAR);
|
|
VAR i: INTEGER;
|
|
VAR i: INTEGER;
|
|
BEGIN StartRead; i := 0;
|
|
BEGIN StartRead; i := 0;
|
|
- IF readstate # ready THEN Done := FALSE END;
|
|
|
|
- WHILE (readstate = ready) & (nextch > ' ') & (i < LEN(s) - 1) DO
|
|
|
|
|
|
+ IF readState # ready THEN Done := FALSE END;
|
|
|
|
+ WHILE (readState = ready) & (nextch > ' ') & (i < LEN(s) - 1) DO
|
|
s[i] := nextch; INC(i); ReadChar
|
|
s[i] := nextch; INC(i); ReadChar
|
|
END;
|
|
END;
|
|
s[i] := 0X;
|
|
s[i] := 0X;
|
|
- WHILE (readstate = ready) & (nextch <= ' ') & (nextch # 0AX) DO ReadChar END;
|
|
|
|
- IF (readstate = ready) & (nextch = 0AX) THEN readstate := pending END
|
|
|
|
|
|
+ WHILE (readState = ready) & (nextch <= ' ') & (nextch # 0AX) DO ReadChar END;
|
|
|
|
+ IF (readState = ready) & (nextch = 0AX) THEN readState := pending END
|
|
END Word;
|
|
END Word;
|
|
|
|
|
|
PROCEDURE String*(VAR s: ARRAY OF CHAR);
|
|
PROCEDURE String*(VAR s: ARRAY OF CHAR);
|
|
VAR i: INTEGER;
|
|
VAR i: INTEGER;
|
|
BEGIN StartAndSkip; i := 0;
|
|
BEGIN StartAndSkip; i := 0;
|
|
- IF (readstate = ready) & (nextch = '"') THEN
|
|
|
|
|
|
+ IF (readState = ready) & (nextch = '"') THEN
|
|
ReadChar;
|
|
ReadChar;
|
|
- WHILE (readstate = ready) & (i < LEN(s) - 1) &
|
|
|
|
|
|
+ WHILE (readState = ready) & (i < LEN(s) - 1) &
|
|
(nextch >= ' ') & (nextch # '"') DO
|
|
(nextch >= ' ') & (nextch # '"') DO
|
|
s[i] := nextch; ReadChar; INC(i)
|
|
s[i] := nextch; ReadChar; INC(i)
|
|
END
|
|
END
|
|
END;
|
|
END;
|
|
- IF (readstate = ready) & (i < LEN(s) - 1) & (nextch = '"') THEN
|
|
|
|
|
|
+ IF (readState = ready) & (i < LEN(s) - 1) & (nextch = '"') THEN
|
|
ReadChar; s[i] := 0X
|
|
ReadChar; s[i] := 0X
|
|
ELSE s[0] := 0X; Done := FALSE
|
|
ELSE s[0] := 0X; Done := FALSE
|
|
END
|
|
END
|
|
@@ -216,6 +230,6 @@ END LongReal;
|
|
BEGIN
|
|
BEGIN
|
|
cp := utf8;
|
|
cp := utf8;
|
|
nextch := 0X;
|
|
nextch := 0X;
|
|
- readstate := pending;
|
|
|
|
|
|
+ readState := pending;
|
|
Done := TRUE
|
|
Done := TRUE
|
|
END In.
|
|
END In.
|