home *** CD-ROM | disk | FTP | other *** search
- (* ----------------------------------------------------------------------- *)
- (* TURING.PAS *)
- (* ein Turing-Maschinen-Interpreter *)
-
- PROGRAM TM_Interpreter (Input, Output);
-
- (*$C-*)
-
- CONST max_Regeln = 32;
- ymin = 12;
- ymax = 25;
-
- TYPE Regel_Satz = RECORD
- Status, NeuerStatus: INTEGER;
- Code, Aktion : CHAR;
- END;
- MyString = STRING[100];
-
- VAR Datei : TEXT;
- Regel : ARRAY[1..max_Regeln] OF Regel_Satz;
- Band,
- DateiName, Blanks : MyString;
- i, row, Frequenz : INTEGER;
- Regel_Anzahl,
- Regel_Nummer,
- aktuelle_Regel,
- alte_Regel,
- ausgefuehrte_Regeln,
- Bandlaenge,
- Band_Index : INTEGER;
-
- (* ----------------------------------------------------------------------- *)
- PROCEDURE RevOn; (* inverse Textdarstellung *)
-
- BEGIN
- TextColor(Black); TextBackGround(White);
- END;
-
-
- PROCEDURE RevOff; (* normale Textdarstelung *)
-
- BEGIN
- TextColor(White); TextBackGround(Black);
- END;
-
-
- PROCEDURE Scroll_up; (* Inhalt des Ausführungs-Fensters scrollen *)
- (* DelLine löscht eine Zeile und läßt die *)
- BEGIN (* darunter befindlichen "hochrutschen" *)
- row := Succ(row);
- IF row = ymax THEN BEGIN
- GotoXY(1,ymin); DelLine; row := ymax-1;
- END;
- GotoXY(1,row);
- END;
-
-
- PROCEDURE Pause (msec : INTEGER); (* Pause einlegen - klar ?! *)
-
- BEGIN
- Delay(msec);
- END;
-
- (* ----------------------------------------------------------------------- *)
- (* Setzt jeweils um die vier Fenster einen Rahmen: *)
-
- PROCEDURE Rahmen (x1, y1, x2, y2 : INTEGER);
-
- VAR i : INTEGER;
-
- BEGIN
- RevOn; GotoXY(x1,y1);
- FOR i := x1 TO x2 DO BEGIN
- GotoXY(i,y1); Write(' '); GotoXY(i,y2); Write(' ');
- END;
- FOR i := y1+1 TO y2-1 DO BEGIN
- GotoXY(x1,i); Write(' '); GotoXY(x2,i); Write(' ');
- END;
- RevOff;
- END;
-
- (* ----------------------------------------------------------------------- *)
-
- PROCEDURE Bildaufbau;
-
- BEGIN
- ClrScr;
- Rahmen(21,1,80,10); GotoXY(35,1); Write(' Turing-Maschine: ');
- Rahmen(1,1,20,5); GotoXY(4,1); Write(' Regel-Zähler ');
- Rahmen(1,6,20,10); GotoXY(3,6); Write(' Regel-Anzeige ');
- Rahmen(1,11,80,11); GotoXY(3,11); Write(' Turing-Regel ');
- GotoXY(42,11); Write(' Turing-Band ');
- END;
-
- (* ----------------------------------------------------------------------- *)
- (* Turing-Maschine aus Datei einlesen, Eingabe des Bandes, der Start- *)
- (* Position sowie der Pausenzeit: *)
-
- FUNCTION Turing_Maschine_initialisiert : BOOLEAN;
-
- VAR open_err, read_err: BOOLEAN;
- i, x, y : INTEGER;
-
- BEGIN
- REPEAT
- Regel_Anzahl := 0;
- WriteLn; Scroll_up;
- Write('Name der Turing-Maschine eingeben (leere Eingabe beendet!):');
- Scroll_up; ReadLn(DateiName); Scroll_up;
- IF DateiName <> '' THEN BEGIN
- IF Pos('.',DateiName) = 0 THEN DateiName := Concat(DateiName,'.TUR');
- Assign(Datei,DateiName);
- (*$I-*)
- ReSet(Datei);
- (*$I+*)
- open_err := IOResult <> 0; read_err := FALSE;
- IF NOT open_err THEN BEGIN
- WHILE NOT(Eof(Datei) OR read_err) AND (Regel_Anzahl < max_Regeln) DO
- BEGIN
- Regel_Anzahl := Succ(Regel_Anzahl);
- WITH Regel[Regel_Anzahl] DO BEGIN
- (*$I-*)
- ReadLn(Datei, Status, Code, Code, Aktion, Aktion, NeuerStatus);
- (*$I+*)
- read_err := IOResult <> 0;
- Aktion := UpCase(Aktion);
- END;
- END;
- IF read_err THEN BEGIN
- WriteLn('*** Fehler: ungültige Regeln in "',DateiName,'" !');
- Scroll_up; Regel_Anzahl := 0;
- END
- ELSE BEGIN
- GotoXY(53,1); Write(Copy(DateiName,1,14),' '); DateiName := '';
- RevOn; Write(' '); RevOff;
- END;
- END
- ELSE BEGIN
- WriteLn('*** Fehler: "',DateiName,'" nicht gefunden !'); Scroll_up;
- END;
- Close(Datei);
- END;
- UNTIL DateiName = '';
- x := 23; y := 1; (* Regeln im Fenster ausgeben *)
- FOR i := 1 TO max_Regeln DO BEGIN
- y := Succ(y); GotoXY(x,y);
- IF i <= Regel_Anzahl THEN
- WITH Regel[i] DO Write(Status:3,' ',Code:1,' ',Aktion,NeuerStatus:4)
- ELSE
- Write(' ':11);
- IF y = 9 THEN BEGIN y := 1; x := x + 14; END;
- END;
- IF Regel_Anzahl > 0 THEN BEGIN
- WriteLn; Scroll_up;
- WriteLn('Bitte das Band eingeben: '); Scroll_up;
- WriteLn; Scroll_up;
- WriteLn(' | | | | | |',
- ' | | | | | |'); Scroll_up;
- ReadLn(Band); Scroll_up; Bandlaenge := Length(Band);
- IF Bandlaenge > 60 THEN Band := Copy(Band,1,60);
- WriteLn; Scroll_up;
- Write('Startspalte: '); ReadLn(Band_Index); Scroll_up;
- WriteLn; Scroll_up;
- REPEAT
- Write('Pausenzeit (0 - 30 sec.): '); ReadLn(Frequenz); Scroll_up;
- UNTIL Frequenz IN [0..30];
- Frequenz := Frequenz * 1000;
- WriteLn; Scroll_up;
- END;
- Turing_Maschine_initialisiert := Regel_Anzahl <> 0;
- END;
-
- (* ----------------------------------------------------------------------- *)
- (* Unterlegt beim Programmlauf den soeben ausgeführten Turing-Befehl im *)
- (* Fenster rechts oben: *)
-
- PROCEDURE invertiere_Regel;
-
- PROCEDURE XY_Position (Regel_Nummer : INTEGER);
-
- VAR x, y : INTEGER;
-
- BEGIN
- x := 23 + (Pred(Regel_Nummer) DIV 8) * 14;
- y := 1 + Regel_Nummer - (Pred(Regel_Nummer) DIV 8) * 8;
- GotoXY(x,y);
- END;
-
- BEGIN
- IF alte_Regel > 0 THEN BEGIN
- XY_Position(alte_Regel); RevOff;
- WITH Regel[alte_Regel] DO
- Write(Status:3,' ',Code:1,' ',Aktion,NeuerStatus:4);
- END;
- XY_Position(aktuelle_Regel); RevOn;
- WITH Regel[aktuelle_Regel] DO
- Write(Status:3,' ',Code:1,' ',Aktion,NeuerStatus:4);
- RevOff;
- alte_Regel := aktuelle_Regel;
- END;
-
- (* ----------------------------------------------------------------------- *)
- (* Zeigt die Regeln sowie das Turing-Band während des Programmlaufs: *)
-
- PROCEDURE zeige_Regelausfuehrung;
-
- BEGIN
- GotoXY(1,row);
- WITH Regel[aktuelle_Regel] DO BEGIN
- Write(Status:6,' ',Code:1,' ',Aktion,NeuerStatus:4,' ':5);
- IF Aktion IN ['0','1'] THEN
- Band[Band_Index] := Aktion;
- RevOff; Write(Copy(Band,1,Band_Index-1));
- RevOn; Write(Copy(Band,Band_Index,1));
- RevOff; WriteLn(Copy(Band,Band_Index+1,Bandlaenge));
- Scroll_up;
- END
- END;
-
- (* ----------------------------------------------------------------------- *)
- (* Ausführung der TURING-MASCHINE auf dem TURING-BAND: *)
-
- PROCEDURE Programmlauf;
-
- VAR control : INTEGER;
- break : BOOLEAN;
-
- BEGIN
- aktuelle_Regel := 0; alte_Regel := 0;
- Regel_Nummer := 0; ausgefuehrte_Regeln := 0;
- REPEAT
- control := 0;
- REPEAT { Suche der anzuwendenden Turing-Regel }
- aktuelle_Regel := Succ(aktuelle_Regel);
- control := Succ(control);
- break := control > 1000;
- IF break THEN BEGIN
- WriteLn; Scroll_up; Write(' ');
- WriteLn('Abbruch wegen Regelfehler !!'); Scroll_up;
- END;
- IF aktuelle_Regel > Regel_Anzahl THEN aktuelle_Regel := 1;
- UNTIL ((Regel[aktuelle_Regel].Status = Regel_Nummer) AND
- (Regel[aktuelle_Regel].Code = Band[Band_Index])) OR break;
- IF NOT break THEN BEGIN
- invertiere_Regel;
- GotoXY(4,8);
- WITH Regel[aktuelle_Regel] DO
- Write(Status:3,' ',Code:1,' ',Aktion,NeuerStatus:4);
- ausgefuehrte_Regeln := Succ(ausgefuehrte_Regeln);
- GotoXY(8,3); Write(ausgefuehrte_Regeln:5);
- CASE Regel[aktuelle_Regel].Aktion OF
- 'R' : Band_Index := Succ(Band_Index);
- 'L' : Band_Index := Pred(Band_Index);
- END;
- zeige_Regelausfuehrung;
- Regel_Nummer := Regel[aktuelle_Regel].NeuerStatus;
- IF (Band_Index = Bandlaenge) OR (Band_Index = 1) THEN BEGIN
- WriteLn; Scroll_up;
- WriteLn(' Band-Ende erreicht !! ');
- Scroll_up; break := TRUE;
- END;
- Pause(Frequenz);
- END;
- UNTIL break OR KeyPressed;
- END;
-
- (* ----------------------------------------------------------------------- *)
-
- BEGIN
- Bildaufbau; row := ymin;
- WriteLn; Scroll_up; WriteLn; Scroll_up;
- WriteLn('Turing-Maschinen-Interpreter v1.0',
- ' (C) 1988 B.R.Wittek, MC & PASCAL INT.'); Scroll_up;
- WriteLn; Scroll_up; WriteLn; Scroll_up;
- WHILE Turing_Maschine_initialisiert DO Programmlauf;
- ClrScr;
- END.