home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / extra18 / wita / wita.pas < prev   
Encoding:
Pascal/Delphi Source File  |  1992-01-20  |  21.0 KB  |  813 lines

  1. (* ------------------------------------------------- *)
  2. (*                    WITA.PAS                       *)
  3. (*        (c) 1992 W.Hermanns & DMV-Verlag           *)
  4. (* ------------------------------------------------- *)
  5. PROGRAM WITA;
  6.  
  7. {$R-,S-,I-,V-}
  8. {$M $800,0,0}
  9.  
  10. USES Crt, Math, TSR;
  11.  
  12. TYPE
  13.   Str3    = STRING[3];
  14.  
  15. CONST
  16.   Prg     = 'Wissenschaftlicher Taschenrechner';
  17.   Version = 'W. Hermanns, Juli 1990';
  18.   Name    = 'WITA.FOR';
  19.             { Dateiname der Formelsammlung }
  20.   Palette : ARRAY[0..3] OF BYTE = (0,3,11,14);
  21.   MaxEinL   = 128;
  22.   MaxStapel = 47;
  23.   MaxExp    = 88;
  24.   MaxReal   = 1E37;
  25.   MaxFkt    = 27;
  26.   Fkts: ARRAY [1..MaxFkt] OF Str3=
  27.    ('!','ABS','ACH','ACS','ASH','ASN','ATH','ATN','B',
  28.     'COH','COS','EXP','H','INT','LG','LN','M','N','PI',
  29.     'RND','SGN','SIH','SIN','SQR','SQT','TAH','TAN');
  30.   Leer = 'xxx';
  31.   Oper = ['+','-','*','/','\','^','L','R',
  32.           'O','U','X','W'];
  33.   Fehlermel: ARRAY [1..4] OF STRING[8]=
  34.     ('Eingabe','Argument','Überlauf','I/O-Disk');
  35.  
  36. TYPE
  37.   EinTyp  = STRING[MaxEinL];
  38.   Stapelt = RECORD
  39.        CASE INTEGER OF
  40.          0 : (Az : BOOLEAN; Z : REAL);
  41.          1 : (Ac : BOOLEAN; P : BYTE;
  42.               O  : CHAR;    F : Str3);
  43.        END;
  44.  
  45. VAR
  46.   Z1     : Stapelt;
  47.   Zmem   : ARRAY [0..9] OF REAL;
  48.   Stapel : ARRAY [0..MaxStapel] OF Stapelt;
  49.   Err    : INTEGER;
  50.   Datei  : FILE OF EinTyp;
  51.   StZeig, Xc, Yc, Wx, Wy : BYTE;
  52.   S      : EinTyp;
  53.   Sm     : STRING[16];
  54.   Satz, Fkt, Lfw: Str3;
  55.   Zm     : REAL;
  56.   HotKey : WORD;
  57.   SZ,Flg : BOOLEAN;
  58.   Key    : CHAR;
  59.   Bild   : ARRAY [0..3999] OF BYTE ABSOLUTE $BC00:0;
  60.        { Bei Herkules- und CGA-Karte darf der Zusatz }
  61.        { ABSOLUTE $BC00:0 nicht verwendet werden!    }
  62.  
  63.   PROCEDURE Bildsichern;
  64.   BEGIN
  65.     Xc := WhereX; Yc := WhereY;
  66.     CASE Lastmode OF
  67.       3  : Move(Mem[$B800:0], Bild, 4000);
  68.       2,7: Move(Mem[$B000:0], Bild, 4000);
  69.     END;
  70.   END;  { Bildsichern }
  71.  
  72.   PROCEDURE Bildholen;
  73.   BEGIN
  74.     Window (1,1,80,25);
  75.     CASE Lastmode OF
  76.       3  : Move(Bild,Mem[$B800:0],4000);
  77.       2,7: Move(Bild,Mem[$B000:0],4000);
  78.     END;
  79.     GotoXY (Xc,Yc);
  80.   END; { Bildholen }
  81.  
  82.   PROCEDURE CWrite(S : STRING);
  83.   VAR
  84.     i : BYTE;
  85.   BEGIN
  86.     I := 0;
  87.     REPEAT
  88.       INC (I);
  89.       IF S[I] = '@' THEN BEGIN
  90.         INC (I);
  91.         IF S[I] <> '@' THEN BEGIN
  92.           TextColor(Palette[Ord(S[I])-48]);
  93.           INC (I);
  94.         END;
  95.       END;
  96.       IF I <= Length(S) THEN Write (S[I]);
  97.     UNTIL I >= Length(S);
  98.   END; { CWrite }
  99.  
  100.   PROCEDURE Taste(VAR Erw: BOOLEAN; VAR Key: CHAR);
  101.   VAR
  102.     AX : WORD;
  103.   BEGIN
  104.     INLINE ($B4/$00/$CD/$16/$08/$C0/
  105.             $75/$02/$86/$C4/$89/$86/AX);
  106.     Erw := (Hi(AX)=0);  Key := Chr(Lo(AX));
  107.   END; { Taste }
  108.  
  109.   PROCEDURE Cursor(Mode: BOOLEAN);
  110.   BEGIN
  111.     INLINE($B4/$01/$B9/$07/$06/$8A/$86/Mode/
  112.            $08/$C0/$75/$02/$88/$C1/$CD/$10);
  113.   END; { Cursor }
  114.  
  115.   FUNCTION Satznr:BYTE;
  116.   VAR
  117.     CH : CHAR; s : Str3; i : BYTE;
  118.   BEGIN
  119.     s := '';
  120.     REPEAT
  121.       REPEAT
  122.         Taste(SZ, CH);
  123.       UNTIL NOT SZ;
  124.       IF (CH = #8) AND (Length(s) > 0) THEN BEGIN
  125.         Delete(s, Length(s), 1);
  126.         Write (#8' '#8);
  127.       END;
  128.       IF CH IN ['0'..'9'] THEN BEGIN
  129.         s := s + CH;
  130.         Write(CH);
  131.       END;
  132.       Val(s, i, Err);
  133.     UNTIL (Length(s) = 2) OR (CH = #27);
  134.     IF CH<>#27 THEN BEGIN
  135.       Satznr := i;  Str(i, Satz);
  136.       IF i < 10 THEN Satz := '0' + Satz;
  137.     END ELSE BEGIN
  138.       Satznr := 255;
  139.       Satz   := '';
  140.     END;
  141.   END; { Satznr }
  142.  
  143.   PROCEDURE Laufwerk(Nr : BYTE);
  144.   VAR
  145.     CH : CHAR;
  146.   BEGIN
  147.     lfw := #0;
  148.     lfw := ParamStr(Nr);
  149.     CH  := UpCase(lfw[1]);
  150.     IF CH IN ['A'..'H'] THEN
  151.       lfw := CH + ':'
  152.     ELSE
  153.       lfw := '';
  154.   END; { Laufwerk }
  155.  
  156.   PROCEDURE Disk(Satz : BYTE; mode : CHAR);
  157.  
  158.     FUNCTION DiskOk : BOOLEAN;
  159.     BEGIN
  160.       IF IOResult <> 0 THEN BEGIN
  161.         Error  := 4;
  162.         DiskOk := FALSE;
  163.       END ELSE DiskOk := TRUE;
  164.     END; { DiskOk }
  165.  
  166.   BEGIN { Disk }
  167.     IF Satz < 100 THEN BEGIN
  168.       Assign(Datei, lfw+name);
  169.       Reset(Datei);
  170.       IF DiskOK THEN BEGIN
  171.         Seek(Datei, Satz);
  172.         IF mode = 'W' THEN
  173.           Write(Datei, s)
  174.         ELSE
  175.           Read(Datei, s);
  176.         Close(Datei);
  177.       END;
  178.     END;
  179.   END; { Disk }
  180.  
  181.   PROCEDURE Rahmen;
  182.   VAR
  183.     i : BYTE;
  184.   BEGIN
  185.     Bildsichern;
  186.     TextBackground (Palette[0]);
  187.     Window (Wx, Wy, Wx+42, Wy+9);
  188.     CWrite('@1╔');
  189.     FOR i:=1 TO 41 DO Write ('═');
  190.     Write ('╗');
  191.     Write ('║',' ':41,'║');
  192.     Write ('║',' ':41,'║');
  193.     Write ('╟');
  194.     FOR i:=1 TO 41 DO Write ('─');
  195.     Write ('╢');
  196.     CWrite('║ @2SQR SQT EXP () +-*/\ L R ');
  197.     CWrite('@1x@2^@1y x@2W@1y @1F1-F10 ║');
  198.     CWrite('║ @2H@1ex @2B@1in @2U@1nd @2X@1or ');
  199.     CWrite('@2N@1ot @2O@1r @2LN LG M @1Crsr Del ║');
  200.     CWrite('║ @2SIN COS TAN ASN ACS ' +
  201.            'ATN PI RND ABS  @1Esc ║');
  202.     CWrite('║ @2SIH COH TAH ASH ACH ATH ! ' +
  203.            'SGN INT @1<╛ <─ ║');
  204.     Write ('╚');
  205.     FOR i:=1 TO 41 DO Write ('═');
  206.     Write ('╝');
  207.     Window (Wx+1, Wy+1, Wx+41, Wy+7);
  208.   END; { Rahmen }
  209.  
  210.   PROCEDURE Eingabeanzeigen(s : EinTyp; z : BYTE);
  211.   VAR
  212.     A, I, L : BYTE;
  213.   BEGIN
  214.     L := Length(S);
  215.     IF L > 40 THEN A := L-39 ELSE A := 1;
  216.     GotoXY(1,z);  CWrite('@2');
  217.     FOR I := A TO L DO Write(S[I]);
  218.     ClrEol;
  219.   END; { Eingabeanzeigen }
  220.  
  221.   PROCEDURE Statusanzeigen;
  222.   VAR
  223.     I : BYTE;
  224.   BEGIN
  225.     FOR I := 0 TO 9 DO BEGIN
  226.       GotoXY(20+I,3);
  227.       IF Zmem[I] <> 0 THEN
  228.         CWrite('@1'+Chr(I+48))
  229.       ELSE
  230.         CWrite('@1─');
  231.     END;
  232.     GotoXY(2,3);
  233.     IF Satz <> '' THEN
  234.       CWrite('@1Term─#'+Satz)
  235.     ELSE
  236.       CWrite('@1────────');
  237.     GotoXY(34,3);
  238.     CASE Basis OF
  239.       0 : CWrite ('@3Dez');
  240.       1 : CWrite ('@3Bin');
  241.       4 : CWrite ('@3Hex')
  242.     END;
  243.     GotoXY(38,3);
  244.     IF WiMo = 1  THEN CWrite('Bog@2');
  245.     IF WiMo = Wa THEN CWrite('Alt@2');
  246.     IF WiMo = Wn THEN CWrite('Neu@2');
  247.   END; { Statusanzeigen }
  248.  
  249.   PROCEDURE Ergebnisanzeigen;
  250.   BEGIN
  251.     GotoXY(1,2); ClrEol;
  252.     IF Error > 0 THEN BEGIN
  253.       CWrite(' @3'+Fehlermel[Error]+'fehler!@1');
  254.       Sound(500); Delay(25); NoSound;
  255.     END ELSE BEGIN
  256.       IF (Abs(Zm)<=Maxlongint) AND (Basis>0) THEN
  257.         Write (Hexbin(Trunc(Zm)):37)
  258.       ELSE
  259.         IF (Abs(Zm)>MaxlongInt) OR
  260.            (Abs(Zm)<1/MaxLongInt) AND
  261.            (Zm <> 0) THEN Write (Zm:36)
  262.                      ELSE Write (Zm:36:9);
  263.     END;
  264.   END; { Ergebnisanzeigen }
  265.  
  266.   PROCEDURE Eingeben;
  267.   VAR
  268.     CH : CHAR; Nr : BYTE; F4Flg, F5Flg : BOOLEAN;
  269.  
  270.     PROCEDURE Baustring(VAR s : EinTyp);
  271.     BEGIN
  272.       IF NOT (CH IN Oper+[#8,#13,' ','(',')']) AND
  273.               Flg AND (Error=0) THEN
  274.         FillChar(S, MaxEinL, #0);
  275.       Flg := FALSE;  Error := 0;
  276.       IF CH > #26 THEN S := S+CH;
  277.       IF CH = #8 THEN Delete (S, Length(S), 1);
  278.     END; { Baustring }
  279.  
  280.     PROCEDURE Verschieben;
  281.     BEGIN
  282.       Bildholen;
  283.       CASE CH OF
  284.         #72: IF Wy >  1 THEN DEC(Wy);
  285.         #75: IF Wx >  1 THEN DEC(Wx);
  286.         #77: IF Wx < 38 THEN INC(Wx);
  287.         #80: IF Wy < 16 THEN INC(Wy);
  288.       END;
  289.       Bildsichern;
  290.       Rahmen;
  291.     END; { Verschieben }
  292.  
  293.   BEGIN { Eingeben }
  294.     Flg := TRUE;
  295.     REPEAT
  296.       F4Flg := FALSE;  F5Flg := FALSE;
  297.       Taste(SZ, CH);
  298.       IF NOT SZ THEN BEGIN
  299.         Baustring(s); Satz := '';
  300.       END ELSE BEGIN
  301.         Flg := TRUE;
  302.         CASE CH OF
  303.           #59 :
  304.             BEGIN
  305.               IF (Basis = 0) AND Flg THEN BEGIN
  306.                 Basis := 1;  Flg := FALSE;
  307.               END;
  308.               IF (Basis = 1) AND Flg THEN BEGIN
  309.                 Basis := 4;  Flg := FALSE;
  310.               END;
  311.               IF (Basis = 4) AND Flg THEN Basis := 0;
  312.             END;
  313.           #60 :
  314.             BEGIN
  315.               IF (WiMo = 1) AND Flg THEN BEGIN
  316.                 WiMo := Wa;  Flg := FALSE;
  317.               END;
  318.               IF (WiMo = Wa) AND Flg THEN BEGIN
  319.                 WiMo := Wn;  Flg := FALSE;
  320.               END;
  321.               IF (WiMo = Wn) AND Flg THEN WiMo := 1;
  322.             END;
  323.         #61 :
  324.           BEGIN
  325.             { Ergebnis in Variable speichern }
  326.             GotoXY(13,3);  CWrite('@3MemW#');
  327.             REPEAT
  328.               Taste(SZ,CH);
  329.             UNTIL CH IN ['0'..'9'];
  330.             Write (CH);
  331.             Zmem[Ord(CH)-48] := Zm;
  332.           END;
  333.         #62 :
  334.           BEGIN
  335.             { Zahl in Variable speichern }
  336.             sm := '';  F4Flg := TRUE;
  337.             GotoXY(13,3);  CWrite('@3MemS#');
  338.             REPEAT
  339.               Taste(SZ,CH);
  340.             UNTIL CH IN ['0'..'9'];
  341.             Write (CH);
  342.             Nr := Ord(CH)-48;
  343.             REPEAT
  344.               REPEAT
  345.                 Taste(SZ,CH);
  346.               UNTIL NOT SZ;
  347.               IF CH IN ['+'..'9','e','E'] THEN
  348.                 SM := SM+CH;
  349.               IF CH = #8 THEN
  350.                 Delete (SM, Length(SM), 1);
  351.               Eingabeanzeigen(sm, 2);
  352.               Val(sm, Zmem[Nr], Err);
  353.             UNTIL CH = #13;
  354.             IF Err > 0 THEN Zmem[Nr] := 0;
  355.           END;
  356.         #63 :
  357.           BEGIN { Term lesen }
  358.             GotoXY(2,3);  CWrite('@3TermR#');
  359.             Disk(Satznr, 'R');
  360.             F5Flg := TRUE;
  361.           END;
  362.         #64 :
  363.           BEGIN { Term schreiben }
  364.             GotoXY(2,3);  CWrite('@3TermW#');
  365.             Disk(Satznr, 'W');
  366.           END;
  367.         #65,#66,#67,#68 :
  368.           BEGIN { Farbpalette ändern }
  369.             Palette[ord(ch)-65]:=
  370.               Succ(Palette[ord(ch)-65]) AND 15;
  371.             Bildholen; Rahmen;
  372.           END;
  373.         #72,#75,#77,#80:
  374.           BEGIN
  375.             Verschieben; Flg := FALSE;
  376.           END;
  377.         #83 :
  378.           BEGIN
  379.             FillChar(S, MaxEinL, #0);
  380.             Zm := 0;  Satz := '';
  381.           END;
  382.         END;
  383.         CH := #0;
  384.       END;
  385.       Statusanzeigen;
  386.       Ergebnisanzeigen;
  387.       Eingabeanzeigen(s,1);
  388.       GotoXY(13,3);  CWrite('@1──────@2');
  389.     UNTIL (CH = #13) OR F4Flg OR F5Flg;
  390.   END; { Eingeben }
  391.  
  392.   FUNCTION Rang(O : CHAR) : BYTE;
  393.   BEGIN
  394.     CASE O OF
  395.       'O','X': Rang := 2; { OR, XOR }
  396.       'U':     Rang := 3; { UND }
  397.       '+','-': Rang := 4;
  398.       '^','W': Rang := 6; { x^y, xWy }
  399.     ELSE       Rang := 5; { *, /, \, L, R }
  400.     END;
  401.   END; { Rang }
  402.  
  403.   PROCEDURE Suchklammer(VAR Auf, Zu : BYTE);
  404.   VAR
  405.     A, I, Z : BYTE;
  406.   BEGIN
  407.     REPEAT
  408.       A := 0; Z := StZeig-1;
  409.       FOR I := 0 TO StZeig-1 DO
  410.         IF Stapel[I].Ac AND (Stapel[I].O='(') THEN
  411.           A := I;
  412.       FOR I := StZeig-1 DOWNTO A+1 DO
  413.         IF Stapel[I].Ac AND (Stapel[I].O=')') THEN
  414.           Z := I;
  415.       IF (Z = A+2) AND Stapel[A].Ac AND
  416.          Stapel[Z].Ac AND (Stapel[A].O='(') AND
  417.          (Stapel[Z].O=')') THEN BEGIN
  418.         Stapel[A] := Stapel[Succ(A)];
  419.         FOR I := A+1 TO StZeig-1 DO
  420.           Stapel[I] := Stapel[I+2];
  421.         DEC(StZeig,2);
  422.       END;
  423.     UNTIL (Z > A+2) OR (A = 0) AND (Z = StZeig-1);
  424.     IF Stapel[A].Ac AND (Stapel[A].O='(') THEN
  425.       Auf := A+1
  426.     ELSE
  427.       Auf := A;
  428.     IF Stapel[Z].Ac AND (Stapel[Z].O=')') THEN
  429.       Zu := Z-1
  430.     ELSE
  431.       Zu := Z;
  432.   END; { Suchklammer }
  433.  
  434.   FUNCTION MaxRang : BYTE;
  435.   VAR
  436.     A, Z, I, J, K, P : BYTE;
  437.   BEGIN
  438.     Suchklammer(A,Z);
  439.     J := 0;  K := 0;
  440.     FOR I := A TO Z DO
  441.       IF Stapel[I].Ac AND (Stapel[I].P>J) OR
  442.          (Stapel[I].P=7) THEN BEGIN
  443.         J := Stapel[I].P;  K := I;
  444.       END;
  445.     MaxRang := K;
  446.   END; { MaxRang }
  447.  
  448.   FUNCTION TestFkt(X, Y : REAL; O : CHAR) : BOOLEAN;
  449.   VAR
  450.     Ok : BOOLEAN;
  451.   BEGIN
  452.     Ok := TRUE;
  453.     IF (Abs(X) > MaxReal) OR (Abs(Y) > MaxReal) THEN
  454.       Ok := FALSE;
  455.     CASE O OF
  456.       '+':
  457.         IF Sgn(X)=Sgn(Y) THEN
  458.           IF Abs(X) > MaxReal - Abs(Y) THEN
  459.             Ok := FALSE;
  460.       '-':
  461.         IF Sgn(X)<>Sgn(Y) THEN
  462.           IF Abs(X)> MaxReal + Abs(Y) THEN
  463.             Ok := FALSE;
  464.       '*':
  465.         IF (Abs(X) >= 1) AND (Abs(Y) >= 1) THEN
  466.           IF Abs(X) > MaxReal / (Abs(Y)) THEN
  467.             Ok := FALSE;
  468.       '/','\':
  469.         IF (Abs(Y) < 1) AND (Abs(Y) > 0) THEN
  470.           IF Abs(X) > MaxReal/Abs(1/Abs(Y)) THEN
  471.             Ok := FALSE;
  472.       '^':
  473.         IF X <> 0 THEN
  474.           IF Abs(Y)*Ln(Abs(X)) > MaxExp THEN
  475.             Ok := FALSE;
  476.       'W':
  477.         IF (X <> 0) AND (Y <> 0) THEN
  478.           IF Abs(1/Y)*Ln(Abs(X)) > MaxExp THEN
  479.             Ok := FALSE;
  480.     END;
  481.     IF NOT Ok THEN Error := 3;
  482.     TestFkt := Ok;
  483.   END; { TestFkt }
  484.  
  485.   PROCEDURE Funktionswert(VAR Z : REAL);
  486.   BEGIN
  487.     IF Fkt = 'N'   THEN Z := NOT Lint(Z);
  488.     IF Fkt = 'ABS' THEN Z := Abs(Z);
  489.     IF Fkt = 'INT' THEN Z := Int(Z);
  490.     IF Fkt = 'RND' THEN
  491.       IF Z < 0 THEN
  492.         Z := Int(Z-0.5)
  493.       ELSE
  494.         Z := Int(Z+0.5);
  495.     IF Fkt = 'SQR' THEN Z := Sqr(Z);
  496.     IF Fkt = 'SQT' THEN
  497.       IF Z >= 0 THEN
  498.         Z := Sqrt(Z)
  499.       ELSE Error := 2;
  500.     IF Fkt = 'LN' THEN
  501.       IF Z > 0 THEN
  502.         Z := Ln(Z)
  503.       ELSE Error := 2;
  504.     IF Fkt = 'LG'  THEN Z := Lg(Z);
  505.     IF Fkt = 'EXP' THEN
  506.       IF Z <= MaxExp THEN
  507.         IF Z >= -MaxExp THEN
  508.           Z := Exp(Z)
  509.         ELSE
  510.           Z := 0
  511.       ELSE Error := 3;
  512.     IF Fkt = 'SIN' THEN Z := Sin(Z);
  513.     IF Fkt = 'COS' THEN Z := Cos(Z);
  514.     IF Fkt = 'TAN' THEN Z := Tan(Z);
  515.     IF Fkt = 'ASN' THEN Z := Asn(Z);
  516.     IF Fkt = 'ACS' THEN Z := Acs(Z);
  517.     IF Fkt = 'ATN' THEN Z := Atn(Z);
  518.     IF Fkt = '!'   THEN Z := fakultaet(Z);
  519.     IF Fkt = 'SIH' THEN Z := Sih(Z);
  520.     IF Fkt = 'COH' THEN Z := Coh(Z);
  521.     IF Fkt = 'TAH' THEN Z := Tah(Z);
  522.     IF Fkt = 'ASH' THEN Z := Ash(Z);
  523.     IF Fkt = 'ACH' THEN Z := Ach(Z);
  524.     IF Fkt = 'ATH' THEN Z := Ath(Z);
  525.     IF Fkt = 'SGN' THEN Z := Sgn(Z);
  526.   END; { Funktionswert }
  527.  
  528.   PROCEDURE Stapelauswerten;
  529.   VAR
  530.     Z1, Z2 : Stapelt; I, J : BYTE;
  531.   BEGIN
  532.     REPEAT
  533.       J := MaxRang;
  534.       IF Stapel[J].Ac THEN
  535.         Fkt := Stapel[J].F
  536.       ELSE
  537.         Fkt := Leer;
  538.       IF (J > 0) AND (Fkt = Leer) THEN
  539.         Z1 := Stapel[Pred(J)]
  540.       ELSE
  541.         Z1 := Stapel[J];
  542.       Z2 := Stapel[Succ(J)];
  543.       IF Fkt = Leer THEN BEGIN
  544.         IF TestFkt(Z1.Z, Z2.Z, Stapel[J].O) THEN
  545.           CASE (Stapel[J].O) OF
  546.             '+': Z1.Z := Z1.Z + Z2.Z;
  547.             '-': Z1.Z := Z1.Z - Z2.Z;
  548.             '*': Z1.Z := Z1.Z * Z2.Z;
  549.             '/': IF Z2.Z <> 0 THEN
  550.                    Z1.Z := Z1.Z / Z2.Z
  551.                  ELSE
  552.                    Error := 2;
  553.             '\': Z1.Z := Modulo(Z1.Z, Z2.Z);
  554.             '^': Z1.Z := XhochY(Z1.Z, Z2.Z);
  555.             'W': IF Z2.Z <> 0 THEN
  556.                    Z1.Z := XhochY(Z1.Z,1/Z2.Z)
  557.                  ELSE
  558.                    Error := 2;
  559.             'L': IF Z2.Z >= 0 THEN
  560.                    Z1.Z := Lint(Z1.Z) SHL Lint(Z2.Z)
  561.                  ELSE
  562.                    Error := 2;
  563.             'R': IF Z2.Z >= 0 THEN
  564.                    Z1.Z := Lint(Z1.Z) SHR Lint(Z2.Z)
  565.                  ELSE
  566.                    Error := 2;
  567.             'U': Z1.Z := Lint(Z1.Z) AND Lint(Z2.Z);
  568.             'O': Z1.Z := Lint(Z1.Z) OR Lint(Z2.Z);
  569.             'X': Z1.Z := Lint(Z1.Z) XOR Lint(Z2.Z);
  570.           END;
  571.         IF J = 0 THEN J := 1;
  572.         FOR I := Pred(J) TO Pred(StZeig) DO
  573.           Stapel[I] := Stapel[I+2];
  574.         Stapel[Pred(J)].Az := FALSE;
  575.         Stapel[Pred(J)].Z := Z1.Z;
  576.         IF StZeig > 1 THEN
  577.           DEC(StZeig, 2)
  578.         ELSE
  579.           StZeig := 0;
  580.       END ELSE BEGIN
  581.         Funktionswert(Z2.Z);
  582.         IF Z1.O = #1 THEN Z2.Z := -Z2.Z;
  583.         FOR I := J TO Pred(StZeig) DO
  584.           Stapel[I] := Stapel[Succ(I)];
  585.         DEC(StZeig, 1);
  586.         IF (J = 0) OR (Fkt <> Leer) THEN BEGIN
  587.           Stapel[J].Az := FALSE;
  588.           Stapel[J].Z  := Z2.Z;
  589.         END ELSE BEGIN
  590.           Stapel[Pred(J)].Az := FALSE;
  591.           Stapel[Pred(J)].Z  := Z2.Z;
  592.         END;
  593.       END;
  594.     UNTIL (StZeig <= 1) OR (Error>0);
  595.     IF J = 0 THEN
  596.       Zm := Stapel[J].Z
  597.     ELSE
  598.       Zm := Stapel[Pred(J)].Z;
  599.   END; { Stapelauswerten }
  600.  
  601.   PROCEDURE Stapelschreiben;
  602.   VAR
  603.     A, E, Vz : BYTE;
  604.     Neg      : BOOLEAN;
  605.     Klammer  : ShortInt;
  606.  
  607.     PROCEDURE Upstring;
  608.     VAR
  609.       I : BYTE;
  610.     BEGIN
  611.       FOR I := 1 TO Length(S) DO
  612.         IF S[I] = ',' THEN
  613.           S[I] := '.'
  614.         ELSE
  615.           S[I] := UpCase(S[I]);
  616.     END; { Upstring }
  617.  
  618.     PROCEDURE Skipspace;
  619.     BEGIN
  620.       WHILE s[e] = ' ' DO INC(e);
  621.     END; { Skipspace }
  622.  
  623.     PROCEDURE Funktion;
  624.     VAR
  625.       I : BYTE;
  626.     BEGIN
  627.       Skipspace;
  628.       A := E;  Fkt := leer;
  629.       WHILE (S[E] IN ['!','A'..'Z']) AND (E-A < 3) DO
  630.         INC(E);
  631.       IF E > A THEN BEGIN
  632.         Fkt := Copy(S, A, E-A);
  633.         Err := 1;
  634.         FOR I := 1 TO MaxFkt DO
  635.           IF Fkt = Fkts[I] THEN Err := 0;
  636.         Error := Err;
  637.       END;
  638.     END; { Funktion }
  639.  
  640.     PROCEDURE Hexzahl;
  641.     BEGIN
  642.       A := E;  Basis := 4;
  643.       WHILE Pos(S[E], Hexbinzif) > 0 DO INC(E);
  644.       IF E-A > 9 THEN
  645.         Error := 3
  646.       ELSE BEGIN
  647.         Err  := 0;
  648.         Z1.Z := Dez(Copy(S, A, E-A));
  649.       END;
  650.     END; { Hexzahl }
  651.  
  652.     PROCEDURE Binzahl;
  653.     BEGIN
  654.       A := E;  Basis := 1;
  655.       WHILE S[E] IN ['0','1'] DO INC(E);
  656.       IF E-A > 33 THEN
  657.         Error := 3
  658.       ELSE BEGIN
  659.         Err  := 0;
  660.         Z1.Z := Dez(Copy(S, A, E-A));
  661.       END;
  662.       Fkt := Leer;
  663.     END; { Binzahl }
  664.  
  665.     PROCEDURE Dezzahl;
  666.     BEGIN
  667.       A := E;  Basis := 0;
  668.       WHILE S[E] IN ['0'..'9','.','E'] DO BEGIN
  669.         INC(E);
  670.         IF S[E] = 'E' THEN BEGIN
  671.           INC(E);
  672.           IF S[E] IN ['-','+'] THEN INC(E);
  673.         END;
  674.       END;
  675.       IF E > A THEN
  676.         Val(Copy(S, A, E-A), Z1.Z, Err);
  677.     END; { Dezzahl }
  678.  
  679.     PROCEDURE Zahl;
  680.     BEGIN
  681.       Err := 0;
  682.       IF (Fkt = 'M') AND
  683.          (s[e] IN ['0'..'9']) THEN BEGIN
  684.         Z1.Z := Zmem[Ord(s[e])-48];
  685.         INC(e);
  686.       END ELSE IF Fkt = 'PI' THEN
  687.         Z1.Z := Pi
  688.       ELSE IF Fkt = 'H' THEN
  689.         Hexzahl
  690.       ELSE IF Fkt = 'B' THEN
  691.         Binzahl
  692.       ELSE
  693.         Dezzahl;
  694.       IF (Err > 0) THEN Error:=1;
  695.       IF (E < Length(S)) AND
  696.          NOT (S[E] IN Oper+[' ',')']) THEN
  697.         Error := 1;
  698.     END; { Zahl }
  699.  
  700.     PROCEDURE Push;
  701.     BEGIN
  702.       IF StZeig < Pred(MaxStapel) THEN BEGIN
  703.         Stapel[StZeig] := Z1;
  704.         INC(StZeig);
  705.       END ELSE Error := 1;
  706.     END; { Push }
  707.  
  708.   BEGIN { Stapelschreiben }
  709.     Upstring;
  710.     Flg := TRUE;
  711.     E := 1;  Klammer := 0;  Vz := 0;
  712.     Skipspace;
  713.     REPEAT
  714.       IF (S[E]='-') AND
  715.          ((vz=1) OR (Fkt<>Leer) OR (E=1)) THEN BEGIN
  716.         INC(E);  INC(Vz);  Neg := TRUE
  717.       END ELSE
  718.         Neg := FALSE;
  719.       IF (S[E] IN Oper+['(',')']) THEN BEGIN
  720.         IF (S[E] IN Oper) THEN INC(Vz);
  721.         IF Flg AND (S[E] IN Oper+[')']-['-']) OR
  722.            (Vz>1) THEN
  723.           Error := 1;
  724.         IF NOT Flg THEN
  725.           IF S[E] ='(' THEN Error:=1;
  726.         Flg := S[E] IN Oper+['('];
  727.         Z1.Ac := TRUE;
  728.         Z1.O  := S[E];
  729.         Z1.P  := Rang(Z1.O);
  730.         Z1.F  := Leer;
  731.         IF S[E] = '(' THEN BEGIN
  732.           INC(Klammer);
  733.           IF Neg THEN Error := 1;
  734.         END;
  735.         IF S[E] = ')' THEN DEC(Klammer);
  736.         IF Klammer < 0 THEN Error := 1;
  737.         INC(E);
  738.       END ELSE BEGIN
  739.         Vz := 0;
  740.         Funktion;
  741.         IF (Fkt = Leer) OR (Fkt = 'PI') OR
  742.            (Fkt = 'H') OR (Fkt = 'B') OR
  743.            (Fkt = 'M') THEN BEGIN
  744.           IF NOT Flg THEN Error := 1;
  745.           Zahl;
  746.           Fkt   := leer;
  747.           Z1.Az := FALSE;
  748.           Flg   := FALSE;
  749.           IF Neg THEN Z1.Z := -Z1.Z;
  750.         END ELSE BEGIN
  751.           IF NOT Flg THEN Error := 1
  752.                      ELSE Flg := TRUE;
  753.           IF Neg THEN Z1.O := #1
  754.                  ELSE Z1.O := #0;
  755.           Z1.F  := Fkt;
  756.           Z1.P  := 7;
  757.           Z1.Ac := TRUE;
  758.         END;
  759.       END;
  760.       Push;
  761.       Skipspace;
  762.     UNTIL (E > Length(S)) OR (S[E] = #27) OR
  763.           (Error <> 0);
  764.     IF Flg OR (Klammer <> 0) THEN Error := 1;
  765.   END; { Stapelschreiben }
  766.  
  767.   PROCEDURE Loeschen;
  768.   BEGIN
  769.     FOR StZeig := MaxStapel DOWNTO 0 DO
  770.       WITH Stapel[StZeig] DO BEGIN
  771.         AZ := FALSE;  Z := 0;
  772.       END;
  773.     Error := 0;  Z1.Z := 0;
  774.   END; { Loeschen }
  775.  
  776. {$F+}
  777.   PROCEDURE Start;
  778.   BEGIN
  779.     WiMo := Wa;  Basis := 0;  Satz := '';  Zm := 0;
  780.     FillChar(S, MaxEinL, #0);
  781.     Cursor(FALSE);
  782.     Rahmen;
  783.     CWrite('   @2' + Prg + #10#13);
  784.     Write(' ':9, Version);
  785.     REPEAT
  786.       Loeschen;
  787.       Statusanzeigen;
  788.       Eingeben;
  789.       Stapelschreiben;
  790.       IF (Error = 0) THEN Stapelauswerten;
  791.       Ergebnisanzeigen;
  792.     UNTIL Copy(S, Length(S), 1) = #27;
  793.     Bildholen;
  794.     Cursor(TRUE);
  795.   END; { Start }
  796. {$F-}
  797.  
  798. BEGIN { Hauptprogramm }
  799.   FOR Xc := 0 TO 9 DO Zmem[Xc] := 0;
  800.   Wx := 35;  Wy := 2;
  801.   Val(ParamStr(1), HotKey, Err);
  802.   IF Err <> 0 THEN BEGIN
  803.     WriteLn ('Hotkey-Taste drücken!');
  804.     REPEAT
  805.       Taste(SZ,Key);  HotKey := Ord(Key) SHL 8;
  806.     UNTIL SZ;
  807.   END;
  808.   Laufwerk(1);  IF lfw = '' THEN Laufwerk(2);
  809.   MakeResident(@Start, HotKey);
  810. END. { Hauptprogramm }
  811. (* ------------------------------------------------- *)
  812. (*              Ende von WITA.PAS                    *)
  813.