home *** CD-ROM | disk | FTP | other *** search
- MODULE Pute;
-
- (* $OvflChk- $RangeChk- $StackChk- $NilChk- $ReturnChk- $CaseChk- *)
-
- IMPORT io,
- ol := OberonLib;
-
- CONST
- lparen = 0; rparen = 1; times = 2; plus = 3; minus = 4;
- div = 5; mod = 6; number = 7; eof = -1;
-
- TYPE String = ARRAY 80 OF CHAR;
-
- VAR
- Sym: SHORTINT;
- Number: LONGINT;
- Char: CHAR;
- buffer: UNTRACED POINTER TO String;
- index: INTEGER;
- Identifier: String;
- result: LONGINT;
-
- (*-------------------------------------------------------------------------*)
-
- PROCEDURE ReadChar;
-
- BEGIN
- IF index=ol.dosCmdLen THEN Char := 0X;
- ELSE Char := CAP(buffer^[index]); INC(index) END;
- END ReadChar;
-
- (*-------------------------------------------------------------------------*)
-
- PROCEDURE Error;
-
- BEGIN
- io.WriteString("Usage: PUTE <Expression>"); io.WriteLn; HALT(0)
- END Error;
-
- (*-------------------------------------------------------------------------*)
-
- PROCEDURE GetSym();
-
- VAR
- digit: String; (* used to read constant numbers *)
- cnt,i: INTEGER;
- n: SHORTINT;
-
- BEGIN
- WHILE (Char<=" ") AND (Char>0X) DO ReadChar END;
- CASE Char OF
- "A".."Z":
- cnt := 0;
- WHILE (Char>="A") AND (Char<="Z") DO
- Identifier[cnt] := Char;
- ReadChar;
- INC(cnt); IF cnt=80 THEN Error END;
- END;
- Identifier[cnt] := 0X;
- IF Identifier="DIV" THEN Sym := div
- ELSIF Identifier="MOD" THEN Sym := mod
- ELSE Error END |
- "0".."9":
- cnt := -1;
- WHILE ((Char>="0") AND (Char<="9")) OR ((Char>="A") AND (Char<="Z")) DO
- INC(cnt);
- IF cnt=80 THEN Error END;
- digit[cnt] := Char;
- ReadChar;
- END;
- Number := 0; i := 0;
- IF digit[cnt]#"H" THEN
- WHILE i<=cnt DO
- n := SHORT(ORD(digit[i])-ORD("0"));
- CASE n OF 0..9: Number := 10 * Number + n ELSE Error END;
- INC(i);
- END;
- ELSE
- WHILE i<cnt DO
- n := SHORT(ORD(digit[i])-ORD("0"));
- IF n>9 THEN DEC(n,7) END;
- CASE n OF 0..15: Number := 16 * Number + n ELSE Error END;
- INC(i);
- END;
- END;
- Sym := number;
- RETURN |
- "(": Sym := lparen |
- ")": Sym := rparen |
- "*": Sym := times |
- "+": Sym := plus |
- "-": Sym := minus |
- "/": Sym := div |
- 0X : Sym := eof |
- ELSE Error END;
- ReadChar;
- END GetSym;
-
- (*-------------------------------------------------------------------------*)
-
- PROCEDURE Expression(): LONGINT;
-
- VAR
- c: LONGINT;
- addOperator: SHORTINT;
-
- PROCEDURE Term(): LONGINT;
-
- VAR
- d,c: LONGINT;
- s: SHORTINT;
-
- PROCEDURE Factor(): LONGINT;
- VAR c: LONGINT;
- BEGIN
- CASE Sym OF number: c := Number; GetSym |
- lparen: GetSym; c:=Expression();
- IF Sym#rparen THEN Error END;
- GetSym |
- ELSE Error END;
- RETURN c
- END Factor;
-
- BEGIN
- c := Factor();
- LOOP
- CASE Sym OF
- times,div,mod:
- s := Sym;
- GetSym; d := Factor();
- IF s=times THEN c := c * d;
- ELSIF d=0 THEN HALT(0)
- ELSIF s=div THEN c := c DIV d;
- ELSE c := c MOD d END |
- ELSE EXIT END;
- END;
- RETURN c;
- END Term;
-
- BEGIN
- addOperator := Sym;
- IF (addOperator=plus) OR (addOperator=minus) THEN GetSym END;
- c := Term();
- IF addOperator=minus THEN c := -c END;
- LOOP
- CASE Sym OF
- plus : GetSym; INC(c,Term()) |
- minus: GetSym; DEC(c,Term()) |
- ELSE EXIT END;
- END;
- RETURN c;
- END Expression;
-
- BEGIN
- IF ol.wbStarted THEN Error END;
- buffer := ol.dosCmdBuf;
- Char := " "; GetSym;
- result := Expression(); IF Sym#eof THEN Error END;
- io.WriteInt(result,11); io.WriteString(" = ");
- io.WriteHex(result,8); io.Write("H"); io.WriteLn;
- END Pute.
-
-
-