home *** CD-ROM | disk | FTP | other *** search
/ AMIGA PD 1 / AMIGA-PD-1.iso / Programme_zum_Heft / Programmieren / Workshops / E-Compiler / Doks / E-Doku.Deutsch.TXT < prev    next >
Text File  |  1994-04-08  |  112KB  |  3,213 lines

  1. Inhalt
  2.  
  3. }                        Compiler für die E Sprache
  4.                          Von Wouter van Oortmerssen
  5.  
  6.                        Supertolle Preise zu gewinnen
  7.  
  8. }
  9.       1. Formatierung
  10.       2. Direkte Werte
  11.       3. Ausdrücke
  12.       4. Operatoren
  13.       5. Statements
  14.       6. Funktions Definition und Deklaration
  15.       7. Deklaration von Konstanten
  16.       8. Typen
  17.       9. Eingebaute Funktionen
  18.       10. Library Funktionen und Module
  19.       11. Ausgewertete Ausdrücke
  20.       12. Fließkommaunterstützung
  21.       13. Exception Behandlung
  22.       14. Objekt-Orientiertes Programmieren
  23.       15. Der Inline Assembler
  24.       16. Eingebaute Ausgaben
  25. Bemerkung
  26.  
  27.  
  28. Hääää, reingelegt... ROFL
  29.  
  30. Für den Fall, daß irgendjemand Fragen zur Übersetzung einzelner Kapitel
  31. hat, wende er sich bitte an:
  32.  
  33.   Kapitel 1,4-5,7-9,11-12,15  :  Rolf Breuer
  34.                                  Marktstr. 13
  35.                                  45891 Gelsenkirchen
  36.  
  37.   Kapitel 2,3,14,             :  Daniel van Gerpen
  38.   Amiga-Guide Fassung            Alter Postweg 3
  39.                                  26759 Hinte
  40.  
  41.   Kapitel 10                  :  Gregor Goldbach
  42.                                  Grüner Weg 10
  43.                                  21423 Pattensen
  44.  
  45.   Kapitel 16                  :  Christoph Lange
  46.                                  Altdorferstr. 19
  47.                                  63739 Aschaffenburg
  48.  
  49.   Kapitel 6, 13               :  Jörg Wach
  50.                                  Waitzstr. 75
  51.                                  24105 Kiel
  52.  
  53.  
  54. Wenn jemand eine, seiner Meinung nach besser, Übersetzung eines oder
  55. mehrerer Kapitel hat, dann kann er diese an Daniel van Gerpen (s.o.)
  56. schicken, und wird dann beim nächsten Mal hier erwähnt.
  57.  
  58. Index
  59.  
  60.  
  61. }                        Compiler für die E Sprache
  62.                          Von Wouter van Oortmerssen
  63.  
  64.                                     Index
  65.  
  66.  
  67.       1. Formatierung
  68.          A. Tabulatoren(tabs), Zeilenvorschübe(lf) usw.
  69.          B. Kommentare
  70.          C. Identifier und Typen
  71.       2. Direkte Werte
  72.          A. Dezimalzahlen (1)
  73.          B. Hexadezimalzahlen ($1)
  74.          C. Binärzahlen (%1)
  75.          D. Fließkommazahlen (1.0)
  76.          E. Zeichen ('a')
  77.          F. Zeichenketten ('bla')
  78.          G. Listen ([1,2,3]) und symbolische Listen
  79.       3. Ausdrücke
  80.          A. Format
  81.          B. Abarbeitung und Anordnung
  82.          C. Arten von Ausdrücken
  83.          D. Funktionsaufrufe
  84.       4. Operatoren
  85.          A. Mathematische (+ - * /)
  86.          B. Vergleiche (= <> > < >= <=)
  87.          C. Logische und Bitweise (AND OR)
  88.          D. Unary (SIZEOF ` ^ {} ++ -- -)
  89.          E. Dreifach (IF THEN ELSE)
  90.          F. Strukturen (.)
  91.          G. Felder ([])
  92.          H. Fließkommaoperator (|)
  93.          I. Zuweisungsoperator (:=)
  94.          J. Reihenfolge (BUT)
  95.       5. Statements
  96.          A. Format (;)
  97.          B. Sprungmarken und Sprunganweisungen (JUMP)
  98.          C. Zuweisungen (:=)
  99.          D. Assembler Mnemonics
  100.          E. Bedingte Anweisungen (IF)
  101.          F. For-Anweisung (FOR)
  102.          G. While-Anweisung (WHILE)
  103.          H. Repeat-Anweisung (REPEAT)
  104.          I. Loop-Anweisung (LOOP)
  105.          J. Auswahl-Anweisungen (SELECT)
  106.          K. Zuwachs-Anweisungen (INC/DEC)
  107.          L. Void-Ausdrücke (VOID)
  108.       6. Funktions Deklaration und Definition
  109.          A. Prozedur Definition und Argumente (PROC)
  110.          B. Lokale und globale Definitionen (DEF)
  111.          C. Endproc/return
  112.          D. Die 'main' Funktion
  113.          E. E-eigene Systemvariablen
  114.       7. Deklaration von Konstanten
  115.          A. Konstanten (CONST)
  116.          B. Aufzählungen (ENUM)
  117.          C. Sets (SET)
  118.          D. E-eigene Konstanten
  119.       8. Typen
  120.          A. Über das 'type' System
  121.          B. Der Grundtyp (LONG/PTR)
  122.          C. Die einfachen Typen (CHAR/INT/LONG)
  123.          D. Der Feldtyp (ARRAY)
  124.          E. Die komplexen Typen (STRING/LIST)
  125.          F. Der Verbundtyp (OBJECT)
  126.          G. Einrichtung
  127.       9. Eingebaute Funktionen
  128.          A. Ein-/Ausgabeoperationen
  129.          B. Zeichenketten und Zeichenkettenfunktionen
  130.          C. Listen und Listen Funktionen
  131.          D. Intuition unterstützende Funktionen
  132.          E. Grafikfunktionen
  133.          F. Systemfunktionen
  134.          G. Mathematische Funktionen
  135.          H. Funktionen zum Verbinden von Zeichenketten und Listen
  136.       10. Library Funktionen und Module
  137.          A. Eingebaute Library Aufrufe
  138.          B. Schnittstellen zum Amiga Sytem mit den 2.04 Modulen bilden
  139.       11. Ausgewertete Ausdrücke
  140.          A. Auswertung und Bereich
  141.          B. Eval()
  142.          C. Eingebaute Funktionen
  143.       12. Fließkommaunterstützung
  144.          A. Gebrauch/Überladen von Fließkommazahlen/-operatoren
  145.          B. Fließkommaausdrüke und Umwandlungen
  146.       13. Exception Behandlung
  147.          A. Definition von Exceptionhandlern (HANDLE/EXCEPT)
  148.          B. Benutzung der Raise() Funktion
  149.          C. Exceptions für eingebaute Funktionen (RAISE/IF)
  150.          D. Benutzung von Exception-ID's
  151.       14. Objektorientierte Programmierung
  152.       15. Der Inline-Assembler
  153.          A. Variablenteilung
  154.          B. Vergleich zwischen Inline-/Makroassembler
  155.          C. Wege, Binäredaten zu nutzen (INCBIN/CHAR..)
  156.          D. OPT ASM
  157.       16. Dinge über den Compiler
  158.          A. Das OPT Schlüsselwort
  159.          B. Small/Large Modell
  160.          C. Stack Organisation
  161.          D. Festgeschriebene Begrenzungen
  162.          E. Fehlermeldungen, Warnungen und nicht dokumentierte Tests
  163.          F. Compiler Puffer Organisation und Anforderung
  164.          G. Eine kurze Entstehungsgeschichte
  165.  
  166. Formatierung
  167.  
  168.  
  169.          }1.FORMATIERUNG@{uu}
  170.  
  171.          B. Kommentare
  172.          C. Identifier und Typen
  173.  
  174.  
  175.          Vorheriges Kapitel     Nächstes Kapitel
  176. Formatierung
  177.  
  178. }1A.
  179. -----------------------------------------------
  180.  
  181. E-Sources sind reine ASCII-Dateien, mit Zeilenvorschüben (lf) und Semiko-
  182. lons ";" als Trennung zwischen zwei Ausdrücken. Ausdrücke die mehrere Ar-
  183. gumente haben, die durch ein Komma "," getrennt sind, können über mehrere
  184. Zeilen verteilt werden, wenn die Zeile mit einem Komma endet, indem der
  185. folgende Zeilenvorschub ignoriert wird.
  186. Jedes lexikalische Elemente in einer Source-Code-Datei kann durch eine
  187. beliebige Anzahl von Leerzeichen oder Tabulatoren vonm nächsten getrennt
  188. werden.
  189. Formatierung
  190.  
  191. }1B.
  192. --------------
  193.  
  194. Kommentare können überall im Sourcecode plaziert werden, wo Leerzeichen
  195. korrekt wären. Sie beginnen mit "/*" und enden mit "*/" und können unend-
  196. lich verschachtelt werden.
  197. Formatierung
  198.  
  199. }1C.
  200. ------------------------
  201.  
  202. Identifier sind Strings die Programmierer benutzen um bestimmte Objekte zu
  203. benennen, in den meisten Fällen Variabeln, oder nur Schlüsselwörter oder
  204. Funktionsnamen die vom Compiler vordefiniert wurden. Ein Identifier kann
  205. aus folgenden bestehen:
  206.  
  207. -große und kleine Buchstaben
  208. -"0".."9" außer als ersten Buchstaben
  209. -"_" dem Unterstrich
  210.  
  211. Alle Zeichen werden beachtet, aber der Compiler benutzt nur die ersten
  212. beiden um den Typ des Identifiers zu bestimmen, mit dem er ihn behandelt:
  213.  
  214. beide groß      - Schüsselwort wie IF, PROC usw
  215.                 - Konstanten wie MAX-LENGTH
  216.                 - Assembler Mnemonic, wie MOVE
  217.  
  218. erster klein    - Identifier von Variabel/Sprungmarken/Objekten usw.
  219.  
  220. erster groß und
  221. zweiter klein   - E-System-Funktionen
  222.                 - Library Aufrufe: z.B. OpenWindow()
  223.  
  224. Zu bedenken ist, daß alle Identifier dieser Schreibweise folgen, zum Bei-
  225. spiel: WBenchToFront wird zu WbenchToFront
  226.  
  227. Direkte Werte
  228.  
  229.  
  230.          }2.DIREKTE
  231.  
  232.          Direkte  Werte  werden  in  E  immer zu einem 32 Bit Ergebniss
  233.          umgewandelt.   Der  einzige Unterschied zwischen diesen Werten
  234.          (A-G)   ist   entweder  ihre  interne  Darstellung,  oder  die
  235.          Tatsache,   daß   sie   einen   Zeiger  anstatt  eines  Wertes
  236.          zurückgeben.
  237.  
  238.          A. Dezimalzahlen (1)
  239.          B. Hexadezimalzahlen ($1)
  240.          C. Binärzahlen (%1)
  241.          D. Fließkommazahlen (1.0)
  242.          E. Zeichen ('a')
  243.          F. Zeichenketten ('bla')
  244.          G. Listen ([1,2,3]) und symbolische Listen
  245.  
  246.  
  247.  
  248.          Vorheriges Kapitel     Nächstes Kapitel
  249. Direkte Werte
  250.  
  251. }2A.
  252. ---------------------
  253.  
  254. Eine Dezimalzahl ist eine Folge der Zeichen "0"..."9", möglicherweise durch
  255. ein Minuszeichen "-" angeführt um negative Zahlen zu kennzeichnen.
  256. Beispiel: 1, 100, -12, 1024
  257. Direkte Werte
  258.  
  259. }2B.
  260. --------------------------
  261.  
  262. Ein hexadezimaler Wert benutzt die zusätzlichen Zeichen "A"..."F" (oder
  263. "a"..."f") und wird mit einem "$" Zeichen begonnen.
  264. Beispiele: $FC, $DFF180, -$ABCD
  265.  
  266. Direkte Werte
  267.  
  268. }2C.
  269. --------------------
  270.  
  271. Binärzahlen beginnen mit einem "%" Zeichen und benutzen nur die Zeichen
  272. "1" und "0" um einen Wert zu bilden.
  273. Beispiele: %111, %1010100001, -%10101
  274.  
  275. Direkte Werte
  276.  
  277. }2D.
  278. --------------------------
  279.  
  280. Fließkommazahlen unterscheiden sich nur durch einen "." von normalen
  281. Dezimalzahlen, der dazu dient die beiden Teile auseinander zu halten.
  282. Jeweils einer der beiden Teile darf weggelassen werden, nie beide. Zu
  283. Bedenken ist, daß Fließkommazahlen eine andere interne 32 Bit Darstellung
  284. (FFP) haben. Mehr Informationen über Fließkommazahlen gibt es im Kapitel
  285. 12.
  286. Beispiele: 3.14159, .1 (entspricht 0.1), 1. (entspricht 1.0)
  287.  
  288. Direkte Werte
  289.  
  290. }2E.
  291. -----------------
  292.  
  293. Der Wert eines Zeichens (in Anführungszeichen "" eingeschlossen) ist ihr
  294. ASCII Wert, z.B. "A"=65. In E können direkte Zeichenwerte kurze Zeichen-
  295. ketten mit bis zu 4 Zeichen sein, zum Beispiel "FORM", wobei das erste
  296. Zeichen "F" das MSB und "M" das LSB (least significat Bit) der 32 Bit-Dar-
  297. stellung ist.
  298.  
  299. Direkte Werte
  300.  
  301. }2F.
  302. -------------------------
  303.  
  304. Zeichenketten sind irgendwelche ASCII-Darstellungen, die von Hochkommatas
  305. '' (Alt+'Ä') eingeschlossen sind. Der Wert einer solchen Zeichenkette ist
  306. ein Zeiger auf das erste Zeichen der Kette. Spezifischer: 'bla' erzeugt
  307. einen 32 Bit Zeiger zu einem Speicherbereich wo wir die Bytes "b", "l"
  308. und "a" finden können. Alle Zeichenketten in E werden mit einem 0 Byte ab-
  309. geschlossen.
  310. Zeichenketten können Formatzeichen, von einem Backslash "/" angeführt, ent-
  311. halten. Entweder um Zeichen in eine Zeichenkette einzufügen, die aus irgend-
  312. welchen Gründen nicht darstellbar sind, oder um Zeichenkettenformatierungs-
  313. funktionen wie von WriteF(), TextF() und StringF(), oder der Kickstart 2.0
  314. Funktion Vprintf zu nutzen.
  315.  
  316. \n          ein Zeilenvorschub
  317. \a oder ''  ein Hochkomma (das zum Einschließen von Zeichenketten benutzt
  318.             wird)
  319. \e          Escape (ASCII 27)
  320. \t          Tabulator (ASCII 9)
  321. \\          Backslash
  322. \0          ein Null-Byte. Wird nur selten benutzt, da jede Zeichenkette
  323.             mit einem Null-Byte abgeschlossen wird
  324. \b          ein Carriage Return (Wagenrücklauf)
  325.  
  326. Zusätzlich, bei Benutzung mit Format-Funktionen:
  327.  
  328. \d          schreibt ein Dezimalzahl
  329. \h          schreibt eine Hexadezimalzahl
  330. \s          schreibt eine String
  331. \c          schreibt ein Zeichen
  332. \z          schreibt Füllzeichen bei Nullen
  333. \l          formatiert linksbündig
  334. \r          formatiert rechtsbündig
  335.  
  336. Feldvariabeln können /d,/h und /s Codes folgen:
  337.  
  338. [x]         bezeichnet die genaue Feldbreite x
  339. (x,y)       bezeichnet das Minimum und das Maximum y (nur bei Zeichenketten)
  340.  
  341. Beispiel: Schreibt eine Hexadezimalzahl mit 8 Stllen und führenden Nullen
  342.           WriteF ('\z\h[8]\n',num)
  343.  
  344. Eine Zeichenkette kann über meherer Zeilen verteilt werde, indem man sie mit
  345. einem "+" Zeichen und einen <lf> (Zeilenvorschub) verbindet:
  346.  
  347. 'dies ist eine sehr lange Zeichenkette'+
  348. 'sie wurde über mehrere Zeilen verteilt'
  349.  
  350. Direkte Werte
  351.  
  352. }2G.
  353. -------------------------------------------
  354.  
  355. Eine direkte Liste ist das konstante Gegenstück des List Datentyps, genauso
  356. wie eine "Zeichenkette" das konstante Gegenstück für den STRING oder den
  357. ARRAY OF CHAR Datentyp ist. Beispiel:
  358.  
  359. [3,2,1,4]
  360.  
  361. ist ein Ausdruck, das als Wert einen Zeiger auf eine bereits fertigestellte
  362. Liste hat. Eine Liste ist eine Darstellung im Speicher, die gleichwertig
  363. mit ARRAY OF LONG ist, mit einigen zusätzlichen Längeninformationen an
  364. einem negativen Offset. Du kannst diese direkten Listen überall benutzen,
  365. wo eine Funktion einen Zeiger auf ein Feld von 32 Bit Werten oder eine Liste
  366. erwartet. Beispiele:
  367.  
  368. ['Zeichenkette',1.0,2.1]
  369. [WA_FLAGS,1,WA_IDCMP,$200,WA_WIDTH,120,WA_HEIGHT,150,TAGDONE]
  370.  
  371. Schaue Dir das Kapitel über List-Funktionen für eine Besprechung von symbo-
  372. lischen Listen und Detailinformationen an.
  373.  
  374.  
  375. Ausdrücke
  376.  
  377.  
  378.          }3.AUSDRÜCKE@{uu}
  379.  
  380.          B. precedence and grouping
  381.          C. types of expressions
  382.          D. function calls
  383.  
  384.  
  385.  
  386.          Vorheriges Kapitel     Nächstes Kapitel
  387. Ausdrücke
  388.  
  389. }3A.
  390. ----------
  391.  
  392. Ein Ausdruck ist ein Stück Quelltext, das aus Operatoren, Funktionen und
  393. Klammern besteht, um einen Wert zu erstellen.
  394. Sie bestehen meistens aus:
  395.  
  396. - direkten Werten wie im Kapitel 2 besprochen
  397. - Operatoren wie im Kapitel 4 besprochen
  398. - Funktionsaufrufen wie im Kapitel 3D besprochen
  399. - Klammern wie im Kapitel 3B besprochen
  400. - Variabeln oder Variabelausdrücken (siehe Kapitel 3C)
  401.  
  402. Beispiele für Ausdrücke
  403.  
  404. 1
  405. 'Hallo'
  406. $ABCD+(2*5)+Abs(a)
  407. (a<1) OR (b>=100)
  408.  
  409. Ausdrücke
  410.  
  411. }3B.
  412. -----------------------------
  413.  
  414. E hat keinen Abarbeitungsvorrang. D. h., daß Ausdrücke von links nach
  415. rechts ausgewertet werden. Du kannst die Abarbeitung durch Einklammern
  416. von (Unter-) Funktionen ändern:
  417.  
  418. 1+2*3 /*=9*/    1+(2*3) /*=7*/   2*3+1 /*=7*/
  419.  
  420. Ausdrücke
  421.  
  422. }3C.
  423. ------------------------
  424.  
  425. Es gibt drei Arten von Ausdrücken, die für unterschiedliche Verwendungs-
  426. zwecke genutzt werden:
  427.  
  428. - <var> besteht nur aus einer Variabel
  429. - <varexp> bestehend aus einer Variabel, möglicherweise mit einem unary(??)
  430.   Operator dazu, wie ++ (increment) oder [] (Array Operator). Hierfür siehe
  431.   Kapitel 4D und 4G. Es zeigt einen veränderbaren Ausdruck an, wie Lvalues
  432.   in C.
  433.   Bedenke das diese unary (??) Operatoren nie Teil der Abarbeitung sind
  434. - <exp>. Dies beinhaltet <var> und <varexp, und jede andere Art von Aus-
  435.   druck
  436.  
  437. Ausdrücke
  438.  
  439. }3D.
  440. --------------------
  441.  
  442. Ein Funktionsaufruf ist eine zeitweilig Unterbrechung des aktuellen Codes,
  443. um in eine Funktion zu springen. Dies kann entweder eine selbstgeschriebene
  444. Funktion (PROC), oder eine Funktion die vom System zu verfügung gestellt
  445. wird.
  446. Das Format eines solchen Funktionsaufruf ist der Name der Funktion, gefolgt
  447. von zwei Klammern(), die von Null bis zu unendlich vielen Argumenten, die
  448. durch Kommas getrennt werden, enthält. Argumente für Funktionen sind
  449. wiederum Ausdrücke. In Kapitel 6 steht wie man seine eigene Funktion er-
  450. stellt und Kapitel 9 und 10 beschreiben die eingebauten Funktionen. Bei-
  451. spiele:
  452.  
  453. foo (1,2)
  454. Gadget(buffer,glist,2,0,40,80+offset,100,'Cancel')
  455. Close(handle)
  456.  
  457. Operatoren
  458.  
  459.  
  460.          }4.OPERATOREN@{uu}
  461.  
  462.          B. Vergleiche (= <> > < >= <=)
  463.          C. Logische und Bitweise (AND OR)
  464.          D. Unary (SIZEOF ` ^ {} ++ -- -)
  465.          E. Dreifach (IF THEN ELSE)
  466.          F. Strukturen (.)
  467.          G. Felder ([])
  468.          H. Fließkommaoperator (|)
  469.          I. Zuweisungsoperator (:=)
  470.          J. Reihenfolge (BUT)
  471.  
  472.  
  473.          Vorheriges Kapitel     Nächstes Kapitel
  474. Operatoren
  475.  
  476. }4A.
  477. ---------------------------
  478.  
  479. Diese festen Operatoren verbindett einen Ausdruck mit einem anderen Wert,
  480. um einen neuen Wert zu bilden. Beispiele:
  481.  
  482. 1+2, MAX-1*5
  483.  
  484. in Kapitel 12 wird beschrieben, wie man diese Operatoren überlädt um sie
  485. Fließkommazahlen zu benutzen. "-" kann als erster Teil eines Ausdrucks be-
  486. nutzt werden, natürlich inklusive 0.
  487.  
  488. z.B. sind -a oder -b+1 zulässig
  489.  
  490. Bedenke, daß * und / standardmäßig 16 Bit Operatoren sind: siehe Mul()
  491.  
  492. Operatoren
  493.  
  494. }4B.
  495. -------------------------------
  496.  
  497. Gleich wie mathematische Operatoren, mit dem Unterschied, das ihr Ergebniss
  498. entweder TRUE (Wahr) (32 Bit Wert -1) oder FALSE (Falsch). Diese können
  499. auch für Fließkommazahlen überladen werden.
  500.  
  501. Operatoren
  502.  
  503. }4C.
  504. ----------------------------------
  505.  
  506. Diese Operatoren kombinieren entweder Wahrheitswerte zu neuen oder operie-
  507. ren bitweise mit AND und OR. Beispiele:
  508.  
  509. (a>1) AND ((b=2) OR (c>=3))   /*logisch */
  510. a:=b AND $FF                  /*bitweise*/
  511.  
  512. Operatoren
  513.  
  514. }4D. ++ -- `)b}
  515. ---------------------------------
  516.  
  517. -4E. Dreifach (IF THEN ELSE)b}
  518. ---------------------------
  519.  
  520. Der4F. Strukturen (.)b}
  521. ------------------
  522.  
  523. <prt2objekt>.<memberofobjekt>4G. Felder ([])b}
  524. ---------------
  525.  
  526. <var>[<indexexp>]4H. Fließkommaoperator (|)b}
  527. --------------------------
  528.  
  529. <exp>\<exp>
  530. Wandelt4I. Zuweisungsoperator (:=)b}
  531. ---------------------------
  532.  
  533. Zuweisungen4J. Reihenfolge (BUT)b}
  534. ---------------------
  535.  
  536. Der5.STATEMENTSu}
  537.  
  538.          B. Sprungmarken und Sprunganweisungen (JUMP)
  539.          C. Zuweisungen (:=)
  540.          D. Assembler Mnemonics
  541.          E. Bedingte Anweisungen (IF)
  542.          F. For-Anweisung (FOR)
  543.          G. While-Anweisung (WHILE)
  544.          H. Repeat-Anweisung (REPEAT)
  545.          I. Loop-Anweisung (LOOP)
  546.          J. Auswahl-Anweisungen (SELECT)
  547.          K. Zuwachs-Anweisungen (INC/DEC)
  548.          L. Void-Ausdrücke (VOID)
  549.  
  550.  
  551.          Vorheriges Kapitel     Nächstes Kapitel
  552. Statements
  553.  
  554. }5A.
  555. --------------
  556.  
  557. Wie im Kapitel 1A, steht ein Statement in seiner eigenen Reihe, aber mehrere
  558. von ihnen können in einer Reihe, durch ein Semikolon getrennt, geschrieben
  559. werden. Auch kann ein Statement über mehr als eine Zeile verteilt werde,
  560. wobei jede Zeile mit einem Komma enden muß. Beispiel:
  561.  
  562. a:=1, WriteF('Hallo!\n')
  563. DEF a,b,c,d,        /*zuviele Argumente für eine Zeile (vorgemacht)*/
  564.     e,f,g
  565.  
  566. Statement können sein
  567.  
  568. - Zuweisungen
  569. - Bedingt Zuweisungen für Statement und sowas, siehe auch Kapitel 5E-5K
  570. - Rückgabefreie Ausdrücke
  571. - Sprungmarken
  572. - Assembleranweisungen
  573.  
  574. Das Komma ist das erste Zeichen um zu zeigen, das Du das Statement nach dem
  575. nächsten Zeilenvorschub noch nicht beenden willst, aber auch die folgenden
  576. Zeichen zeigen an, daß das Statement in der folgenden Zeile fortgeführt
  577. wird:
  578.  
  579. + - * /
  580. = > < <> >= <=
  581. AND OR BUT THEN
  582.  
  583. Statements
  584.  
  585. }5B.
  586. ---------------------------------------------
  587.  
  588. Lables sind globale Identifier mit einem zusätzlichen ":", wie bei
  589.  
  590. mylable:
  591.  
  592. sie können von Anweisungen wie JUMP benutzt werden, aber auch um statische
  593. Daten zu erzeugen. Sie können benutzt werden, um aus jeder Art von Schleife
  594. zu springen (obwohl diese Technik nicht gut ist), aber es kann nicht aus
  595. einer Prozedure gesprungen werden. In normalen E-Programmen werden sie
  596. meistens für den Inline-Assembler benutzt. Lables sind immer global sicht-
  597. bar.
  598.  
  599. Benutzung von JUMP: JUMP <lable>
  600.  
  601. führt die Abarbeitung beim <lable> fort. Du solltest dies aber nicht be-
  602. nutzen, es ist eigentlich nur für Situationen da, wo man die Komplexität
  603. eines Programms vermindert. Beispiel:
  604.  
  605. IF Mouse()=1 THEN JUMP stopnow
  606.  
  607. /*andere Programmteile*/
  608.  
  609. stopnow:
  610.  
  611. Statements
  612.  
  613. }5C.
  614. --------------------
  615.  
  616. Das grundsätzliche Format einer Zuweisung ist <var>:=<exp>
  617. Beispiele: a:=1, a:=myfunc(), a:=b*3
  618.  
  619. Statements
  620.  
  621. }5D.
  622. -----------------------
  623.  
  624. In E ist der Inline-Assembler ein wirklicher Teil der Sprache, er muß nicht
  625. in spezielle "ASM" Blöcke oder sowas, wie es in anderen Sprachen notwendig
  626. ist, noch ist ein extra Assembler nötig, um den Code zu Asseblieren. Das
  627. heißt auch, daß er den normalen E Syntax-Regeln gehorcht, usw. In Kapitel
  628. 15 kannst Du alles über den Inline-Assembler lesen. Beispiele:
  629.  
  630. DEF a,b
  631. b:=2
  632. MOVEQ   #1,D0       /*nur einige Assembler-Statements*/
  633. MOVEL   D0,a        /*a:=1+D*/
  634. ADD.C   b,a
  635. WriteF('a=\d\n',a)  /*a wird 3 sein*/
  636.  
  637. Statements
  638.  
  639. }5E.
  640. -----------------------------
  641.  
  642. IF, THEN, ELSE, ELSEIF, ENDIF
  643.  
  644. Syntax: IF <exp> THEN <Statment> [ELSE <Statement>]
  645. oder  : IF <exp>
  646.                 <Statements>
  647.         [ELSEIF <exp>           /*mehrere elseifs können vorkommen*/
  648.                 <Statements>]
  649.         [ELSE
  650.                 <Statements>]
  651.         ENDIF
  652.  
  653. bilden einen Bedingten-Block. Bedenke das es zwei Hauptformen von diesem
  654. Statement gibt, eine einzeilen und eine mehrzeilen Version.
  655.  
  656. Statements
  657.  
  658. }5F.
  659. -----------------------
  660.  
  661. FOR, TO, STEP, DO, ENDFOR
  662.  
  663. Syntax: FOR <var>:=<exp> STEP <Schrittweite> DO <Statement>
  664. oder  : FOR <var>:=<exp> STEP <Schrittweite>
  665.                         <Statements>
  666.         ENDFOR
  667.  
  668. bilden einen FOR-Block, beachte die beiden Hauptformen. <Schrittweite> kann
  669. jede positive oder negative Konstanten, außer 0 sein. Beispiele:
  670.  
  671. FOR a:=1 TO 10 DO WriteF('\d\n'a)
  672.  
  673. Statements
  674.  
  675. }5G.
  676. ---------------------------
  677.  
  678. WHILE, DO, ENDWHILE
  679.  
  680. Syntax: WHILE <exp> DO <Statement>
  681. oder  : WHILE <exp>
  682.                 <Statements>
  683.         ENDWHILE
  684.  
  685. bilden eine While-Schleife, die solange durchlaufen wird, wie <exp> TRUE
  686. ergibt. Beachte die Ein-Zeile/Ein-Statement-Version und die Mehrzeilen-
  687. Version.
  688.  
  689. Statements
  690.  
  691. }5H.
  692. -----------------------------
  693.  
  694. REPEAT, UNTIL
  695.  
  696. Syntax: REPEAT
  697.             <Statements>
  698.         UNTIL <exp>
  699.  
  700. bilden einen Repeat-Until-Block. Die Schleife wird fortgesetzt bis <exp>=
  701. TRUE ist. Beispiel:
  702.  
  703. REPEAT
  704.     WriteF('Möchtest du wirklich dieses Programm beenden?\n'
  705.     ReadStr(stdout,s)
  706. UNTIL StrCmp(s,'ja bitte!')
  707.  
  708. Statements
  709.  
  710. }5I.
  711. -------------------------
  712.  
  713. LOOP, ENDLOOP
  714.  
  715. Syntax: LOOP
  716.             <Statements>
  717.         ENDLOOP
  718.  
  719. bilden eine unendliche Schleife.
  720.  
  721. Statements
  722.  
  723. }5J.
  724. --------------------------------
  725.  
  726. Syntax: SELECT <var>
  727.             [CASE <exp>
  728.                 <Statements>]
  729.             [CASE <exp>
  730.                 <Statements>]   /*eine beliebige Anzahl weiterer Blöcke*/
  731.             [DEFAULT <exp>
  732.                 <Statement>]
  733.         ENDSELECT
  734.  
  735. bilden einen Select-Case-Block. Beliebige Ausdrücke werden mit der Varia-
  736. bel <var> verglichen, und der erste passende Block wird ausgeführt. Wenn
  737. kein gleicher Ausdruck vorhanden ist, kann ein Default-Block ausgeführt
  738. werden.
  739.  
  740. SELECT zeichen
  741.     CASE 10
  742.         WriteF('Hey, wir haben einen Zeilenvorschub gefunden\n')
  743.     CASE 9
  744.         WriteF('Wow, das muß ein Tabulator sein!\n')
  745.     DEFAULT('Kennst Du dieses Zeichen: \c?\n',zeichen)
  746.  
  747. ENDSELECT
  748.  
  749. Statements
  750.  
  751. }5K.
  752. ---------------------------------
  753.  
  754. INC, DEC
  755.  
  756. Syntax: INC <var>
  757.         DEC <var>
  758.  
  759. kurz für <var>:=<var+1> und <var>:=var-1. Der einzige Unterschied zu var++
  760. und var-- ist, daß dies Statements sind, und keinen Wert zurückgeben und
  761. folglich optimaler sind.
  762.  
  763. Statements
  764.  
  765. }5L.
  766. ------------------------
  767.  
  768. Syntax: VOID <exp>
  769.  
  770. Berchnet den Ausdruck ohnen das der Wert irgendwohin geht. Dies ist nur
  771. für eine lesbarere Syntax nützlich, da Ausdrücke in E auch als Statement
  772. ohne VOID benutzt werden können. Dies kann heikle Fehler verursachen, da
  773. "a:=1" a den Wert 1 zuweist, aber "a=1" als Statement nichts tut. E warnt
  774. Dich, wenn das passiert.
  775.  
  776. Function Definitions and Declarations
  777.  
  778.  
  779.          }6.FUNKTIONS
  780.  
  781.          A. Prozedur Definition und Argumente (PROC)
  782.          B. Lokale und globale Definitionen (DEF)
  783.          C. Endproc/return
  784.          D. Die 'main' Funktion
  785.          E. E-eigene Systemvariablen
  786.  
  787.  
  788.  
  789.          Vorheriges Kapitel     Nächstes Kapitel
  790. Funktions Deklaration und Definition
  791.  
  792. }6A.
  793. --------------------------------------------
  794.  
  795. Du darfst PROC und ENDPROC zur Zusammenfassung von Ausdrücken in deinen
  796. eigenen Funktionen zu verwenden.
  797.  
  798. Solche ein Funktion darf irgendwelche Anzahl von Argumente haben und liefert
  799. einen Wert zurück.
  800.  
  801.  
  802.  
  803.  
  804. PROC, ENDPROC
  805.  
  806.  
  807.  
  808. Syntax:         PROC <Marke> ( <Argumente> , ... )
  809.  
  810.                 ENDPROC <Rückgabewert>
  811.  
  812. Definiert eine Prozedur mit irgendeiner Anzahl von Argumenten.
  813. Argumente sind von Typ LONG oder Optional als PTR TO <TYP> (siehe Kapitel 8)
  814. und brauchen kein weitere Deklarationen.
  815.  
  816. Das Ende einer Prozedur wird gekennzeichnet durch ENDPROC. Wenn kein Rück-
  817. gabewert mitgegeben wird, so wird 0 zurückgeliefert.
  818.  
  819. Beispiel: Eine Funktion, die zwei Argumente zusammengefasst zurückliefert:
  820.  
  821.  
  822. PROC add(x,y)         /* x und y sind lokale Variablen */
  823. ENDPROC x+y           /* liefert das Resultat zurück  */
  824. Funktions Deklaration und Definition
  825.  
  826. }6B.
  827. -----------------------------------------
  828.  
  829. Du darfst lokale Variablen definieren, indem Du die Argumente mit der
  830. DEF-Angabe bestimmst. Der leichteste Weg ist
  831.  
  832.  
  833. DEF a,b,c
  834.  
  835.  
  836. erklärt die Bezeichner a, b und c als Variablen deiner Funktion.
  837.  
  838. Beachten daß solche Deklarationen am Anfang Deiner Funktionen stehen müssen.
  839.  
  840.  
  841.  
  842.  
  843. DEF
  844.  
  845.  
  846. Syntax:         DEF <Deklarationen>,...
  847.  
  848. Beschreibung    definiert Variablen. Eine Deklarationen hat eine der Formen:
  849.  
  850.                 <Variable>
  851.  
  852.                 <Variable>:<Typ>          wobei <typ>=LONG,<objectidentifizierer>
  853.  
  854.                 <Variable>[<Größe>]:<Typ> wobei <typ>=ARRAY,STRING,LIST
  855.  
  856.  
  857.  
  858. Siehe Kapitel 8 für mehr Beispiele, wo steht, wie die Typen benutzt
  859. werden.
  860.  
  861. Fürs erste ist es gut die <Variable>-Form zu benutzen.
  862. Argumente für Funktionen sind beschränkt auf die Basis-Typen; siehe Kapitel 8B.
  863.  
  864. Ein Deklarationen eines Basis-Types kann eine Initialisierung haben, in der
  865. aktuellen Version muß dieses ein Integer sein (kein Ausdruck):
  866.  
  867.  
  868. DEF a=1,b=2
  869.  
  870.  
  871.  
  872. Ein Programm beinhaltet mehrere Funktionen, genannt PROCs. Jede
  873.  
  874. procedure may have Local variables, and the program as a whole may have
  875. Prozedur darf lokale Variablen haben, und das Programm als ganzes
  876. darf globale Variablen haben.
  877. Ein Programm muß mindestens aus der Prozedur PROC main() bestehen, da diese
  878. Prozedur den Anfang der Ausführung bestimmt.
  879.  
  880. Ein einfaches Programm könnte wie folgt ausschauen:
  881.  
  882.  
  883. DEF a, b                            /* Definition der globalen Variablen */
  884.  
  885. PROC main()                         /* alle Funktionen in zufälliger Ordnung */
  886.  
  887.   bla(1)
  888.  
  889. ENDPROC
  890.  
  891. PROC bla(x)
  892.  
  893.   DEF y,z                           /* Eigene, lokalen Variablen möglich. */
  894.  
  895. ENDPROC
  896.  
  897.  
  898.  
  899. Zusammengefasst: lokale Definitionen sind diejenigen, die Du am Start der
  900. Prozeduren nennst und welche erst in der Prozedur sichtbar werden. Globale
  901. Definitionen werden vor der ersten PROC gemacht, also am Start deines
  902. Quell-Codes, und sie sind global verfügbar. Globale und lokale Variablen
  903. (und natürlich lokale Variablen von zwei unterschiedlichen Funktionen)
  904. dürfen den gleichen Name haben.
  905.  
  906. Lokale Variablen haben immer höhere Priorität!
  907. Funktions Deklaration und Definition
  908.  
  909. }6C.
  910. ------------------
  911.  
  912. Wie zuvor gesagt, markiert ENDPROC das Ende einer Funktionen-Definition,
  913. und darf einen Wert zurückliefern.
  914. Optional kann RETURN an irgendwelchen Punkt in der Funktion zum beenden der
  915. Funktion benutzt werden. Wenn REURN in der Prozedur main() benutzt wird,
  916. dann endet das Programm.
  917.  
  918. Siehe auch CleanUp() in Kapitel 9F.
  919.  
  920. RETURN [<Rückgabewert>]          /* optional */
  921.  
  922.  
  923. Beispiel:
  924.  
  925.  
  926.  
  927. PROC getresources()
  928.  
  929.   /* ... */
  930.  
  931.   IF error THEN RETURN FALSE  /* etwas ist schiefgegangen, also raus
  932.                                  aus der Funktion mit dem Rückgabewert
  933.                                  "FALSCH". */
  934.  
  935.   /* ... */
  936.  
  937. ENDPROC TRUE  /* wir sind soweit, damit liefern wir TRUE zurück. */
  938.  
  939.  
  940. Eine sehr kurz Version bei einer Funktion-Definition ist
  941.  
  942.  
  943.  
  944. PROC <marke> ( <Argument> , ... ) RETURN <Ausdruck>
  945.  
  946.  
  947. These are function definitions that only make small computations, like
  948. Diese sind Funktions-Definitionen die kleine Berechnungen machen, wie
  949. fakultative Funktionen und sie sind (ein-Zeiler :-)
  950.  
  951.  
  952.  
  953. PROC fac(n) RETURN IF n=1 THEN 1 ELSE fac(n-1)*n
  954. Funktions Deklaration und Definition
  955.  
  956. }6D.
  957. -----------------------
  958. Die PROC mit dem Namen main() ist unheimlich Wichtig, weil es
  959. die erste aufgerufene Funktion ist; sie ist genauso aufgebaut wie andere
  960. Funktionen und darf auch lokale Variablen haben.
  961.  
  962. main() hat keine Argumente; die CLI-Kommando-Zeilen Argumente werden in
  963. der System-Variable "arg" geliefert, oder können überprüft werden mit
  964.  
  965. ReadArgs()
  966. Funktions Deklaration und Definition
  967.  
  968. }6E.
  969. ----------------------------
  970. Folgende globale Variablen sind immer verfügbar in Deinem Programm,
  971. sie werden System Variablen genannt.
  972.  
  973.  
  974.  
  975.  
  976. arg             Wie oben gesagt, beinhaltet "arg" einen Zeiger zu einem mit
  977.                 mit Null abgeschlossen String. Der String wiederum
  978.                 beinhaltet die CLI-Kommando-Zeilen-Argumente.
  979.                 Benutze nicht diese Variable wenn du ReadArgs() in
  980.                 Deinem Programm benutzt.
  981.  
  982. stdout          Beinhaltet ein File-Handle zu der Standard Ausgabe
  983.                 (und Eingabe).
  984.                 Wenn dein Programm von der Workbench gestartet wurde, so daß
  985.                 kein Shell-Fenster verfügbar ist, WriteF() öffnet ein CON:
  986.                 Fenster für dich und setzt den entsprechenden File-Handler
  987.                 hier hinein.
  988.  
  989. conout          Hier wird das File-Handle abgelegt, und das CON:
  990.                 Fenster wird automatisch geschlossen nach einem exit
  991.                 von Deinem Programm.
  992.                 Siehe WriteF() in Abschnitt 9E, um zu sehen, wie die zwei
  993.                 Variablen richtig benutzt werden.
  994.  
  995. execbase,       Diese fünf Variablen enthalten IMMER die
  996. dosbase,        richtigen Werte.
  997. gfxbase,
  998. intuitionbase,
  999. mathbase
  1000.  
  1001. stdrast         Zeiger zum Standard-Rastport, um diesen in deinem Programm
  1002.                 benutzten zu können, oder NIL.
  1003.                 Die eingebauten Grafik-Funktionen wie Line() benutzen
  1004.                 diese Variable.
  1005.  
  1006. wbmessage       Beinhaltet einen Zeiger zu ein Nachricht die du bekommst,
  1007.                 wenn du von der Worbench startest, sonst NIL.
  1008.                 Darf benutzt werden wie ein Boolean-Wert um festzustellen,
  1009.                 ob du von der Workbench gestartet bist oder sogar zum
  1010.                 überprüfen irgendwelcher Argumente, die mit Deinem ICON
  1011.                 "Shift-ausgewählt" wurden.
  1012.                 Siehe WbArgs.e in dem sources/Examples Verzeichnis, um zu
  1013.                 sehen, wie gut man wbmessage benutzen kann.
  1014. Deklaration von Konstanten
  1015.  
  1016.  
  1017.          }7.DEKLARATION
  1018.  
  1019.          A. Konstanten (CONST)
  1020.          B. Aufzählungen (ENUM)
  1021.          C. Sets (SET)
  1022.          D. E-eigene Konstanten
  1023.  
  1024.  
  1025.  
  1026.          Vorheriges Kapitel     Nächstes Kapitel
  1027. Deklaration von Konstanten
  1028.  
  1029. }7A.
  1030. ----------------------
  1031. Syntax: CONST <Deklaration>
  1032.  
  1033. Ermöglicht es Dir eine Konstante zu deklarieren. Eine Deklaration sieht so
  1034. aus:
  1035.  
  1036. <ident>=<Wert>
  1037.  
  1038. Konstanten müssen großgeschrieben sein, und werden für den Rest des Pro-
  1039. gramms als <Wert> behandelt. Beispiel:
  1040.  
  1041. CONST MAX_LINES=100, ER_NOMEM=1, ER_NOFILE=2
  1042.  
  1043. Man kann keine Konstanten mit Termen deklarieren in denen Konstanten sind
  1044. die im selben Statement deklarier werden: Schreibe diese ins nächste.
  1045.  
  1046. Deklaration von Konstanten
  1047.  
  1048. }7B.
  1049. -----------------------
  1050.  
  1051. Aufzählungen sind ein spezieller Typ von Konstanten, bei denen kein Wert an-
  1052. gegeben werden braucht, da sie im Bereich von 0..n definiert sind, das erste
  1053. Element ist 0. An einem beliebigen Punkt in einer Aufzählung kannst Du
  1054. "=<Wert>" einsetzen um den Zähler auf einen Wert zu setzen oder rückzuset-
  1055. zen. Beispiele:
  1056.  
  1057. ENUM ZERO, ONE, TWO, THREE, MONDAY=1, TUESDAY, WENDSDAY
  1058. ENUM ER_NOFILE=100, ER_NOMEM, ER_NOWINDOW
  1059.  
  1060. Deklaration von Konstanten
  1061.  
  1062. }7C.
  1063. --------------
  1064. Sets sind den Aufzählungen ähnlich, mit dem Unterschied, daß anstatt einem
  1065. Wert wie (0,1,2..) eine Bitnummer hat (0,1,2...) die erhöht wird. So haben
  1066. Sets die Werte (1,2,4,8...). Das hat den zusätzlichen Vorteil, daß sie als
  1067. Sets von Flags benutzt werden können, wie das Schlüsselwort sagt.
  1068. Stellen wir uns ein Set wie oben vor, das die Einrichtung eines Fensters
  1069. beschreibt:
  1070.  
  1071. SET SIZEGAD, CLOSEGAD, SCROLLBAR, DEPTH
  1072.  
  1073. um eine Variabel mit den Werten DEPTH und SIZEGAD vorzubereiten:
  1074.  
  1075. winflags:=DEPTH OR SIZEGAD
  1076.  
  1077. um einen zusätzlichen SCROLLBAR einzurichten
  1078.  
  1079. winflags:=winflags OR SCROLLBAR
  1080.  
  1081. und testen ob zwei Einrichtung gehalten wurden
  1082.  
  1083. IF winflags AND (SCROLLBAR OR DEPTH) THEN /*   */
  1084.  
  1085. Deklaration von Konstanten
  1086.  
  1087. }7D.
  1088. -----------------------
  1089. Folgende eingebaute Konstanten können benutzt werden:
  1090.  
  1091. TRUE, FALSE         Repräsentiert die boolschen Wert Wahr und Falsch (-1,0)
  1092. NIL                 (=0) nicht initialisierter Pointer
  1093. ALL                 wird bei String-Funktionen wie StrCopy benutzt, damit
  1094.                     alle Zeichen kopiert werden.
  1095. GADGETSIZE          kleinste Größe in Bytes um ein Gadget zu erhalten, siehe
  1096.                     auch Gadget() 9D
  1097. OLDFILE, NEWFILE    Modusprameter beim benutzen von Open()
  1098. STRLEN              Hat immer den Wert der zuletzt benutzten Zeichenkette.
  1099.                     Beispiel: Write(handle,'Hallo Leute!',STRLEN) /* =9 /*
  1100.  
  1101.  
  1102. Typen
  1103.  
  1104.  
  1105.          }8.TYPEN@{uu}
  1106.  
  1107.          B. Der Grundtyp (LONG/PTR)
  1108.          C. Die einfachen Typen (CHAR/INT/LONG)
  1109.          D. Der Feldtyp (ARRAY)
  1110.          E. Die komplexen Typen (STRING/LIST)
  1111.          F. Der Verbundtyp (OBJECT)
  1112.          G. Einrichtung
  1113.  
  1114.  
  1115.          Vorheriges Kapitel     Nächstes Kapitel
  1116. Typen
  1117.  
  1118. }8A.
  1119. --------------------------
  1120. E hat kein strenges Typen-System wie in Pascal oder Modula2, es ist sogar
  1121. flexibler als in C. Du kannst es auch ein Datentypen-System. Dies geht Hand
  1122. in Hand mit der Philosophie, daß alle Datentypen in E gleich sind: alle
  1123. kleinen Grundtypen wie Zeichen, Dezimalzahlen etc. Alle haben die gleichen
  1124. 32 Bitgröße und alle anderen Daten und alle anderen Datentypen wie Felder
  1125. und Zeichenketten werden von auf einen 32 Bitzeiger auf sie. So kann der
  1126. Compiler einen vielseitigen Code generieren.
  1127. Die Vor- und Nachteile sind offensichtlich:
  1128.  
  1129. Nachteile des E-Typen-Systems:
  1130.  
  1131. - weniger Compiler-Überprüfungen für dumme Fehler von DIR!
  1132.  
  1133. Vorteile:
  1134.  
  1135. - Low-Level Vielseitigkeit
  1136. - flexible Programmgestaltung: kein Problem das einige Typen Werte zurück
  1137.   geben die nicht zu anderen Aufrufe usw.
  1138. - es ist nicht schwer Fehler beim mischen von verschieden großer Daten in
  1139.   Ausdrücken zu finden
  1140. - er werden immer noch selbstdokumentierende Typen unterstützt, wie:
  1141.  
  1142.   PTR to newscreen
  1143.  
  1144. Typen
  1145.  
  1146. }8B.
  1147. ---------------------------
  1148. Es gibt nur einen nicht komplexen Grundtyp in E, es ist der 32 Bit Typ LONG.
  1149. Da er der Defaulttyp ist, kann er so definiert werden:
  1150.  
  1151. DEF a:LONG          oder nur    DEF a
  1152.  
  1153. Diese Variabel kann das aufnehmen, was in anderen Programmiersprachen die
  1154. Typen CHAR/INT/PTR/LONG enthalten. Eine spezielle Art des LONG Typen ist
  1155. der PTR-Typ. Dieser Typ ist kompatibel mi dem LONG-Typen, mit dem Unter-
  1156. schied, daß angegeben wird, auf was er zeigt. Als Voreinstellung gilt, das
  1157. LONG als PRT TO CHAR angegeben wird. Syntax:
  1158.  
  1159. DEF <var>:PTR TO <Typ>
  1160.  
  1161. wobei Typ entweder ein einfacher oder ein zusammengesetzter Typ ist. Bei-
  1162. spiel:
  1163.  
  1164. DEF x:PTR TO INT, myscreen: PTR TO screen
  1165.  
  1166. Beachte, daß 'screen' der Name eines Objekts ist, das im Module intuition/
  1167. screens.m definiert ist. Zu Beispiel wenn Du Deinen eigenen Screen öffnest
  1168. mit:
  1169.  
  1170. myscreen:=OpenS(... usw.
  1171.  
  1172. kannst Du den Zeiger myscreen z.B. als 'myscreen.rastport' benutzen. Wenn
  1173. Du aber nichts mit den Variabeln machen willst, bis Du CloseS(myscree)
  1174. aufrufst, kannst Du sie so deklarieren:
  1175.  
  1176. DEF myscreen
  1177.  
  1178. Typen
  1179.  
  1180. }8C.
  1181. ---------------------------------------
  1182. Die einfachen Typen CHAR(8 Bit) und INT (16 Bit) sollten nicht als Grund-
  1183. typen für (einzelne) Variabeln benutzt werden; der Grund dafür sollten
  1184. jetzt wohl klar sein. Trotzdem können sie als Datentypen zum Bilden von
  1185. Arrays benutzt werden. Sie können auch in Objektdefinitionen benutzt wer-
  1186. den, und man kann einen Zeiger auf sie setzen.
  1187.  
  1188. Typen
  1189.  
  1190. }8D.
  1191. -----------------------
  1192. ARRAYs werden über ihre Länge in Bytes definiert:
  1193.  
  1194. DEF b[100]:ARRAY
  1195.  
  1196. dies definiert ein Feld von 100 Bytes. Intern ist b eine Variabel des Typs
  1197. LONG und ein Zeiger auf diesen Speicherbereich. Standardmäßig ist der Typ
  1198. eines Feldelements CHAR, es kann aber jeder andere sein:
  1199.  
  1200. DEF x[100]: ARRAY OF LONG
  1201. DEF mymenus[10]:ARRAY OF newmenu
  1202.  
  1203. wobei "newmenu" ein Beispiel für eine Struktur ist, die in E OBJECT genannt
  1204. werden.
  1205. Der Feldzugriff ist sehr einfach mit <var>[<sexp>]:
  1206.  
  1207. b[1]:="a"
  1208. z:=mymenu[a+1].multiexclude
  1209.  
  1210. Bedenke das der Index eines Felds der Größe n von 0 bis n-1 und nicht von
  1211. 1 bis n geht.
  1212. ARRAY OF <Typ> ist kompatibel mit PRT TO <Typ>, mit dem Unterschied das die
  1213. Variabeln die in einem Feld sind schon eingerichtet.
  1214.  
  1215.  
  1216. Typen
  1217.  
  1218. }8E.
  1219. -------------------------------------
  1220. - STRINGs. Ähnlich den Feldern, sind aber anders, weil sie nur von den E
  1221.   Zeichkettenfunktionen geändert werden können, und das sie Größen- und
  1222.   Maximalgrößenangaben enthalten. So können die E-Funktionen den String
  1223.   auf sichere Art verändern. Z. B.: Der String kann nie größer werden als
  1224.   der Speicherbereich, indem er steht. Definition:
  1225.  
  1226.   DEF s[80]:STRING
  1227.  
  1228.   Der String-Typ ist abwärtskompatibel mit PTR OF CHAR und natürlich mit
  1229.   ARRAY OF CHAR, aber nicht andersherum. Mehr Details im Abschnitt über
  1230.   Zeichenkettenfunktionen.
  1231.  
  1232. - LISTs. Diesen Datentyp gibt es in anderen prozedualen Programmiersprachen
  1233.   nicht, es gibt ihn in Programmiersprachen wie Lisp oder Prolog. Die E-
  1234.   Variante kann als Mischung zwischen STRING und ARRAY OF LONG interpre-
  1235.   tiert werden. Zum Beispiel kann diese Datenstruktur eine Liste von LONG-
  1236.   Variabeln aufnehmen, welche als STRINGs erweitert oder verkürzt werden
  1237.   können. Definition:
  1238.  
  1239.   DEF x[100]:LIST
  1240.  
  1241.   Eine mächtige Erweiterung dieses Typs ist, daß er ein konstantes Gegen-
  1242.   stück [], wie Zeichenketten mit '', hat. LIST ist abwärtskompatibel mit
  1243.   PTR TO LONG und natürlich ARRAY OF LONG, aber nichts andersherum. In
  1244.   Kapitel 2G und 9C steht mehr darüber.
  1245.  
  1246. Typen
  1247.  
  1248. }8F.
  1249. ---------------------------
  1250. OBJECTs sind fast wie eine struct in C oder ein RECORD in Pascal. Beispiel:
  1251.  
  1252. OBJECT meinobject
  1253.     a: LONG
  1254.     b: CHAR
  1255.     c: INT
  1256. ENDOBJECT
  1257.  
  1258. Dies definiert eine Struktur die aus drei Elementen. Syntax:
  1259.  
  1260. OBJECT
  1261.     <Elementname>[:<Typ>]   /*hiervon eine unbeschränkte Zahl*/
  1262. ENDOBJECT
  1263.  
  1264. wobei Typ wieder ein einfacher Typ, ein zusammengesetzter Typ oder ein
  1265. einfacher Feldtyp ist, z. B. [<Elementzahl>]:ARRAY mit der Größe von CHAR
  1266. für ein Element. Bedenke das <Elementname> nicht ein einzigartiger Identi-
  1267. fier sein muß, er kann auch in anderen Objekten enthalten sein. Es gibt
  1268. viele Arten um Objekte zu benutzen:
  1269.  
  1270. DEF x:meinobj               /* x ist eine Strucktur*/
  1271. DEF y:PRT TO meinobj        /* y ist ein Zeiger auf ein Struktur*/
  1272. DEF z[10]:ARRAY OF meinobj
  1273.  
  1274. y:=[-1,"a",100]:meinobj     /*geschriebene Liste*/
  1275. IF y.b="a" THEN /*...*/
  1276. z[4].c:=z[d+1].b++
  1277.  
  1278. ARRAY in Objekten werden immer auf gerade Zahlen gerundet und werden auf
  1279. gerade Offsets gesetzt.
  1280.  
  1281. OBJECT meinstring
  1282.     len:CHAR, daten[9]:ARRAY
  1283. ENDOBJECT
  1284.  
  1285. SIZEOF meinstring ist 12, und "daten" beginnt auf dem Offset 2.
  1286. Bedenke: OBJECTs in E sind nicht so wie sie in anderen Sprachen benutzt
  1287. werden können. Z. B. kann nicht jeder Typ ein Element eines Objekts bilden,
  1288. und deswegen machen rekursive Zugriffe wie x.y.z wenig Sinn (bis jetzt).
  1289.  
  1290. Typen
  1291.  
  1292. }8G.
  1293. ---------------
  1294. 1. Immer mit NIL eingerichtet (oder anders wenn extra angegeben)
  1295.    -Globale Variabel
  1296.     Bedenke: Für Dokumentationszwecke ist es immer besser wnn Du =NIL in
  1297.              Definitionen von Variabeln schreibst, die du als NIL erwartest
  1298. 2. Als '' oder [] eingerichtet:
  1299.    -Globale und lokale STRINGs
  1300.    -Globale und lokale LISTs
  1301. 3. Nicht eingerichtet
  1302.    -Lokale Variabel (wenn nicht extra angegeben)
  1303.    -Globale und lokale ARRAYs
  1304.    -Globale und lokale OBJECTs
  1305.  
  1306. Eingebaute Funktionen
  1307.  
  1308.  
  1309.          }9.EINGEBAUTE
  1310.  
  1311.          A. Ein-/Ausgabeoperationen
  1312.          B. Zeichenketten und Zeichenkettenfunktionen
  1313.          C. Listen und Listen Funktionen
  1314.          D. Intuition unterstützende Funktionen
  1315.          E. Grafikfunktionen
  1316.          F. Systemfunktionen
  1317.          G. Mathematische Funktionen
  1318.          H. Funktionen zum Verbinden von Zeichenketten und Listen
  1319.  
  1320.  
  1321.          Vorheriges Kapitel     Nächstes Kapitel
  1322. Eingebaute Funktionen
  1323.  
  1324. }9A.
  1325. ---------------------------
  1326. WriteF(Formatzeichenkett, Argumente,...)
  1327.  
  1328. schreibt eine Zeichenkette (die Formatcodes enthalten kann) in den stdout.
  1329. Es können von keinem bis zu unendlich vielen Argumenten angefügt werden.
  1330. Bedenke, daß Formatzeichenketten dynamisch erzeugt werden können. Die An-
  1331. zahl der Argumente wird nicht überprüft. Beispiele:
  1332.  
  1333. WriteF('Hallo Welt!\n') /*schreibt nur eine Zeichenkette mit einem Zeilen-
  1334.                           vorschub am Ende*/
  1335. WriteF('a=\d\n',a)      /*schreibt "a=123" wenn a=123 ist*/
  1336.  
  1337. Alles andere mußt Du unter dem Thema Strings nachschauen.
  1338. Wenn stdout=NIList, zum Beispiel wenn Dein Programm von der Workbench ge-
  1339. startet wir, erzeugt WriteF() ein Ausgabefenster, und schreibt den Handle
  1340. in conout und stdout. Dieses Fenster wird am Ende des Programms geschlossen,
  1341. nachdem der Anwender ein <Return> eingegeben hat. WriteF() ist die einzige
  1342. Funktion die dieses Fenster öffnet. als, wenn Du eine Ein-/Ausgabefunktion
  1343. über stdout machen willst, un nicht sicher weißt ob stdout<>NIL benutze ein
  1344. WriteF('') als ersten Befehl deines Programms um die Ausgabe sicher zu
  1345. stellen. Wenn Du selbst ein Consolen-Fenster öffnen willst, solltest Du den
  1346. resultierenden Filehandle in die 'stdout' und 'conout' Variabel schreiben,
  1347. da Dein Fenster so nach dem Programmende automatisch geschlossen wird. Wenn
  1348. Du das Fenster manuelle schließen willst, vergewisser Dich, daß Du 'conout'
  1349. wieder auf NIL gesetzt hast, um E anzuzeigen das es kein Console-Fenster
  1350. gibt, das geschlossen werden muß.
  1351.  
  1352. Out(filehandle, char) und char:=Inp(filehandle)
  1353.  
  1354. Schreibt oder ließt ein einzelnes Byte in/aus einem File oder stdout. Wenn
  1355. char=-1 ist, ist das Ende des Files erreicht oder ein Fehler ist aufgetre-
  1356. ten.
  1357.  
  1358.     len:=FileLength(Namenstring)
  1359.  
  1360. Bestimmt die Länge eines Files, den Du vielleicht laden willst, und gibt
  1361. ebenso an, ob er existiert (gibt -1 zurück, wenn ein Fehler auftritt oder
  1362. der File nicht vorhanden ist.
  1363.  
  1364.     ok:=ReadStr(filehandle, estring)
  1365.  
  1366. siehe Stringunterstützung
  1367.  
  1368.     oldout:=StdOut(newstdout)
  1369.  
  1370. setzt die Standard-Output-Variabel 'stdout' auf den neuen Wert. Gleich mit:
  1371. oldout:=stdout; stdout:=newstdout
  1372.  
  1373. Eingebaute Funktionen
  1374.  
  1375. }9B.
  1376. ---------------------------------------------
  1377. E hat einen Datentyp STRING. Dies ist ein String, von nun an 'EString' ge-
  1378. nannt, der in der Größe modifizier und verändert werden kann, als Gegen-
  1379. stück zu einem normalen 'String', welcher als durch ein Null-Byte beendete
  1380. Zeichenfolge benutzt wird. EStrings sind abwärtskompatibel, aber nicht an-
  1381. dersherum. Also wen ein Argument ein String erfordert, können beide benutzt
  1382. werden. Wenn ein EString erforderlich ist, kann nur ein solcher benutz wer-
  1383. den. Beispiele fü die Anwendung:
  1384.  
  1385. DEF s[80]:STRING    /*s ist ein EString mit einer maximalen Länge von 80
  1386.                       Zeichen*/
  1387. ReadStr(stdout,s)   /*ließt eine Eingabe von der Console*/
  1388. m:=Val(s,N)         /*holt eine Nummer von der Console*/
  1389.  
  1390. Bei allen Zeichenkettenfunktionen bei denen Strings größer werden können
  1391. als ihr Maximum, werden Vorsichtsmaßnahmen getroffen.
  1392.  
  1393. DEF s[6]:STRING
  1394. StrAdd(s,'dieser String ist länger als 6 Zeichen',ALL)
  1395.  
  1396. s wird nur 'dieser' enthalten.
  1397. Ein String kann dynamisch aus dem Systemspeicher mit der Funktion String()
  1398. angefordert werden (der Zeiger hierfür muß auf NIL geprüft werden)
  1399.  
  1400.     s:=String(maxlen)
  1401.  
  1402. DEF s[80] ist gleich mit DEF s und s:=String(10)
  1403.  
  1404.     bool:=StrCmp(string,string,len)
  1405.  
  1406. vergleicht zwei Zeichenketten, len ist die Anzahl der Bytes, die verglichen
  1407. werden sollen, oder All, wenn die ganze Länge überprüft werden soll. Gibt
  1408. True oder False zurück.
  1409.  
  1410.     StrCopy(estring,string,len)
  1411.  
  1412. kopiert den String in EString. Wenn len=ALL ist, wird alles kopiert.
  1413.  
  1414.     StrAdd(estring,string,len)
  1415.  
  1416. genauso wie StrCopy(), nur das der String am Ende angehängt wird.
  1417.  
  1418.     len:=StrLen(string)
  1419.  
  1420. berechnet die Länge eines Strings der durch ein Null-Byte abgeschlossen
  1421. wurde
  1422.  
  1423.     len:=EstrLen(estring)
  1424.  
  1425. gibt die maximale Länge eines EStrings zurück.
  1426.  
  1427.     RightStr(estring,estring,n)
  1428.  
  1429. Füllt den ersten EString mit den letzten n Bytes des zweiten EStrings.
  1430.  
  1431.     MidStr(estring,string,pos,len)
  1432.  
  1433. kopiert jede beliebige Anzahl von Zeichen (alle eingeschloseen, wenn len=
  1434. All) von der Position pos im String in den EString.
  1435. WICHTIG: Bei allen stringverarbeitenden Funktionen ist zu Bedenken, daß das
  1436.          erste Zeichen die Position 0 hat, und nicht 1, wie in normalen
  1437.          Sprachen, wie Basic.
  1438.  
  1439.     wert:=Val(string,read)
  1440.  
  1441. Findet eine Dezimalzahl im ASCII-Code codiert aus einr Zeichenkette. Führen-
  1442. de Leerzeichen/Tabulatoren werden übersprungen. Auch Hexadezimalzahlen
  1443. (1234567890ABCDEFabcdef) und Binärzahlen (01) können so gelesen werden,
  1444. wenn sie von einem "$"- oder "%"-Zeichen angeführt werden. Ein Minuszeichen
  1445. kann eine negative Zahl anzeigen. Val() gibt die Anzahl der gelesenen
  1446. Zeichen im zweiten Argument zurück, welches über Referenz (<-!!!) übergeben
  1447. werden muß. Wenn read den Wert 0 (wert wird auch 0 sein) hat, dann enthält
  1448. der String keine Dezimalzahl, oder der Wert ist zu groß um in 32 Bit auf-
  1449. genommen zu werden. "read" kann NIL sein.
  1450.  
  1451. Beispiel für Zeichenketten die korrekt übersetzt werden:
  1452.  
  1453. '-12345', '%10101010', '-$ABcd12'
  1454.  
  1455. diese würden in "wert" und der Variabel [read] eine 0 zurückgeben:
  1456.  
  1457. '', 'Hallo'
  1458.  
  1459.     findepos:=IntStr(string1, string2, startpos)
  1460.  
  1461. sucht in string1 nach dem Vorkommen von string2. Es kann auch von einer
  1462. anderen Position  als 0 gestartet werden. Zurückgegeben wird die *Addresse*,
  1463. an der der Unterstring gefunden wurde, ansonsten -1.
  1464.  
  1465.     neuestringadr:=TrimStr(string)
  1466.  
  1467. gibt die *Addresse* des ersten Zeichen in einem String, z.B. nach führenden
  1468. Leerzeiche, Tabulatoren usw.
  1469.  
  1470.     UperStr(string)     und     LowerStr(string)
  1471.  
  1472. ändert die Groß- und Kleinschreibung einer Zeichenkette.
  1473. BEACHTE: diese Funktion verändert die Elemente einer Zeichenkette. Deshalb
  1474. sollte man sie nur bei EStrings und Zeichenketten die ein Teil des Codes
  1475. sind verwenden. Effektiv heißt das, daß wenn Du eine Stringaddresse vom
  1476. Betriebssystem bekommen hast, mußt Du diesen erst mit StrCopy() in einen
  1477. String Deines Programms kopieren, und dann erst mit diesem Programm be-
  1478. nutzen.
  1479.  
  1480.     ok:=ReadStr(filehandle, EString)
  1481.  
  1482. ließt eine String (mit ASCII 10 endent) aus einem File oder stdout. ok ent-
  1483. hält -1 wenn ein Fehler festgestellt oder das EOF erreicht wurde.
  1484. Bedenke: Die Elemente des Strings, die bis dahin gelesen wurden sind gültig.
  1485.  
  1486.     SetStr(EString,neuelänge)
  1487.  
  1488. Setzt manuelle die Länge eines Strings. Dies ist nur nützlich, wenn Du Daten
  1489. in einen EString über nicht E-String-Funktionen ließ, und ihn als EString
  1490. weiter benutzen willst. Z. B. nach der Benutzung einer Funktion die nur
  1491. einen Null-Byte-Beendeten String auf die Addresse eines EStrings schreibt,
  1492. benutze SetStr(meinstr,StrLen(meinstr)) um ihn wieder manipulierbar zu
  1493. machen.
  1494. Für String-Zusammenführungsfunktionen siehe Kapitel 9H
  1495.  
  1496. Eingebaute Funktionen
  1497.  
  1498. }9C.
  1499. --------------------------------
  1500. Listen sind wie Strings nur das sie sich aus LONGs und nicht aus CHARs zu-
  1501. sammensetzen. Sie können auch entweder global, lokal oder dynamisch angefor-
  1502. dert werden:
  1503.  
  1504. DEF meineliste[100]:LIST    /*lokal oder global*/
  1505. DEF a
  1506. a:=LIST(10)                 /*dynamisch*/
  1507.  
  1508. (beachte das im letzteren Fall der Zeiger a NIL enthalten kann). Genauso wie
  1509. Strings als Konstanten in Ausdrücken dargestellt werden können, haben Listen
  1510. ihr konstantes Equivalent:
  1511.  
  1512. [1,2,3,4]
  1513.  
  1514. Der Wert eines solchen Ausdrucks ist ein Zeiger auf eine fertig initalisier-
  1515. te Liste. Eine spezielle Eigenschaft ist, das sie dynamische Teile, z. B.,
  1516. welche während der Laufzeit gefüllt werden:
  1517.  
  1518. a:=3
  1519. [1,2,a,4]
  1520.  
  1521. außerdem können Listen auch einige andere Typen als die Voreinstellung LONG
  1522. enthalten, wie:
  1523.  
  1524. [1,2,3]:INT
  1525. [65,66,67,0]:CHAR               /*gleich mit 'ABC' *
  1526. ['topaz.font',8,0,0]:textattr
  1527. OpenScreenTagList(NIL,[SA_TITEL,'MeinScreen',TAG_DONE])
  1528.  
  1529. Wie im letzten Beispiel gezeigt, sind Listen extrem nützlich bei der Benut-
  1530. zung von Systemfunktionen: Sie sind abwärtskompatibel mit einem ARRAY OF
  1531. LONG, und auf ein Objektzeigende können überall dort benutzt werden, wo eine
  1532. Systemfunktion einen benutzt werden, wo eine Systemfunktion einen Zeiger auf
  1533. einige Strukturen oder ein Feld von Zeigern benötigt. Taglist und vararg-
  1534. Funktionen können auch auf diese Weise benutzt werden.
  1535. BEACHTE: Alle Funktionen arbeiten nur mit LONG Listen, typenzugeordnete
  1536.          Listen sind nur geeignet um komplexe Datenstrukturen und Ausdrücke
  1537.          aufzubauen.
  1538.  
  1539. Wie bei Strings gibt es eine klare Hierachie.
  1540.  
  1541. Listen Variabeln -> Konstante Liste -> Feld von Longs/Zeiger auf Longs
  1542.  
  1543. Wenn eine Funktion ein Feld von Longs braucht, kannst Du auch eine Liste als
  1544. Argument angegeben. Wenn aber eine Funktion eine Listenvariabel oder eine
  1545. konstante Liste braucht, reicht ein Feld von Longs nicht aus.
  1546.  
  1547. Es ist wichtig, daß Du die Mächtigkeit von Listen besonders typenorien-
  1548. tierter verstehst: dis kann Dir viel Ärger beim Aufbau irgendeiner Daten-
  1549. struktur ersparen. Versuche diese Listen in Deinen eigenen Programmen zu
  1550. benutzen und schauen  welche Funktion sie in den Beispielprogrammen haben.
  1551. Wenn Du Listen einmal im Griff hast, möchtest Du niemals ein Programm ohne
  1552. sie schreiben.
  1553.  
  1554. Zusammenfassung:
  1555.  
  1556. [<Element>, <Element>,...]          direkte Liste (von LONGs, Benutzung mit
  1557.                                     Listenfunktion
  1558. [<Element>, <Element>,...]:<Typ>    Typenorientierte Liste (nur um Daten-
  1559.                                     strukturen zu bauen)
  1560.  
  1561. Wenn <Typ> ein einfacher Typ wie INT oder CHAR ist, hast Du nur das einge-
  1562. richtete Gegenstück zu ARRAY OF <Typ> ein Objektname ist erzeugst Du ein
  1563. eingerichtetes Objekt oder ARRAY OF <Objekt>, sich auf die Länge der Liste
  1564. stützend.
  1565.  
  1566. Wenn Du schreibst [1,2,3]:INT erzeugst Du eine Datenstruktur von 6 Bytes,
  1567. von 3 16 Bit Werten um genau zu sein. Der Wert eines solchen Ausdrucks ist
  1568. dann ein Zeiger zu einem Speicherbereich um genau zu sein. Es funktoniert
  1569. z. B. mit einem Objekt.
  1570.  
  1571. OBJECT meinobjekt
  1572.     a:LONG, b:CHAR, c:INT
  1573. ENDOBJECT
  1574.  
  1575. wenn Du jetzt schreibst:  [1,2,3]:meinobjekt würde dann eine Datenstruktur
  1576. von 8 Bytes im Speicher erstellen. Diese ersten vier Byte sind eine LONG-
  1577. Zahl mit dem Wert 1, das folgende Byte ist ein CHAR mit dem Wert 2, dann
  1578. ein Füllbyte, um die Wort-Anordnung zu erhalten (16 Bit). Es ist trotzdem
  1579. sehr wahrscheinlich, daß ein E-Compiler für eine 80x86 Architektur das Füll-
  1580. byte nicht nutzen wird und eine 7 Byte Struktur erzeugen wird. Und ein E-
  1581. Compiler für eine Sun-Sparc Architektur (wenn ich mich nicht vertue) wird
  1582. versuchen alles auf 32 Bit Grenzen zu stzen, so macht er eine 10 oder 12
  1583. Byte Struktur. Einige Mikroprozessoren (sie sind selten aber es gibt sie)
  1584. benutzen sogar (36:18:9) als Anzahl von Bits für ihre Typen (LONG:INT:CHAR)
  1585. anstatt von (32:16:8) wie wir es gewöhnt sind. Mache Dir kein zu großen
  1586. Vorstellungen der Struktur eines OBJECTS oder einer LISTe, wenn Du Code
  1587. schreiben willst, der eine Chance haben soll portabel zu sein oder sich auf
  1588. Seiteneffekte zu verlassen.
  1589.  
  1590.     ListCopy(Listenvar,Liste,Anzahl)
  1591.  
  1592. Kopiert Anzahl Elemente aus Liste in die Listenvar. Beispiel:
  1593.  
  1594. DEF meineliste[10]:LIST
  1595. ListCopy(meineliste,[1,2,3,4,5],ALL)
  1596.  
  1597.     ListAdd(Listenvariabel, Liste, Anzahl)
  1598.  
  1599. Kopiert Anzahl Elemente von Liste an die erste nicht belegte Stelle von
  1600. Listenvariabel
  1601.  
  1602.     ListCmp(Liste, Liste, Anzahl)
  1603.  
  1604. Vergleicht zwei Listen, oder Anzahl Teile von ihnen.
  1605.  
  1606.     länge:=ListLen(Liste)
  1607.  
  1608. Gibt die Länge der Liste zurück, wie ListLen([a,b,c]) 3 zurückgeben würde.
  1609.  
  1610.     maximum:=ListMax(Listenvariabel)
  1611.  
  1612. Gibt die maximal mögliche Listenlänge von Listenvariabel zurück.
  1613.  
  1614.     wert:=ListItem(Liste,Index)
  1615.  
  1616. funktioniert wie wert:=Liste[Index] mit dem Unterschied, daß Liste ein kon-
  1617. stanter Wert anstatt eines Zeiger sein kann. Dies kann in Situationen sehr
  1618. nützlich sein, in denen wir direkt ein Liste von Werten benutzen wollen:
  1619.  
  1620. WriteF(ListItem(['ok','kein Speicher','keine Datei'],fehler))
  1621.  
  1622. Es verhält sich wie:
  1623.  
  1624. dummy:=['ok','kein Speicher','keine Datei']
  1625. WriteF(dummy[fehler])
  1626.  
  1627.     SetList(Listenvariabel, neuelänge)
  1628.  
  1629. setzt manuell die Länge einer Liste. Dies is nur nützlich, wenn Du mit nicht
  1630. listenspezifischen Funktionen Daten in eine Liste schreibst, sie aber als
  1631. richtige Liste weiterverwenden willst.
  1632.  
  1633. Für Listenfunktion, die ausgewertete Ausdrücke benutzen siehe Kapitel 11C.
  1634. Für Listenverbindungsfunktionen siehe Kapitel 9H
  1635.  
  1636.  
  1637. Eingebaute Funktionen
  1638.  
  1639. }9D.
  1640. ---------------------------------------
  1641.     wptr:=OpenW(x,y,Breite,Höhe,IDCMP,WFlags,Titel,Screen,SFlags,Gadgets)
  1642.  
  1643. erzeugt ein Fenster, wobei WFlags die Flags für das Windowlayout sind (wie
  1644. BACKDROP, SIMPLEREFRESH usw, normalerweise $F) und SFlags ist da um die
  1645. Screenart zu bestimmen auf der das Fenster geöffnet werden soll (1=WB,
  1646. 15=Custom). Screen muß nur gültig sein, wenn SFlags=15, ansonsten reicht
  1647. NIL. Gadgets kann auf eine GList-Struktur zeigen, welche einfach mit Gad-
  1648. get() erzeugt werden kann, ansonsten NIL.
  1649.  
  1650.     CloseW(wptr)
  1651.  
  1652. schließt das Fenster wieder. Der einzige Unterschied zu CloseWindow ist
  1653. das es NIL-Zeiger akzeptiert und den stdrast wieder auf NIL setzt.
  1654.  
  1655.     sptr:=OpenS(Weite,Höhe,Tiefe,SFlags,Titel)
  1656.  
  1657. Öffnet einen Customscreen. Tiefe ist die Anzahl der Bitplanes (1-6, 1-8
  1658. AGA), SFlags ist etwas wie 0, oder $8000 für Hires (addiere 4 für Interlace)
  1659.  
  1660.     CloseS(sptr)
  1661.  
  1662. wie CloseW(), nun für Screens.
  1663.  
  1664.     nächsterbuffer:=Gadget(buffer,glist,id,flags,x,y,Breite,string)
  1665.  
  1666. Diese Funktion erstellt eine Liste von Gadgets, welche in Deinem Fenster
  1667. angezeigt werden können, in dem Du sie als Argument bei OpenW() als Argu-
  1668. ment übergibst. Später kannst Du das auch mit der Intuitionfunktion
  1669. AddGlist() erledigen.
  1670. Bufer ist meistens ein ARRAY on mindestens der GrößeGADGETSIZE Bytes um alle
  1671. Strukturen die zu einem Gadget gehören aufzunehmen. ID ist eine beliebige
  1672. Nummer die Dir helfen soll später zu erkennen welches Gadget gedrückt wurde,
  1673. wenn ine IntuiMessage ankommt. Flags sind 0=normal, 1=Boolean Gadget, 3=
  1674. Boolean Gadget das ausgewählt ist. Width ist die Weite in Pixeln, die groß
  1675. genug sein sollte um den String aufzunehmen, welcher automatisch zentriert
  1676. wird. Glist sollte beim ersten Gadget NIL sein, und glistvar für alle ande-
  1677. ren, so kann E alle Gadget zusammenlinken. Die Funktion gibt einen Zeiger
  1678. auf den nächsten Buffer zurück (=buffer+GADGETSIZE). Beispiel für 3 Gadgets:
  1679.  
  1680. CONST   MAXGADGETS=GADGETSIZE*3
  1681.  
  1682. DEF buf[MAXGADGETS]:ARRAY, next, wptr
  1683.  
  1684. next:=Gadget(buf,NIL,1,0,10,20,80,'bla' /*das erste Gadget*/
  1685. next:=Gadget(next,buf...)
  1686. next:=Gadget(next,buf...)    /*jede Anzahl kann zum ersten gelinkt werden*/
  1687.  
  1688. wptr:=OpenW(...,buf)
  1689.  
  1690. Schaue Dir die richtigen Beispiele wie SuperVisor.e für richtige Anwendugen
  1691. an.
  1692.  
  1693.     code:=Mouse()
  1694.  
  1695. gibt Dir den momentanen Status von allen 2 oder 3 Mausknöpfen zurück, links
  1696. =1, rechts=2 und mitte=4. Wenn der Code z.B. gleich 3 ist, sind die linke
  1697. und die rechte Maustaste gedrückt.
  1698. WICHTIG: die ist keine richtige Inituition-Funktion, wenn Du auf regulären
  1699. Weg etwas über die Maus-Events erfahren willst, muß Du die IntuiMessages
  1700. kontrollieren, die an Deinem Window ankommen. Das ist die einezige E-Funk-
  1701. tion die direkt auf die Hardware zugreift, und ist deshalb nur für demo-
  1702. artige Programme nützlich:
  1703.  
  1704.     x:=MouseX(win)       und     y:=MouseY(win)
  1705.  
  1706. ermöglicht es Dir die Mauskoordinaten zu lesen. Win ist das Window zu dem
  1707. sie relativ sind.
  1708.  
  1709.     class:=WaitIMessage(window)
  1710.  
  1711. Diese Funktion macht es einfacher auf ein Window-Event zu warten. Es spei-
  1712. chert andere Variabeln wie Cod und Qualifiers als private, globale Varia-
  1713. beln, für den Zugriff mit Funktionen, die unten beschrieben werden.
  1714. WaitIMessage() representiert folgenden Code:
  1715.  
  1716. PROC waitimessage(win:PTR TO window)
  1717.   DEF port,mes:PTR TO intuimessage,class,code,qual,iaddr
  1718.   port:=win.userport
  1719.   IF (mes:=GetMsg(port))=NIL
  1720.     REPEAT
  1721.       WaitPort(port)
  1722.     UNTIL (mes:=GetMsg(port))<>NIL
  1723.   ENDIF
  1724.   class:=mes.class
  1725.   code:=mes.code             /* intern abgespeichert */
  1726.   qual:=mes.qualifier
  1727.   iaddr:=mes.iaddress
  1728.   ReplyMsg(mes)
  1729. ENDPROC class
  1730.  
  1731. wie Du siehst, holt es exakt eine Nachricht, und vergißt keinen mehrfach
  1732. Message, die bei einem Ereigniss ankommt. Wenn mehr als ein Aufruf erfolgt.
  1733. Zum Beispiel, sagen wir Du hast ein Window geöffnet, das etwas anzeigt, und
  1734. nur auf das Cosegadget wartet (Du hast nur IDCMP_CLOSEWINDOW angegeben):
  1735.  
  1736.     WaitMessage(meinwindow)
  1737.  
  1738. oder Du hast ein Programm das auf mehrere Arten von Events wartet, sie in
  1739. einer Schleife bearbeitet, un mit einem Closewindow-Event endet:
  1740.  
  1741. WHILE (class:=WaitIMessag(win))<>IDCMP_CLOSWINDOW
  1742.     /*Bearbeitung der anderen Klassen */
  1743. ENDWHILE
  1744.  
  1745.     code:=MsgCode()     qual:=MsgQualifier()    iaddr:=MsgIaddr()
  1746.  
  1747. Dies alles versorgt Dich mit den privaten globalen Variabel, die vorher er-
  1748. wähnt wurden. Die Werte die zurückgegeben werden, wurden alle vom letzten
  1749. Aufruf von WaitIMessage() definiert. Beispiel:
  1750.  
  1751. IF class:=IDCMP_GADGETUP
  1752.     mygadget:=MsgIaddr()
  1753.     If mygadget.userdata=1 THEN     /* der Anwender hat Gadget #1 gedrückt*/
  1754. ENDIF
  1755.  
  1756. Eingebaute Funktionen
  1757.  
  1758. }9E.
  1759. --------------------
  1760. Alle grafikunterstützenden Funktionen, die nicht extra einen Rastport ver-
  1761. langen, benutzen die System-Variabel 'stdrast'. Sie wird automatisch vom
  1762. letzten Aufruf von OpenW() oder OpenS() definiert, und wird von CloseW()
  1763. und CloseS() auf NIL gesetzt. Der Aufruf dieser Routinen, während 'stdrast'
  1764. NIL ist, ist erlaubt. stdrast kann manuelle über SetStdRast() oder stdrast:=
  1765. meinrast geändert werden.
  1766.  
  1767.     Plot(x,y,Farbe)
  1768.  
  1769. Malt einen einzelnen Punkt auf Deinem Screen/Window in einer der verfügbaren
  1770. Farben. Die Farbe geht von 0-255, oder 0-31 auf vor-AGA Maschinen.
  1771.  
  1772.     Line(x1,y1,x2,y2,Farbe)
  1773.  
  1774. Malt eine Linie.
  1775.  
  1776.     Box(x1,y1,x2,y2,Farbe)
  1777.  
  1778. Malt ein Rechteck.
  1779.  
  1780.     Colour(Vordergrund, Hintergrund)
  1781.  
  1782. setzt die Farbe für alle Grafikfunktionen (aus dem Library), die kein Farb-
  1783. argumente annehmen. Dies ist das *Farbregister* (z.B. 0-31) und nicht der
  1784. *Farbwert*.
  1785. BEACHTE: Funktionen, die ein "Farbe" als Argument haben, verändern den Apen
  1786. des stdrast.
  1787.  
  1788.     TextF(x,y,Formatstring,args,....)
  1789.  
  1790. hat genau dieselbe Funktion wie WriteF(), nur an irgendeiner (x,y) Position
  1791. in deinem stdrast, anstatt von stdout. Siehe auch WriteF() und Strings in
  1792. der Sprachbeschreibung.
  1793.  
  1794.     alterrast:=SetStdRast(neuerrast)
  1795.  
  1796. verändert den Ausgaberastprot der E-Grafik-Funktionen.
  1797.  
  1798.     SetTopaz(größe)
  1799.  
  1800. setzt den Font des Rastport "stdras" auf Topaz, nur um sicher zu sein, daß
  1801. einige Custom-Fonts des Anwenders nicht unser Bildschirmlayout durchein-
  1802. ander werfen. Größe ist natürlich 8 oder 9.
  1803.  
  1804. Eingebaute Funktionen
  1805.  
  1806. }9F.
  1807. --------------------
  1808.  
  1809.     bool:=KickVersion(vers)
  1810.  
  1811. Gibt TRUE zurück, wenn die Kickstart in der Maschine, auf der Dein Programm
  1812. läuft, gleich oder größer ist, ansonsten FALSE.
  1813.  
  1814.     mem:=New(n)
  1815.  
  1816. Dies erzeugt dynamisch ein Feld (oder Speicherbereich, wenn Du möchtest) von
  1817. n Bytes. Unterschiede zu AllocMem() sind, daß es automatisch die Flaggs
  1818. $10000 (also gelöschter Speicher, jeder Typ) angibt und keine Dispose()
  1819. Aufrufe notwendig sind, da es an eine Speicherliste angefügt wird, die auto-
  1820. matisch am Ende des Programms freigegeben wird.
  1821.  
  1822.     Dispose(mem)
  1823.  
  1824. Gibt jedes mem frei, das durch New() angefordert wurde. Du muß diese Funk-
  1825. tion nur benutzen, wenn Speicher während des Programmablaufs freigegeben
  1826. werden soll, da es am Ende sowieso freigegeben wird.
  1827.  
  1828.     CleanUp(Rückgabewert)
  1829.  
  1830. Beendet das Programm von jeden Punkt. Es ist der Ersatzt für den DOS-Aufruf
  1831. Exit(): benutze diesen niemals!!!!!! anstatt von CleanUp(), welcher es
  1832. ermöglicht Speicher freizugeben, Libraries richtig zu schließen usw. Der
  1833. Rückgabewert wird als Returncode an DOS zurückgegeben.
  1834.  
  1835.     menge:=FreeStack
  1836.  
  1837. gibt die Menge des freien Stackspeichers zurück. Diese sollte immer 1000
  1838. oder mehr betragen. Siehe in Kapitel 16 wie E seinen Stack organisiert.
  1839. Wenn Du nicht im Rekursionswahn bist, brauchst Du Dir über den freien Stack-
  1840. Speicher keine Sorgen zu machen.
  1841.  
  1842.     bool:=CtrlC()
  1843.  
  1844. Gibt TRUE zurück, wenn Ctrl-C nach der letzten Überprüfung gedrückt wurde,
  1845. ansonsten FALSE. Dies arbeitet nur mit Programmen, die über die Console
  1846. laufen, d.h. CLI-Programme.
  1847.  
  1848. /*berechnet die Fakultät des CLI-Arguments*/
  1849.  
  1850. OPT STACK=100000
  1851.  
  1852. PROC main()
  1853.   DEF num,r
  1854.   num:=Val(arg,{r})
  1855.   IF r=0 THEN WriteF('Argumentfehler.\n') ELSE WriteF('Wert: \d\n',fac(num))
  1856. ENDPROC
  1857.  
  1858. PROC fac(n)
  1859.   DEF r
  1860.   IF FreeStack()<1000 OR CtrlC() THEN CleanUp(5)    /* Extra Controlle */
  1861.   IF n=1 THEN r:=1 ELSE r:=fac(n-1)*n
  1862. ENDPROC r
  1863.  
  1864. Natürlich wird diese Rekursion kaum den Stack zum überlaufen bringen, und
  1865. wenn dies passiert, wird es so schnell von FreeStack() angehalten, das Du
  1866. keine Zeit hast Ctrl-C zu drücken, aber es ist die Idee die hier zählt.
  1867. Eine Definition von fac(n) wie:
  1868.  
  1869. Proc fac(n) RETURN IF n=1 THEN 1 ELSE fac(n-1)*n
  1870.  
  1871. wäre nicht so sicher.
  1872.  
  1873. Eingebaute Funktionen
  1874.  
  1875. }9G.
  1876. ----------------------------
  1877.  
  1878.     a:=And(b,c)     a:=Or(b,c)      a:=Not(b)
  1879.     a:=Eor(b,c)
  1880.  
  1881. Diese arbeiten mit den normalen Operatoren, boolschen genauso wie aritme-
  1882. thische. Beachte, daß für And() und Or() Operatoren existieren:
  1883.  
  1884.     a:=Mul(b,c)     a:=Div(a,b)
  1885.  
  1886. Macht dasselbe wie die '*' und '/' Operatoren, aber jetzt mit vollen 32 Bit.
  1887. Aus Geschwindigkeitsgründen sind normale Operationen 16 Bit * 16 Bit =
  1888. 32 bit und 32 Bit/ 16 Bit = 16 Bit. Dies reicht für fast alle Rechnungen aus
  1889. und wo nicht, kannst Du Mul() und Div() benutzen. BEACHTE: im Fall von Div()
  1890. wird a durch b geteilt und nicht umgekehrt.
  1891.  
  1892.     bool:=Odd(x)        bool:=Even(x)
  1893.  
  1894. Gibt TRUE oder FALSE zurück wenn ein Ausdruck gerade oder ungerade ist.
  1895.  
  1896.     randnum:=Rnd(max)   seed:=RndQ(seed)
  1897.  
  1898. Rnd() berechnet eine Zufallszahl aus einer Internen seed im Raum von 0..
  1899. max-1. Zum Beispiel, Rnd(1000) gibt eine Dezimalzahl von 0..999 zurück. Um
  1900. die Interne  Quelle zu Initalisieren, rufe Rnd() mit einem negativen Wert
  1901. auf. Der Abs() dieses Werts wird dann als Ursprungs'seed' genommen.
  1902. RndQ() berechnet eine Zufallszahl schneller als Rnd(), aber gibt nur ganze
  1903. 32 Bit Zufallszahlen zurück. Benutze das Ergebniss als seed für den nächsten
  1904. Aufruf, und als Anfangs'seed' benutze einen großen Wert wie $AGF87EC1
  1905.  
  1906.     abswert:=Abs(wert)
  1907.  
  1908. berechnet den absoluten Wert.
  1909.  
  1910.     a:=Mod(b,c)
  1911.  
  1912. Dividiert 32 Bit b durch 16 Bit c und gibt den 16 Bit Modulo a zurück.
  1913.  
  1914.     x:=Shl(y,num)       x:=Shr(y,num)
  1915.  
  1916. Schiebt y um num Bits nach links oder nach rechts.
  1917.  
  1918.     a:=Long(adr)        a:=Int(adr)     a:=Char(adr)
  1919.  
  1920. Ließt aus einer Speicheraddresse einen Wert und gibt ihn zurück. Dies geht
  1921. mit 32, 16 und 8 Bit Werten in dieser Reihenfolge. Der Compiler überprüft
  1922. nicht ob die Addresse gültig ist. Diese Funktionen sind in E verfügbar für
  1923. den Fall, daß das Lesen und Schreiben im Speicher mit PTR TO <Typ> das Pro-
  1924. gramm nur noch komplexer und uneffizienter machen würde. Du solltest aber
  1925. nicht dazu ermutigt werden, diese Funktionen zu benutzen.
  1926.  
  1927.     PutLong(adr,a)      PutInt(adr,a)       und     PutChar(adr,a)
  1928.  
  1929. Poket (schreibt) den Wert 'a' in den Speicher, Siehe auch Long()
  1930.  
  1931. Eingebaute Funktionen
  1932.  
  1933. }9H.
  1934. ---------------------------------------------------------
  1935.  
  1936. E ist mit einer Reihe von Funktionen ausgestattet, die die Erstellung von
  1937. verketteten Listen mit dem STRING und LIST Datentyp, oder Strings und
  1938. Listen, die mit String() und List() erstellt wurden, erlaubt. Wie Du viel-
  1939. leicht weißt, sind Listen, Strings, komplexe Datentypen Zeiger auf ihre
  1940. verschiedenen Daten, und haben ein extra Feld an einem negativen Offset
  1941. dieses Zeigers die ihre aktuelle und ihre maximale Länge enthält. Die Off-
  1942. sets dieses Feld sind PRIVATE. Als Zusatzt zu diesen beiden, hat jeder
  1943. komplexe Datentyp ein 'next' Feld, welches Defaultmäßig auf NIL gesetzt ist.
  1944. Dieses kann benutzt werden, um verkettete Listen zu erzeugen, z.B. von
  1945. Strings. Ab jetzt verstehe ich unter komplex einen ptr auf einen STRING
  1946. oder eine LISTe, und unter 'tail' noch einen solchen Zeiger, oder einen
  1947. der schon einen solchen String anghängt hat. 'tail' kann auch ein NIL Zeiger
  1948. sein, der das Ende einer verketteten Liste anzeigt. Die folgenden Funktionen
  1949. können benutzt werden.
  1950.  
  1951.     komplex:=Link(komplex,tail)
  1952.  
  1953. schreibt den Wert von tail in das 'next'-Feld von komplex. Beispiel:
  1954.  
  1955. DEF s[10]:STRING, t[10]:STRING
  1956. Link(s,t)
  1957.  
  1958. erzeugt eine verkettete Liste wie: s-->t-->NIL
  1959.  
  1960.     tail:=Next(komplex)
  1961.  
  1962. ließt das 'next' Feld einer komplexen Variabel. Dies kann natürlich NIL
  1963. sein, oder eine komplett verkettete Liste. Next(NIL) aufrufen ergibt NIL,
  1964. so ist es sicher Next aufzurufen, wnn man sich nicht sicher ist ob man am
  1965. Ende einer verketteten Liste ist.
  1966.  
  1967.     tail:=Forward(c,1)
  1968.  
  1969. genau dasselbe, geht nur um num Links vorwärts, anstatt von einem, also:
  1970.  
  1971. Next(c)=Forward(c,1)
  1972.  
  1973. Du kannst Forward sicher mit Nummern aufrufen, die zu weit gehen; Forward
  1974. hält an sobald es ein NIL beim suchen eines Links entdeckt und gibt NIL
  1975. zurück.
  1976.  
  1977.     DisposeLink(complex)
  1978.  
  1979. dasselbe wie Dispose(), mit dem Unterschied: es ist nur für Strings und
  1980. Listen die mit String() und List() angefordert wurden, und entfernt auto-
  1981. matisch den 'tail' eines komplexen Datentyps. Beachte, daß in große verket-
  1982. teten Listen, die Strings enthalten, die sowohl mit String() als auch einige
  1983. lokal und global mit STRING allociert wurden können auch auf diese Art
  1984. freigegeben werden.
  1985.  
  1986. Für ein gutes Beispiel, wie man Listen von Strings gut im wirklichen Leben
  1987. gebrauchen kann, siehe 'D.e'.
  1988.  
  1989. Library Funktionen und Module
  1990.  
  1991.  
  1992.          }10.LIBRARY
  1993.  
  1994.          A. Eingebaute Library Aufrufe
  1995.          B. Schnittstellen zum Amiga Sytem mit den 2.04 Modulen bilden
  1996.  
  1997.  
  1998.  
  1999.          Vorheriges Kapitel     Nächstes Kapitel
  2000. Library Funktionen und Module
  2001.  
  2002. }10A.
  2003. -------------------------------
  2004. Wie Du vielleicht schon aus den vorherigen Abschnitten weißt, wird vor Dein
  2005. Programm automatisch um ein Programmteil (der "initialisation code") ergänzt,
  2006. der beim Programmstart immer folgende vier Bibliotheken öffnet: Intuition,
  2007. Dos, Graphics und Mathffp. Daher sind die Funktionsaufrufe zu diesen fünf
  2008. Bibliotheken (Exec eingeschlossen) im Compiler integriert (es sind einige
  2009. Hundert). Jedenfalls bis zu AmigaDos v2.04, v3.00 sollte bis zur nächsten
  2010. Version von Amiga E implementiert sein. Um Open() von der dos.library
  2011. aufzurufen, genügt ein schlichtes:
  2012.  
  2013. handle:=Open('meinedatei',OLDFILE)
  2014.  
  2015. oder AddDisplayInfo() von graphics.library:
  2016.  
  2017. AddDisplayInfo(meindispinfo)
  2018.  
  2019. So einfach ist das.
  2020.  
  2021. Library Funktionen und Module
  2022.  
  2023. }10B.
  2024. ---------------------------------------------------------------
  2025. Um eine beliebige andere Bibliothek als die fünf im vorherigen Abschnitt
  2026. genannten zu benutzen, mußt Du Module wählen. Du brauchst auch Module, wenn
  2027. Du - wie in C oder Assembler üblich - OBJECT oder CONST Definition aus den
  2028. Amiga-Includes benutzt. Module sind Binärdateien, die Definitionen von
  2029. Konstanten, Objekten, Bibliotheken und Funktionen (code) beinhalten können.
  2030. Die Tatsache, daß sie binär vorliegen, hat den ASCII-Dateien (benutzt in C
  2031. und Assembler) gegenüber den Vorteil, daß sie nicht jedesmal neu compiliert
  2032. werden müßen, wenn Dein Programm neu compiliert wird. Der Nachteil ist, daß
  2033. man sie sich nicht einfach anschauen kann; um ihren Inhalt sichtbar zu
  2034. machen, ist ein Utility wie ShowModule (siehe utility.doc) nötig. Die
  2035. Module, die die Bibliotheksdefinitionen (d.h. deren Aufrufe) enthalten,
  2036. stehen im Wurzelverzeichnis von emodules: (dem Modul-Verzeichnis in der
  2037. Distribution), die Definitionen der Konstanten/Objekte befinden sich in den
  2038. Unterverzeichnissen, sie sind wie die Originale von Commodore aufgebaut.
  2039.  
  2040.  
  2041. MODULE
  2042.  
  2043. Sytax:          MODULE <Modulname>,...
  2044. Lädt ein Modul. Ein Modul ist eine Binärdatei, die Informationen über
  2045. Bibliotheken, Konstanten und manchmal auch Funktionen enthält. Durch
  2046. Modulbenutzung ist es Dir möglich, Bibliotheken und Funktionen zu benutzen,
  2047. die dem Compiler vorher nicht bekannt waren.
  2048.  
  2049. Nun zu einem Beispiel, unten steht ein kleine Version des Sources
  2050. sources/examples/asldemo.e, das Module verwendet, um einen Filerequester
  2051. der 2.0 Asl.library darzustellen.
  2052.  
  2053.  
  2054. MODULE 'Asl', 'libraries/Asl'
  2055.  
  2056. PROC main()
  2057.   DEF req:PTR TO filerequestr
  2058.   IF aslbase:=OpenLibrary('asl.library',37)
  2059.     IF req:=AllocFileRequest()
  2060.       IF RequestFile(req) THEN WriteF('File: "\s" in "\s"\n',req.file,req.dir)
  2061.       FreeFileRequest(req)
  2062.     ENDIF
  2063.     CloseLibrary(aslbase)
  2064.   ENDIF
  2065. ENDPROC
  2066.  
  2067.  
  2068. Aus dem Modul 'asl' erfährt der Compiler die Definitionen der
  2069. asl-Funktionen, wie zum Beispiel RequestFile(), und die globale Variable
  2070. 'aslbase', die vom Programmierer lediglich initialisiert werden muß. Aus
  2071. 'libraries/asl' erfährt er die Definition des Objektes filerequestr, das
  2072. wir benutzen, um zu erfahren, welche Datei der Anwender ausgewählt hat.
  2073. Das war doch nun wirklich nicht schwer: hast Du gedacht, daß es so einfach
  2074. wäre, einen Filerequester in E zu programmieren?
  2075.  
  2076.  
  2077. Ausgewertete Ausdrücke
  2078.  
  2079.  
  2080.          }11.AUSGEWERTETE
  2081.  
  2082.          A. Auswertung und Bereich
  2083.          B. Eval()
  2084.          C. Eingebaute Funktionen
  2085.  
  2086.  
  2087.          Vorheriges Kapitel     Nächstes Kapitel
  2088. Ausgewertete Ausdrücke
  2089.  
  2090. }11A.
  2091. ---------------------------
  2092. Quotierte Ausdrücke beginnen mit dem Hochkomma. Der Wert eines ausgewerteten
  2093. Ausdrucks ist nicht das Ergebniss von einer Berechnung eines Ausdrucks, son-
  2094. dern die Adddresse des Codes. Dieses Ergebniss kann als eine normale Varia-
  2095. bel weiterverwendet werden, oder als ein Argument für bestimmte Funktionen.
  2096.  
  2097. meinefunk:=`x*x*x
  2098.  
  2099. meinefunk ist nun ein Zeiger auf eine Funktion die x^3 berechnet, wenn sie
  2100. berechnet wird. Diese Zeiger auf Funktionen sind sehr unterschiedlich zu
  2101. normalen PROCs, und Du solltest die beiden nie durcheinander bringen. Die
  2102. größten Unterschiede sinde, daß quotierte Ausdrücke nur einfache Ausdrücke
  2103. sind, und deshalb keine eigenen lokalen Variabeln haben kann. In unserem
  2104. Beispiel ist "x" nur eine lokale oder globale Variabel. Das ist warum vor-
  2105. sicht sein muß: Wenn meinefunk irgendwo später gleichen PROC auswertest,
  2106. kann x lokal sein, aber wenn meinefunk als Parameter an einen anderen PROC
  2107. übergibst, und dann auswertest, muß x natürlich global sein. Es gibt keine
  2108. Bereichsprüfung hierbei.
  2109.  
  2110. Ausgewertete Ausdrücke
  2111.  
  2112. }11B.
  2113. -----------
  2114.     Eval(funk)
  2115.  
  2116. wertet einfach einen quotierten Ausdruck (exp=Eval('exp)) aus.
  2117. BEDENKE: Weil E eine etwas typenlose Sprache ist, wird vom Compiler dummer-
  2118. weise nicht bemerkt, wenn wir "Eval(x*x)" anstatt von "Eval(`x*x)" schrei-
  2119. ben, und das macht Dir große Laufzeitprobleme: der Wert von x*x wird als
  2120. Zeiger auf Code benutzt.
  2121. Um zu verstehen warum "quotierte Ausdrücke" so mächtig sind, danke an die
  2122. folgenden Fälle: wenn Du eine Reihe von Aktionen mit einer Reihe von Varia-
  2123. beln abarbeiten mußt, schreibst Due eine Funktion und rufst die Funktion
  2124. mit verschiedenen Argumenten auf. Aber was ist, wenn das Argument ein Teil
  2125. des Codes ist. In traditionellen Programmiersprachen wäre dies nicht mög-
  2126. lich, so müßtest Du die Blöcke die Deine Funktion repräsentieren "kopieren",
  2127. und dann den Ausdruck hineinschreiben. Nicht in E. Sagen wir, Du möchtest
  2128. ein Programm schreiben, das die Arbeitungszeit von verschiedenen Ausdrücken
  2129. vergleicht. In E würdest Du einfach nur schreiben:
  2130.  
  2131. PROC timing(funk,titel)
  2132.  
  2133.     /*macht alle Dinge um die Zeit zu stellen+/
  2134.  
  2135.     Eval(funk)
  2136.  
  2137.     /*und den Rest*/
  2138.  
  2139.     Write('Die gemessene Zeit von \s war \d\n',titel,t)
  2140.  
  2141. ENDPROC
  2142.  
  2143. und rufen es auf mit:
  2144.  
  2145. timing (`x*x*x,'Multiplication')
  2146. timing (`großeberechnung(),'Große Rechnung')
  2147.  
  2148. in jeder anderen Befehlssprache, müßtest Du für jeden timing-Aufruf eine Ko-
  2149. pie schreiben, oder Du müßtest jeden Ausdruck in eine seperate Funktion
  2150. schreiben. Dies ist nur ein einfaches Beispiel: denke daran, was Du mit Da-
  2151. tenstrukturen (LISTs) mit unausgewerteten Code machen kannst.
  2152.  
  2153. malfunks:   [`Plot(x,y,c), `Line(x,y,x+10,y+10,c), `Box(x,y,x+20,y+20,c)]
  2154.  
  2155. Die Idee von Funktionen als normale Variabeln/Werten ist keine Neuheit von
  2156. E. Quotierte Ausdrücke wurden von LISP beschrieben, welche auch noch etwas
  2157. mächtigeres, Lambda Funktionen genannt, hat, was auch als Argument an Funk-
  2158. tionen übergeben wird. E`s quotierte Ausdrücke können auch als parameterlo-
  2159. se (oder nur globale Parameter) Lambdas angesehen werden.
  2160.  
  2161. Ausgewertete Ausdrücke
  2162.  
  2163. }11C.
  2164. --------------------------
  2165.  
  2166.     MapList(variabeladr,liste,listenvar,funk)
  2167.  
  2168. unterstützt einige Funktionen auf alle Elemente von liste und gibt alle Er-
  2169. gebnisse in listenvar zurück. funk muß ein quotierter Ausdruck sein (siehe
  2170. oben) und variabel (im welchen Bereich der liste) muß als Referenz überge-
  2171. ben werden.
  2172.  
  2173. MapList([x],[1,2,3,4,5],r,`x*x) ergibt in r:[1,4,9,16,25]
  2174.  
  2175.     ForAll(variabeladr,liste,funk)
  2176.  
  2177. Gibt TRUE zurück, wenn alle Werte in liste die Funktion (quotierter Aus-
  2178. druck) zu TRUE verarbeiten, ansonsten FALSE. Kann auch benutzt werden, um
  2179. eine bestimmte Funktion auf alle Elemente einer Liste abzuarbeiten.
  2180.  
  2181. ForAll([x],['eins','zwei','drei'],`WriteF('Beispiel: \s\n',x)
  2182.  
  2183.     Exists(variabeladr,liste,funk)
  2184.  
  2185. Wie ForAll(), nur diese gibt TRUE zurück, wenn irgend ein Element TRUE(<>)
  2186. ergibt. Beachte, daß ForAll() immer alle Elemente berechnet, aber Exists()
  2187. möglicherweise nicht.
  2188.  
  2189. Beispiele, wie man diese Funktionen auf eine spezielle Art und Weise be-
  2190. nutzt:
  2191. wir allozieren verschiedene Größen von Speicher in einem Statement, über-
  2192. prüfen Sie alle auf einmal und geben nur die frei, die erfolgreich angefor-
  2193. dert wurden. (Beispiel für v37+)
  2194.  
  2195. PROC main()
  2196.   LOCAL mem[4]:LIST,x
  2197.   MapList({x},[200,80,10,2500],mem,`AllocVec(x,0)) /* einige allozieren */
  2198.   IF ForAll({x},mem,`x)                            /* Erfolg ? */
  2199.     WriteF('Yes!\n')
  2200.   ELSE
  2201.     WriteF('No!\n')
  2202.   ENDIF
  2203.   ForAll({x},mem,`IF x THEN FreeVec(x) ELSE NOP)   /* nur die <>NIL frei-
  2204.                                                       geben*/
  2205. ENDPROC
  2206.  
  2207. Beachte das fehlen von Wiederholungen in diesem Code. Versuche doch einfach
  2208. dieses Beispiel in irgendeiner anderen Programmiersprache zu schreiben, und
  2209. siehe warum dies besonders ist.
  2210.  
  2211. Fließkommaunterstützung
  2212.  
  2213.  
  2214.          }12.FLIEßKOMMAUNTERSTÜTZUNG@{uu}
  2215.  
  2216.          B. Fließkommaausdrüke und Umwandlungen
  2217.  
  2218.  
  2219.  
  2220.          Vorheriges Kapitel     Nächstes Kapitel
  2221.  
  2222. Fließkommaunterstützung
  2223.  
  2224. }12A.
  2225. --------------------------------------------------------
  2226. Das überladen der standard Operatoren + * usw mit den fließkomma Gegen-
  2227. stücken ist seit der E Version 2.0 möglich, aber ich habe die Hauptdokumen-
  2228. tation davon entfernt, da wahrscheinlich das Fließkommakonzept ab der Ver-
  2229. sion v2.2 oder später sich ändern wird: diese Version wird dann 68881 In-
  2230. line-Code neben den normalen FFP-Routinen in einer transparenten Art er-
  2231. lauben.
  2232. Wenn Du wirklich Fließkommazahlen benutzen willst, mußt Du die eingebauten
  2233. SpXxx()-Routinen des mathffp.library benutzen.
  2234.  
  2235. Beispiel
  2236.  
  2237. x:=SpMul(y,0.013483)
  2238.  
  2239. Sei Dir bewußt, daß wenn v2.5 rauskommt, Dein Code vielleicht geändert wer-
  2240. den muß. (Für die besseren)
  2241.  
  2242. Fließkommaunterstützung
  2243.  
  2244. }12B.
  2245. ----------------------------------------
  2246. wie 12A.
  2247. Exception Behandlung
  2248.  
  2249.  
  2250.          }13.EXCEPTION
  2251.  
  2252.          A. Definition von Exceptionhandlern (HANDLE/EXCEPT)
  2253.          B. Benutzung der Raise() Funktion
  2254.          C. Exceptions für eingebaute Funktionen (RAISE/IF)
  2255.          D. Benutzung von Exception-ID's
  2256.  
  2257.  
  2258.  
  2259.          Vorheriges Kapitel     Nächstes Kapitel
  2260. Exception Behandlung
  2261.  
  2262. }13A.
  2263. -----------------------------------------------------
  2264. Der Ausnahme Mechanismus in E ist hauptsächlich der gleiche wie in ADA;
  2265. es steht für flexible Reaktionen auf Fehler in deinem Programm und
  2266. komplexe Ressourcen Leitung. Beachte: der Ausdruck 'exeption' in E hat
  2267. sehr wenig zu tun mit Ausnahmen ("GURUS"), die vom 680x0 Prozessor verursacht werden!
  2268.  
  2269. Ein Exeption-Handler ist ein Stück des Programm-Codes, daß aufgerufen wird,
  2270. wenn Laufzeitfehler geschehen, solche wie erfolgloses Öffnen von Fenstern
  2271. oder Speicher, der nicht mehr verfügbar ist. Du, oder das Laufzeit-System
  2272. selber, dürfen Signalisieren, daß etwas falsch ist (diese wird "Reaktion
  2273. auf einen Ausnahmezustand genannt), und dann wird das Laufzeit-System
  2274. versuchen, den zutreffenden Ausnahme Handler zu finden.
  2275.  
  2276. Ich sage "zutreffend", weil ein Programm mehr als einen Ausnahme Handler
  2277. enthalten kann, auf allen Stufen eines Programmes.
  2278.  
  2279. Eine normale Funktionen-Definition darf (wie wir alle wissen) folgendermaßen
  2280. ausschauen:
  2281.  
  2282.  
  2283. PROC bla()
  2284.  
  2285.   /* ... */
  2286.  
  2287. ENDPROC
  2288.  
  2289.  
  2290. Eine Funktion mit einem Ausnahme Handler sieht wie diese aus:
  2291.  
  2292.  
  2293. PROC bla() HANDLE
  2294.  
  2295.   /* ... */
  2296.  
  2297. EXCEPT
  2298.  
  2299.   /* ... */
  2300.  
  2301. ENDPROC
  2302.  
  2303.  
  2304. Der Block zwischen PROC und EXCEPT wird normal ausgeführt, und wenn keine
  2305. Ausnahme passiert ist, wird der Block zwischen EXCEPT und ENDPROC
  2306. übersprungen, und die Prozedur wird bei ENDPROC verlassen.
  2307.  
  2308. Wenn eine Ausnahme passiert, entweder im PROC-Abschnitt oder in
  2309. irgendeiner Funktion, die in dem Block aufgerufen wurde, dann wird der
  2310. Ausnahme-Handler ausgelöst.
  2311.  
  2312. Exception Behandlung
  2313.  
  2314. }13B.
  2315. -----------------------------------
  2316.  
  2317. Es gibt viele Wege um ein Ausnahme-Situation auszulösen, der einfachste
  2318. ist der über die Funktion Raise():
  2319.  
  2320.  
  2321.         Raise(exceptionID)
  2322.  
  2323.  
  2324. Die exeptionID ist einfach eine Konstante die den Typ der Ausnahme
  2325. definiert und wird benutzt von Ausnahme-Handlern, um zu untersuchen,
  2326. was schief gegangen ist.
  2327.  
  2328. Beispiel:
  2329.  
  2330.  
  2331. ENUM NOMEM,NOFILE  /* und andere */
  2332.  
  2333.  
  2334. PROC bla() HANDLE
  2335.  
  2336.   DEF mem
  2337.  
  2338.   IF (mem:=New(10))=NIL THEN Raise(NOMEM)
  2339.   myfunc()
  2340.  
  2341. EXCEPT
  2342.  
  2343.   SELECT exception
  2344.  
  2345.     CASE NOMEM
  2346.  
  2347.       WriteF('Kein Speicher!\n')
  2348.  
  2349.     /* ... und anderes */
  2350.  
  2351.   ENDSELECT
  2352.  
  2353. ENDPROC
  2354.  
  2355.  
  2356. PROC myfunc()
  2357.  
  2358.   DEF mem
  2359.  
  2360.   IF (mem:=New(10))=NIL THEN Raise(NOMEM)
  2361.  
  2362. ENDPROC
  2363.  
  2364.  
  2365. Die "Ausnahme"-Variable im Handler beinhaltet immer den Wert des Arguments,
  2366. das durch den Aufruf der Raise()-Funktion übergeben worden ist.
  2367. In beiden New()-Fällen übergab die Raise()-Funktion dem Handler der
  2368. Funktion bla(), und dann ging es richtig zurück zum Aufrufer von bla().
  2369.  
  2370. Wenn myfunc() einen eigenen Ausnahme-Handler hätte würde dieser aufegrufen
  2371. werden für den New()-Funktionsaufruf in myfunc(). Der Umfang eines Ausnahme-
  2372. Handler ist vom Start der PROC, in welcher er definiert wurde, bis zum
  2373. EXCEPT-Schlüsselwort, einschliesslich alle Aufrufe, die von hier gemacht
  2374. werden.
  2375.  
  2376.  
  2377. Dieses hat drei Konsequenzen:
  2378.  
  2379. A. Handler sind rekursiv organisiert, und welcher Handler eigentlich
  2380.    aufgerufen wird ist abhängig von dem Fuknktionsaufruf bei
  2381.    Programmausführung;
  2382.  
  2383. B. wenn eine Ausnahme in einem Handler ausgelöst wird, dann wird der Handler
  2384.    einer niedrigeren Stufe ausgeführt. Dieses Verhalten der Handler
  2385.    darf benutzt werden, um komplex zusammengesetzte rekursive
  2386.    Zuteilungsarien mit großartig Bequemlichkeit zu benutzen, wie wir in
  2387.    Kürze sehen werden.
  2388.  
  2389. C. Wenn eine Ausnahme ausgelöst wird auf einer Stufe, in der kein
  2390.    niedriger "Stufen"-Handler verfügbar ist (oder in einem Programm, daß
  2391.    keinen Handler bekommen hat), dann wird das Programm abgebrochen
  2392.  
  2393.    Z.B.: Raise(x) hat den gleichen Effekt wie CleanUp(0)
  2394.  
  2395. Exception Behandlung
  2396.  
  2397. }13C.
  2398. ----------------------------------------------
  2399. Mit Ausnahmen, wie zuvor beschrieben, haben wir etwas Bedeutendes erreichet
  2400. Über den alten Weg der Definition unserer eigenen "Fehler()"-Funktionen,
  2401. aber dennoch gibt es eine Menge einzugeben, um NIL bei jedem Aufruf von
  2402. New() zu prüfen.
  2403.  
  2404. Das E-Ausnahme-Laufzeitsystem erlaubt Definition von Ausnahmen
  2405. für alle E Funktionen (wie New(), OpenW() usw..), und für alle Library
  2406. Funktionen (OpenLibrary(), AllocMem() usw..), sogar für eingebundene Module.
  2407.  
  2408. Syntax:
  2409.  
  2410.  
  2411. RAISE <exceptionId> IF <Funktion> <Vergleich> <Wert> , ...
  2412.  
  2413.  
  2414. der Teil nach RAISE darf wiederholt werden mit einem ",".
  2415.  
  2416. Beispiel:
  2417.  
  2418.  
  2419. RAISE NOMEM IF New()=NIL,
  2420.  
  2421.       NOLIBRARY IF OpenLibrary()=NIL
  2422.  
  2423.  
  2424. die ersten Zeilen sagen etwas wie "immer wenn ein Aufruf von New()
  2425. in NIL resultiert, dann rufe automatisch die NOMEM Ausnahme auf".
  2426.  
  2427. <Vergleich> kann irgendetwas wie = <> > < >= <= sein.
  2428.  
  2429. Nach dieser Definition dürfen wir alles über unser Programm schreiben:
  2430.  
  2431.  
  2432. mem:=New(size)
  2433.  
  2434.  
  2435. ohne zu schreiben:
  2436.  
  2437.  
  2438. IF mem=NIL THEN Raise(NOMEM)
  2439.  
  2440.  
  2441. Beachte, daß der einzige Unterschied ist, daß "mem" nie einen Wert bekommt,
  2442. wenn das Laufzeit-System den Handler aufruft: Code wird erzeugt für
  2443. jeden aufruf zu New() um nach der Rückkehr von New() zu prüfen
  2444. und evtl. Raise() aufzurufen, wenn dieses notwendig ist.
  2445.  
  2446.  
  2447.  
  2448. Wir haben jetzt ein kleines Beispiel, daß komplex genug ist, um ohne
  2449. Ausnahme-Handling auszukommen: wir rufen eine Funktion rekursiv auf und
  2450. in jedem Aufruf teilen wir eine Ressource zu (in diese Fall Speicher),
  2451. welchen wir vorher allokiert haben, und führen danach den rekursiv Aufruf
  2452. aus.
  2453.  
  2454. Was geschieht, wenn irgendwo oben in der Rekursion ein Fehler entsteht und
  2455. wir das Programm zu verlassen haben?
  2456.  
  2457. Richtig: wir würden (in einer konventionellen Sprache) nicht die niedrigeren
  2458. Resourcen freibekommen, während wir das Programm verlassen, weil alle
  2459. Zeiger zu diesem Speicher in unerreichbaren lokalen Variablen hinterlegt
  2460. sind!
  2461.  
  2462. In E erhöhen wir einfach eine Ausnahme und von dem Ende des Handlers
  2463. erhöhen wir wieder eine Ausnahme, so daß wir alle Handler Rekursiv aufrufen
  2464. und alle Resourcen freigeben.
  2465.  
  2466. Beispiel:
  2467.  
  2468.  
  2469.  
  2470. CONST SIZE=100000
  2471. ENUM NOMEM  /* ,... */
  2472.  
  2473. RAISE NOMEM IF AllocMem()=NIL
  2474.  
  2475. PROC main()
  2476.  
  2477.   alloc()
  2478.  
  2479. ENDPROC
  2480.  
  2481.  
  2482. PROC alloc() HANDLE
  2483.  
  2484.   DEF mem
  2485.  
  2486.   mem:=AllocMem(SIZE,0)         /* sehen, wie viele Blöcke wir bekommen
  2487.                                    können */
  2488.  
  2489.   alloc()                       /* und jetzt die Rekursion .... */
  2490.  
  2491.   FreeMem(mem,SIZE)             /* wir werden nie hierher kommen ... */
  2492.  
  2493. EXCEPT
  2494.  
  2495.   IF mem THEN FreeMem(mem,SIZE)
  2496.   Raise(exception)              /* Rekursiver Aufruf aller Handler */
  2497.  
  2498. ENDPROC
  2499.  
  2500.  
  2501.  
  2502.  
  2503. Dieses ist, natürlich, eine Simulation eines natürlichen Programm-Problem,
  2504. daß gewönlich komplexer ist, und soll auch nur den Gebrauch der
  2505. Ausnahme-Benutzung darstellen. Für ein echtes Beispiel Programm würde das
  2506. Fehlerhandling ohne Ausnahmezustände wesentlich schwieriger werden,
  2507. siehe auch das 'D.e'-Utility Programm.
  2508.  
  2509. Exception Behandlung
  2510.  
  2511. }13D.
  2512. ---------------------------------
  2513.  
  2514. Im echten Leben ist die Ausnahme-ID ein normaler 32-Bit-Wert
  2515. und du darfst alles mögliche an einen Ausnahme-Handler geben, z.B.
  2516. um es als Ausgabe für fehlerhafte Strings zu nutzen:
  2517.  
  2518.  
  2519. Raise('Could not open "gadtools.library"!')
  2520.  
  2521.  
  2522. Wie auch immer, wenn du die Ausnahmen in einer ausführbaren Weise
  2523. nutzen möchtest und Du möchtest auch zukünftige Module nutzen,
  2524. deren Ausnahmen nicht in Deinem Programm definiert sind, dann folge
  2525. den folgenden Vorschlägen:
  2526.  
  2527. - Benutze und definiere die ID 0 als "kein Fehler" (z.B. normaler Abbruch)
  2528.  
  2529. - Um Ausnahmezustände in Deinem Programm zu bestimmen, nutze die
  2530.   ID's 1-10000.
  2531.  
  2532.   Definiere diese mit der gewöhnlichen Methode von ENUM:
  2533.  
  2534.  
  2535.   ENUM OK,NOMEM,NOFILE,...
  2536.  
  2537.  
  2538.   (OK wird 0, und andere werden 1+)
  2539.  
  2540.  
  2541. - ID's 12336 bis 2054847098 (dieses sind alles Bezeichner als
  2542.   Bestandteil von groß-/kleingeschriebenen Buchstaben und Ziffern
  2543.   der Länge 2,3 oder 4 eingeschlossen in "") sind reserviert als
  2544.   gemeinsam benutzte Ausnahmen. Eine gemeinsame Ausnahme ist ein Ausnahme,
  2545.   die nicht in Deinem Programm definiert werden braucht, und die
  2546.   benutzt wird von Vorgaben von Modulen (mit Funktionen in ihnen) um
  2547.   Ausnahmen zu erhöhen: z.B., wenn du eine Anzahl von Prozeduren
  2548.   erstellst die in einem eigenem Task laufen, dann kannst Du die Ausnahmen
  2549.   erhöhen.
  2550.  
  2551.   Wenn du diese Funktionen in verschiedenen Programme nutzen möchtest,
  2552.   dann würde es nicht praktisch sein, die ID's mit dem Haupt Programm
  2553.   zu koordinieren, und ferner, wenn du mehr als eine Funktionen benutzt
  2554.   (in einem Modul, in der Zukunft) und jedes Modul würde eine
  2555.   unterschiedliche Id haben für 'kein Speicher!', dann können Dir die Dinge
  2556.   aus der Hand gleiten.
  2557.  
  2558.   Und hier kommen die gemeinsamen Ausnahmen zum tragen: die gemeinsame
  2559.   'kein Speicher'-ID ist "MEM" (einschliesslich den Anführungsstrichen):
  2560.   jeder kann jetzt einfach von jedem Punkt
  2561.  
  2562.  
  2563.   Raise("MEM")
  2564.  
  2565.  
  2566.   von allen unterschiedlichen Prozeduren aufrufen, und der Programmierer,
  2567.   der diese Module benutzt, braucht nur einen Ausnahme-Handler,
  2568.   der "MEM" versteht.
  2569.  
  2570.  
  2571.   Zukünftige Module, die verschiede Funktionen beinhalten, werden angeben,
  2572.   was für Ausnahmen ein gesichertes Verfahren auslösen darf, und wenn diese
  2573.   sich überlappen mit den ID's von anderen Prozeduren, dann wird die
  2574.   Umgebung des Programmierers, die mit der Ausnahme zu arbeiten hat,
  2575.   außerordentlich schwierig sein.
  2576.  
  2577.  
  2578.   Beispiele
  2579.  
  2580.  
  2581.   (system)
  2582.  
  2583.   "MEM"         kein Speicher
  2584.   "FLOW"        (beinahe) Stack überfließend
  2585.   "^C"          Kontrollieren-C-Tasten-Abbruch
  2586.   "ARGS"        schlecht Argumente
  2587.  
  2588.  
  2589.   (exec/libraries)
  2590.  
  2591.   "SIG"         konnte kein Signal zuteilen
  2592.   "PORT"        konnte keinen Nachrichtenport erstellen
  2593.   "LIB"         Library nicht verfügbar
  2594.   "ASL"         keine asl.library
  2595.   "UTIL"        keine utility.library
  2596.   "LOC"         keine locale.library
  2597.   "REQ"         keine req.library
  2598.   "RT"          keine reqtools.library
  2599.   "GT"          keinen gadtools.library  (ähnlich für anderen)
  2600.  
  2601.  
  2602.   (intuition/gadtools/asl)
  2603.  
  2604.   "WIN"         kein Fenster zu öffnen
  2605.   "SCR"         kein Schirm zu öffnen
  2606.   "REQ"         kein Requester zu öffnen
  2607.   "FREQ"        Kein Filerequester zu öffnen
  2608.   "GAD"         konnte kein Gadget erstellen
  2609.   "MENU"        konnte kein Menu erstellen
  2610.  
  2611.  
  2612.   (dos)
  2613.  
  2614.   "OPEN"        konnte kein File aufmachen/File existiert nicht
  2615.   "OUT"         Proble beim lesen
  2616.   "IN"          Probleme beim schreiben
  2617.   "EOF"         Ende des Files
  2618.   "FORM"        Eingabe Format Fehler
  2619.  
  2620.  
  2621.   Die allgemeine Tendenz ist Großschreibung für allgemeine System
  2622.   Ausnahmen und Kleinschreibung (oder gemischt) für spezifizierte Module.
  2623.  
  2624.  
  2625. - alles anderen (einschliesslich aller negativen ID's) sind reserviert.
  2626.  
  2627.  
  2628. Objektorientierte Programmierung
  2629.  
  2630.  
  2631.          }14.OBJEKTORIENTIERTE
  2632.  
  2633.  
  2634.          Da in Version 2.1b noch nichts eingebaut ist, ist auch nichts
  2635.          dokumentiert. (Im Gegensatz zu Version 3.0 !!!)
  2636.  
  2637.  
  2638.          Vorheriges Kapitel     Nächstes Kapitel
  2639. Der Inline-Assembler
  2640.  
  2641.  
  2642.          }15.DER
  2643.  
  2644.          A. Variablenteilung
  2645.          B. Vergleich zwischen Inline-/Makroassembler
  2646.          C. Wege, Binäredaten zu nutzen (INCBIN/CHAR..)
  2647.          D. OPT ASM
  2648.  
  2649.  
  2650.  
  2651.          Vorheriges Kapitel     Nächstes Kapitel
  2652. Der Inline-Assembler
  2653.  
  2654. }15A.
  2655. ---------------------
  2656. Wie Du wahrscheinlich beim Beispiel im Kapitel 5D erraten hast, können
  2657. Assembleranweisungen frei mit E-Anweisungen vermischt werden. Das große Ge-
  2658. heimniss ist, das ein kompletter Assembler in den Compiler eingebaut
  2659. wurde.
  2660. Getrennt von den normalen Assembler Addressierungsmodies kannst Du auch fol-
  2661. gende Identifiers benutzen:
  2662.  
  2663. meinlabel:
  2664. LEA mylabel(PC),A1      /* Labels */
  2665.  
  2666. DEF a                   /* Variablen */
  2667. MOVE.L (A0)+,a          /* Beachte das <var> ein <offset>(A4) (or A5) ist */
  2668.  
  2669. MOVE.L dosbase,A6       /* Identifiers für Library-Aufrufe */
  2670. JSR    Output(A6)
  2671.  
  2672. MOVEQ  #TRUE,D0         /* Konstanten */
  2673.  
  2674. Der Inline-Assembler
  2675.  
  2676. }15B.
  2677. ----------------------------------------------
  2678. Der Inline-Assembler unterscheidet sich etwas von einem normalen Macro-
  2679. Assembler. Dies ist dadurch bedingt, daß er eine Erweiterung von E ist, und
  2680. deshalb der E-Syntax folgt. Hauptunterschiede sind:
  2681.  
  2682. - Kommentare werden nicht mit einem ';' Semikolon eingeleitet, sondern in /*
  2683.   */ eingeschlossen, sie haben unterschiedlich Bedeutung.
  2684. - Schlüsselworte und Register werden großgeschrieben, alles ist von der Groß-
  2685.   und Kleinschreibung abhängig.
  2686. - keine Macros und ander luxuriöse Assemblereigenschaften (es gibt schließ-
  2687.   lich den kompletten E-Sprachumfang dafür)
  2688. - Du solltest aufpassen, daß Du den Inhalt der Register A4/A5 nicht mit dem
  2689.   Inline-Assembler überschreibst, da sie vom E-Code benutzt werden.
  2690. - keine Unterstützung des Large Modells/Relloc-Hunks im Assembler -JETZT-
  2691.   Dies bedeutet hauptsächlich, das Du bis jetzt die PC-Relative Addressie-
  2692.   rung benutzen mußt.
  2693.  
  2694. Der Inline-Assembler
  2695.  
  2696. }15C.
  2697. ------------------------------------------------
  2698. INCBIN
  2699.  
  2700. Syntax: INCBIN <filename>
  2701.  
  2702. Fügt einen Binär-File genau am Punkt des Statements ein, und sollte deshalb
  2703. vom Code getrennt werden. Beispiel:
  2704.  
  2705. meinetab:   INCBIN <filename>
  2706.  
  2707. LONG, INT, CHAR
  2708.  
  2709. Syntax: LONG <werte>
  2710.         INT  <werte>
  2711.         CHAR <werte>
  2712.  
  2713. Erlaubt Dir binäre Daten direkt in ein Programm einzufügen. Funktioniert
  2714. fast wie DC.x in Assembler. Beachte, daß das CHAR-Statement auch Strings
  2715. annimmt und immer auf gerade Wortaddressen gelegt wird. Beispiel:
  2716.  
  2717. meinedaten: LONG 1,2; CHAR 3,4,'Hey Leute',0,1
  2718.  
  2719. Der Inline-Assembler
  2720.  
  2721. }15D.
  2722. ------------
  2723. OPT ASM  wird im Kaptel 16A besprochen. Es erlaubt Dir EC wie einen Assemb-
  2724. ler zu programmieren. Es gibt keinen guten Grund, EC anstatt eines Assemb-
  2725. lers zu  nehmen, außer der Geschwindigkeit. Er ist wesentlich schneller als
  2726. zum Beispiel A68k, gleich mit dem DevPac und langsamer als AsmOne. Du wirst
  2727. auch eine schwere Zeit haben, wenn Du die alten Seka-Sources von deiner
  2728. Disk schröpfen willst, aufgrund der aufgeführten Unterschiede (siehe 15B).
  2729. Wenn Du Assembler-Programme mit EC schreiben und sie zu anderen Assemblern
  2730. kompatibel halten willst, schreibe vor jede E-Speziefische Funktion ein ";",
  2731. EC wird sie benutzen und jeder andere Assembler ihn wird als Kommentar an-
  2732. sehen.
  2733. Beispiel:
  2734.  
  2735. ;OPT ASM
  2736.  
  2737. start:  MOVEQ   #1,D0   ;/*macht etwas dummes*/
  2738.         RTS             ;/*und steigt aus*/
  2739.  
  2740. dies wird von jedem Assembler assembliert, EC eingeschlossen.
  2741.  
  2742. Dinge über den Compiler
  2743.  
  2744.  
  2745.          }16.DINGE
  2746.  
  2747.          A. Das OPT Schlüsselwort
  2748.          B. Small/Large Modell
  2749.          C. Stack Organisation
  2750.          D. Festgeschriebene Begrenzungen
  2751.          E. Fehlermeldungen, Warnungen und nicht dokumentierte Tests
  2752.          F. Compiler Puffer Organisation und Anforderung
  2753.          G. Eine kurze Entstehungsgeschichte
  2754.  
  2755.  
  2756.          Vorheriges Kapitel     Nächstes Kapitel
  2757. Dinge über den Compiler
  2758.  
  2759. }16A.
  2760. --------------------------
  2761.  
  2762. OPT, LARGE, STACK, ASM, NOWARN, DIR, OSVERSION
  2763.  
  2764. syntax: OPT <Optionen>
  2765.  
  2766. Bietet die Möglichkeit, die Einstellungen des Compilers zu verändern.
  2767.  
  2768. LARGE  Das Code- und Datenmodell wird auf "LARGE" gestellt. Grundein-
  2769.        stellung ist "SMALL"; der Compiler generiert einen 100% pc-
  2770.        ähnlichen Code, mit einer Maximalgröße von 32K. Mit "LARGE"
  2771.        gibt es keine solchen Begrenzungen, zudem werden "reloc-hunks"
  2772.        generiert. Siehe -L
  2773. STACK=x  Setzt die Stackgröße auf x Bytes. Man sollte diese Option
  2774.          nur verwenden, wenn man weiß, was man tut. Normalerweise
  2775.          schätzt der Compiler die benötigte Stackgröße selbstständig
  2776.          recht gut ein.
  2777. ASM  Der Compiler wird in den Assembler-Modus geschaltet. Von da an
  2778.      sind nur noch Assembler-Befehle erlaubt und es wird kein Initi-
  2779.      alisierungscode generiert. Siehe: das Kapitel über integriertes
  2780.      Assembler.
  2781. NOWARN  Schaltet die Warnungen aus. Der Compiler gibt eine Warnung
  2782.         aus, wenn er *glaubt*, daß das Programm falsch ist, syntakt-
  2783.         isch aber in Ordnung ist. Siehe -n
  2784. DIR=moduledir  Legt das Verzeichnis fest, in dem der Compiler nach
  2785.                Modulen sucht. Grundeinstellung ist 'emodules:'
  2786. OSVERSION=vers  Grundeinstellung ist 33.(V1.2). Setzt die Minimum-
  2787.                 Version des Kickstarts (wie z.B. 37. für V2.04) fest,
  2788.                 ab denen das Programm laufen soll. Auf diesem Weg
  2789.                 bricht das Programm einfach ab, wenn die dos.library
  2790.                 einer älteren Version in der Initialisierungsroutine
  2791.                 auf einer älteren Maschine geöffnet wird. Allerdings
  2792.                 ist es für den User hilfreicher, wenn man die Kick-
  2793.                 startversion selber testet und eine geeignete Fehler-
  2794.                 meldung ausgibt.
  2795. Beispiel:
  2796. OPT STACK=20000,NOWARN,DIR='DF1:Modules',OSVERSON=39
  2797. Dinge über den Compiler
  2798.  
  2799. }16B.
  2800. -----------------------
  2801.  
  2802. Amiga-E läßt einem die Wahl zwischen einem SMALL und einem LARGE Code/
  2803. Daten-Modell. Allerdings dürften die meisten Programme, die man schreibt
  2804. (besonders, wenn man gerade erst mit Amiga-E angefangen hat), in die
  2805. 32K passen, wenn compiliert wird: man braucht sich also keine Gedanken
  2806. über das Einstellen eines Code-Genrierungs-Modelles machen. Man kann die
  2807. Notwendigkeit eines LARGE-Modelles daran erkennen, daß sich EC darüber
  2808. beschwert, daß es den Code nicht mehr in die 32K hineinbekommt. Folgender
  2809. Befehl compiliert einen Source-Code mit dem LARGE-Modell:
  2810. 1> ec -l sizy.e
  2811. oder, besser, setzen sie die Anweisung
  2812. OPT LARGE
  2813. in ihren Code.
  2814.  
  2815. Dinge über den Compiler
  2816.  
  2817. }16C.
  2818. -----------------------
  2819.  
  2820. Um alle lokalen und globalen Variablen zu speichern, weißt das run-time Sys-
  2821. tem eines von E generierten ausführbaren Programmes einen Speicherbereich zu,
  2822. von dem es einen festen Teil verwendet, um alle globalen Variablen zu speichern.
  2823. Der Rest wird dynamisch verwendet, wenn Funktionen aufgerufen werden. Wenn in E
  2824. eine Funktion aufgerufen wird, wird ein Bereich im Stack reserviert, um alle
  2825. lokalen Daten zu speichern, sobald die Funktion beendet ist, wird der Bereich
  2826. wieder freigegeben. Deshalb ist es gefährlich, große Arrays für lokale Daten
  2827. zu haben, wenn diese rekursiv aufgerufen werden: alle Daten der vorherigen Auf-
  2828. rufe der selben Funktion befinden sich noch immer im Stack und besetzen somit
  2829. einen großen Bereich in diesem. Werden Prozeduren jedoch linear aufgerufen, dann
  2830. kann der Stack nicht überlaufen.
  2831. Beispiel:
  2832.  
  2833. global data:        10K (arrays e.d)
  2834. local data PROC #1:  1K
  2835. local data PROC #1:  3K
  2836.  
  2837. Das run-time System reserviert immer zusätzliche 10K für normale Rekursion (z.B. mit
  2838. kleinen lokalen Arrays) und weitere Buffers/Systemspeicher, so daß insgesamt 24K
  2839. Stackspeicher zugewiesen werden.
  2840.  
  2841. Dinge über den Compiler
  2842.  
  2843. }16D.
  2844. ----------------------------------
  2845.  
  2846. Beachte diese Zeichen:  (+-)   ungefähr, hängt von der Situation ab
  2847.                         (n.l.) kein klares Limit, aber dieser Wert scheint sinnvoll
  2848.  
  2849. OBJEKT/GEGENSTAND                                      WERT/MENGE/MAX
  2850. ---------------------------------------------------------------------------------
  2851. Wert des Datentyps CHAR                                0 ... 255
  2852. Wert des Datentyps INT                                 -32K ... +32K
  2853. Wert des Datentyps LONG/PTR                            -2Gig ... +2 Gig
  2854.  
  2855. Identifierlänge                                        100 bytes (n.l.)
  2856. Länge einer Quellcodezeile                             2000 lexikalische Zeichen (+-)
  2857. Quellcode Länge                                        2 Gig (theoretisch)
  2858. konkrete listen                                        einige hundert Elemente (+-)
  2859. konstante Strings                                      1000 Zeichen (n.l.)
  2860. max. Tiefe der Schleifen                               500 tief
  2861. max. Tiefe der Kommentare                              unbegrenzt
  2862.  
  2863. # der lokalen Variablen pro Prozedur                   8000
  2864. # der globalen Variablen                               7500
  2865. # der Argumente für eigene Funktionen                  8000 (zusammen mit locals (?))
  2866. # der für E-varargs Funktionen [WriteF()]              64
  2867.  
  2868. ein Objekt (lokal/global oder dyn. zugewiesen)         8K
  2869. ein Array, List oder String (lokal oder global)        32K
  2870. ein String (dynamisch)                                 32K
  2871. ein List dynamisch)                                    128K
  2872. ein Array (dynamisch)                                  250MB
  2873.  
  2874. lokale Daten pro Prozedur                              250MB
  2875. globale Daten                                          250MB
  2876.  
  2877. Code-Größe einer Prozedur                              32K
  2878. Code-Größe eines ausführbaren Progs.                   32K SMALL, 2Gig LARGE Modell
  2879.  
  2880. Buffer-Größe eines generierten Codes und Identifiers   abhängig vom Quellcode
  2881. Buffer-Größe von Sprungmarken/Zweigen                  unabhängig (wieder)zugewiesen
  2882.  
  2883. Dinge über den Compiler
  2884.  
  2885. }16E.
  2886. --------------------------------------------------------------
  2887.  
  2888. Manchmal. wenn sie ihren Quellcode mit EC compilieren, erhalten sie eine Meldung, die
  2889. ungefähr folgendermaßen aussieht: UNREFERENCED <ident.>, <ident.>, ...
  2890. Dies passiert, wenn sie Variable, Funktionen oder Sprungmarken definieren, diese aber
  2891. nicht verwenden. Dies ist ein Extra-Service des Compilers, der helfen soll, solche
  2892. schwer zu findenden Fehler zu entdecken. Es gibt mehrere Warnungen, die der Compiler
  2893. ausgiebt, um sie darauf aufmerksam zu machen, daß etwas nicht in Ordnung ist, dies aber
  2894. kein echter Fehler ist.
  2895.  
  2896. - "A4/A5 used in line assembly"
  2897.   Diese Warnung wird ausgegeben, wenn sie Register A4 und A5 in ihrem Assembler Code
  2898.   verwenden. Der Grund dafür ist, daß diese Register von E intern verwendet werden,
  2899.   um lokale und globale Variable richtig zu addressieren. Natürlich kann es gute Gründe
  2900.   geben, diese zu gebrauchen, wie MOVEM.L A4/A5,-(A7) vor einen großen Stück Inline-
  2901.   Assembler-Code.
  2902.  
  2903. - "keep eye on stacksize"
  2904. - "stack is definitely too small"
  2905.   Beides kann ausgegeben werden, wenn sie OPT STACK=<size> verwenden. Der Compiler ver-
  2906.   gleicht einfach ihre Angabe mit seiner eigene Schätzung (siehe Kapitel 16C.), und gibt
  2907.   erstere Meldung aus, wenn er meint, die Größe sei etwas knapp kalkuliert oder letztere,
  2908.   wenn sie definitiv zu klein ist.
  2909.  
  2910. - 'suspicious use of "=" in void expression'
  2911.   Diese Warnung erscheint, wenn sie den Ausdruck 'a=1' als Anweisung gebrauchen. Ein Grund
  2912.   ist, daß ein Vergleich als Anweisung wenig Sinn macht, aber der Hauptgrund ist, daß dies
  2913.   oft vorkommende Rechtschreibfehler bei 'a:=1' ist. Den vergessenen ":" zu finden ist
  2914.   schwer, aber er kann ernsthafte Konsequenzen haben.
  2915.  
  2916. FEHLER:
  2917.  
  2918. - 'syntax error'
  2919.   Häufigster Fehler. Diese Fehlermeldung erscheint, wenn entweder keine andere Meldung passt,
  2920.   oder ihre Anordnung des Codes dem Compiler etwas seltsam erscheint.
  2921.  
  2922. - 'unknown keyword/const'
  2923.   Sie haben einen Identifier in Großbuchstaben (wie "IF" oder "TRUE") verwendet, und der Compiler
  2924.   konnte keine Definition dafür finden. Gründe:
  2925.   * falschgeschriebenes Schlüsselwort
  2926.   * sie haben eine Konstante verwendet, diese aber nicht zuvor mit CONST definiert
  2927.   * sie haben vergessen, das Modul anzugeben, in dem ihre Konstante definiert ist
  2928.  
  2929. - '":=" expected'
  2930.   Sie haben eine FOR Anweisung oder eine Zuweisung geschrieben, und haben dabei etwas anderes als
  2931.   ":=" verwendet.
  2932.  
  2933. - 'unexpected characters in line'
  2934.   Sie haben Zeichen verwendet die in E außerhalb von Strings keine syntaktische Bedeutung haben.
  2935.   Beispiel: "§!&Öß"
  2936.  
  2937. - 'label expected'
  2938.   In bestimmten Fällen, zum Beispiel nach den Schlüsselwörtern PROC oder JUMP, ist ein Iden-
  2939.   tifier notwendig. Sie haben irgendetwas anderes geschrieben.
  2940.  
  2941. - '"," expected'
  2942.   Innerhalb einer Gegenstandsliste (z.B. eine Parameter Liste), haben sie etwas anderes als
  2943.   ein Komma verwendet.
  2944.  
  2945. - 'variable expected'
  2946.   Diese Konstruktion braucht eine Variable, Beispiel:
  2947.   FOR <var>:= ... etc.
  2948.  
  2949. - 'value does not fit into 32 bit'
  2950.   Beim spezifizieren einer Konstanten haben sie einen zu großen Wert einegegeben, Beispiel:
  2951.   $FFFFFFFFF, "abcdef"  /siehe Kapitel 2A-2E)
  2952.   Diese Meldung erscheint auch, wenn ein SET-Befehl mit mehr als 32 Elementen verwendet wird.
  2953.  
  2954. - 'missing apostrophe/quote'
  2955.   Sie haben ein ' am Ende einer String vergessen.
  2956.  
  2957. - 'incoherrent program structure'
  2958.   * sie haben eine neue PROCedure gestartet, ohne die vorherige zu beenden.
  2959.   * die Verzweigung ihrer Programme ist falsch, z.B.:
  2960.     FOR
  2961.       IF
  2962.       ENDFOR
  2963.     ENDIF
  2964.  
  2965. - 'illegal command-line option'
  2966.   Innerhalb der Befehlszeile 'EC -opt source' haben sie für -opt einen Ausdruck verwendet, der
  2967.   EC unbekannt ist.
  2968.  
  2969. - ' division and multiplication 16 bit only'
  2970.   Der Compiler hat festgestellt, daß sie einen 32 bit Wert für * oder / verwendet haben. Dies
  2971.   würde nicht den erwünschten Wert im Runtime ergeben.
  2972.   Siehe Mul() und Div().
  2973.  
  2974. - 'superfluous items in expression/statement'
  2975.   Nachdem der Compiler ihren Anweisung bearbeitet hat, hat er immer noch Zeichen anstelle
  2976.   eines Linefeeds gefunden. Sie haben wahrscheinlich den <lf> oder ";" vergessen, um zwei
  2977.   Anweisungen zu trennen.
  2978.  
  2979. - 'procedure "main" not available'
  2980.   Ihre Programm hat keine 'main procedure'.
  2981.  
  2982. - 'double declaration of label'
  2983.   Sie haben eine Sprungmarke zweimal vergeben, z.B.:
  2984.   label:
  2985.   PROC label()
  2986.  
  2987. - 'unsafe use of "*" or "/"'
  2988.   Dies hat wieder etwas mit 16 Bit anstelle von 32 Bit * und / zu tun. Siehe 'division and
  2989.   multiplication 16 bit only'.
  2990.  
  2991. - 'reading sourcefile didn't succed'
  2992.   Überprüfen sie ihre Angaben für die Quelle, die sie mit 'ec mysource' angegeben haben.
  2993.   Achten sie darauf, daß die Quelle und nicht die Kommandozeile auf '.e' endet.
  2994.  
  2995. - 'writing executable didn't succed'
  2996.   Der Versuch, das eben generierte ausführbare Programm zu schreiben verursachte einen DOS-
  2997.   Fehler. Unter umständen existierte das Programm bereits und konnte nicht überschrieben
  2998.   werden.
  2999.  
  3000. - 'no args'
  3001.   "GEBRAUCH: ec [-opts] <Quellcodedateiname> ('.e' wird hinzugefügt)"
  3002.   Sie erhalten diese Meldung, wenn sie ec ohne Argumente verwenden.
  3003.  
  3004. - 'unknown/illegal addressing mode'
  3005.   Dieser Fehler erscheint nur, wenn sie den inline Assembler verwenden. Mögliche Gründe:
  3006.   * sie haben eine Addressierungsweise verwendet, die es für den 68000er nicht gibt.
  3007.   * die Addressierungsmethode existiert, aber nicht für diesen Befehl. Nicht alle Assembler-
  3008.     Befehle unterstützen alle Kombinationen der effektiven Addressen für Quelle und Ziel.
  3009.  
  3010. - 'unmatched parentheses'
  3011.   Ihre Anweisung hat mehr "(" als ")" oder umgekehrt.
  3012.  
  3013. - 'double declaration'
  3014.   Ein Identifier wird in zwei oder mehr Deklarationen verwendet.
  3015.  
  3016. - 'unknown'
  3017.   Ein Identifier wird in keiner Deklaration verwendet; er ist unbekannt. Wahrscheinlich haben
  3018.   sie vergessen, ihn in eine DEF-Anweisung zu setzen.
  3019.  
  3020. - 'incorrect # of args or use of ()'
  3021.   * sie haben vergessen "(" oder ")" an die richtige Stelle zu setzen
  3022.   * sie haben eine falsche Anzahl von Argumenten für eine Funktion verwendet
  3023.  
  3024. - 'unknown e/library function'
  3025.   Sie haben einen Identifier mit einem Großbuchstaben begonnen und dann mit Kleinbuchstaben
  3026.   fortgesetzt, aber der Compiler konnte keine Definition finden.
  3027.   Mögliche Gründe:
  3028.   * eine Funktion wurde falschgeschrieben
  3029.   * sie haben das Modul miteinzuschließen, das diesen Bibliotheksaufruf enthält
  3030.  
  3031. - 'illegal function call'
  3032.   Erscheint selten. Sie erhalten diesen Fehler, wenn sie seltsame Funktionsaufrufe starten,
  3033.   wie z.B. verzweigte WriteF()'s :
  3034.   WriteF(WriteF('hi'))
  3035.  
  3036. - 'unknown format code following ""'
  3037.   Sie haben in einer String einen Formatcode verwendet, der unzulässig ist.
  3038.   Siehe Kapitel 2F für eine Liste der Formatcodes.
  3039.  
  3040. - '/* not properly nested comment structure */'
  3041.   Die Anzahl der '/*' stimmt nicht mit der Anzahl der '*/' überein, oder haben eine komische
  3042.   Reihenfolge.
  3043.  
  3044. - 'could not load binary'
  3045.   <filespec> innerhalb von INCBIN <filespec> konnte nicht gelesen werden.
  3046.  
  3047. - '"}" expected'
  3048.   Sie haben einen Ausdruck mit "{<var>" begonnen, aber das "}" vergessen.
  3049.  
  3050. - 'immediate value expected'
  3051.   Manche Konstruktione erfordern einen direkten Wert anstelle eines Ausdrucks.
  3052.   Beispiel:
  3053.   DEF s[x*y]:STRING   /* falsch, nur etwas wie s[100]:STRING ist zulässig */
  3054.  
  3055. - 'incorrect size of value'
  3056.   Sie haben einen unzulässig großen/kleinen Wert in einer Konstruktion verwendet.
  3057.   Beispiel:
  3058.   DEF s[-1]:STRING, +[1000000]:STRING    /* muß 0 ... 32000 sein */
  3059.   MOVEQ #1000,D2                         /* muß -128 ... 127 sein */
  3060.  
  3061. - 'no e code allowed in assembly modus'
  3062.   Sie haben den Compiler als Assembler arbeiten lassen, aber, aus Versehen, E-Code
  3063.   geschrieben.
  3064.  
  3065. - 'illegal/inappropriate type'
  3066.   An einer Stelle wo eine <type> Spezifikation notwendig gewesen wäre, haben sie etwas
  3067.   unpassendes eingegeben. Beispiele:
  3068.   DEF a:PTR TO ARRAY        /* es gibt keinen solchen Typ */
  3069.   [1,2,3]:STRING
  3070.  
  3071. - '"]" expected
  3072.   Sie haben mit einem "[" begonnen, aber nie mit einem "]" aufgehört.
  3073.  
  3074. - ' statement out of local/global scope'
  3075.   Ein wesentlicher Punkt bei der Kontrolle ist die erste PROC-Anweisung. Davor sind nur
  3076.   globale Definitionen (DEF, CONST,MODULE etc.) erlaubt, und keinerlei Code. Im zweiten
  3077.   Teil sind nur Code, aber keine globalen Definitionen erlaubt.
  3078.  
  3079. - 'could not read module correctly'
  3080.   Es gab einen DOS-Fehler beim Versuch, ein Modul von einer MODULE-Anweisung einzulesen.
  3081.   Gründe:
  3082.   * emodules:wurden nciht korrekt zugewiesen (assign emodules: ...)
  3083.   * der Modulname wurde falsch geschrieben, oder es existiert nicht
  3084.   * sie haben MODULE 'bla.m' anstelle von MODULE 'bla'
  3085.  
  3086. - 'workspace full'
  3087.   Erscheint selten. Wenn dieser Fehler erscheint, müssen sie EC mit der '-m' Option dazu
  3088.   zwingen, die Schätzung über die benötigte Speichermenge höher anzusetzen. Versuchen sie
  3089.   es zuerst mit '-m2', dann '-m3', bis der Fehler verschwindet. Sie müssen aber schon rie-
  3090.   sige Anwendungsprogramme, mit einer Unmenge Daten schreiben, damit dieser Fehler er-
  3091.   scheint.
  3092.  
  3093. - 'not enough memory while (re-)allocating'
  3094.   Mögliche Lösungen für dieses Problem:
  3095.   1. Sie haben andere Programme im Multitasking laufen. Stoppen sie diese und versuchen
  3096.      sie es nocheinmal.
  3097.   2. Sie haben akuten Speichermangel und der Speicher war fragmentiert. Rebooten sie.
  3098.   3. Weder 1. noch 2., kaufen sie sich eine Speichererweiterung (hüstel).
  3099.  
  3100. - 'incorrect object definition'
  3101.   Sie haben bei einer Definition zwischen OBJECT und ENDOBJECT Blödsinn geschrieben.
  3102.   Siehe Kapitel 8F, um herauszufinden, wie's richtig geht.
  3103.  
  3104. - 'incomplete if-then-else expression'
  3105.   Wenn sie IF als einen Operator verwenden, dann muß ELSE ein Teil dieses Ausdrucks sein:
  3106.   ein Ausdruck mit einer IF-Anweisung muß immer einen Wert zurückgeben, aber wenn keine
  3107.   ELSE-Anweisung da ist, kann IF im Prinzip nichts tun.
  3108.  
  3109. - 'unknown object identifier'
  3110.   Sie haben einen Identifier verwendet, den der Compiler als einen Teil eines Objekts er-
  3111.   kannt hat, aber sie haben vergessen, ihn zu deklarieren. Gründe:
  3112.   * falsch geschriebener Name
  3113.   * fehlendes Modul
  3114.   * der Identifier innerhalb des Modules wird nicht so geschrieben, wie sie es aus den
  3115.     Rom-Kernel-Manuals erwartet haben. Überprüfen sie es mit ShowModule.
  3116.     Beachten sie, daß Amiga-System-Objekte auf Assembler Identifiern basieren und nicht auf
  3117.     C. Zweitens: Identifier folgen dem E-Syntax.
  3118.  
  3119. - 'double declaration of object identifier'
  3120.   Ein Identifier wurde in zwei Objekt Definitionen verwendet.
  3121.  
  3122. - 'reference(s) out of 32K range: switch to LARGE model'
  3123.   Ihr Programm wird größer als 32K. Fügen sie einfach 'OPT LARGE' in ihren Quellcode mit
  3124.   ein. Siehe Kapitel 16B.
  3125.  
  3126. - 'reference(s) out of 256 byte range'
  3127.   Sie haben wahrscheinlich BRA.S oder Bcc.S über eine zu große Distanz geschrieben.
  3128.  
  3129. - 'too sizy expression'
  3130.   Sie haben wahrscheinlich eine Liste von [], möglicherweise [[]], geschrieben, die zu groß
  3131.   ist.
  3132.  
  3133. - 'incomplete exception handler definition'
  3134.   Sie haben unter Umstaänden EXCEPT ohne HANDLE verwendet, oder aber auch anders herum.
  3135.   Siehe Kapitel 13 für "exception handling".
  3136.  
  3137. Dinge über den Compiler
  3138.  
  3139. }16F.
  3140. -------------------------------------------------
  3141.  
  3142. Wenn sie den Fehler 'workspace full' (sehr unwahrscheinlich) erhalten, oder wissen wollen was
  3143. wirklich passiert, wenn ihr Programm compiliert wird, ist es wichtig, zu wissen, wie EC seine
  3144. Buffer organisiert.
  3145. Ein Compiler, und in diesem Fall EC, braucht Buffer, um alle möglichen Dinge, wie z.B. Identi-
  3146. fier nachverfolgen zu können. Es braucht diese auch, um darin den generierten Code zu speichern.
  3147. EC weiß nicht, wie groß diese Buffer sein müssen. Bei manchen Buffern, wie dem für Konstanten,
  3148. ist das kein Problem: wenn der Buffer voll ist, weißt EC einfach ein weiteres Stück Speicher zu
  3149. und arbeitet dann weiter. Andere Buffer, wie der für den generierten Code, müssen ein einziger
  3150. Speicherblock sein, der sich während des Compilierens nicht verändert: EC muß also den notwendigen
  3151. Speicher gut abschätzen, um große und kleine Quellcodes compilieren zu können. EC berechnet also
  3152. anhand des Quellcodes den benötigten Speicherplatz und fügt dazu nocheinmal eine ansehnliche Menge
  3153. hinzu. Somit reicht in 99% aller Fälle der Speicher aus, andern Falls erhalten sie eine Fehler-
  3154. meldung un müssen weiteren Speicher mit der '-m' Option hinzufügen.
  3155. Experimentieren sie mit unterschiedlichen Typen und Größen von Quellcoden in Verbindung mit der
  3156. '-b' Option um herauszufinden, wie es funktioniert.
  3157.  
  3158. Dinge über den Compiler
  3159.  
  3160. }16G.
  3161. --------------------------------------
  3162.  
  3163. E ist nicht einfach einen weitere Programmiersprache: sie wurde schrittweise und vorsichtig
  3164. vom Autor entwickelt, da er mit den existierenden Programmiersprachen nicht besonders glück-
  3165. lich war, speziell den langsamen und "schlabrige-Codes-erzeugenden" Compilern, die es für
  3166. diese gab. E hatte als primäres Ziel dem Autor für seine Entwickling von Amiga Programmen zu
  3167. dienen, und war dabei bisher sehr erfolgreich. E wurde in einen Zeitraum von 1½ Jahren in Ver-
  3168. bindung mit intensiver Arbeit entwickelt und war nicht der erste Compiler, den der Autor ge-
  3169. schrieben hat: manch einer erinnert sich vielleicht an den DEX-Compiler.
  3170.  
  3171. Dieser war langsam und nicht besonders mächtig und kann nur schwerlich mit dem Amiga E Com-
  3172. piler verglichen werden, aber er gab dem Autor wichtige Erfahrungen, die halfen, Amiga E zu
  3173. dem zu machen, was es heute ist. DEX Programierer werden feststellen, daß es sehr einfach ist
  3174. ihre Quellcodes in E umzuwandeln, und die Entwicklung mit der 10fachen Power und der 20fachen
  3175. Geschwindigkeit fortzusetzen. Eine witzige Sache an DEX ist, daß sich die Entwicklung von DEX
  3176. und E überschnitten hat: als DEX fertig war, war E V1.6 zur Hälfte geschrieben. Weil E schon
  3177. damals wesentlich besser war, wurden E Bibliotheken/Beispiele und Codes auf allgemeinen Wunsch
  3178. hin auf DEX übertragen, so daß der Vorgänger Teile seines Nachfolgers beinhaltete.
  3179. Der AUtor hat auch noch weitere Compiler und Interpreter geschrieben, die aber teilweise nie
  3180. veröffentlicht wurden.
  3181.  
  3182. Amiga E ist ein Produkt, das weiter entwickelt wird, bis es die ultimative Sprache und Amiga
  3183. Entwicklungssystem ist:
  3184.  
  3185. - indem diese, bisher fehlenden Teile, in die Sprache miteinbezogen werden
  3186.   * Objektorientierung
  3187.   * besseres Fließkomma Konzept
  3188.  
  3189. - indem am Compiler einige Veränderungen vorgenommen werden
  3190.   * mögliche Genrierung von 020/030/881 Code
  3191.   * Optimierung des Compilierungsprozesses, so daß unter Umstäden sich Zeile/Minute Figuren
  3192.     verdoppeln
  3193.   * es soll dem User ermöglicht werden, eigenen Code in Module zu wandeln, um somit große
  3194.     Anwendungen modular aufbauen zu können
  3195.  
  3196. - indem wetvolle Elemente dem Packet hinzugefügt werden
  3197.   * ein integrierte Editor ?
  3198.   * source-level debugger ?
  3199.   * CASE Werkzeuge, zum Beispiel
  3200.  
  3201. - indem Bugs entfernt werden (welche Bugs ??!!)
  3202.  
  3203.  
  3204. Das ENDE! Schnauf! Viel Spaß mit E!
  3205.  
  3206.  
  3207.