home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / spezial / 02 / texte / pascomp.8 < prev   
Encoding:
Text File  |  1980-01-03  |  20.3 KB  |  526 lines

  1.  
  2.  
  3. PASCOMP
  4.  
  5. PASCAL baut einen Pascal-Compiler
  6.  
  7.  
  8. Teil 8: Erweiterungen
  9.         von Johannes Velmans
  10.  
  11.  
  12. In  diesem letzten Teil der Serie über Compilerbau möchte ich Sie
  13. mit  dem Erweiterungskonzept des PASCOMP-Pascalcompilers vertraut
  14. machen.  Nach  langem  Warten  ist nun mittlerweile die komplette
  15. Compilersource  für  jeden  PASCAL-Leser  zugänglich.  Sicherlich
  16. stellt  der  eine  oder andere Leser gewisse Anforderungen an den
  17. Compiler,  die  dieser bis jetzt noch nicht erfüllen kann. Aller-
  18. dings  soll das PASCOMP-Projekt, wie das in einer der ersten Fol-
  19. gen  bereits betont wurde, keinen "Super"-Pascal-Compiler hervor-
  20. bringen,  sondern nur einen Einblick in den Compilerbau verschaf-
  21. fen. Erinnern wir uns...
  22.  
  23. So  mußten  fast immer Kompromisse hinsichtlich der Effizienz ge-
  24. macht  werden, da an vielen Stellen immer wieder effizientere Me-
  25. thoden  zu  Gunsten einfacherer und verständlicherer Verfahren in
  26. den  Hintergrund traten. Einige Vorteile haben Sie als regelmäßi-
  27. ger  PASCAL-Leser jedoch errungen. Sie verfügen immerhin über ei-
  28. nen  kompletten und lauffähigen Standard-Pascal-Compiler. Bislang
  29. existiert  sicherlich  genügend  Material, das eine Einführung in
  30. den  Compilerbau  ermöglicht.  Allerdings  gibt es in fast keinem
  31. Werk  so  etwas  wie  einen  kompletten und lauffähigen Compiler.
  32. Meist  beschränkt  man sich in der Literatur auf die Konstruktion
  33. eines Mini-Compilers, der dann irgendwelche Teilmengen einer gän-
  34. gigen Programmiersprache akzeptiert.
  35.  
  36. Mit  diesem  vollständigen Compiler- Listing sind Sie nun auch in
  37. der  Lage - basierend auf diesen Compiler - Implementierungen an-
  38. derer imperativer Programmiersprachen wie Basic, Modula-2, C usw.
  39. vorzunehmen.  Dies  entspricht übrigens dem gängigen Implementie-
  40. rungs-Verfahren  einer neuen Sprache: Diese wird nämlich in einer
  41. bereits bestehenden Programmiersprache entwickelt, die die größte
  42. Teilmenge  der  neuen  Sprache  beinhaltet. Das bedeutet aber zu-
  43. gleich,  daß  dieser Compiler auch "offen" für Erweiterungen ist.
  44. Ähnlich  wie man seinen Rechner durch Hardware-Karten "aufblasen"
  45. kann, so kann man zum Beispiel den PASCOMP-Compiler um die vorde-
  46. finierten  Typen  "String"  und "long integer" erweitern oder das
  47. Konzept der parallelen Prozesse einführen (Hanssen-Pascal).
  48.  
  49. Wie man solche Erweiterungen konsequent durch den Aufbau der Com-
  50. piler- Source "hindurchzieht" soll das Thema dieser letzten Folge
  51. sein. Also auf zum letzten Angriff ....
  52.  
  53.  
  54. Compilererweiterungen
  55.  
  56. Derjenige,  der  sich  den  PASCOMP- Compiler näher ansieht, wird
  57. feststellen,  daß  doch einige Routinen über den vorgeschriebenen
  58. Standard  hinausgehen. Da ist zum Beispiel die ansatzweise Imple-
  59. mentierung von Betriebssystem-Aufrufen des Atari ST und die voll-
  60. ständige  Implementierung  des quasi-Standard-Typs "long integer"
  61. zu  nennen.  Anhand der "long integer" Implementierung wollen wir
  62. uns  die  Erweiterung  der  Compiler-Source mit selbstgebastelten
  63. Typen näher anschauen.
  64.  
  65. Zunächst  aber wollen wir dem Kind erst mal einen Namen geben. In
  66. ST- Pascal wird der entsprechende Typ mit "Long_Integer" bezeich-
  67. net.  Dies  erscheint ein bischen lang. Meine Wahl fiel daher auf
  68. "LongInt".  Initialisiert wird der Name "LongInt" in der Prozedur
  69. "Initstandardtypes".  Wer sich einen anderen Namen für diesen Typ
  70. wünscht, der kann in dieser Prozedur den entsprechenden Namen än-
  71. dern. So einfach geht das. Bei der weiteren Besprechung aber soll
  72. der  Name "LongInt" zur Bezeichnung dieses Types beibehalten wer-
  73. den. Programmstücke wie
  74.  
  75.   ...
  76.   VAR longinteger: LongInt;
  77.   ...
  78.   longinteger := longinteger + 10;
  79.   ...
  80.  
  81. müssen  daher  im  Nachfolgenden vom Compiler als richtig erkannt
  82. werden.
  83.  
  84. Wie  geht  man nun aber die Sache an und strickt an den richtigen
  85. Source- Stellen die richtigen Erweiterungen ein? Nun, im Speziel-
  86. len  wird  das sicherlich unterschiedliche Vorgehensweisen bedin-
  87. gen.  Im Großen und Ganzen läßt sich aber sagen, daß ein schritt-
  88. weises  Abklären  der nachfolgend aufgeführten Punkte hinreichend
  89. für  eine  geeignete Implementierung des gewünschten Typs, Proze-
  90. dur,  Funktion  o.ä.  ist.  Hierbei ist auch zu beachten, daß zum
  91. Beispiel die nachträgliche Aufnahme von neuen Standard-Prozeduren
  92. in  das Source- Listing weitaus einfacher ist als die hier darge-
  93. stellte  Typ-Implementierung, da viele der vorgestellten Schritte
  94. einfach entfallen. Und dann noch ein Tip: Da in dem nachfolgenden
  95. Text  sehr oft Bezüge zum Compiler- Listing auftreten, ist es für
  96. das  bessere Verständnis am sinnvollsten den Compiler-Text griff-
  97. bereit zu halten.
  98.  Nun - fangen wir an ....
  99.  
  100. 1. Schritt:
  101. Konstanten, Typen und Variablenerweiterungen.
  102.  
  103. Die meisten Konstanten, die im Compiler-Listing verwendet werden,
  104. stehen  in  direktem  Zusammenhang  mit der Speicherabbildung der
  105. vordefinierten  Typen. Die Konstantennamen "intsize", "realsize",
  106. "boolsize" usw. deuten dies an. Auch für den Typ "LongInt" findet
  107. sich  eine  Konstante "longsize" (=1), welche die Größe der Spei-
  108. cherabbildung  -  bezogen auf den Interpreterspeicher - festlegt.
  109. Fast alle in einem Pascal-Programm auftretenden Konstanten werden
  110. in Verbunden (Records) vom Typ Konstante abgelegt. Hier speichern
  111. wir auch unsere "LongInt"-Konstanten. Dazu muß dieser Record ent-
  112. sprechend erweitert werden. Zuerst einmal vergößern wird den Auf-
  113. zählungstyp Constklasse:
  114.  
  115. Constklasse=(reell,setkonst,strg,long);
  116.  
  117. und  führen  gleichzeitig in den Typ Konstante eine neue Variante
  118. ein, und zwar:
  119.  
  120. Konstante =
  121.   RECORD
  122.     CASE konstart: constklasse OF
  123.       ...
  124.       long: (savval: Long_Integer); (**)
  125.     END;
  126.  
  127. Zu  (**): Hier weicht die Implementierung, wie an wenigen anderen
  128. Stellen und hauptsächlich bei Benutzung von Stringfunktionen, von
  129. der   Standard-Pascal-Definition   ab.   Der  hier  benutzte  Typ
  130. "Long_Integer"  ist dem ST-Pascal für den ATARI ST entnommen, in-
  131. dem auch das Compiler-Listing erstellt wurde. Verwendet man ande-
  132. re  Compiler  zur  Übersetzung  von PASCOMP, die diesen Typ nicht
  133. implementiert  haben,  so kann man den Typ "LongInt" zum Beispiel
  134. auch  durch  zwei normale Integer-Typen oder noch einfacher durch
  135. den Real-Typ programmieren. Dies sähe dann in etwa so aus:
  136.  
  137.  
  138. Konstante =
  139.   RECORD
  140.     CASE konstart: constklasse OF
  141.       ...
  142.       long: (highword,lowword: INTEGER);
  143. bzw.
  144.       long: (savval: REAL);
  145.     END;
  146.  
  147.  
  148. Im  übrigen wird es in den meisten Fällen von Typerweiterungen so
  149. sein,  daß  die neu zu implementierenden Typen von dem die Source
  150. übersetzenden  Compiler  nicht  beherrscht  werden. Man denke zum
  151. Beispiel  an  die Einführung eines Typs für imaginäre Zahlen, der
  152. sicherlich  in  vielen Mathematik-Programmen einen Sinn macht und
  153. es  so  von Vorteil wäre, diesen Typ als Standardtyp definiert zu
  154. wissen.  Dabei wird es wohl keinen Compiler geben, mit dem dieser
  155. Typ  wie  in  unserem Beispiel der Typ "LongInt" direkt implemen-
  156. tiert  werden  kann.  Soweit zur Einführung von weiteren Typen in
  157. die  Compiler-Source.  Als  letztes  wird noch eine neue Variable
  158. "LongPtr"  vom  Typ "STP" eingeführt, der eine wichtige Bedeutung
  159. bei späteren Kompatibilitäts- Überprüfungen zu Gute kommt.
  160.  
  161.  
  162. 2.Schritt:
  163. Definition der auf "LongInt" zulässigen Operationen
  164.  
  165. Für  den Typ "LongInt" sind die Arithmetik-Operationen -un, +, -,
  166. *,  DIV und MOD, sowie die Ein- und Ausgabe- Prozeduren Write und
  167. Read  zugelassen.  -un  bezeichnet dabei das unäre Minus, das zum
  168. Beispiel  in der Zuweisung a := -1 vorkommt. Eine der Hauptaufga-
  169. ben  der  Compiler-Source-Erweiterung besteht nun darin, für alle
  170. diese  Operationen  und  Prozeduren  entsprechende P-Code-Befehle
  171. bereitzustellen.  Wer  den  Compiler-Source-Text überfliegt, wird
  172. sicherlich  auch  die  verschiedenen  Initialisierungs-Prozeduren
  173. entdecken.
  174.  
  175. Für diesen zweiten Schritt sind die Prozeduren "InitStdProcs" und
  176. "InitPCodeInstruction"  von Bedeutung. In den damit korrespondie-
  177. renden Arrays "StdNames" und "PCO" werden P-Code- Befehle für die
  178. Ein-  und  Ausgabe  sowie  für  die Arithmetik untergebracht. Die
  179. nachfolgende Tabelle gibt einen Ausschnitt der beiden Arrays wie-
  180. der:
  181.  
  182. neue "long integer" Operationen:
  183.  
  184.  
  185.        Operation  │  P-Code
  186.      ─────────────┼──────────────
  187.            -un    │  ngl
  188.              +    │  adl
  189.              -    │  sbl
  190.              *    │  mpl
  191.            div    │  dvl
  192.            mod    │  mdl
  193.                   │  ilo,ilt
  194.                   │  (Typanpassung Integer -> LongInt)
  195.                   │  lfo,lft
  196.                   │  (Typanpassung LongInt -> Real)
  197.          write    │  wrl
  198.           read    │  rdl
  199.  
  200.  
  201.  
  202. 3. Schritt:
  203. Kompatibilitätsprobleme
  204.  
  205. In  der gleichen Weise, in der auch Kompatibilitäten zwischen In-
  206. teger  und  Real  überprüft  werden, muß auch der Typ LongInt auf
  207. Typverträglichkeit hinsichtlich der bereits bestehenden Standard-
  208. Typen  untersucht  werden.  Zur  besseren Veranschaulichung seien
  209. sämtliche  Typkombinationen zwischen Integer, LongInt und Real in
  210. einer Tabelle dargestellt. Dabei bedeutet xi ist kompatibel zu yj
  211. genau  dann, wenn yj := xi eine erlaubte Zuweisung darstellt. Die
  212. Kürzel k und nk stehen für kompatibel und nicht kompatibel.
  213.  
  214.  
  215.   xi\yi │ INTEGER │ LONGINT │ REAL
  216. ────────┼─────────┼─────────┼──────
  217. INTEGER │    k    │    k    │   k
  218. ────────┼─────────┼─────────┼──────
  219. LONGINT │    nk   │    k    │   k
  220. ────────┼─────────┼─────────┼──────
  221. REAL    │    nk   │    nk   │   k
  222.  
  223.  
  224.  
  225. Die Tabelle macht deutlich, daß in genau drei Fällen Typanpassun-
  226. gen erforderlich werden. Dies sind
  227.  
  228.   1. INTEGER -> REAL    (flo,flt).
  229.   2. INTEGER -> LONGINT (ilo,ilt).
  230.   3. LONGINT -> REAL    (lfo,lft).
  231.  
  232. Da der erste Fall unabhängig von unserem neueingeführten Typ ist,
  233. bleiben  nur  die beiden letzten Fälle zu behandeln. Die in Klam-
  234. mern  angegebenen Befehle, die im Array "PCO" ab Index 66 gespei-
  235. chert  sind,  bezeichnen die P-Code-Befehle für die Typanpassung.
  236. Dazu  eine  kleine  Erklärung: Wie eigentlich alle P-Code-Befehle
  237. haben auch die Typanpassungs-Befehle eine unmittelbare Auswirkung
  238. auf  den Laufzeitkeller (s. PASCAL 1/88 & 2/88, Codeerzeugung und
  239. Interpreter).  Mit  't' endende Befehle beziehen sich dabei immer
  240. auf  die Spitze des Laufzeitkellers und führen ihre Konvertierung
  241. dort  aus.  Die  Befehle, die auf 'o' enden, bewirken eine Typan-
  242. passung auf den Inhalt des zweiten Elements oben auf dem Stack.
  243.  
  244. Warum gibt es aber zu jedem der drei genannten Fälle zwei P-Code-
  245. Befehle  für  je eine Typanpassung. Eine Antwort hierauf gibt ein
  246. näherer  Einblick  in die Implementierung der Auswertung von Aus-
  247. drücken.
  248.  
  249.  
  250. 4. Schritt:
  251. Auswertung von Ausdrücken.
  252.  
  253. Falls  wir unseren neuen Typ nicht mit Operatoren versehen haben,
  254. so  können  wir diesen Schritt einfach weglassen. Andernfalls muß
  255. der Teil des Compilers, der sich mit dem Auswerten von Ausdrücken
  256. beschäftigt,  näher untersucht werden. Genau dies ist bei dem Typ
  257. "LongInt"  der Fall. Der Compiler zerlegt jeden Ausdruck in seine
  258. entsprechende  Postfix-Form.  Beispiel:  Der Ausdruck a+b wird zu
  259. ab+ umgeformt. Bei der Auswertung des Ausdrucks werden immer zwei
  260. Operanden auf den Stack gelegt und mit dem Operator verknüpft. Im
  261. Anschluß  hieran  wird  das Ergebnis der Auswertung auf den Stack
  262. zurückgelegt.
  263.  
  264. Von  Bedeutung ist nun, daß eine mögliche Typanpassung nur unmit-
  265. telbar  vor der Verarbeitung mit dem Operator durchgeführt werden
  266. kann.  Anschaulich bedeutet das: Auf dem Stack befinden sich zwei
  267. Operanden, deren Attribute in den Variablen "LastAttr" und "attr"
  268. stehen.  Der  zugehörige  Operator  ist in der Variablen "LastOp"
  269. gespeichert.  Muß  vor  der Berechnung des Ausdrucks noch ein Typ
  270. angepasst werden, so werden Typanpassungs-Befehle aus dem P-Code-
  271. Befehlssatz gewählt, die auf 'o' enden, wenn "LastAttr" an "Attr"
  272. angepasst  werden muß. Wenn "Attr" an "LastAttr" angepasst werden
  273. muß, werden Befehle mit einer Endung 't' gewählt, .
  274.  
  275. Ein  kleines  Pascal-Programm  soll diesen Sachverhalt verdeutli-
  276. chen:
  277.  
  278.  
  279. PROGRAM a;
  280. VAR i: INTEGER; l: LONGINT;
  281. BEGIN
  282.   l := l+i;
  283.   l := i+l
  284. END.
  285.  
  286. Setzt  man  unseren  Compiler  auf  dieses kleine Programm an, so
  287. "spuckt" er das P-Code-Stück aus, wie in Abb.1 zu sehen ist. Die-
  288. se  hier  im  vierten  Schritt beschriebene Anpassung wird in den
  289. Rümpfen  der Prozedur "Term" (*, DIV, MOD) und "SimpleExpression"
  290. (+,-)  durchgeführt  und  ist anhand des Compiler-Listings leicht
  291. nachzuvollziehen.
  292.  
  293.  
  294. Abb.1:
  295.  
  296.  l      3
  297.    ent      1   l   4
  298.    ent      2   l   5
  299.                           ; 1.Zuweisung.
  300.    ldol            10     ; lade Inhalt von l auf den Stack.
  301.    ldoi             9     ; lade Inhalt von i auf den Stack.
  302.    ilt                    ; konvertiere den Wert von i in einen
  303.                             longint Wert.
  304.    adl
  305.    srol            10
  306.                           ; 2.Zuweisung.
  307.    ldoi             9     ; lade Inhalt von i auf den Stack.
  308.    ldol            10     ; lade Inhalt von l auf den Stack.
  309.    ilo                    ; konvertiere den Wert von i in einen
  310.                             longint Wert.
  311.    adl
  312.    srol            10
  313.    retp
  314.   l     4=11
  315.   l     5=7
  316.   q
  317.   i     0
  318.    mst              0
  319.    cup      0   l   3
  320.    stp
  321.   q
  322.  
  323. Der erzeugte P-Code zur Typanpassung in Ausdrücken.
  324.  
  325.  
  326. 5. Schritt:
  327. Verwendung des neuen Typs bei Prozedur-Aufrufen.
  328.  
  329. Der Aufruf von benutzerdefinierten Prozeduren und Funktionen fin-
  330. det  im Source-Listing in der Prozedur "ExtendedCall" statt. Auch
  331. an  dieser Stelle darf man nicht vergessen, daß man auch hier mit
  332. Kompatibilitäts- Problemen zu kämpfen hat. Denn bei einer Überga-
  333. be  von Aktual-Parametern müssen die beiden betreffenden zu über-
  334. prüfenden  Typen nicht gleich, sondern nur verträglich zueinander
  335. sein.  Eine entsprechende Anpassung von LongInt an Real und Inte-
  336. ger  an  LongInt  muß somit in die Pascal- Source mit aufgenommen
  337. werden.  Auch  hier soll ein kleines Pascal-Programm diese Anpas-
  338. sung erläutern:
  339.  
  340. PROGRAM b;
  341.  
  342. VAR l: LongInt;
  343.  
  344.   PROCEDURE anpassung (r: REAL);
  345.   BEGIN
  346.   END;
  347.  
  348. BEGIN
  349.   anpassung(l)
  350. end.
  351.  
  352.  
  353. Bei  diesem Programm gibt der Compiler den in Abb. 2 gezeigten P-
  354. Code aus.
  355.  
  356.  
  357. Abb.2:
  358.  
  359.  1    3                ; Prozedur "Anpassung"
  360.   ent     1   l   4
  361.   ent     2   l   5
  362.   retp
  363.  l     4=6
  364.  l     5=5
  365.  l    6                ; Hauptprogramm
  366.   ent     1   l   7
  367.   ent     2   l   8
  368.   mst             0    ; Eintritt in den Prozeduraufruf.
  369.   ldol            9    ; Lade den Inhalt von l auf den Stack.
  370.   lft                  ; konvertiere den Wert von l in eine
  371.                          Realzahl.
  372.   cup     1   l   3    ; Aufruf der Prozedur "Anpassung"
  373.   retp
  374.  l    7=10
  375.  l    8=6
  376.  q
  377.  i    0
  378.   mst             0
  379.   cup     0   l   6
  380.   stp
  381.  q
  382.  
  383.  
  384. Der P-Code zur Typanpassung bei Aufrufen benutzerdefinierter Pro-
  385. zeduren
  386.  
  387.  
  388. Sind  nun alle fünf Schritte nacheinander abgearbeitet worden, so
  389. wird  unser erweitertes Compiler-Listing übersetzt - in der Hoff-
  390. nung,  mit dem neu erstellten Compiler ein Werkzeug geschaffen zu
  391. haben, das unseren Ansprüchen ein wenig mehr genügt. Funktioniert
  392. erst  mal  der Compiler, so hat man das größte Stück Arbeit schon
  393. hinter  sich gebracht. Was bleibt denn noch zu tun? Nun, der Com-
  394. piler  behandelt  jetzt  Variablen vom Typ "LongInt" korrekt. Für
  395. den  Interpreter ist die Erweiterung des Befehlssatzes allerdings
  396. noch  ein  "böhmisches  Dorf". Und genau das soll im sechsten und
  397. letzten Schritt geändert werden.
  398.  
  399.  
  400. 6. Schritt:
  401. Implementierung des erweiterten P- Code-Befehlssatzes.
  402.  
  403. Als  erstes  muß dem Interpreter mitgeteilt werden, daß er ab so-
  404. fort  in  der Lage ist, den Typ "LongInt" in seine Speicherklasse
  405. mit  aufzunehmen.  Dies  geschieht mittels Einführung einer neuen
  406. Variante  im  globalen  Interpreter-Typ  "StoreRec", der dann wie
  407. folgt aussieht:
  408.  
  409. StoreRec =
  410.   PACKED RECORD
  411.     CASE DataType OF
  412.       ...
  413.       long: (vl: Long_Integer);
  414.       ...
  415.     END;
  416.  
  417. Für  den  Typ "Long_Integer" gilt auch hier das bei der Implemen-
  418. tierung im Compiler gesagte. Als nächstes müssen die im Programm-
  419. text  auftretenden  "LongInt"-Konstanten ähnlich wie bei Set- und
  420. Real-Konstanten  in ein separates Array untergebracht werden. So-
  421. mit vereinbaren wir zwei neue Variable:
  422.  
  423. LongTable: ARRAY [1..MaxLong] OF Long_Integer;
  424. LongPos : INTEGER;
  425. (* gibt den maximal belegten Index in LongTable an *)
  426.  
  427. Was  nun noch fehlt ist die Einführung der neuen Namen in die Ar-
  428. rays "PCO" und "SPTable". Dies wird in der Prozedur "Init" durch-
  429. geführt.  Wer  sich  noch an die Folge über den Interpreter erin-
  430. nert,  dem  wird sicherlich die Zweiteilung des Interpreters noch
  431. ein Begriff sein. In der ersten Phase - der Assemblerphase - wird
  432. der  textuelle P-Code in einen Zahlencode umgewandelt. Gleichzei-
  433. tig  werden  Sprungtabellen  und  Konstantentabellen gefüllt. Die
  434. daran anschließende Interpreterphase führt diesen Zahlencode dann
  435. Anweisung für Anweisung aus. Was die Erweiterung der ersten Phase
  436. angeht,  so  besteht  diese  allein darin, in der Prozedur "Load-
  437. Const" die Konstantentabelle "LongTable" mit eventuell auftreten-
  438. den LongInt-Konstanten zu füllen. Das hier einzufügende Programm-
  439. stück erklärt sich von selbst:
  440.  
  441.  ...
  442.  Read(PCode,LongKonst);
  443.  IF LongPos < MaxLong THEN
  444.    LongPos := LongPos+1
  445.  ELSE      (* Programm abbrechen: *)
  446.    Error('longtable overflow');
  447.  LongTable[LongPos] := LongKonst;
  448.  ...
  449.  
  450. Die Erweiterungen in der zweiten Phase sind da schon etwas umfan-
  451. greicher.  Hier  werden  ausschließlich die Implementierungen der
  452. neuen  Operatoren (+,-,*,....) und Standardprozeduren (Read, Wri-
  453. te)  aufgenommen.  Die  Interpretation von "rdl" und "wrl" findet
  454. dabei  in den Prozeduren "ReadLong" und "WriteLong" statt, wohin-
  455. gegen die Operatoren +,-,*,.... in der Prozedur "NextCase" inter-
  456. pretiert werden und deren Implementierung wiederum so leicht ver-
  457. ständlich ist, daß der Programmtext für sich selbst spricht:
  458.  
  459. PROCEDURE NextCase (Op: INTEGER);
  460. BEGIN
  461.   CASE Op OF
  462.     62 : BEGIN             (* ADL *)
  463.            SP:=SP-1;
  464.            STORE[SP].VL :=
  465.               STORE[SP].VL+STORE[SP+1].VL
  466.          END;
  467.     63 : BEGIN             (* SBL *)
  468.            SP:=SP-1;
  469.            STORE[SP].VL :=
  470.              STORE[SP].VL-STORE[SP+1].VL
  471.          END;
  472.     64 : BEGIN             (* DVL *)
  473.            SP:=SP-1;
  474.            STORE[SP].VL :=
  475.              STORE[SP].VL DIV STORE[SP+1].VL
  476.          END;
  477.     65 : BEGIN              (* MDL *)
  478.            SP:=SP-1;
  479.            STORE[SP].VL :=
  480.              STORE[SP].VL MOD STORE[SP+1].VL
  481.          END;
  482.     68 : BEGIN              (* MPL *)
  483.            SP:=SP-1;
  484.            STORE[SP].VL :=
  485.              STORE[SP].VL*STORE[SP+1].VL
  486.          END;
  487.     66 : STORE[SP-1].VL:=STORE[SP-1].VI; (* ILO *)
  488.     67 : STORE[SP].VL:=STORE[SP].VI;     (* ILT *)
  489.     69 : STORE[SP].VL:=-STORE[SP].VL;    (* NGL *)
  490.     70 : STORE[SP-1].VR:=STORE[SP-1].VL; (* LFO *)
  491.     71 : STORE[SP].VR:=STORE[SP].VL;     (* LFT *)
  492.     ...
  493.   END
  494. END;
  495.  
  496.  
  497. Mit  diesen  selbstgebastelten  Erweiterungen  ist unser PASCOMP-
  498. Compiler nun in der Lage, den Typ "LongInt" (hoffentlich) korrekt
  499. zu compilieren und zu interpretieren. Vielleicht hat ja jetzt der
  500. eine oder andere Leser Lust bekommen, selbst neue Typen, Prozedu-
  501. ren  o.ä.  in seinen eigenen Compiler einzubauen. Sicherlich wird
  502. das keine 5-Minuten-Arbeit sein, aber man wird nach gewisser Zeit
  503. feststellen,  daß  die  ca. 100 Seiten Papier, die bei einem Aus-
  504. druck  von Compiler- und Interpreter-Listing schon mal herauskom-
  505. men, doch ein relativ einfaches Konzept, das sich auf einige Sei-
  506. ten zusammenfassen läßt, aufweisen.
  507.  
  508. Und  demjenigen, der sich dann noch näher mit dem Compilerbau be-
  509. schäftigt, wird bald klar werden, daß die beschriebenen Verfahren
  510. und  Techniken sich nicht nur auf den Compilerbau beschränken. So
  511. findet  man  zum  Beispiel  Scanner in fast allen Programmen, die
  512. etwas  mit Eingabe von Informationen zu tun haben - meist mit an-
  513. derem Namen oder gar nicht als separaten Programmteil deklariert.
  514. Parser  spielen  eine  große  Rolle in der KI und in Information-
  515. Retrievel-  Systemen.  Alles in allem kann man die in diesem Pro-
  516. jekt  dargestellten Verfahren als einen großen Werkzeugkasten für
  517. viele  Bereiche  der Informatik ansehen. Wie hoffen, daß dies mit
  518. dieser Serie verdeutlichen werden konnte.
  519.  
  520. Mit  dieser  Folge  sind  wir nun am Ende der Serie angelangt. Es
  521. gäbe  natürlich  noch  vieles  zu  berichten, vor allem, weil der
  522. Fortschritt im Bereich der Informatik so ungeheuer schnell voran-
  523. schreitet.  Wir  bedanken uns bei Ihnen, liebe Leser, daß Sie bis
  524. hierhin  gefolgt  sind  und wünschen Ihnen noch viel Spaß mit dem
  525. Compiler.
  526.