⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fileio.mi

📁 一个Modula-2语言分析器
💻 MI
📖 第 1 页 / 共 3 页
字号:
        END
      END;
      IF j <= HIGH(str) THEN str[j] := 0C END;
      Okay := j > 0; f^.haveCh := TRUE; f^.savedCh := ch;
    END
  END ReadToken;

PROCEDURE ReadInt (f: File; VAR i: INTEGER);
  VAR
    Digit: INTEGER;
    j: CARDINAL;
    Negative: BOOLEAN;
    s: ARRAY [0 .. 80] OF CHAR;
  BEGIN
    i := 0; j := 0;
    IF NotRead(f) THEN Okay := FALSE; RETURN END;
    ReadToken(f, s);
    IF s[0] = "-" (* deal with sign *)
      THEN Negative := TRUE; INC(j)
      ELSE Negative := FALSE; IF s[0] = "+" THEN INC(j) END
    END;
    IF (s[j] < "0") OR (s[j] > "9") THEN Okay := FALSE END;
    WHILE (j <= 80) & (s[j] >= "0") & (s[j] <= "9") DO
      Digit := VAL(INTEGER, ORD(s[j]) - ORD("0"));
      IF i <= (MAX(INTEGER) - Digit) DIV 10
        THEN i := 10 * i + Digit
        ELSE Okay := FALSE
      END;
      INC(j)
    END;
    IF Negative THEN i := -i END;
    IF (j > 80) OR (s[j] # 0C) THEN Okay := FALSE END;
    IF ~ Okay THEN i := 0 END;
  END ReadInt;

PROCEDURE ReadCard (f: File; VAR i: CARDINAL);
  VAR
    Digit: CARDINAL;
    j: CARDINAL;
    s: ARRAY [0 .. 80] OF CHAR;
  BEGIN
    i := 0; j := 0;
    IF NotRead(f) THEN Okay := FALSE; RETURN END;
    ReadToken(f, s);
    WHILE (j <= 80) & (s[j] >= "0") & (s[j] <= "9") DO
      Digit := ORD(s[j]) - ORD("0");
      IF i <= (MAX(CARDINAL) - Digit) DIV 10
        THEN i := 10 * i + Digit
        ELSE Okay := FALSE
      END;
      INC(j)
    END;
    IF (j > 80) OR (s[j] # 0C) THEN Okay := FALSE END;
    IF ~ Okay THEN i := 0 END;
  END ReadCard;

PROCEDURE ReadBytes (f: File; VAR buf: ARRAY OF SYSTEM.BYTE; VAR len: CARDINAL);
  VAR
    TooMany: BOOLEAN;
    Wanted: CARDINAL;
  BEGIN
    IF NotRead(f) OR (File(f) = con)
      THEN Okay := FALSE; len := 0;
      ELSE
        IF len = 0 THEN Okay := TRUE; RETURN END;
        TooMany := len - 1 > HIGH(buf);
        IF TooMany THEN Wanted := HIGH(buf) + 1 ELSE Wanted := len END;
        BuffIO.GetBytes(f^.ref, buf, Wanted);
        Okay := Wanted # 0;
        IF len # Wanted THEN Okay := FALSE END;
        len := Wanted;
    END;
    IF ~ Okay THEN f^.eof := TRUE END;
    IF TooMany THEN Okay := FALSE END;
  END ReadBytes;

PROCEDURE Write (f: File; ch: CHAR);
  BEGIN
    IF NotWrite(f) THEN Okay := FALSE; RETURN END;
    IF ch = EOL THEN ch := LF END;
    IF (File(f) = con) OR (File(f) = StdOut) & ToScreen 
      THEN  ConWrite(ch); Okay := TRUE;
      ELSIF File(f) = err THEN ErrWrite(ch); Okay := TRUE;
      ELSE  BuffIO.PutByte(f^.ref, ch);
    END;
  END Write;

PROCEDURE WriteLn (f: File);
  BEGIN
    IF NotWrite(f)
      THEN Okay := FALSE;
      ELSE Write(f, EOL)
    END
  END WriteLn;

PROCEDURE WriteString (f: File; str: ARRAY OF CHAR);
  VAR
    pos: CARDINAL;
  BEGIN
    IF NotWrite(f) THEN Okay := FALSE; RETURN END;
    pos := 0;
    WHILE (pos <= HIGH(str)) & (str[pos] # 0C) DO
      Write(f, str[pos]); INC(pos)
    END
  END WriteString;

PROCEDURE WriteText (f: File; text: ARRAY OF CHAR; len: INTEGER);
  VAR
    i, slen: INTEGER;
  BEGIN
    IF NotWrite(f) THEN Okay := FALSE; RETURN END;
    slen := Strings1.Length(text);
    FOR i := 0 TO len - 1 DO
      IF i < slen THEN Write(f, text[i]) ELSE Write(f, " ") END;
    END
  END WriteText;

PROCEDURE WriteInt (f: File; n: INTEGER; wid: CARDINAL);
  VAR
    l, d: CARDINAL;
    x: INTEGER;
    t: ARRAY [1 .. 25] OF CHAR;
    sign: CHAR;
  BEGIN
    IF NotWrite(f) THEN Okay := FALSE; RETURN END;
    IF n < 0
      THEN sign := "-"; x := - n;
      ELSE sign := " "; x := n;
    END;
    l := 0;
    REPEAT
      d := x MOD 10; x := x DIV 10;
      INC(l); t[l] := CHR(ORD("0") + d);
    UNTIL x = 0;
    IF wid = 0 THEN Write(f, " ") END;
    WHILE wid > l + 1 DO Write(f, " "); DEC(wid); END;
    IF (sign = "-") OR (wid > l) THEN Write(f, sign); END;
    WHILE l > 0 DO Write(f, t[l]); DEC(l); END;
  END WriteInt;

PROCEDURE WriteCard (f: File; n, wid: CARDINAL);
  VAR
    l, d: CARDINAL;
    t: ARRAY [1 .. 25] OF CHAR;
  BEGIN
    IF NotWrite(f) THEN Okay := FALSE; RETURN END;
    l := 0;
    REPEAT
      d := n MOD 10; n := n DIV 10;
      INC(l); t[l] := CHR(ORD("0") + d);
    UNTIL n = 0;
    IF wid = 0 THEN Write(f, " ") END;
    WHILE wid > l DO Write(f, " "); DEC(wid); END;
    WHILE l > 0 DO Write(f, t[l]); DEC(l); END;
  END WriteCard;

PROCEDURE WriteBytes (f: File; VAR buf: ARRAY OF SYSTEM.BYTE; len: CARDINAL);
  VAR
    TooMany: BOOLEAN;
  BEGIN
    TooMany := (len > 0) & (len - 1 > HIGH(buf));
    IF NotWrite(f) OR (File(f) = con) OR (File(f) = err)
      THEN
        Okay := FALSE
      ELSE
        IF TooMany THEN len := HIGH(buf) + 1 END;
        BuffIO.PutBytes(f^.ref, buf, len);
    END;
    IF TooMany THEN Okay := FALSE END;
  END WriteBytes;

PROCEDURE Write2 (f: File; i: CARDINAL);
  BEGIN
    Write(f, CHR(i DIV 10 + ORD("0")));
    Write(f, CHR(i MOD 10 + ORD("0")));
  END Write2;

PROCEDURE WriteDate (f: File);
  VAR 
    t: LIBC.TIME;
    TimeNow: INTEGER;
  BEGIN
    IF NotWrite(f) THEN Okay := FALSE; RETURN END;
    SysLib.time(TimeNow);
    t := LIBC.localtime(TimeNow);
    Write2(f, t^.Day); Write(f, "/"); Write2(f, t^.Month+1); Write(f, "/");
    WriteCard(f, t^.Year + 1900, 1)
  END WriteDate;

PROCEDURE WriteTime (f: File);
  VAR 
    t: LIBC.TIME;
    TimeNow: INTEGER;
  BEGIN
    IF NotWrite(f) THEN Okay := FALSE; RETURN END;
    SysLib.time(TimeNow);
    t := LIBC.localtime(TimeNow);
    Write2(f, t^.Hours); Write(f, ":"); Write2(f, t^.Mins); Write(f, ":");
    Write2(f, t^.Secs)
  END WriteTime;

VAR
  Time0, Time1: INTEGER;

PROCEDURE WriteElapsedTime (f: File);
  VAR
    TimeNow, Diff, Secs: INTEGER;
  BEGIN
    IF NotWrite(f) THEN Okay := FALSE; RETURN END;
    TimeNow := LIBC.clock();
    WriteString(f, "Elapsed time: ");
    Diff := TimeNow - Time1;
    Secs := Diff DIV LIBC.CLOCKSPERSEC; 
    WriteInt(f,  Secs, 1);
    Write(f, '.');
    Write2(f, Diff - Secs * LIBC.CLOCKSPERSEC); 
    WriteString(f, " s"); WriteLn(f);
    Time1 := TimeNow;
  END WriteElapsedTime;

PROCEDURE WriteExecutionTime (f: File);
  VAR
    TimeNow, Diff, Secs: INTEGER;
  BEGIN
    IF NotWrite(f) THEN Okay := FALSE; RETURN END;
    TimeNow := LIBC.clock();
    WriteString(f, "Execution time: ");
    Diff := TimeNow - Time0;
    Secs := Diff DIV LIBC.CLOCKSPERSEC; 
    WriteInt(f,  Secs, 1);
    Write(f, '.');
    Write2(f, Diff - Secs * LIBC.CLOCKSPERSEC); 
    WriteString(f, " s"); WriteLn(f);
  END WriteExecutionTime;

(* The code for the next four procedures below may be commented out if your
   compiler supports ISO PROCEDURE constant declarations and these declarations
   are made in the DEFINITION MODULE *)

PROCEDURE SLENGTH (stringVal: ARRAY OF CHAR): CARDINAL;
  BEGIN
    RETURN Strings1.Length(stringVal)
  END SLENGTH;

PROCEDURE Assign (source: ARRAY OF CHAR; VAR destination: ARRAY OF CHAR);
  BEGIN
  (* Be careful - some libraries have the parameters reversed! *)
    Strings1.Assign(destination, source)
  END Assign;

PROCEDURE Extract (source: ARRAY OF CHAR; startIndex: CARDINAL;
                   numberToExtract: CARDINAL; VAR destination: ARRAY OF CHAR);
  BEGIN
    Strings1.Copy(source, startIndex, numberToExtract, destination);
  END Extract;

PROCEDURE Concat (source1, source2: ARRAY OF CHAR; VAR destination: ARRAY OF CHAR);
  BEGIN
    Strings1.Concat(source1, source2, destination);
  END Concat;

(* The code for the four procedures above may be commented out if your
   compiler supports ISO PROCEDURE constant declarations and these declarations
   are made in the DEFINITION MODULE *)

PROCEDURE Compare (stringVal1, stringVal2: ARRAY OF CHAR): INTEGER;
  BEGIN
    RETURN Strings1.compare(stringVal1, stringVal2);
  END Compare;

PROCEDURE ORDL (n: INT32): CARDINAL;
   BEGIN RETURN VAL(CARDINAL, n) END ORDL;

PROCEDURE INTL (n: INT32): INTEGER;
   BEGIN RETURN VAL(INTEGER, n) END INTL;

PROCEDURE INT (n: CARDINAL): INT32;
   BEGIN RETURN VAL(INT32, n) END INT;

PROCEDURE InitTTY;
  VAR
    termName: ARRAY [0 .. 30] OF CHAR;
  BEGIN
    Strings1.Assign(termName, "/dev/tty");
    TermFD := SysLib.open(SYSTEM.ADR(termName), SysLib.oRDWR);
    reply := LIBC.tcgetattr(TermFD, termioOrig); (* terminal characteristics *)
    Erase := termioOrig.CC[LIBC.ERASE];
    Kill := termioOrig.CC[LIBC.KILL];
    EOFChar := termioOrig.CC[LIBC.EOF];
    Intr := termioOrig.CC[LIBC.INTR];
    BreakEnabled := LIBC.ISIG IN termioOrig.LFlag;
    termioNew := termioOrig;            (* retain so can reset later *)
    EXCL(termioNew.LFlag, LIBC.ISIG);
    EXCL(termioNew.LFlag, LIBC.ICANON);
    EXCL(termioNew.LFlag, LIBC.ECHO); (* stty -isig -echo -canon *)
  END InitTTY;

PROCEDURE CloseAll;
  VAR
    handle: CARDINAL;
  BEGIN
    FOR handle := 0 TO MaxFiles - 1 DO
      IF handle IN Handles THEN BuffIO.FlushBuffer(Opened[handle]^.ref) END
    END;
    IF ~ ToScreen THEN BuffIO.FlushBuffer(1) END;
    reply := LIBC.tcsetattr(TermFD, 0, termioOrig);
  END CloseAll;

PROCEDURE QuitExecution;
  BEGIN
    HALT
  END QuitExecution;

BEGIN
  InitTTY;
  Time0 := LIBC.clock(); Time1 := Time0;
  Handles := BITSET{};
  Okay := FALSE;
  Param := 0;

  ALLOCATE(con, SYSTEM.TSIZE(FileRec));
  con^.ref := TermFD;
  con^.savedCh := 0C; con^.haveCh := FALSE; con^.self := con;
  con^.noOutput := FALSE; con^.noInput := FALSE; con^.textOK := TRUE;
  con^.eof := FALSE; con^.eol := FALSE;

  ALLOCATE(StdIn, SYSTEM.TSIZE(FileRec));
  BuffIO.OpenInput(StdIn^.ref, ""); (* allocate a buffer - special name *)
  StdIn^.savedCh := 0C; StdIn^.haveCh := FALSE; StdIn^.self := StdIn;
  StdIn^.noOutput := TRUE; StdIn^.noInput := FALSE; StdIn^.textOK := TRUE;
  StdIn^.eof := FALSE; StdIn^.eol := FALSE;
  FromKeyboard := LIBC.tcgetattr(StdIn^.ref, termioNew) = 0; (* probe redirection *);

  ALLOCATE(StdOut, SYSTEM.TSIZE(FileRec));
  BuffIO.OpenOutput(StdOut^.ref, ""); (* allocate a buffer - special name *)
  StdOut^.savedCh := 0C; StdOut^.haveCh := FALSE; StdOut^.self := StdOut;
  StdOut^.noOutput := FALSE; StdOut^.noInput := TRUE; StdOut^.textOK := TRUE;
  StdOut^.eof := TRUE; StdOut^.eol := TRUE;
  ToScreen := LIBC.tcgetattr(StdOut^.ref, termioNew) = 0; (* probe redirection *);

  ALLOCATE(err, SYSTEM.TSIZE(FileRec));
  err^.ref := 2;
  err^.savedCh := 0C; err^.haveCh := FALSE; err^.self := err;
  err^.noOutput := FALSE; err^.noInput := TRUE; err^.textOK := TRUE;
  err^.eof := TRUE; err^.eol := TRUE;
  Arguments.GetArgs(numPar, argv);
  reply := LIBC.atexit(CloseAll);
END FileIO.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -